Bytes, Nibbles & Bits for CoreMidi
So I’m working on YAMP (yet another midi project
and it took me a while to recollect all the binary arithmetic required to parse MIDI packets.
Take a midi packet with 3 bytes in hexadecimal notation such as 99 3C 64. This stream encapsulates the following instructions:
Play middle C on channel 10 at velocity 100. Now lets strip it down to nibbles & bits.
9 -> Note on message. (Examples of other status messages are: 0xB for controller change, 0x C for program change & 0xE for pitch-bend)
9 -> Middle channel 10. (Range 0 -15)
3C ->Middle C -> Note 60
64 -> 100 in decimal
Determining if a stream begins with a status byte.
A set high-bit on the first byte identifies the byte as a status message. This can be accomplished visually by converting 99 from hex to binary 10011001, and seeing if the first bit is 1. This can be tested mathematically with the following condtion:
0×99 > 0x7F
Once you have determined that the byte actually sets a status, you need to identify the actual status that is set. Some examples of status messages are: 0xB for controller change, 0xC for program change & 0xE for pitch-bend. To get the value of the left nibble, you can use the following expression.
0×99 >> 4 (Shift the 4 places) or 0×99 / 0×10
Determining the midi transmission channel.
The second nibble (99) of the first byte in the stream, represents the midi transmission channel. Channels are 0 indexed so they range from 0-F in hex or 0-15 in decimal. So we can tell quite easily that the transmission channel in our stream is 10 just by adding 1 to the second nibble. We can extract the 2nd nibble using the following expression:
0×99 % 0×10 (% = modulo)
and get the midi channel by adding 1 to the result
(0×99 % 0×10) + 1
Determining the note number and velocity.
These are pretty simple. Just convert the Hex values to a decimal values
0x3c = 60
0×64 = 100
I’ll post my parser here when I’m done with it this weekend.

Did you get your parser done before you bailed on the project? If so, please do post or email it still. I am working on a 16 track sequencer and I need all the help I can get.
Thanks for your other CoreMIDI posts. (All two of them).
Lol. Shame on me. That weekend never came. I’ll return to the project sometime this month when I’m done with a paying gig
I created a virtual receive port and I went as far as logging the received messages and updating my midi activity monitor. I’ll post what I have done so far and hope you find in useful. If not, I’ll post my complete parser soon.
This is the midiReadProc from my virtual receive port.
static void midiReadProc(const MIDIPacketList *midiPacketList, void *readProcRefCon, void *srcConnRefCon){
[[JXMidiSystem sharedInstance] updateReceiveActivityMonitor];
int i, j;
MIDIPacket *nextPacket = (MIDIPacket *)midiPacketList->packet;
for (j=0 ; j < midiPacketList->numPackets; ++j)
{
for (i = 0; i < nextPacket->length; ++i)
{
NSLog(@"--%02X", nextPacket->data[i]);
}
nextPacket = MIDIPacketNext(nextPacket);
NSLog(@"MIDIPacketNext");
}
//left nibble is 0x9A >> 4
// right nibble 0x9A % 16
// status bit >> 127
//y = ((x >> 4) & 0x0f) | ((x < < 4) & 0xf0); swap nibbles
}
Thanks for the post, and congrats on the paying gig. One of the challenges with my own project is figuring out how to handle the data I will be recording and outputting. It’s a pattern based beast, so will have a minimum 99 patterns of variable lengths, each with 16 tracks…and each track will have all the packet/packetlists and other data associated with that. Not sure how best to ‘struct’ all that. Then my other technical wonderment is going to be how to time all that on the way back out and still deal with interface updates, etc.? There’s not much roadmap for all this. Blogs likes yours and others are helpful, since googling on CoreMIDI provides not much information.
@Robert
I’m posting this without having had much time to think it through.
I think timing shouldn’t be a big problem. Maybe you could deliver timestamped midi data in 2 measure chunks. Or you could make the chunk size dependent on the tempo of the pattern. The faster the tempo, the higher the chunk size.
As far as how to structure it all, I would probably approach it like below. Mind you, I haven’t spent much time thinking about this.
Song
attributes: name, tempo, followSongOrPatternTempo?
has a playlist
Playlist
has a list of slots.
Slot
attributes: length
has one pattern
Pattern
attributes: name, tempo, length, swing
has 16 tracks
belongs to Song
Track
attributes: name, length, resolution, output, loop
has many steps but resolution determines which steps are active
belongs to a pattern
Step
attributes: active?, accent, index
has one note or controller message
belongs to a track
Note
attributes: pitch, velocity
belongs to a step. time_stamp can be derived from the step.
Thanks, that’s a help. When I wrote pattern based, I meant parts actually, a la the Alesis MMT-8. It will alos be a live recorder (packetlists) Don’t know if that changes things. I work best that way, assembling chunks of different and similar sounding parts into songs. Thanks again for your time and thoughts.
Thanks, that’s a help. When I wrote pattern based, I meant parts actually, a la the Alesis MMT-8. It will alos be a live recorder (packetlists) Don’t know if that changes things. I work best that way, assembling chunks of different and similar sounding parts into songs. Thanks again for your time and thoughts.
[WORDPRESS HASHCASH] The poster sent us ’0 which is not a hashcash value.