From Serial Electronic MIDI Messaging to Human Readable MIDI
In order to get to grips with the underlying MIDI system that jOrgan uses you need to have a basic understanding of the MIDI Messaging Protocol, which in turn requires some understanding of serial electronic messaging systems. For a good understanding of MIDI, you also need to understand the basics of base-n mathematics (in this case base-2, base-10, and base-16, otherwise known as Binary, Decimal, and Hexadecimal).
These basics are not difficult subjects, so don't read the above statements and give up! Keep reading...
MIDI - A Serial Electronics Communications Protocol
MIDI is both an electronic serial communications protocol and a Human Readable Code, so in this tutorial I'm going to take you through some of these basics.
Firstly we need to understand what an 'electronic serial communication protocol' is, and in order to understand that we need to understand binary logic processing in bits. Now all of you use bits everyday.
Wikipedia definition of a digital bit: A bit (a contraction of Binary digIT) is the basic unit of information in computing and telecommunications. A bit can have only two values: either 1 or 0. A bit can be implemented in hardware by means of a two state device. Eight bits form a byte.
You know all that RAM you're using on your PC - well it stores information in Binary digIT (bit) format, with each 8 bits making up a byte, each 1024 bytes making up a kilobyte, and onwards until you're using gigabytes.
Back to MIDI - when MIDI signals are sent across the wires there is a central clock timer, and pulses of either high or low voltage states within those periods of time. The MIDI format defines time in terms of 31,250 bits per second. And by todays standards that is very very slow! When there is a higher voltage state the signal says '1', when there is a lower voltage state the signal says '0'.
A single MIDI message is made up of 11 bits, but three of those bits are just for the timer to know where the actual MIDI message is. One start bit (must be 0), eight data bits (a byte of data), a no parity bit and one stop bit (must be 1). We will only concern ourselves with the MIDI byte of data being sent, as this is where the message is located.
So now you know what serial electronic communications require... an agreed upon clock rate or period of time, and a system of sending binary messages based on that period of time.
But before we dig into that Byte of MIDI data being communicated, we need to discuss the relationship between base-2 (Binary), base-10 (Decimal), and base-16 (Hexadecimal).
Binary, Decimal, and Hexadecimal
Our base-10 number system likely grew up because we have 10 fingers, but if we happened to evolve to have eight fingers instead, we would probably have a base-8 number system. In mathematics you can have base-anything number systems....
Counting in binary is pretty easy. Starting at zero and going through 20, counting in decimal and binary looks like this:
0 = 0 1 = 1 2 = 10 3 = 11 4 = 100 5 = 101 6 = 110 7 = 111 8 = 1000 9 = 1001 10 = 1010 11 = 1011 12 = 1100 13 = 1101 14 = 1110 15 = 1111 16 = 10000 17 = 10001 18 = 10010 19 = 10011 20 = 10100
When you look at this sequence, 0 and 1 are the same for decimal and binary number systems. At the number 2, you see carrying first take place in the binary system. If a bit is 1, and you add 1 to it, the bit becomes 0 and the next bit becomes 1. In the transition from 15 to 16 this effect rolls over through 4 bits, turning 1111 into 10000.
Why are there 8 bits in a byte? A similar question is, "Why are there 12 eggs in a dozen?" The 8-bit byte is something that people settled on through trial and error over the past 50 years, but is mostly due to machine coding for early computing chips.
With 8 bits in a byte, you can represent 256 values ranging from 0 to 255, as shown here:
0 = 00000000 1 = 00000001 2 = 00000010 254 = 11111110 255 = 11111111
Now that you have these basics, go to http://www.myhome.org/pg/numbers.html for a basics course in dealing with Binary, Decimal, and Hexadecimal Numbers.
Why Hexadecimal? It is easier to convert Binary to Hex and vice-versa compared to decimal (base-10). By grouping Binary numbers by 4, you can actually convert it directly to Hex, and vice versa. Below is a table of the conversion:
0 = 0000 1 = 0001 2 = 0010 3 = 0011 4 = 0100 5 = 0101 6 = 0110 7 = 0111 8 = 1000 9 = 1001 A = 1010 B = 1011 C = 1100 D = 1101 E = 1110 F = 1111
If you are now blurry eyed... take a break. Have a cup of coffee. Then go back to that tutorial until you understand how from Binary to Hex to Decimal we get 10000000= 80= 128. If you still don't get it, take a nap, or leave it alone and come back tomorrow. Until you understand this conversion of base-n digits, MIDI data tables will be a mystery to you.
Human Readable MIDI
Ok, so now you understand bits being sent over electronic lines as higher or lower voltage signals within a specific timed period, and you understand how 8 bits create a byte of binary data, and you understand how binary relates to hexadecimal and decimal numbers. Most MIDI messages are three bytes in length, starting with the MIDI function, then the MIDI functions setting, and lastly the value.
With this understanding you can now read the tables in http://www.midi.org/techspecs/midimessages.php
And you can read the MIDI Specification from http://www.gweep.net/~prefect/eng/reference/protocol/midispec.html (written with reference to the Hexadecimal) and translate for yourself what the specification is telling you...
For instance, in jOrgan MPL we would see something like this
set 176, set 11, set value | div 2 | add 0.5 | mult volume 127
Using table#2 and table#3 from the MIDI Messages page we can translate this to:
set 176 = Use Channel 1 Control/Mode Change set 11 = Use Control Change 11 [Expression Controller] set value | div 2 | add 0.5 | mult volume 127 = use this mathematical formula to create the expression curve required for the expression values being sent to the soundfont
Sometimes when a manual or topic lists an Hexadecimal numeral they will indicate that they are using hexadecimal by adding the 'H' to end of the numeral. For example:
B0H 5BH 7FH just means B0 5B 7F