[sdiy] MIDI bytestream parser
Neil Johnson
neil.johnson97 at ntlworld.com
Wed Nov 17 00:16:38 CET 2010
Hi Tom,
> The MIDI bytestream never shows you the channel values as displayed
> to the user. Channel "One" is always '0x0'. In fact, aside from the
> actual user display, there isn't anywhere that MIDI channel 16
> actually exists, is there?
You're confusing a particular encoding of channel numbers, with the
actual channel numbers. MIDI has channels 1-16, while the encoding
uses 0-15. If anything, it would be more correct to say that MIDI
channel 0 does not exist!
>> The HASH( ) is used to implement a lookup map from status byte to
>> handler function, by observing that there are no two status byte with
>> the same nibble checksum (they are either nx, with n between 8 and E
>> and x for channel messages, or Fn, with n below 8 for system
>> messages.
>
> I'm not sure I get this. Ok, status bytes are unique, I get that.
> And there are only certain values possible, I get that. And we have
> a function to call for each type of message. So far so good.
Great!
> But what's the point of the hash? A lookup map, you say? So it maps
> from status byte x to function y?
No, you don't seem to understand what a hash is. A hash generates a
value from a small set of values given a value from a large set.
There are bound to be clashes (multiple input values hash to the same
output value), but in this specific case the sparse input values do
not cause clashes in the output values, so it all works out
nicely :) The end result is the values 0x80, 0x90, 0xA0, 0xB0, 0xC0,
0xD0, 0xE0, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6 and 0xF7 are
hashed, without clashing, onto the range 0-15.
> Why not use an array
Because for the set of input values, without any processing, you
would need an array of size 0xF7 - 0x80 = 0x77, or 119, entries.
> a switch statement,
I could, but again given the sparse input values this would either be
turned into a list of if--else or if the compiler is *really* smart
it would work out the same hashing function in order to generate an
index into a jump table.
> a long if/elseif,
Not very compact though is it? And think of all those lines of source!
Also note that a long chain of if--else has different processing
times depending on the order of tests - those early in the chain
execute faster than those at the end of the chain.
> or any of the other possible constructions that would provide this
> mapping?
You mean, like a hash function and a small function pointer table?
Its a common idiom.
> If that is really what it's for, I still don't understand why you'd
> do it like this.
It has many advantages, a few of which I've touched on here.
Cheers,
Neil
--
http://www.njohnson.co.uk
More information about the Synth-diy
mailing list