http://bugs.winehq.org/show_bug.cgi?id=33126
Bug #: 33126 Summary: divided SysEx and coalesced midiOutLongMsg Product: Wine Version: 1.5.25 Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: winealsa.drv AssignedTo: wine-bugs@winehq.org ReportedBy: hoehle@users.sourceforge.net Classification: Unclassified
Johannes Kroll reported in wine-patches that the KORG Kontrol Editor software hung after sending an ill-formed SysEx via winealsa's midiOutLongMsg. http://www.winehq.org/pipermail/wine-patches/2013-January/121335.html The MIDIHDR data is F0 ... F7 00 00 00 (125 bytes). http://www.winehq.org/pipermail/wine-devel/2013-February/098852.html He observed that no hang occurs when skipping the trailing 3 zero bytes. F7 is the "End Of SysEx" (EOX) marker.
It is still unclear what happens. MIDI HW is expected to skip over bogus bytes, thus the zero bytes should cause no harm. OTOH, ALSA might be getting into trouble processing ill-formed messages, and we don't know if or how many bytes ALSA actually sent out through the serial port.
In any case, midiOutLongMsg handling in Wine needs fixes. - winealsa should extract the F0...F7 part and send that as a SysEx. - More generally, midiOutLong is known to accept not only SysEx packets, but also coalesced status messages. Some MIDI authors prefer to send e.g. chords via one LongMsg rather than successive calls to midiOutShortMsg, arguing that it's faster. Hence all Wine MIDI drivers need to decompose midiOutLongMsg into packets consisting of status message, regular SysEx ... and possibly junk. - All APIs (MS, ALSA, OSS, CA) acknowledge the existence of divided SysEx. As a result, framing SysEx with F0 ... F7 is entirely under application control. The current winealsa framing code is simply wrong. - winecoreaudio always declared 3 bytes for short messages, even program change.
I have written a sequence of patches to fix all of this. The only thing that is unclear is how to encapsulate garbage data like the above 3 zero bytes or real time messages with ALSA. What ALSA API function and what ALSA message type to use? Heck, I'm not even sure winealsa.drv/midi.c:modData is ok to send a 2-byte MTC quarter frame via snd_seq_ev_set_sysex instead of using a primitive that sets the type SND_SEQ_EVENT_CLOCK/TICK.