dsound: Add a function to (re)open sound device to avoid code duplication.
This commit is contained in:
parent
3bf6315af2
commit
7519326d03
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue