MIDI API
Overviewβ
Use MatrixOS.MIDI to receive and send MIDI packets from a Python app.
Value ranges:
- MIDI channel:
0..15 - Seven-bit MIDI data:
0..127 - Pitch bend and song position:
0..16383
MatrixOS.MIDI.getβ
get(timeout_ms: int = 0) -> MidiPacket | None
Reads the next MIDI packet.
Parameters:
timeout_ms: Maximum time to wait in milliseconds.0is non-blocking.
Returns:
MidiPacket | None: MIDI packet, orNonewhen no packet is available.
MatrixOS.MIDI.sendβ
send(packet: MidiPacket, port: int = MatrixOS.MIDI.PORT_EACH_CLASS, timeout_ms: int = 0) -> bool
Sends one MIDI packet.
Parameters:
packet: Packet to send.port: Target MIDI port mask.timeout_ms: Maximum time to wait while sending.
Returns:
bool:Truewhen sent.
MatrixOS.MIDI.send_sysexβ
send_sysex(port: int, data: bytes, include_meta: bool = True) -> bool
Sends a SysEx payload.
Parameters:
port: Target MIDI port mask.data: SysEx payload bytes.include_meta: WhenTrue, Matrix OS includes SysEx start/end framing.
Returns:
bool:Truewhen sent.
MatrixOS.MIDI.is_note_onβ
is_note_on(packet: MidiPacket) -> bool
Checks whether a packet is a note-on message with velocity greater than 0.
Parameters:
packet: Packet to inspect.
Returns:
bool:Truefor note-on with nonzero velocity.
MatrixOS.MIDI.is_note_offβ
is_note_off(packet: MidiPacket) -> bool
Checks whether a packet is a note-off message.
Parameters:
packet: Packet to inspect.
Returns:
bool:Truefor real note-off packets and for the common note-on with velocity0form.
Send A Note From Inputβ
import MatrixOS
def loop():
# Drain all input events so quick key presses do not pile up.
event = MatrixOS.Input.get_event()
while event is not None:
keypad = event.get("keypad")
point = event.get("point")
if keypad and point and keypad.get("pressed"):
# Map the X coordinate to a simple chromatic note row.
note = 60 + point[0]
MatrixOS.MIDI.send(MatrixOS.MIDI.note_on(0, note, 100))
elif keypad and point and keypad.get("released"):
note = 60 + point[0]
MatrixOS.MIDI.send(MatrixOS.MIDI.note_off(0, note, 0))
event = MatrixOS.Input.get_event()
Light An LED From MIDIβ
import MatrixOS
def loop():
# Drain all pending MIDI packets in this loop call.
packet = MatrixOS.MIDI.get()
while packet is not None:
if MatrixOS.MIDI.is_note_on(packet):
# Reuse the note number as a stable LED index for visual feedback.
led = packet.note() % MatrixOS.LED.count()
level = min(255, packet.velocity() * 2)
MatrixOS.LED.set_index(led, (0, level, 0))
MatrixOS.LED.update()
elif MatrixOS.MIDI.is_note_off(packet):
led = packet.note() % MatrixOS.LED.count()
MatrixOS.LED.set_index(led, (0, 0, 0))
MatrixOS.LED.update()
packet = MatrixOS.MIDI.get()
This app-loop pattern drains all pending MIDI packets, lights the LED indexed by the MIDI note, and turns it off on note-off.
Packet Factory Methodsβ
Each factory returns a MidiPacket.
MatrixOS.MIDI.note_onβ
note_on(channel: int, note: int, velocity: int) -> MidiPacket
Creates a note-on packet.
Parameters: channel is 0..15; note and velocity are 0..127.
MatrixOS.MIDI.note_offβ
note_off(channel: int, note: int, velocity: int) -> MidiPacket
Creates a note-off packet.
Parameters: channel is 0..15; note and velocity are 0..127.
MatrixOS.MIDI.aftertouchβ
aftertouch(channel: int, note: int, pressure: int) -> MidiPacket
Creates a polyphonic aftertouch packet.
Parameters: channel is 0..15; note and pressure are 0..127.
MatrixOS.MIDI.control_changeβ
control_change(channel: int, controller: int, value: int) -> MidiPacket
Creates a control-change packet.
Parameters: channel is 0..15; controller and value are 0..127.
MatrixOS.MIDI.program_changeβ
program_change(channel: int, program: int) -> MidiPacket
Creates a program-change packet.
Parameters: channel is 0..15; program is 0..127.
MatrixOS.MIDI.channel_pressureβ
channel_pressure(channel: int, pressure: int) -> MidiPacket
Creates a channel-pressure packet.
Parameters: channel is 0..15; pressure is 0..127.
MatrixOS.MIDI.pitch_bendβ
pitch_bend(channel: int, value: int) -> MidiPacket
Creates a pitch-bend packet.
Parameters: channel is 0..15; value is 0..16383.
MatrixOS.MIDI.song_positionβ
song_position(position: int) -> MidiPacket
Creates a song-position packet.
Parameters: position is 0..16383.
MatrixOS.MIDI.song_selectβ
song_select(song: int) -> MidiPacket
Creates a song-select packet.
Parameters: song is 0..127.
MatrixOS.MIDI.mtc_quarter_frameβ
mtc_quarter_frame(value: int) -> MidiPacket
Creates an MTC quarter-frame packet.
Parameters: value is 0..127.
MatrixOS.MIDI.tune_requestβ
tune_request() -> MidiPacket
Creates a tune-request packet.
MatrixOS.MIDI.clockβ
clock() -> MidiPacket
Creates a MIDI clock packet.
MatrixOS.MIDI.tickβ
tick() -> MidiPacket
Creates a MIDI tick packet.
MatrixOS.MIDI.startβ
start() -> MidiPacket
Creates a MIDI start packet.
MatrixOS.MIDI.continue_β
continue_() -> MidiPacket
Creates a MIDI continue packet.
continue is a Python keyword, so the factory is named continue_().
MatrixOS.MIDI.stopβ
stop() -> MidiPacket
Creates a MIDI stop packet.
MatrixOS.MIDI.active_senseβ
active_sense() -> MidiPacket
Creates an active-sense packet.
MatrixOS.MIDI.resetβ
reset() -> MidiPacket
Creates a MIDI reset packet.
MidiPacketβ
You can construct a packet directly when a factory is not convenient:
MatrixOS.MIDI.MidiPacket()
MatrixOS.MIDI.MidiPacket(other_packet)
MatrixOS.MIDI.MidiPacket(status, data0, data1, data2)
packet.statusβ
status() -> int
Returns the packet status byte.
packet.set_statusβ
set_status(status: int) -> bool
Sets the packet status.
Returns: True when the status is valid for the packet.
packet.portβ
port() -> int
Returns the packet port mask.
packet.set_portβ
set_port(port: int) -> None
Sets the packet port mask.
packet.channelβ
channel() -> int | None
Returns the channel for channel messages, or None when the packet has no channel.
packet.set_channelβ
set_channel(channel: int) -> bool
Sets the packet channel.
Parameters: channel is 0..15.
Returns: True when the packet supports channel data.
packet.noteβ
note() -> int | None
Returns the packet note number, or None when not applicable.
packet.set_noteβ
set_note(note: int) -> bool
Sets the packet note number.
Parameters: note is 0..127.
Returns: True when the packet supports note data.
packet.controllerβ
controller() -> int | None
Returns the controller number, or None when not applicable.
packet.set_controllerβ
set_controller(controller: int) -> bool
Sets the controller number.
Parameters: controller is 0..127.
Returns: True when the packet supports controller data.
packet.velocityβ
velocity() -> int | None
Returns note velocity, or None when not applicable.
packet.set_velocityβ
set_velocity(velocity: int) -> bool
Sets note velocity.
Parameters: velocity is 0..127.
Returns: True when the packet supports velocity data.
packet.valueβ
value() -> int | None
Returns the packet value field, or None when not applicable.
packet.set_valueβ
set_value(value: int) -> bool
Sets the packet value field.
Parameters: value is 0..16383.
Returns: True when the packet supports a value field.
packet.lengthβ
length() -> int
Returns the MIDI byte length represented by the packet.
packet.is_sysexβ
is_sysex() -> bool
Returns whether the packet is part of a SysEx message.
packet.is_sysex_startβ
is_sysex_start() -> bool
Returns whether the packet starts a SysEx message.
packet.dataβ
data() -> tuple[int, int, int]
Returns the packet's three raw data bytes.
Status Constantsβ
STATUS_NONESTATUS_NOTE_OFFSTATUS_NOTE_ONSTATUS_AFTERTOUCHSTATUS_CONTROL_CHANGESTATUS_PROGRAM_CHANGESTATUS_CHANNEL_PRESSURESTATUS_PITCH_BENDSTATUS_MTC_QUARTER_FRAMESTATUS_SONG_POSITIONSTATUS_SONG_SELECTSTATUS_TUNE_REQUESTSTATUS_CLOCKSTATUS_TICKSTATUS_STARTSTATUS_CONTINUESTATUS_STOPSTATUS_ACTIVE_SENSESTATUS_RESETSTATUS_SYSEX_DATASTATUS_SYSEX_END
Port Constantsβ
PORT_EACH_CLASSPORT_ALLPORT_USBPORT_PHYSICALPORT_BLUETOOTHPORT_WIRELESSPORT_RTPPORT_DEVICE_CUSTOMPORT_SYNTHPORT_OSPORT_INVALID
Comments