From 725d8c39aaa5c4665373efebeee90dfe2e609aab Mon Sep 17 00:00:00 2001 From: Robert Reif <reif@earthlink.net> Date: Mon, 15 Sep 2003 20:08:05 +0000 Subject: [PATCH] Device enumeration callbacks should return a NULL guid for default devices. Fixed some volume and pan cases. Added missing property set. Fixed capture notification bug. --- dlls/dsound/buffer.c | 16 +++-- dlls/dsound/capture.c | 6 +- dlls/dsound/dsound_main.c | 4 +- dlls/dsound/primary.c | 55 +++++++++++++++-- dlls/dsound/propset.c | 118 ++++++++++++++++++++++++++++++++++++- dlls/winmm/wineoss/audio.c | 3 +- 6 files changed, 186 insertions(+), 16 deletions(-) diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 486bd0f763f..f248228ffd4 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -235,15 +235,18 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume( ICOM_THIS(IDirectSoundBufferImpl,iface); TRACE("(%p,%p)\n",This,vol); + if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) { + WARN("control unavailable\n"); + return DSERR_CONTROLUNAVAIL; + } + if (vol == NULL) { WARN("invalid parameter: vol == NULL\n"); return DSERR_INVALIDPARAM; } - if (This->dsbd.dwFlags & DSBCAPS_CTRL3D) - *vol = This->ds3db_lVolume; - else - *vol = This->volpan.lVolume; + *vol = This->volpan.lVolume; + return DS_OK; } @@ -759,6 +762,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetPan( ICOM_THIS(IDirectSoundBufferImpl,iface); TRACE("(%p,%p)\n",This,pan); + if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) { + WARN("control unavailable\n"); + return DSERR_CONTROLUNAVAIL; + } + if (pan == NULL) { WARN("invalid parameter: pan = NULL\n"); return DSERR_INVALIDPARAM; diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index e13b388c161..43f990dad2e 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -197,7 +197,7 @@ DirectSoundCaptureEnumerateA( 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) + if (lpDSEnumCallback(NULL, "Primary Sound Capture Driver", desc.szDrvName, lpContext) == FALSE) return DS_OK; } } @@ -270,7 +270,7 @@ DirectSoundCaptureEnumerateW( 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) + if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) return DS_OK; } } @@ -325,10 +325,10 @@ DSOUND_capture_callback( This->read_position = mtime.u.cb; This->state = STATE_CAPTURING; } - This->index = (This->index + 1) % This->nrofpwaves; waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR)); if (This->capture_buffer->nrofnotifies) SetEvent(This->capture_buffer->notifies[This->index].hEventNotify); + This->index = (This->index + 1) % This->nrofpwaves; if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) { TRACE("end of buffer\n"); This->state = STATE_STOPPED; diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c index 144557259e8..a312b549c49 100644 --- a/dlls/dsound/dsound_main.c +++ b/dlls/dsound/dsound_main.c @@ -336,7 +336,7 @@ HRESULT WINAPI DirectSoundEnumerateA( 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) + if (lpDSEnumCallback(NULL, "Primary Sound Driver", desc.szDrvName, lpContext) == FALSE) return DS_OK; } } @@ -408,7 +408,7 @@ HRESULT WINAPI DirectSoundEnumerateW( wDesc, sizeof(wDesc)/sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wName, sizeof(wName)/sizeof(WCHAR) ); - if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback, wDesc, wName, lpContext) == FALSE) + if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE) return DS_OK; } } diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index b58615b3ac8..42b76fb4bc5 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -745,11 +745,53 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan( LPDIRECTSOUNDBUFFER8 iface,LONG pan ) { ICOM_THIS(PrimaryBufferImpl,iface); + IDirectSoundImpl* dsound = This->dsound; + LONG oldPan; + TRACE("(%p,%ld)\n",This,pan); - /* You cannot set the pan of the primary buffer */ - WARN("control unavailable\n"); - return DSERR_CONTROLUNAVAIL; + if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLPAN)) { + WARN("control unavailable\n"); + return DSERR_CONTROLUNAVAIL; + } + + if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) { + WARN("invalid parameter: pan = %ld\n", pan); + return DSERR_INVALIDPARAM; + } + + /* **** */ + EnterCriticalSection(&(dsound->mixlock)); + + oldPan = dsound->volpan.lPan; + dsound->volpan.lPan = pan; + DSOUND_RecalcVolPan(&dsound->volpan); + + if (pan != oldPan) { + if (dsound->hwbuf) { + HRESULT hres; + hres = IDsDriverBuffer_SetVolumePan(dsound->hwbuf, &(dsound->volpan)); + if (hres != DS_OK) { + LeaveCriticalSection(&(dsound->mixlock)); + WARN("IDsDriverBuffer_SetVolumePan failed\n"); + return hres; + } + } + else { +#if 0 /* should we really do this? */ + /* the DS volume ranges from 0 (max, 0dB attenuation) to -10000 (min, 100dB attenuation) */ + /* the MM volume ranges from 0 to 0xffff in an unspecified logarithmic scale */ + WORD cvol = 0xffff + vol*6 + vol/2; + DWORD vol = cvol | ((DWORD)cvol << 16) + waveOutSetVolume(dsound->hwo, vol); +#endif + } + } + + LeaveCriticalSection(&(dsound->mixlock)); + /* **** */ + + return DS_OK; } static HRESULT WINAPI PrimaryBufferImpl_GetPan( @@ -758,6 +800,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan( ICOM_THIS(PrimaryBufferImpl,iface); TRACE("(%p,%p)\n",This,pan); + if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLPAN)) { + WARN("control unavailable\n"); + return DSERR_CONTROLUNAVAIL; + } + if (pan == NULL) { WARN("invalid parameter: pan == NULL\n"); return DSERR_INVALIDPARAM; @@ -774,7 +821,7 @@ static HRESULT WINAPI PrimaryBufferImpl_Unlock( ICOM_THIS(PrimaryBufferImpl,iface); IDirectSoundImpl* dsound = This->dsound; - TRACE("(%p,%p,%ld,%p,%ld):stub\n", This,p1,x1,p2,x2); + TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2); if (dsound->priolevel != DSSCL_WRITEPRIMARY) { WARN("failed priority check!\n"); diff --git a/dlls/dsound/propset.c b/dlls/dsound/propset.c index 6d72cc20f2e..eeb628ed6fd 100644 --- a/dlls/dsound/propset.c +++ b/dlls/dsound/propset.c @@ -449,9 +449,123 @@ static HRESULT WINAPI DSPROPERTY_DescriptionA( ULONG cbPropData, PULONG pcbReturned ) { - FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n", + PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData; + HRESULT err; + GUID guid, dev_guid; + TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n", debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned); - return E_PROP_ID_UNSUPPORTED; + + TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId)); + if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) { + /* default device of type specified by ppd->DataFlow */ + if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) { + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); + } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) { + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); + } else { + TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow); + } + FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n", + debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned); + return E_PROP_ID_UNSUPPORTED; + } + + ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; + GetDeviceID(&ppd->DeviceId, &dev_guid); + + if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) || + IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) { + ULONG wod; + int wodn; + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n"); + ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER; + wodn = waveOutGetNumDevs(); + for (wod = 0; wod < wodn; wod++) { + err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0)); + if (err == DS_OK) { + if (IsEqualGUID( &dev_guid, &guid) ) { + DSDRIVERDESC desc; + ppd->WaveDeviceId = wod; + err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0)); + if (err == DS_OK) { + PIDSDRIVER drv = NULL; + /* FIXME: this is a memory leak */ + CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1); + CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1); + CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1); + + strcpy(szDescription, desc.szDesc); + strcpy(szModule, desc.szDrvName); + strcpy(szInterface, "Interface"); + + ppd->Description = szDescription; + ppd->Module = szModule; + ppd->Interface = szInterface; + err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0)); + if (err == DS_OK && drv) + ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; + break; + } else { + WARN("waveOutMessage failed\n"); + return E_PROP_ID_UNSUPPORTED; + } + } + } else { + WARN("waveOutMessage failed\n"); + return E_PROP_ID_UNSUPPORTED; + } + } + } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) || + IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) { + ULONG wid; + int widn; + TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n"); + ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE; + widn = waveInGetNumDevs(); + for (wid = 0; wid < widn; wid++) { + err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0)); + if (err == DS_OK) { + if (IsEqualGUID( &dev_guid, &guid) ) { + DSDRIVERDESC desc; + ppd->WaveDeviceId = wid; + err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0)); + if (err == DS_OK) { + PIDSCDRIVER drv; + /* FIXME: this is a memory leak */ + CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1); + CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1); + CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1); + + strcpy(szDescription, desc.szDesc); + strcpy(szModule, desc.szDrvName); + strcpy(szInterface, "Interface"); + + ppd->Description = szDescription; + ppd->Module = szModule; + ppd->Interface = szInterface; + err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0)); + if (err == DS_OK && drv) + ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD; + break; + } else { + WARN("waveInMessage failed\n"); + return E_PROP_ID_UNSUPPORTED; + } + break; + } + } else { + WARN("waveOutMessage failed\n"); + return E_PROP_ID_UNSUPPORTED; + } + } + } + + if (pcbReturned) { + *pcbReturned = cbPropData; + TRACE("*pcbReturned=%ld\n", *pcbReturned); + } + + return S_OK; } static HRESULT WINAPI DSPROPERTY_DescriptionW( diff --git a/dlls/winmm/wineoss/audio.c b/dlls/winmm/wineoss/audio.c index fb56fab6a31..83cd00db07a 100644 --- a/dlls/winmm/wineoss/audio.c +++ b/dlls/winmm/wineoss/audio.c @@ -2140,7 +2140,8 @@ static HRESULT WINAPI IDsDriverBufferImpl_SetVolumePan(PIDSDRIVERBUFFER iface, P { /* ICOM_THIS(IDsDriverBufferImpl,iface); */ FIXME("(%p,%p): stub!\n",iface,pVolPan); - return DSERR_UNSUPPORTED; + /* FIXME: the dsound software mixer does this for us so don't return an error */ + return DS_OK; } static HRESULT WINAPI IDsDriverBufferImpl_SetPosition(PIDSDRIVERBUFFER iface, DWORD dwNewPos) -- GitLab