This chapter presents a brief overview of the Musical Instrument Digital Interface—MIDI. You should also have a more detailed reference on the subject, especially if you need to understand advanced features not covered here, such as MIDI Time Code and Sample Dump Standard.
Introduction
The MIDI specification details a combination of hardware and software, enabling synthesizers, computers, effects, and other MIDI devices to communicate with each other. Communication may be one-way (sending or receiving) or two-way (sending and receiving). For instance, a simple effects processor might have only MIDI input, to allow remote MIDI selection of program number. Synthesizers usually have MIDI input and output. They can receive requests to play notes from other keyboards or from a computer, and they can send notes played on the unit’s own keyboard. Program changes and actual program information can be sent and received.
Numbers and conventions
Often, MIDI documentation refers to number values in decimal, hexadecimal (often called hex), or binary, as is convenient. Tables often denote MIDI bytes as binary, such as 1011nnnn or 0vvvvvvv. Otherwise, if not noted or obvious, assume decimal. Hexadecimal is used as a shorthand for binary, usually preceded by a dollar sign ($)—as in this text—or followed by an H. (For instance, $7E and 7EH stand for hexadecimal 7E.)
MIDI hardware interface
The MIDI interface operates at 31.25 Kbaud, which works out to 320 microseconds per byte. Since most MIDI messages consist of two or three bytes, this means that it takes less than a millisecond to send a MIDI command.
The serial data is transferred in a current loop configuration. Many devices have a MIDI thru, which simply passes the MIDI input. You may use these to daisy-chain MIDI devices, but a chain of three devices is the practical limit, since each thru adds timing distortion to the MIDI signal, making it difficult for the receiver to interpret the data correctly. Y-cords are not appropriate for either splitting or combining MIDI data. You must use MIDI thru boxes to distribute, and mergers to combine MIDI streams.
Proper MIDI cables are made from shielded twisted pair cable, and should be a maximum length of 50 feet (15 meters). (Beyond using quality built MIDI cables, there is no advantage to using expensive or esoteric cables. They have no effect on the MIDI transfer or the sound quality of your instrument.)
As a final hardware note, the thoughtful folks that brought us MIDI deemed that the connections would be opto-isolated. This eliminates the possibility of ground loops through the MIDI cables. Also, you will not harm your MIDI ports if you accidentally plug an output into another output (but it won’t do anything interesting either).
MIDI data format
MIDI communications happen through multibyte messages consisting of one status byte, optionally followed by one or two data bytes, except for system exclusive messages, which have an arbitrary number of data bytes. Status bytes have their most significant bit (MSB) set to differentiate them from data bytes, so status bytes range in value from 128 ($80) to 255 ($FF), while data bytes range from 0 to 127 ($7F).
MIDI supports 16 message channels, letting you link multiple devices while maintaining individual control. Messages sent on specific channels, such as note on and note off, are called channel messages. Messages that are not channel oriented are called system messages. See Table 1 at the end of this chapter for a summary of MIDI messages.
Channel messages
Channel messages contain their channel number in the lower four bits of the status byte. A value of 0 corresponds to channel 1, 1 to channel 2, and so on, up to a value of 15 (for MIDI channel 16). When status bytes are listed as 1011nnnn (binary), the nnnn part refers to the channel part of the status byte. Similarly, in $Bn, the n refers to the channel part, in hexadecimal.
There are two types of channel messages: mode and voice. Mode messages are used to control the polyphony of a synthesizer, and to send all notes off commands. Voice messages are those that control a particular synthesizer voice on a particular channel.
Mode
MIDI allows for several variations in assigning voices to the 16 MIDI channels. These variations are controlled by channel mode messages. The status byte for channel mode messages is the same as for control change messages (a channel voice message). The two are differentiated by the data byte that follows, which is 0-120 for controllers and 121-127 for mode messages.
The mode messages give you control over whether omni is on or off, and whether the unit is responding in poly (voices assigned polyphonically) or mono (voices assigned monophonically) mode. Omni determines whether the device is responding to voice messages on a given channel (omni off), or to voice messages on all channels (omni on). These messages carry an implicit all notes off command. A separate all notes off mode message is also available.
Some modes let a device respond to more than one MIDI channel at a time. Mode messages are recognized by a receiver only when sent on the basic channel to which the receiver is assigned, regardless of the current mode. Since the modes implemented by a MIDI device are dependent on the actual hardware design, refer to your manual to get a more complete description.
Voice
Voice messages may be received on the basic channel and on other channels—all called voice channels—that are related specifically to the basic channel, depending on which mode has been selected.
Voice messages include all the messages that affect a specific instrument voice, such and note on and note off, pitch bend, modulation, aftertouch, and program number.
System messages
System messages are not encoded with channel numbers. There are three types of system messages: common, real-time, and exclusive.
Common
System common messages are intended for all units in a system, and include such messages as song select and tune request.
Real-Time
System real-time messages consist of a single status byte, and are used for timing and start/stop information. Real-time messages may be interspersed in the MIDI data stream, even within a multibyte message, without affecting the current status. Real-time messages are usually intercepted or generated at the MIDI driver level and used for timing information (when clocking externally, for instance); generally, you will not have to deal with these directly.
Exclusive
System exclusive (or sysex) messages are used to transfer information that may be specific to a given MIDI device. Generally, the actual data that is used describe a sound (usually called a program or patch) is not usable by another device, even from the same manufacturer. This is because the sound generating architecture varies dramatically between devices.
System exclusive messages begin with the system exclusive status byte (240, or $F0), followed by a manufacturer’s ID code. The number of data bytes that follow are determined by the manufacturer. Finally, the message is terminated by an end of exclusive (EOX) status byte (247, or $F7). So as not to get stuck reading an endless system exclusive message if the EOX is missing, the MIDI specification states that any status byte (other than real-time) acts to terminate a system exclusive message.
If you want to write a device editor or librarian stack, you will be primarily concerned with system exclusive messages. The device’s maker specifies its system exclusive format. Some manufacturers include a detailed system exclusive specification with each unit they sell. Others requires that you contact them directly to request system exclusive documentation for the device.
System exclusive messages usually get sent as a result of requesting them, either by sending a system exclusive message to your device requesting a patch dump, or by a front panel invocation. As with all MIDI messages, if you receive a system exclusive message that you don’t understand or are not interested in, simply ignore it and all associated data bytes.
A final note on system exclusive: Since this is the most flexible form of MIDI message, you might expect that this is where extensions to the MIDI specification would take place. Well, extensions have already been added here, with certain MIDI Time Code messages—which help to marry MIDI with SMPTE Time Code—and with the Sample Dump Standard format.
Additional status notes
Here are some notes on special status conditions and messages.
Running status
Channel messages (voice and mode) can have running status. That is, if the next channel status byte is the same as the last, it may be omitted. The receiver assumes that the accompanying data is of the same status as was last sent. Receipt of any other status byte except real-time terminates running status.
Running status is especially convenient for sending strings of note-on and note-off messages, when using “note on with velocity of 0” for note off, and for output of continuous controllers. This allows you to cut the length of such strings by one-third.
Undefined and unimplemented status
Undefined status bytes are reserved and should not be used. Any undefined or unimplemented status bytes received should be ignored. Any subsequent data bytes should be ignored until the next legal status byte is received. In this way, these unused status bytes can be added to the MIDI specification in the future without breaking your program.
Table 1
MIDI byte value summary
Message | Hex | Decimal | Data byte count |
---|---|---|---|
data | 00-7F | 0-127 | na |
Channel messages | |||
Note off | 8n | 128+n | 2 |
Note on | 9n | 144+n | 2 |
Polyphonic key pressure | An | 160+n | 2 |
Control/Mode change | Bn | 176+n | 2 |
Program change | Cn | 192+n | 1 |
Monophonic channel pressure | Dn | 208+n | 1 |
Pitch bend change | En | 224+n | 2 |
System exclusive | |||
System exclusive status | F0 | 240 | variable |
System common | |||
MIDI Time Code (MTC) | F1 | 241 | 1 |
Song position pointer | F2 | 242 | 2 |
Song select | F3 | 243 | 1 |
(Undefined) | F4 | 244 | 0 |
Cable select* | F5 | 245 | 1 |
Tune request | F6 | 246 | 0 |
End of exclusive (EOX) | F7 | 247 | 0 |
System real-time | |||
Timing clock | F8 | 248 | 0 |
(Undefined) | F9 | 249 | 0 |
Start | FA | 250 | 0 |
Continue | FB | 251 | 0 |
Stop | FC | 252 | 0 |
(Undefined) | FD | 253 | 0 |
Active sense | FE | 254 | 0 |
System reset | FF | 255 | 0 |
Note: n is the channel number – 1 (0 is channel 1, 1 is channel 2, …).
* Though officially undefined, some MIDI interfaces use this message to control cable access; a single data byte that follows designates the cable number on which subsequent MIDI messages are routed.