Hi,
midiOutShortMsg() is an incredibly bad API for SW synths. It's just good enough at the lowest level, to throw bytes to the serial hardware. It is antithetical to buffering. The machine is stressed to obey the event ASAP, which is travelling across several threads that hence need be set as time-critical each, until a note is eventually produced. No wonder there's stuttering with some apps.
OTOH, analyzing several events in advance in a stream buffer, the SW synth would have a lot of time to produce excellent quality output.
Consequently, Wine's MCISEQ should use WINMM's midiStream interface. Then, the individual audio drivers should implement MIDICAPS_STREAM. (Alas I don't know what MODM_ message corresponds to this.) WineOSS.drv could then make use of SEQ_DELTA_TIME() and throw a whole buffer of events at OSS' MIDI interface, instead of relying on SEQ_DUMPBUF() to immediately start processing a tiny one note "buffer".
This implies that Wine must be able to mix several streams by event timestamp, duplicating what MacOS' CoreMIDI can. Perhaps this can be delegated to the OS? Unless it's easier to leave mixing in the file parser, which is what MIDI_mciFindNextEvent() currently does, generating one stream per file instead of one per track.
Converting a .mid to streams of MIDIEVENT might be useful as well should Wine ever implement DirectMusic. It may also help implement MCI_SEQ_FORMAT_SONGPTR which is MCISEQ's default time format on native for all .mid files I tried, not milliseconds or bytes. Tests with MCI_SEEK show that the native MCI cannot seek exactly to arbitrary milliseconds, instead it steps in units of "song pointer".
Any volunteers? What's the recommended place (what Wiki page?) to add this as Wine task so every potential taker looking for a job can see it?
Regards, Jörg Höhle