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
......@@ -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