Commit 8c2ec131 authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Added a configuration option for setting the hardware acceleration

level just like the direct sound control panel app. More work on the full duplex interface so the compile warning is no longer generated. Full duplex interface is still stubbed out. Moved full duplex mixer reset fix into wineoss driver where it belongs. Added some more locking fixes. Capture and full duplex are now stable.
parent 998f56e0
......@@ -64,6 +64,16 @@ static HRESULT DSOUND_CreateDirectSoundCaptureBuffer(
IDirectSoundCaptureImpl *ipDSC,
LPCDSCBUFFERDESC lpcDSCBufferDesc,
LPVOID* ppobj );
static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(
LPDIRECTSOUNDFULLDUPLEX iface,
LPCGUID pCaptureGuid,
LPCGUID pRendererGuid,
LPCDSCBUFFERDESC lpDscBufferDesc,
LPCDSBUFFERDESC lpDsBufferDesc,
HWND hWnd,
DWORD dwLevel,
LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 );
static ICOM_VTABLE(IDirectSoundCapture) dscvt;
static ICOM_VTABLE(IDirectSoundCaptureBuffer8) dscbvt;
......@@ -427,9 +437,13 @@ IDirectSoundCaptureImpl_Initialize(
}
err = DS_OK;
/* Disable the direct sound driver to force emulation if requested. */
if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
This->driver = NULL;
/* Get driver description */
if (This->driver) {
ERR("You have a sound card that is Direct Sound Capture capable but the driver is not finished\n");
ERR("You have a sound card that is Direct Sound Capture capable but the driver is not finished. You can add a line to the wine config file in [dsound]: \"HardwareAcceleration\" = \"Emulation\" to force emulation mode.\n");
/* FIXME: remove this return to test driver */
return DSERR_NODRIVER;
TRACE("using DirectSound driver\n");
......@@ -455,6 +469,7 @@ IDirectSoundCaptureImpl_Initialize(
/* the driver is now open, so it's now allowed to call GetCaps */
if (This->driver) {
This->drvcaps.dwSize = sizeof(This->drvcaps);
err = IDsCaptureDriver_GetCaps(This->driver,&(This->drvcaps));
if (err != DS_OK) {
WARN("IDsCaptureDriver_GetCaps failed\n");
......@@ -580,10 +595,12 @@ DSOUND_CreateDirectSoundCaptureBuffer(
} else {
LPBYTE newbuf;
DWORD buflen;
DWORD flags = CALLBACK_FUNCTION;
if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
flags |= WAVE_DIRECTSOUND;
err = mmErr(waveInOpen(&(ipDSC->hwi),
ipDSC->drvdesc.dnDevNode, &(ipDSC->wfx),
(DWORD)DSOUND_capture_callback, (DWORD)ipDSC,
CALLBACK_FUNCTION | WAVE_DIRECTSOUND));
(DWORD)DSOUND_capture_callback, (DWORD)ipDSC, flags));
if (err != DS_OK) {
WARN("waveInOpen failed\n");
ipDSC->hwi = 0;
......@@ -757,6 +774,7 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition(
if (This->dsound->driver) {
return IDsCaptureDriverBuffer_GetPosition(This->dsound->hwbuf, lpdwCapturePosition, lpdwReadPosition );
} else if (This->dsound->hwi) {
EnterCriticalSection(&(This->dsound->lock));
TRACE("old This->dsound->state=%ld\n",This->dsound->state);
if (lpdwCapturePosition) {
MMTIME mtime;
......@@ -777,6 +795,7 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition(
*lpdwReadPosition = This->dsound->read_position;
}
TRACE("new This->dsound->state=%ld\n",This->dsound->state);
LeaveCriticalSection(&(This->dsound->lock));
if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%ld\n",*lpdwCapturePosition);
if (lpdwReadPosition) TRACE("*lpdwReadPosition=%ld\n",*lpdwReadPosition);
} else {
......@@ -838,6 +857,8 @@ IDirectSoundCaptureBufferImpl_GetStatus(
}
*lpdwStatus = 0;
EnterCriticalSection(&(This->dsound->lock));
TRACE("old This->dsound->state=%ld, old lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus);
if ((This->dsound->state == STATE_STARTING) ||
(This->dsound->state == STATE_CAPTURING)) {
......@@ -846,6 +867,7 @@ IDirectSoundCaptureBufferImpl_GetStatus(
*lpdwStatus |= DSCBSTATUS_LOOPING;
}
TRACE("new This->dsound->state=%ld, new lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus);
LeaveCriticalSection(&(This->dsound->lock));
TRACE("status=%lx\n", *lpdwStatus);
TRACE("returning DS_OK\n");
......@@ -1170,6 +1192,63 @@ static ICOM_VTABLE(IDirectSoundCaptureBuffer8) dscbvt =
IDirectSoundCaptureBufferImpl_GetFXStatus
};
/***************************************************************************
* DirectSoundFullDuplexCreate8 [DSOUND.8]
*
* Create and initialize a DirectSoundFullDuplex interface
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
* DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
*/
HRESULT WINAPI
DirectSoundFullDuplexCreate8(
LPCGUID pcGuidCaptureDevice,
LPCGUID pcGuidRenderDevice,
LPCDSCBUFFERDESC pcDSCBufferDesc,
LPCDSBUFFERDESC pcDSBufferDesc,
HWND hWnd,
DWORD dwLevel,
LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
LPUNKNOWN pUnkOuter)
{
IDirectSoundFullDuplexImpl** ippDSFD=(IDirectSoundFullDuplexImpl**)ppDSFD;
TRACE("(%s,%s,%p,%p,%lx,%lx,%p,%p,%p,%p)\n", debugstr_guid(pcGuidCaptureDevice),
debugstr_guid(pcGuidRenderDevice), pcDSCBufferDesc, pcDSBufferDesc,
(DWORD)hWnd, dwLevel, ppDSFD, ppDSCBuffer8, ppDSBuffer8, pUnkOuter);
if ( pUnkOuter ) {
WARN("pUnkOuter != 0\n");
return DSERR_NOAGGREGATION;
}
*ippDSFD = (IDirectSoundFullDuplexImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
if (*ippDSFD == NULL) {
TRACE("couldn't allocate memory\n");
return DSERR_OUTOFMEMORY;
}
else
{
ICOM_THIS(IDirectSoundFullDuplexImpl, *ippDSFD);
This->ref = 1;
InitializeCriticalSection( &(This->lock) );
ICOM_VTBL(This) = &dsfdvt;
return IDirectSoundFullDuplexImpl_Initialize( (LPDIRECTSOUNDFULLDUPLEX)This,
pcGuidCaptureDevice, pcGuidRenderDevice,
pcDSCBufferDesc, pcDSBufferDesc,
hWnd, dwLevel, ppDSCBuffer8, ppDSBuffer8);
}
}
static HRESULT WINAPI
IDirectSoundFullDuplexImpl_QueryInterface(
LPDIRECTSOUNDFULLDUPLEX iface,
......@@ -1192,6 +1271,7 @@ IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
TRACE( "(%p) was 0x%08lx\n", This, This->ref );
uRef = ++(This->ref);
LeaveCriticalSection( &(This->lock) );
return uRef;
......
......@@ -115,6 +115,7 @@ int ds_hel_margin = DS_HEL_MARGIN;
int ds_hel_queue = DS_HEL_QUEUE;
int ds_snd_queue_max = DS_SND_QUEUE_MAX;
int ds_snd_queue_min = DS_SND_QUEUE_MIN;
int ds_hw_accel = DS_HW_ACCEL_FULL;
/*
* Call the callback provided to DirectSoundEnumerateA.
......@@ -199,6 +200,17 @@ void setup_dsound_options(void)
if (!get_config_key( hkey, appkey, "SndQueueMin", buffer, MAX_PATH ))
ds_snd_queue_min = atoi(buffer);
if (!get_config_key( hkey, appkey, "HardwareAcceleration", buffer, MAX_PATH )) {
if (strcmp(buffer, "Full") == 0)
ds_hw_accel = DS_HW_ACCEL_FULL;
else if (strcmp(buffer, "Standard") == 0)
ds_hw_accel = DS_HW_ACCEL_STANDARD;
else if (strcmp(buffer, "Basic") == 0)
ds_hw_accel = DS_HW_ACCEL_BASIC;
else if (strcmp(buffer, "Emulation") == 0)
ds_hw_accel = DS_HW_ACCEL_EMULATION;
}
if (appkey) RegCloseKey( appkey );
RegCloseKey( hkey );
......@@ -212,7 +224,13 @@ void setup_dsound_options(void)
WARN("ds_snd_queue_max = %d (default=%d)\n",ds_snd_queue_max ,DS_SND_QUEUE_MAX);
if (ds_snd_queue_min != DS_SND_QUEUE_MIN)
WARN("ds_snd_queue_min = %d (default=%d)\n",ds_snd_queue_min ,DS_SND_QUEUE_MIN);
if (ds_hw_accel != DS_HW_ACCEL_FULL)
WARN("ds_hw_accel = %s (default=Full)\n",
ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
"Unknown");
}
......@@ -604,6 +622,10 @@ HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *
/* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
/* Disable the direct sound driver to force emulation if requested. */
if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
drv = NULL;
/* Allocate memory */
*ippDS = (IDirectSoundImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
if (*ippDS == NULL)
......@@ -654,6 +676,12 @@ HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *
* before the DirectSound interface is opened */
if ((*ippDS)->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
{
DWORD flags = CALLBACK_FUNCTION;
/* disable direct sound if requested */
if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
flags |= WAVE_DIRECTSOUND;
/* FIXME: is this right? */
(*ippDS)->drvdesc.dnDevNode = 0;
err = DSERR_ALLOCATED;
......@@ -665,7 +693,7 @@ HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *
err = mmErr(waveOutOpen(&((*ippDS)->hwo),
(*ippDS)->drvdesc.dnDevNode, &((*ippDS)->wfx),
(DWORD)DSOUND_callback, (DWORD)(*ippDS),
CALLBACK_FUNCTION | WAVE_DIRECTSOUND));
flags));
(*ippDS)->drvdesc.dnDevNode++; /* next wave device */
}
......
......@@ -26,11 +26,18 @@
#define DS_HEL_FRAGS 48 /* HEL only: number of waveOut fragments in primary buffer
* (changing this won't help you) */
/* direct sound hardware acceleration levels */
#define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
#define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
#define DS_HW_ACCEL_BASIC 2
#define DS_HW_ACCEL_EMULATION 3
extern int ds_emuldriver;
extern int ds_hel_margin;
extern int ds_hel_queue;
extern int ds_snd_queue_max;
extern int ds_snd_queue_min;
extern int ds_hw_accel;
/*****************************************************************************
* Predeclare the interface implementation structures
......
......@@ -901,11 +901,7 @@ void DSOUND_PerformMix(void)
/* DSOUND_callback may need this lock */
LeaveCriticalSection(&(dsound->mixlock));
#endif
/* FIXME: OSS doesn't allow independent stopping of input and output streams */
/* in full duplex mode so don't stop when capturing. This should be moved into */
/* the OSS driver someday. */
if ( (dsound_capture == NULL) || (dsound_capture->state != STATE_CAPTURING) )
DSOUND_PrimaryStop(dsound);
DSOUND_PrimaryStop(dsound);
#ifdef SYNC_CALLBACK
EnterCriticalSection(&(dsound->mixlock));
#endif
......
......@@ -213,6 +213,9 @@ HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This)
if (This->hwbuf) {
err = IDsDriverBuffer_Stop(This->hwbuf);
if (err == DSERR_BUFFERLOST) {
DWORD flags = CALLBACK_FUNCTION;
if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
flags |= WAVE_DIRECTSOUND;
/* Wine-only: the driver wants us to reopen the device */
/* FIXME: check for errors */
IDsDriverBuffer_Release(This->hwbuf);
......@@ -220,7 +223,7 @@ HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This)
This->hwo = 0;
err = mmErr(waveOutOpen(&(This->hwo), This->drvdesc.dnDevNode,
&(This->wfx), (DWORD)DSOUND_callback, (DWORD)This,
CALLBACK_FUNCTION | WAVE_DIRECTSOUND));
flags));
if (err == DS_OK)
err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
DSBCAPS_PRIMARYBUFFER,0,
......@@ -323,13 +326,16 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
dsound->wfx.nSamplesPerSec * dsound->wfx.nBlockAlign;
if (dsound->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) {
DWORD flags = CALLBACK_FUNCTION;
if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
flags |= WAVE_DIRECTSOUND;
/* FIXME: check for errors */
DSOUND_PrimaryClose(dsound);
waveOutClose(dsound->hwo);
dsound->hwo = 0;
err = mmErr(waveOutOpen(&(dsound->hwo), dsound->drvdesc.dnDevNode,
&(dsound->wfx), (DWORD)DSOUND_callback, (DWORD)dsound,
CALLBACK_FUNCTION | WAVE_DIRECTSOUND));
flags));
if (err == DS_OK)
DSOUND_PrimaryOpen(dsound);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment