From 7519326d03568b57b57dfde93ca59e7174182a70 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Mon, 27 Aug 2007 17:07:14 +0200 Subject: [PATCH] dsound: Add a function to (re)open sound device to avoid code duplication. --- dlls/dsound/dsound.c | 45 ++----------------- dlls/dsound/dsound_private.h | 1 + dlls/dsound/primary.c | 84 ++++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 54 deletions(-) diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c index bbbbd0dad7c..7d6dc93497c 100644 --- a/dlls/dsound/dsound.c +++ b/dlls/dsound/dsound.c @@ -1413,52 +1413,15 @@ HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcG device->guid = devGUID; device->driver = NULL; - /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */ - if (ds_hw_accel != DS_HW_ACCEL_EMULATION) - waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0); - - /* Get driver description */ - if (device->driver) { - hr = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc)); - if (hr != DS_OK) { - WARN("IDsDriver_GetDriverDesc failed\n"); - return hr; - } - } else { - /* if no DirectSound interface available, use WINMM API instead */ - device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT; - } - device->drvdesc.dnDevNode = wod; - - /* If the driver requests being opened through MMSYSTEM - * (which is recommended by the DDK), it is supposed to happen - * before the DirectSound interface is opened */ - if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) + hr = DSOUND_ReopenDevice(device, FALSE); + if (FAILED(hr)) { - DWORD flags = CALLBACK_FUNCTION; - - /* disable direct sound if requested */ - if (device->driver) - flags |= WAVE_DIRECTSOUND; - - hr = mmErr(waveOutOpen(&(device->hwo), - device->drvdesc.dnDevNode, device->pwfx, - (DWORD_PTR)DSOUND_callback, (DWORD)device, - flags)); - if (hr != DS_OK) { - WARN("waveOutOpen failed\n"); - return hr; - } + WARN("DSOUND_ReopenDevice failed: %08x\n", hr); + return hr; } if (device->driver) { - hr = IDsDriver_Open(device->driver); - if (hr != DS_OK) { - WARN("IDsDriver_Open failed\n"); - return hr; - } - /* the driver is now open, so it's now allowed to call GetCaps */ hr = IDsDriver_GetCaps(device->driver,&(device->drvcaps)); if (hr != DS_OK) { diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index f3032e8e5cc..db73f77d144 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -426,6 +426,7 @@ HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device); HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device); HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos); HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex); +HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave); /* duplex.c */ diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index 44b453a7593..69c1734fd59 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -68,6 +68,67 @@ static void DSOUND_RecalcPrimary(DirectSoundDevice *device) device->writelead = (device->pwfx->nSamplesPerSec / 100) * nBlockAlign; } +HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) +{ + HRESULT hres = DS_OK; + if (device->driver) + { + IDsDriver_Close(device->driver); + if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) + waveOutClose(device->hwo); + IDsDriver_Release(device->driver); + device->driver = NULL; + device->buffer = NULL; + device->hwo = 0; + } + else if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) + waveOutClose(device->hwo); + + /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */ + if (ds_hw_accel != DS_HW_ACCEL_EMULATION && !forcewave) + waveOutMessage((HWAVEOUT)device->drvdesc.dnDevNode, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0); + + /* Get driver description */ + if (device->driver) { + DWORD wod = device->drvdesc.dnDevNode; + hres = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc)); + device->drvdesc.dnDevNode = wod; + if (FAILED(hres)) { + WARN("IDsDriver_GetDriverDesc failed: %08x\n", hres); + IDsDriver_Release(device->driver); + device->driver = NULL; + } + } + + /* if no DirectSound interface available, use WINMM API instead */ + if (!device->driver) + device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT; + + if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) + { + DWORD flags = CALLBACK_FUNCTION; + + if (device->driver) + flags |= WAVE_DIRECTSOUND; + + hres = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode, device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD)device, flags)); + if (FAILED(hres)) { + WARN("waveOutOpen failed\n"); + if (device->driver) + { + IDsDriver_Release(device->driver); + device->driver = NULL; + } + return hres; + } + } + + if (device->driver) + hres = IDsDriver_Open(device->driver); + + return hres; +} + static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) { HRESULT err = DS_OK; @@ -82,17 +143,8 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) if (err != DS_OK) { WARN("IDsDriver_CreateSoundBuffer failed (%08x), falling back to waveout\n", err); - /* Wine-only: close wine directsound driver, then reopen without WAVE_DIRECTSOUND */ - IDsDriver_Close(device->driver); - if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) - waveOutClose(device->hwo); - IDsDriver_Release(device->driver); - device->driver = NULL; - device->buffer = NULL; - device->hwo = 0; - device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT; - err = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode, device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD)device, CALLBACK_FUNCTION)); - if (err != DS_OK) + err = DSOUND_ReopenDevice(device, TRUE); + if (FAILED(err)) { WARN("Falling back to waveout failed too! Giving up\n"); return err; @@ -284,9 +336,15 @@ HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) err = IDsDriverBuffer_Stop(device->hwbuf); if (err == DSERR_BUFFERLOST) { DSOUND_PrimaryClose(device); - err = DSOUND_PrimaryOpen(device); + err = DSOUND_ReopenDevice(device, !device->driver); if (FAILED(err)) - WARN("DSOUND_PrimaryOpen failed\n"); + ERR("DSOUND_ReopenDevice failed\n"); + else + { + err = DSOUND_PrimaryOpen(device); + if (FAILED(err)) + WARN("DSOUND_PrimaryOpen failed\n"); + } } else if (err != DS_OK) { WARN("IDsDriverBuffer_Stop failed\n"); }