Good resources

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).


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.


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


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.



We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.


Your email address will not be published.