Working with MIDI data in Python using Mido
Time to read: 4 minutes
MIDI is an extremely popular and versatile format for music data, whether you're using it as a digital musical instrument interface or just transcribing music in it to show your bandmates new songs. Mido is a Python library you can use to interact with MIDI in your code.
Let's walk through the basics of working with MIDI data using the Mido Python library.
Setting up
Before moving on, you will need to make sure you have an up to date version of Python 3 and pip installed. Make sure you create and activate a virtual environment before installing Mido.
Run the following command to install Mido in your virtual environment:
In the rest of this post, we will be working with these two MIDI files as examples. Download them and save them to the directory where you want your code to run.
VampireKillerCV1.mid
is the stage 1 music from the original Castlevania game on the NES. VampireKillerCV3.mid
is the Castlevania 3 version of the same song, which is slightly remixed and plays later in the game when you enter Dracula's Castle (hence the track name "Deja Vu")!
Working with MidiFile objects and track data
The MidiFile
object is one of the basic types you're going to work with when using Mido. As the name implies, it can be used to read, write and play back MIDI files. You can create a new MIDI file or open up an existing file as a MidiFile
object. Any changes you make to this object won't be written until you call the save()
method with a filename.
Let's start by opening VampireKillerCV1.mid
and examining its properties. Open up your Python shell and follow along with this code which will create a new MidiFile
object with the contents of the file we want:
We are using clip=True
just in case we end up opening a file with notes over 127 velocity, the maximum for a note in a MIDI file. This isn't a typical scenario and would usually mean the data is corrupted, but when working with large amounts of files it's good to keep in mind that this is a possibility. This would clip the velocity of all notes to 127 if they are higher than that.
You should see some output similar to this:
<midi file 'VampireKillerCV1.mid' type 1, 9 tracks, 4754 messages>
This means that the MIDI file has 9 synchronous tracks, with 4754 messages inside of them. Each MidiFile
has a type
property that designates how the tracks interact with each other.
There are three types of MIDI files:
- type 0 (single track): all messages are saved in one track
- type 1 (synchronous): all tracks start at the same time
- type 2 (asynchronous): each track is independent of the others
Let's loop through some of the tracks and see what we find:
Your output should look something like this:
This allows you to see the track titles and how many messages are in each track. You can loop through the messages in a track:
This particular track contains only meta information about the MIDI file in general such as the tempo and time signature, but other tracks contain actual musical data:
Now let's actually do something with this info!
Manipulating MIDI tracks and writing new files
If you've opened this file in a music program such as GarageBand, you might have noticed that there are duplicate tracks for the main melody and harmony (corresponding to the NES square wave channels 1 and 2 in the source tune). This kind of thing is pretty common when dealing with video game music MIDIs, and might seem unnecessary.
Let's write some code to clean this file up and remove the duplicate tracks to make it more closely resemble the original NES version. Create and open a file called remove_duplicates.py
, and add the following code to it:
This code loops through the tracks in our MIDI file, searches for tracks that have the same exact number of messages, and removes them from the overall MIDI file to get rid of the duplicates.
The new MIDI file is saved to new_song.mid
to keep the original file intact. Run the code with the following command:
Now open up new_song.mid
and see for yourself that the MIDI file has no duplicate tracks!
Let's make some new music
Cleaning up MIDI files is cool, but making new music is a lot more fun! If you open VampireKillerCV3.mid
you can hear the Castlevania 3 version of this song is remixed to be a little more upbeat. The melody stays mostly the same but the harmony adds some more flavor, and the bass and drums are both played at a more consistent pace as opposed to the original game.
Let's write some code to take the bass and drum tracks from the Castlevania 3 version and mash them up with the original melody and harmony tracks from the first Castlevania game.
Open a file called mashup.py
and add the following code to it:
This code deletes the bass and drum tracks from the first file, and adds the bass and drum tracks from the second file. Notice that we are opening new_song.mid
so that we have the version of the MIDI with no duplicate tracks, and saving the new tune to a file called mashup.mid
.
Run this code and open mashup.mid
and jam out to our new remix of Vampire Killer from Castlevania 1 and 3.
Now what?
There is a lot you can do with MIDI data. You can use it to write interfaces for digital instruments, or use it to clean up data to train on a neural network with Magenta. This post only brushed the surface of the functionality of the Mido library, but I hope you feel a little more equipped to take this further and use it for your own MIDI files!
Feel free to reach out for any questions or to show off any cool music you make with Python:
- Email: Sagnew@twilio.com
- Twitter: @Sagnewshreds
- GitHub: Sagnew
- Twitch (streaming live code): Sagnewshreds
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.