Commit 5ec32cec authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Added SecondaryBuffer and DirectSoundCaptureNotify COM objects to get

reference counting right.
parent b7945a8a
......@@ -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;i<This->dsound->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;
}
......@@ -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;i<howmuch;i++)
TRACE("notify at %ld to 0x%08lx\n",
notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
}
if (This->dscb->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;
......
......@@ -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;
}
......
......@@ -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);
......@@ -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");
......
......@@ -303,7 +303,7 @@ HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWO
/*******************************************************************************
* IDirectSoundBuffer
* PrimaryBuffer
*/
/* This sets this format for the <em>Primary Buffer Only</em> */
/* 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;
}
......@@ -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;
}
......
......@@ -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;
......
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