Skip to main content

pyrtmidi

Realtime MIDI I/O for Python on Windows, OS X, and Linux. Includes comprehensive MidiMessage class, support for virtual ports on OS X and Linux, and multi-threaded lister utility classes.

Pyrtmidi provides MIDI I/O for PKMidiCron.

Installation

Install using:

pip install rtmidi

Usage

pyrtmidi is a Python interface to RtMidi. It provides real-time midi input and output.

import rtmidi

midiin = rtmidi.RtMidiIn()

def print_message(midi):
    if midi.isNoteOn():
        print('ON: ', midi.getMidiNoteName(midi.getNoteNumber()), midi.getVelocity())
    elif midi.isNoteOff():
        print('OFF:', midi.getMidiNoteName(midi.getNoteNumber()))
    elif midi.isController():
        print('CONTROLLER', midi.getControllerNumber(), midi.getControllerValue())

ports = range(midiin.getPortCount())
if ports:
    for i in ports:
        print(midiin.getPortName(i))
    print("Opening port 0!") 
    midiin.openPort(0)
    while True:
        m = midiin.getMessage(250) # some timeout in ms
        if m:
            print_message(m)
else:
    print('NO MIDI INPUT PORTS!')

The API is copied near verbatim from the C++ code. Refer to the RtMidi tutorial, and take into account the following caveats:

RtMidiIn

getMessage(timeout_ms=None)

  • The message argument has been replaced with an optional millisecond timeout value.
  • The function will return a MidiMessage object, or None if no message is available.

setCallback

  • This function works just as described in the above docs, and takes a python callable object.
  • This method is most useful with a queue.Queue object to communicate between threads.

MidiMessage

This class has been taken from the juce library, and includes an excellent comprehensive set of midi functions. please check here for available methods.

Recipes

The following implements a QObject wrapper for rtmidi.RtMidiIn that emits a 'message()' signal. The essential code is follows:

class MidiInput(QThread):
    def __init__(self, devid, parent=None):
        QThread.__init__(self, parent)
        self.device = rtmidi.RtMidiIn()
        self.device.openPort(devid)
        self.running = False

    def run(self):
        self.running = True
        while self.running:
            msg = self.device.getMessage(250)
            if msg:
                self.msg = msg
                self.emit(SIGNAL('message(PyObject *)'), self.msg)
                self.emit(SIGNAL('message()')

midi = MidiInput(1)
def slotMessage(msg):
   print msg
QObject.connect(midi, SIGNAL('message(PyObject *)'), slotMessage)

The following implements a midi echo for all ports.

import sys
import rtmidi
import threading

def print_message(midi, port):
    if midi.isNoteOn():
        print '%s: ON: ' % port, midi.getMidiNoteName(midi.getNoteNumber()), midi.getVelocity()
    elif midi.isNoteOff():
        print '%s: OFF:' % port, midi.getMidiNoteName(midi.getNoteNumber())
    elif midi.isController():
        print '%s: CONTROLLER' % port, midi.getControllerNumber(), midi.getControllerValue()

class Collector(threading.Thread):
    def __init__(self, device, port):
        threading.Thread.__init__(self)
        self.setDaemon(True)
        self.port = port
        self.portName = device.getPortName(port)
        self.device = device
        self.quit = False

    def run(self):
        self.device.openPort(self.port)
        self.device.ignoreTypes(True, False, True)
        while True:
            if self.quit:
                return
            msg = self.device.getMessage()
            if msg:
                print_message(msg, self.portName)


dev = rtmidi.RtMidiIn()
collectors = []
for i in range(dev.getPortCount()):
    device = rtmidi.RtMidiIn()
    print 'OPENING',dev.getPortName(i)
    collector = Collector(device, i)
    collector.start()
    collectors.append(collector)


print 'HIT ENTER TO EXIT'
sys.stdin.read(1)
for c in collectors:
    c.quit = True

Common Problems

This is a commonly reported build error on linux, although I it works for me using python2.7 on ubuntu.

:~/devel/pkaudio/pyrtmidi/tests$ python test_rtmidi.py 
Traceback (most recent call last):
File "test_rtmidi.py", line 29, in 
import rtmidi
ImportError: /usr/local/lib/python2.6/dist-packages/rtmidi.so: undefined symbol: _ZN11MidiMessageaSERKS_

Metadata

Release files for rtmidi 2.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rtmidi 2.5.0
File Size Uploaded
rtmidi-2.5.0.tar.gz 56.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for rtmidi 2.5.0
File Interpreter ABI Platform
rtmidi-2.5.0-cp311-cp311-macosx_13_0_x86_64.whl CPython 3.11 CPython 3.11 macOS 13.0+ x86-64 Details
rtmidi-2.5.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details

Total release size: 157.1 kB

Release files / rtmidi-2.5.0.tar.gz

Download URL rtmidi-2.5.0.tar.gz
Size 56.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bc1e40c24f7df052df9b1e586b82a6987f899ae1a8596ec682af662df275e9b0
BLAKE2b-256 checksum
How to use checksums
ca5bb535626a0e9f7569b2981209bafe77cfa0da1e93920c111adba823184509
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.3

Release files / rtmidi-2.5.0-cp311-cp311-macosx_13_0_x86_64.whl

Download URL rtmidi-2.5.0-cp311-cp311-macosx_13_0_x86_64.whl
Size 56.6 kB
Tags CPython 3.11 macOS 13.0+ x86-64
SHA-256 checksum
How to use checksums
2ac450917a226003199e25a66054ba535d2ec5a4ff232c6a4b7432a7689db31a
BLAKE2b-256 checksum
How to use checksums
c76aae4fc394af665bab655b1364b406061762147213dc76eedc5c8ce441166a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.3

Release files / rtmidi-2.5.0-cp310-cp310-win_amd64.whl

Download URL rtmidi-2.5.0-cp310-cp310-win_amd64.whl
Size 44.0 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
5b13afd4bfa62190470827d46b495930d76d9f4fe0e132e3ceba4fb945c9edb9
BLAKE2b-256 checksum
How to use checksums
0213c9fccc472305d8d11c0d90aa4a8994f5894cb11dd2dccd046f389301808f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.4

Release history Release notifications | RSS feed

This release

2.5.0 This release

3 release files

2.3.4

1 release file

2.3.3

1 release file

2.3.2

1 release file

2.3.1

1 release file

2.3

2.2

1 release file

2.1

1 release file

2.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page