Sponsored by

Navigate

Check these out

Using Raspberry Pi as an automatic MIDI logger

During my summer holidays I got an interesting idea: Pianoteq has a very nice feature of “always on MIDI logging” that saves everything you play on your keyboard while Pianoteq was on. I’ve previously made some MIDI projects and had a great idea:

How about building a small device that records everything I play on my piano, and save it as MIDI files?

This would enable me to later grab a good performance, and eliminate the “recording anxiety” I get if I know I’m recording and should definitely not do any mistakes during the next 1000+ notes. Furthermore, even with easy MIDI recording to USB stick, it’s still several manual steps plugging the memory stick in, starting recording, stopping it, lugging it to a computer, etc.

My first idea was to use some WLAN-enabled embedded device, but MIDI IN would require optoisolators and some custom electronics, and more modern digital pianos often come with only USB MIDI, so it could easily become an exercise in communication protocols. Fast forward a couple of minutes to my next revelation:

Recording MIDI with Raspbian

Turns out recording MIDI from a USB MIDI enabled device is really easy. When I plug in my Kawai CS-11 (sorry for the unsolicited link, I love my CS11 :) to the Pi (or just turn it on when it’s plugged in), dmesg shows that the Pi automatically notices the new MIDI device:

Easy! Only problem for automatic recording is, that you have to manually interrupt arecordmidi to end recording. However, if we run it on background (add & to the end of the command), we can just kill it later:

Automating MIDI logging with Python 3 and cron

Instead of running these commands myself, I made a simple Python 3 script to

1. List ALSA MIDI ports with “MIDI” mentioned (notice that “14:0 Midi Through” will not match as it is not all uppercase)
2. List all process ids of runnign arecordmidi
3. If there are ports available but no processes running, start recording
4. If there are processes running but no ports, kill the process

There are some additional tweaks in the code below to generate a MIDI file with current date and time in its name, and use my own timezone for the time instead of UTC. Here’s my full recmidi.py:

You need to run sudo pip3 install pytz to use the time zone support, or alternatively just delete the ‘tz = …’ line and remove tz from datetime.now(tz).... Oh, and of course you need to have sudo apt-get install python3 for the script to work.

I placed the recmidi.py in the pi user’s home directory, and used chmod a+x recmidi.py to make it executable. At this point, you can try the command manually: plug a USB midi device in and run it, it should start arecordmidi, and unplug it (or turn the keyboard off) and run the script again, it should kill the recording process. Oh, and remember to create the directory mentioned in recpath with mkdir -p /home/pi/midi.

Once you are satisfied the command does not throw any errors, you can add a cronjob to run it once a minute. Without additional changes it means, that the first minute of your piano playing might get missed, but we can correct that later. Just use crontab -e to edit your cron jobs and add the line:

* * * * * /home/pi/recmidi.py >> /home/pi/recmidi.log

You’re all set! Just keep the Pi connected to your MIDI device and powered up, and you’ll automatically get files like rec2017-08-01_18.13.48.mid in your recording folder! With the full set of Raspbian software at your fingertips, you could then do great stuff like:

Serve the files over HTTP server so you can access them with your browser

Use a software synthesizer to generate audio files of your playing sessions

Make a script to split the resulting MIDI files based on longer pauses in playback (or special pedal or keypress combinations)

Maybe even use audio fingerprinting to recognize what you are playing!

Starting recording right away

You can shorten the 1 minute delay in crontab by making the recmidi.py run endlessly:

That’s it! Now within 10 seconds of powering up your keyboard, the MIDI recording will start. Nice.

I even had a section about using udev to launch the recording session automatically, but I have yet to make this work (udev triggered the script 5+ times upon connection, midi files turned out empty, there were strange timeouts, you name it). So meanwhile, use the above solution or post me your solution.

Published by

Joonas Pihlajamaa

Coding since 1990 in Basic, C/C++, Perl, Java, PHP, Ruby and Python, to name a few. Also interested in math, movies, anime, and the occasional slashdot now and then. Oh, and I also have a real life, but lets not talk about it!
View all posts by Joonas Pihlajamaa