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