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