Plug — I’ve since done even more work with MIDI and created a MIDI to LSDJ app in Python
I’m really into music, If you spend 5 minutes talking to me you’ll probably realise that I care a little too much about how particular songs, albums and bands make me feel when I listen to them and why other bands just don’t cut the audio mustard.
I have a growing collection of notation files on my computer for my favourite songs, these are often in Guitar Pro (me being a guitar player) or in MIDI. The latter comes in very handy when I want to record myself playing the guitar parts as I can just import the drum track and the tempo and time signature changes are brought in with it.
I found this awesome Python library for parsing MIDI files and decided to hook it up to Matplotlib to see if I could visualise the notes in the file to make a nifty little representation of the song.
I’d used Matplotlib before at a hack day where we were parsing DICOM files and using Matplotlib to plot the x, y and z values we were able to build a 3D representation of the data in the file relatively easy.
Converting MIDI to a line
The python-midi library gives you a really helpful method called
read_midifile which handles the loading and parsing of the MIDI file.
The result of the
read_midifile method is a list of MIDI tracks which each contain a list of MIDI events such as:
- Setting the tempo —
- Setting the time signature —
- Starting and ending notes —
- Pitch Bending —
- End of the Track —
All of the events have a tick associated with it, this is relative by default but if you call
make_ticks_abs() on the loaded file it will return the ticks as absolute values. It can be a little confusing when looking at the events with relative ticks as you’ll see loads of a
0 ticks followed by high number ones, for the sake of plotting notes on a chart I used absolute ticks.
To get the pitch of the note in
midi.NoteOnEvents there’s a
.pitch property so by collecting these
NoteOnEvents and collecting the absolute tick and pitch values for each note we then have data to draw.