Maarten Lankhorst : dsound: Add a function to (re)
open sound device to avoid code duplication.
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Aug 27 13:57:13 CDT 2007
Module: wine
Branch: master
Commit: 7519326d03568b57b57dfde93ca59e7174182a70
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7519326d03568b57b57dfde93ca59e7174182a70
Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date: Mon Aug 27 17:07:14 2007 +0200
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 bbbbd0d..7d6dc93 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 f3032e8..db73f77 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 44b453a..69c1734 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");
}
More information about the wine-cvs
mailing list