MIDI to Music Box score converter
Keeping with the theme of things I've forgotten to blog about (every time I think I've mentioned everything, I remember something else), in this post I'm going to talk about yet another project of mine that's been happily sitting around (and I've nearly blogged about but then forgot on at least 3 separate occasions): A MIDI file to music box conversion script. A while ago, I bought one of these customisable music boxes:
(Above: My music box (centre), and the associated hole punching device it came with (top left).)
The basic principle is that you bunch holes in a piece of card, and then you feed it into the music box to make it play the notes you've punched into the card. Different variants exist with different numbers of notes - mine has a staggering 30 different nodes it can play!
It has a few problems though:
- The note names on the card are wrong
- Figuring out which one is which is a problem
- Once you've punched a hole, it's permanent
- Punching the holes is fiddly
Solving problem #4 might take a bit more work (a future project out-of-scope of this post), but the other 3 are definitely solvable.
MIDI is a protocol (and a file format) for storing notes from a variety of different instruments (this is just the tip of the iceberg, but it's all that's needed for this post), and it just so happens that there's a C♯ library on NuGet called DryWetMIDI that can read MIDI files in and allow one to iterate over the notes inside.
By using this and an homebrew SVG writer class (another blog post topic for another time once I've tidied it up), I implemented a command-line program I've called MusicBoxConverter (the name needs work - comment below if you can think of a better one) that converts MIDI files to an SVG file, which can then be printed (carefully - full instructions on the project's page - see below).
Before I continue, it's perhaps best to give an example of my (command line) program's output:
(Above: A lovely little tune from the TV classic The Clangers, converted for a 30 note music box by my MusicBoxConverter program. I do not own the song!)
The output from the program can (once printed to the correct size) then be cut out and pinned onto a piece of card for hole punching. I find paper clips work for this, but in future I might build myself an Arduino-powered device to punch holes for me.
The SVG generated has a bunch of useful features that makes reading it easy:
- Each note is marked by a blue circle with a red plus sign to help with accuracy (the hole puncher that came with mine has lines on it that make a plus shape over the viewing hole)
- Each hole is numbered to aid with getting it the right way around
- Big arrows in the background ensure you don't get it backwards
- The orange bar indicates the beginning
- The blue circle should always be at the bottom and the and the red circle at the top, so you don't get it upside down
- The green lines should be lined up with the lines on the card
While it's still a bit tedious to punch the holes, it's much easier be able to adapt a score in Musescore, export to MIDI, push it through MusicBoxConverter than doing lots of trial-and-error punching it directly unaided.
I won't explain how to use the program in this blog post in any detail, since it might change. However, the project's README explains in detail how to install and use it:
Something worth a particular mention here is the printing process for the generated SVGs. It's somewhat complicated, but this is unfortunately necessary in order to avoid rescaling the SVG during the conversion process - otherwise it doesn't come out the right size to be compatible with the music box.
A number of improvements stand out to me that I could make to this project. While it only supports 30 note music boxes at the moment, it can easily be extended to support multiple other different type of music box (I just don't have them to hand).
Implementing a GUI is another possible improvement but would take a lot of work, and might be best served as a different project that uses my MusicBoxConverter CLI under the hood.
Finally, as I mentioned above, in a future project (once I have a 3D printer) I want to investigate building an automated hole punching machine to make punching the holes much easier.
If you make something cool with this program, please comment below! I'd love to hear from you (and I may feature you in the README of the project too).
Sources and further reading
- Musescore - free and open source music notation program with a MIDI export function
- MusicBoxConverter (name suggestions wanted in the comments below)