Exemple #1
0
def _parse_port_connections(ports, out):
    if not _misc.issequence(ports):
        return {}

    connections = {}
    for n, port in enumerate(ports):
        if not _misc.issequence(port) or len(port) <= 1 or port[1] is None:
            continue
        portname = port[0]
        if port[0] is None:
            portname = _default_portname(n, out)
        connections[portname] = port[1:]
    return connections
Exemple #2
0
def _parse_port_connections(ports, out):
    if not _misc.issequence(ports):
        return {}

    connections = {}
    for n, port in enumerate(ports):
        if not _misc.issequence(port) or len(port) <= 1 or port[1] is None:
            continue
        portname = port[0]
        if port[0] is None:
            portname = _default_portname(n, out)
        connections[portname] = port[1:]
    return connections
Exemple #3
0
def _parse_portnames(ports, out):
    if not _misc.issequence(ports):
        return [_default_portname(n, out) for n in range(ports)]

    portnames = []
    for n, port in enumerate(ports):
        if _misc.issequence(port):
            if port[0] is None:
                portnames.append(_default_portname(n, out))
            else:
                portnames.append(port[0])
        else:
            portnames.append(port)
    return portnames
Exemple #4
0
def _parse_portnames(ports, out):
    if not _misc.issequence(ports):
        return [_default_portname(n, out) for n in range(ports)]

    portnames = []
    for n, port in enumerate(ports):
        if _misc.issequence(port):
            if port[0] is None:
                portnames.append(_default_portname(n, out))
            else:
                portnames.append(port[0])
        else:
            portnames.append(port)
    return portnames
Exemple #5
0
 def __call__(self, arg):
     if not misc.issequence(arg):
         raise TypeError("not a sequence")
     try:
         t = type(arg) if not isinstance(arg, types.GeneratorType) else list
         return t(self.what(value) for value in arg)
     except (TypeError, ValueError) as ex:
         raise type(ex)("illegal item in sequence: %s" % str(ex))
Exemple #6
0
 def __call__(self, arg):
     if not misc.issequence(arg):
         raise TypeError("not a sequence")
     try:
         t = type(arg) if not isinstance(arg, types.GeneratorType) else list
         return t(self.what(value) for value in arg)
     except (TypeError, ValueError) as ex:
         raise type(ex)("illegal item in sequence: %s" % str(ex))
Exemple #7
0
 def __call__(self, arg):
     if not misc.issequence(arg):
         raise TypeError("not a sequence")
     if len(arg) != len(self.what):
         raise ValueError("expected sequence of %d items, got %d" %
                          (len(self.what), len(arg)))
     try:
         t = type(arg) if not isinstance(arg, types.GeneratorType) else list
         return t(what(value) for what, value in zip(self.what, arg))
     except (TypeError, ValueError) as ex:
         raise type(ex)("illegal item in sequence: %s" % str(ex))
Exemple #8
0
 def __call__(self, arg):
     if not misc.issequence(arg):
         raise TypeError("not a sequence")
     if len(arg) != len(self.what):
         raise ValueError("expected sequence of %d items, got %d" %
                          (len(self.what), len(arg)))
     try:
         t = type(arg) if not isinstance(arg, types.GeneratorType) else list
         return t(what(value) for what, value in zip(self.what, arg))
     except (TypeError, ValueError) as ex:
         raise type(ex)("illegal item in sequence: %s" % str(ex))
Exemple #9
0
def sysex_manufacturer(manufacturer):
    if not _misc.issequence(manufacturer, True):
        manufacturer = [manufacturer]
    manid = sysex_to_sequence(manufacturer)
    if len(manid) not in (1, 3):
        raise ValueError("manufacturer id must be either one or three bytes")
    elif len(manid) == 3 and manid[0] != 0x00:
        raise ValueError("three-byte manufacturer id must"
                         " start with null byte")
    elif any(c > 0x7f for c in manid):
        raise ValueError("manufacturer id out of range")
    return manid
Exemple #10
0
def sysex_manufacturer(manufacturer):
    if not _misc.issequence(manufacturer, True):
        manufacturer = [manufacturer]
    manid = sysex_to_sequence(manufacturer)
    if len(manid) not in (1, 3):
        raise ValueError("manufacturer id must be either one or three bytes")
    elif len(manid) == 3 and manid[0] != 0x00:
        raise ValueError("three-byte manufacturer id must"
                         " start with null byte")
    elif any(c > 0x7f for c in manid):
        raise ValueError("manufacturer id out of range")
    return manid
Exemple #11
0
def sysex_manufacturer(manufacturer):
    if not _misc.issequence(manufacturer, True):
        manufacturer = [manufacturer]
    manid = sysex_to_bytearray(manufacturer)
    if len(manid) not in (1, 3):
        raise ValueError("manufacturer id must be either one or three bytes")
    elif len(manid) == 3 and manid[0] != 0x00:
        raise ValueError("three-byte manufacturer id must start with 0x00")
    else:
        for c in manid:
            if c > 0x7f:
                raise ValueError("manufacturer id byte %#x is out of range" % c)
    return manid
Exemple #12
0
def sysex_manufacturer(manufacturer):
    if not _misc.issequence(manufacturer, True):
        manufacturer = [manufacturer]
    manid = sysex_to_bytearray(manufacturer)
    if len(manid) not in (1, 3):
        raise ValueError("manufacturer id must be either one or three bytes")
    elif len(manid) == 3 and manid[0] != 0x00:
        raise ValueError("three-byte manufacturer id must start with 0x00")
    else:
        for c in manid:
            if c > 0x7f:
                raise ValueError("manufacturer id byte %#x is out of range" %
                                 c)
    return manid
Exemple #13
0
 def _parse_scene_number(self, number):
     if number in self._scenes:
         # single scene number, no subscene
         return (_util.actual(number), -1)
     elif (_misc.issequence(number) and len(number) > 1
           and number[0] in self._scenes):
         # scene/subscene numbers as tuple...
         if _util.actual(number[1]) < len(self._scenes[number[0]][1]):
             # both scene and subscene numbers are valid
             return (_util.actual(number[0]), _util.actual(number[1]))
         # subscene number is invalid
         return (_util.actual(number[0]), -1)
     # no such scene
     return (-1, -1)
Exemple #14
0
 def _parse_scene_number(self, number):
     if number in self._scenes:
         # single scene number, no subscene
         return (_util.actual(number), -1)
     elif (_misc.issequence(number) and
             len(number) > 1 and number[0] in self._scenes):
         # scene/subscene numbers as tuple...
         if _util.actual(number[1]) < len(self._scenes[number[0]][1]):
             # both scene and subscene numbers are valid
             return (_util.actual(number[0]), _util.actual(number[1]))
         # subscene number is invalid
         return (_util.actual(number[0]), -1)
     # no such scene
     return (-1, -1)
Exemple #15
0
    def make_event(self, *args, **kwargs):
        """
        Create a new MIDI event. Attributes can be specified in args or
        kwargs, unspecified attributes are filled with random values.
        """
        type, port, channel, data1, data2, sysex = \
            itertools.islice(itertools.chain(args, itertools.repeat(None)), 6)

        for k, v in kwargs.items():
            if k == 'type': type = v
            if k == 'port': port = v
            elif k == 'channel': channel = v
            elif k in ('data1', 'note', 'ctrl'): data1 = v
            elif k in ('data2', 'velocity', 'value'): data2 = v
            elif k == 'program': data2 = v - setup.get_config('data_offset')
            elif k == 'sysex': sysex = v

        if type is None:
            if channel is None:
                type = random.choice(
                    list(set(constants._EVENT_TYPES.values()) - set([DUMMY])))
            else:
                type = random.choice([
                    NOTEON, NOTEOFF, CTRL, PITCHBEND, AFTERTOUCH,
                    POLY_AFTERTOUCH, PROGRAM
                ])
        elif type == NOTE:
            type = random.choice([NOTEON, NOTEOFF])
        elif misc.issequence(type):
            type = random.choice(type)

        if port is None:
            port = random.randrange(0, 42) + setup.get_config('data_offset')
        if channel is None:
            channel = random.randrange(0, 16) + setup.get_config('data_offset')
        if data1 is None:
            data1 = random.randrange(0, 128)
        if data2 is None:
            data2 = (random.randrange(1, 128) if type == NOTEON else
                     0 if type == NOTEOFF else random.randrange(0, 128))

        if type == SYSEX and sysex is None:
            sysex = [0xf0] + [
                random.randrange(0, 128) for n in range(random.randrange(1024))
            ] + [0xf7]

        return MidiEvent(type, port, channel, data1, data2, sysex)
Exemple #16
0
 def _run_scenes_impl(self, scenes, events):
     # set up a dummy engine
     setup._config_impl(backend='dummy')
     e = engine.Engine()
     e.setup(scenes, None, None, None)
     r = []
     # allow input to be a single event, as well as a sequence of events
     if not misc.issequence(events):
         events = [events]
     # process each event, append each list of output events to the
     # returned list of lists
     for ev in events:
         ret = e.process_event(ev)[:]
         for rev in ret:
             rev.__class__ = MidiEvent
         r.append(ret)
     return r
Exemple #17
0
 def _run_scenes_impl(self, scenes, events):
     # set up a dummy engine
     setup._config_impl(backend='dummy')
     e = engine.Engine()
     e.setup(scenes, None, None, None)
     r = []
     # allow input to be a single event, as well as a sequence of events
     if not misc.issequence(events):
         events = [events]
     # process each event, append each list of output events to the
     # returned list of lists
     for ev in events:
         ret = e.process_event(ev)[:]
         for rev in ret:
             rev.__class__ = MidiEvent
         r.append(ret)
     return r
Exemple #18
0
    def make_event(self, *args, **kwargs):
        """
        Create a new MIDI event. Attributes can be specified in args or
        kwargs, unspecified attributes are filled with random values.
        """
        type, port, channel, data1, data2, sysex = \
            itertools.islice(itertools.chain(args, itertools.repeat(None)), 6)

        for k, v in kwargs.items():
            if k == 'type': type = v
            if k == 'port': port = v
            elif k == 'channel': channel = v
            elif k in ('data1', 'note', 'ctrl'): data1 = v
            elif k in ('data2', 'velocity', 'value'): data2 = v
            elif k == 'program': data2 = v - setup.get_config('data_offset')
            elif k == 'sysex': sysex = v

        if type is None:
            if channel is None:
                type = random.choice(list(set(constants._EVENT_TYPES.values())
                                        - set([DUMMY])))
            else:
                type = random.choice([NOTEON, NOTEOFF, CTRL, PITCHBEND,
                                      AFTERTOUCH, POLY_AFTERTOUCH, PROGRAM])
        elif type == NOTE:
            type = random.choice([NOTEON, NOTEOFF])
        elif misc.issequence(type):
            type = random.choice(type)

        if port is None:
            port = random.randrange(0, 42) + setup.get_config('data_offset')
        if channel is None:
            channel = random.randrange(0, 16) + setup.get_config('data_offset')
        if data1 is None:
            data1 = random.randrange(0, 128)
        if data2 is None:
            data2 = (random.randrange(1, 128) if type == NOTEON
                     else 0 if type == NOTEOFF
                     else random.randrange(0, 128))

        if type == SYSEX and sysex is None:
            sysex = [0xf0] + [random.randrange(0, 128)
                              for n in range(random.randrange(1024))] + [0xf7]

        return MidiEvent(type, port, channel, data1, data2, sysex)
Exemple #19
0
        def do_call(ev):
            # add additional properties that don't exist on the C++ side
            ev.__class__ = _event.MidiEvent

            # call the function
            ret = function(ev)

            if ret is None or async:
                return None
            elif isinstance(ret, _types.GeneratorType):
                # function is a generator, build list
                ret = list(ret)
            elif not _misc.issequence(ret):
                ret = [ret]

            for ev in ret:
                ev._finalize()
            return ret
Exemple #20
0
        def do_call(ev):
            # add additional properties that don't exist on the C++ side
            ev.__class__ = _event.MidiEvent

            # call the function
            ret = function(ev)

            if ret is None or async:
                return None
            elif isinstance(ret, _types.GeneratorType):
                # function is a generator, build list
                ret = list(ret)
            elif not _misc.issequence(ret):
                ret = [ret]

            for ev in ret:
                ev._finalize()
            return ret
Exemple #21
0
def Harmonize(tonic, scale, interval, non_harmonic='below'):
    """
     A diatonic harmonizer.

    :param tonic:
        The tonic of the scale, as a note name.

    :param scale:
        The type/mode, of the scale, one of:
        ``'major'``, ``'minor'``, ``'minor_harmonic'``, ``'ionian'``,
        ``'dorian'``, ``'phrygian'``, ``'lydian'``, ``'mixolydian'``,
        ``'aeolian'``, ``'locrian'``.

    :param interval:
        The number of steps to transpose the notes by
        (as an integer), or one of these interval names:
        ``'unison'``, ``'second'``, ``'third'``, ``'fourth'``, ``'fifth'``,
        ``'sixth'``, ``'seventh'``, ``'octave'``, ``'ninth'``, ``'tenth'``,
        ``'eleventh'``, ``'twelfth'``, ``'thirteenth'``.

        It is also possible to pass a list of intervals, to create
        multiple harmonized voices.

    :param non_harmonic: What to do with out-of-scale notes:

        - ``'below'``: Transpose by the same interval as the next on-scale
        - ``'above'``: Transpose by the same interval as the next on-scale
        - ``'skip'``: Ignore note.
        - ``'same'``: Output note as is, without transposing it.
    """
    t = _util.tonic_note_number(tonic)

    if _misc.issequence(scale):
        shift = 0
    elif isinstance(scale, str):
        if scale == 'major':
            scale = _MAJOR_SCALE
            shift = 0
        elif scale == 'minor':
            scale = _MAJOR_SCALE
            shift = 5
        elif scale == 'minor_harmonic':
            scale = _HARMONIC_MINOR_SCALE
            shift = 0
        elif scale in _MODES:
            shift = _MODES.index(scale)
            scale = _MAJOR_SCALE

    # shift scale to the correct mode
    s = ([x - scale[shift] for x in scale[shift:]] +
         [x + 12 - scale[shift] for x in scale[:shift]])

    if not _misc.issequence(interval):
        interval = [interval]

    # convert all interval names to numbers
    iv = [(_INTERVALS.index(x) if x in _INTERVALS else x) for x in interval]

    # python version:
#    f = [ _m.Process(_Harmonizer(t, s, i, non_harmonic)) for i in iv ]

    # pure mididings version:
    f = []
    for i in iv:
        h = _Harmonizer(t, s, i, non_harmonic)
        # get offset for each key
        offsets = [(x, h.note_offset(x)) for x in range(128)]
        # group by offset
        groups = _itertools.groupby(sorted(offsets, key=_itemgetter(1)),
                                    key=_itemgetter(1))

        # create one KeyFilter()/Transpose() pair for each offset
        for off, keys in groups:
            if off is not None:
                f.append(_m.KeyFilter(notes=[k[0] for k in keys]) >>
                         _m.Transpose(off))

    return _m.Filter(_m.NOTE) % f
Exemple #22
0
def Harmonize(tonic, scale, interval, non_harmonic='below'):
    """
     A diatonic harmonizer.

    :param tonic:
        The tonic of the scale, as a note name.

    :param scale:
        The type/mode, of the scale, one of:
        ``'major'``, ``'minor'``, ``'minor_harmonic'``, ``'ionian'``,
        ``'dorian'``, ``'phrygian'``, ``'lydian'``, ``'mixolydian'``,
        ``'aeolian'``, ``'locrian'``.

    :param interval:
        The number of steps to transpose the notes by
        (as an integer), or one of these interval names:
        ``'unison'``, ``'second'``, ``'third'``, ``'fourth'``, ``'fifth'``,
        ``'sixth'``, ``'seventh'``, ``'octave'``, ``'ninth'``, ``'tenth'``,
        ``'eleventh'``, ``'twelfth'``, ``'thirteenth'``.

        It is also possible to pass a list of intervals, to create
        multiple harmonized voices.

    :param non_harmonic: What to do with out-of-scale notes:

        - ``'below'``: Transpose by the same interval as the next on-scale
        - ``'above'``: Transpose by the same interval as the next on-scale
        - ``'skip'``: Ignore note.
        - ``'same'``: Output note as is, without transposing it.
    """
    t = _util.tonic_note_number(tonic)

    if _misc.issequence(scale):
        shift = 0
    elif isinstance(scale, str):
        if scale == 'major':
            scale = _MAJOR_SCALE
            shift = 0
        elif scale == 'minor':
            scale = _MAJOR_SCALE
            shift = 5
        elif scale == 'minor_harmonic':
            scale = _HARMONIC_MINOR_SCALE
            shift = 0
        elif scale in _MODES:
            shift = _MODES.index(scale)
            scale = _MAJOR_SCALE

    # shift scale to the correct mode
    s = ([x - scale[shift] for x in scale[shift:]] +
         [x + 12 - scale[shift] for x in scale[:shift]])

    if not _misc.issequence(interval):
        interval = [interval]

    # convert all interval names to numbers
    iv = [(_INTERVALS.index(x) if x in _INTERVALS else x) for x in interval]

    # python version:
    #    f = [ _m.Process(_Harmonizer(t, s, i, non_harmonic)) for i in iv ]

    # pure mididings version:
    f = []
    for i in iv:
        h = _Harmonizer(t, s, i, non_harmonic)
        # get offset for each key
        offsets = [(x, h.note_offset(x)) for x in range(128)]
        # group by offset
        groups = _itertools.groupby(sorted(offsets, key=_itemgetter(1)),
                                    key=_itemgetter(1))

        # create one KeyFilter()/Transpose() pair for each offset
        for off, keys in groups:
            if off is not None:
                f.append(
                    _m.KeyFilter(notes=[k[0]
                                        for k in keys]) >> _m.Transpose(off))

    return _m.Filter(_m.NOTE) % f
Exemple #23
0
 def __init__(self, port=56418, notify_ports=[56419]):
     self.port = port
     if _misc.issequence(notify_ports):
         self.notify_ports = notify_ports
     else:
         self.notify_ports = [notify_ports]
Exemple #24
0
 def __init__(self, port=56418, notify_ports=[56419]):
     self.port = port
     if _misc.issequence(notify_ports):
         self.notify_ports = notify_ports
     else:
         self.notify_ports = [notify_ports]