*********************************** AM/FM ***********************************  MIDI standard (for programmers and advanced users) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ By Teijo Kinnunen On this TechCorner column I'll discuss the basic facts of the MIDI standard and the structures of the most common MIDI messages. These things are probably not necessary for a casual MIDI user, but it always helps to know them. My main source for the information listed here was the book "MIDI 1.0 - musiikkilaitteiden tiedonsiirtostandardi" by Otto Romanowski. Teijo Kinnunen, 9.9.1991 *********************************** AM/FM ***********************************  What is MIDI? ~~~~~~~~~~~~~ In short, MIDI is a "Musical Instrument Digital Interface". It's a standard for transferring musical data, established on 1983. It quickly came THE standard. Today, practically all electronic instruments have a MIDI interface. Despite its limitations, MIDI is a GREAT thing. Thanks to MIDI, it's now possible to create music of professional quality even at home with the help of your computer (Amiga, in this case ;-) and relatively low budget. MIDI data ~~~~~~~~~ All MIDI data consists of commands or hex data. The actual audio signal is NOT transferred. Instead, MIDI defines commands like "Play note C-4 on channel 3 with velocity 64". Most commands are real-time, so the receiving device will play the note immediately when it receives the "Note on" message. MIDI Hardware ~~~~~~~~~~~~~ Actually MIDI is a high-speed serial interface, with 5-pin DIN connector. The transfer rate is 31250 bits per second (+/- 10 %), 8 bits, 1 start bit and 1 stop bit. This is also the worst bottleneck of MIDI. MIDI can send approximately 1041 Note on messages per second. This may sound a lot, but there are also other types of messages sent very often (in particular, Note Off). Due to this, the practical speed might be about 300 - 400 notes/second. Unfortunately, when a large number of notes are played simultaneously, there may be a small - but audible - delay between the first and the last notes, and this may sound like the music is a bit "out of sync" in some conditions. So, this was due to the slowness of the serial connection. (When will we see MIDI devices with SCSI connectors?) In each MIDI compatible instrument there must be MIDI in and MIDI out connectors. Although it's actually optional, MIDI thru is implemented on nearly every device. The instrument receives the MIDI messages from the MIDI in connector. As noted above, the commands are usually executed immediately. The information received from MIDI in will be sent out from MIDI thru, unchanged. So, you can connect several instruments into a chain. The MIDI out sends the notes/data entered on that instrument. As you've probably already figured out, MIDI cables are unidirectional. The data is only sent in one direction on a cable. Therefore, if you e.g. want to connect a synthesizer to your computer you need two cables (in the case you want to both play and record, of course...) *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* MIDI Messages ~~~~~~~~~~~~~ ALL data is sent as messages. There are several kinds of messages, some of which are very short (1 byte), and some can be longer (hundreds of bytes). The standard messages, however, are not longer than 3 bytes. Usually, the message type can be recognized by looking at the first byte. Here's a list of the different types of messages: - channel voice messages (length 2 - 3 bytes) - channel mode messages (length 3 bytes) - system real time messages (length 1 byte) - system common messages (length 1 - 3 bytes) - system exclusive messages (length undefined) Each byte sent can be either a status (command) byte, or a data byte (e.g. a command qualifier). It's easy to distinguish a status byte from a data byte. Just look at the bit #7 of the byte. If it's set, it's a status byte. Otherwise it's a data byte. Therefore, each data byte can have values from $00 to $7F. For example, look at this "Note on" message: This is the status byte. Note that it has the highest bit set. | $90 $30 $40 | | These two are the data bytes. More information about what they mean is given later. Running status optimization ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Because MIDI should be as fast as possible, there's a way to slightly reduce the amount of MIDI data by leaving out subsequent status bytes if they are exactly the same. For example, consider the following example: Two "Note on" messages (on channel 1) are sent: (the first) $90 $30 $40 (the second) $90 $34 $40 This can be written as: (the first) $90 $30 $40 (the second) $34 $40 Therefore, you don't have to repeat the $90. Because the length of Note on messages are always 3 bytes (1 status + 2 data), the receiving device knows that if no new status byte is received after the 2 data bytes, the previous command is assumed. Note that real time messages don't affect the running status system. For example: Active sensing | $90 $30 $40 $FE $34 $40 The Active sensing (discussed later) message does not affect the note data at all. Real time messages may also appear during SysEx messages without affecting anything. If you're writing a program which receives MIDI data, you should be aware of this (and strip unwanted real time messages). Also, don't forget to handle the running status correctly! My MIDI output routines on AM/FM #1 handle the running status optimizing automatically, so if you're using them, you don't need to care about it. MIDI channels ~~~~~~~~~~~~~ Anyone who has been using MIDI knows, that there are 16 separate MIDI channels (1 - 16). They are used to direct MIDI messages to a certain instrument (otherwise every instrument would play every note, meaning that multi-timbral sound would be impossible). Usually you can select from which channel(s) each instrument will receive data, and to which send it. Most MIDI messages contain the MIDI channel the message is directed to. The MIDI channel is the lower nibble of the status byte ($0 - $F), for example: lower nibble = 0 -> MIDI channel 1 | $90 $20 $30 lower nibble = F -> MIDI channel 16 | $9F $20 $30 Now, let's have a list of the standard MIDI commands... ===== Channel voice messages ================================================ NOTE ON ~~~~~~~ Format: $9x $yy $zz x = MIDI channel ($0 - $F) yy = key ($00 - $7F) zz = velocity ($00 - $7F) This is probably the most frequently used MIDI command. It plays the note 'yy' at velocity 'zz'. The middle C has a 'yy' value of $3C. 'zz' is the velocity of the note, usually the same as the volume of the note. If the sending device can't recognize the velocity, the default value is 64 ($40). For each NOTE ON message, there must be a corresponding NOTE OFF message. (In plain English, you've to remember to turn off every note you've turned on.) If the velocity is 0, the message means 'NOTE OFF at velocity 64'. This is very useful for the running status optimization. The same status byte can be used for turning the note both on and off (instead of having to send a separate NOTE OFF command). Example: $93 $3D $7F Play the middle C# note on MIDI channel 4 at the maximum velocity ($7F). $93 $3D $00 Turns off the middle C# note on channel 4 (at velocity 64). The above commands (if sent in succession), could be optimized as: $93 $3D $7F ... $3D $00 So, the running status saves us from sending a byte. NOTE OFF ~~~~~~~~ Format: $8x $yy $zz x = MIDI channel ($0 - $F) yy = key ($00 - $7F) zz = velocity ($00 - $7F) This command turns off the note 'yy'. 'zz' is the velocity at which the key was released (default = 64 ($40)). Often you may want to use the NOTE ON command with velocity 0 to turn off a note. The advantage of using the NOTE OFF command instead, is that you can select the velocity (although the velocity is often ignored or has little affection). Example: $91 $50 $60 (turn on a note) $81 $50 $30 Turn the note off, at velocity $30. PROGRAM CHANGE ~~~~~~~~~~~~~~ Format: $Cx $yy x = MIDI channel ($0 - $F) yy = program number ($00 - $7F) The PROGRAM CHANGE message usually changes the preset number. How the number is actually interpreted, depends greatly on the receiving instrument. Example: $C0 $03 Select preset 4 on MIDI channel 0. CONTROL CHANGE ~~~~~~~~~~~~~~ Format: $Bx $yy $zz x = MIDI channel ($0 - $F) yy = controller number ($00 - $79) zz = new controller value ($00 - $7F) On nearly all MIDI instruments there are several controllers and switches. The CONTROL CHANGE command is a standard way to change most of them. There are 122 different controllers (many are currently undefined). The 'yy' byte is the number of the controller to change, and 'zz' is the new value. The interpretation of the controller value depends on the controller and its type. First, there are 7-bit controllers (values $00 - $7F). Then, there are 'switch' type controllers with only two values (on/off). Value $00 means 'off' and $7F 'on'. However, the input data should be interpreted so that $00 - $3F means 'off' and the greater values mean 'on'. Finally, there are 14-bit controllers. These controllers have two controller numbers. One for the MSB (most significant byte), and another for the LSB. So, a complete value must be passed with two CONTROL CHANGE commands. Then, there are parameter controllers (not used very often). With them, it may be possible to change the non-standard settings. There are also registered parameter numbers for e.g. setting the pitch bender range. Non-standard settings are documented in the manual of the MIDI device. The parameter number is changed by selecting the parameter using the 'registered/non-registered parameter number' controllers (both MSB and LSB) and then setting the parameter value with 'data entry' (MSB and LSB). Here's a list of the current recommendations of the controller numbers: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ controller number recommendation ----------------------------------------------------------------------- 14-bit controllers: (MSB = 7 highest bits) $00 undefined $01 modulation wheel $02 breath controller $03 undefined $04 foot controller $05 portamento time $06 data entry, MSB $07 main volume $08 balance $09 undefined $0A pan controller $0B expression controller $0C - $0F undefined $10 - $13 general purpose controllers $14 - $1F undefined 14-bit controllers: (LSB) $20 - $3F the lower 7 bits of controllers $00 - $1F 7-bit controllers/switches: $40 hold/sustain pedal $41 portamento $42 sostenuto $43 soft pedal $44 undefined $45 hold 2 $46 - $4F undefined $50 - $53 general purpose controllers $54 - $5B undefined $5C tremolo depth $5D chorus depth $5E detune depth $5F phaser depth Parameter controllers: $06 data entry, MSB $26 data entry, LSB $60 data increment $61 data decrement Parameter selectors: $62 non-registered parameter number, LSB $63 non-registered parameter number, MSB $64 registered parameter number, LSB $65 registered parameter number, MSB Undefined controllers: $66 - $79 ----------------------------------------------------------------------- Examples: $B2 $07 $30 Changes the volume of MIDI channel 3 to $30. $B0 $01 $40 $21 $00 Changes the modulation wheel on channel 1 to 8192 (128 * $40). PITCH BEND CHANGE ~~~~~~~~~~~~~~~~~ Format: $Ex $yy $zz x = MIDI channel ($0 - $F) yy = LSB of the pitch bend value ($00 - $7F) zz = MSB of the pitch bend value ($00 - $7F) The pitch bender of most MIDI instruments can be controlled with this command. (Actually it should be a standard controller, but because the pitch bender is used fairly often, it has an own command.) The pitch bender has 16384 possible positions (a 14-bit number, range $0000 - $3FFF). The middle position is $2000. The 14-bit number is sent in two 7-bit bytes. The lower 7 bits are sent in the first data byte, and the higher ones are sent in the second. Examples: $E0 $00 $00 Sets the channel 1 pitch bender to the lowest position. $E0 $00 $40 Resets the channel 1 bender ($2000: LSB = $00, MSB = $40 (only 7 bits/byte!) CHANNEL AFTERTOUCH ~~~~~~~~~~~~~~~~~~ Format: $Dx $yy x = MIDI channel ($0 - $F) yy = the channel pressure ($00 - $7F) Many MIDI keyboards/synthesizers can sense the changes of the pressure of a key, when it's held down. This is called aftertouch. Aftertouch can be used e.g. for vibrato or volume control. There are actually two types of aftertouch. The channel aftertouch is the more common of them. It affects all the notes on that MIDI channel (while polyphonic aftertouch allows each note to have its own aftertouch). Because the aftertouch changes very often (every time the player changes the pressure of his hands even a little), it may seriously load the MIDI transfer. Many sequencers, for example, can ignore aftertouch because it would fill the memory quickly. Example: $D6 $30 Changes the channel pressure (or channel aftertouch) of MIDI channel 7 to $30. POLYPHONIC AFTERTOUCH ~~~~~~~~~~~~~~~~~~~~~ Format: $Ax $yy $zz x = MIDI channel ($0 - $F) yy = key ($00 - $7F) zz = the key pressure ($00 - $7F) This is the second type of aftertouch. Each key can have its own aftertouch value. Example: $AF $40 $20 Changes the pressure of the middle C ($40) to $20, on MIDI channel 16. ===== Channel mode messages ================================================= CHANNEL MODE MESSAGE ~~~~~~~~~~~~~~~~~~~~ General format: $Bx $yy $zz x = MIDI channel ($0 - $F) yy = mode ($7A - $7F) zz = qualifier ($00 - $7F) Channel mode messages control how the receiving instrument reacts on the incoming voice messages. Local control ~~~~~~~~~~~~~ $Bx $7A $00 (off)/$7F (on) If the local control is off, the instrument (keyboard/synthesizer..) sends out the notes you push, but doesn't play them. The data received from MIDI in connector is played normally. All notes off ~~~~~~~~~~~~~ $Bx $7B $00 Turns off all notes on MIDI channel 'x'. Omni mode off ~~~~~~~~~~~~~ $Bx $7C $00 Sets the receiving instrument to accept data from ALL channels (so, the channel number of MIDI messages is ignored). Omni mode on ~~~~~~~~~~~~ $Bx $7D $00 Sets the receiving instruments to accept MIDI messages only on the specified receiving channels. Mono mode on ~~~~~~~~~~~~ $Bx $7E $00 - $0F Turns on the mono mode, on which the instrument works as a non-polyphonic (chords not possible) instrument. The second data byte is the number of channels to which non-polyphonic voice messages are sent. If zero, the receiver sets 1 voice/channel according to its number of voices. Note that the mono mode is seldom useful in today's polyphonic instruments. Poly mode on (mono mode off) ~~~~~~~~~~~~ $Bx $7F $00 Turns on the poly mode When the omni/poly switches are combined, there are a total of four different MIDI modes: MODE 1 = Omni on/poly MODE 2 = Omni on/mono MODE 3 = Omni off/poly MODE 4 = Omni off/mono ===== System common messages ================================================ SONG POSITION POINTER ~~~~~~~~~~~~~~~~~~~~~ Format: $F2 $xx $yy xx = the low 7 bits ($00 - $7F) yy = the high 7 bits ($00 - $7F) This command sets the song position pointer (in sequencers etc.). The position is specified in MIDI beats (1 MIDI beat = 6 MIDI-clocks = 1/8th note). SONG SELECT ~~~~~~~~~~~ Format: $F3 $xx xx = song number ($00 - $7F) This command selects the number of the song (for sequencers allowing multiple songs). The song position pointer is reset. TUNE REQUEST ~~~~~~~~~~~~ Format: $F6 'Tune request' command requests analog devices to tune themselves. (Few instruments recognize this message.) END OF EXCLUSIVE ~~~~~~~~~~~~~~~~ Format: $F7 At the end of 'System exclusive' messages, this command may be sent. It isn't absolutely necessary, however, as any status byte (except real time messages) terminates the system exclusive message. It's recommended, however. ===== System real time messages ============================================= The real time messages are used for general timing etc. on the MIDI system. These messages are one byte long, between $F8 - $FF. Real time messages do not disturb the running status, or terminate SysEx messages! TIMING CLOCK ~~~~~~~~~~~~ Format: $F8 Timing clock is the master clock for synchronizing the MIDI system. It should be sent in regular intervals 24 times/quarter note. START ~~~~~ Format: $FA Start command starts playing the sequence from the beginning. CONTINUE ~~~~~~~~ Format: $FB This command continues playing the sequence from the point it was stopped. STOP ~~~~ Format: $FC Stops playing the sequence. ACTIVE SENSING ~~~~~~~~~~~~~~ Format: $FE This optional command serves as an 'everything OK' message. It can be sent in 300 ms (or less) intervals when no other data is sent. If the sender has been sending this message, and there's a >300 ms delay with no data, the receiver turns off all notes, and resets. This is to ensure reliable operation in performance (if the MIDI wire happens to come off, all notes will be turned off). SYSTEM RESET ~~~~~~~~~~~~ Format: $FF Initializes the MIDI system. Must not be used loosely. ===== System exclusive messages ============================================= System exclusive (SysEx) messages are MACHINE DEPENDENT messages e.g. for sending patch data. There are also standardized SysEx messages for time code, and sample dumps, for example. The SysEx messages are also a way to do future expansions for the MIDI standard. General format: $F0 $id ...(any number of bytes)... $F7 (or other status byte) id = message identification ($01 - $6F = manufacturer ID) ($7D = universal non-commercial) ($7E = universal non-real time) ($7F = universal real time) The manufacturer ID is unique for each manufacturer. Some examples: $40 = Kawai $41 = Roland $42 = Korg $43 = Yamaha $44 = Casio The manufacturer ID can also be longer than one byte, e.g.: $00 $00 $16 = OpCode Systems The 'universal' types of messages are used for standardized SysExs. *********************************** AM/FM ***********************************