def test_midi_in_corrupt_stream(): # A port with a valid Channel Pressure message, followed by a corrupted one, followed by # another valid one. port = PortStub( iter([ smolmidi.CHANNEL_PRESSURE, 0x64, smolmidi.CHANNEL_PRESSURE, 0x81, # 0x81 is a status byte, not a data byte smolmidi.CHANNEL_PRESSURE, 0x65, ])) midi_in = smolmidi.MidiIn(port) msg1 = midi_in.receive() assert msg1.type == smolmidi.CHANNEL_PRESSURE assert msg1.data[0] == 0x64 msg2 = midi_in.receive() assert msg2 is None msg3 = midi_in.receive() assert msg3.type == smolmidi.CHANNEL_PRESSURE assert msg3.data[0] == 0x65 assert midi_in.error_count == 1
def test_midi_in_empty(): port = PortStub(iter([])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg is None
def test_midi_in_invalid_data(): # A port with non-status leading bytes port = PortStub(iter([0x01])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg is None assert midi_in.error_count == 1
def test_midi_in_no_data(): # A port with a midi tick. port = PortStub(iter([smolmidi.TICK])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg.type == smolmidi.TICK assert msg.channel == None assert bytes(msg) == bytes([smolmidi.TICK])
def test_midi_in_one_data_byte(): # A port with a program change message. port = PortStub(iter([smolmidi.PROGRAM_CHANGE | 0x02, 0x42])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg.type == smolmidi.PROGRAM_CHANGE assert msg.channel == 0x02 assert msg.data[0] == 0x42 assert bytes(msg) == bytes([smolmidi.PROGRAM_CHANGE | 0x02, 0x42])
def test_midi_in_two_data_bytes(): # A port with a Note On message. port = PortStub(iter([smolmidi.NOTE_ON | 0x01, 0x64, 0x42])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg.type == smolmidi.NOTE_ON assert msg.channel == 0x01 assert msg.data[0] == 0x64 assert msg.data[1] == 0x42
def test_midi_in_sysex_receive(): port = PortStub( iter([ smolmidi.SYSEX, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, smolmidi.SYSEX_END ])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg.type == smolmidi.SYSEX sysex_msg, truncated = midi_in.receive_sysex(128) assert sysex_msg == bytearray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) assert not truncated
def test_midi_in_running_status(): # A port with a Note On message followed by another with running status. port = PortStub(iter([smolmidi.NOTE_ON | 0x01, 0x64, 0x42, 0x65, 0x43])) midi_in = smolmidi.MidiIn(port, enable_running_status=True) msg = midi_in.receive() assert msg.type == smolmidi.NOTE_ON assert msg.channel == 0x01 assert msg.data[0] == 0x64 assert msg.data[1] == 0x42 msg = midi_in.receive() assert msg.type == smolmidi.NOTE_ON assert msg.channel == 0x01 assert msg.data[0] == 0x65 assert msg.data[1] == 0x43
def test_midi_sysex_discard(): port = PortStub( iter([ smolmidi.SYSEX, 1, smolmidi.SYSEX_END, smolmidi.NOTE_ON | 0x01, 0x64, 0x42 ])) midi_in = smolmidi.MidiIn(port) msg = midi_in.receive() assert msg.type == smolmidi.SYSEX msg = midi_in.receive() assert msg.type == smolmidi.NOTE_ON assert msg.channel == 0x01 assert msg.data[0] == 0x64 assert msg.data[1] == 0x42
def __init__(self): self.outputs = Outputs() self._midi_in = _midi_ext.DeduplicatingMidiIn( smolmidi.MidiIn(usb_midi.ports[0])) self._clocks = 0 self._last_clock = time.monotonic_ns()
def __init__(self): self.outputs = Outputs() self._midi_in = _midi_ext.DeduplicatingMidiIn( smolmidi.MidiIn(usb_midi.ports[0]) ) self._clocks = 0
""" Code that runs on Sol to allow the setup scripts to set voltage outputs for calibration. """ import struct import usb_midi import winterbloom_sol.sol import winterbloom_smolmidi as smolmidi SYSEX_MARKER = 0x78 outputs = winterbloom_sol.sol.Outputs() midi_in = smolmidi.MidiIn(usb_midi.ports[0]) while True: msg = midi_in.receive() if not msg: continue if msg.type != smolmidi.SYSEX: continue msg, _ = midi_in.receive_sysex(64) if not msg: continue if msg[0] != SYSEX_MARKER: print("Invalid marker") continue