Hi,
Johannes Krol wrote:
Joerg, if you want the complete log I can send it to you by PM, it's about 1.7M.
I don't need that for now. What I need are the 119 missing bytes between 17.015:003b:trace:midi:modLongData dwBufferLength=125 ! 17.015:003b:trace:midi:modLongData F0 42 40 ... 00 00 00
Please copy&paste & adapt this code to produce a full hex dump: http://source.winehq.org/source/dlls/winmm/winmm.c#L1066
In particular, I want to know if there's some F7 amid that data (remember that your original patch precisely stopped at a F7...) and what the bytes following that F7 look like.
This could be interpreted to mean that Windows will add the 0xF7 marker, if it was missing, when any other MIDI message is sent.
That's a possible interpretation, however your log snippet shows no sign of sending another message.
Do you have MIDI/ALSA debugging tools that can show you whether ALSA truly sends out the 125 bytes? That too would help identify the problem.
Thank you, Jörg Höhle
On Tue, 12 Feb 2013 15:49:18 +0100 Joerg-Cyril.Hoehle@t-systems.com wrote:
Hi,
Johannes Krol wrote:
Joerg, if you want the complete log I can send it to you by PM, it's about 1.7M.
I don't need that for now. What I need are the 119 missing bytes between 17.015:003b:trace:midi:modLongData dwBufferLength=125 ! 17.015:003b:trace:midi:modLongData F0 42 40 ... 00 00 00
Please copy&paste & adapt this code to produce a full hex dump: http://source.winehq.org/source/dlls/winmm/winmm.c#L1066
In particular, I want to know if there's some F7 amid that data (remember that your original patch precisely stopped at a F7...) and what the bytes following that F7 look like.
9.532:0023:trace:winmm:MMDRV_Message Calling message(dev=2 msg=59 usr=0x00008000 p1=0x00b281b8 p2=0x00000040) 9.532:003a:warn:midi:modLongData Alleged system exclusive buffer is not correct Please report with MIDI file 9.532:0023:trace:midi:ALSA_midMessage (0002, 003B, 00008000, 00B281B8, 00000040); 9.532:003a:trace:midi:modLongData dwBufferLength=88 ! f0 42 9.532:0023:trace:midi:midAddBuffer (0002, 0xb281b8, 00000040); 41 00 01 11 01 7f 4b 40 7a 01 7f 02 7f 7f .BA.....K@z..... 7f 7f 71 7f 40 01 7f 7f 7f 7f 03 7f 7f 01 01 00 ..q.@........... 00 7f 06 02 7f 7f 01 40 00 00 7c 7f 00 7f 7f 7f .......@..|..... 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ................ 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ................ 7f 7f 01 7f f7 00 00 00 ........ 9.532:003a:trace:midi:modLongData dwBytesRecorded=0
So there is an F7 there... Maybe the app expects that the driver scans through the buffer for the F7 and doesn't send the following bytes...
In any case, adding an F7 at the end works for my hardware but it isn't correct...
Hi,
Johannes Kroll wrote:
9.532:003a:trace:midi:modLongData dwBufferLength=88 ! f0 42 41 00 01 11 01 7f 4b 40 7a 01 7f 02 7f 7f .BA.....K@z..... 7f 7f 71 7f 40 01 7f 7f 7f 7f 03 7f 7f 01 01 00 ..q.@........... 00 7f 06 02 7f 7f 01 40 00 00 7c 7f 00 7f 7f 7f .......@..|..... 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ................ 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ................ 7f 7f 01 7f f7 00 00 00 ........
Could you please log dwBytesRecorded next to TRACE("dwBufferLength=%u !\n", lpMidiHdr->dwBufferLength);
I once proved that dwBytesRecorded is what gets used with midiSTREAMout
So there is an F7 there... Maybe the app expects that the driver scans through the buffer for the F7 and doesn't send the following bytes...
Net.wisdom is that modLongData need be scanned for coalesced regular status messages, e.g. some people use it to play chords, arguing that one LongMsg is faster than 3 consecutive midiOutShortMsg. That's a patch yet to be written.
However, I wouldn't know what to do with the three 00 bytes. That's not MIDI!
Also, I'm wondering what ALSA does with that packet. Do the bytes as shown really make their way over the serial port? (Perhaps you could use some virtual MIDI device to dump what ALSA processes internally?)
Do you have a working wineOSS? WineOSS simply dumps the bytes one by one and does not require us to tell it what a sysex might be. I already tested that disguising a chord as an ALSA SysEx within midiOutLongMsg doesn't work (at least with a SW synth).
Thank you, Jörg Höhle
On Wed, 13 Feb 2013 09:29:19 +0100 Joerg-Cyril.Hoehle@t-systems.com wrote:
Hi,
Johannes Kroll wrote:
9.532:003a:trace:midi:modLongData dwBufferLength=88 ! f0 42 41 00 01 11 01 7f 4b 40 7a 01 7f 02 7f 7f .BA.....K@z..... 7f 7f 71 7f 40 01 7f 7f 7f 7f 03 7f 7f 01 01 00 ..q.@........... 00 7f 06 02 7f 7f 01 40 00 00 7c 7f 00 7f 7f 7f .......@..|..... 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ................ 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f 7f ................ 7f 7f 01 7f f7 00 00 00 ........
Could you please log dwBytesRecorded next to TRACE("dwBufferLength=%u !\n", lpMidiHdr->dwBufferLength);
I once proved that dwBytesRecorded is what gets used with midiSTREAMout
I did. It is in the log line that you deleted. Immediately after the hex dump...
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]); { unsigned long dwToGo; #define dprintf(x...) fprintf(stderr, x) for (dwToGo = 0; dwToGo < lpMidiHdr->dwBufferLength; dwToGo += 16) { DWORD i; BYTE ch;
for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) dprintf("%02x ", lpData[dwToGo + i]); for (; i < 16; i++) dprintf(" "); for (i = 0; i < min(16, lpMidiHdr->dwBufferLength - dwToGo); i++) { ch = lpData[dwToGo + i]; dprintf("%c", (ch >= 0x20 && ch < 0x7F) ? ch : '.'); } dprintf("\n"); } TRACE("dwBytesRecorded=%d\n", lpMidiHdr->dwBytesRecorded); }
So there is an F7 there... Maybe the app expects that the driver scans through the buffer for the F7 and doesn't send the following bytes...
Net.wisdom is that modLongData need be scanned for coalesced regular status messages, e.g. some people use it to play chords, arguing that one LongMsg is faster than 3 consecutive midiOutShortMsg. That's a patch yet to be written.
However, I wouldn't know what to do with the three 00 bytes. That's not MIDI!
No. Maybe dwBytesRecorded *should* be the length of the data. But it isn't, it's always zero. Yes, really, I checked in several runs.
Also, I'm wondering what ALSA does with that packet. Do the bytes as shown really make their way over the serial port? (Perhaps you could use some virtual MIDI device to dump what ALSA processes internally?)
If I figure out a way to do that I'll let you know...
Do you have a working wineOSS? WineOSS simply dumps the bytes one by one and does not require us to tell it what a sysex might be. I already tested that disguising a chord as an ALSA SysEx within midiOutLongMsg doesn't work (at least with a SW synth).
No, I don't have wineOSS. Does it require a proper OSSv4? Or would it work with ALSA OSS emulation? I don't have 'real' OSS.
Johannes Kroll wrote:
It is in the log line that you deleted.
Oops.
No, I don't have wineOSS. Does it require a proper OSSv4?
Currently, yes. You'd have to try out wine-1.3.24 or older.
I'll try and see how to use virtual MIDI devices to dump data without using a serial port.
Anyway, I'll start writing a patch that decomposes LongMsg into snippets, although I don't know how to handle the three 00 00 00 bytes.
Regards, Jörg Höhle
On Wed, 13 Feb 2013 19:18:42 +0100 Joerg-Cyril.Hoehle@t-systems.com wrote:
Johannes Kroll wrote:
It is in the log line that you deleted.
Oops.
No, I don't have wineOSS. Does it require a proper OSSv4?
Currently, yes. You'd have to try out wine-1.3.24 or older.
I'll try and see how to use virtual MIDI devices to dump data without using a serial port.
Anyway, I'll start writing a patch that decomposes LongMsg into snippets, although I don't know how to handle the three 00 00 00 bytes.
I don't understand what you mean by "decompose LongMsg into snippets".
Is it possible that either A) the app expects the API code to scan the buffer for a trailing 0xf7 end marker and send only the bytes up to that marker; or B) that the mysterious "dwBytesRecorded" should really contain the bytes to be sent, and that it should be set by a function calling LongMsg (i. e. somewhere else in Wine)?
Hi,
Johannes Kroll wrote:
I don't understand what you mean by "decompose LongMsg into snippets". Is it possible that either A) the app expects the API code to scan the buffer for a trailing 0xf7 end marker and send only the bytes up to that marker; or B) that the mysterious "dwBytesRecorded" should really contain the bytes to be sent, and that it should be set by a function calling LongMsg (i. e. somewhere else in Wine)?
We have no evidence that dwBytesRecorded shall be used.
Neither A nor B. I'll explain. Net.wisdom has it that midiOutLongMsg can be used to play chords, e.g. send 2 note-on events: 91 K1 V1 92 K2 V2
If MIDI worked only over the serial port, there would be no complication: Simply send all those bytes over the serial port. Let the receiver handle them.
The OSS interface works like this: just dump bytes one by one. http://source.winehq.org/source/dlls/wineoss.drv/midi.c?v=wine-1.5.23#L1559 That's why I believe OSS would work fine as is with your app.
The ALSA interface is much more complex. It expects markup - use snd_seq_ev_set_sysex() for a SysEx, - use snd_seq_ev_set_noteoff() for NOTE_OFF, - snd_seq_ev_set_noteon|keypress|controller|... http://source.winehq.org/source/dlls/winealsa.drv/midi.c?v=wine-1.5.23#L844
Therefore, winealsa needs to scan the buffer and decompose it into snippets, then call the matching snd_seq_ev_set_* function.
So winealsa must call snd_seq_ev_set_noteon on each 91 K1 V1 snippet. In the case of your app it would call snd_seq_ev_set_sysex on the F0...F7 snippet, then ... well I don't know what to call on the remaining three 00 00 00 bytes. The "simply send bytes over the serial port" analogy would mean to not skip those bytes rather than find some means to send them via ALSA.
Regards, Jörg Höhle