[linux-audio-dev] Basic MIDI question

Ari Kauppi kauppi at papupata.org
Wed Jul 26 10:25:38 UTC 2006


On Wed, 26 Jul 2006, Clemens Ladisch wrote:

> Ari Kauppi wrote:
>> On Wed, 26 Jul 2006, Jens M Andreasen wrote:
>>
>>>     if(runningStatus == NOTE_ON || runningStatus == NOTE_OFF)
>>
>> If you plan to receive messages from other channels than 0 you have to
>> use (runningStatus & 0xF0) instead of the full runningStatus and perhaps
>> check for (runningStaus & 0x0F) == receiveChannel..
>
> Okay, here is my entry to the Official LAD MIDI Parser Contest 2006:

Good try but it still has at least one potential problem: according to 
MIDI spec running status should be set only with channel messages. 
Sysex/common messages should reset it to undefined (0).

With this exact implementation it shouldn't cause any problems but if the 
parser is extended/modified later it might become a pretty hard to find 
bug with some input..

> void handleByte(u8 byte)
> {
> 	/* in a driver, these static variables should go into some struct: */
> 	static enum {
> 		STATE_UNKNOWN, /* not a note command */
> 		STATE_NOTE1,   /* expecting 1st data byte (note) */
> 		STATE_NOTE2,   /* expecting 2nd data byte (velocity) */
> 	} state = STATE_UNKNOWN;
> 	static u8 command;
> 	static u8 note;
>
> 	if (byte >= 0xf8) /* real-time command */
> 		;
> 	else if (byte & 0x80) { /* status byte */
> 		command = byte;
> 		/* note-on or note-off? */
> 		state = (byte & 0xf0) <= 0x90 ? STATE_NOTE1 : STATE_UNKNOWN;
> 	} else { /* data byte */
> 		if (state == STATE_NOTE1) {
> 			note = byte;
> 			state = STATE_NOTE2;
> 		} else if (state == STATE_NOTE2) {
> 			if ((command & 0xf0) == 0x90 && byte > 0) {
> 				/* note on */
> 			} else {
> 				/* note off */
> 			}
> 			state = STATE_NOTE1;
> 		}
> 	}
> }


-- 
Ari



More information about the Linux-audio-dev mailing list