A Python binding for the RtMidi C++ library providing cross-platform realtime MIDI input/output functionality.
npx @tessl/cli install tessl/pypi-python-rtmidi@1.5.0A Python binding for the RtMidi C++ library providing cross-platform realtime MIDI input/output functionality. Supports Linux (ALSA & JACK), macOS (CoreMIDI & JACK), and Windows (MultiMedia System) with a thin Cython wrapper around the RtMidi C++ interface, adapted to Python PEP-8 conventions.
pip install python-rtmidiimport rtmidiSub-modules:
import rtmidi.midiconstants
import rtmidi.midiutilimport time
import rtmidi
# Create MIDI output instance
midiout = rtmidi.MidiOut()
available_ports = midiout.get_ports()
if available_ports:
midiout.open_port(0)
else:
midiout.open_virtual_port("My virtual output")
# Send MIDI messages using context manager
with midiout:
note_on = [0x90, 60, 112] # channel 1, middle C, velocity 112
note_off = [0x80, 60, 0]
midiout.send_message(note_on)
time.sleep(0.5)
midiout.send_message(note_off)
time.sleep(0.1)
del midioutpython-rtmidi provides a thin wrapper around RtMidi's C++ classes:
with statementsPrimary interfaces for MIDI input and output operations, including port management, message handling, callback registration, and error handling.
class MidiIn:
def __init__(self, rtapi=API_UNSPECIFIED, name="RtMidi Client", queue_size_limit=1024): ...
def get_current_api(self): ...
def get_port_count(self): ...
def get_ports(self, encoding='auto'): ...
def open_port(self, port=0, name=None): ...
def open_virtual_port(self, name=None): ...
def close_port(self): ...
def get_message(self): ...
def set_callback(self, func, data=None): ...
class MidiOut:
def __init__(self, rtapi=API_UNSPECIFIED, name="RtMidi Client"): ...
def get_current_api(self): ...
def get_port_count(self): ...
def get_ports(self, encoding='auto'): ...
def open_port(self, port=0, name=None): ...
def open_virtual_port(self, name=None): ...
def close_port(self): ...
def send_message(self, message): ...Comprehensive collection of MIDI message types, controller numbers, system messages, and helper functions for MIDI protocol implementation.
# MIDI Channel Events (from rtmidi.midiconstants)
NOTE_OFF = 0x80
NOTE_ON = 0x90
CONTROLLER_CHANGE = 0xB0
PROGRAM_CHANGE = 0xC0
PITCH_BEND = 0xE0
# Controller Numbers
MODULATION = 0x01
VOLUME = 0x07
PAN = 0x0A
SUSTAIN = 0x40
# System Messages
SYSTEM_EXCLUSIVE = 0xF0
TIMING_CLOCK = 0xF8
ACTIVE_SENSING = 0xFE
def is_status(byte): ...Helper functions for MIDI port management, API selection, and interactive port opening with support for environment-based configuration.
def get_api_from_environment(api=rtmidi.API_UNSPECIFIED): ...
def list_input_ports(api=rtmidi.API_UNSPECIFIED): ...
def list_output_ports(api=rtmidi.API_UNSPECIFIED): ...
def open_midiinput(port=None, api=rtmidi.API_UNSPECIFIED,
use_virtual=False, interactive=True,
client_name=None, port_name=None): ...
def open_midioutput(port=None, api=rtmidi.API_UNSPECIFIED,
use_virtual=False, interactive=True,
client_name=None, port_name=None): ...# API Backend Information
def get_compiled_api(): ...
def get_api_name(api): ...
def get_api_display_name(api): ...
def get_compiled_api_by_name(name): ...
def get_rtmidi_version(): ...
# API Constants
API_UNSPECIFIED = 0
API_MACOSX_CORE = 1
API_LINUX_ALSA = 2
API_UNIX_JACK = 3
API_WINDOWS_MM = 4
API_WEB_MIDI = 5
API_RTMIDI_DUMMY = 6
# Error Type Constants
ERRORTYPE_WARNING = 0
ERRORTYPE_DEBUG_WARNING = 1
ERRORTYPE_UNSPECIFIED = 2
ERRORTYPE_NO_DEVICES_FOUND = 3
ERRORTYPE_INVALID_DEVICE = 4
ERRORTYPE_MEMORY_ERROR = 5
ERRORTYPE_INVALID_PARAMETER = 6
ERRORTYPE_INVALID_USE = 7
ERRORTYPE_DRIVER_ERROR = 8
ERRORTYPE_SYSTEM_ERROR = 9
ERRORTYPE_THREAD_ERROR = 10class RtMidiError(Exception):
"""
Base exception for all RtMidi errors.
Attributes:
- type: int - Error type constant (one of ERRORTYPE_* values)
"""
type: int
class InvalidPortError(RtMidiError, ValueError):
"""
Invalid port number or unavailable port.
Raised when:
- Port number exceeds available ports
- Attempting to open non-existent port
- Port selection fails in non-interactive mode
"""
class InvalidUseError(RtMidiError, RuntimeError):
"""
Method called in inappropriate state.
Raised when:
- Opening port when port already open
- Calling port-specific methods when no port open
- Using deleted MidiIn/MidiOut instances
"""
class MemoryAllocationError(RtMidiError, MemoryError):
"""
C++ level memory allocation failure.
Raised when:
- Insufficient memory for MIDI operations
- Internal buffer allocation fails
"""
class SystemError(RtMidiError, OSError):
"""
MIDI driver or operating system error.
Raised when:
- MIDI backend initialization fails
- Driver-level communication errors
- OS-level MIDI system problems
"""
class NoDevicesError(SystemError):
"""
No MIDI devices available.
Raised when:
- No MIDI ports found on system
- All ports in use or inaccessible
- MIDI subsystem unavailable
"""
class UnsupportedOperationError(RtMidiError, RuntimeError):
"""
Operation not supported by current API backend.
Raised when:
- Virtual ports requested on Windows MM API
- Client/port name changes on unsupported APIs
- API-specific feature limitations
"""