>>> rtmidi example please python?
Below is a **complete, ready‑to‑run example** that shows how to use the **`python-rtmidi`** package in
Python.
It demonstrates:
1. Listing all available MIDI ports
2. Opening a physical MIDI input port and reading messages (polling style)
3. Using a callback function for event‑driven input
4. Sending a simple MIDI note‑on/off through a physical output port
5. Creating a *virtual* output port that other software can connect to
---
## 1️⃣ Install the library
```bash
# pip will pull in the underlying RtMidi C++ library automatically
pip install python-rtmidi
```
> **Tip:**
> - On Windows you may need the Visual C++ Build Tools.
> - On macOS you need Xcode command line tools (`xcode-select --install`).
> - On Linux install `libasound2-dev` (ALSA) or `libjack-dev` as required.
---
## 2️⃣ The Python script
```python
#!/usr/bin/env python3
"""
Python‑RTMidi Example
---------------------
* Lists input & output ports
* Opens the first available input port and reads messages
* Sends a short C‑note via the first available output port
* Creates a virtual output port that other programs can listen to
Run this file as: python3 rtmidi_example.py
"""
import time
import sys
try:
import rtmidi
except ImportError:
print("Module 'rtmidi' not found. Run: pip install python-rtmidi")
sys.exit(1)
def list_ports():
"""Print a friendly list of all input and output ports."""
midi_in = rtmidi.MidiIn()
midi_out = rtmidi.MidiOut()
print("\n--- MIDI INPUT PORTS ---")
for i, port in enumerate(midi_in.get_ports()):
print(f" [{i}] {port}")
print("\n--- MIDI OUTPUT PORTS ---")
for i, port in enumerate(midi_out.get_ports()):
print(f" [{i}] {port}")
midi_in.close_port()
midi_out.close_port()
def callback_handler(message, data=None):
"""Called automatically whenever a MIDI message arrives."""
msg, delta_time = message
print(f"\n[Callback] Time Δ={delta_time:.3f}s | Message={msg}")
# Example: stop any note that is currently on
# (simple, not a full state machine)
if msg[0] & 0xF0 == 0x90: # Note On
note, velocity = msg[1], msg[2]
if velocity > 0:
print(f" Note ON : note={note} vel={velocity}")
else:
print(f" Note OFF : note={note} (vel=0)")
# Forward the message to all output ports
for out_port in data["output_ports"]:
out_port.send_message(msg)
def main():
# 1️⃣ List all ports for the user
list_ports()
# 2️⃣ Open first available input port (if any)
midi_in = rtmidi.MidiIn()
input_ports = midi_in.get_ports()
if not input_ports:
print("\n⚠️ No MIDI input ports found. Exiting.")
return
print(f"\nOpening input port: '{input_ports[0]}'")
midi_in.open_port(0)
# 3️⃣ Open first available output port (if any)
midi_out = rtmidi.MidiOut()
output_ports = midi_out.get_ports()
if output_ports:
print(f"Opening output port: '{output_ports[0]}'")
midi_out.open_port(0)
output_list = [midi_out]
else:
print("\n⚠️ No MIDI output ports found. Creating virtual port.")
midi_out.open_virtual_port("PythonRTMidi Virtual Out")
output_list = [midi_out]
# 4️⃣ Send a short C‑note (Middle C, channel 1) for 0.5 s
note_on = [0x90, 60, 127] # Note On, middle C, velocity 127
note_off = [0x80, 60, 0] # Note Off, middle C
print("\nSending a short C‑note through the output port.")
midi_out.send_message(note_on)
time.sleep(0.5)
midi_out.send_message(note_off)
# 5️⃣ Set up a callback (event‑driven) – runs in its own thread
# We pass the output list via `data` so the callback can forward
midi_in.set_callback(callback_handler, data={"output_ports": output_list})
print("\n--- Entering event loop (press Ctrl+C to quit) ---")
try:
while True:
time.sleep(1) # Keep the main thread alive
except KeyboardInterrupt:
print("\nExiting…")
# 6️⃣ Clean‑up
midi_in.close_port()
midi_out.close_port()
if __name__ == "__main__":
main()```
### How the script works
| Section | What it does |
|---------|--------------|
| **`list_ports`** | Prints all available input and output ports for your reference. |
| **`callback_handler`** | Receives every incoming MIDI message, prints it, and forwards it to all open
output ports. |
| **`main`** | |
| - Opens the first input port. | |
| - Opens the first output port, or creates a virtual one if none exist. | |
| - Sends a simple “note on” for 0.5 s and then “note off”. | |
| - Installs the callback so you get real‑time events. | |
| - Enters a harmless `while True` loop that keeps the program running. | |
---
## 3️⃣ What to try
1. **Run the script.**
You’ll see the list of ports and a short note being sent.
2. **Plug in a MIDI keyboard** (or any device) that is connected to the input port the script opened.
- Every note you play will print to the console via the callback.
- The same notes will be forwarded to the output port (so they’ll come back out to your keyboard if it’s a
bidirectional device, or to any other software listening on the virtual port).
3. **Open another DAW or MIDI monitoring app** and connect it to the *virtual output* created by the script.
You’ll hear the notes you play on the keyboard.
---
## 4️⃣ Common gotchas
| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| **`rtmidi` not found** | Library not installed | `pip install python-rtmidi` |
| **No ports listed** | No devices connected, or drivers missing | Connect a MIDI device or install proper
drivers |
| **Access denied on Windows** | Running as non‑admin | Run the terminal as Administrator or grant “MIDI
access” |
| **Crash when sending note** | Trying to send to a closed port | Ensure `midi_out.open_port()` succeeded
before `send_message()` |
---
### Final note
`python-rtmidi` gives you a *thin* but powerful wrapper around the excellent RtMidi C++ library.
With this scaffold you can:
- Build a real‑time MIDI controller app
- Implement custom MIDI processing pipelines
- Interface a Python script with any DAW or virtual instrument
Happy hacking! 🎹✨