From: johnj@echo.philips.nl (John Janssen)
Newsgroups: rec.music.synth
Subject: MIDI software basics (was: ATTN: ...)
Date: 30 Jul 92 11:55:25 GMT
Organization: Digital Equipment Corporation, E.C.H.O. development department


MIDI SOFTWARE BASICS
====================

Due to the many request for MIDI information, I wrote this little
introduction, which is meant for software people. It will not cover 
the hardware aspects like cables, pinning and routing, as they are 
described in every(?) manual of a system which handles MIDI.

TRANSPORT
=========

MIDI is an asynchronious serial interface. It uses 31.25 kBaud 
(=1MHz divided several times by 2), 8 data bits, 1 start bit and 1 stop bit. 
So, every UART can handle it, having the right timing available.

I did write several MIDI programs for atari, so should be able
to give some help on this topic too:
Use the standard BIOS functions to output to the MIDI port, 
as they are set correct for MIDI at start up!

PROTOCOL
========

MIDI includes a software protocol:
Every message (called an "event") is sent in the following way:
- First byte has the sign bit set, and is called status byte.
- Following bytes of tbat mesage must have the sign bit reset!

Each connected device looks for a status byte coming in, and see
if they have to react on it. If not they skip the rest of the event message
and wait for a next status byte, etc.

If the status byte indicates something the device should react on,
he will decode the (possible) rest of the event and reacts to it.

A device has two ways two detemine if it should react on the event:
1. If the device is capable to handle the specific event.
2. If the event included the correct MIDI channel number.

Remark:
  Most devices can be set to react on specific channel(s), however some
  are set to one channel which is fixed. Some devices even requires to be set
  in MIDI mode to look at MIDI at all (specially keyboards for home-use).
  Some devices can receive and send MIDI events on different MIDI channels
  while others will use the same channel for both. So refer to the device's
  manual for this.

STATUS BYTE
===========
The status byte contains info about the sort of event and if the event is 
meant for one MIDI channel only, the channel is in that byte as well.

Best way to recognise events is to use hexadecimal notation.
As the most significant bit (sign bit) is always set for the status byte, 
the status bytes range from $80 to $FF (note that I use the "$" to 
indicate hexadecimal notation).

The type of event is recognised by the first 'digit', while the
second digit contains the midi channel. Except for status bytes
which first digit is an F, these events do not contain a midi
channel but are using the second digit for to indicate a sub-command
(popular speaking).

In this way a maximum of 16 channels can be addressed via one MIDI port.

Example: $80. 
The 8 specifies the specific event, while the 0 indicates the midi channel.
Note that for the user, a digit of 0 for the midi channel is called
channel 1, a digit of 1 for the midi channel (within the byte) is
called channel 2, etc. So $80 is an event for midi channel 1.

The following commands are known:

$8x   Note off
$9x   Note on (sometimes used for note off too, see below)
$Ax   Poly pressure (aftertouch per key)
$Bx   Control commands
$Cx   Program change (=set preset)
$Dx   Aftertouch (per channel)
$Ex   Pitch bend

The x must be replaced with the MIDI channel as explained above,
so $80 is a note off command for the device at MIDI channel 1.

The rest of the commands are spilt in two groups (without channel info):
$F0-$F7 Non real time events
$F8-$FF Real time events

EVENTS
======

Most used events are of course the note on/note off events:
The first byte can be $90 (followed by a byte to indicate the key
(decimal 60 is the middle C), followed by the velocity (decimal
64 is average). A velocity of 0 is equal to note-off without
specific velocity info.
The note will sound as long as you do not send the corresponding 
note off event for that key, by either note on for that key (with
velocity equals to 0) or by sending its specific note off ($80)
event, which has simular following bytes as the note on event.

The poly pressure, when send while the key is sounding, may 
influence the way it sounds. It uses the similar two following bytes
as additional info as the note on/off commands.

Control events can be used to set a setting of the synth. The
second byte indicates which control to be set, while the third 
byte indicates its value.

Example:
For setting the volume, the second byte must contain the value 7, 
while the third byte contains the volume level (0= off, 127 = max.)

The program change event can be used to select a preset on the
synth (fixed ones and self programmed ones!). The second byte
contains the preset number. Again real data differs from the user view:
a value of 0 indicates preset, a value of 1 indicates preset 2, etc..
Note that this event has only two bytes.

The aftertouch event is simular to the poly pressure event, except that
all sounding notes of a channel will be influenced in the same way. The 
second (and last) byte of the event contains the velocity (0 is min,
127 is max).

The two bytes that follows the status byte of the pitch bend event
indicate the position from minimum to maximum that the pitch bend
is moved. The value ranges from 0 up to 16.000. The value is split
in two bytes each containing 7 bits of the value it self.

So far my explination of the events. I think the above is what you
need at first when you start with MIDI. You won't need the more
advanced ones until you have some experience with the explained ones.
That's why I do not describe them here.
 
EXAMPLES
========

$90 $40 $7F   Note on for middle C ($40=decimal 60) on channel 1 (very loud!).
$A0 $40 $20   Note pressure change for that same note (if still sounding).
$90 $40 $00   Note off for that same note and channel.
$BF $07 $7F   Set maximum volume for channel 16.
$C3 $00       Set preset 1 for channel 4.
$D0 $60       Pressure change for all notes of channel 1.
$E0 $00 $00   Pitch bend set to min value.
$E0 $40 $00   Pitch bend set to middle position.
$E0 $7F $7F   Pitch bend set to max value.

LAST REMARK
===========

Note that most synths/keyboards/modules/etc will not handle all 
possible MIDI events. So check the MIDI specification of your thing.
For everything goes: you get what you pay for:-)

John
-- 
John Janssen         Email: johnj@echo.tds.philips.nl
The Netherlands      or:    John.Janssen@atehv.bso.nl
Work: +31 40 756425 
Home: +31 77 513177  Atari Mega STE, PC 386 SX, MIDI, Astrology, C