コード例 #1
0
ファイル: main.py プロジェクト: Autotonic/m2k
class M2K:
    def __init__(self):
        self.config_path = Path().cwd() / "m2k.json"
        self.table: dict = {}
        self.midi = RtMidiIn()
        self.keyboard = Controller()

    def set_config(self) -> NoReturn:
        with open(str(self.config_path), "r") as j:
            self.table = json.load(j)

    def update_config(self, update: dict) -> NoReturn:
        with open(str(self.config_path), "w") as new:
            new.write(json.dumps(update))
        self.set_config()

    def send_key(self, midi_message) -> NoReturn:
        key = midi_message.getMidiNoteName(midi_message.getNoteNumber())
        if key not in self.table:
            return
        if midi_message.isNoteOn():
            self.keyboard.press(self.table[key])
        elif midi_message.isNoteOff():
            self.keyboard.release(self.table[key])

    def run(self) -> NoReturn:
        ports = range(self.midi.getPortCount())
        if ports:
            print("Running")
            self.midi.openPort(1)
            while True:
                if midi_message := self.midi.getMessage(0):
                    self.send_key(midi_message)
コード例 #2
0
 def __init__(self, usb_device_name, app):
     self._log = logging.getLogger(__name__)
     self._midi_in, self._midi_out = RtMidiIn(), RtMidiOut()
     self._connect_midi(usb_device_name)
     self._midi_in.setCallback(self._midi_message_cb)
     self._app = app
     self.enabled = True
コード例 #3
0
ファイル: listen.py プロジェクト: richgong/midi-warp
 def __init__(self, port_index):
     self.device = RtMidiIn()
     self.device_name = self.device.getPortName(port_index)
     print("[Device] Input:", self.device_name)
     self.device.openPort(port_index)
     self.device.ignoreTypes(False, True, False) # midiSysex, midiTime, midiSense
     self.device.setCallback(self.on_message)
コード例 #4
0
ファイル: test_rtmidi.py プロジェクト: patrickkidd/pyrtmidi
    def test_transmission(self):
        import multiprocessing as mp
        if hasattr(mp, 'set_start_method'):
            mp.set_start_method('spawn')

        iq = mp.Queue()
        oq = mp.Queue()
        portName = 'TestVirtualPorts.%i' % time.time()
        senderProc = mp.Process(target=SenderProc, args=(oq, iq, portName))
        senderProc.start()

        # handshake
        self.assertEqual(iq.get(), 'init')  # virtual midi port is now open

        # Supposedly you can't just open a virtual port by name from
        # within the same proc or proc group? Anyway opening by index
        # works.
        device = RtMidiIn()
        for i in range(device.getPortCount()):
            if device.getPortName(i) == portName:
                device.openPort(i)
                break
        self.assertTrue(device.isPortOpen())

        # collect messages and print progress
        self.messages = []
        self.last_s = ''

        def put(m):
            self.messages.append(m)
            if len(self.messages) % 10 == 0:
                sys.stdout.write('\b' * len(self.last_s))  # backspace
                self.last_s = '%s: Received message %i / 32640' % (__name__, len(self.messages))
                sys.stdout.write(self.last_s)
                # sys.stdout.write('.')
                sys.stdout.flush()

        oq.put('start')
        for i in range(128):
            for j in range(1, 128):
                msg = device.getMessage(1000)
                self.assertTrue(msg is not None)
                self.assertTrue(msg.isNoteOn())
                self.assertEqual(msg.getNoteNumber(), i)
                self.assertEqual(msg.getVelocity(), j)
                put(msg)
                oq.put('next')

        for i in range(128):
            for j in range(128):
                msg = device.getMessage(1000)
                self.assertTrue(msg is not None)
                self.assertTrue(msg.isController())
                self.assertEqual(msg.getControllerNumber(), i)
                self.assertEqual(msg.getControllerValue(), j)
                put(msg)
                oq.put('next')

        self.assertEqual(len(self.messages), 32640)
        oq.put('done')
コード例 #5
0
ファイル: footpedal.py プロジェクト: tobiw/pymusicduino
    def __init__(self, midi_controller):
        self._midi_in, self._midi_out = RtMidiIn(), RtMidiOut()
        self._connect_midi(midi_controller)
        self._midi_in.setCallback(self._midi_message_cb)
        self._osc_client = udp_client.SimpleUDPClient('127.0.0.1', 5005)
        self._osc_client.send_message('/ping', '1')

        # This part needs to be configurable per mode/user config/DIP switches/etc
        # At the moment, Arduino Micro MIDI device should do:
        # --------------
        # | 5  6  7  8 |
        # | 1  2  3  4 |
        # --------------
        #    Press         Press         Press         Long
        #    Preset        Stomp         Looper        Press
        #    Mode          Mode          Mode
        # 1) Preset 1[10]  Stomp1En[20]  Undo[30]     PresetMod[40]
        # 2) Preset 2[11]  Stomp2En[21]  Record[31]   StompMode[41]
        # 3) Preset 3[12]  Stomp3En[22]  Overdub[32]  LooperMod[42]
        # 4) Preset 4[13]  Stomp4En[23]               Tuner[43]
        # 5) Stomp1En[14]  Stomp5En[24]               Stomp1Sel[44]
        # 6) Stomp2En[15]  Stomp6En[25]               Stomp2Sel[45]
        # 7) Stomp3En[16]  Stomp7En[26]               Stomp3Sel[46]
        # 8) Stomp4En[17]  TapTempo[27]               Stomp4Sel[47]
        self._cc_osc_translation = {
            # Presets
            10: '/preset/1', 11: '/preset/2', 12: '/preset/3', 13: '/preset/4',
            14: '/stomp/1/enable', 15: '/stomp/2/enable', 16: '/stomp/3/enable', 17: '/stomp/4/enable',

            # Stompboxes
            20: '/stomp/1/enable', 21: '/stomp/2/enable', 22: '/stomp/3/enable', 23: '/stomp/4/enable',
            24: '/stomp/5/enable', 25: '/stomp/6/enable', 26: '/stomp/7/enable', 27: '/stomp/8/enable',

            # Looper
            30: '/looper/undo', 31: '/looper/record', 32: '/looper/overdub', 33: '/looper/mute_trigger',
            34: '/looper/redo', 35: '/looper/insert', 36: '/looper/multiply', 37: '/looper/pause',

            # Metronome
            40: '/metronome/pause', 41: '/metronome/dec_bpm', 42: '/metronome/inc_bpm', 43: '/metronome/tap',
            44: '', 45: '', 46: '', 47: '',

            # Long press
            100: '/mode/preset', 101: '/mode/stomp', 102: '/mode/looper', 103: '/mode/metronome',
            104: '/stomp/1/select', 105: '/stomp/2/select', 106: '/stomp/3/select', 107: '/stomp/4/select'
        }
コード例 #6
0
ファイル: listen.py プロジェクト: richgong/midi-warp
class Reader:
    def __init__(self, port_index):
        self.device = RtMidiIn()
        self.device_name = self.device.getPortName(port_index)
        print("[Device] Input:", self.device_name)
        self.device.openPort(port_index)
        self.device.ignoreTypes(False, True, False) # midiSysex, midiTime, midiSense
        self.device.setCallback(self.on_message)

    def on_message(self, msg):
        try:
            channel = msg.getChannel()
            if msg.isNoteOn():
                note = msg.getNoteNumber()
                print(f'[{self.device_name}] ch={channel} n={note}/{msg.getMidiNoteName(note)} v={msg.getVelocity()}')
            elif msg.isNoteOff():
                note = msg.getNoteNumber()
                print(f'[{self.device_name}] ch={channel} n={note}/{msg.getMidiNoteName(note)} v=0')
            elif msg.isController():
                print(f'[{self.device_name}] ch={channel} cc={msg.getControllerNumber()} v={msg.getControllerValue()}')
            else:
                print(f'[{self.device_name}] other: {msg}')
            if msg.isController():
                cc = msg.getControllerNumber()
                v = msg.getControllerValue()
                if cc == 64 and self.device_name != VIRTUAL_OUTPUT_NAME:
                    if v > 0:
                        smart_start(send_midi=None)
                    else:
                        smart_stop(send_midi=None)

        except Exception as e:
            logging.exception(e)
コード例 #7
0
class MidiReceiver:
    """
    Handles incoming MIDI messages from attached controllers or instruments.

    Incoming messages can be remapped to other MIDI events, OSC, or trigger
    events inside the app.
    """
    def __init__(self, usb_device_name, app):
        self._log = logging.getLogger(__name__)
        self._midi_in, self._midi_out = RtMidiIn(), RtMidiOut()
        self._connect_midi(usb_device_name)
        self._midi_in.setCallback(self._midi_message_cb)
        self._app = app
        self.enabled = True

    def _connect_midi(self, usb_device_name):
        def find_port(ports, name):
            for i, p in enumerate(ports):
                if p.startswith(name):
                    return i
            return None

        # Find the MIDI In port
        port = find_port([self._midi_in.getPortName(i) for i in range(self._midi_in.getPortCount())], usb_device_name)
        if port is None:
            raise ValueError('Could not find "{}" MIDI port'.format(usb_device_name))

        self._log.info("MidiIn connecting to {}".format(port))
        self._midi_in.openPort(port)

        # Find the MIDI Out port
        port = find_port([self._midi_out.getPortName(i) for i in range(self._midi_out.getPortCount())], usb_device_name)
        assert port is not None
        self._log.info("MidiOut connecting to {}".format(port))
        self._midi_out.openPort(port)

    def _midi_message_cb(self, msg):
        if not self.enabled:
            return

        ch = msg.getChannel()
        cc = msg.getControllerNumber()

        self._log.debug('Received MIDI message: {} {}'.format(ch, cc))

        # Mapping (channel, cc, value) to event
        self._mapping = [
            # single click
            MidiMapping(channel=2, cc=10, event_target=MidiMapping.EVENT_TARGET_MIDI_LOOP, payload=1),  # toggle loop 1
            # MidiMapping(channel=2, cc=11, event_target=MidiMapping.EVENT_TARGET_DRUMS, payload=1),  # play drums
            # MidiMapping(channel=2, cc=12, event_target=MidiMapping.EVENT_TARGET_LOOPER, payload='record'),  # record
            # MidiMapping(channel=2, cc=13, event_target=MidiMapping.EVENT_TARGET_LOOPER, payload='stop'),  # stop
            MidiMapping(channel=2, cc=14, event_target=MidiMapping.EVENT_TARGET_PRESET, payload=0),  # switch loops off
            MidiMapping(channel=2, cc=15, event_target=MidiMapping.EVENT_TARGET_PRESET, payload=1),  # switch to preset 1
            MidiMapping(channel=2, cc=16, event_target=MidiMapping.EVENT_TARGET_PRESET, payload=2),  # switch to preset 2
            MidiMapping(channel=2, cc=17, event_target=MidiMapping.EVENT_TARGET_PRESET, payload=3),  # switch to preset 3

            # long click
        ]

        def find_mapping(ch_, cc_):
            for m in self._mapping:
                if m.channel == ch_ and m.cc == cc_:
                    return m

        m = find_mapping(ch, cc)
        if m:
            self._log.info('Sending event {}:{}'.format(m.event_target, m.payload))
            self._app.send_event(m.event_target, m.payload)
コード例 #8
0
    def test_transmission(self):
        import multiprocessing as mp
        if hasattr(mp, 'set_start_method'):
            mp.set_start_method('spawn')

        iq = mp.Queue()
        oq = mp.Queue()
        portName = 'TestVirtualPorts.%i' % time.time()
        senderProc = mp.Process(target=SenderProc, args=(oq, iq, portName))
        senderProc.start()

        # handshake
        self.assertEqual(iq.get(), 'init')  # virtual midi port is now open

        # Supposedly you can't just open a virtual port by name from
        # within the same proc or proc group? Anyway opening by index
        # works.
        device = RtMidiIn()
        for i in range(device.getPortCount()):
            if device.getPortName(i) == portName:
                device.openPort(i)
                break
        self.assertTrue(device.isPortOpen())

        # collect messages and print progress
        self.messages = []
        self.last_s = ''

        def put(m):
            self.messages.append(m)
            if len(self.messages) % 10 == 0:
                sys.stdout.write('\b' * len(self.last_s))  # backspace
                self.last_s = '%s: Received message %i / 32640' % (
                    __name__, len(self.messages))
                sys.stdout.write(self.last_s)
                # sys.stdout.write('.')
                sys.stdout.flush()

        oq.put('start')
        for i in range(128):
            for j in range(1, 128):
                msg = device.getMessage(1000)
                self.assertTrue(msg is not None)
                self.assertTrue(msg.isNoteOn())
                self.assertEqual(msg.getNoteNumber(), i)
                self.assertEqual(msg.getVelocity(), j)
                put(msg)
                oq.put('next')

        for i in range(128):
            for j in range(128):
                msg = device.getMessage(1000)
                self.assertTrue(msg is not None)
                self.assertTrue(msg.isController())
                self.assertEqual(msg.getControllerNumber(), i)
                self.assertEqual(msg.getControllerValue(), j)
                put(msg)
                oq.put('next')

        self.assertEqual(len(self.messages), 32640)
        oq.put('done')
コード例 #9
0
# /Users/macbook/miniconda3/envs/AIP/bin/pip install rtmidi
from rtmidi import MidiMessage, RtMidiIn, RtMidiOut
import time
import midi_tools

midiout = RtMidiOut()
midiout.openPort(2)

midiin = RtMidiIn()
midiin.openPort(2)

midi_tools.print_ports(midiin)
midi_tools.print_ports(midiout)


class MidiConnection:
    def __init__(self, _channel, _DEBUG=False, _port=0):
        self.port = _port
        self.channel = _channel
        self.DEBUG = _DEBUG

    def output(self, m):
        midiout.sendMessage(m)
        if (self.DEBUG):
            midi_tools.print_message(m)

    def sendNoteSignal(self, note, vel, wait=.1):
        m = MidiMessage.noteOn(self.channel, note, vel)
        self.output(m)
        time.sleep(wait)
        m = MidiMessage.noteOff(self.channel, note)
コード例 #10
0
ファイル: footpedal.py プロジェクト: tobiw/pymusicduino
class MidiToOsc:
    """
    Translates MIDI messages from a controller to OSC messages for the main program.

    Sets up MIDI and OSC connects, then everything is handled through a callback.
    Uses ALSA/RtMidi to receive MIDI messages. Assumes the OSC server is on localhost at the default port.
    """
    def __init__(self, midi_controller):
        self._midi_in, self._midi_out = RtMidiIn(), RtMidiOut()
        self._connect_midi(midi_controller)
        self._midi_in.setCallback(self._midi_message_cb)
        self._osc_client = udp_client.SimpleUDPClient('127.0.0.1', 5005)
        self._osc_client.send_message('/ping', '1')

        # This part needs to be configurable per mode/user config/DIP switches/etc
        # At the moment, Arduino Micro MIDI device should do:
        # --------------
        # | 5  6  7  8 |
        # | 1  2  3  4 |
        # --------------
        #    Press         Press         Press         Long
        #    Preset        Stomp         Looper        Press
        #    Mode          Mode          Mode
        # 1) Preset 1[10]  Stomp1En[20]  Undo[30]     PresetMod[40]
        # 2) Preset 2[11]  Stomp2En[21]  Record[31]   StompMode[41]
        # 3) Preset 3[12]  Stomp3En[22]  Overdub[32]  LooperMod[42]
        # 4) Preset 4[13]  Stomp4En[23]               Tuner[43]
        # 5) Stomp1En[14]  Stomp5En[24]               Stomp1Sel[44]
        # 6) Stomp2En[15]  Stomp6En[25]               Stomp2Sel[45]
        # 7) Stomp3En[16]  Stomp7En[26]               Stomp3Sel[46]
        # 8) Stomp4En[17]  TapTempo[27]               Stomp4Sel[47]
        self._cc_osc_translation = {
            # Presets
            10: '/preset/1', 11: '/preset/2', 12: '/preset/3', 13: '/preset/4',
            14: '/stomp/1/enable', 15: '/stomp/2/enable', 16: '/stomp/3/enable', 17: '/stomp/4/enable',

            # Stompboxes
            20: '/stomp/1/enable', 21: '/stomp/2/enable', 22: '/stomp/3/enable', 23: '/stomp/4/enable',
            24: '/stomp/5/enable', 25: '/stomp/6/enable', 26: '/stomp/7/enable', 27: '/stomp/8/enable',

            # Looper
            30: '/looper/undo', 31: '/looper/record', 32: '/looper/overdub', 33: '/looper/mute_trigger',
            34: '/looper/redo', 35: '/looper/insert', 36: '/looper/multiply', 37: '/looper/pause',

            # Metronome
            40: '/metronome/pause', 41: '/metronome/dec_bpm', 42: '/metronome/inc_bpm', 43: '/metronome/tap',
            44: '', 45: '', 46: '', 47: '',

            # Long press
            100: '/mode/preset', 101: '/mode/stomp', 102: '/mode/looper', 103: '/mode/metronome',
            104: '/stomp/1/select', 105: '/stomp/2/select', 106: '/stomp/3/select', 107: '/stomp/4/select'
        }

    def _connect_midi(self, midi_controller):
        def find_port(ports, name):
            for i, p in enumerate(ports):
                if p.startswith(name):
                    return i
            return None

        # Find the MIDI In port the Arduino Micro is connected to
        arduino_port = find_port([self._midi_in.getPortName(i) for i in range(self._midi_in.getPortCount())], midi_controller)
        if arduino_port is None:
            raise ValueError('Could not find "Arduino Micro" MIDI port')

        print("MidiIn connecting to {}".format(arduino_port))
        self._midi_in.openPort(arduino_port)

        # Find the MIDI Out port the Arduino Micro is connected to
        arduino_port = find_port([self._midi_out.getPortName(i) for i in range(self._midi_out.getPortCount())], midi_controller)
        assert arduino_port is not None
        print("MidiOut connecting to {}".format(arduino_port))
        self._midi_out.openPort(arduino_port)

    def _midi_message_cb(self, msg):
        cc, value = msg.getControllerNumber(), msg.getControllerValue()
        osc_topic = self._cc_osc_translation.get(cc, None)
        print('{} -> {} -> {}'.format(cc, '1' if value > 0 else '0', str(osc_topic)))
        if osc_topic:
            self._osc_client.send_message(osc_topic, '1')
            print('sent.')
コード例 #11
0
ファイル: main.py プロジェクト: Autotonic/m2k
 def __init__(self):
     self.config_path = Path().cwd() / "m2k.json"
     self.table: dict = {}
     self.midi = RtMidiIn()
     self.keyboard = Controller()
コード例 #12
0
ファイル: server.py プロジェクト: pbeckman/gEcho
        print '%s: ON: ' % port, msg.getNoteNumber(), "=", msg.getMidiNoteName(
            msg.getNoteNumber()), msg.getVelocity()
    elif msg.isNoteOff():
        print '%s: OFF:' % port, msg.getNoteNumber(), "=", msg.getMidiNoteName(
            msg.getNoteNumber())
    elif msg.isController():
        print '%s: CONTROLLER' % port, msg.getControllerNumber(
        ), msg.getControllerValue()


if __name__ == '__main__':
    # increase stack size to avoid segfault
    resource.setrlimit(resource.RLIMIT_CORE,
                       (resource.RLIM_INFINITY, resource.RLIM_INFINITY))

    midi_in = RtMidiIn()
    midi_out = RtMidiOut()

    print "AVAILABLE PORTS:"
    for i in range(midi_in.getPortCount()):
        print "  ", i, midi_in.getPortName(i)

    in_port = raw_input("INPUT PORT  (1): ")
    in_port = 1 if in_port.strip() == "" else int(in_port)
    out_port = raw_input("OUTPUT PORT (0): ")
    out_port = 0 if out_port.strip() == "" else int(out_port)

    server = Server(midi_in, in_port, midi_out, out_port)
    server.start()

    print 'HIT ENTER TO EXIT'
コード例 #13
0
ファイル: listen.py プロジェクト: richgong/midi-warp
if __name__ == '__main__':
    say("Listening.")  # Shows that speech synthesis isn't blocked.
    parser = argparse.ArgumentParser(description="A MIDI/Keyboard signal router.")
    parser.add_argument('-v', '--volume', dest="volume",
                        help='Listen for volume key.', action='store_true', required=False)
    parser.add_argument('-a', '--accent', dest="accent",
                        help='Listen for accent key.', action='store_true', required=False)
    parser.add_argument('-r', '--record', dest="send_midi_record",
                        help='Send synthetic MIDI record/stop/new', action='store_true', required=False)
    parser.add_argument('-p', '--play', dest="send_midi_play",
                        help='Send synthetic MIDI play/stop', action='store_true', required=False)
    ARGS = parser.parse_args()

    #listen_to_all_keys()
    listen_to_hot_keys()

    for i in range(RtMidiIn().getPortCount()):
        Reader(i)

    fake_out = RtMidiOut()
    for i in range(fake_out.getPortCount()):
        if fake_out.getPortName(i) == VIRTUAL_OUTPUT_NAME:
            VIRTUAL_OUTPUT = Writer(i)


    while True:
        # print("HI")
        time.sleep(100)
        #gevent.sleep(1.0)
        #gevent.spawn_later(0.1, call_obs_api)