Visualising MIDI files with Python
— Python, Music, Data Visualisation — 2 min read
Visualising MIDI files with Python
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 —
midi.SetTempoEvent
- Setting the time signature —
midi.TimeSignatureEvent
- Starting and ending notes —
midi.NoteOnEvent
andmidi.NoteOffEvent
respectively - Pitch Bending —
midi.PitchWheelEvent
- End of the Track —
midi.EndOfTrackEvent
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.
To plot these values in Matplotlib we just need to pass it a list of x and y values, for multiple tracks we just add more x and y values such as:
pyplot.plot(track1_ticks, track1_pitches, track2_ticks, track2_pitches)
Or create a list of ticks and pitches and then unpack that list into the plot
function. Finally we just need to call pyplot.show()
which will bring up a rendered chart.
You can find my final file at https://gitlab.com/colinfwren/midivis.
The end result
Here’s a bunch of songs I have on my computer put through my program.