Good resources
hinton-instruments.co.uk/reference/midi/protocol/
midi.org/techspecs/midimessages.php
Communications Overview
Command bytes
Always 128 or greater (0x80 to 0xFF)
Includes things like note on, note off, pitch bend, etc.
Data bytes
Always less than 127 (0x00 to 0x7F)
Includes things like the pitch of the note to play, the velocity, or loudness of the note, and amount of pitch bend, etc.
MIDI packets
At least two bytes:- a status/command byte and a data byte.
Most common MIDI messages have three bytes:- a status/command byte followed by two data bytes. In a typical MIDI message this comprises of the action (note on, note off, pitch bend, etc), the pitch (musical pitch) and the velocity (how loud the sound should play).
Commands
Value (Hex) Command Data bytes
0x80-0x8F Note off 2 (note, velocity)
0x90-0x9F Note on 2 (note, velocity)
0xA0-0xAF Key Pressure 2 (note, key pressure)
0xB0-0xBF Control Change 2 (controller no., value)
0xC0-0xCF Program Change 1 (program no.)
0xD0-0xDF Channel Pressure 1 (pressure)
0xE0-0xEF Pitch Bend 2 (least significant byte, most significant byte)
The 0x0 to 0xF range is for the channel number, e.g. 0xB0 is Control change for channel 1, 0xB1 is addressing channel 2, etc.
Individual Commands
# = MIDI channel number from 0x0 to 0xF (0 – 15) in the command bytes below
0xB# 0x7B – All notes off
0x9# | 0x7B | 0x00
Clears all playing notes. Can be very handy during development!
0x9# – Note On
Indicates that a particular note should be played – the note should starts sounding.
0x9# | Note Number | Velocity
Note Number
There are 128 possible notes on a MIDI device, numbered 0 to 127. Middle C is note number 60.
Velocity
A value from 0 to 127. Indicates how much force the note should be played with (127 = maximum force). Default: 64 (0x40)
It's up to a MIDI device how it uses velocity information. Often it is used to tailor the VCA attack time and/or attack level (and therefore the overall volume of the note).
MIDI devices that can generate Note On messages, but don't implement velocity features, will transmit Note On messages with a preset velocity of 64.
Note On messages which have a velocity of 0 are considered to actually be a Note Off messages, this "trick" having been created to take advantage of running status, so that Note Off message can be incorporated in a run of Note On messages
A device which recognizes MIDI Note On messages must be able to recognize both a real Note Off as well as a Note On with 0 velocity (as a Note Off). There are many devices which generate real Note Off messages but many other devices thich use Note On with 0 velocity instead.
Every Note On should be followed by a respective Note Off message at some point. Even if the note's sound fades out before a Note Off for this note is received, at some later point a Note Off should be received. For example, if a MIDI device receives the following Note On:
If a device receives a Note On for a note which is already playing it is up to the device whether to add another layer of note playing sound or cut off the sound playing the preceding note and re-trigger the note.
Example Note On Commands
0x90 0x3C 0x40
Note On, MIDI channel 0, Middle C, velocity of 64
0x90 0x3C 0x00
Note Off, MIDI channel 0, Middle C, velocity of 0 = Note Off
0x8# – Note Off
Note Off can also be sent by sending Note On with velocity = 0
Indicates that a particular note should be released.
0x8# | Note Number | Velocity
Note number
0 to 127
Velocity
A value from 0 to 127 which indicates how quickly the note should be released (127 = fastest). Default: 64 (0x40)
It's up to a MIDI device how it uses velocity information.
MIDI devices which generate Note Off messages but don't implement velocity features will transmit Note Off messages with a preset velocity of 64.
Example Note Off Command:
0x80 0x3C 0x40
Note Off, MIDI Channel 0, Middle C, velocity of 64
Running Status
You are allowed to omit the first command byte when sending multiple commands of the same type. For instance if you want to send multiple Note On commands you could send this:
0x90 0x3C 0x7F
0x90 0x40 0x7F
0x90 0x43 0x7F
or this:
0x90 0x3C 0x7F 0x40 0x7F 0x43 0x7F
If a receiver see's a new byte after it assumes a command has finished it must assume that a new command of the same type is being sent.
Running status is only implemented for Voice Category messages (Status byte 0x80 to 0xEF).
0xB# 0x79 – Reset All Controllers
0x9# | 0x79 | 0x00
All controller values are reset to their default values.