winealsa: Have the MIDI recorder wait in poll(), not snd_seq_event_input().

Johannes Kroll jkroll at lavabit.com
Tue Feb 12 06:10:22 CST 2013


On Mon, 11 Feb 2013 19:41:27 +0100
<Joerg-Cyril.Hoehle at t-systems.com> wrote:

> Johannes Kroll asked:
> >Did this patch get through? I don't see it on
> >http://source.winehq.org/patches/ ...
> 
> It did.
> You looked too late in patches/. Committed patches are deleted sooner than
> rejected ones that are in turn deleted sooner than new/pending patches.

Okay.


> I'm still interested in your testing my other MIDI patches.  I fact I have a
> queue of half a dozen patches ready for submission, except that I'd like
> somebody to test them with real MIDI HW.
> 
> There's another patch yet to be written: midiOutLongMessage CAN be used for
> coalesced non-sysex messages.  This affects winealsa.  Wineoss needs no change,
> because it simply dumps the bytes, one by one, regardless of SysEx or
> standard message.  ALSA needs different API functions to be used.  I've yet
> to check MacOSX CoreMIDI.

You asked me to test what happens when I remove the code that adds
F0/F7 markers when they are missing. I changed modLongData like this:

    [...]
    /* FIXME: MS doc is not 100% clear. Will lpData only contain system exclusive
     * data, or can it also contain raw MIDI data, to be split up and sent to
     * modShortData() ?
     * If the latest is true, then the following WARNing will fire up
     */
    if (lpData[0] != 0xF0 || lpData[lpMidiHdr->dwBufferLength - 1] != 0xF7) {
	WARN("Alleged system exclusive buffer is not correct\n\tPlease report with MIDI file\n");
	lpNewData = HeapAlloc(GetProcessHeap(), 0, lpMidiHdr->dwBufferLength + 2);
    }
    else
    {
        WARN("modLongData got SysEx message with correct F0/F7 markers.\n");
    }

    TRACE("dwBufferLength=%u !\n", lpMidiHdr->dwBufferLength);
    TRACE("                 %02X %02X %02X ... %02X %02X %02X\n",
	  lpData[0], lpData[1], lpData[2], lpData[lpMidiHdr->dwBufferLength-3],
	  lpData[lpMidiHdr->dwBufferLength-2], lpData[lpMidiHdr->dwBufferLength-1]);

    switch (MidiOutDev[wDevID].caps.wTechnology) {
    case MOD_FMSYNTH:
	/* FIXME: I don't think there is much to do here */
	break;
    case MOD_MIDIPORT:
	if (lpData[0] != 0xF0) {
	    //~ /* Send start of System Exclusive */
	    //~ len_add = 1;
	    //~ lpNewData[0] = 0xF0;
	    //~ memcpy(lpNewData + 1, lpData, lpMidiHdr->dwBufferLength);
	    //~ WARN("Adding missing 0xF0 marker at the beginning of "
		 //~ "system exclusive byte stream\n");
        WARN("*** Not adding missing 0xF0 marker.\n");
	}
	if (lpData[lpMidiHdr->dwBufferLength-1] != 0xF7) {
	    //~ /* Send end of System Exclusive */
	    //~ if (!len_add)
		//~ memcpy(lpNewData, lpData, lpMidiHdr->dwBufferLength);
            //~ lpNewData[lpMidiHdr->dwBufferLength + len_add] = 0xF7;
	    //~ len_add++;
	    //~ WARN("Adding missing 0xF7 marker at the end of "
		 //~ "system exclusive byte stream\n");
        WARN("*** Not adding missing 0xF7 marker.\n");
	}
    [...]

I then started the korg kontrol editor with the nanopad2 attached to
USB. It does find the nanopad correctly, and it can receive the scene
set correctly. But when I try to write the scene set, it fails with a
timeout message box.

The log first indicates several SysEx message with included F0/F7 is
requested to be written, this looks like this:

  2.663:0031:trace:midi:modLongData (0000, 0x1cbc10, 00000040);
  2.663:0031:warn:midi:modLongData modLongData got SysEx message with correct F0/F7 markers.
  2.663:0031:trace:midi:modLongData dwBufferLength=6 !
  2.663:0031:trace:midi:modLongData                  F0 42 50 ... 00 01 F7

Then, a SysEx with start marker, but no end marker is requested to be
sent (and I don't add the end marker):

 17.015:003b:trace:midi:ALSA_modMessage (0005, 0008, 00008001, 001CA7A8, 00000040);
 17.015:003b:trace:midi:modLongData (0005, 0x1ca7a8, 00000040);
 17.015:003b:warn:midi:modLongData Alleged system exclusive buffer is not correct
        Please report with MIDI file
 17.015:003b:trace:midi:modLongData dwBufferLength=125 !
 17.015:003b:trace:midi:modLongData                  F0 42 40 ... 00 00 00
 17.015:003b:warn:midi:modLongData *** Not adding missing 0xF7 marker.
 17.015:003b:trace:midi:modLongData client = 20 port = 0
 17.015:003b:trace:midi:MIDI_NotifyClient wDevID = 0005 wMsg = 969 dwParm1 = 1CA7A8 dwParam2 = 0000
 17.015:003b:trace:driver:DriverCallback (00000023, task 0002, 0x8001, 03C9, 00B28110, 001CA7A8, 00000000)
 17.015:003b:trace:driver:DriverCallback Done
 17.015:003b:trace:winmm:MMDRV_Message => MMSYSERR_NOERROR
 17.015:0023:trace:winmm:midiOutUnprepareHeader (0x8001, 0x1ca7a8, 64)
 17.015:0023:trace:winmm:MMDRV_Get (0x8001, 0003, N)
 17.015:0023:trace:winmm:MMDRV_Message (MidiOut 5 6 0x00008001 0x001ca7a8 0x00000040)
 17.015:0023:trace:winmm:MMDRV_Message Calling message(dev=5 msg=6 usr=0x00008001 p1=0x001ca7a8 p2=0x00000040)
 17.015:0023:trace:midi:ALSA_modMessage (0005, 0006, 00008001, 001CA7A8, 00000040);
 17.015:0023:trace:midi:modUnprepare (0005, 0x1ca7a8, 00000040);
 17.015:0023:trace:winmm:MMDRV_Message => MMSYSERR_NOERROR
 17.265:003a:trace:midi:midRecThread Thread loop
 17.515:003a:trace:midi:midRecThread Thread loop
 17.765:003a:trace:midi:midRecThread Thread loop
 18.016:003a:trace:midi:midRecThread Thread loop
 18.266:003a:trace:midi:midRecThread Thread loop
 18.516:003a:trace:midi:midRecThread Thread loop
 18.767:003a:trace:midi:midRecThread Thread loop
 19.017:003a:trace:midi:midRecThread Thread loop
 19.268:003a:trace:midi:midRecThread Thread loop
 19.518:003a:trace:midi:midRecThread Thread loop
 19.768:003a:trace:midi:midRecThread Thread loop
 20.017:0009:trace:winmm:midiInStop (0x8000)
 20.017:0009:trace:winmm:MMDRV_Get (0x8000, 0002, N)
 20.017:0009:trace:winmm:MMDRV_Message (MidiIn 1 61 0x00008000 0x00000000 0x00000000)
 20.017:0009:trace:winmm:MMDRV_Message Calling message(dev=1 msg=61 usr=0x00008000 p1=0x00000000 p2=0x00000000)
 20.017:0009:trace:midi:ALSA_midMessage (0001, 003D, 00008000, 00000000, 00000000);
 20.017:0009:trace:midi:midStop (0001);
 20.017:0009:trace:winmm:MMDRV_Message => MMSYSERR_NOERROR
 20.017:0009:trace:winmm:midiInReset (0x8000)
 20.017:0009:trace:winmm:MMDRV_Get (0x8000, 0002, N)
 20.017:0009:trace:winmm:MMDRV_Message (MidiIn 1 62 0x00008000 0x00000000 0x00000000)
 20.017:0009:trace:winmm:MMDRV_Message Calling message(dev=1 msg=62 usr=0x00008000 p1=0x00000000 p2=0x00000000)
 20.017:0009:trace:midi:ALSA_midMessage (0001, 003E, 00008000, 00000000, 00000000);
 20.017:0009:trace:midi:midReset (0001);
 20.017:0009:trace:midi:MIDI_NotifyClient wDevID = 0001 wMsg = 964 dwParm1 = B28258 dwParam2 = 4E31
 20.017:0009:trace:driver:DriverCallback (00000023, task 0002, 0x8000, 03C4, 00B28110, 00B28258, 00004E31)
 20.017:0009:trace:driver:DriverCallback Done
 20.017:0009:trace:midi:MIDI_NotifyClient wDevID = 0001 wMsg = 964 dwParm1 = B28298 dwParam2 = 4E31
 20.017:0009:trace:driver:DriverCallback (00000023, task 0002, 0x8000, 03C4, 00B28110, 00B28298, 00004E31)
 20.018:0009:trace:driver:DriverCallback Done

After that, the timeout happens.

Joerg, if you want the complete log I can send it to you by PM, it's
about 1.7M.

So the conclusion is that it's necessary to add the end markers if
they are missing.

MSDN [1] contains this somewhat strange 'Note':

	Note  Any MIDI status byte other than a system-real-time
	message will terminate a system-exclusive message. If you are
	using multiple data blocks to send a single system-exclusive
	message, do not send any MIDI messages other than
	system-real-time messages between data blocks.

This could be interpreted to mean that Windows will add the 0xF7
marker, if it was missing, when any other MIDI message is sent. I don't
know if that's true and I currently don't have a Windows machine to
test. 

[1]
http://msdn.microsoft.com/en-us/library/windows/desktop/dd798657%28v=vs.85%29




More information about the wine-devel mailing list