MIDI library for CircuitPython
TMIDI is a MIDI library for CircuitPython / MicroPython. It attempts to
be a provide a simpler API and perform faster, especially for MIDI parsing,
compared to adafruit_midi (adafruit_midi github)
TMIDI is derived from winterbloom_smolmidi
(smolmidi github)
by Thea Flowers for Winterbloom.
Like adafruit_midi, TMIDI works on CircuitPython's usb_midi and busio.UART,
or any stream-like object that supports .readinto() and .write()
Sending MIDI over USB. Channels are 0-indexed, so channel=0 is
MIDI channel 1:
import time
import usb_midi
import tmidi
midi = tmidi.MIDI(midi_out=usb_midi.ports[1])
while True:
midi.send(tmidi.Message(tmidi.NOTE_ON, 60, 100, channel=0))
time.sleep(0.5)
midi.send(tmidi.Message(tmidi.NOTE_OFF, 60, 0, channel=0))
time.sleep(0.5)Receiving MIDI over USB. receive() returns None when nothing
has arrived:
import usb_midi
import tmidi
midi = tmidi.MIDI(midi_in=usb_midi.ports[0])
while True:
if msg := midi.receive():
if msg.type == tmidi.NOTE_ON:
print("note on:", msg.note, msg.velocity, msg.channel)
else:
print(msg)Instead of receive(), register functions for the message types you want
and call poll(). No Message objects are allocated.
def note_on(channel, note, velocity):
print("note on:", channel, note, velocity)
midi.on(tmidi.NOTE_ON, note_on)
while True:
midi.poll()See examples/tmidi_simple_poll.py for a full example.
TMIDI runs entirely in Python, but uses a faster @micropython.viper
parser when your firmware can load native code. The parsers ship inside the
tmidi/ library folder as tmidi_kernel.<arch>.mpy, and CircuitPython
picks the one for your board. tmidi.ENGINE says which parser is in use.
TMIDI 3.0 is a folder, lib/tmidi/, instead of a single lib/tmidi.mpy.
Delete an old lib/tmidi.mpy when upgrading.
tmidi_kernel file |
Boards |
|---|---|
armv6m |
RP2040 |
armv7emsp |
SAMD51, nRF52840, RP2350, STM32F4 |
xtensawin |
ESP32-S2, ESP32-S3 |
rv32imc |
ESP32-C3, C5, C6 |
To rebuild them from src/tmidi_turbo.py, use an mpy-cross from the
CircuitPython version they will run on. The files land in tmidi/:
cd src
make MPY_CROSS=path/to/circuitpython/mpy-cross/build/mpy-crossThis library depends on:
Please ensure all dependencies are available on the CircuitPython filesystem. This is easily achieved by downloading the Adafruit library and driver bundle or individual libraries can be installed using circup.
On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally from PyPI. To install for current user:
pip3 install circuitpython-tmidiTo install system-wide (this may be required in some cases):
sudo pip3 install circuitpython-tmidiTo install in a virtual environment in your current project:
mkdir project-name && cd project-name
python3 -m venv .venv
source .env/bin/activate
pip3 install circuitpython-tmidiMake sure that you have circup installed in your Python environment.
Install it with the following command if necessary:
pip3 install circupWith circup installed and your CircuitPython device connected use the
following command to install:
circup install tmidiOr the following command to update an existing version:
circup updateAPI documentation for this library can be found on Read the Docs.
For information on building library documentation, please check out this guide.
Install pytest with pip3 install pytest circuitpython-mocks --upgrade and run pytest -v
Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.