tmidi
MIDI library for CircuitPython
Author(s): Tod Kurt, with code from Alethea Flowers for Winterbloom
Portions of this library come from Winterbloom_SmolMIDI: https://github.com/wntrblm/Winterbloom_SmolMIDI
Implementation Notes
Hardware:
Native USB for USB MIDI
UART for Serial MIDI
PIO-USB or MAX3421E USB Host for USB Host MIDI
Software and Dependencies:
Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads
- tmidi.ACTIVE_SENSING = 254
Active Sensing
- tmidi.AFTERTOUCH = 160
Aftertouch
- tmidi.BUS_SELECT = 245
BUS Select
- tmidi.CHANNEL_PRESSURE = 208
Channel Pressure
- tmidi.CLOCK = 248
Clock
- tmidi.CONTINUE = 251
Continue
- tmidi.CONTROLLER_CHANGE = 176
Controller Change
- class tmidi.MIDI(midi_in=None, midi_out=None, enable_running_status=False)
MIDI Parser, receiver and sender
midi_inormidi_outmust be set or both together.- Parameters:
midi_in – an object which implements
read(length), set tousb_midi.ports[0]for USB MIDI, default None.midi_out – an object which implements
write(buffer, length), set tousb_midi.ports[1]for USB MIDI, default None.enable_running_status (bool) – Allow running status messages to work, default False.
Example of sending MIDI over USB:
import usb_midi import tmidi midi_usb = tmidi.MIDI(midi_out=usb_midi.ports[1]) msg_on = tmidi.Message(tmidi.NOTE_ON, notenum, velocity) midi_usb.send(msg_on)
Example of sending MIDI over UART (TRS or 5-pin):
import board import busio import tmidi uart = busio.UART(tx=board.TX, rx=board.RX, timeout=0.001) midi_uart = tmidi.MIDI(midi_out=uart) msg_on = tmidi.Message(tmidi.NOTE_ON, notenum, velocity) midi_uart.send(msg_on)
Example of receiving MIDI:
import board import busio import usb_midi import tmidi uart = busio.UART(tx=board.TX, rx=board.RX, timeout=0.001) midi_uart = tmidi.MIDI(midi_in=uart, midi_out=uart) midi_usb = tmidi.MIDI(midi_in=usb_midi.ports[0], midi_out=usb_midi.ports[1]) while True: if msg := midi_usb.receive(): print("usb midi:", msg) if msg := midi_uart.receive(): print("uart midi:", msg)
- property error_count
Number of errors encountered when parsing received messages
- receive()
Read message from MIDI port, parse that data and return the first MIDI message (event). This maintains the blocking characteristics of the midi_in port. Relies on the port to buffer the incoming unread MIDI messages.
- Returns Message object:
Returns object or None for nothing.
- class tmidi.Message(mtype=SYSTEM_RESET, data0=0, data1=0, channel=0)
MIDI Message.
- Parameters:
mtype – The type of message, e.g. tmidi.NOTE_ON.
data0 – The first data byte for this message, e.g. the note number as an
int(0-127) for NOTE_ON messages.data1 – The second data byte for this message, e.g. the velocity (0-127) for NOTE_ON messages.
channel – The MIDI channel for this message, if applicable (0-15)
Example of creating Messages:
# create Note On middle-C message on ch 1 (0-indexed) m = Message(tmidi.NOTE_ON, 60, 127, channel=0) # create CC 74 with val 63 on ch 4 m = Message(tmidi.CC, 74, 63, channel=4-1) # create a pitch bend full up on ch 1 m = Message(tmidi.PITCH_BEND, 8191)
Example of creating accessing Message attributes:
if msg := midi.receive(): if msg.type == tmidi.NOTE_ON: print("note on:", msg.note, msg.velocity) elif msg.type == tmidi.NOTE_OFF: print("note off:", msg.note, msg.velocity) elif msg.type == tmidi.PROGRAM_CHANGE: print("program change:", msg.value)
- property note
MIDI note number of message (only valid for NOTE_ON/NOTE_OFF msgs)
- property pitch_bend
Pitch bend value of message (only valid for PITCH_BEND msgs)
- property value
Message value, only valid for len1 messages (Program Change, etc)
- property velocity
MIDI velocity of message (only valid for NOTE_ON/NOTE_OFF msgs)
- tmidi.NOTE_OFF = 128
Note Off
- tmidi.NOTE_ON = 144
Note On
- tmidi.PITCH_BEND = 224
Pitch Bend
- tmidi.PROGRAM_CHANGE = 192
Program Change
- tmidi.SONG_POSITION = 242
Song Position
- tmidi.SONG_SELECT = 243
Song Select
- tmidi.START = 250
Start
- tmidi.STOP = 252
Stop
- tmidi.SYSEX_END = 247
Sysex End
- tmidi.SYSTEM_EXCLUSIVE = 240
Sysex
- tmidi.SYSTEM_RESET = 255
System Reset
- tmidi.TICK = 249
Tick
- tmidi.TUNE_REQUEST = 246
Tune Request