[DSOUND] Improvements to DirectSound(Capture)EnumerateW (#3899)

Fix and improve DirectSoundEnumerateW and DirectSoundCaptureEnumerateW implementations in our dsound.

Use the Windows-compatible way to get the device name and pass it to callback.
- Don't use Wine-specific DSDRIVERDESC structure and DRV_QUERYDSOUNDDESC message, declared in sdk/include/dxsdk/dsdriver.h, whose are obsolete even in Wine for now.
- Instead, declare a new WAVEINCAPSW and WAVEOUTCAPSW structures (for input and output appropriately), call waveInGetDevCapsW and WaveOutGetDevCapsW for enumerated device ID and store retieved device name in these structures.
- Then pass them to a lpDSEnumCallbackW as well, without Ansi to Unicode conversion (since the retrieved string is Unicode already).
- Do this both for capture and playback functions.
- Addtionally, add MMSYSERR_BADDEVICEID status code to mmErr macro, because it also might be returned by waveIn/OutGetDevCapsW as well, in case of failure.
- And mark our dosund as forked, because it definitely will not be synced at least until we'll retarget to Vista or newer. Add an appropriate comment.

This fixes incorrect detection of DirectSound audio input and output devices, so now a lot of apps are able to detect it correctly, and can play the sound properly (e.g. AIMP 2.61 and IcyTower from RAPPS).

CORE-7535 CORE-10907 CORE-15324 CORE-15533 CORE-16340
This commit is contained in:
Oleg Dubinskiy 2021-08-11 21:36:52 +03:00 committed by Stanislav Motylkov
parent d6002f9475
commit d7b2280c5c
No known key found for this signature in database
GPG key ID: AFE513258CBA9E92
2 changed files with 20 additions and 48 deletions

View file

@ -52,6 +52,7 @@ HRESULT mmErr(UINT err)
case MMSYSERR_INVALHANDLE:
case WAVERR_STILLPLAYING:
return DSERR_GENERIC; /* FIXME */
case MMSYSERR_BADDEVICEID:
case MMSYSERR_NODRIVER:
return DSERR_NODRIVER;
case MMSYSERR_NOMEM:
@ -318,11 +319,9 @@ HRESULT WINAPI DirectSoundEnumerateW(
LPVOID lpContext )
{
unsigned devs, wod;
DSDRIVERDESC desc;
WAVEOUTCAPSW capsW;
GUID guid;
int err;
WCHAR wDesc[MAXPNAMELEN];
WCHAR wName[MAXPNAMELEN];
TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
lpDSEnumCallback, lpContext);
@ -337,16 +336,13 @@ HRESULT WINAPI DirectSoundEnumerateW(
devs = waveOutGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
static const WCHAR empty[] = { 0 };
for (wod = 0; wod < devs; ++wod) {
if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod] ) ) {
err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
err = mmErr(waveOutGetDevCapsW(wod, &capsW, sizeof(WAVEOUTCAPSW)));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
"Primary Sound Driver",desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE)
TRACE("calling lpDSEnumCallback(NULL,\"%ls\",\"%ls\",%p)\n",
capsW.szPname,L"Primary Sound Driver",lpContext);
if (lpDSEnumCallback(NULL, capsW.szPname, L"Primary Sound Driver", lpContext) == FALSE)
return DS_OK;
}
}
@ -355,19 +351,11 @@ HRESULT WINAPI DirectSoundEnumerateW(
}
for (wod = 0; wod < devs; ++wod) {
err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
err = mmErr(waveOutGetDevCapsW(wod, &capsW, sizeof(WAVEOUTCAPSW)));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0';
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], wDesc, wName, lpContext) == FALSE)
TRACE("calling lpDSEnumCallback(%s,\"%ls\",\"%ls\",%p)\n",
debugstr_guid(&DSOUND_renderer_guids[wod]),capsW.szPname,L"Primary Sound Driver",lpContext);
if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], capsW.szPname, L"Primary Sound Driver", lpContext) == FALSE)
return DS_OK;
}
}
@ -423,11 +411,9 @@ DirectSoundCaptureEnumerateW(
LPVOID lpContext)
{
unsigned devs, wid;
DSDRIVERDESC desc;
WAVEINCAPSW capsW;
GUID guid;
int err;
WCHAR wDesc[MAXPNAMELEN];
WCHAR wName[MAXPNAMELEN];
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
@ -443,17 +429,11 @@ DirectSoundCaptureEnumerateW(
if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
for (wid = 0; wid < devs; ++wid) {
if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) {
err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
err = mmErr(waveInGetDevCapsW(wid, &capsW, sizeof(WAVEINCAPSW)));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
"Primary Sound Capture Driver",desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
TRACE("calling lpDSEnumCallback(NULL,\"%ls\",\"%ls\",%p)\n",
capsW.szPname,L"Primary Sound Capture Driver",lpContext);
if (lpDSEnumCallback(NULL, capsW.szPname, L"Primary Sound Capture Driver", lpContext) == FALSE)
return DS_OK;
}
}
@ -462,19 +442,11 @@ DirectSoundCaptureEnumerateW(
}
for (wid = 0; wid < devs; ++wid) {
err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel));
err = mmErr(waveInGetDevCapsW(wid, &capsW, sizeof(WAVEINCAPSW)));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext);
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
wDesc[(sizeof(wDesc)/sizeof(WCHAR)) - 1] = '\0';
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
wName[(sizeof(wName)/sizeof(WCHAR)) - 1] = '\0';
if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE)
TRACE("calling lpDSEnumCallback(%s,\"%ls\",\"%ls\",%p)\n",
debugstr_guid(&DSOUND_capture_guids[wid]),capsW.szPname,L"Primary Sound Capture Driver",lpContext);
if (lpDSEnumCallback(&DSOUND_capture_guids[wid], capsW.szPname, L"Primary Sound Capture Driver", lpContext) == FALSE)
return DS_OK;
}
}

View file

@ -36,7 +36,7 @@ dll/directx/wine/dmusic # Synced to WineStaging-4.18
dll/directx/wine/dplay # Synced to WineStaging-3.3
dll/directx/wine/dplayx # Synced to WineStaging-4.18
dll/directx/wine/dpnhpast # Synced to WineStaging-4.18
dll/directx/wine/dsound # Synced to Wine-1.3.29
dll/directx/wine/dsound # Forked at Wine-1.3.29. Newer versions are depending on NT6+ mmdevapi, so the further syncing makes no sense until we're retargeted to Vista or newer.
dll/directx/wine/dxdiagn # Synced to WineStaging-4.18
dll/directx/wine/msdmo # Synced to WineStaging-4.18
dll/directx/wine/qcap # Synced to WineStaging-3.3