Пример #1
0
def _panic_bypass():
    # send all notes off (CC #123) and sustain off (CC #64) to all output
    # ports and on all channels
    for p in _engine.out_ports():
        for c in range(16):
            _engine.output_event(_event.CtrlEvent(p, _util.offset(c), 123, 0))
            _engine.output_event(_event.CtrlEvent(p, _util.offset(c), 64, 0))
Пример #2
0
def _panic_bypass():
    # send all notes off (CC #123) and sustain off (CC #64) to all output
    # ports and on all channels
    for p in _engine.out_ports():
        for c in range(16):
            _engine.output_event(
                _event.CtrlEvent(p, _util.offset(c), 123, 0))
            _engine.output_event(
                _event.CtrlEvent(p, _util.offset(c), 64, 0))
Пример #3
0
def Output(port=None,
           channel=None,
           program=None,
           volume=None,
           pan=None,
           expression=None,
           ctrls={}):
    """
    Output(port=None, channel=None, program=None, volume=None, pan=None, expression=None, ctrls={})

    Route incoming events to the specified *port* and *channel*.
    When switching to the scene containing this unit, a program change and/or
    arbitrary control changes can be sent.

    To send a bank select (CC #0 and CC #32) before the program change,
    *program* can be a tuple with two elements, where the first element is the
    bank number, and the second is the program number.

    Values for the commonly used controllers *volume* (#7), *pan* (#10) and
    *expression* (#11) can be specified directly. For all other controllers,
    the *ctrls* argument can contain a mapping from controller numbers to
    their respective values.

    If *port* or *channel* are ``None``, events will be routed to the first
    port/channel.
    """
    if port is None:
        port = _util.offset(0)
    if channel is None:
        channel = _util.offset(0)

    if isinstance(program, tuple):
        bank, program = program
    else:
        bank = None

    init = []

    if bank is not None:
        init.append(Ctrl(port, channel, 0, bank // 128))
        init.append(Ctrl(port, channel, 32, bank % 128))

    if program is not None:
        init.append(Program(port, channel, program))

    if volume is not None:
        init.append(Ctrl(port, channel, 7, volume))
    if pan is not None:
        init.append(Ctrl(port, channel, 10, pan))
    if expression is not None:
        init.append(Ctrl(port, channel, 11, expression))

    for k, v in ctrls.items():
        init.append(Ctrl(port, channel, k, v))

    return Fork([Init(init), Port(port) >> Channel(channel)])
Пример #4
0
def Output(port=None, channel=None, program=None,
           volume=None, pan=None, expression=None, ctrls={}):
    """
    Output(port=None, channel=None, program=None, volume=None, pan=None, expression=None, ctrls={})

    Route incoming events to the specified *port* and *channel*.
    When switching to the scene containing this unit, a program change and/or
    arbitrary control changes can be sent.

    To send a bank select (CC #0 and CC #32) before the program change,
    *program* can be a tuple with two elements, where the first element is the
    bank number, and the second is the program number.

    Values for the commonly used controllers *volume* (#7), *pan* (#10) and
    *expression* (#11) can be specified directly. For all other controllers,
    the *ctrls* argument can contain a mapping from controller numbers to
    their respective values.

    If *port* or *channel* are ``None``, events will be routed to the first
    port/channel.
    """
    if port is None:
        port = _util.offset(0)
    if channel is None:
        channel = _util.offset(0)

    if isinstance(program, tuple):
        bank, program = program
    else:
        bank = None

    init = []

    if bank is not None:
        init.append(Ctrl(port, channel, 0, bank // 128))
        init.append(Ctrl(port, channel, 32, bank % 128))

    if program is not None:
        init.append(Program(port, channel, program))

    if volume is not None:
        init.append(Ctrl(port, channel, 7, volume))
    if pan is not None:
        init.append(Ctrl(port, channel, 10, pan))
    if expression is not None:
        init.append(Ctrl(port, channel, 11, expression))

    for k, v in ctrls.items():
        init.append(Ctrl(port, channel, k, v))

    return Fork([
        Init(init),
        Port(port) >> Channel(channel)
    ])
Пример #5
0
 def next_subscene_cb(self, path, args):
     s = _engine.scenes()[_engine.current_scene()]
     n = _util.actual(_engine.current_subscene()) + 1
     if len(s[1]) and len(args) and args[0]:
         n %= len(s[1])
     if n < len(s[1]):
         _engine.switch_subscene(_util.offset(n))
Пример #6
0
 def next_subscene_cb(self, path, args):
     s = _engine.scenes()[_engine.current_scene()]
     n = _util.actual(_engine.current_subscene()) + 1
     if len(s[1]) and len(args) and args[0]:
         n %= len(s[1])
     if n < len(s[1]):
         _engine.switch_subscene(_util.offset(n))
Пример #7
0
def Panic(bypass=True):
    """
    Generate all-notes-off (CC #123) and sustain off (CC #64) events on
    all channels.

    :param bypass:
        If true, events will be sent directly on all output ports, instead
        of originating from the :func:`Panic()` unit and being subject to
        further processing.
    """
    if bypass:
        return _m.Call(lambda ev: _panic_bypass())
    else:
        return _m.Fork([(_m.Ctrl(p, _util.offset(c), 123, 0) //
                         _m.Ctrl(p, _util.offset(c), 64, 0))
                        for p in _engine.out_ports() for c in range(16)])
Пример #8
0
    def scene_switch_callback(self, scene, subscene):
        # scene and subscene parameters are the actual numbers without offset!
        if scene == -1:
            # no scene specified, use current
            scene = _mididings.Engine.current_scene(self)
        if subscene == -1:
            # no subscene specified, use first
            subscene = 0

        # save actual subscene index
        subscene_index = subscene

        # add data offset to scene/subscene numbers
        scene = _util.offset(scene)
        subscene = _util.offset(subscene)

        found = (scene in self._scenes
                 and (not subscene_index
                      or subscene_index < len(self._scenes[scene][1])))

        # get string representation of scene/subscene number
        if (subscene_index
                or (scene in self._scenes and len(self._scenes[scene][1]))):
            number = "%d.%d" % (scene, subscene)
        else:
            number = str(scene)

        if not _setup.get_config('silent'):
            if found:
                # get scene/subscene name
                scene_data = self._scenes[scene]
                if scene_data[1]:
                    name = "%s - %s" % (scene_data[0],
                                        scene_data[1][subscene_index])
                else:
                    name = scene_data[0]

                scene_desc = (("%s: %s" %
                               (number, name)) if name else str(number))
                print("switching to scene %s" % scene_desc)
            else:
                print("no such scene: %s" % number)

        if found:
            self._call_hooks('on_switch_scene', scene, subscene)
Пример #9
0
    def scene_switch_callback(self, scene, subscene):
        # scene and subscene parameters are the actual numbers without offset!
        if scene == -1:
            # no scene specified, use current
            scene = _mididings.Engine.current_scene(self)
        if subscene == -1:
            # no subscene specified, use first
            subscene = 0

        # save actual subscene index
        subscene_index = subscene

        # add data offset to scene/subscene numbers
        scene = _util.offset(scene)
        subscene = _util.offset(subscene)

        found = (scene in self._scenes and
                 (not subscene_index or
                    subscene_index < len(self._scenes[scene][1])))

        # get string representation of scene/subscene number
        if (subscene_index or
                (scene in self._scenes and len(self._scenes[scene][1]))):
            number = "%d.%d" % (scene, subscene)
        else:
            number = str(scene)

        if not _setup.get_config('silent'):
            if found:
                # get scene/subscene name
                scene_data = self._scenes[scene]
                if scene_data[1]:
                    name = "%s - %s" % (scene_data[0],
                                        scene_data[1][subscene_index])
                else:
                    name = scene_data[0]

                scene_desc = (("%s: %s" % (number, name)) if name
                                else str(number))
                print("switching to scene %s" % scene_desc)
            else:
                print("no such scene: %s" % number)

        if found:
            self._call_hooks('on_switch_scene', scene, subscene)
Пример #10
0
def Panic(bypass=True):
    """
    Generate all-notes-off (CC #123) and sustain off (CC #64) events on
    all channels.

    :param bypass:
        If true, events will be sent directly on all output ports, instead
        of originating from the :func:`Panic()` unit and being subject to
        further processing.
    """
    if bypass:
        return _m.Call(lambda ev: _panic_bypass())
    else:
        return _m.Fork([
            (_m.Ctrl(p, _util.offset(c), 123, 0) //
             _m.Ctrl(p, _util.offset(c), 64, 0))
                for p in _engine.out_ports()
                for c in range(16)
        ])
Пример #11
0
def run(patch):
    if (isinstance(patch, dict)
            and all(not isinstance(k, _constants._EventType)
                    for k in patch.keys())):
        # bypass the overload mechanism (just this once...) if there's no way
        # the given dict could be accepted as a split
        run(scenes=patch)
    else:
        e = Engine()
        e.setup({_util.offset(0): patch}, None, None, None)
        e.run()
Пример #12
0
def run(patch):
    if (isinstance(patch, dict) and
            all(not isinstance(k, _constants._EventType)
                for k in patch.keys())):
        # bypass the overload mechanism (just this once...) if there's no way
        # the given dict could be accepted as a split
        run(scenes=patch)
    else:
        e = Engine()
        e.setup({_util.offset(0): patch}, None, None, None)
        e.run()
Пример #13
0
def process_file(infile, outfile, patch):
    """
    Process a MIDI file, using pysmf.
    """
    import smf

    # create dummy engine with no inputs or outputs
    _setup._config_impl(backend='dummy')
    engine = Engine()
    engine.setup({_util.offset(0): patch}, None, None, None)

    # open input file
    smf_in = smf.SMF(infile)

    # create SMF object with same ppqn and number of tracks as input file
    smf_out = smf.SMF()
    smf_out.ppqn = smf_in.ppqn
    for n in range(len(smf_in.tracks)):
        smf_out.add_track()

    for smf_ev in smf_in.events:
        if smf_ev.midi_buffer[0] == 0xff:
            # event is metadata. copy to output unmodified
            smf_out.add_event(smf.Event(smf_ev.midi_buffer),
                              smf_ev.track_number,
                              pulses=smf_ev.time_pulses)
        else:
            ev = _mididings.buffer_to_midi_event(smf_ev.midi_buffer,
                                                 smf_ev.track_number,
                                                 smf_ev.time_pulses)

            # use base class version of process_event() to bypass calling
            # ev._finalize(), which would fail since ev is of type
            # _mididings.MidiEvent.
            for out_ev in _mididings.Engine.process_event(engine, ev):
                buf, track, pulses = _mididings.midi_event_to_buffer(out_ev)
                smf_out.add_event(smf.Event(buf), track, pulses=pulses)

    smf_out.save(outfile)
Пример #14
0
def process_file(infile, outfile, patch):
    """
    Process a MIDI file, using pysmf.
    """
    import smf

    # create dummy engine with no inputs or outputs
    _setup._config_impl(backend='dummy')
    engine = Engine()
    engine.setup({_util.offset(0): patch}, None, None, None)

    # open input file
    smf_in = smf.SMF(infile)

    # create SMF object with same ppqn and number of tracks as input file
    smf_out = smf.SMF()
    smf_out.ppqn = smf_in.ppqn
    for n in range(len(smf_in.tracks)):
        smf_out.add_track()

    for smf_ev in smf_in.events:
        if smf_ev.midi_buffer[0] == 0xff:
            # event is metadata. copy to output unmodified
            smf_out.add_event(smf.Event(smf_ev.midi_buffer),
                              smf_ev.track_number, pulses=smf_ev.time_pulses)
        else:
            ev = _mididings.buffer_to_midi_event(smf_ev.midi_buffer,
                              smf_ev.track_number, smf_ev.time_pulses)

            # use base class version of process_event() to bypass calling
            # ev._finalize(), which would fail since ev is of type
            # _mididings.MidiEvent.
            for out_ev in _mididings.Engine.process_event(engine, ev):
                buf, track, pulses = _mididings.midi_event_to_buffer(out_ev)
                smf_out.add_event(smf.Event(buf), track, pulses=pulses)

    smf_out.save(outfile)
Пример #15
0
 def current_subscene(self):
     return _util.offset(_mididings.Engine.current_subscene(self))
Пример #16
0
 def current_subscene(self):
     return _util.offset(_mididings.Engine.current_subscene(self))
Пример #17
0
 def getter(self):
     self._check_type_attribute(type, name)
     return _util.offset(getattr(self, data))
Пример #18
0
 def getter(self):
     self._check_type_attribute(type, name)
     return _util.offset(getattr(self, data))