|
- # -*- coding: utf-8 -*-
-
- import rtmidi
- import random
-
- # ------------------------------------------------------------------------------
-
- class Midi:
- InvalidType = 0x00 # For notifying errors
- NoteOff = 0x80 # Note Off
- NoteOn = 0x90 # Note On
- AfterTouchPoly = 0xA0 # Polyphonic AfterTouch
- ControlChange = 0xB0 # Control Change / Channel Mode
- ProgramChange = 0xC0 # Program Change
- AfterTouchChannel = 0xD0 # Channel (monophonic) AfterTouch
- PitchBend = 0xE0 # Pitch Bend
- SystemExclusive = 0xF0 # System Exclusive
- TimeCodeQuarterFrame = 0xF1 # System Common - MIDI Time Code Quarter Frame
- SongPosition = 0xF2 # System Common - Song Position Pointer
- SongSelect = 0xF3 # System Common - Song Select
- TuneRequest = 0xF6 # System Common - Tune Request
- Clock = 0xF8 # System Real Time - Timing Clock
- Start = 0xFA # System Real Time - Start
- Continue = 0xFB # System Real Time - Continue
- Stop = 0xFC # System Real Time - Stop
- ActiveSensing = 0xFE # System Real Time - Active Sensing
- SystemReset = 0xFF # System Real Time - System Reset
-
- @staticmethod
- def getChannel(statusByte):
- return statusByte & 0x0f;
-
- @staticmethod
- def getType(statusByte):
- if statusByte >= 0xf0:
- # System messages
- return statusByte
- else:
- # Channel messages
- return statusByte & 0xf0;
-
-
- # ------------------------------------------------------------------------------
-
- class MidiInterface:
- def __init__(self, listenerCallback = None):
- self.input = rtmidi.MidiIn()
- self.output = rtmidi.MidiOut()
- self.listenerCallback = listenerCallback
- self.ports = self.getAvailablePorts()
- self.port = self.connect(self.choosePorts())
-
- # --------------------------------------------------------------------------
-
- def handleMidiInput(self, message, timestamp):
- midiData = message[0]
- if self.listenerCallback:
- self.listenerCallback(midiData)
-
- def send(self, message):
- print('Sending', message)
- self.output.send_message(message)
-
- # --------------------------------------------------------------------------
-
- def getAvailablePorts(self):
- return {
- 'input' : self.input.get_ports(),
- 'output': self.output.get_ports(),
- }
-
- def choosePorts(self):
- return {
- 'input' : self.choosePort(self.ports['input'], 'input'),
- 'output': self.choosePort(self.ports['output'], 'output')
- }
-
- def choosePort(self, ports, direction):
- if not ports:
- print('No MIDI ports available, bailing out.')
- return None
-
- if len(ports) == 1:
- return {
- 'id': 0,
- 'name': ports[0]
- }
-
- else:
- # Give a choice
- print('Multiple %s ports available, please make a choice:' % direction)
- choices = dict()
- for port, i in zip(ports, range(0, len(ports))):
- choices[i] = port
- print(' [%d]' % i, port)
- choiceIndex = int(input('-> '))
- return {
- 'id': choiceIndex,
- 'name': choices[choiceIndex]
- }
-
- # --------------------------------------------------------------------------
-
- def connect(self, ports):
- if not ports:
- return None
-
- print('Connecting input to %s' % ports['input']['name'])
- print('Connecting output to %s' % ports['output']['name'])
-
- self.input.set_callback(self.handleMidiInput)
- self.input.open_port(ports['input']['id'])
- self.output.open_port(ports['output']['id'])
- return ports
|