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](http://vedanamedia.com/our-products/pkmidicron/).
Installation
------------
Install using:
```bash
pip install rtmidi
```
Usage
-----
pyrtmidi is a Python interface to RtMidi. It provides real-time midi input and output.
```python
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](http://www.music.mcgill.ca/~gary/rtmidi/), 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](https://www.juce.com/doc/classMidiMessage).
*Recipes*
The following implements a QObject wrapper for rtmidi.RtMidiIn that emits a 'message()' signal. The essential code is follows:
```python
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.
```python
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_
```
Raw data
{
"_id": null,
"home_page": "https://github.com/patrickkidd/pyrtmidi",
"name": "rtmidi",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "midi audio hardware",
"author": "Patrick Stinson",
"author_email": "patrickkidd@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/ca/5b/b535626a0e9f7569b2981209bafe77cfa0da1e93920c111adba823184509/rtmidi-2.5.0.tar.gz",
"platform": null,
"description": "pyrtmidi\n========\n\nRealtime 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.\n\nPyrtmidi provides MIDI I/O for [PKMidiCron](http://vedanamedia.com/our-products/pkmidicron/).\n\nInstallation\n------------\n\nInstall using:\n\n```bash\npip install rtmidi\n```\n\nUsage\n-----\n\npyrtmidi is a Python interface to RtMidi. It provides real-time midi input and output.\n\n```python\n\nimport rtmidi\n\nmidiin = rtmidi.RtMidiIn()\n\ndef print_message(midi):\n if midi.isNoteOn():\n print('ON: ', midi.getMidiNoteName(midi.getNoteNumber()), midi.getVelocity())\n elif midi.isNoteOff():\n print('OFF:', midi.getMidiNoteName(midi.getNoteNumber()))\n elif midi.isController():\n print('CONTROLLER', midi.getControllerNumber(), midi.getControllerValue())\n\nports = range(midiin.getPortCount())\nif ports:\n for i in ports:\n print(midiin.getPortName(i))\n print(\"Opening port 0!\") \n midiin.openPort(0)\n while True:\n m = midiin.getMessage(250) # some timeout in ms\n if m:\n print_message(m)\nelse:\n print('NO MIDI INPUT PORTS!')\n```\n\nThe API is copied *near* verbatim from the C++ code. Refer to the [RtMidi tutorial](http://www.music.mcgill.ca/~gary/rtmidi/), and take into account the following caveats:\n\n*RtMidiIn*\n\n`getMessage(timeout_ms=None)`\n\n * The message argument has been replaced with an optional millisecond timeout value.\n * The function will return a MidiMessage object, or None if no message is available.\n\n`setCallback`\n\n * This function works just as described in the above docs, and takes a python callable object.\n * This method is most useful with a queue.Queue object to communicate between threads.\n\n*MidiMessage*\n\nThis class has been taken from the juce library, and includes an excellent comprehensive set of midi functions. [please check here for available methods](https://www.juce.com/doc/classMidiMessage).\n\n*Recipes*\n\nThe following implements a QObject wrapper for rtmidi.RtMidiIn that emits a 'message()' signal. The essential code is follows:\n\n```python\nclass MidiInput(QThread):\n def __init__(self, devid, parent=None):\n QThread.__init__(self, parent)\n self.device = rtmidi.RtMidiIn()\n self.device.openPort(devid)\n self.running = False\n\n def run(self):\n self.running = True\n while self.running:\n msg = self.device.getMessage(250)\n if msg:\n self.msg = msg\n self.emit(SIGNAL('message(PyObject *)'), self.msg)\n self.emit(SIGNAL('message()')\n\nmidi = MidiInput(1)\ndef slotMessage(msg):\n print msg\nQObject.connect(midi, SIGNAL('message(PyObject *)'), slotMessage)\n```\n\nThe following implements a midi echo for all ports.\n\n```python\n\nimport sys\nimport rtmidi\nimport threading\n\ndef print_message(midi, port):\n if midi.isNoteOn():\n print '%s: ON: ' % port, midi.getMidiNoteName(midi.getNoteNumber()), midi.getVelocity()\n elif midi.isNoteOff():\n print '%s: OFF:' % port, midi.getMidiNoteName(midi.getNoteNumber())\n elif midi.isController():\n print '%s: CONTROLLER' % port, midi.getControllerNumber(), midi.getControllerValue()\n\nclass Collector(threading.Thread):\n def __init__(self, device, port):\n threading.Thread.__init__(self)\n self.setDaemon(True)\n self.port = port\n self.portName = device.getPortName(port)\n self.device = device\n self.quit = False\n\n def run(self):\n self.device.openPort(self.port)\n self.device.ignoreTypes(True, False, True)\n while True:\n if self.quit:\n return\n msg = self.device.getMessage()\n if msg:\n print_message(msg, self.portName)\n\n\ndev = rtmidi.RtMidiIn()\ncollectors = []\nfor i in range(dev.getPortCount()):\n device = rtmidi.RtMidiIn()\n print 'OPENING',dev.getPortName(i)\n collector = Collector(device, i)\n collector.start()\n collectors.append(collector)\n\n\nprint 'HIT ENTER TO EXIT'\nsys.stdin.read(1)\nfor c in collectors:\n c.quit = True\n```\n\n\n\n\nCommon Problems\n-----------------\n\nThis is a commonly reported build error on linux, although I it works for me using python2.7 on ubuntu.\n\n```\n:~/devel/pkaudio/pyrtmidi/tests$ python test_rtmidi.py \nTraceback (most recent call last):\nFile \"test_rtmidi.py\", line 29, in \nimport rtmidi\nImportError: /usr/local/lib/python2.6/dist-packages/rtmidi.so: undefined symbol: _ZN11MidiMessageaSERKS_\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "Realtime MIDI I/O for Python on Windows, OS X, and Linux",
"version": "2.5.0",
"project_urls": {
"Homepage": "https://github.com/patrickkidd/pyrtmidi"
},
"split_keywords": [
"midi",
"audio",
"hardware"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0213c9fccc472305d8d11c0d90aa4a8994f5894cb11dd2dccd046f389301808f",
"md5": "1e80215c178d456b851d9b6666e9ff1f",
"sha256": "5b13afd4bfa62190470827d46b495930d76d9f4fe0e132e3ceba4fb945c9edb9"
},
"downloads": -1,
"filename": "rtmidi-2.5.0-cp310-cp310-win_amd64.whl",
"has_sig": false,
"md5_digest": "1e80215c178d456b851d9b6666e9ff1f",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": null,
"size": 44016,
"upload_time": "2023-05-02T08:22:41",
"upload_time_iso_8601": "2023-05-02T08:22:41.842402Z",
"url": "https://files.pythonhosted.org/packages/02/13/c9fccc472305d8d11c0d90aa4a8994f5894cb11dd2dccd046f389301808f/rtmidi-2.5.0-cp310-cp310-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c76aae4fc394af665bab655b1364b406061762147213dc76eedc5c8ce441166a",
"md5": "bd7d0dba87bf284589db7cab72a80d51",
"sha256": "2ac450917a226003199e25a66054ba535d2ec5a4ff232c6a4b7432a7689db31a"
},
"downloads": -1,
"filename": "rtmidi-2.5.0-cp311-cp311-macosx_13_0_x86_64.whl",
"has_sig": false,
"md5_digest": "bd7d0dba87bf284589db7cab72a80d51",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": null,
"size": 56556,
"upload_time": "2023-05-02T08:19:42",
"upload_time_iso_8601": "2023-05-02T08:19:42.039684Z",
"url": "https://files.pythonhosted.org/packages/c7/6a/ae4fc394af665bab655b1364b406061762147213dc76eedc5c8ce441166a/rtmidi-2.5.0-cp311-cp311-macosx_13_0_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ca5bb535626a0e9f7569b2981209bafe77cfa0da1e93920c111adba823184509",
"md5": "01434c449e94f92040bcb90d789dcf40",
"sha256": "bc1e40c24f7df052df9b1e586b82a6987f899ae1a8596ec682af662df275e9b0"
},
"downloads": -1,
"filename": "rtmidi-2.5.0.tar.gz",
"has_sig": false,
"md5_digest": "01434c449e94f92040bcb90d789dcf40",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 56573,
"upload_time": "2023-05-02T08:19:44",
"upload_time_iso_8601": "2023-05-02T08:19:44.442572Z",
"url": "https://files.pythonhosted.org/packages/ca/5b/b535626a0e9f7569b2981209bafe77cfa0da1e93920c111adba823184509/rtmidi-2.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-02 08:19:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "patrickkidd",
"github_project": "pyrtmidi",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "rtmidi"
}