Changes

Jump to navigation Jump to search

MIDI format

5,488 bytes added, 01:20, 15 July 2019
m
6 revisions imported
Here's what a chunk's header looks like if you defined it in C:
<prec>
struct CHUNK_HEADER
{
unsigned long Length;
};
</prec>
<B><FONT COLOR=RED>NOTE:</FONT></B> The <B>Length</B> does not include the 8 byte chunk
header. It simply tells you how many bytes of data are in the chunk <U>following this header</U>.
And here's an example chunk header (with bytes expressed in hex) if you examined it with a hex editor:
4D 54 68 64 00 00 00 06
Note that the first 4 bytes make up the ascii ID of <B>MThd</B> (ie, the first four
The last two bytes indicate how many Pulses (i.e. clocks) Per Quarter Note (abbreviated as PPQN) resolution the time-stamps are based upon, <B>Division</B>. For example, if your sequencer has 96 ppqn, this field would be (in hex):
00 60
<B><FONT COLOR=RED>NOTE:</FONT></B> The 4 bytes that make up the <B>Length</B> are stored in (Motorola) "Big Endian" byte order, not (Intel) "Little Endian" reverse byte order. (ie, The 06 is the fourth byte instead
Here's what an MThd chunk looks like if you defined it in C:
<prec>
struct MTHD_CHUNK
{
unsigned short Division;
};
</prec>
And here's an example of a complete MThd chunk (with header) if you examined it in a hex editor:
Here's what an MTrk chunk looks like if you defined it in C:
<prec>
struct MTRK_CHUNK
{
unsigned char Data[]; /* Its actual size is Data[Length] */
};
</prec>
reaches the last byte of a variable length quantity, and returns a 32-bit value.
<prec>
void WriteVarLen(register unsigned long value)
{
return(value);
}
</prec>
<B><FONT COLOR=RED>NOTE:</FONT></B> The concept of variable length quantities (ie, breaking up a
==== Events in an MTrk ====
An MTrk can contain [http://www.borg.com/~jglatt/tech/midispec.htm MIDI events ] and non-MIDI events (ie, events that contain data such as
tempo settings, track names, etc).
The first (1 to 4) byte(s) in an MTrk will be the first event's delta-time as a variable length
quantity. The next data byte is actually the first byte of that event itself. I'll refer to this as
the event's <B>Status</B>. For [http://www.borg.com/~jglatt/tech/midispec.htm MIDI events], this will be the actual MIDI Status byte
(or the first midi data byte if running status). For example, if the byte is hex 90, then this
event is a <B>Note-On</B> upon midi channel 0. If for example, the byte was hex 23, you'd have to
For example, consider the following SYSEX MIDI message:
F0 7F 7F 04 01 7F 7F F7
This would be stored in a MIDI file as the following series of bytes (minus the delta-time
bytes which would precede it):
F0 07 7F 7F 04 01 7F 7F F7
The 07 above is the variable length quantity (which happens to fit in just one byte for this
all midi events, Meta-Events have a delta-time from the previous event regardless of what type
of event that may be. So, you can freely intermix MIDI and Meta events).
 
 
==== Meta-Events in an MTrk ====
----
===== Sequence Number =====
FF 00 02 <I><FONT COLOR=RED><B>ss ss</B></FONT></I>
or...
FF 00 00
This optional event must occur at the beginning of a MTrk (ie, before any non-zero
----
===== Text =====
FF 01 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
Any amount of text (amount of bytes = <I><FONT COLOR=GREEN><B>len</B></FONT></I>) for any
----
===== Copyright =====
FF 02 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
A copyright message. It's best to put this event at the beginning of an MTrk.
----
===== Sequence/Track Name =====
FF 03 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
The name of the sequence or track. It's best to put this event at the beginning of an
----
===== Instrument =====
FF 04 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
The name of the instrument (ie, MIDI module) being used to play the track. This may be
----
===== Lyric =====
FF 05 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
A song lyric which occurs on a given beat. A single Lyric
===== Marker =====
FF 06 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
The text for a marker which occurs on a given beat. Marker events might be used to denote a loop start and loop end (ie, where the sequence loops back to a previous event).
----
===== Cue Point=====
FF 07 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
The text for a cue point which occurs on a given beat. A Cue Point might be used to denote
----
===== Program (Patch) Name =====
FF 08 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
The name of the program (ie, patch) used to play the MTrk. This may be
wrong value when played on a General MIDI instrument. Intelligent software can use the
Program Name event to look up the correct value for the <B>MIDI Program Change</B> event.
 
Note that <I><FONT COLOR=GREEN><B>len</B></FONT></I> could be a series of bytes since it
is expressed as a variable length quantity.
----
===== Device (Port) Name =====
FF 09 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>
 
The name of the MIDI device (port) where the track is routed. This replaces the "MIDI Port"
Meta-Event which some sequencers formally used to route MIDI tracks to various MIDI ports (in
order to support more than 16 MIDI channels).
 
For example, assume that you have a MIDI interface that has 4 MIDI output ports. They are
listed as "MIDI Out 1", "MIDI Out 2", "MIDI Out 3", and "MIDI Out 4". If you wished a particular
MTrk to use "MIDI Out 1" then you would put a Port Name Meta-event at the beginning of the MTrk,
with "MIDI Out 1" as the <I><FONT COLOR=RED><B>text</B></FONT></I>.
 
All MIDI events that occur in the MTrk, after a given Port Name event, will be routed to that
port.
 
In a format 0 MIDI file, it would be permissible to have numerous Port Name events intermixed
with MIDI events, so that the one MTrk could address numerous ports. But that would likely make
the MIDI file much larger than it need be. The Port Name event is useful primarily in format 1
MIDI files, where each MTrk gets routed to one particular port.
 
Note that <B>len</B> could be a series of bytes since it is expressed as a variable length
quantity.
----
===== End of Track =====
FF 2F 00
 
This event is <u>not</u> optional. It must be the last event in every MTrk. It's used as a definitive marking of the end of an MTrk. Only 1 per MTrk.
----
===== Tempo =====
FF 51 03 <I><FONT COLOR=RED><B>tt tt tt</B></FONT></I>
 
Indicates a tempo change. The 3 data bytes of <B>tt tt tt</B> are the tempo in microseconds per quarter note. In other
words, the microsecond tempo value tells you how long each one of your sequencer's "quarter notes" should be. For example,
if you have the 3 bytes of 07 A1 20, then each quarter note should be 0x07A120 (or 500,000) microseconds long.
 
So, the MIDI file format expresses tempo as "the amount of time (ie, microseconds) per quarter note".
 
<B><FONT COLOR=RED>NOTE:</FONT></B> If there are no tempo events in a MIDI file, then the
tempo is assumed to be 120 BPM
 
In a format 0 file, the tempo changes are scattered throughout the one
MTrk. In format 1, the very first MTrk should consist of only the tempo (and time signature) events
so that it could be read by some device capable of generating a "tempo map". It is best not to
place MIDI events in this MTrk. In format 2, each
MTrk should begin with at least one initial tempo (and time signature) event.
----
===== SMPTE Offset =====
FF 54 05 <I><FONT COLOR=RED><B>hr mn se fr ff</B></FONT></I>
 
Designates the SMPTE start time (hours, minutes, seconds, frames, subframes) of the MTrk. It should
be at the start of the MTrk. The hour should not be encoded with the SMPTE format as it is in
<B>MIDI Time Code</B>. In a format 1 file, the SMPTE OFFSET must be stored with the tempo
map (ie, the first MTrk), and has no meaning in any other MTrk. The <FONT COLOR=RED><B>ff</B></FONT>
field contains fractional frames in 100ths of a frame, even in SMPTE based MTrks which specify a different
frame subdivision for delta-times (ie, different from the subframe setting in the MThd).
----
===== Time Signature =====
FF 58 04 <I><FONT COLOR=RED><B>nn dd cc bb</B></FONT></I>
 
Time signature is expressed as 4 numbers. <I><FONT COLOR=RED><B>nn</B></FONT></I>
and <I><FONT COLOR=RED><B>dd</B></FONT></I> represent the
"numerator" and "denominator" of the signature as notated on sheet music. The denominator is a
negative power of 2: 2 = quarter note, 3 = eighth, etc.
 
The <I><FONT COLOR=RED><B>cc</B></FONT></I> expresses the number of
MIDI clocks in a metronome click.
 
The <I><FONT COLOR=RED><B>bb</B></FONT></I> parameter expresses the number of notated
32nd notes in a MIDI quarter note (24 MIDI clocks). This event allows a program to relate what
MIDI thinks of as a quarter, to something entirely different.
 
For example, 6/8 time with a
metronome click every 3 eighth notes and 24 clocks per quarter note would be the following
event:
 
FF 58 04 06 03 18 08
 
<B><FONT COLOR=RED>NOTE:</FONT></B> If there are no time signature events in a MIDI file,
then the time signature is assumed to be 4/4.
 
In a format 0 file, the time signatures changes are scattered throughout the one
MTrk. In format 1, the very first MTrk should consist of only the time signature (and tempo) events
so that it could be read by some device capable of generating a "tempo map". It is best not to
place MIDI events in this MTrk. In format 2, each
MTrk should begin with at least one initial time signature (and tempo) event.
----
===== Key Signature =====
FF 59 02 <I><FONT COLOR=RED><B>sf mi</B></FONT></I>
 
<I><FONT COLOR=RED><B>sf</B></FONT></I> = -7 for 7 flats, -1 for 1 flat, etc, 0 for key of c, 1 for 1 sharp, etc.
 
<I><FONT COLOR=RED><B>mi</B></FONT></I> = 0 for major, 1 for minor
----
===== Proprietary Event =====
FF 7F <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>data</B></FONT></I>
 
This can be used by a program to store proprietary data. The first byte(s) should be a unique ID
of some sort so that a program can identity whether the event belongs to it, or to some other
program. A 4 character (ie, ascii) ID is recommended for such.
Note that <I><FONT COLOR=GREEN><B>len</B></FONT></I> could be a series of bytes since it
is expressed as a variable length quantity.

Navigation menu