Standard MIDI FIle (SMF) Format 1.0

Header Chunk
Track Chunk
[Track Chunk]
• • •

 

 

 

 

SMF = <header_chunk> + <track_chunk> [+ <track_chunk> ...]

type length Data
MThd 6 <format> <tracks> <division>
MTrk <length> <delta_time> <event> ...
:
MTrk <length> <delta_time> <event> ...

 

 

 

 

 


File Header Chunk

header_chunk = "MThd" + <header_length> + <format> + <n> + <division>

Chunk header
"MThd" (4bytes)
the literal string MThd, or 0x4d546864. These four characters at the start of the MIDI file indicate that this is a MIDI file.
Header length
4 bytes
length of the header chunk in bytes (always 6--the size of the next three fields).
Format/type
2 bytes
0 = single track file format
1 = multiple track file format
2 = multiple song file format (i.e., a series of type 0 files)
Number of tracks
2 bytes
number of track chunks that follow the header chunk (always 1 for type 0)
Division
2bytes
Unit of time for delta timing. If the positive, it represents the units per beat, e.g, +64 would mean 64 ticks per beat. If negative, delta times are in SMPTE compatible units.

TRack header Chunk

Chunk header
"MTrk" (4bytes)
the literal string MTrk, or 0x4d546864. These four characters at the start of each MIDI track.
Data length
4 bytes
length of the track data
MTrk events
n bytes
<delta-time> <event>, • • •

[MTrk events]

• • •

n bytes
<delta-time> <event>, • • •

A track may contain up to 16 MIDI channels

<Track Chunk> = <chunk type> <length> <MTrk event>+<MTrk event>+...

<MTrk event> = <delta-time> <event>

<delta-time> is stored as a variable-length quantity. It represents the amount of time before the following event.
<event> = <MIDI event> | <sysex event> | <meta-event>

<meta-event>

http://ourworld.compuserve.com/homepages/mark_clay/midi.htm

Some numbers in MIDI Files are represented in a form called a variable-length quantity, e.g. <delta-time>. These numbers are represented 7 bits per byte, most significant bits first. All bytes except the last have bit 7 set, and the last byte has bit 7 clear. If the number is between 0 and 127, it is thus represented exactly as one byte.

Here are some examples of numbers represented as variable-length quantities:

Number (hex)
Representation (hex)
00000000 00
00000040 40
0000007F 7F
00000080 81 00
00002000 C0 00
00003FFF FF 7F
00004000 81 80 00
00100000 C0 80 00
00lFFFFF FF FF 7F
00200000 81 80 80 00
08000000 C0 80 80 00
0FFFFFFF FF FF FF 7F

   // Take the input 'value' and prepare for output in 'buffer'.
   // Go from the least significant byte in 'value' (the rightmost byte) and 
   // build 'buffer' in reverse byte order, i.e. the least significant
   // byte to the left.

   WriteVarLen (long value)
   {
     long buffer;                // the encoded format in reverse order
     buffer = value & 0x7f;    
     while ((value >>= 7) > 0)   // build buffer
     {
       buffer <<= 8;             // shift to left by 8 bits (one byte)
       buffer |= 0x80;           // set the leftmost bit
       buffer += (value & 0x7f); // strip the leftmost bit then add
     }
     while (1) // output section
     {
       putc(buffer, outfile); // ouput rightmost byte
       if (buffer & 0x80)     // if not the last byte (leftmost bit is zero)
         buffer >>= 8;        // get the next byte
       else
         break;
     }
  }

  unsigned long ReadVarLen (void)
  {
    unsigned long value;
    char c;
    if ((value = getc(infile)) & 0x80) // if more than one byte
    {
      value &= 0x7F;       // strip the lefmost bit
      do                   // shift left 7 bits and add the next byte
      {                    // without the leftmost bit 
         value = (value << 7) + ((c = getc(infile)) & 0x7F);
      } while (c & 0x80); // while not the last byte
    }
    return value;
  }

http://crystal.apana.org.au/ghansper/midi_introduction/midi_file_format.html