This is a CircuitPython helper library for communicating over MIDI. This library is intentionally minimal and low-level. It's just enough to make using the PortIn
bearable. If you are looking for a high-level, beginner-friendly MIDI library please look at Adafruit CircuitPython MIDI.
It's also experimental at this point. While I've verified it works for my boards, my controllers, and my DAWs, I haven't been able to test it broadly enough to feel confident it'll work with other setups. If you use it and run into issues, please file a bug and let me know!
Create a MidiIn
instance using a PortIn
instance:
import usb_midi
import winterbloom_smolmidi as smolmidi
midi_in = smolmidi.MidiIn(usb_midi.ports[0])
Then use receive
to receive messages. You can use the message type constants at the top of the library file to determine what sort of MIDI message you received:
while True:
msg = midi_in.receive()
if not msg:
continue
if msg.type == midi.NOTE_ON:
channel = msg.channel
note = msg.data[0]
velocity = msg.data[1]
print('Note On, Channel: {}, Note: {}, Velocity: {}'.format(
channel, note, velocity))
elif msg.type == midi.NOTE_OFF:
note = msg.data[0]
velocity = msg.data[1]
print('Note Off, Channel: {}, Note: {}, Velocity: {}'.format(
channel, note, velocity))
elif msg.type == midi.SYSTEM_RESET:
print('System reset')
This library has basic support for system exclusive messages. To get a system exclusive message you must check for the SYSEX
message and then call receive_sysex
to get the data for the payload. If you don't call receive_sysex
the payload will be discarded on the next call to receive
. receive_sysex
requires you to pass the maximum number of bytes to read from the payload. Any remaining bytes will be discarded.
while True:
msg = midi_in.receive()
if not msg:
continue
if msg.type == midi.SYSEX:
sysex_payload, truncated = midi_in.receive_sysex(128)
print('Got sysex of length {}, Truncated: {}'.format(
len(sysex_payload, 128)))
In the future, I may add the ability to read the sysex messages in chunks if that's something folks desire.
The built-in PortOut is more than usable enough at a low-level. For example, you can use the constants defined here to send a Note On message:
port_out = usb_midi.ports[0]
port_out.write(bytearray([smolmidi.NOTE_ON, 0x64, 0x42]))
So at this point I don't feel like it needs an additional library to wrap it, but, if you have ideas I'd love to hear them. :)
Install this library by copying winterbloom_smolmidi.py to your device's lib
folder.
This is available under the MIT License. I welcome contributors, please read the Code of Conduct first. :)