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->guid = devGUID;
|
||||||
device->driver = NULL;
|
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;
|
device->drvdesc.dnDevNode = wod;
|
||||||
|
hr = DSOUND_ReopenDevice(device, FALSE);
|
||||||
/* If the driver requests being opened through MMSYSTEM
|
if (FAILED(hr))
|
||||||
* (which is recommended by the DDK), it is supposed to happen
|
|
||||||
* before the DirectSound interface is opened */
|
|
||||||
if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
|
|
||||||
{
|
{
|
||||||
DWORD flags = CALLBACK_FUNCTION;
|
WARN("DSOUND_ReopenDevice failed: %08x\n", hr);
|
||||||
|
return hr;
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->driver) {
|
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 */
|
/* the driver is now open, so it's now allowed to call GetCaps */
|
||||||
hr = IDsDriver_GetCaps(device->driver,&(device->drvcaps));
|
hr = IDsDriver_GetCaps(device->driver,&(device->drvcaps));
|
||||||
if (hr != DS_OK) {
|
if (hr != DS_OK) {
|
||||||
|
|
|
@ -426,6 +426,7 @@ HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device);
|
||||||
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device);
|
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device);
|
||||||
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos);
|
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos);
|
||||||
HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex);
|
HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex);
|
||||||
|
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave);
|
||||||
|
|
||||||
/* duplex.c */
|
/* duplex.c */
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,67 @@ static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
|
||||||
device->writelead = (device->pwfx->nSamplesPerSec / 100) * nBlockAlign;
|
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)
|
static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
|
||||||
{
|
{
|
||||||
HRESULT err = DS_OK;
|
HRESULT err = DS_OK;
|
||||||
|
@ -82,17 +143,8 @@ static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
|
||||||
|
|
||||||
if (err != DS_OK) {
|
if (err != DS_OK) {
|
||||||
WARN("IDsDriver_CreateSoundBuffer failed (%08x), falling back to waveout\n", err);
|
WARN("IDsDriver_CreateSoundBuffer failed (%08x), falling back to waveout\n", err);
|
||||||
/* Wine-only: close wine directsound driver, then reopen without WAVE_DIRECTSOUND */
|
err = DSOUND_ReopenDevice(device, TRUE);
|
||||||
IDsDriver_Close(device->driver);
|
if (FAILED(err))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
WARN("Falling back to waveout failed too! Giving up\n");
|
WARN("Falling back to waveout failed too! Giving up\n");
|
||||||
return err;
|
return err;
|
||||||
|
@ -284,9 +336,15 @@ HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device)
|
||||||
err = IDsDriverBuffer_Stop(device->hwbuf);
|
err = IDsDriverBuffer_Stop(device->hwbuf);
|
||||||
if (err == DSERR_BUFFERLOST) {
|
if (err == DSERR_BUFFERLOST) {
|
||||||
DSOUND_PrimaryClose(device);
|
DSOUND_PrimaryClose(device);
|
||||||
err = DSOUND_PrimaryOpen(device);
|
err = DSOUND_ReopenDevice(device, !device->driver);
|
||||||
if (FAILED(err))
|
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) {
|
} else if (err != DS_OK) {
|
||||||
WARN("IDsDriverBuffer_Stop failed\n");
|
WARN("IDsDriverBuffer_Stop failed\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue