Reversed relationship between buffers and notifies.

Fixed notify reuse bug.
Minor documentation and error message cleanup.
This commit is contained in:
Robert Reif 2003-05-02 20:16:48 +00:00 committed by Alexandre Julliard
parent bcfff87be5
commit abde7d0acf
6 changed files with 194 additions and 90 deletions

View File

@ -54,13 +54,21 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(
LPDIRECTSOUNDNOTIFY iface,REFIID riid,LPVOID *ppobj
) {
ICOM_THIS(IDirectSoundNotifyImpl,iface);
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
if (This->dsb)
return IDirectSoundBuffer8_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
else if (This->dscb)
return IDirectSoundCaptureBuffer8_QueryInterface((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb, riid, ppobj);
return DSERR_GENERIC;
if ( IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IDirectSoundNotify) ||
IsEqualGUID(riid, &IID_IDirectSoundNotify8) ) {
IDirectSoundNotify_AddRef(iface);
*ppobj = This;
return DS_OK;
}
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
*ppobj = 0;
return E_NOINTERFACE;
}
static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface) {
@ -80,11 +88,12 @@ static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface) {
TRACE("(%p) ref was %ld\n", This, This->ref);
ref = InterlockedDecrement(&(This->ref));
if (!ref) {
if (This->dsb)
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
else if (This->dscb)
IDirectSoundCaptureBuffer8_Release((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb);
/* FIXME: A notification should be a part of a buffer rather than pointed
* to from a buffer. Hence the -1 ref count */
if (ref == -1) {
if (This->notifies != NULL)
HeapFree(GetProcessHeap(), 0, This->notifies);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
@ -95,33 +104,31 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(
LPDIRECTSOUNDNOTIFY iface,DWORD howmuch,LPCDSBPOSITIONNOTIFY notify
) {
ICOM_THIS(IDirectSoundNotifyImpl,iface);
int i;
TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);
if (!notify) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
if (TRACE_ON(dsound)) {
TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);
int i;
for (i=0;i<howmuch;i++)
TRACE("notify at %ld to 0x%08lx\n",
notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
TRACE("notify at %ld to 0x%08lx\n",
notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
}
if (This->dsb) {
This->dsb->notifies = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->dsb->notifies,(This->dsb->nrofnotifies+howmuch)*sizeof(DSBPOSITIONNOTIFY));
memcpy( This->dsb->notifies+This->dsb->nrofnotifies,
notify,
howmuch*sizeof(DSBPOSITIONNOTIFY)
);
This->dsb->nrofnotifies+=howmuch;
} else if (This->dscb) {
TRACE("notifies = %p, nrofnotifies = %d\n", This->dscb->notifies, This->dscb->nrofnotifies);
This->dscb->notifies = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->dscb->notifies,(This->dscb->nrofnotifies+howmuch)*sizeof(DSBPOSITIONNOTIFY));
memcpy( This->dscb->notifies+This->dscb->nrofnotifies,
notify,
howmuch*sizeof(DSBPOSITIONNOTIFY)
);
This->dscb->nrofnotifies+=howmuch;
TRACE("notifies = %p, nrofnotifies = %d\n", This->dscb->notifies, This->dscb->nrofnotifies);
if (This->hwnotify) {
return IDsDriverNotify_SetNotificationPositions(This->hwnotify, howmuch, notify);
}
else {
/* Make an internal copy of the caller-supplied array.
* Replace the existing copy if one is already present. */
This->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
This->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
memcpy(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
This->nrofnotifies = howmuch;
}
else
return DSERR_INVALIDPARAM;
return S_OK;
}
@ -816,17 +823,23 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
IDirectSoundNotifyImpl *dsn;
dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*dsn));
dsn->ref = 1;
dsn->dsb = This;
dsn->dscb = 0;
IDirectSoundBuffer8_AddRef(iface);
dsn->lpVtbl = &dsnvt;
*ppobj = (LPVOID)dsn;
return S_OK;
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ||
IsEqualGUID( &IID_IDirectSoundNotify8, riid ) ) {
if (!This->notify) {
This->notify = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,sizeof(*This->notify));
if (This->notify) {
This->notify->ref = 0; /* release when ref == -1 */
This->notify->lpVtbl = &dsnvt;
}
}
if (This->notify) {
IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
*ppobj = (LPVOID)This->notify;
return S_OK;
}
*ppobj = NULL;
return E_FAIL;
}
if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
@ -837,6 +850,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)*ppobj);
return S_OK;
}
*ppobj = NULL;
return E_FAIL;
}
@ -854,6 +868,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
IKsPropertySet_AddRef((LPKSPROPERTYSET)*ppobj);
return S_OK;
}
*ppobj = NULL;
return E_FAIL;
}

View File

@ -82,12 +82,24 @@ IDirectSoundCaptureImpl* dsound_capture = NULL;
/***************************************************************************
* DirectSoundCaptureCreate [DSOUND.6]
*
* Create and initialize a DirectSoundCapture interface
* Create and initialize a DirectSoundCapture interface.
*
* PARAMS
* lpcGUID [I] Address of the GUID that identifies the sound capture device.
* lplpDSC [O] Address of a variable to receive the interface pointer.
* pUnkOuter [I] Must be NULL.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
* DSERR_OUTOFMEMORY
*
* NOTES
* lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
* or NULL for the default device or DSDEVID_DefaultCapture or
* DSDEVID_DefaultVoiceCapture.
*
* DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
*/
HRESULT WINAPI
DirectSoundCaptureCreate8(
@ -99,7 +111,7 @@ DirectSoundCaptureCreate8(
TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), lplpDSC, pUnkOuter);
if ( pUnkOuter ) {
WARN("pUnkOuter != 0\n");
WARN("invalid parameter: pUnkOuter != NULL\n");
return DSERR_NOAGGREGATION;
}
@ -141,7 +153,11 @@ DirectSoundCaptureCreate8(
/***************************************************************************
* DirectSoundCaptureEnumerateA [DSOUND.7]
*
* Enumerate all DirectSound drivers installed in the system
* Enumerate all DirectSound drivers installed in the system.
*
* PARAMS
* lpDSEnumCallback [I] Address of callback function.
* lpContext [I] Address of user defined context passed to callback function.
*
* RETURNS
* Success: DS_OK
@ -160,7 +176,7 @@ DirectSoundCaptureEnumerateA(
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter\n");
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
}
@ -204,7 +220,11 @@ DirectSoundCaptureEnumerateA(
/***************************************************************************
* DirectSoundCaptureEnumerateW [DSOUND.8]
*
* Enumerate all DirectSound drivers installed in the system
* Enumerate all DirectSound drivers installed in the system.
*
* PARAMS
* lpDSEnumCallback [I] Address of callback function.
* lpContext [I] Address of user defined context passed to callback function.
*
* RETURNS
* Success: DS_OK
@ -225,7 +245,7 @@ DirectSoundCaptureEnumerateW(
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter\n");
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
}
@ -283,7 +303,9 @@ DSOUND_capture_callback(
DWORD dw2 )
{
IDirectSoundCaptureImpl* This = (IDirectSoundCaptureImpl*)dwUser;
TRACE("entering at %ld, msg=%08x\n", GetTickCount(), msg);
TRACE("(%p,%08x(%s),%08lx,%08lx,%08lx) entering at %ld\n",hwi,msg,
msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" :
msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount());
if (msg == MM_WIM_DATA) {
EnterCriticalSection( &(This->lock) );
@ -300,8 +322,8 @@ DSOUND_capture_callback(
}
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);
if (This->capture_buffer->notify && This->capture_buffer->notify->nrofnotifies)
SetEvent(This->capture_buffer->notify->notifies[This->index].hEventNotify);
if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
TRACE("end of buffer\n");
This->state = STATE_STOPPED;
@ -698,22 +720,40 @@ IDirectSoundCaptureBufferImpl_QueryInterface(
ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
if (IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
IDirectSoundNotifyImpl *dsn;
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ||
IsEqualGUID( &IID_IDirectSoundNotify8, riid ) ) {
if (!This->notify) {
This->notify = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(*This->notify));
if (This->notify) {
This->notify->ref = 0; /* release when ref = -1 */
This->notify->lpVtbl = &dsnvt;
}
}
if (This->notify) {
if (This->dsound->hwbuf) {
HRESULT err;
err = IDsCaptureDriverBuffer_QueryInterface(This->dsound->hwbuf,
&IID_IDsDriverNotify, (LPVOID*)&(This->notify->hwnotify));
if (err != DS_OK) {
WARN("IDsCaptureDriverBuffer_QueryInterface failed\n");
*ppobj = 0;
return err;
}
}
dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),0,
sizeof(*dsn));
dsn->ref = 1;
dsn->dsb = 0;
dsn->dscb = This;
/* FIXME: get this right someday */
IDirectSoundCaptureBuffer8_AddRef(iface);
dsn->lpVtbl = &dsnvt;
*ppobj = (LPVOID)dsn;
return DS_OK;
IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
*ppobj = (LPVOID)This->notify;
return DS_OK;
}
*ppobj = 0;
return E_FAIL;
}
if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) {
if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer, riid ) ||
IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) {
IDirectSoundCaptureBuffer8_AddRef(iface);
*ppobj = This;
return NO_ERROR;
@ -721,7 +761,9 @@ IDirectSoundCaptureBufferImpl_QueryInterface(
FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
return E_FAIL;
*ppobj = 0;
return E_NOINTERFACE;
}
static ULONG WINAPI
@ -783,8 +825,8 @@ IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
else
ERR("does not reference dsound\n");
if (This->notifies)
HeapFree(GetProcessHeap(),0, This->notifies);
if (This->notify)
IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
HeapFree( GetProcessHeap(), 0, This );
}
@ -1042,10 +1084,10 @@ IDirectSoundCaptureBufferImpl_Start(
IDirectSoundCaptureImpl* ipDSC = This->dsound;
if (ipDSC->buffer) {
if (This->nrofnotifies) {
if (This->notify && This->notify->nrofnotifies) {
unsigned c;
ipDSC->nrofpwaves = This->nrofnotifies;
ipDSC->nrofpwaves = This->notify->nrofnotifies;
/* prepare headers */
ipDSC->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->pwave,
@ -1055,13 +1097,13 @@ IDirectSoundCaptureBufferImpl_Start(
if (c == 0) {
ipDSC->pwave[0].lpData = ipDSC->buffer;
ipDSC->pwave[0].dwBufferLength =
This->notifies[0].dwOffset + 1;
This->notify->notifies[0].dwOffset + 1;
} else {
ipDSC->pwave[c].lpData = ipDSC->buffer +
This->notifies[c-1].dwOffset + 1;
This->notify->notifies[c-1].dwOffset + 1;
ipDSC->pwave[c].dwBufferLength =
This->notifies[c].dwOffset -
This->notifies[c-1].dwOffset;
This->notify->notifies[c].dwOffset -
This->notify->notifies[c-1].dwOffset;
}
ipDSC->pwave[c].dwUser = (DWORD)ipDSC;
ipDSC->pwave[c].dwFlags = 0;
@ -1256,9 +1298,21 @@ static ICOM_VTABLE(IDirectSoundCaptureBuffer8) dscbvt =
};
/***************************************************************************
* DirectSoundFullDuplexCreate8 [DSOUND.8]
* DirectSoundFullDuplexCreate8 [DSOUND.10]
*
* Create and initialize a DirectSoundFullDuplex interface
* Create and initialize a DirectSoundFullDuplex interface.
*
* PARAMS
* pcGuidCaptureDevice [I] Address of sound capture device GUID.
* pcGuidRenderDevice [I] Address of sound render device GUID.
* pcDSCBufferDesc [I] Address of capture buffer description.
* pcDSBufferDesc [I] Address of render buffer description.
* hWnd [I] Handle to application window.
* dwLevel [I] Cooperative level.
* ppDSFD [O] Address where full duplex interface returned.
* ppDSCBuffer8 [0] Address where capture buffer interface returned.
* ppDSBuffer8 [0] Address where render buffer interface returned.
* pUnkOuter [I] Must be NULL.
*
* RETURNS
* Success: DS_OK

View File

@ -231,13 +231,24 @@ void setup_dsound_options(void)
/***************************************************************************
* GetDeviceId [DSOUND.2]
* GetDeviceID [DSOUND.9]
*
* Retrieves unique identifier of default device specified
*
* PARAMS
* pGuidSrc [I] Address of device GUID.
* pGuidDest [O] Address to receive unique device GUID.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_INVALIDPARAM
*
* NOTES
* pGuidSrc is a valid device GUID or DSDEVID_DefaultPlayback,
* DSDEVID_DefaultCapture, DSDEVID_DefaultVoicePlayback, or
* DSDEVID_DefaultVoiceCapture.
* Returns pGuidSrc if pGuidSrc is a valid device or the device
* GUID for the specified constants.
*/
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
{
@ -277,6 +288,10 @@ HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
*
* Enumerate all DirectSound drivers installed in the system
*
* PARAMS
* lpDSEnumCallback [I] Address of callback function.
* lpContext [I] Address of user defined context passed to callback function.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_INVALIDPARAM
@ -294,7 +309,7 @@ HRESULT WINAPI DirectSoundEnumerateA(
lpDSEnumCallback, lpContext);
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter\n");
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
}
@ -339,6 +354,10 @@ HRESULT WINAPI DirectSoundEnumerateA(
*
* Enumerate all DirectSound drivers installed in the system
*
* PARAMS
* lpDSEnumCallback [I] Address of callback function.
* lpContext [I] Address of user defined context passed to callback function.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_INVALIDPARAM
@ -358,7 +377,7 @@ HRESULT WINAPI DirectSoundEnumerateW(
lpDSEnumCallback, lpContext);
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter\n");
WARN("invalid parameter: lpDSEnumCallback == NULL\n");
return DSERR_INVALIDPARAM;
}
@ -708,6 +727,18 @@ static ICOM_VTABLE(IDirectSound8) dsvt =
/*******************************************************************************
* DirectSoundCreate (DSOUND.1)
*
* Creates and initializes a DirectSound interface.
*
* PARAMS
* lpcGUID [I] Address of the GUID that identifies the sound device.
* ppDS [O] Address of a variable to receive the interface pointer.
* pUnkOuter [I] Must be NULL.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
* DSERR_NODRIVER, DSERR_OUTOFMEMORY
*/
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
{
@ -976,7 +1007,8 @@ DWORD WINAPI DSOUND_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
/*******************************************************************************
* DllCanUnloadNow [DSOUND.4] Determines whether the DLL is in use.
* DllCanUnloadNow [DSOUND.4]
* Determines whether the DLL is in use.
*
* RETURNS
* Success: S_OK

View File

@ -117,8 +117,7 @@ struct IDirectSoundBufferImpl
DWORD primary_mixpos, buf_mixpos;
BOOL need_remix;
/* IDirectSoundNotifyImpl fields */
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
IDirectSoundNotifyImpl *notify;
};
HRESULT WINAPI SecondaryBuffer_Create(
@ -189,9 +188,9 @@ struct IDirectSoundCaptureBufferImpl
IDirectSoundCaptureImpl* dsound;
/* FIXME: don't need this */
LPDSCBUFFERDESC pdscbd;
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
DWORD flags;
/* IDirectSoundNotifyImpl fields */
IDirectSoundNotifyImpl *notify;
};
/*****************************************************************************
@ -216,8 +215,10 @@ struct IDirectSoundNotifyImpl
ICOM_VFIELD(IDirectSoundNotify);
DWORD ref;
/* IDirectSoundNotifyImpl fields */
IDirectSoundBufferImpl* dsb;
IDirectSoundCaptureBufferImpl* dscb;
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
PIDSDRIVERNOTIFY hwnotify;
};
/*****************************************************************************

View File

@ -79,13 +79,13 @@ void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len)
DWORD offset;
LPDSBPOSITIONNOTIFY event;
if (dsb->nrofnotifies == 0)
if (!dsb->notify || dsb->notify->nrofnotifies == 0)
return;
TRACE("(%p) buflen = %ld, playpos = %ld, len = %d\n",
dsb, dsb->buflen, dsb->playpos, len);
for (i = 0; i < dsb->nrofnotifies ; i++) {
event = dsb->notifies + i;
for (i = 0; i < dsb->notify->nrofnotifies ; i++) {
event = dsb->notify->notifies + i;
offset = event->dwOffset;
TRACE("checking %d, position %ld, event = %p\n",
i, offset, event->hEventNotify);

View File

@ -388,10 +388,12 @@ static HRESULT WINAPI DSPROPERTY_DescriptionW(
}
ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
if (pcbReturned) {
*pcbReturned = cbPropData;
TRACE("*pcbReturned=%ld\n", *pcbReturned);
}
return S_OK;
}