MIDI Data Conversions
Revised: 98Jul08
Number System Basics
What is Binary?
Computers are simply switches. Millions of them, perhaps, and specially
organized, but really just lots of switches.
A switch is open or closed. Think of your flashlight. It's just a switch,
a power source (battery), and a light. If the switch is open, electricity
can't flow, and the light is off. If the switch is open, electricity flows,
and the light is on.
We can show if a switch is open or closed by using a one ("1") or a
zero ("0"). For example, if the switch is open, let's call that a zero,
or "0". If the switch is closed, that would be a one, or "1". This is quite
arbitrary - we could just as easily done it the other way around (and we
actually do just that in intermediate binary class), but for now, 0 = off,
or nothing, and 1 = on, or something.
Representing Numbers
Suppose you had a friend in the house across the way, and every night,
the two of you signal each with flashlights. If you were practical, you
would learn morse code, and that would work fine. But then this lesson
would be over, and you wouldn't know binary. So forget morse code.
Suppose you had four flashlights, and you wanted to send a phone number.
If 0 = off and 1 = on, here's a table of flashlight codes you could use
to send zero through nine:
Binary Coded Decimal (BCD) Table
| Decimal |
Four-Flashlight Code (4-Bit Binary) |
| 0 |
0000 |
| 1 |
0001 |
| 2 |
0010 |
| 3 |
0011 |
| 4 |
0100 |
| 5 |
0101 |
| 6 |
0110 |
| 7 |
0111 |
| 8 |
1000 |
| 9 |
1001 |
On to Hex
Now, Binary Coded Decimal (BCD) is very common where numbers are displayed
(like clocks and cash registers). But notice that we haven't used up all
the possible flashlight (binary) codes. There are six codes not being used
(1010, 1011, 1100, 1101, 1110, and 1111). For maximum efficiency, we want
to use these codes, so we assign them sequential capital letters, starting
with "A". The result is:
Hexadecimal ("Hex") Table
| Hexadecimal |
Binary |
|
Hexadecimal |
Binary |
| 0 |
0000 |
|
8 |
1000 |
| 1 |
0001 |
|
9 |
1001 |
| 2 |
0010 |
|
A |
1010 |
| 3 |
0011 |
|
B |
1011 |
| 4 |
0100 |
|
C |
1100 |
| 5 |
0101 |
|
D |
1101 |
| 6 |
0110 |
|
E |
1110 |
| 7 |
0111 |
|
F |
1111 |
On to Bytes
You've seen how four bits can represent any number up to 16. What if you
had five bits, how many numbers could you send? Answer: 32. Six bits? 64
numbers. Seven bits? 128.
If we have eight bits, two groups of four, we can represent 256 values.
Eight bits is called a "byte". If you see something is called "byte-wide",
that means it is eight bits wide. (By the way, and you don't see this much
anymore, 4-bits is called a "nibble", or if you really want to be cute,
"nybble".)
Anyway, we can show the value of a byte by dividing the byte down the
middle into two groups of four, then using the hex code for each nibble.
Examples:
8-bit Binary - to - Hex Encoding Examples
| Binary |
4-Bit Groups |
Hex Encoding |
Final Hex Code |
| 01010001 |
0101 0001 |
5 1 |
51h |
| 10101110 |
1010 1110 |
A E |
AEh |
| 11110111 |
1111 0111 |
F 7 |
F7h |
Base Labels
Here's a value: "51". Is it a decimal 51 or a hexadecimal 51? When there
is room for confusion, we add a letter to indicate the number base (base
2 = binary, base 16 = hex, etc.). Unfortunately, there is no one way to
do this. Different cultures (corporate or otherwise) use different codes.
Decimal is fairly standard - put a lower case "d" at the end (like,
"51d").
Hex, on the other hand, has at least three "standards":
lower case "h" suffix (51h)
upper case "H" suffix (51H)
"0x" prefix (0x51)
Terminology
Most Significant Bit (MSB): The left-most bit (which
represents the highest value). The "1" in 1000000 is the MSB.
Least Significant Bit (LSB): The right-most bit (which
represents the lowest value). The "1" in 00000001 is the LSB.
Onward
Now that you understand bits and bytes, you are ready to learn how the
01 sends data over MIDI. Technically, the 01/W uses Packed Transmission
with the Most Significant Bits sent first.
Format Conversions
As long as you are sending standard MIDI messages (like Note On, Volume,
Pan, Controller Change, etc.), every bit position is defined, and there
are no conversion issues. But what if you send a System Exclusive (SysEx)
message? These manufacturer-specific messages are not defined by the MIDI
standard - manufacturers can do whatever they want. So, when it comes time
to send a byte of SysEx data, we run smack into...
The 8-Bits into 7-Bits Problem
Internal to the Korg 01/W (and most MIDI instruments), 8-bit data is used.
MIDI Data bytes also use 8 bits, but the MSB must be
"0" (Click here if you must know why.).
This means there are only 7 bits available for data in a MIDI Data byte.
How do we squeeze 8 bits from the 01 byte into the 7 bits of a MIDI Data
byte?
You can't. Every time you put an 8-bit byte into 7 MIDI Data bits, you're
gonna have one bit left over. You need a scheme to get these left-over
data bits into the MIDI transfer somehow. Different manufacturers use different
schemes, and some manufacturers use different schemes in different products.
The 01/W Conversion Scheme
Remember a MIDI Data byte holds 7 bits. The 01 first grabs seven 8-bit
bytes. It then takes the MSB of each byte and puts it into a new MIDI Data
byte. The result is 8 bytes of 7 bits each, one byte containing nothing
but the MSBs of the other seven bytes.
This group of eight MIDI Data bytes is then sent out one bit at a time,
starting with the MSB byte, then byte 0, byte 1, ... , byte 6, and finally
byte 7.
Converting 8-Bit
Data to MIDI 7-Bit Data for Packed Transmission, MSBs Sent First.
The 01 converts 8-bit internal data to 7-bit MIDI data as follows:
Step 1
Group the 8-bit data into 7 bytes (byte 0, byte 1, byte 2, ... , byte 6).
In 01 terminology, DATA is (1 set = 7 bytes of 8 bits each). Order
the bytes so the first byte (Byte 0) is on the left with additional byte
to the right. This is just like reading English, left-to-right.
01/W 8-bit Internal Data (7 bytes worth)
|
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
Byte 4 |
Byte 5 |
Byte 6 |
|
00000000 |
10001000 |
01000100 |
11001100 |
00100010 |
10101010 |
11100110 |
Step 2
Build a byte containing only the MSB of those seven
bytes. Bit 0 come from Byte 0, bit 1 comes from Byte 1, and so on. Call
this the MSB Byte.
Building the MIDI 7-bit "MSB Byte"
| bit 7 |
bit 6 |
bit 5 |
bit 4 |
bit 3 |
bit 2 |
bit 1 |
bit 0 |
| always 0 |
MSB of
Byte 6 |
MSB of
Byte 5 |
MSB of
Byte 4 |
MSB of
Byte 3 |
MSB of
Byte 2 |
MSB of
Byte 1 |
MSB of
Byte 0 |
| 0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
Step 3
Mask out (that is, set to zero) the MSB of all the original 8-bit bytes
(set all MSBs = 0).
MIDI Data (7 bytes of 01 data in 8 MIDI bytes)
| MSB |
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
Byte 4 |
Byte 5 |
Byte 6 |
| 00101010 |
00000000 |
00001000 |
01000100 |
01001100 |
00100010 |
00101010 |
01100110 |
Step 4
Send the MIDI data , leading off with the MSB Byte (byte MSB, byte 0, byte
1, byte 2, ... byte 6). In 01 terminology, MIDI DATA (1 set = 8 bytes
of 7 bits each).
Reminder: This applies to 01 internal data only. All external
MIDI stuff (like SysEx headers, MIDI commands/instructions) are already
in MIDI format.
Converting "MIDI
7-Bit Data" to "01 8-Bit Data"
Why? If you do a MIDI Dump from the 01, like into your computer-based sequencer,
you will see a series of MIDI bytes that don't exactly line up with what
you read in the 01 MIDI Tables. That's because internal to the 01, 8-bit
data is used. MIDI uses 7-bit data, with the MSB = 0.
To understand the MIDI data, you must convert the 7-bit MIDI data to
8-bit internal data as follows:
Step 1
Write your MIDI data in same order it was received, first received byte
on the left, next byte to the right, and so on ( byte 0, byte 1, byte 2,
... byte 7).
MIDI Data (7 bytes of 01 data in 8 MIDI bytes)
MIDI
Byte 0 |
MIDI
Byte 1 |
MIDI
Byte 2 |
MIDI
Byte 3 |
MIDI
Byte 4 |
MIDI
Byte 5 |
MIDI
Byte 6 |
MIDI
Byte 7 |
01
MSB |
01
Byte 0 |
01
Byte 1 |
01
Byte 2 |
01
Byte 3 |
01
Byte 4 |
01
Byte 5 |
01
Byte 6 |
| 00101010 |
00000000 |
00001000 |
01000100 |
01001100 |
00100010 |
00101010 |
01100110 |
Step 2
Move each bit out of the MSB Byte to the MSB of all the original 8-bit
bytes. Bit 0 goes to Byte 0, bit 1 to Byte 1, through bit 6 to Byte 6.
(Bit 7 is always 0, and doesn't go to any Byte.)
Restoring the 8th Bit of Each Byte
| bit 7 |
bit 6 |
bit 5 |
bit 4 |
bit 3 |
bit 2 |
bit 1 |
bit 0 |
| always 0 |
MSB of
Byte 6 |
MSB of
Byte 5 |
MSB of
Byte 4 |
MSB of
Byte 3 |
MSB of
Byte 2 |
MSB of
Byte 1 |
MSB of
Byte 0 |
| 0 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
You now have 7 bytes of 01/W 8-bit internal data.
01/W 8-bit Internal Data (7 bytes worth)
|
Byte 0 |
Byte 1 |
Byte 2 |
Byte 3 |
Byte 4 |
Byte 5 |
Byte 6 |
|
00000000 |
10001000 |
01000100 |
11001100 |
00100010 |
10101010 |
01100110 |
Why MIDI Data is only 7 bits?
MIDI uses 8 bits for all transfers, but the MIDI language defines two classes
of messages: Status and Data. Status messages have Bit 7, the MSB, = 1.
Data messages have Bit 7 = 0. So, if we tried to send eight bits of data
in a Data message, and Bit 7 happened to be a "1", then our data would
be interpreted as a Status message - which it isn't.
In other words, MIDI is an 8-bit language. If we used all eight bits
for data, there would be no way to say what to do with the data - no way
to identify MIDI commands.
Copyright ©1998 by Ken Westover at Cliff Canyon
Publishing Co.
9807100957