https://bugs.winehq.org/show_bug.cgi?id=52592
Bug ID: 52592 Summary: MilkyTracker does not work: no valid waveout devices. Product: Wine Version: unspecified Hardware: aarch64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: winmm&mci Assignee: wine-bugs@winehq.org Reporter: carlo.bramix@libero.it Distribution: ---
MilkyTracker is an multi-platform music application for creating .MOD and .XM module files.
https://github.com/milkytracker/MilkyTracker
Unfortunately, it doesn't work on WINE because it cannot open any waveout device. Sources of MilkyTracker do these actions:
1) waveOutOpen(&hwo, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL);
This call is a success and it returns a valid handle.
2) waveOutGetID(hwo,(LPUINT)&waveOutID);
This call also returns success and it returns a value of 63 into "waveOutID". BUT THIS IS WRONG. "waveOutID" should be equal to WAVE_MAPPER, which equal to -1, as you can see in point (1).
3) waveOutGetDevCaps((UINT)waveOutID, &waveoutcaps, sizeof(waveoutcaps));
As result, this call to waveOutGetDevCaps() fails with return value of MMSYSERR_BADDEVICEID.
Here there is the point where there is the code that I'm talking about:
https://github.com/milkytracker/MilkyTracker/blob/4f97b7011b20519890e30368e2...
The cause of the trouble is the way the function waveOutGetID() is implemented. waveOutGetID() calls WINMM_GetDeviceFromHWAVE(). And WINMM_GetDeviceFromHWAVE() calls WINMM_DecomposeHWAVE() Into WINMM_DecomposeHWAVE(), there are these lines:
ULONG32 l = HandleToULong(hwave); *device_index = l & 0xFF;
But this is wrong, because *device_index will be never able to return -1 that is the value for WAVE_MAPPER.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #1 from Carlo Bramini carlo.bramix@libero.it --- In addition, I can tell you that I used the last source of WINE available at the time of writing, after version 7.2. I discovered it by using WINE on Aarch64 but, by looking the source of WINMM, I think that this can be easily verified also on i686 and x64.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #2 from Rafał Mużyło galtgendo@o2.pl --- If I'm reading the code correctly, what you're actually saying is that in waveOutGetID (and - most likely - in waveInGetID too), the line
WINMM_DecomposeHWAVE((HWAVE)hWaveOut, lpuDeviceID, &is_out, &dev, &junk);
should actually go:
WINMM_DecomposeHWAVE((HWAVE)hWaveOut, &dev, &is_out, lpuDeviceID, &junk);
because that's where things actually seem to fail (WINMM_IsMapper checks against device index, not mm_device index; most of the other functions seem to expect device index too).
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #3 from Rafał Mużyło galtgendo@o2.pl --- ...actually, ignore the nonsense above, understanding the code takes awhile...
What is actually needed is far more simple: in waveOutGetDevCapsW, WINMM_IsMapper shouldn't be used. Just like in WINMM_GetDeviceFromHWAVE, proper check should be ' uDeviceID == MAPPER_INDEX'.
...actually, I don't really understand the difference between device index and mm_device index, cause looking at the relevant sections, it seems to me that ' uDeviceID == MAPPER_INDEX' should actually be what WINMM_IsMapper should be checking for - in most of those, uDeviceID is later checked against g_inmmdevices_count, which would suggest that the code always expects mm_device index.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #4 from Carlo Bramini carlo.bramix@libero.it --- The problem is that waveOutGetID() does not return the same id that you used into waveOutOpen().
On Windows, waveOutGetID() returns WAVE_MAPPER (-1). On WINE, waveOutGetID() returns 63 on my system.
It is not the same thing and this seems wrong.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #5 from Rafał Mużyło galtgendo@o2.pl --- A longer look at the sources seem to confirm that in pretty much all cases (in, out and mixer) the value checked against is the mm_device index. It's almost certainly true for all uDeviceID and req_device checks. Only piece contradicting this is reroute_mapper_device, but that's pretty much it.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #6 from Rafał Mużyło galtgendo@o2.pl --- (In reply to Carlo Bramini from comment #4)
The problem is that waveOutGetID() does not return the same id that you used into waveOutOpen().
On Windows, waveOutGetID() returns WAVE_MAPPER (-1). On WINE, waveOutGetID() returns 63 on my system.
It is not the same thing and this seems wrong.
Good point. So, basically, waveOutGetID (and likely waveInGetID) need to explicitly special case WAVE_MAPPER, instead of pushing it through WINMM_DecomposeHWAVE (cause that one seems correct as it is).
Something like:
if (hWaveOut = WAVE_MAPPER) *lpuDeviceID = WAVE_MAPPER; else WINMM_DecomposeHWAVE((HWAVE)hWaveOut, lpuDeviceID, &is_out, &dev, &junk);
That way current WINMM_IsMapper check will make some sense.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #7 from Rafał Mużyło galtgendo@o2.pl --- ...'hWaveOut == WAVE_MAPPER', obviously...
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #8 from Rafał Mużyło galtgendo@o2.pl --- ...sorry, that's again nonsense...
What would work would be what follows your report: after WINMM_DecomposeHWAVE, 'if (*lpuDeviceID == MAPPER_INDEX) *lpuDeviceID = -1;'.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #9 from Rafał Mużyło galtgendo@o2.pl --- ...and without magic numbers: '*lpuDeviceID = WAVE_MAPPER;'
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #10 from Rafał Mużyło galtgendo@o2.pl --- ...I'm still being confused by the term 'handle'...
Reading the code again, idea from comment 6 might actually be valid too... One way or another, by your report WAVE_MAPPER needs to be special-cased in (most likely) both of these functions.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #11 from Carlo Bramini carlo.bramix@libero.it --- Created attachment 71958 --> https://bugs.winehq.org/attachment.cgi?id=71958 Test program to reproduce the bug.
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #12 from Carlo Bramini carlo.bramix@libero.it --- This test program allows to reproduce the bug. On Windows, it prints on the console:
waveOutOpen success waveOutGetID returned waveOutID=-1, expected -1 waveOutGetDevCaps success
On WINE, it prints:
waveOutOpen success waveOutGetID returned waveOutID=63, expected -1 waveOutGetID failed with error 2
You can compile the tiny example with:
i686-w64-mingw32-gcc test_waveout.c -o test_waveout.exe -mconsole -lwinmm
You can replace "i686" with "x86_64" if you want a 64bit executable instead.
https://bugs.winehq.org/show_bug.cgi?id=52592
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Hardware|aarch64 |x86-64 Keywords| |download, testcase
https://bugs.winehq.org/show_bug.cgi?id=52592
--- Comment #13 from Carlo Bramini carlo.bramix@libero.it --- There is a pending fix for closing this issue:
https://gitlab.winehq.org/wine/wine/-/merge_requests/4820
https://bugs.winehq.org/show_bug.cgi?id=52592
Ken Sharp imwellcushtymelike@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- URL| |https://github.com/milkytra | |cker/MilkyTracker Keywords| |patch, source Version|unspecified |7.2