Added SecondaryBuffer and DirectSoundCaptureNotify COM objects to get
reference counting right.
This commit is contained in:
parent
b7945a8ab3
commit
5ec32cecf2
|
@ -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;
|
||||
|
@ -155,6 +141,30 @@ ICOM_VTABLE(IDirectSoundNotify) dsnvt =
|
|||
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;
|
||||
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);
|
||||
IDirectSound3DBufferImpl_Create(This, &(This->ds3db));
|
||||
if (This->ds3db) {
|
||||
IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)This->ds3db);
|
||||
*ppobj = This->ds3db;
|
||||
if (*ppobj) {
|
||||
IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)*ppobj);
|
||||
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,28 +133,54 @@ 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,
|
||||
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,
|
||||
HRESULT WINAPI PrimaryBufferImpl_Create(
|
||||
IDirectSoundImpl *ds,
|
||||
PrimaryBufferImpl **pdsb,
|
||||
LPDSBUFFERDESC dsbd);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
PIDSDRIVERNOTIFY hwnotify;
|
||||
IDirectSoundBufferImpl* dsb;
|
||||
};
|
||||
|
||||
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,7 +300,7 @@ struct IDirectSound3DListenerImpl
|
|||
};
|
||||
|
||||
HRESULT WINAPI IDirectSound3DListenerImpl_Create(
|
||||
PrimaryBufferImpl *This,
|
||||
PrimaryBufferImpl *pb,
|
||||
IDirectSound3DListenerImpl **pdsl);
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -269,7 +316,7 @@ struct IKsBufferPropertySetImpl
|
|||
};
|
||||
|
||||
HRESULT WINAPI IKsBufferPropertySetImpl_Create(
|
||||
IDirectSoundBufferImpl *This,
|
||||
IDirectSoundBufferImpl *dsb,
|
||||
IKsBufferPropertySetImpl **piks);
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -299,7 +346,7 @@ struct IDirectSound3DBufferImpl
|
|||
};
|
||||
|
||||
HRESULT WINAPI IDirectSound3DBufferImpl_Create(
|
||||
IDirectSoundBufferImpl *This,
|
||||
IDirectSoundBufferImpl *dsb,
|
||||
IDirectSound3DBufferImpl **pds3db);
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -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,17 +944,13 @@ 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);
|
||||
|
||||
*ppobj = This->dsound->listener;
|
||||
|
||||
if (This->dsound->listener) {
|
||||
*ppobj = This->dsound->listener;
|
||||
IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
WARN("IID_IDirectSound3DListener failed\n");
|
||||
return E_NOINTERFACE;
|
||||
|
@ -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;
|
||||
if (!ulReturn) {
|
||||
This->dsb->iks = 0;
|
||||
IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
|
||||
return 0;
|
||||
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,10 +839,14 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface(
|
|||
}
|
||||
|
||||
if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
|
||||
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 ) );
|
||||
return E_NOINTERFACE;
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue