This file is indexed.

/usr/lib/python3/dist-packages/rtmidi/midiutil.py is in python3-rtmidi 1.1.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# -*- coding: utf-8 -*-
#
# util.py
#
"""Collection of utility functions for handling MIDI I/O and ports.

Currently contains functions to list MIDI input/output ports, to get the RtMidi
API to use from the environment and to open MIDI ports.

"""

from __future__ import print_function, unicode_literals

import logging
import os

try:
    raw_input
except NameError:
    # Python 3
    raw_input = input
    basestring = str

import rtmidi


__all__ = (
    'get_api_from_environment',
    'list_available_ports',
    'list_input_ports',
    'list_output_ports',
    'open_midiinput',
    'open_midioutput',
    'open_midiport',
)

log = logging.getLogger(__name__)


def _prompt_for_virtual(type_):
    """Prompt on the console whether a virtual MIDI port should be opened."""
    return raw_input("Do you want to create a virtual MIDI %s port? (y/N) " %
                     type_).strip().lower() in ['y', 'yes']


def get_api_from_environment(api=rtmidi.API_UNSPECIFIED):
    """Return RtMidi API specified in the environment if any.

    If the optional api argument is ``rtmidi.API_UNSPECIFIED`` (the default),
    look in the environment variable ``RTMIDI_API`` for the name of the RtMidi
    API to use. Valid names are ``LINUX_ALSA``, ``UNIX_JACK``, ``MACOSX_CORE``,
    ``WINDOWS_MM`` and ``RTMIDI_DUMMY``. If no valid value is found,
    rtmidi.API_UNSPECIFIED will be used.

    Returns a ``rtmmidi.API_*`` constant.

    """
    if api == rtmidi.API_UNSPECIFIED and 'RTMIDI_API' in os.environ:
        try:
            api_name = os.environ['RTMIDI_API'].upper()
            api = getattr(rtmidi, 'API_' + api_name)
        except AttributeError:
            log.warning("Ignoring unknown API '%s' in environment variable "
                        "RTMIDI_API." % api_name)

    return api


def list_available_ports(ports=None, midiio=None):
    """List MIDI ports given or available on given MIDI I/O instance."""
    if ports is None:
        ports = midiio.get_ports()
        type_ = " input" if isinstance(midiio, rtmidi.MidiIn) else " ouput"
    else:
        type_ = ''

    if ports:
        print("Available MIDI{} ports:\n".format(type_))

        for portno, name in enumerate(ports):
            print("[{}] {}".format(portno, name))
    else:
        print("No MIDI{} ports found.".format(type_))

    print()


def list_input_ports(api=rtmidi.API_UNSPECIFIED):
    """List available MIDI input ports.

    Optionally the RtMidi API can be passed with the ``api`` argument. If not
    it will be determined via the ``get_api_from_environment`` function.

    """
    midiin = rtmidi.MidiIn(get_api_from_environment(api))
    list_available_ports(midiio=midiin)


def list_output_ports(api=rtmidi.API_UNSPECIFIED):
    """List available MIDI output ports.

    Optionally the RtMidi API can be passed with the ``api`` argument. If not
    it will be determined via the ``get_api_from_environment`` function.

    """
    midiout = rtmidi.MidiOut(get_api_from_environment(api))
    list_available_ports(midiio=midiout)


def open_midiport(port=None, type_="input", api=rtmidi.API_UNSPECIFIED,
                  use_virtual=False, interactive=True, client_name=None,
                  port_name=None):
    """Open MIDI port for input or output and return MidiIn/MidiOut instance.

    Arguments:

    ``port``
        A MIDI port number or (substring of) a port name or ``None``.

        Available ports are enumerated starting from zero separately for input
        and output ports. If only a substring of a port name is given, the
        first matching port is used.

    ``type_``
        Must be ``"input"`` or ``"output"``. Determines whether a ``MidiIn``
        or ``MidiOut`` instance will be created and returned.

    ``api``
        Select the low-level MIDI API to use. Defaults to ``API_UNSPECIFIED``,
        The specified api will be passed to the ``get_api_from_environment``
        function and its return value will be used. If it's ``API_UNSPECIFIED``
        the first compiled-in API, which has any input resp. output ports
        available, will be used.

    ``use_virtual``
        If ``port is ``None``, should a virtual MIDI port be opened? Defaults
        to ``False``.

    ``interactive``
        If port is ``None`` or no MIDI port matching the port number or name is
        available, should the user be prompted on the console whether to open
        a virtual MIDI port (if ``use_virtual`` is ``True``) and/or with a list
        of available MIDI ports and the option to choose one? Defaults to
        ``True``.

    ``client_name``
        The name of the MIDI client passed when instantiating a `MidiIn`` or
        ``MidiOut`` object.

        See the documentation of the constructor for these classes for the
        default values and caveats and OS-dependent ideosyncracies regarding
        the client name.

    ``port_name``
        The name of the MIDI port passed to the ``open_port`` or
        ``open_virtual_port`` method of the new ``MidiIn`` or ``MidiOut``
        instance.

        See the documentation of the ``open_port`` resp. ``open_virtual_port``
        methods for the default values and caveats when wanting to change the
        port name afterwards.

    Returns:

    A two-element tuple of a new ``MidiIn`` or ``MidiOut`` instance and the
    name of the MIDI port which was opened.

    Exceptions:

    ``KeyboardInterrupt, EOFError``
        Raised when the user presses Control-C or Control-D during a console
        prompt.

    ``IOError``
        Raised when no MIDI input or output ports (depending on what was
        requested) are available.

    ``ValueError``
        Raised when an invalid port number or name is passed and
        ``interactive`` is ``False``.

    """
    midiclass_ = rtmidi.MidiIn if type_ == "input" else rtmidi.MidiOut
    log.debug("Creating %s object.", midiclass_.__name__)

    api = get_api_from_environment(api)

    midiobj = midiclass_(api, name=client_name)
    type_ = "input" if isinstance(midiobj, rtmidi.MidiIn) else "output"

    ports = midiobj.get_ports()

    if port is None:
        try:
            if (midiobj.get_current_api() != rtmidi.API_WINDOWS_MM and
                    (use_virtual or (interactive and _prompt_for_virtual(type_)))):
                if not port_name:
                    port_name = "Virtual MIDI %s" % type_

                log.info("Opening virtual MIDI %s port.", type_)
                midiobj.open_virtual_port(port_name)
                return midiobj, port_name
        except (KeyboardInterrupt, EOFError):
            del midiobj
            print('')
            raise

    if len(ports) == 0:
        del midiobj
        raise IOError("No MIDI %s ports found." % type_)
        raise IOError("No MIDI %s ports found." % type_)

    try:
        port = int(port)
    except (TypeError, ValueError):
        if isinstance(port, basestring):
            portspec = port
            for portno, name in enumerate(ports):
                if portspec in name:
                    port = portno
                    break
            else:
                log.warning("No port matching '%s' found.", portspec)
                port = None

    while interactive and (port is None or (port < 0 or port >= len(ports))):
        list_available_ports(ports)

        try:
            r = raw_input("Select MIDI %s port (Control-C to exit): " % type_)
            port = int(r)
        except (KeyboardInterrupt, EOFError):
            del midiobj
            print('')
            raise
        except (ValueError, TypeError):
            port = None

    if port is not None and (port >= 0 and port < len(ports)):
        if not port_name:
            port_name = ports[port]

        log.info("Opening MIDI %s port #%i (%s)." % (type_, port, port_name))
        midiobj.open_port(port, port_name)
        return midiobj, port_name
    else:
        raise ValueError("Invalid port.")


def open_midiinput(port=None, api=rtmidi.API_UNSPECIFIED, use_virtual=False,
                   interactive=True, client_name=None, port_name=None):
    """Open a MIDI port for input and return a MidiIn instance.

    See the ``open_midiport`` functon for information on parameters.
    """
    return open_midiport(port, "input", api, use_virtual, interactive,
                         client_name, port_name)


def open_midioutput(port=None, api=rtmidi.API_UNSPECIFIED, use_virtual=False,
                    interactive=True, client_name=None, port_name=None):
    """Open a MIDI port for output and return a MidiOut instance.

    See the ``open_midiport`` function for information on parameters.
    """
    return open_midiport(port, "output", api, use_virtual, interactive,
                         client_name, port_name)