From 5ec32cecf2c38ae9ccf6e33277b73287e4080bb0 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Mon, 1 Sep 2003 23:58:43 +0000 Subject: [PATCH] Added SecondaryBuffer and DirectSoundCaptureNotify COM objects to get reference counting right. --- dlls/dsound/buffer.c | 442 ++++++++++++++++++++++++++++++++++++------- dlls/dsound/capture.c | 193 +++++++++++++++---- dlls/dsound/dsound_main.c | 107 +++++++---- dlls/dsound/dsound_private.h | 96 +++++++--- dlls/dsound/mixer.c | 18 +- dlls/dsound/primary.c | 39 ++-- dlls/dsound/propset.c | 22 ++- dlls/dsound/sound3d.c | 22 ++- 8 files changed, 727 insertions(+), 212 deletions(-) diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 10119172a82..576d60bafd2 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -58,23 +58,12 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface( ICOM_THIS(IDirectSoundNotifyImpl,iface); TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - if (ppobj == NULL) { + if (This->dsb == NULL) { WARN("invalid parameter\n"); return E_INVALIDARG; } - *ppobj = NULL; /* assume error */ - - 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 ) ); - return E_NOINTERFACE; + return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER)This->dsb, riid, ppobj); } static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface) { @@ -94,14 +83,11 @@ static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface) { TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); ref = InterlockedDecrement(&(This->ref)); - /* 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); - + if (ref == 0) { + IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER)This->dsb); + This->dsb->notify = NULL; HeapFree(GetProcessHeap(),0,This); - return 0; + TRACE("(%p) released\n",This); } return ref; } @@ -124,23 +110,23 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions( notify[i].dwOffset,(DWORD)notify[i].hEventNotify); } - if (This->hwnotify) { + if (This->dsb->hwnotify) { HRESULT hres; - hres = IDsDriverNotify_SetNotificationPositions(This->hwnotify, howmuch, notify); + hres = IDsDriverNotify_SetNotificationPositions(This->dsb->hwnotify, howmuch, notify); if (hres != DS_OK) WARN("IDsDriverNotify_SetNotificationPositions failed\n"); return hres; } 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)); - if (This->notifies == NULL) { + This->dsb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + This->dsb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY)); + if (This->dsb->notifies == NULL) { WARN("out of memory\n"); return DSERR_OUTOFMEMORY; } - memcpy(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY)); - This->nrofnotifies = howmuch; + memcpy(This->dsb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY)); + This->dsb->nrofnotifies = howmuch; } return S_OK; @@ -148,13 +134,37 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions( ICOM_VTABLE(IDirectSoundNotify) dsnvt = { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IDirectSoundNotifyImpl_QueryInterface, - IDirectSoundNotifyImpl_AddRef, - IDirectSoundNotifyImpl_Release, - IDirectSoundNotifyImpl_SetNotificationPositions, + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IDirectSoundNotifyImpl_QueryInterface, + IDirectSoundNotifyImpl_AddRef, + IDirectSoundNotifyImpl_Release, + IDirectSoundNotifyImpl_SetNotificationPositions, }; +HRESULT WINAPI IDirectSoundNotifyImpl_Create( + IDirectSoundBufferImpl * dsb, + IDirectSoundNotifyImpl **pdsn) +{ + IDirectSoundNotifyImpl * dsn; + TRACE("(%p,%p)\n",dsb,pdsn); + + dsn = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsn)); + + if (dsn == NULL) { + WARN("out of memory\n"); + return DSERR_OUTOFMEMORY; + } + + dsn->ref = 0; + dsn->lpVtbl = &dsnvt; + dsn->dsb = dsb; + dsb->notify = dsn; + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb); + + *pdsn = dsn; + return DS_OK; +} + /******************************************************************************* * IDirectSoundBuffer */ @@ -361,7 +371,6 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) { for (i=0;idsound->nrofbuffers;i++) if (This->dsound->buffers[i] == This) break; - if (i < This->dsound->nrofbuffers) { /* Put the last buffer of the list in the (now empty) position */ This->dsound->buffers[i] = This->dsound->buffers[This->dsound->nrofbuffers - 1]; @@ -401,8 +410,12 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) { if (This->iks) IKsPropertySet_Release((LPKSPROPERTYSET)This->iks); + if (This->notifies != NULL) + HeapFree(GetProcessHeap(), 0, This->notifies); + HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); return 0; } @@ -920,24 +933,24 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface( if ( IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectSoundBuffer) || IsEqualGUID(riid, &IID_IDirectSoundBuffer8) ) { - IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This); - *ppobj = This; - return S_OK; + if (!This->dsb) + SecondaryBufferImpl_Create(This, &(This->dsb)); + if (This->dsb) { + IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This->dsb); + *ppobj = This->dsb; + return S_OK; + } + WARN("IID_IDirectSoundBuffer\n"); + return E_NOINTERFACE; } 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) + IDirectSoundNotifyImpl_Create(This, &(This->notify)); if (This->notify) { IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify); - *ppobj = (LPVOID)This->notify; + *ppobj = This->notify; return S_OK; } WARN("IID_IDirectSoundNotify\n"); @@ -946,10 +959,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface( if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) { if (!This->ds3db) - IDirectSound3DBufferImpl_Create(This, &This->ds3db); - *ppobj = This->ds3db; - if (*ppobj) { - IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)*ppobj); + IDirectSound3DBufferImpl_Create(This, &(This->ds3db)); + if (This->ds3db) { + IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)This->ds3db); + *ppobj = This->ds3db; return S_OK; } WARN("IID_IDirectSound3DBuffer\n"); @@ -965,13 +978,12 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface( /* only supported on hardware 3D secondary buffers */ if (!(This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) && (This->dsbd.dwFlags & DSBCAPS_CTRL3D) && - (This->dsbd.dwFlags & DSBCAPS_LOCHARDWARE) && (This->hwbuf != NULL) ) { if (!This->iks) - IKsBufferPropertySetImpl_Create(This, &This->iks); - *ppobj = This->iks; - if (*ppobj) { + IKsBufferPropertySetImpl_Create(This, &(This->iks)); + if (This->iks) { IKsPropertySet_AddRef((LPKSPROPERTYSET)*ppobj); + *ppobj = This->iks; return S_OK; } } @@ -1013,8 +1025,8 @@ static ICOM_VTABLE(IDirectSoundBuffer8) dsbvt = IDirectSoundBufferImpl_GetObjectInPath }; -HRESULT WINAPI SecondaryBuffer_Create( - IDirectSoundImpl *This, +HRESULT WINAPI IDirectSoundBufferImpl_Create( + IDirectSoundImpl *ds, IDirectSoundBufferImpl **pdsb, LPDSBUFFERDESC dsbd) { @@ -1023,6 +1035,7 @@ HRESULT WINAPI SecondaryBuffer_Create( HRESULT err = DS_OK; DWORD capf = 0; int use_hw; + TRACE("(%p,%p,%p)\n",ds,pdsb,dsbd); if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) { WARN("invalid parameter: dsbd->dwBufferBytes = %ld\n", dsbd->dwBufferBytes); @@ -1038,7 +1051,8 @@ HRESULT WINAPI SecondaryBuffer_Create( return DSERR_OUTOFMEMORY; } dsb->ref = 0; - dsb->dsound = This; + dsb->dsb = 0; + dsb->dsound = ds; dsb->lpVtbl = &dsbvt; memcpy(&dsb->dsbd, dsbd, sizeof(*dsbd)); @@ -1050,12 +1064,17 @@ HRESULT WINAPI SecondaryBuffer_Create( dsb->buflen = dsbd->dwBufferBytes; dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec; + dsb->notify = NULL; + dsb->notifies = NULL; + dsb->nrofnotifies = 0; + dsb->hwnotify = 0; + /* Check necessary hardware mixing capabilities */ if (wfex->nChannels==2) capf |= DSCAPS_SECONDARYSTEREO; else capf |= DSCAPS_SECONDARYMONO; if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT; else capf |= DSCAPS_SECONDARY8BIT; - use_hw = (This->drvcaps.dwFlags & capf) == capf; + use_hw = (ds->drvcaps.dwFlags & capf) == capf; /* FIXME: check hardware sample rate mixing capabilities */ /* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */ @@ -1063,7 +1082,7 @@ HRESULT WINAPI SecondaryBuffer_Create( /* FIXME: handle DSDHEAP_CREATEHEAP for hardware buffers */ /* Allocate system memory if applicable */ - if ((This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) { + if ((ds->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) { dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer))); if (dsb->buffer == NULL) { WARN("out of memory\n"); @@ -1084,7 +1103,7 @@ HRESULT WINAPI SecondaryBuffer_Create( /* Allocate the hardware buffer */ if (use_hw) { - err = IDsDriver_CreateSoundBuffer(This->driver,wfex,dsbd->dwFlags,0, + err = IDsDriver_CreateSoundBuffer(ds->driver,wfex,dsbd->dwFlags,0, &(dsb->buflen),&(dsb->buffer->memory), (LPVOID*)&(dsb->hwbuf)); if (err != DS_OK) { @@ -1109,7 +1128,7 @@ HRESULT WINAPI SecondaryBuffer_Create( dsb->state = STATE_STOPPED; dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) / - This->wfx.nSamplesPerSec; + ds->wfx.nSamplesPerSec; dsb->nAvgBytesPerSec = dsb->freq * dsbd->lpwfxFormat->nBlockAlign; @@ -1139,29 +1158,312 @@ HRESULT WINAPI SecondaryBuffer_Create( InitializeCriticalSection(&(dsb->lock)); /* register buffer */ - RtlAcquireResourceExclusive(&(This->lock), TRUE); + RtlAcquireResourceExclusive(&(ds->lock), TRUE); if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) { - IDirectSoundBufferImpl **newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl*)*(This->nrofbuffers+1)); + IDirectSoundBufferImpl **newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,ds->buffers,sizeof(IDirectSoundBufferImpl*)*(ds->nrofbuffers+1)); if (newbuffers) { - This->buffers = newbuffers; - This->buffers[This->nrofbuffers] = dsb; - This->nrofbuffers++; - TRACE("buffer count is now %d\n", This->nrofbuffers); + ds->buffers = newbuffers; + ds->buffers[ds->nrofbuffers] = dsb; + ds->nrofbuffers++; + TRACE("buffer count is now %d\n", ds->nrofbuffers); } else { - ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers); + ERR("out of memory for buffer list! Current buffer count is %d\n", ds->nrofbuffers); if (dsb->buffer->memory) HeapFree(GetProcessHeap(),0,dsb->buffer->memory); if (dsb->buffer) HeapFree(GetProcessHeap(),0,dsb->buffer); DeleteCriticalSection(&(dsb->lock)); - RtlReleaseResource(&(This->lock)); + RtlReleaseResource(&(ds->lock)); HeapFree(GetProcessHeap(),0,dsb); *pdsb = NULL; return DSERR_OUTOFMEMORY; } } - RtlReleaseResource(&(This->lock)); - IDirectSound8_AddRef((LPDIRECTSOUND8)This); + RtlReleaseResource(&(ds->lock)); + IDirectSound8_AddRef((LPDIRECTSOUND8)ds); *pdsb = dsb; return S_OK; } + +/******************************************************************************* + * SecondaryBuffer + */ + +static HRESULT WINAPI SecondaryBufferImpl_QueryInterface( + LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + + return IDirectSoundBufferImpl_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb,riid,ppobj); +} + +static DWORD WINAPI SecondaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) +{ + ICOM_THIS(IDirectSoundBufferImpl,iface); + DWORD ref; + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); + + ref = InterlockedIncrement(&(This->ref)); + if (!ref) { + FIXME("thread-safety alert! AddRef-ing with a zero refcount!\n"); + } + return ref; +} + +static DWORD WINAPI SecondaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) +{ + ICOM_THIS(IDirectSoundBufferImpl,iface); + DWORD ref; + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); + + ref = InterlockedDecrement(&(This->ref)); + if (!ref) { + This->dsb->dsb = NULL; + IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb); + HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); + } + return ref; +} + +static HRESULT WINAPI SecondaryBufferImpl_GetCaps( + LPDIRECTSOUNDBUFFER8 iface,LPDSBCAPS caps) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p)->(%p)\n",This,caps); + + return IDirectSoundBufferImpl_GetCaps((LPDIRECTSOUNDBUFFER8)This->dsb,caps); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetCurrentPosition( + LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p,%p)\n",This,playpos,writepos); + + return IDirectSoundBufferImpl_GetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,playpos,writepos); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetFormat( + LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten); + + return IDirectSoundBufferImpl_GetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,lpwf,wfsize,wfwritten); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetVolume( + LPDIRECTSOUNDBUFFER8 iface,LPLONG vol) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p)\n",This,vol); + + return IDirectSoundBufferImpl_GetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetPan( + LPDIRECTSOUNDBUFFER8 iface,LPLONG pan) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p)\n",This,pan); + + return IDirectSoundBufferImpl_GetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetFrequency( + LPDIRECTSOUNDBUFFER8 iface,LPDWORD freq) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p)\n",This,freq); + + return IDirectSoundBufferImpl_GetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetStatus( + LPDIRECTSOUNDBUFFER8 iface,LPDWORD status) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p)\n",This,status); + + return IDirectSoundBufferImpl_GetStatus((LPDIRECTSOUNDBUFFER8)This->dsb,status); +} + +static HRESULT WINAPI SecondaryBufferImpl_Initialize( + LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND8 dsound,LPDSBUFFERDESC dbsd) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p,%p)\n",This,dsound,dbsd); + + return IDirectSoundBufferImpl_Initialize((LPDIRECTSOUNDBUFFER8)This->dsb,dsound,dbsd); +} + +static HRESULT WINAPI SecondaryBufferImpl_Lock( + LPDIRECTSOUNDBUFFER8 iface,DWORD writecursor,DWORD writebytes,LPVOID lplpaudioptr1,LPDWORD audiobytes1,LPVOID lplpaudioptr2,LPDWORD audiobytes2,DWORD flags) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%ld,%ld,%p,%p,%p,%p,0x%08lx)\n", + This,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,flags); + + return IDirectSoundBufferImpl_Lock((LPDIRECTSOUNDBUFFER8)This->dsb,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,flags); +} + +static HRESULT WINAPI SecondaryBufferImpl_Play( + LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%08lx,%08lx,%08lx)\n",This,reserved1,reserved2,flags); + + return IDirectSoundBufferImpl_Play((LPDIRECTSOUNDBUFFER8)This->dsb,reserved1,reserved2,flags); +} + +static HRESULT WINAPI SecondaryBufferImpl_SetCurrentPosition( + LPDIRECTSOUNDBUFFER8 iface,DWORD newpos) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%ld)\n",This,newpos); + + return IDirectSoundBufferImpl_SetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,newpos); +} + +static HRESULT WINAPI SecondaryBufferImpl_SetFormat( + LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX wfex) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p)\n",This,wfex); + + return IDirectSoundBufferImpl_SetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,wfex); +} + +static HRESULT WINAPI SecondaryBufferImpl_SetVolume( + LPDIRECTSOUNDBUFFER8 iface,LONG vol) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%ld)\n",This,vol); + + return IDirectSoundBufferImpl_SetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol); +} + +static HRESULT WINAPI SecondaryBufferImpl_SetPan( + LPDIRECTSOUNDBUFFER8 iface,LONG pan) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%ld)\n",This,pan); + + return IDirectSoundBufferImpl_SetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan); +} + +static HRESULT WINAPI SecondaryBufferImpl_SetFrequency( + LPDIRECTSOUNDBUFFER8 iface,DWORD freq) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%ld)\n",This,freq); + + return IDirectSoundBufferImpl_SetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq); +} + +static HRESULT WINAPI SecondaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p)\n",This); + + return IDirectSoundBufferImpl_Stop((LPDIRECTSOUNDBUFFER8)This->dsb); +} + +static HRESULT WINAPI SecondaryBufferImpl_Unlock( + LPDIRECTSOUNDBUFFER8 iface,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2); + + return IDirectSoundBufferImpl_Unlock((LPDIRECTSOUNDBUFFER8)This->dsb,p1,x1,p2,x2); +} + +static HRESULT WINAPI SecondaryBufferImpl_Restore( + LPDIRECTSOUNDBUFFER8 iface) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p)\n",This); + + return IDirectSoundBufferImpl_Restore((LPDIRECTSOUNDBUFFER8)This->dsb); +} + +static HRESULT WINAPI SecondaryBufferImpl_SetFX( + LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%lu,%p,%p)\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes); + + return IDirectSoundBufferImpl_SetFX((LPDIRECTSOUNDBUFFER8)This->dsb,dwEffectsCount,pDSFXDesc,pdwResultCodes); +} + +static HRESULT WINAPI SecondaryBufferImpl_AcquireResources( + LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%08lu,%lu,%p)\n",This,dwFlags,dwEffectsCount,pdwResultCodes); + + return IDirectSoundBufferImpl_AcquireResources((LPDIRECTSOUNDBUFFER8)This->dsb,dwFlags,dwEffectsCount,pdwResultCodes); +} + +static HRESULT WINAPI SecondaryBufferImpl_GetObjectInPath( + LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID* ppObject) +{ + ICOM_THIS(SecondaryBufferImpl,iface); + TRACE("(%p,%s,%lu,%s,%p)\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject); + + return IDirectSoundBufferImpl_GetObjectInPath((LPDIRECTSOUNDBUFFER8)This->dsb,rguidObject,dwIndex,rguidInterface,ppObject); +} + +static ICOM_VTABLE(IDirectSoundBuffer8) sbvt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + SecondaryBufferImpl_QueryInterface, + SecondaryBufferImpl_AddRef, + SecondaryBufferImpl_Release, + SecondaryBufferImpl_GetCaps, + SecondaryBufferImpl_GetCurrentPosition, + SecondaryBufferImpl_GetFormat, + SecondaryBufferImpl_GetVolume, + SecondaryBufferImpl_GetPan, + SecondaryBufferImpl_GetFrequency, + SecondaryBufferImpl_GetStatus, + SecondaryBufferImpl_Initialize, + SecondaryBufferImpl_Lock, + SecondaryBufferImpl_Play, + SecondaryBufferImpl_SetCurrentPosition, + SecondaryBufferImpl_SetFormat, + SecondaryBufferImpl_SetVolume, + SecondaryBufferImpl_SetPan, + SecondaryBufferImpl_SetFrequency, + SecondaryBufferImpl_Stop, + SecondaryBufferImpl_Unlock, + SecondaryBufferImpl_Restore, + SecondaryBufferImpl_SetFX, + SecondaryBufferImpl_AcquireResources, + SecondaryBufferImpl_GetObjectInPath +}; + +HRESULT WINAPI SecondaryBufferImpl_Create( + IDirectSoundBufferImpl *dsb, + SecondaryBufferImpl **psb) +{ + SecondaryBufferImpl *sb; + TRACE("(%p,%p)\n",dsb,psb); + + sb = (SecondaryBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb)); + + if (sb == 0) { + WARN("out of memory\n"); + *psb = NULL; + return DSERR_OUTOFMEMORY; + } + sb->ref = 0; + sb->dsb = dsb; + sb->lpVtbl = &sbvt; + + IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)dsb); + *psb = sb; + return S_OK; +} diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index d14b2f771e7..6b5707a2894 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -325,8 +325,8 @@ DSOUND_capture_callback( } This->index = (This->index + 1) % This->nrofpwaves; waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR)); - if (This->capture_buffer->notify && This->capture_buffer->notify->nrofnotifies) - SetEvent(This->capture_buffer->notify->notifies[This->index].hEventNotify); + if (This->capture_buffer->nrofnotifies) + SetEvent(This->capture_buffer->notifies[This->index].hEventNotify); if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) { TRACE("end of buffer\n"); This->state = STATE_STOPPED; @@ -377,10 +377,9 @@ IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface ) { ULONG uRef; ICOM_THIS(IDirectSoundCaptureImpl,iface); + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); EnterCriticalSection( &(This->lock) ); - - TRACE( "(%p) was 0x%08lx\n", This, This->ref ); uRef = ++(This->ref); if (This->driver) @@ -396,10 +395,10 @@ IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface ) { ULONG uRef; ICOM_THIS(IDirectSoundCaptureImpl,iface); + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); EnterCriticalSection( &(This->lock) ); - TRACE( "(%p) was 0x%08lx\n", This, This->ref ); uRef = --(This->ref); LeaveCriticalSection( &(This->lock) ); @@ -418,9 +417,9 @@ IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface ) DeleteCriticalSection( &(This->lock) ); HeapFree( GetProcessHeap(), 0, This ); dsound_capture = NULL; + TRACE("(%p) released\n",This); } - TRACE( "returning 0x%08lx\n", uRef ); return uRef; } @@ -704,6 +703,9 @@ DSOUND_CreateDirectSoundCaptureBuffer( This->ref = 1; This->dsound = ipDSC; This->dsound->capture_buffer = This; + This->notify = NULL; + This->nrofnotifies = 0; + This->hwnotify = NULL; This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, lpcDSCBufferDesc->dwSize); @@ -765,6 +767,131 @@ DSOUND_CreateDirectSoundCaptureBuffer( return DS_OK; } +/******************************************************************************* + * IDirectSoundCaptureNotify + */ +static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_QueryInterface( + LPDIRECTSOUNDNOTIFY iface, + REFIID riid, + LPVOID *ppobj) +{ + ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface); + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + + if (This->dscb == NULL) { + WARN("invalid parameter\n"); + return E_INVALIDARG; + } + + return IDirectSoundCaptureBuffer_QueryInterface((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb, riid, ppobj); +} + +static ULONG WINAPI IDirectSoundCaptureNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface) +{ + ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface); + DWORD ref; + + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); + + ref = InterlockedIncrement(&(This->ref)); + return ref; +} + +static ULONG WINAPI IDirectSoundCaptureNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface) +{ + ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface); + DWORD ref; + + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); + + ref = InterlockedDecrement(&(This->ref)); + if (ref == 0) { + This->dscb->notify=NULL; + IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb); + HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); + } + return ref; +} + +static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_SetNotificationPositions( + LPDIRECTSOUNDNOTIFY iface, + DWORD howmuch, + LPCDSBPOSITIONNOTIFY notify) +{ + ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface); + TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify); + + if (notify == NULL) { + WARN("invalid parameter: notify == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (TRACE_ON(dsound)) { + int i; + for (i=0;idscb->hwnotify) { + HRESULT hres; + hres = IDsDriverNotify_SetNotificationPositions(This->dscb->hwnotify, howmuch, notify); + if (hres != DS_OK) + WARN("IDsDriverNotify_SetNotificationPositions failed\n"); + return hres; + } else { + /* Make an internal copy of the caller-supplied array. + * Replace the existing copy if one is already present. */ + This->dscb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + This->dscb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY)); + if (This->dscb->notifies == NULL) { + WARN("out of memory\n"); + return DSERR_OUTOFMEMORY; + } + memcpy(This->dscb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY)); + This->dscb->nrofnotifies = howmuch; + } + + return S_OK; +} + +ICOM_VTABLE(IDirectSoundNotify) dscnvt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IDirectSoundCaptureNotifyImpl_QueryInterface, + IDirectSoundCaptureNotifyImpl_AddRef, + IDirectSoundCaptureNotifyImpl_Release, + IDirectSoundCaptureNotifyImpl_SetNotificationPositions, +}; + +HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create( + IDirectSoundCaptureBufferImpl *dscb, + IDirectSoundCaptureNotifyImpl **pdscn) +{ + IDirectSoundCaptureNotifyImpl * dscn; + TRACE("(%p,%p)\n",dscb,pdscn); + + dscn = (IDirectSoundCaptureNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dscn)); + + if (dscn == NULL) { + WARN("out of memory\n"); + return DSERR_OUTOFMEMORY; + } + + dscn->ref = 0; + dscn->lpVtbl = &dscnvt; + dscn->dscb = dscb; + dscb->notify = dscn; + IDirectSoundCaptureBuffer_AddRef((LPDIRECTSOUNDCAPTUREBUFFER)dscb); + + *pdscn = dscn; + return DS_OK; +} + +/******************************************************************************* + * IDirectSoundCaptureBuffer + */ static HRESULT WINAPI IDirectSoundCaptureBufferImpl_QueryInterface( LPDIRECTSOUNDCAPTUREBUFFER8 iface, @@ -772,6 +899,7 @@ IDirectSoundCaptureBufferImpl_QueryInterface( LPVOID* ppobj ) { ICOM_THIS(IDirectSoundCaptureBufferImpl,iface); + HRESULT hres; TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj ); if (ppobj == NULL) { @@ -783,24 +911,16 @@ IDirectSoundCaptureBufferImpl_QueryInterface( 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) + hres = IDirectSoundCaptureNotifyImpl_Create(This, &This->notify); 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) { + hres = IDsCaptureDriverBuffer_QueryInterface(This->dsound->hwbuf, + &IID_IDsDriverNotify, (LPVOID*)&(This->hwnotify)); + if (hres != DS_OK) { WARN("IDsCaptureDriverBuffer_QueryInterface failed\n"); *ppobj = 0; - return err; + return hres; } } @@ -809,7 +929,6 @@ IDirectSoundCaptureBufferImpl_QueryInterface( return DS_OK; } - *ppobj = 0; WARN("IID_IDirectSoundNotify\n"); return E_FAIL; } @@ -822,9 +941,6 @@ IDirectSoundCaptureBufferImpl_QueryInterface( } FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj); - - *ppobj = 0; - return E_NOINTERFACE; } @@ -833,13 +949,12 @@ IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) { ULONG uRef; ICOM_THIS(IDirectSoundCaptureBufferImpl,iface); - TRACE( "(%p)\n", This ); + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); assert(This->dsound); EnterCriticalSection( &(This->dsound->lock) ); - TRACE( "(%p) was 0x%08lx\n", This, This->ref ); uRef = ++(This->ref); LeaveCriticalSection( &(This->dsound->lock) ); @@ -852,13 +967,12 @@ IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) { ULONG uRef; ICOM_THIS(IDirectSoundCaptureBufferImpl,iface); - TRACE( "(%p)\n", This ); + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); assert(This->dsound); EnterCriticalSection( &(This->dsound->lock) ); - TRACE( "(%p) was 0x%08lx\n", This, This->ref ); uRef = --(This->ref); LeaveCriticalSection( &(This->dsound->lock) ); @@ -890,10 +1004,13 @@ IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) if (This->notify) IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify); + if (This->notifies != NULL) + HeapFree(GetProcessHeap(), 0, This->notifies); + HeapFree( GetProcessHeap(), 0, This ); + TRACE("(%p) released\n",This); } - TRACE( "returning 0x%08lx\n", uRef ); return uRef; } @@ -1205,10 +1322,10 @@ IDirectSoundCaptureBufferImpl_Start( IDirectSoundCaptureImpl* ipDSC = This->dsound; if (ipDSC->buffer) { - if (This->notify && This->notify->nrofnotifies) { + if (This->nrofnotifies) { unsigned c; - ipDSC->nrofpwaves = This->notify->nrofnotifies; + ipDSC->nrofpwaves = This->nrofnotifies; /* prepare headers */ ipDSC->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->pwave, @@ -1218,13 +1335,13 @@ IDirectSoundCaptureBufferImpl_Start( if (c == 0) { ipDSC->pwave[0].lpData = ipDSC->buffer; ipDSC->pwave[0].dwBufferLength = - This->notify->notifies[0].dwOffset + 1; + This->notifies[0].dwOffset + 1; } else { ipDSC->pwave[c].lpData = ipDSC->buffer + - This->notify->notifies[c-1].dwOffset + 1; + This->notifies[c-1].dwOffset + 1; ipDSC->pwave[c].dwBufferLength = - This->notify->notifies[c].dwOffset - - This->notify->notifies[c-1].dwOffset; + This->notifies[c].dwOffset - + This->notifies[c-1].dwOffset; } ipDSC->pwave[c].dwUser = (DWORD)ipDSC; ipDSC->pwave[c].dwFlags = 0; @@ -1604,10 +1721,10 @@ IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface ) { ULONG uRef; ICOM_THIS(IDirectSoundFullDuplexImpl,iface); + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); EnterCriticalSection( &(This->lock) ); - TRACE( "(%p) was 0x%08lx\n", This, This->ref ); uRef = ++(This->ref); LeaveCriticalSection( &(This->lock) ); @@ -1620,18 +1737,18 @@ IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface ) { ULONG uRef; ICOM_THIS(IDirectSoundFullDuplexImpl,iface); + TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); EnterCriticalSection( &(This->lock) ); - TRACE( "(%p) was 0x%08lx\n", This, This->ref ); uRef = --(This->ref); LeaveCriticalSection( &(This->lock) ); if ( uRef == 0 ) { - TRACE("deleting object\n"); DeleteCriticalSection( &(This->lock) ); HeapFree( GetProcessHeap(), 0, This ); + TRACE("(%p) released\n",This); } return uRef; diff --git a/dlls/dsound/dsound_main.c b/dlls/dsound/dsound_main.c index 204745469a8..bd926c9cf9f 100644 --- a/dlls/dsound/dsound_main.c +++ b/dlls/dsound/dsound_main.c @@ -529,39 +529,52 @@ static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer( wfex->wBitsPerSample, wfex->cbSize); if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) { - *ppdsb=(LPDIRECTSOUNDBUFFER8)This->primary; - if (*ppdsb==NULL) - WARN("PrimaryBuffer_Create failed\n"); - else { + if (This->primary) { + WARN("Primary Buffer already created\n"); + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary)); + *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary); + } else { This->dsbd = *dsbd; - IDirectSoundBuffer_AddRef(*ppdsb); + hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd)); + if (This->primary) { + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary)); + *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary); + } else + WARN("PrimaryBufferImpl_Create failed\n"); } } else { - hres = SecondaryBuffer_Create(This, (IDirectSoundBufferImpl**)ppdsb, dsbd); - if (hres != DS_OK) - WARN("SecondaryBuffer_Create failed\n"); - else - IDirectSoundBuffer_AddRef(*ppdsb); + IDirectSoundBufferImpl * dsb; + hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd); + if (dsb) { + hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb); + if (*ppdsb) { + dsb->dsb = (SecondaryBufferImpl*)*ppdsb; + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb); + } else + WARN("SecondaryBufferImpl_Create failed\n"); + } else + WARN("IDirectSoundBufferImpl_Create failed\n"); } return hres; } static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer( - LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 pdsb,LPLPDIRECTSOUNDBUFFER8 ppdsb + LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 psb,LPLPDIRECTSOUNDBUFFER8 ppdsb ) { ICOM_THIS(IDirectSoundImpl,iface); - IDirectSoundBufferImpl* ipdsb=(IDirectSoundBufferImpl*)pdsb; + IDirectSoundBufferImpl* pdsb; IDirectSoundBufferImpl* dsb; - TRACE("(%p,%p,%p)\n",This,pdsb,ppdsb); + HRESULT hres = DS_OK; + TRACE("(%p,%p,%p)\n",This,psb,ppdsb); if (This == NULL) { WARN("invalid parameter: This == NULL\n"); return DSERR_INVALIDPARAM; } - if (pdsb == NULL) { - WARN("invalid parameter: pdsb == NULL\n"); + if (psb == NULL) { + WARN("invalid parameter: psb == NULL\n"); return DSERR_INVALIDPARAM; } @@ -570,13 +583,16 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer( return DSERR_INVALIDPARAM; } - if (ipdsb->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) { + /* FIXME: hack to make sure we have a secondary buffer */ + if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) { ERR("trying to duplicate primary buffer\n"); *ppdsb = NULL; return DSERR_INVALIDCALL; } - if (ipdsb->hwbuf) { + pdsb = ((SecondaryBufferImpl *)psb)->dsb; + + if (pdsb->hwbuf) { FIXME("need to duplicate hardware buffer\n"); *ppdsb = NULL; return DSERR_INVALIDCALL; @@ -590,8 +606,8 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer( return DSERR_OUTOFMEMORY; } - memcpy(dsb, ipdsb, sizeof(IDirectSoundBufferImpl)); - dsb->ref = 1; + memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl)); + dsb->ref = 0; dsb->state = STATE_STOPPED; dsb->playpos = 0; dsb->buf_mixpos = 0; @@ -600,7 +616,8 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer( dsb->hwbuf = NULL; dsb->ds3db = NULL; dsb->iks = NULL; /* FIXME? */ - memcpy(&(dsb->wfx), &(ipdsb->wfx), sizeof(dsb->wfx)); + dsb->dsb = NULL; + memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx)); InitializeCriticalSection(&(dsb->lock)); /* register buffer */ RtlAcquireResourceExclusive(&(This->lock), TRUE); @@ -613,7 +630,7 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer( TRACE("buffer count is now %d\n", This->nrofbuffers); } else { ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers); - IDirectSoundBuffer8_Release(pdsb); + IDirectSoundBuffer8_Release(psb); DeleteCriticalSection(&(dsb->lock)); RtlReleaseResource(&(This->lock)); HeapFree(GetProcessHeap(),0,dsb); @@ -623,10 +640,15 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer( } RtlReleaseResource(&(This->lock)); IDirectSound_AddRef(iface); - *ppdsb = (LPDIRECTSOUNDBUFFER8)dsb; - return DS_OK; -} + hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb); + if (*ppdsb) { + dsb->dsb = (SecondaryBufferImpl*)*ppdsb; + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb); + } else + WARN("SecondaryBufferImpl_Create failed\n"); + return hres; +} static HRESULT WINAPI IDirectSoundImpl_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS lpDSCaps) { ICOM_THIS(IDirectSoundImpl,iface); @@ -699,7 +721,6 @@ static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) { TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId()); ulReturn = InterlockedDecrement(&This->ref); - if (ulReturn == 0) { HRESULT hres; UINT i; @@ -718,8 +739,10 @@ static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) { RtlReleaseResource(&(This->lock)); - if (This->primary) + if (This->primary) { + WARN("primary buffer not released\n"); IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary); + } hres = DSOUND_PrimaryDestroy(This); if (hres != DS_OK) @@ -739,8 +762,9 @@ static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) { DeleteCriticalSection(&This->ds3dl_lock); HeapFree(GetProcessHeap(),0,This); dsound = NULL; - return 0; + TRACE("(%p) released\n",This); } + return ulReturn; } @@ -748,7 +772,11 @@ static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig( LPDIRECTSOUND8 iface,DWORD config ) { ICOM_THIS(IDirectSoundImpl,iface); - FIXME("(%p,0x%08lx):stub\n",This,config); + TRACE("(%p,0x%08lx)\n",This,config); + + This->speaker_config = config; + + WARN("not fully functional\n"); return DS_OK; } @@ -796,7 +824,16 @@ static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig( { ICOM_THIS(IDirectSoundImpl,iface); TRACE("(%p, %p)\n", This, lpdwSpeakerConfig); - *lpdwSpeakerConfig = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16); + + if (lpdwSpeakerConfig == NULL) { + WARN("invalid parameter\n"); + return DSERR_INVALIDPARAM; + } + + WARN("not fully functional\n"); + + *lpdwSpeakerConfig = This->speaker_config; + return DS_OK; } @@ -883,6 +920,7 @@ HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown if (dsound) { if (IsEqualGUID(&devGuid, &dsound->guid) ) { + /* FIXME: this is wrong, need to create a new instance */ ERR("dsound already opened\n"); IDirectSound_AddRef((LPDIRECTSOUND)dsound); *ippDS = dsound; @@ -957,6 +995,7 @@ HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown (*ippDS)->nrofbuffers = 0; (*ippDS)->buffers = NULL; (*ippDS)->primary = NULL; + (*ippDS)->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16); /* 3D listener initial parameters */ (*ippDS)->listener = NULL; @@ -1115,15 +1154,7 @@ HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); } - /* create a user accessable primary buffer */ - (*ippDS)->dsbd.dwSize = sizeof((*ippDS)->dsbd); - err = PrimaryBuffer_Create((*ippDS), (PrimaryBufferImpl**)&((*ippDS)->primary), &((*ippDS)->dsbd)); - if ((*ippDS)->primary) - IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(*ippDS)->primary); - else - WARN("PrimaryBuffer_Create failed\n"); - - return err; + return DS_OK; } diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index f1fe3b9e52c..f66cb4b3a24 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -50,11 +50,13 @@ typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl; typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl; typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl; typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl; +typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl; typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl; typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl; typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl; typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl; typedef struct PrimaryBufferImpl PrimaryBufferImpl; +typedef struct SecondaryBufferImpl SecondaryBufferImpl; typedef struct IClassFactoryImpl IClassFactoryImpl; /***************************************************************************** @@ -87,6 +89,7 @@ struct IDirectSoundImpl DSVOLUMEPAN volpan; PrimaryBufferImpl* primary; DSBUFFERDESC dsbd; + DWORD speaker_config; /* DirectSound3DListener fields */ IDirectSound3DListenerImpl* listener; @@ -112,9 +115,8 @@ struct IDirectSoundBufferImpl ICOM_VFIELD(IDirectSoundBuffer8); DWORD ref; /* IDirectSoundBufferImpl fields */ + SecondaryBufferImpl* dsb; IDirectSoundImpl* dsound; - IDirectSound3DBufferImpl* ds3db; - IKsBufferPropertySetImpl* iks; CRITICAL_SECTION lock; PIDSDRIVERBUFFER hwbuf; WAVEFORMATEX wfx; @@ -131,30 +133,56 @@ struct IDirectSoundBufferImpl DWORD probably_valid_to, last_playpos; DWORD primary_mixpos, buf_mixpos; BOOL need_remix; + /* IDirectSoundNotifyImpl fields */ IDirectSoundNotifyImpl* notify; + LPDSBPOSITIONNOTIFY notifies; + int nrofnotifies; + PIDSDRIVERNOTIFY hwnotify; /* DirectSound3DBuffer fields */ + IDirectSound3DBufferImpl* ds3db; DS3DBUFFER ds3db_ds3db; LONG ds3db_lVolume; BOOL ds3db_need_recalc; + + /* IKsPropertySet fields */ + IKsBufferPropertySetImpl* iks; }; -HRESULT WINAPI SecondaryBuffer_Create( - IDirectSoundImpl *This, - IDirectSoundBufferImpl **pdsb, - LPDSBUFFERDESC dsbd); +HRESULT WINAPI IDirectSoundBufferImpl_Create( + IDirectSoundImpl *ds, + IDirectSoundBufferImpl **pdsb, + LPDSBUFFERDESC dsbd); -struct PrimaryBufferImpl { +/***************************************************************************** + * SecondaryBuffer implementation structure + */ +struct SecondaryBufferImpl +{ + ICOM_VFIELD(IDirectSoundBuffer8); + DWORD ref; + IDirectSoundBufferImpl* dsb; +}; + +HRESULT WINAPI SecondaryBufferImpl_Create( + IDirectSoundBufferImpl *dsb, + SecondaryBufferImpl **pdsb); + +/***************************************************************************** + * PrimaryBuffer implementation structure + */ +struct PrimaryBufferImpl +{ ICOM_VFIELD(IDirectSoundBuffer8); DWORD ref; IDirectSoundImpl* dsound; }; -HRESULT WINAPI PrimaryBuffer_Create( - IDirectSoundImpl *This, - PrimaryBufferImpl **pdsb, - LPDSBUFFERDESC dsbd); +HRESULT WINAPI PrimaryBufferImpl_Create( + IDirectSoundImpl *ds, + PrimaryBufferImpl **pdsb, + LPDSBUFFERDESC dsbd); /***************************************************************************** * IDirectSoundCapture implementation structure @@ -208,8 +236,12 @@ struct IDirectSoundCaptureBufferImpl /* FIXME: don't need this */ LPDSCBUFFERDESC pdscbd; DWORD flags; - /* IDirectSoundNotifyImpl fields */ - IDirectSoundNotifyImpl* notify; + + /* IDirectSoundCaptureNotifyImpl fields */ + IDirectSoundCaptureNotifyImpl* notify; + LPDSBPOSITIONNOTIFY notifies; + int nrofnotifies; + PIDSDRIVERNOTIFY hwnotify; }; /***************************************************************************** @@ -233,13 +265,28 @@ struct IDirectSoundNotifyImpl /* IUnknown fields */ ICOM_VFIELD(IDirectSoundNotify); DWORD ref; - /* IDirectSoundNotifyImpl fields */ - LPDSBPOSITIONNOTIFY notifies; - int nrofnotifies; + IDirectSoundBufferImpl* dsb; +}; - PIDSDRIVERNOTIFY hwnotify; +HRESULT WINAPI IDirectSoundNotifyImpl_Create( + IDirectSoundBufferImpl *dsb, + IDirectSoundNotifyImpl **pdsn); + +/***************************************************************************** + * IDirectSoundCaptureNotify implementation structure + */ +struct IDirectSoundCaptureNotifyImpl +{ + /* IUnknown fields */ + ICOM_VFIELD(IDirectSoundNotify); + DWORD ref; + IDirectSoundCaptureBufferImpl* dscb; }; +HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create( + IDirectSoundCaptureBufferImpl *dscb, + IDirectSoundCaptureNotifyImpl ** pdscn); + /***************************************************************************** * IDirectSound3DListener implementation structure */ @@ -253,8 +300,8 @@ struct IDirectSound3DListenerImpl }; HRESULT WINAPI IDirectSound3DListenerImpl_Create( - PrimaryBufferImpl *This, - IDirectSound3DListenerImpl **pdsl); + PrimaryBufferImpl *pb, + IDirectSound3DListenerImpl **pdsl); /***************************************************************************** * IKsBufferPropertySet implementation structure @@ -269,8 +316,8 @@ struct IKsBufferPropertySetImpl }; HRESULT WINAPI IKsBufferPropertySetImpl_Create( - IDirectSoundBufferImpl *This, - IKsBufferPropertySetImpl **piks); + IDirectSoundBufferImpl *dsb, + IKsBufferPropertySetImpl **piks); /***************************************************************************** * IKsPrivatePropertySet implementation structure @@ -283,7 +330,7 @@ struct IKsPrivatePropertySetImpl }; HRESULT WINAPI IKsPrivatePropertySetImpl_Create( - IKsPrivatePropertySetImpl **piks); + IKsPrivatePropertySetImpl **piks); /***************************************************************************** * IDirectSound3DBuffer implementation structure @@ -299,8 +346,8 @@ struct IDirectSound3DBufferImpl }; HRESULT WINAPI IDirectSound3DBufferImpl_Create( - IDirectSoundBufferImpl *This, - IDirectSound3DBufferImpl **pds3db); + IDirectSoundBufferImpl *dsb, + IDirectSound3DBufferImpl **pds3db); /******************************************************************************* * DirectSound ClassFactory implementation structure @@ -356,6 +403,5 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb); extern IDirectSoundImpl* dsound; extern IDirectSoundCaptureImpl* dsound_capture; -extern ICOM_VTABLE(IDirectSoundNotify) dsnvt; extern HRESULT mmErr(UINT err); extern void setup_dsound_options(void); diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index cf927e12b81..64191c3f4d5 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -68,6 +68,7 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) { DWORD sw; + TRACE("(%p)\n",dsb); sw = dsb->wfx.nChannels * (dsb->wfx.wBitsPerSample / 8); /* calculate the 10ms write lead */ @@ -79,14 +80,15 @@ void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len) int i; DWORD offset; LPDSBPOSITIONNOTIFY event; + TRACE("(%p,%d)\n",dsb,len); - if (!dsb->notify || dsb->notify->nrofnotifies == 0) + if (dsb->nrofnotifies == 0) return; TRACE("(%p) buflen = %ld, playpos = %ld, len = %d\n", dsb, dsb->buflen, dsb->playpos, len); - for (i = 0; i < dsb->notify->nrofnotifies ; i++) { - event = dsb->notify->notifies + i; + for (i = 0; i < dsb->nrofnotifies ; i++) { + event = dsb->notifies + i; offset = event->dwOffset; TRACE("checking %d, position %ld, event = %p\n", i, offset, event->hEventNotify); @@ -354,7 +356,7 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO BYTE *buf, *ibuf, *obuf; INT16 *ibufs, *obufs; - TRACE("%p,%ld,%ld)\n",dsb,writepos,fraglen); + TRACE("(%p,%ld,%ld)\n",dsb,writepos,fraglen); len = fraglen; if (!(dsb->playflags & DSBPLAY_LOOPING)) { @@ -440,6 +442,7 @@ static void DSOUND_PhaseCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, DWOR INT advance = dsb->dsound->wfx.wBitsPerSample >> 3; BYTE *buf, *ibuf, *obuf; INT16 *ibufs, *obufs; + TRACE("(%p,%ld,%ld)\n",dsb,writepos,len); nBlockAlign = dsb->dsound->wfx.nBlockAlign; len = len / nBlockAlign * nBlockAlign; /* data alignment */ @@ -552,6 +555,7 @@ void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos) void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb) { + TRACE("(%p)\n",dsb); EnterCriticalSection(&dsb->lock); if (dsb->state == STATE_PLAYING) { #if 0 /* this may not be quite reliable yet */ @@ -585,6 +589,7 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD wri DWORD buf_left = dsb->buflen - buf_writepos; int still_behind; + TRACE("(%p,%ld,%ld,%ld)\n",dsb,playpos,writepos,mixlen); TRACE("buf_writepos=%ld, primary_writepos=%ld\n", buf_writepos, writepos); TRACE("buf_done=%ld, primary_done=%ld\n", buf_done, primary_done); TRACE("buf_mixpos=%ld, primary_mixpos=%ld, mixlen=%ld\n", dsb->buf_mixpos, dsb->primary_mixpos, @@ -724,7 +729,7 @@ static DWORD DSOUND_MixToPrimary(DWORD playpos, DWORD writepos, DWORD mixlen, BO INT i, len, maxlen = 0; IDirectSoundBufferImpl *dsb; - TRACE("(%ld,%ld,%ld)\n", playpos, writepos, mixlen); + TRACE("(%ld,%ld,%ld,%d)\n", playpos, writepos, mixlen, recover); for (i = dsound->nrofbuffers - 1; i >= 0; i--) { dsb = dsound->buffers[i]; @@ -808,6 +813,7 @@ static void DSOUND_MixReset(DWORD writepos) static void DSOUND_CheckReset(IDirectSoundImpl *dsound, DWORD writepos) { + TRACE("(%p,%ld)\n",dsound,writepos); if (dsound->need_remix) { DSOUND_MixReset(writepos); dsound->need_remix = FALSE; @@ -827,6 +833,7 @@ static void DSOUND_CheckReset(IDirectSoundImpl *dsound, DWORD writepos) void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq) { + TRACE("(%p,%ld)\n",dsound,mixq); if (mixq + dsound->pwqueue > ds_hel_queue) mixq = ds_hel_queue - dsound->pwqueue; TRACE("queueing %ld buffers, starting at %d\n", mixq, dsound->pwwrite); for (; mixq; mixq--) { @@ -1034,6 +1041,7 @@ 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("(%p,%x,%lx,%lx,%lx)\n",hwo,msg,dwUser,dw1,dw2); 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"); diff --git a/dlls/dsound/primary.c b/dlls/dsound/primary.c index ef394c6fd75..4abf248d4a5 100644 --- a/dlls/dsound/primary.c +++ b/dlls/dsound/primary.c @@ -303,7 +303,7 @@ HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWO /******************************************************************************* - * IDirectSoundBuffer + * PrimaryBuffer */ /* This sets this format for the Primary Buffer Only */ /* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */ @@ -573,9 +573,11 @@ static DWORD WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) { TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); ref = InterlockedDecrement(&(This->ref)); - if (ref == -1) { + if (ref == 0) { This->dsound->primary = NULL; + IDirectSound_Release((LPDIRECTSOUND)This->dsound); HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); } return ref; @@ -942,16 +944,12 @@ static HRESULT WINAPI PrimaryBufferImpl_QueryInterface( } if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) { - if (This->dsound->dsbd.dwFlags & DSBCAPS_CTRL3D) { - if (!This->dsound->listener) - IDirectSound3DListenerImpl_Create(This, &This->dsound->listener); - + if (!This->dsound->listener) + IDirectSound3DListenerImpl_Create(This, &This->dsound->listener); + if (This->dsound->listener) { *ppobj = This->dsound->listener; - - if (This->dsound->listener) { - IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj); - return S_OK; - } + IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj); + return S_OK; } WARN("IID_IDirectSound3DListener failed\n"); @@ -996,14 +994,14 @@ static ICOM_VTABLE(IDirectSoundBuffer8) dspbvt = PrimaryBufferImpl_GetObjectInPath }; -HRESULT WINAPI PrimaryBuffer_Create( - IDirectSoundImpl *This, +HRESULT WINAPI PrimaryBufferImpl_Create( + IDirectSoundImpl *ds, PrimaryBufferImpl **pdsb, LPDSBUFFERDESC dsbd) { PrimaryBufferImpl *dsb; - TRACE("%p,%p,%p)\n",This,pdsb,dsbd); + TRACE("%p,%p,%p)\n",ds,pdsb,dsbd); if (dsbd->lpwfxFormat) { WARN("invalid parameter: dsbd->lpwfxFormat != NULL\n"); @@ -1019,19 +1017,20 @@ HRESULT WINAPI PrimaryBuffer_Create( return DSERR_OUTOFMEMORY; } - dsb->ref = -1; - dsb->dsound = This; + dsb->ref = 0; + dsb->dsound = ds; dsb->lpVtbl = &dspbvt; - memcpy(&This->dsbd, dsbd, sizeof(*dsbd)); + memcpy(&ds->dsbd, dsbd, sizeof(*dsbd)); TRACE("Created primary buffer at %p\n", dsb); TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld," "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n", - This->wfx.wFormatTag, This->wfx.nChannels, This->wfx.nSamplesPerSec, - This->wfx.nAvgBytesPerSec, This->wfx.nBlockAlign, - This->wfx.wBitsPerSample, This->wfx.cbSize); + ds->wfx.wFormatTag, ds->wfx.nChannels, ds->wfx.nSamplesPerSec, + ds->wfx.nAvgBytesPerSec, ds->wfx.nBlockAlign, + ds->wfx.wBitsPerSample, ds->wfx.cbSize); + IDirectSound_AddRef((LPDIRECTSOUND)ds); *pdsb = dsb; return S_OK; } diff --git a/dlls/dsound/propset.c b/dlls/dsound/propset.c index 55ec34852d6..30adad224c8 100644 --- a/dlls/dsound/propset.c +++ b/dlls/dsound/propset.c @@ -72,9 +72,7 @@ static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface) ULONG ulReturn; TRACE("(%p) ref was %ld\n", This, This->ref); - ulReturn = InterlockedIncrement(&This->ref); - if (ulReturn == 1) - IDirectSoundBuffer_AddRef((LPDIRECTSOUND3DBUFFER)This->dsb); + ulReturn = InterlockedIncrement(&(This->ref)); return ulReturn; } @@ -85,10 +83,13 @@ static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface) TRACE("(%p) ref was %ld\n", This, This->ref); ulReturn = InterlockedDecrement(&This->ref); - if (ulReturn) - return ulReturn; - IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb); - return 0; + if (!ulReturn) { + This->dsb->iks = 0; + IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb); + HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); + } + return ulReturn; } static HRESULT WINAPI IKsBufferPropertySetImpl_Get( @@ -146,16 +147,19 @@ static ICOM_VTABLE(IKsPropertySet) iksbvt = { }; HRESULT WINAPI IKsBufferPropertySetImpl_Create( - IDirectSoundBufferImpl *This, + IDirectSoundBufferImpl *dsb, IKsBufferPropertySetImpl **piks) { IKsBufferPropertySetImpl *iks; iks = (IKsBufferPropertySetImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*iks)); iks->ref = 0; - iks->dsb = This; + iks->dsb = dsb; + dsb->iks = iks; iks->lpVtbl = &iksbvt; + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb); + *piks = iks; return S_OK; } diff --git a/dlls/dsound/sound3d.c b/dlls/dsound/sound3d.c index 9b3660150f6..2105bcf9e81 100644 --- a/dlls/dsound/sound3d.c +++ b/dlls/dsound/sound3d.c @@ -395,10 +395,11 @@ static ULONG WINAPI IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId()); ulReturn = InterlockedDecrement(&This->ref); if (!ulReturn) { - IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This); This->dsb->ds3db = NULL; + IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb); DeleteCriticalSection(&(This->lock)); HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); } return ulReturn; @@ -766,11 +767,11 @@ static ICOM_VTABLE(IDirectSound3DBuffer) ds3dbvt = }; HRESULT WINAPI IDirectSound3DBufferImpl_Create( - IDirectSoundBufferImpl *This, + IDirectSoundBufferImpl *dsb, IDirectSound3DBufferImpl **pds3db) { IDirectSound3DBufferImpl *ds3db; - TRACE("(%p,%p)\n",This,pds3db); + TRACE("(%p,%p)\n",dsb,pds3db); ds3db = (IDirectSound3DBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db)); @@ -781,7 +782,7 @@ HRESULT WINAPI IDirectSound3DBufferImpl_Create( } ds3db->ref = 0; - ds3db->dsb = This; + ds3db->dsb = dsb; ds3db->lpVtbl = &ds3dbvt; ds3db->dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER); @@ -805,6 +806,8 @@ HRESULT WINAPI IDirectSound3DBufferImpl_Create( InitializeCriticalSection(&(ds3db->lock)); + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb); + *pds3db = ds3db; return S_OK; } @@ -836,9 +839,13 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface( } if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) { - *ppobj = This->dsound->primary; - IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj); - return S_OK; + if (!This->dsound->primary) + PrimaryBufferImpl_Create(This->dsound, &(This->dsound->primary), &(This->dsound->dsbd)); + if (This->dsound->primary) { + *ppobj = This->dsound->primary; + IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj); + return S_OK; + } } FIXME( "Unknown IID %s\n", debugstr_guid( riid ) ); @@ -873,6 +880,7 @@ static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER i IDirectSound8_Release((LPDIRECTSOUND8)This->dsound); This->dsound->listener = 0; HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n",This); } return ulReturn; -- 2.11.4.GIT