Exploring Notes in MIDI Files.
Sample MIDI File
I’m using Bach’s “Two-Part Invention No. 1” in this series. Here is a PDF of the sheet music and a MIDI file for the piece.
In Part 4 of this series we extracted the notes from the sample MIDI file. I listed them for the first measure like this for the treble clef.
1 2 3 4 5 6 7 8 9 10 11
Let’s look at what these notes are in more detail and at how Core MIDI lets us work with them. MIDI is a streaming control protocol. It was intended for playing music live and is action based. A MIDI device, like a keyboard controller, would send these events to a computer to play a quarter note that is middle C (C4).
- Start playing C4 at timestamp 0.0
- Stop playing C4 at timestamp 1.0
Core MIDI simplifies this for us by combining the Note On and the balancing Note Off message into one
MIDINoteMessage struct. When we get a note and cast the data into a note message we have all the information for one note.
1 2 3 4
1 2 3 4 5 6 7
The data for our note would look like this.
What does a
duration of 1.0 mean?
MIDI timestamps are a relative time indicator, not an absolute time. The default value of a quarter note is 1.0. A MIDI file starts with a timestamp of 0.0. All the notes will have a timestamp relative to 0.0. Here is a list of some of the common notes and their default
- Whole Note: 4.0
- Half Note: 2.0
- Quarter Note: 1.0
- Eighth Note: 0.5
- Sixteenth Note: 0.25
duration is the only data we have in MIDI about the length of a note. We do not have a flag saying what type of note it is in the score.
What about tied or dotted notes?
It’s very common in music scores to have tied notes like this
or dotted notes like this. How are these done in MIDI? They aren’t. There is no way in MIDI to do these notes. It is not a notation language, it is a streaming protocol. When a note is played all we hear is how long it was played, we have no information on how it was scored in the sheet music. The tied note would have this information in the
The dotted note would be
What about notes that could be either tied or dotted? We don’t have enough information to distinguish between them unless the note extends over a measure boundary. We can’t make a fully accurate score from a MIDI file, there is not enough information.
What about rests?
There is no MIDI event for a rest in a music score. To MIDI, a rest is the absence of a note. Our sample piece gives a good example of this. Here is the first measure.
The treble clef starts with a sixteenth note rest. The timestamp for the first note event is 0.25. This implies that there is a rest before the first note of 0.25, which is a sixteenth note rest.
1 2 3
In the bass clef the first note starts at 2.25. That is a half note and a sixteenth note into the measure. We can assume there are rests in the score for that length, but we can only guess as to how it has been notated.
1 2 3
Human Readable Notes?
Can we convert the MIDI data for a note into a human readable music note? We can finally answer yes to a question. The data for the note value can be from 0–127. Middle C (261.6 Hz) is 60. Every half step is a value of 1 away from the notes next to it. This gives us this chart for note translation.
The sharped notes can also be flatted notes depending on the key. We also know the key signature of each measure so we can accurately translate notes. You can use a simple array to translate as in this C function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
That’s all we do in this post in the series. The next logical step is to combine notes into measures. That will be the next entry.
Just keep coding,