Commit 725d8c39 authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

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.
parent b4557d01
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
}
......
......@@ -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");
......
......@@ -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(
......
......@@ -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)
......
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