ABC and MIDI: a Primer for ML Music

ABC files

You can think of ABC files as a text equivalent to sheet music.

They’re meant to be human readable and can be edited with any text editor.

The basic structure looks like this:

X: <identifier>
T: <title>
M: <meter>
K: <key>
<notes>

You can also have multiple voices in a single ABC song. In that case, it might look like this:

X: <identifier>
T: <title>
M: <meter>
K: <key>
V:1
<notes-one>
V:2
<notes-two>

% preceeds a comment. They can be on their own line or to the right of another line.

%% is used as a processor instruction for abc2midi. You’ll commonly see:

%%MIDI program 80

Which tells the MIDI processor to use a particular instrument. You can learn more about MIDI below.

I would highly recommend you use this website to verify your ABC, see the sheet music equivalent, and listen to a MIDI rendition.

This is a great reference if you see something in ABC you don’t understand.

MIDI files

For context, MIDI is a protocol used to e.g. allow your electric keyboard to send sound information to your computer. That data can be captured in a MIDI file and then played back.

A MIDI file doesn’t contain any sound. It’s a set of instructions. These instructions are called “messages” and say things like, “An acoustic grand piano should play note 76”.

There are four main message types: note_on, note_off, program_change, and control_change.

To play the MIDI file you need either a physical device (like the electric keyboard you used to record the sound) or a “soundfont” which defines each instrument (an acoustic grand piano, a harmonica, or a french horn) for a particular note.

Message types

note_on

note_on channel=0 note=66 velocity=81 time=0

note_on indicates a change in volume for a particular note on a particular channel.

channel is the channel the note is being played on. More on that later.

note is the note being played.

Mapping note numbers to note, octave

velocity is the volume of the note.

time is the difference in time between the last message and this one.

If these are the first two messages:

note_on channel=0 note=66 velocity=81 time=0
note_off channel=0 note=66 velocity=81 time=1000

Then that means note 66 will play for 1000 ticks.

If instead we had:

note_on channel=0 note=66 velocity=81 time=1000
note_off channel=0 note=66 velocity=81 time=1000

Then we would hear silence for 1000 ticks, then note 66 for 1000 ticks.

If instead:

note_on channel=0 note=66 velocity=81 time=1000
note_off channel=0 note=66 velocity=81 time=0

Then we would hear silence for 1000 ticks, then a super quick note and then silence again.

note_on as note_off

A note_on with a velocity of 0 also ends the note just like a note_off so you can see stuff like this:

note_on channel=10 note=69 velocity=92 time=0
note_on channel=10 note=69 velocity=0 time=115

Which will play note 69 for 115 ticks.

program_change

program_change channel=0 program=33 time=0

This changes the instrument used on channel 0 to 33 ( Electric Bass (finger)). You can find the rest of the list here (under program change).

control_change

control_change channel=0 control=64 value=0 time=0

Control changes can do a whole bunch of different things.

  • I don’t love Mido, but it looks like the only big supported Python MIDI library.
comments powered by Disqus