Back MIDI Reference Next

Articles Index

This page describes the common types of MIDI Messages.

Channel Messages

These messages are addressed to a specific MIDI channel.

In the following table, an "x" specifies any MIDI channel (0 - 15). Thus "status byte 8x" means any value from 80 to 8F.

Note that some message types have two data bytes; others have only one.

Type Status (Hex) Data (value = 0-127)
Note off 8x note, velocity
Note on 9x note, velocity (velocity 0 = note off)
Polyphonic pressure Ax note, value
Controller change Bx controller, value
Program change Cx program
Channel pressure Dx value
Pitch bend Ex value, value (two bytes). However, many devices accept a single data byte (the MSB byte)

System Messages

System messages are intended for the whole MIDI system - not channel specific.

Note that any non-realtime status byte ends a System Exclusive message; F7 (EOX) is not required at the end of a SysEx message.

Realtime status bytes may appear any time in the MIDI data stream, including in the middle of a SysEx message.

Type Status (Hex) Data (value = 0-127)
System Exclusive F0 data
Time Code F1 one byte
Song Position Pointer F2 two bytes: lsb msb
Song Select F3 one byte: song number 0 - 127
(undefined) F4  
(undefined) F5  
Tune Request F6 no data
EOX (End of System Exclusive) F7  

System Exclusive message examples:
• GM System On = F0 7E 7F 09 01 F7
• XG System On = F0 43 10 4C 00 00 7E 00 F7
• XG Works On = F0 43 76 1A 10 01 01 01 01 01 01 01 01 F7
• Yamaha = F0 43 73 39 F1 00 46 00 F7
• XG Reset = F0 43 10 4C 00 00 7F 00 F7

Realtime Messages

Realtime messages are not associated with any one MIDI channel.

They can appear in the MIDI data stream at any time.

These messages consist of a single status byte; they have no data bytes.

Type Status (Hex)
Clock F8
(undefined) F9
Start FA
Continue FB
Stop FC
(undefined) FD
Active Sensing FE
System Reset FF
Meta Messages

Meta messages are not associated with any one MIDI channel.

They can appear in the MIDI data stream at any time (except for Time Signature and End of Track).

However it is recommended to insert most of the messages in the beginning of the stream/file.

Note that Meta messages are not for realtime use; but for use in MIDI files.
• 1. byte: FF = status byte (always FF)
• 2. byte: Message (event) type
• 3. byte: Length of the remaining data bytes
• 4. and following bytes: The data itself.

Type Status (FF) Data (Hex) Comments
Sequence Number FF 00 02 ss ss Specifies the number of a sequence.
The two data bytes ss ss, are that number which corresponds to the MIDI Cue message.
Text FF 01 len text Any amount of text (amount of bytes = len) for any purpose.
This event is primarily used to add "comments" to a MIDI file which a program would be expected to ignore when loading that file.
Copyright FF 02 len text A copyright message (ie, text).
Sequence/Track Name FF 03 len text The name of the sequence or track (ie, text).
Instrument FF 04 len text The name of the instrument that the track plays (ie, text).
Lyric FF 05 len text A song lyric (ie, text) which occurs on a given beat.
A single Lyric MetaEvent should contain only one syllable.
Marker FF 06 len text A marker (ie, text) 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 len text A cue point (ie, text) which occurs on a given beat.
A Cue Point might be used to denote where a WAVE (ie, sampled sound) file starts playing, where the text would be the WAVE's filename.
MIDI Channel FF 20 01 cc Specifies to which MIDI Channel any subsequent MetaEvent or System Exclusive events are associated.
The data byte cc, is the MIDI channel, where 0 would be the first channel.
MIDI Port FF 21 01 pp Specifies out of which MIDI Port (ie, buss) the MIDI events in the MIDI track go.
The data byte pp, is the port number, where 0 would be the first MIDI buss in the system.
End of Track FF 2F 00 This message is NOT optional. It must be the last event in every MIDI track. It's used as a definitive marking of the end of a MIDI track. Only 1 per MIDI track.
Tempo FF 51 03 tt tt tt Indicates a tempo change.
The 3 data bytes of tt tt tt 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.
If tt tt tt = 07 A1 20, then each quarter note should be 07 A1 20 (or 500,000) microseconds long. (Check with your Windows Calculator in Scientific Mode).
Normally, musicians express tempo as "the amount of quarter notes in every minute (ie, time period)". This is the opposite of the way that the MIDI file format expresses it.
To convert the MIDI file format's tempo to BPM (beats per minute): BPM = 60,000,000/(tt tt tt)
For example, a tempo of 120 BPM = 07 A1 20 microseconds per quarter note.
NOTE:
• If no Tempo is defined at all, the default value 120 BPM is assumed.
SMPTE Offset FF 54 05 hr mn se fr ff Designates the SMPTE start time (hours, minutes, secs, frames, subframes) of the MIDI track.
Time Signature FF 58 04 nn dd cc bb Time signature is expressed as 4 numbers.
• nn and dd 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.
• cc expresses the number of MIDI clocks in a metronome click.
• bb 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
NOTE:
• If no Time Signature is defined, the default value 4/4 is assumed.
• Time Signature can only be redefined at measure beginnings.
Key Signature FF 59 02 sf mi • sf = -7 for 7 flats, -1 for 1 flat, etc, 0 for key of c, 1 for 1 sharp, etc.
• mi = 0 for major, 1 for minor
Proprietary Event FF 7F len data 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 identify whether the event belongs to it, or to some other program. A 4 character (ie, ascii) ID is recommended for such.