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