Alex
—May 08, 2022
"Let's read MIDI files," I said. "It'll be easy," I said. "This is the standard musical interchange format, and has been for decades, it must be well-defined and simple to parse," I said.
Firstly, MIDI files are not (as I had assumed) text files, they are binary files, so I am unable to parse them directly. Luckily Java has the javax.sound.midi
library which can do some of the work for me. Using it wasn't instantly straightforward, but I found this handy article on the processing forums.
I found a MIDI copy of In The Hall Of The Mountain King and tested the code on it.
This was a decent start as, with minimal effort from me, I had a list of notes taken from a MIDI file, which could easily be swapped out for basically any song in existence.
One small note, for some reason the MIDI file I had had a random empty track on it.A track seems to be a bit of a modern invention on top of the original system of channels. A MIDI file/device/instrument can (normally) only have 16 output channels, as a holdover from when data was being sent down physical 16-wite cables. The ability to subdivide things further (e.g. each different drum in a kit having a separate track, but the same channel) can be useful during the editing process.My understanding is that I should be playing all tracks and all channels simultaneously.
The next thing to do was to try actually playing this, which means I need to convert MIDI note
values to frequencies. I found a handy gist on GitHub which I was ready to convert to Java, but I typed out the function name midiNoteToFrequency
and GitHub Copilot (which I forgot I had really) did it for me!
Ignoring channels, for now, I removed the SONG
array and added a line to the loop in the MIDI demo code which would create SnakeFood
objects, ready to be played. And here is the finished result!
Hmm, something isn't quite right! From the screenshot I can see there are 2 channels (0 and 1) and I am just playing them both at the same time. Here are the two channels played separately
Channel 0
Channel 1
Channel 1 sounds a bit odd/boring but it's only a baseline, I'm sure it'll sound fine in context. Channel 0 is clearly recognizable and highlights my next problem: note duration. The proper song (as demonstrated in my last post) should have 6 quavers and then a crotchet, however here all notes are being played with the same duration so it just sounds like 7 quavers
I'll figure this out in part 4!