MidiJam Bootstrap

I had a moment of clarity on how to get my MIDI jamming tools working this morning. I made a sketch, it was all crystal clear in my mind, and had the typical ‘right, let’s do this!’ moment that all programmers experience, before having all joy boiled out of it by a cascade of tool and API issues.

So it’s been a slow day, but on the upside I seem to have my MIDI library working and a bare bones environment I can crack on with in future.

OK, rewinding to morning: my plan was to write a minimal script that can receive and transmit midi. For example, a Qt app that perhaps echoes a midi signal or something.

I found the pyrtmidi library which has a nice simple real time interface: The other libraries I’ve seen have APIs which I am concerned will introduce unnecessary overhead. Also some seemed to only send midi, others were just about making midi files. So with frayed temper, I seized pyrtmidi.

Unfortunately it wouldn’t install out-of-the-box. I had to install sudo apt-get install libasound2-dev on Linux. I also had to explicitly pip install wheel or else the pyrtmidi would silently fail, it was in the pip list but the actual build was broken (I’m on Ubuntu 18.04.4 LTS if relevant):

(.venv) alex@zub:~/Documents/midijam$ pip install rtmidi==2.3.2                                             
 Collecting rtmidi==2.3.2                                                                                                      
   Downloading (52k
     100% |████████████████████████████████| 61kB 1.6MB/s                                                    
 Building wheels for collected packages: rtmidi                                                                                                     Running bdist_wheel for rtmidi … error                                                               
   Complete output from command /home/alex/Documents/midijam/.venv/bin/python3 -u -c "import setuptools, tokenize;file='/tmp/pip-build-q70b1f6
 w/rtmidi/';f=getattr(tokenize, 'open', open)(file);'\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" bdist_wheel -d /tmp/tmp4exmx2ospip-wheel- --python-tag cp36:                           
   /usr/lib/python3.6/distutils/ UserWarning: Unknown Extension options: 'headers'
   usage: -c [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] …]  
      or: -c --help [cmd1 cmd2 …]                                                                                                           
      or: -c --help-commands                                                                                                                           or: -c cmd --help                                                
 error: invalid command 'bdist_wheel'                      
 Failed building wheel for rtmidi                                                                                                               
   Running clean for rtmidi                                                             
 Failed to build rtmidi                                                                
 Installing collected packages: rtmidi                                              
   Running install for rtmidi … done                                                             
 Successfully installed rtmidi-2.3.2                                                                         

When trying to replicate this in a fresh venv, the issue went away; I assume something was installed deep down that is no longer required. So frustratingly I don’t have a repro for raising an issue on the pyrtmidi project. After the issue was resolved I could use the latest version of the library, I didn’t have to lock down to 2.3.2.

On the subject of versions, PyQt5 would also not install out-of-the-box. I vaguely recalled there being an issue with the latest release, so I used version 5.14.0.

Now running this minimal script I can get the connected MIDI device:

import rtmidi
midiin = rtmidi.RtMidiIn()
ports = range(midiin.getPortCount())
print(f"{len(ports)}(s) MIDI ports found")
if ports:
  for i in ports:
    print(f"{i}: {midiin.getPortName(i)}")
(.venv) alex@zub:~/Documents/midijam$ python .
 2(s) MIDI ports found
 0: Midi Through 14:0
 1: UM-1 20:0
 (.venv) alex@zub:~/Documents/midijam$ 

Next steps for this project: try echoing messages around to devices and some simple interaction in PyQt.


Music enjoyed whilst writing this:
– The Joy of Music, The Job of Real Estate by Vulfpeck

Leave a Reply

Your email address will not be published. Required fields are marked *