Re: MIDI parser source (bytestream->MIDI messages)
Christian Packmann <[email protected]> Wed, 28 Jan 2004 20:59:38 +0100
| Newsgroups | gmane.os.openbeos.midi |
|---|---|
| Message-ID | <[email protected]> |
Matthijs Hollemans wrote: > Christian wrote: > > But I think there's a bug, or rather a missing workaround, in the cod= e.=20 >=20 > Thanks. I'll add that to the never-ending to-do list :-) Uhm... bad news: I started coding my parser, and soon realized that=20 MidiPortProducer::GetData() is utterly broken. It does not keep track of Running Status, nor will it handle RealTime=20 messages interspersed into multi-byte messages correctly (only RealTime=20 within SysEx is handled okay). <http://www.borg.com/~jglatt/tech/midispec/run.htm> says: "The MIDI spec allows for a MIDI message to be sent without its Status by= te=20 (ie, just its data bytes are sent) as long as the previous, transmitted=20 message had the same Status. This is referred to as running status. Runni= ng=20 status is simply a clever scheme to maximize the efficiency of MIDI=20 transmission (by removing extraneous Status bytes). The basic philosophy = of=20 running status is that a device must always remember the last Status byte= =20 that it received (except for RealTime), and if it doesn't receive a Statu= s=20 byte when expected (on subsequent messages), it should assume that it's=20 dealing with a running status situation. A device that generates MIDI=20 messages should always remember the last Status byte that it sent (except= =20 for RealTime), and if it needs to send another message with the same=20 Status, the Status byte may be omitted." And <http://www.borg.com/~jglatt/tech/midispec/real.htm> tells us: "Each RealTime Category message (ie, Status of 0xF8 to 0xFF) consists of=20 only 1 byte, the Status. These messages are primarily concerned with=20 timing/syncing functions which means that they must be sent and received = at=20 specific times without any delays. Because of this, MIDI allows a RealTim= e=20 message to be sent at any time, even interspersed within some other MIDI=20 message. For example, a RealTime message could be sent inbetween the two=20 data bytes of a Note On message. A device should always be prepared to=20 handle such a situation; processing the 1 byte RealTime message, and then= =20 subsequently resume processing the previously interrupted message as if t= he=20 RealTime message had never occurred." Basically this means that MidiPortProducer::GetData() can be thrown away = -=20 it'll have to be totally rewritten to parse MIDI streams correctly. But... good news: as I need a MIDI parser urgently, I've started coding o= ne=20 which takes the above requirements into account. It should be ready withi= n=20 1-2 weeks (if I can hide from Murphy). I'll test it within SerialMidiHost, and once it works okay, I can write a= =20 fixed MidiPortProducer::GetData(). I currently don't have time to setup=20 OBOS CVS on my machine, so somebody else would have to do integration &=20 testing. But I guess that's preferable to having to write that stuff from= =20 the ground up. ;-) Bye, Chris