MD_MIDIFile Standard MIDI File Processing 2.6
Library to play Standard MIDI Files (SMF)
SMF Format Definition

MIDI

MIDI (Musical Instrument Digital Interface) is a technical standard that describes a protocol, digital interface and connectors and allows a wide variety of electronic musical instruments, computers and other related devices to connect and communicate with one another. A single MIDI link can carry up to sixteen channels of information, each of which can be routed to a separate device.

MIDI carries event messages that specify notation, pitch and velocity, control signals for parameters such as volume, vibrato, audio panning, cues, and clock signals that set and synchronize tempo between multiple devices. These messages are sent to other devices where they control sound generation and other features. This data can also be recorded into a hardware or software device called a sequencer, which can be used to edit the data and to play it back at a later time. These recordings are usually in Standard MIDI File (SMF) format.

Advantages of MIDI include compactness (an entire song can be coded in a few kilobytes), ease of modification and manipulation and choice of instruments.

Standard MIDI File Format

The Standard MIDI File (SMF) is a file format that provides a standardized way for sequences to be saved, transported, and opened in other systems. The compact size of these files has led to their widespread use in computers, mobile phone ring tones, web page authoring and greeting cards. They are intended for universal use, and include such information as note values, timing and track names. Lyrics may be included as metadata, and can be displayed by karaoke machines. The SMF specification was developed and is maintained by the MIDI Manufacturer's Association (MMA).

SMFs are created as an export format of software sequencers or hardware workstations. They organize MIDI messages into one or more parallel tracks, and time stamp the events so that they can be played back in sequence. A SMF file is arranged into "chunks". It starts with a header chunk and is followed by one or more track chunks.

The header chunk contains the arrangement's setup data, which may include such things as tempo and instrumentation, and information such as the song's composer. The header also specifies which of three SMF formats applies to the file

  • A type 0 file contains the entire performance, merged onto a single track
  • A type 1 files may contain any number of tracks, running synchronously.
  • A type 2 files may contain any number of tracks, running asynchronously. This type is rarely used and not supported by this library.

Each track chunk defines a logical track and contains events to be processed at specific time intervals. Events can be one of three types:

  • MIDI Events (status bytes 0x8n - 0xEn)

These correspond to the standard Channel MIDI messages. In this case 'n' is the MIDI channel (0 - 15). This status byte will be followed by 1 or 2 data bytes, as is usual for the particular MIDI message. Any valid Channel MIDI message can be included in a MIDI file.

If the first (status) byte is less than 128 (hex 80), this implies that running status is in effect, and that this byte is actually the first data byte (the status carrying over from the previous MIDI event). This can only be the case if the immediately previous event was also a MIDI event, ie SysEx and Meta events interrupt (clear) running status.

MIDI events may be processed by the calling program through a callback with relevant data passed through a pointer to a midi_event data structure.

  • SYSEX events (status bytes 0xF0 and 0xF7)

There are a couple of ways in which system exclusive messages can be encoded - as a single message (using the 0xF0 status), or split into packets (using the 0xF7 status). The 0xF7 status is also used for sending escape sequences.

SYSEX events may be processed by the calling program through a callback with relevant data passed through a pointer to a sysex_event data structure.

  • META events (status byte 0xFF)

These contain additional information which would not be in the MIDI data stream itself. TimeSig, KeySig, Tempo, TrackName, Text, Marker, Special, EOT (End of Track) are the most common such events being some of the most common.

Relevant META events are processed by the library code, but this is only a subset of all the available events.

META events may be processed by the calling program through a callback with relevant data passed through a pointer to a meta_event data structure.

Note that the status bytes associated with System Common messages (0xF1 to 0xF6 inclusive) and System Real Time messages (0xF8 to 0xFE inclusive) are not valid within a MIDI file. For the rare occasion when you do need to include one of these messages, it should be embedded within a SysEx escape sequence.

SMF Format Grammar

This grammar is from http://www.ccarh.org/courses/253/handout/smf/ and is useful to understand the structure of the file in a programmer-friendly format.

 <descriptor:length> means 'length' bytes, MSB first
 <descriptor:v> means variable length argument (special format)

 SMF := <header_chunk> + <track_chunk> [ + <track_chunk> ... ]
 header chunk := "MThd" + <header_length:4> + <format:2> + <num_tracks:2> + <time_division:2>
 track_chunk := "MTrk" + <length:4> + <track_event> [ + <track_event> ... ]
 track_event := <time:v> + [ <midi_event> | <meta_event> | <sysex_event> ]
 midi_event := any MIDI channel message, including running status
 meta_event := 0xFF + <meta_type:1> + <length:v> + <event_data_bytes>
 sysex_event := 0xF0 + <len:1> + <data_bytes> + 0xF7
 sysex_event := 0xF7 + <len:1> + <data_bytes> + 0xF7