Playing MIDI files on Arduino – Part 2 Keeping to the Beat

MIDI_computer_music

Keeping time in music is very important. So it stands to reason that MIDI files include a number of parameters related to keeping time, and the MIDI standard also includes time synchronization messages to ensure that all the instruments keep to the same musical beat.

Part 1 covered the content of Standard MIDI Files. In this part we’ll look at the how to  keep the music synchronised to the beat, one of the more complex parts of playing a SMF.

What is a Beat?

The fundamental time unit of music is the beat. Beats can be slower or faster depending on the kind of music, and the tempo (speed of the beats) can change even in a single piece. Tempo in standard music notation are typically given in beats per minute (BPM).

In music a bar is a segment of time defined by a given number of beats of a given duration. The values which define a bar, are called the Time Signature.

Notes come in different power-of-two lengths. A MIDI quarter note normally is one beat long. A half note is two beats, and a whole note is four beats (as it takes up a whole measure, if you’re in 4). An eighth note is half a quarter note, so there are two eighth notes per beat, a sixteenth note is half an eighth so there are 4 sixteenths per beat, and so on.

Time Signature is two numbers, one on top of the other. The numerator describes the number of beats in a Bar, while the denominator describes of what note value a beat is (ie, how many quarter notes there are in a beat). So

  • 4/4 would be four quarter-notes per bar (MIDI default),
  • 4/2 would be four half-notes per bar (or 8 quarter notes),
  • 4/8 would be four eighth-notes per bar (or 2 quarter notes), and
  • 2/4 would be two quarter-notes per bar.

The default MIDI tempo is 120 BPM, and the default Time Signature is 4/4.

However the Set Tempo meta event can change these defaults. As MIDI only deals in quarter notes, the Set Tempo meta event only deals in quarter notes but also gives the time signature. If the time signature is 4/8, a quarter-note is not a beat since its described as an eighth-note, so using it to calculate beats per minute on its own is incorrect.

MIDI Beat Time

Musical timing is defined in fractions of a musical beat, so it makes sense to create a timebase that measures time as fractions of a beat. A quarter note is always one fourth of a whole note – regardless of the tempo. Similarly, a sixteenth note is always the same fraction of a beat. The rate at which the notes occur can change as the tempo changes, but the relative durations are always the same. So the ideal timebase divides a musical beat into many small bits that occur at a rate determined by the current tempo. Each of these tiny fractions of a beat is called a tick, and the number of ticks per beat is independent of the tempo.

The SMF header chunk contains a 16-bit value that gives the number of ticks per quarter note. If it is not specified the MIDI default is 48 ticks per quarter note. This value is a constant over the whole file. Within the MIDI data stream are tempo meta-events, which contain a 24-bit value that give the number of microseconds per quarter note. Divide this one by the first one, include the time signature, and you get the number of microseconds per tick.

SMF Time Specification

Events in a SMF are defined in terms of Delta Time. Delta Time determines when an event should be played relative to the track’s last event, in ticks. A delta time of zero ticks means that it should play simultaneously with the last event. A track’s first event delta time defines the amount of time (number of ticks) to wait before playing this first event. Events unaffected by time are still preceded by a delta time field, but should always use a value of zero and come first in the stream of track events.

Sequencing Time

Delta times are stored as ticks, so what we need to know now is how many ticks make up a quarter-note. This is given in the header of the SMF as Ticks Per Quarter Note.

The number of microseconds per quarter note is given in the Set tempo meta event and is by default 500,000 if not specified. So

midi_formula1

Delta times are cumulative, and the next event’s delta time needs to be added onto this one after it has been calculated. If the MIDI time division is 60 ticks per beat and if the microseconds per beat is 500,000, then 1 tick = 500,000 / 60 = 8333.33 microseconds. The fractional number of microseconds must be properly accounted for or the MIDI playback will drift away from the correctly synchronized time.

Programming a Tick Generator

A tick generator can be viewed as a black box function that has three inputs

MIDI_Tick_Time

  • Resolution in ticks/beat (or equivalently ticks/Quarter note). This fixes the smallest time interval to be generated.
  • Tempo in microseconds per beat, which determines how many ticks are generated in a set time interval.
  • Elapsed time which provides the fixed timebase for playing the midi events.

midi_formula2

Or, in terms of the calculated units of measure

midi_formula3

So the question remains as to where does all this data come from?

  • Time is the elapsed time between calls to the tick generator. This must be calculated by the tick generator based on the history of the previous call to the tick generator.
  • Tempo is the tempo determined by the Set Tempo MIDI event. Note this event only deals in Quarter Notes.
  • Resolution is held as TicksPerQuarterNote but is is also determined by the Time Signature. If time signature is specified a 4/8 then a quarter note is not a beat as it is one eighth note (denominator value). So the TicksPerQuarterNote resolution must be multiplied by (time_signature_demoninator)/4 to give the correct number of ticks in the beat.

In Part 3 we’ll explore hardware required to play MIDI notes and the functionality of the MD_MIDIFile library.

See Also:

Playing MIDI files on Arduino – Part 1 Standard MIDI Files

Playing MIDI files on Arduino – Part 3 Hardware and MD_MIDIFile Library

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s