Commit 89b469fe authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Added support for multiple direct sound devices.

parent 2e24a148
......@@ -84,7 +84,7 @@ static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface) {
if (This->dsb)
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
else if (This->dscb)
IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb);
IDirectSoundCaptureBuffer8_Release((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
......@@ -543,6 +543,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
assert(audiobytes1!=audiobytes2);
assert(lplpaudioptr1!=lplpaudioptr2);
EnterCriticalSection(&(This->lock));
if ((writebytes == This->buflen) &&
((This->state == STATE_STARTING) ||
(This->state == STATE_PLAYING)))
......@@ -601,6 +603,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
}
}
}
LeaveCriticalSection(&(This->lock));
return DS_OK;
}
......
......@@ -20,8 +20,6 @@
*/
/*
* TODO:
* Fix Enumerate for multiple sound devices.
* Handle device GUIDs properly.
* Implement DirectSoundFullDuplex support.
* Implement FX support.
*/
......@@ -97,6 +95,7 @@ DirectSoundCaptureCreate8(
LPDIRECTSOUNDCAPTURE* lplpDSC,
LPUNKNOWN pUnkOuter )
{
IDirectSoundCaptureImpl** ippDSC=(IDirectSoundCaptureImpl**)lplpDSC;
TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), lplpDSC, pUnkOuter);
if ( pUnkOuter ) {
......@@ -110,43 +109,33 @@ DirectSoundCaptureCreate8(
}
/* Default device? */
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) ||
IsEqualGUID(lpcGUID, &DSDEVID_DefaultCapture) ||
IsEqualGUID(lpcGUID, &DSDEVID_DefaultVoiceCapture) ) {
IDirectSoundCaptureImpl** ippDSC=(IDirectSoundCaptureImpl**)lplpDSC;
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
lpcGUID = &DSDEVID_DefaultCapture;
*ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
*ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
if (*ippDSC == NULL) {
TRACE("couldn't allocate memory\n");
return DSERR_OUTOFMEMORY;
}
else
{
ICOM_THIS(IDirectSoundCaptureImpl, *ippDSC);
This->ref = 1;
This->state = STATE_STOPPED;
if (*ippDSC == NULL) {
TRACE("couldn't allocate memory\n");
return DSERR_OUTOFMEMORY;
}
else
{
ICOM_THIS(IDirectSoundCaptureImpl, *ippDSC);
if (lpcGUID)
This->guid = *lpcGUID;
else
This->guid = GUID_NULL;
This->ref = 1;
This->state = STATE_STOPPED;
InitializeCriticalSection( &(This->lock) );
InitializeCriticalSection( &(This->lock) );
ICOM_VTBL(This) = &dscvt;
dsound_capture = This;
ICOM_VTBL(This) = &dscvt;
dsound_capture = This;
return IDirectSoundCaptureImpl_Initialize( (LPDIRECTSOUNDCAPTURE)This, lpcGUID );
}
if (GetDeviceID(lpcGUID, &This->guid) == DS_OK)
return IDirectSoundCaptureImpl_Initialize( (LPDIRECTSOUNDCAPTURE)This, &This->guid);
}
FIXME( "Unknown GUID %s\n", debugstr_guid(lpcGUID) );
*lplpDSC = NULL;
return DSERR_OUTOFMEMORY;
WARN("invalid GUID\n");
return DSERR_INVALIDPARAM;
}
/***************************************************************************
......@@ -163,8 +152,10 @@ DirectSoundCaptureEnumerateA(
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
WAVEINCAPSA wcaps;
unsigned devs, wid;
DSDRIVERDESC desc;
GUID guid;
int err;
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
......@@ -174,15 +165,37 @@ DirectSoundCaptureEnumerateA(
}
devs = waveInGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
GUID temp;
for (wid = 0; wid < devs; ++wid) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
if (err == DS_OK) {
if (IsEqualGUID( &guid, &temp ) ) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, "Primary Sound Capture Driver", desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
}
for (wid = 0; wid < devs; ++wid) {
waveInGetDevCapsA(wid, &wcaps, sizeof(wcaps));
if (lpDSEnumCallback) {
TRACE("calling lpDSEnumCallback(%s,\"WINE DirectSound\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),wcaps.szPname,lpContext);
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, "WINE DirectSound",
wcaps.szPname ,lpContext);
return DS_OK;
}
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
if (lpDSEnumCallback(&guid, desc.szDesc, desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
return DS_OK;
......@@ -202,9 +215,12 @@ DirectSoundCaptureEnumerateW(
LPDSENUMCALLBACKW lpDSEnumCallback,
LPVOID lpContext)
{
WAVEINCAPSW wcaps;
unsigned devs, wid;
WCHAR desc[MAXPNAMELEN];
DSDRIVERDESC desc;
GUID guid;
int err;
WCHAR wDesc[MAXPNAMELEN];
WCHAR wName[MAXPNAMELEN];
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
......@@ -214,14 +230,45 @@ DirectSoundCaptureEnumerateW(
}
devs = waveInGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
GUID temp;
for (wid = 0; wid < devs; ++wid) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
if (err == DS_OK) {
if (IsEqualGUID( &guid, &temp ) ) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
}
for (wid = 0; wid < devs; ++wid) {
waveInGetDevCapsW(wid, &wcaps, sizeof(wcaps));
if (lpDSEnumCallback) {
MultiByteToWideChar( CP_ACP, 0, "WINE Sound Capture Driver", -1,
desc, sizeof(desc)/sizeof(WCHAR) );
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, desc, wcaps.szPname ,lpContext);
return DS_OK;
}
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),desc.szDesc,desc.szDrvName,lpContext);
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
}
return DS_OK;
......@@ -402,7 +449,7 @@ IDirectSoundCaptureImpl_Initialize(
LPDIRECTSOUNDCAPTURE iface,
LPCGUID lpcGUID )
{
HRESULT err = DS_OK;
HRESULT err = DSERR_INVALIDPARAM;
unsigned wid, widn;
ICOM_THIS(IDirectSoundCaptureImpl,iface);
TRACE("(%p)\n", This);
......@@ -427,8 +474,24 @@ IDirectSoundCaptureImpl_Initialize(
/* Get dsound configuration */
setup_dsound_options();
/* FIXME: should enumerate WINMM audio devices and find the one we want */
wid = 0;
/* enumerate WINMM audio devices and find the one we want */
for (wid=0; wid<widn; wid++) {
GUID guid;
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
if (err != DS_OK) {
WARN("waveInMessage failed; err=%lx\n",err);
return err;
}
if (IsEqualGUID( lpcGUID, &guid) ) {
err = DS_OK;
break;
}
}
if (err != DS_OK) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&(This->driver),0));
if ( (err != DS_OK) && (err != DSERR_UNSUPPORTED) ) {
......@@ -443,9 +506,6 @@ IDirectSoundCaptureImpl_Initialize(
/* Get driver description */
if (This->driver) {
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");
err = IDsCaptureDriver_GetDriverDesc(This->driver, &(This->drvdesc));
if (err != DS_OK) {
......@@ -484,11 +544,9 @@ IDirectSoundCaptureImpl_Initialize(
strncpy(This->drvdesc.szDrvName, wic.szPname,
sizeof(This->drvdesc.szDrvName));
This->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
This->drvcaps.dwFormats = wic.dwFormats;
This->drvcaps.dwChannels = wic.wChannels;
if (ds_emuldriver)
This->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
}
}
}
......@@ -656,7 +714,7 @@ IDirectSoundCaptureBufferImpl_QueryInterface(
return NO_ERROR;
}
FIXME("(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj);
FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
return E_FAIL;
}
......@@ -1226,7 +1284,7 @@ DirectSoundFullDuplexCreate8(
}
*ippDSFD = (IDirectSoundFullDuplexImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
if (*ippDSFD == NULL) {
TRACE("couldn't allocate memory\n");
......
......@@ -6,7 +6,7 @@
6 stdcall DirectSoundCaptureCreate(ptr ptr ptr) DirectSoundCaptureCreate8
7 stdcall DirectSoundCaptureEnumerateA(ptr ptr) DirectSoundCaptureEnumerateA
8 stdcall DirectSoundCaptureEnumerateW(ptr ptr) DirectSoundCaptureEnumerateW
9 stub GetDeviceID
9 stdcall GetDeviceID(ptr ptr) GetDeviceID
10 stub DirectSoundFullDuplexCreate
11 stdcall DirectSoundCreate8(ptr ptr ptr) DirectSoundCreate8
12 stdcall DirectSoundCaptureCreate8(ptr ptr ptr) DirectSoundCaptureCreate8
......@@ -116,23 +116,8 @@ 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.
*/
inline static void enumerate_devices(LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
if (lpDSEnumCallback != NULL) {
TRACE("calling lpDSEnumCallback(%s,\"WINE DirectSound\",\"sound\",%p)\n",
debugstr_guid(&DSDEVID_DefaultPlayback),lpContext);
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback,
"WINE DirectSound", "sound", lpContext);
}
}
int ds_default_playback = 0;
int ds_default_capture = 0;
/*
* Get a config key from either the app-specific or the default config
......@@ -211,6 +196,12 @@ void setup_dsound_options(void)
ds_hw_accel = DS_HW_ACCEL_EMULATION;
}
if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
ds_default_playback = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
ds_default_capture = atoi(buffer);
if (appkey) RegCloseKey( appkey );
RegCloseKey( hkey );
......@@ -231,11 +222,57 @@ void setup_dsound_options(void)
ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
"Unknown");
if (ds_default_playback != 0)
WARN("ds_default_playback = %d (default=0)\n",ds_default_playback);
if (ds_default_capture != 0)
WARN("ds_default_capture = %d (default=0)\n",ds_default_playback);
}
/***************************************************************************
* GetDeviceId [DSOUND.2]
*
* Retrieves unique identifier of default device specified
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_INVALIDPARAM
*/
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
{
if ( ( pGuidSrc == NULL) || (pGuidDest == NULL) ) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
GUID guid;
int err = mmErr(waveOutMessage((HWAVEOUT)ds_default_playback,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
memcpy(pGuidDest, &guid, sizeof(GUID));
return DS_OK;
}
}
if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
GUID guid;
int err = mmErr(waveInMessage((HWAVEIN)ds_default_capture,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
memcpy(pGuidDest, &guid, sizeof(GUID));
return DS_OK;
}
}
memcpy(pGuidDest, pGuidSrc, sizeof(GUID));
return DS_OK;
}
/***************************************************************************
* DirectSoundEnumerateA [DSOUND.2]
*
* Enumerate all DirectSound drivers installed in the system
......@@ -245,25 +282,56 @@ void setup_dsound_options(void)
* Failure: DSERR_INVALIDPARAM
*/
HRESULT WINAPI DirectSoundEnumerateA(
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
WAVEOUTCAPSA wcaps;
unsigned devs, wod;
TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
lpDSEnumCallback, lpContext);
devs = waveOutGetNumDevs();
for (wod = 0; wod < devs; ++wod) {
waveOutGetDevCapsA(wod, &wcaps, sizeof(wcaps));
if (wcaps.dwSupport & WAVECAPS_DIRECTSOUND) {
TRACE("- Device %u supports DirectSound\n", wod);
enumerate_devices(lpDSEnumCallback, lpContext);
return DS_OK;
}
}
return DS_OK;
unsigned devs, wod;
DSDRIVERDESC desc;
GUID guid;
int err;
TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
lpDSEnumCallback, lpContext);
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
devs = waveOutGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
GUID temp;
for (wod = 0; wod < devs; ++wod) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
if (err == DS_OK) {
if (IsEqualGUID( &guid, &temp ) ) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultPlayback),"Primary Sound Driver",desc.szDrvName,lpContext);
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback, "Primary Sound Driver", desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
}
for (wod = 0; wod < devs; ++wod) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
if (lpDSEnumCallback(&guid, desc.szDesc, desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
return DS_OK;
}
/***************************************************************************
......@@ -588,36 +656,62 @@ static ICOM_VTABLE(IDirectSound8) dsvt =
/*******************************************************************************
* DirectSoundCreate (DSOUND.1)
*/
HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
{
IDirectSoundImpl** ippDS=(IDirectSoundImpl**)ppDS;
PIDSDRIVER drv = NULL;
unsigned wod, wodn;
HRESULT err = DS_OK;
if (lpGUID)
TRACE("(%p,%p,%p)\n",lpGUID,ippDS,pUnkOuter);
else
TRACE("DirectSoundCreate (%p)\n", ippDS);
HRESULT err = DSERR_INVALIDPARAM;
GUID devGuid;
TRACE("(%p,%p,%p)\n",lpcGUID,ippDS,pUnkOuter);
if (ippDS == NULL)
return DSERR_INVALIDPARAM;
if (dsound) {
IDirectSound_AddRef((LPDIRECTSOUND)dsound);
*ippDS = dsound;
return DS_OK;
}
/* Get dsound configuration */
setup_dsound_options();
/* Default device? */
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
lpcGUID = &DSDEVID_DefaultPlayback;
if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
if (dsound && IsEqualGUID(&devGuid, &dsound->guid) ) {
ERR("dsound already opened\n");
if (IsEqualGUID(&devGuid, &dsound->guid) ) {
IDirectSound_AddRef((LPDIRECTSOUND)dsound);
*ippDS = dsound;
return DS_OK;
} else {
ERR("different dsound already opened\n");
}
}
/* Enumerate WINMM audio devices and find the one we want */
wodn = waveOutGetNumDevs();
if (!wodn) return DSERR_NODRIVER;
/* FIXME: How do we find the GUID of an audio device? */
wod = 0; /* start at the first audio device */
for (wod=0; wod<wodn; wod++) {
GUID guid;
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
if (err != DS_OK) {
WARN("waveOutMessage failed; err=%lx\n",err);
return err;
}
if (IsEqualGUID( &devGuid, &guid) ) {
err = DS_OK;
break;
}
}
if (err != DS_OK) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
/* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
......@@ -648,6 +742,7 @@ HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *
(*ippDS)->listener = NULL;
(*ippDS)->prebuf = ds_snd_queue_max;
(*ippDS)->guid = devGuid;
/* Get driver description */
if (drv) {
......
......@@ -38,6 +38,8 @@ extern int ds_hel_queue;
extern int ds_snd_queue_max;
extern int ds_snd_queue_min;
extern int ds_hw_accel;
extern int ds_default_playback;
extern int ds_default_capture;
/*****************************************************************************
* Predeclare the interface implementation structures
......@@ -62,6 +64,7 @@ struct IDirectSoundImpl
ICOM_VFIELD(IDirectSound8);
DWORD ref;
/* IDirectSoundImpl fields */
GUID guid;
PIDSDRIVER driver;
DSDRIVERDESC drvdesc;
DSDRIVERCAPS drvcaps;
......
......@@ -983,7 +983,9 @@ void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWOR
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
IDirectSoundImpl* This = (IDirectSoundImpl*)dwUser;
TRACE("entering at %ld, msg=%08x\n", GetTickCount(), msg);
TRACE("entering at %ld, msg=%08x(%s)\n", GetTickCount(), msg,
msg==MM_WOM_DONE ? "MM_WOM_DONE" : msg==MM_WOM_CLOSE ? "MM_WOM_CLOSE" :
msg==MM_WOM_OPEN ? "MM_WOM_OPEN" : "UNKNOWN");
if (msg == MM_WOM_DONE) {
DWORD inq, mixq, fraglen, buflen, pwplay, playpos, mixpos;
if (This->pwqueue == (DWORD)-1) {
......
......@@ -184,7 +184,8 @@ HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This)
{
DSOUND_PrimaryClose(This);
if (This->hwbuf) {
IDsDriverBuffer_Release(This->hwbuf);
if (IDsDriverBuffer_Release(This->hwbuf) == 0)
This->hwbuf = 0;
} else {
unsigned c;
for (c=0; c<DS_HEL_FRAGS; c++) {
......
......@@ -488,6 +488,12 @@ UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
case DRV_QUERYDSOUNDDESC: /* Wine-specific: Retrieve DirectSound driver description*/
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
case DRV_QUERYDSOUNDGUID: /* Wine-specific: Retrieve DirectSound driver GUID */
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
default:
WARN("Unknown call %04x\n", uMsg);
return MMSYSERR_INVALPARAM;
......
......@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = winealsa.drv
IMPORTS = winmm user32 kernel32 ntdll
EXTRALIBS = @ALSALIBS@
EXTRALIBS = $(LIBUUID) @ALSALIBS@
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
......
......@@ -149,13 +149,16 @@ typedef struct {
ALSA_MSG_RING msgRing;
/* DirectSound stuff */
DSDRIVERDESC ds_desc;
GUID ds_guid;
} WINE_WAVEOUT;
static WINE_WAVEOUT WOutDev [MAX_WAVEOUTDRV];
static DWORD ALSA_WodNumDevs;
static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc);
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid);
/* These strings used only for tracing */
#if 0
......@@ -412,6 +415,9 @@ LONG ALSA_WaveInit(void)
wwo->caps.vDriverVersion = 0x0100;
wwo->caps.dwFormats = 0x00000000;
wwo->caps.dwSupport = WAVECAPS_VOLUME;
strcpy(wwo->ds_desc.szDesc, "WineALSA DirectSound Driver");
strcpy(wwo->ds_desc.szDrvName, "winealsa.drv");
wwo->ds_guid = DSDEVID_DefaultPlayback;
if (!wine_dlopen("libasound.so.2", RTLD_LAZY|RTLD_GLOBAL, NULL, 0))
{
......@@ -1572,7 +1578,10 @@ DWORD WINAPI ALSA_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
case WODM_SETVOLUME: return wodSetVolume (wDevID, dwParam1);
case WODM_RESTART: return wodRestart (wDevID);
case WODM_RESET: return wodReset (wDevID);
case DRV_QUERYDSOUNDIFACE: return wodDsCreate(wDevID, (PIDSDRIVER*)dwParam1);
case DRV_QUERYDSOUNDIFACE: return wodDsCreate (wDevID, (PIDSDRIVER*)dwParam1);
case DRV_QUERYDSOUNDDESC: return wodDsDesc (wDevID, (PDSDRIVERDESC)dwParam1);
case DRV_QUERYDSOUNDGUID: return wodDsGuid (wDevID, (LPGUID)dwParam1);
default:
FIXME("unknown message %d!\n", wMsg);
}
......@@ -1947,10 +1956,9 @@ static HRESULT WINAPI IDsDriverImpl_GetDriverDesc(PIDSDRIVER iface, PDSDRIVERDES
{
ICOM_THIS(IDsDriverImpl,iface);
TRACE("(%p,%p)\n",iface,pDesc);
memcpy(pDesc, &(WOutDev[This->wDevID].ds_desc), sizeof(DSDRIVERDESC));
pDesc->dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
DSDDESC_USESYSTEMMEMORY;
strcpy(pDesc->szDesc, "WineALSA DirectSound Driver");
strcpy(pDesc->szDrvName, "winealsa.drv");
pDesc->dnDevNode = WOutDev[This->wDevID].waveDesc.dnDevNode;
pDesc->wVxdId = 0;
pDesc->wReserved = 0;
......@@ -2094,6 +2102,22 @@ static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
(*idrv)->primary = NULL;
return MMSYSERR_NOERROR;
}
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
memcpy(desc, &(WOutDev[wDevID].ds_desc), sizeof(DSDRIVERDESC));
return MMSYSERR_NOERROR;
}
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid)
{
TRACE("(%d,%p)\n",wDevID,pGuid);
memcpy(pGuid, &(WOutDev[wDevID].ds_guid), sizeof(GUID));
return MMSYSERR_NOERROR;
}
#endif
#ifndef HAVE_ALSA
......
......@@ -267,6 +267,16 @@ WINE REGISTRY Version 2
;"SndQueueMax" = "28"
;; Min number of fragments to prebuffer
;"SndQueueMin" = "12"
;; Forces emulation mode (using wave api)
;"HardwareAcceleration" = "Emulation"
;; Sets default playback device (0 - number of devices - 1)
;"DefaultPlayback" = "0" ; use first device (/dev/dsp)
;"DefaultPlayback" = "1" ; use second device (/dev/dsp1)
;"DefaultPlayback" = "2" ; use third device (/dev/dsp2)
;; Sets default capture device (0 - number of devices - 1)
;"DefaultCapture" = "0" ; use first device (/dev/dsp)
;"DefaultCapture" = "1" ; use second device (/dev/dsp1)
;"DefaultCapture" = "2" ; use third device (/dev/dsp2)
[Network]
;; Use the DNS (Unix) host name always as NetBIOS "ComputerName" (boolean, default "Y").
......
......@@ -81,6 +81,8 @@ typedef struct {
#define DRV_QUERYMAPPABLE (DRV_RESERVED + 5)
#ifdef __WINESRC__
#define DRV_QUERYDSOUNDIFACE (DRV_RESERVED + 10)
#define DRV_QUERYDSOUNDDESC (DRV_RESERVED + 11)
#define DRV_QUERYDSOUNDGUID (DRV_RESERVED + 12)
#endif
#define WODM_INIT DRVM_INIT
......
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