3D buffer and listener reference counts should be fixed.
3D sound now plays in 3D. COM interfaces should be correct for buffers and 3D stuff. The COM interface is broken on notifications but I will fix that next. Fixed the bug when closing and opening the same or another sound device quickly. Fixed some locking but there is a lot of work left yet.
This commit is contained in:
parent
0d6a2e9aba
commit
9dacf206fe
@ -29,8 +29,10 @@
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h> /* Insomnia - pow() function */
|
||||
#include <math.h>
|
||||
|
||||
#define NONAMELESSSTRUCT
|
||||
#define NONAMELESSUNION
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
@ -56,6 +58,8 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(
|
||||
ICOM_THIS(IDirectSoundNotifyImpl,iface);
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
|
||||
*ppobj = NULL; /* assume error */
|
||||
|
||||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSoundNotify) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSoundNotify8) ) {
|
||||
@ -65,9 +69,6 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(
|
||||
}
|
||||
|
||||
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
|
||||
|
||||
*ppobj = 0;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface) {
|
||||
ICOM_THIS(IDirectSoundNotifyImpl,iface);
|
||||
DWORD ref;
|
||||
|
||||
TRACE("(%p) ref was %ld\n", This, This->ref);
|
||||
TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
|
||||
|
||||
ref = InterlockedIncrement(&(This->ref));
|
||||
return ref;
|
||||
@ -85,7 +86,7 @@ static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface) {
|
||||
ICOM_THIS(IDirectSoundNotifyImpl,iface);
|
||||
DWORD ref;
|
||||
|
||||
TRACE("(%p) ref was %ld\n", This, This->ref);
|
||||
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
|
||||
@ -186,8 +187,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(
|
||||
EnterCriticalSection(&(This->lock));
|
||||
|
||||
if (This->dsbd.dwFlags & DSBCAPS_CTRL3D) {
|
||||
oldVol = This->ds3db->lVolume;
|
||||
This->ds3db->lVolume = vol;
|
||||
oldVol = This->ds3db_lVolume;
|
||||
This->ds3db_lVolume = vol;
|
||||
} else {
|
||||
oldVol = This->volpan.lVolume;
|
||||
This->volpan.lVolume = vol;
|
||||
@ -223,7 +224,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume(
|
||||
}
|
||||
|
||||
if (This->dsbd.dwFlags & DSBCAPS_CTRL3D)
|
||||
*vol = This->ds3db->lVolume;
|
||||
*vol = This->ds3db_lVolume;
|
||||
else
|
||||
*vol = This->volpan.lVolume;
|
||||
return DS_OK;
|
||||
@ -340,6 +341,7 @@ static DWORD WINAPI IDirectSoundBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) {
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
|
||||
ICOM_THIS(IDirectSoundBufferImpl,iface);
|
||||
int i;
|
||||
@ -366,25 +368,33 @@ static DWORD WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
|
||||
RtlReleaseResource(&(This->dsound->lock));
|
||||
|
||||
DeleteCriticalSection(&(This->lock));
|
||||
|
||||
if (This->hwbuf) {
|
||||
IDsDriverBuffer_Release(This->hwbuf);
|
||||
if (This->dsound->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)
|
||||
if (This->dsound->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
|
||||
This->buffer->ref--;
|
||||
if (This->buffer->ref==0) {
|
||||
HeapFree(GetProcessHeap(),0,This->buffer->memory);
|
||||
HeapFree(GetProcessHeap(),0,This->buffer);
|
||||
}
|
||||
else if (!This->parent)
|
||||
}
|
||||
} else {
|
||||
This->buffer->ref--;
|
||||
if (This->buffer->ref==0) {
|
||||
HeapFree(GetProcessHeap(),0,This->buffer->memory);
|
||||
HeapFree(GetProcessHeap(),0,This->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (This->ds3db) {
|
||||
IDirectSound3DBuffer_Release((LPDIRECTSOUND3DBUFFER)This->ds3db);
|
||||
WARN("ds3db still has reference\n");
|
||||
EnterCriticalSection(&(This->ds3db->lock));
|
||||
This->ds3db->dsb = NULL;
|
||||
LeaveCriticalSection(&(This->ds3db->lock));
|
||||
}
|
||||
if (This->dsound->listener) {
|
||||
if (IDirectSound3DListener_Release((LPDIRECTSOUND3DLISTENER)This->dsound->listener) == 0)
|
||||
This->dsound->listener = 0;
|
||||
}
|
||||
if (This->iks) {
|
||||
HeapFree(GetProcessHeap(), 0, This->iks);
|
||||
}
|
||||
if (This->parent)
|
||||
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->parent);
|
||||
|
||||
if (This->iks)
|
||||
IKsPropertySet_Release((LPKSPROPERTYSET)This->iks);
|
||||
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
|
||||
@ -622,7 +632,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
|
||||
} else {
|
||||
BOOL remix = FALSE;
|
||||
if (writecursor+writebytes <= This->buflen) {
|
||||
*(LPBYTE*)lplpaudioptr1 = This->buffer+writecursor;
|
||||
*(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
|
||||
*audiobytes1 = writebytes;
|
||||
if (lplpaudioptr2)
|
||||
*(LPBYTE*)lplpaudioptr2 = NULL;
|
||||
@ -630,10 +640,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
|
||||
*audiobytes2 = 0;
|
||||
TRACE("->%ld.0\n",writebytes);
|
||||
} else {
|
||||
*(LPBYTE*)lplpaudioptr1 = This->buffer+writecursor;
|
||||
*(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
|
||||
*audiobytes1 = This->buflen-writecursor;
|
||||
if (lplpaudioptr2)
|
||||
*(LPBYTE*)lplpaudioptr2 = This->buffer;
|
||||
*(LPBYTE*)lplpaudioptr2 = This->buffer->memory;
|
||||
if (audiobytes2)
|
||||
*audiobytes2 = writebytes-(This->buflen-writecursor);
|
||||
TRACE("->%ld.%ld\n",*audiobytes1,audiobytes2?*audiobytes2:0);
|
||||
@ -757,14 +767,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
|
||||
|
||||
TRACE("(%p,%p,%ld,%p,%ld)\n", This,p1,x1,p2,x2);
|
||||
|
||||
#if 0
|
||||
/* Preprocess 3D buffers... */
|
||||
|
||||
/* This is highly experimental and liable to break things */
|
||||
if (This->dsbd.dwFlags & DSBCAPS_CTRL3D)
|
||||
DSOUND_Create3DBuffer(This);
|
||||
#endif
|
||||
|
||||
if (!(This->dsound->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
|
||||
HRESULT hres;
|
||||
hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2);
|
||||
@ -774,8 +776,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
|
||||
}
|
||||
}
|
||||
|
||||
if (p2) probably_valid_to = (((LPBYTE)p2)-This->buffer) + x2;
|
||||
else probably_valid_to = (((LPBYTE)p1)-This->buffer) + x1;
|
||||
if (p2) probably_valid_to = (((LPBYTE)p2)-This->buffer->memory) + x2;
|
||||
else probably_valid_to = (((LPBYTE)p1)-This->buffer->memory) + x1;
|
||||
while (probably_valid_to >= This->buflen)
|
||||
probably_valid_to -= This->buflen;
|
||||
if ((probably_valid_to == 0) && ((x1+x2) == This->buflen) &&
|
||||
@ -903,6 +905,16 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
|
||||
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
|
||||
*ppobj = NULL; /* assume failure */
|
||||
|
||||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSoundBuffer8) ) {
|
||||
IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ||
|
||||
IsEqualGUID( &IID_IDirectSoundNotify8, riid ) ) {
|
||||
if (!This->notify) {
|
||||
@ -918,9 +930,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
|
||||
*ppobj = (LPVOID)This->notify;
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
WARN("IID_IDirectSoundNotify\n");
|
||||
return E_FAIL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
|
||||
@ -931,15 +942,13 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
|
||||
IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)*ppobj);
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
WARN("IID_IDirectSound3DBuffer\n");
|
||||
return E_FAIL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
|
||||
ERR("app requested IDirectSound3DListener on secondary buffer\n");
|
||||
*ppobj = NULL;
|
||||
return E_FAIL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
|
||||
@ -950,21 +959,12 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
|
||||
IKsPropertySet_AddRef((LPKSPROPERTYSET)*ppobj);
|
||||
return S_OK;
|
||||
}
|
||||
*ppobj = NULL;
|
||||
WARN("IID_IKsPropertySet\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSoundBuffer8, riid ) ) {
|
||||
IDirectSoundBuffer8_AddRef(iface);
|
||||
*ppobj = This;
|
||||
return NO_ERROR;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
|
||||
|
||||
*ppobj = NULL;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
@ -1009,7 +1009,7 @@ HRESULT WINAPI SecondaryBuffer_Create(
|
||||
int use_hw;
|
||||
|
||||
if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) {
|
||||
ERR("invalid parameter: dsbd->dwBufferBytes = %ld\n", dsbd->dwBufferBytes);
|
||||
WARN("invalid parameter: dsbd->dwBufferBytes = %ld\n", dsbd->dwBufferBytes);
|
||||
*pdsb = NULL;
|
||||
return DSERR_INVALIDPARAM; /* FIXME: which error? */
|
||||
}
|
||||
@ -1021,9 +1021,8 @@ HRESULT WINAPI SecondaryBuffer_Create(
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
dsb->ref = 1;
|
||||
dsb->ref = 0;
|
||||
dsb->dsound = This;
|
||||
dsb->parent = NULL;
|
||||
dsb->lpVtbl = &dsbvt;
|
||||
|
||||
memcpy(&dsb->dsbd, dsbd, sizeof(*dsbd));
|
||||
@ -1049,22 +1048,33 @@ HRESULT WINAPI SecondaryBuffer_Create(
|
||||
|
||||
/* Allocate system memory if applicable */
|
||||
if ((This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) {
|
||||
dsb->buffer = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
|
||||
dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
|
||||
if (dsb->buffer == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
|
||||
if (dsb->buffer->memory == NULL) {
|
||||
WARN("out of memory\n");
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the hardware buffer */
|
||||
if (use_hw) {
|
||||
err = IDsDriver_CreateSoundBuffer(This->driver,wfex,dsbd->dwFlags,0,
|
||||
&(dsb->buflen),&(dsb->buffer),
|
||||
&(dsb->buflen),&(dsb->buffer->memory),
|
||||
(LPVOID*)&(dsb->hwbuf));
|
||||
if (err != DS_OK) {
|
||||
WARN("IDsDriver_CreateSoundBuffer failed\n");
|
||||
if (dsb->buffer->memory)
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer->memory);
|
||||
if (dsb->buffer)
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
@ -1087,16 +1097,26 @@ HRESULT WINAPI SecondaryBuffer_Create(
|
||||
dsb->nAvgBytesPerSec = dsb->freq *
|
||||
dsbd->lpwfxFormat->nBlockAlign;
|
||||
|
||||
if (dsbd->dwFlags & DSBCAPS_CTRL3D) {
|
||||
err = IDirectSound3DBufferImpl_Create(dsb, &dsb->ds3db);
|
||||
if (err != DS_OK) {
|
||||
WARN("IDirectSound3DBufferImpl_Create failed\n");
|
||||
if (dsb->buffer)
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
dsb = NULL;
|
||||
return err;
|
||||
}
|
||||
if (dsb->dsbd.dwFlags & DSBCAPS_CTRL3D) {
|
||||
dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
|
||||
dsb->ds3db_ds3db.vPosition.u1.x = 0.0;
|
||||
dsb->ds3db_ds3db.vPosition.u2.y = 0.0;
|
||||
dsb->ds3db_ds3db.vPosition.u3.z = 0.0;
|
||||
dsb->ds3db_ds3db.vVelocity.u1.x = 0.0;
|
||||
dsb->ds3db_ds3db.vVelocity.u2.y = 0.0;
|
||||
dsb->ds3db_ds3db.vVelocity.u3.z = 0.0;
|
||||
dsb->ds3db_ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
|
||||
dsb->ds3db_ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
|
||||
dsb->ds3db_ds3db.vConeOrientation.u1.x = 0.0;
|
||||
dsb->ds3db_ds3db.vConeOrientation.u2.y = 0.0;
|
||||
dsb->ds3db_ds3db.vConeOrientation.u3.z = 0.0;
|
||||
dsb->ds3db_ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME;
|
||||
dsb->ds3db_ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE;
|
||||
dsb->ds3db_ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE;
|
||||
dsb->ds3db_ds3db.dwMode = DS3DMODE_NORMAL;
|
||||
|
||||
dsb->ds3db_need_recalc = FALSE;
|
||||
DSOUND_Calc3DBuffer(dsb);
|
||||
} else
|
||||
DSOUND_RecalcVolPan(&(dsb->volpan));
|
||||
|
||||
@ -1113,12 +1133,14 @@ HRESULT WINAPI SecondaryBuffer_Create(
|
||||
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);
|
||||
if (dsb->buffer->memory)
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer->memory);
|
||||
if (dsb->buffer)
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer);
|
||||
DeleteCriticalSection(&(dsb->lock));
|
||||
RtlReleaseResource(&(This->lock));
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
dsb = NULL;
|
||||
*pdsb = NULL;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -48,8 +48,10 @@
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h> /* Insomnia - pow() function */
|
||||
#include <math.h>
|
||||
|
||||
#define NONAMELESSSTRUCT
|
||||
#define NONAMELESSUNION
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
@ -471,8 +473,12 @@ static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
|
||||
LPDIRECTSOUND8 iface,HWND hwnd,DWORD level
|
||||
) {
|
||||
ICOM_THIS(IDirectSoundImpl,iface);
|
||||
TRACE("(%p,%08lx,%ld)\n",This,(DWORD)hwnd,level);
|
||||
|
||||
FIXME("(%p,%08lx,%ld):stub\n",This,(DWORD)hwnd,level);
|
||||
if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
|
||||
FIXME("level=%s not fully supported\n",
|
||||
level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
|
||||
}
|
||||
|
||||
This->priolevel = level;
|
||||
|
||||
@ -484,7 +490,7 @@ static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
|
||||
) {
|
||||
ICOM_THIS(IDirectSoundImpl,iface);
|
||||
LPWAVEFORMATEX wfex;
|
||||
HRESULT hres;
|
||||
HRESULT hres = DS_OK;
|
||||
|
||||
TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
|
||||
|
||||
@ -522,13 +528,19 @@ static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
|
||||
wfex->wBitsPerSample, wfex->cbSize);
|
||||
|
||||
if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
|
||||
hres = PrimaryBuffer_Create(This, (PrimaryBufferImpl**)ppdsb, dsbd);
|
||||
if (hres != DS_OK)
|
||||
*ppdsb=(LPDIRECTSOUNDBUFFER8)This->primary;
|
||||
if (*ppdsb==NULL)
|
||||
WARN("PrimaryBuffer_Create failed\n");
|
||||
else {
|
||||
This->dsbd = *dsbd;
|
||||
IDirectSoundBuffer_AddRef(*ppdsb);
|
||||
}
|
||||
} else {
|
||||
hres = SecondaryBuffer_Create(This, (IDirectSoundBufferImpl**)ppdsb, dsbd);
|
||||
if (hres != DS_OK)
|
||||
WARN("SecondaryBuffer_Create failed\n");
|
||||
else
|
||||
IDirectSoundBuffer_AddRef(*ppdsb);
|
||||
}
|
||||
|
||||
return hres;
|
||||
@ -577,28 +589,15 @@ static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
IDirectSoundBuffer8_AddRef(pdsb);
|
||||
memcpy(dsb, ipdsb, sizeof(IDirectSoundBufferImpl));
|
||||
dsb->ref = 1;
|
||||
dsb->state = STATE_STOPPED;
|
||||
dsb->playpos = 0;
|
||||
dsb->buf_mixpos = 0;
|
||||
dsb->dsound = This;
|
||||
dsb->parent = ipdsb;
|
||||
dsb->buffer->ref++;
|
||||
dsb->hwbuf = NULL;
|
||||
if (ipdsb->ds3db != NULL) {
|
||||
HRESULT hres;
|
||||
hres = IDirectSound3DBufferImpl_Create(dsb, &(dsb->ds3db));
|
||||
if (hres != DS_OK) {
|
||||
WARN("IDirectSound3DBufferImpl_Create failed\n");
|
||||
} else {
|
||||
IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)(dsb->ds3db));
|
||||
dsb->dsbd.dwFlags |= DSBCAPS_CTRL3D;
|
||||
memcpy(&(dsb->ds3db->ds3db), &(ipdsb->ds3db->ds3db), sizeof(DS3DBUFFER));
|
||||
}
|
||||
} else {
|
||||
dsb->ds3db = NULL;
|
||||
}
|
||||
dsb->iks = NULL; /* FIXME? */
|
||||
memcpy(&(dsb->wfx), &(ipdsb->wfx), sizeof(dsb->wfx));
|
||||
InitializeCriticalSection(&(dsb->lock));
|
||||
@ -689,45 +688,57 @@ static HRESULT WINAPI IDirectSoundImpl_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS lpD
|
||||
|
||||
static ULONG WINAPI IDirectSoundImpl_AddRef(LPDIRECTSOUND8 iface) {
|
||||
ICOM_THIS(IDirectSoundImpl,iface);
|
||||
TRACE("(%p) ref was %ld\n", This, This->ref);
|
||||
return ++(This->ref);
|
||||
TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
|
||||
return InterlockedIncrement(&This->ref);
|
||||
}
|
||||
|
||||
static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) {
|
||||
HRESULT hres;
|
||||
ICOM_THIS(IDirectSoundImpl,iface);
|
||||
TRACE("(%p), ref was %ld\n",This,This->ref);
|
||||
if (!--(This->ref)) {
|
||||
ULONG ulReturn;
|
||||
|
||||
TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
|
||||
ulReturn = InterlockedDecrement(&This->ref);
|
||||
|
||||
if (ulReturn == 0) {
|
||||
HRESULT hres;
|
||||
UINT i;
|
||||
|
||||
timeKillEvent(This->timerID);
|
||||
timeEndPeriod(DS_TIME_RES);
|
||||
/* wait for timer to expire */
|
||||
Sleep(DS_TIME_RES+1);
|
||||
|
||||
RtlAcquireResourceShared(&(This->lock), TRUE);
|
||||
|
||||
if (This->buffers) {
|
||||
for( i=0;i<This->nrofbuffers;i++)
|
||||
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
|
||||
}
|
||||
|
||||
RtlReleaseResource(&(This->lock));
|
||||
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
|
||||
|
||||
hres = DSOUND_PrimaryDestroy(This);
|
||||
if (hres != DS_OK)
|
||||
WARN("DSOUND_PrimaryDestroy failed\n");
|
||||
|
||||
RtlDeleteResource(&This->lock);
|
||||
DeleteCriticalSection(&This->mixlock);
|
||||
if (This->driver) {
|
||||
if (This->driver)
|
||||
IDsDriver_Close(This->driver);
|
||||
}
|
||||
if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) {
|
||||
|
||||
if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
|
||||
waveOutClose(This->hwo);
|
||||
}
|
||||
|
||||
if (This->driver)
|
||||
IDsDriver_Release(This->driver);
|
||||
|
||||
RtlDeleteResource(&This->lock);
|
||||
DeleteCriticalSection(&This->mixlock);
|
||||
DeleteCriticalSection(&This->ds3dl_lock);
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
dsound = NULL;
|
||||
return 0;
|
||||
}
|
||||
return This->ref;
|
||||
return ulReturn;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
|
||||
@ -742,14 +753,24 @@ static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
|
||||
LPDIRECTSOUND8 iface,REFIID riid,LPVOID *ppobj
|
||||
) {
|
||||
ICOM_THIS(IDirectSoundImpl,iface);
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
|
||||
ERR("app requested IDirectSound3DListener on dsound object\n");
|
||||
*ppobj = NULL;
|
||||
return E_FAIL;
|
||||
*ppobj = NULL; /* assume failure */
|
||||
|
||||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSound) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSound8) ) {
|
||||
IDirectSound8_AddRef((LPDIRECTSOUND8)This);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FIXME("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
|
||||
WARN("app requested IDirectSound3DListener on dsound object\n");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
@ -927,7 +948,28 @@ HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown
|
||||
(*ippDS)->state = STATE_STOPPED;
|
||||
(*ippDS)->nrofbuffers = 0;
|
||||
(*ippDS)->buffers = NULL;
|
||||
(*ippDS)->primary = NULL;
|
||||
|
||||
/* 3D listener initial parameters */
|
||||
(*ippDS)->listener = NULL;
|
||||
(*ippDS)->ds3dl.dwSize = sizeof(DS3DLISTENER);
|
||||
(*ippDS)->ds3dl.vPosition.u1.x = 0.0;
|
||||
(*ippDS)->ds3dl.vPosition.u2.y = 0.0;
|
||||
(*ippDS)->ds3dl.vPosition.u3.z = 0.0;
|
||||
(*ippDS)->ds3dl.vVelocity.u1.x = 0.0;
|
||||
(*ippDS)->ds3dl.vVelocity.u2.y = 0.0;
|
||||
(*ippDS)->ds3dl.vVelocity.u3.z = 0.0;
|
||||
(*ippDS)->ds3dl.vOrientFront.u1.x = 0.0;
|
||||
(*ippDS)->ds3dl.vOrientFront.u2.y = 0.0;
|
||||
(*ippDS)->ds3dl.vOrientFront.u3.z = 1.0;
|
||||
(*ippDS)->ds3dl.vOrientTop.u1.x = 0.0;
|
||||
(*ippDS)->ds3dl.vOrientTop.u2.y = 1.0;
|
||||
(*ippDS)->ds3dl.vOrientTop.u3.z = 0.0;
|
||||
(*ippDS)->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
|
||||
(*ippDS)->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
|
||||
(*ippDS)->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
|
||||
|
||||
InitializeCriticalSection(&(*ippDS)->ds3dl_lock);
|
||||
|
||||
(*ippDS)->prebuf = ds_snd_queue_max;
|
||||
(*ippDS)->guid = devGuid;
|
||||
@ -1064,7 +1106,14 @@ HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown
|
||||
dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
|
||||
(DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
|
||||
}
|
||||
return DS_OK;
|
||||
|
||||
/* 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);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,12 +80,26 @@ struct IDirectSoundImpl
|
||||
BOOL need_remix;
|
||||
int nrofbuffers;
|
||||
IDirectSoundBufferImpl** buffers;
|
||||
IDirectSound3DListenerImpl* listener;
|
||||
RTL_RWLOCK lock;
|
||||
CRITICAL_SECTION mixlock;
|
||||
DSVOLUMEPAN volpan;
|
||||
PrimaryBufferImpl* primary;
|
||||
DSBUFFERDESC dsbd;
|
||||
|
||||
/* DirectSound3DListener fields */
|
||||
IDirectSound3DListenerImpl* listener;
|
||||
DS3DLISTENER ds3dl;
|
||||
CRITICAL_SECTION ds3dl_lock;
|
||||
BOOL ds3dl_need_recalc;
|
||||
};
|
||||
|
||||
/* reference counted buffer memory for duplicated buffer memory */
|
||||
typedef struct BufferMemory
|
||||
{
|
||||
DWORD ref;
|
||||
LPBYTE memory;
|
||||
} BufferMemory;
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirectSoundBuffer implementation structure
|
||||
*/
|
||||
@ -97,13 +111,12 @@ struct IDirectSoundBufferImpl
|
||||
DWORD ref;
|
||||
/* IDirectSoundBufferImpl fields */
|
||||
IDirectSoundImpl* dsound;
|
||||
IDirectSoundBufferImpl* parent; /* for duplicates */
|
||||
IDirectSound3DBufferImpl* ds3db;
|
||||
IKsPropertySetImpl* iks;
|
||||
CRITICAL_SECTION lock;
|
||||
PIDSDRIVERBUFFER hwbuf;
|
||||
WAVEFORMATEX wfx;
|
||||
LPBYTE buffer;
|
||||
BufferMemory* buffer;
|
||||
DWORD playflags,state,leadin;
|
||||
DWORD playpos,startpos,writelead,buflen;
|
||||
DWORD nAvgBytesPerSec;
|
||||
@ -117,7 +130,12 @@ struct IDirectSoundBufferImpl
|
||||
DWORD primary_mixpos, buf_mixpos;
|
||||
BOOL need_remix;
|
||||
/* IDirectSoundNotifyImpl fields */
|
||||
IDirectSoundNotifyImpl *notify;
|
||||
IDirectSoundNotifyImpl* notify;
|
||||
|
||||
/* DirectSound3DBuffer fields */
|
||||
DS3DBUFFER ds3db_ds3db;
|
||||
LONG ds3db_lVolume;
|
||||
BOOL ds3db_need_recalc;
|
||||
};
|
||||
|
||||
HRESULT WINAPI SecondaryBuffer_Create(
|
||||
@ -129,7 +147,6 @@ struct PrimaryBufferImpl {
|
||||
ICOM_VFIELD(IDirectSoundBuffer8);
|
||||
DWORD ref;
|
||||
IDirectSoundImpl* dsound;
|
||||
DSBUFFERDESC dsbd;
|
||||
};
|
||||
|
||||
HRESULT WINAPI PrimaryBuffer_Create(
|
||||
@ -190,7 +207,7 @@ struct IDirectSoundCaptureBufferImpl
|
||||
LPDSCBUFFERDESC pdscbd;
|
||||
DWORD flags;
|
||||
/* IDirectSoundNotifyImpl fields */
|
||||
IDirectSoundNotifyImpl *notify;
|
||||
IDirectSoundNotifyImpl* notify;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
@ -230,10 +247,7 @@ struct IDirectSound3DListenerImpl
|
||||
ICOM_VFIELD(IDirectSound3DListener);
|
||||
DWORD ref;
|
||||
/* IDirectSound3DListenerImpl fields */
|
||||
PrimaryBufferImpl* dsb;
|
||||
DS3DLISTENER ds3dl;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL need_recalc;
|
||||
IDirectSoundImpl* dsound;
|
||||
};
|
||||
|
||||
HRESULT WINAPI IDirectSound3DListenerImpl_Create(
|
||||
@ -266,10 +280,7 @@ struct IDirectSound3DBufferImpl
|
||||
DWORD ref;
|
||||
/* IDirectSound3DBufferImpl fields */
|
||||
IDirectSoundBufferImpl* dsb;
|
||||
DS3DBUFFER ds3db;
|
||||
LONG lVolume;
|
||||
CRITICAL_SECTION lock;
|
||||
BOOL need_recalc;
|
||||
};
|
||||
|
||||
HRESULT WINAPI IDirectSound3DBufferImpl_Create(
|
||||
@ -302,6 +313,10 @@ void DSOUND_PerformMix(void);
|
||||
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
|
||||
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
|
||||
|
||||
/* sound3d.c */
|
||||
|
||||
void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
|
||||
|
||||
#define STATE_STOPPED 0
|
||||
#define STATE_STARTING 1
|
||||
#define STATE_PLAYING 2
|
||||
@ -313,12 +328,6 @@ void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, D
|
||||
extern IDirectSoundImpl* dsound;
|
||||
extern IDirectSoundCaptureImpl* dsound_capture;
|
||||
|
||||
struct PrimaryBuffer {
|
||||
DWORD ref;
|
||||
PIDSDRIVERBUFFER hwbuf;
|
||||
DWORD state;
|
||||
};
|
||||
|
||||
extern ICOM_VTABLE(IDirectSoundNotify) dsnvt;
|
||||
extern HRESULT mmErr(UINT err);
|
||||
extern void setup_dsound_options(void);
|
||||
|
@ -50,6 +50,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
||||
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
|
||||
{
|
||||
double temp;
|
||||
TRACE("(%p)\n",volpan);
|
||||
|
||||
/* the AmpFactors are expressed in 16.16 fixed point */
|
||||
volpan->dwVolAmpFactor = (ULONG) (pow(2.0, volpan->lVolume / 600.0) * 65536);
|
||||
@ -190,7 +191,7 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
||||
INT iAdvance = dsb->wfx.nBlockAlign;
|
||||
INT oAdvance = dsb->dsound->wfx.nBlockAlign;
|
||||
|
||||
ibp = dsb->buffer + dsb->buf_mixpos;
|
||||
ibp = dsb->buffer->memory + dsb->buf_mixpos;
|
||||
obp = buf;
|
||||
|
||||
TRACE("(%p, %p, %p), buf_mixpos=%ld\n", dsb, ibp, obp, dsb->buf_mixpos);
|
||||
@ -204,7 +205,7 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
||||
memcpy(obp, ibp, len);
|
||||
else { /* wrap */
|
||||
memcpy(obp, ibp, bytesleft );
|
||||
memcpy(obp + bytesleft, dsb->buffer, len - bytesleft);
|
||||
memcpy(obp + bytesleft, dsb->buffer->memory, len - bytesleft);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -219,8 +220,8 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
||||
ibp += iAdvance;
|
||||
ilen += iAdvance;
|
||||
obp += oAdvance;
|
||||
if (ibp >= (BYTE *)(dsb->buffer + dsb->buflen))
|
||||
ibp = dsb->buffer; /* wrap */
|
||||
if (ibp >= (BYTE *)(dsb->buffer->memory + dsb->buflen))
|
||||
ibp = dsb->buffer->memory; /* wrap */
|
||||
}
|
||||
return (ilen);
|
||||
}
|
||||
@ -240,7 +241,7 @@ static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
|
||||
ilen = 0;
|
||||
ipos = dsb->buf_mixpos;
|
||||
for (i = 0; i < size; i++) {
|
||||
cp_fields(dsb, (dsb->buffer + ipos), obp);
|
||||
cp_fields(dsb, (dsb->buffer->memory + ipos), obp);
|
||||
obp += oAdvance;
|
||||
dsb->freqAcc += dsb->freqAdjust;
|
||||
if (dsb->freqAcc >= (1<<DSOUND_FREQSHIFT)) {
|
||||
@ -380,7 +381,8 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
|
||||
|
||||
ilen = DSOUND_MixerNorm(dsb, ibuf, len);
|
||||
if ((dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) ||
|
||||
(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME))
|
||||
(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) ||
|
||||
(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
|
||||
DSOUND_MixerVol(dsb, ibuf, len);
|
||||
|
||||
obuf = dsb->dsound->buffer + writepos;
|
||||
@ -450,7 +452,8 @@ static void DSOUND_PhaseCancel(IDirectSoundBufferImpl *dsb, DWORD writepos, DWOR
|
||||
|
||||
ilen = DSOUND_MixerNorm(dsb, ibuf, len);
|
||||
if ((dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) ||
|
||||
(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME))
|
||||
(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) ||
|
||||
(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
|
||||
DSOUND_MixerVol(dsb, ibuf, len);
|
||||
|
||||
/* subtract instead of add, to phase out premixed data */
|
||||
@ -844,21 +847,12 @@ void DSOUND_PerformMix(void)
|
||||
|
||||
TRACE("()\n");
|
||||
|
||||
RtlAcquireResourceShared(&(dsound->lock), TRUE);
|
||||
|
||||
if (!dsound || !dsound->ref) {
|
||||
/* seems the dsound object is currently being released */
|
||||
RtlReleaseResource(&(dsound->lock));
|
||||
return;
|
||||
}
|
||||
|
||||
/* the sound of silence */
|
||||
nfiller = dsound->wfx.wBitsPerSample == 8 ? 128 : 0;
|
||||
|
||||
/* whether the primary is forced to play even without secondary buffers */
|
||||
forced = ((dsound->state == STATE_PLAYING) || (dsound->state == STATE_STARTING));
|
||||
|
||||
TRACE("entering at %ld\n", GetTickCount());
|
||||
if (dsound->priolevel != DSSCL_WRITEPRIMARY) {
|
||||
BOOL paused = ((dsound->state == STATE_STOPPED) || (dsound->state == STATE_STARTING));
|
||||
/* FIXME: document variables */
|
||||
@ -866,7 +860,7 @@ void DSOUND_PerformMix(void)
|
||||
if (dsound->hwbuf) {
|
||||
hres = IDsDriverBuffer_GetPosition(dsound->hwbuf, &playpos, &writepos);
|
||||
if (hres) {
|
||||
RtlReleaseResource(&(dsound->lock));
|
||||
WARN("IDsDriverBuffer_GetPosition failed\n");
|
||||
return;
|
||||
}
|
||||
/* Well, we *could* do Just-In-Time mixing using the writepos,
|
||||
@ -954,7 +948,7 @@ void DSOUND_PerformMix(void)
|
||||
hres = IDsDriverBuffer_GetPosition(dsound->hwbuf, &playpos, NULL);
|
||||
if (hres) {
|
||||
LeaveCriticalSection(&(dsound->mixlock));
|
||||
RtlReleaseResource(&(dsound->lock));
|
||||
WARN("IDsDriverBuffer_GetPosition failed\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@ -1012,12 +1006,13 @@ void DSOUND_PerformMix(void)
|
||||
dsound->state = STATE_STOPPED;
|
||||
}
|
||||
}
|
||||
TRACE("completed processing at %ld\n", GetTickCount());
|
||||
RtlReleaseResource(&(dsound->lock));
|
||||
}
|
||||
|
||||
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
|
||||
{
|
||||
TRACE("(%d,%d,0x%lx,0x%lx,0x%lx)\n",timerID,msg,dwUser,dw1,dw2);
|
||||
TRACE("entering at %ld\n", GetTickCount());
|
||||
|
||||
if (!dsound) {
|
||||
ERR("dsound died without killing us?\n");
|
||||
timeKillEvent(timerID);
|
||||
@ -1025,8 +1020,15 @@ void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWOR
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE("entered\n");
|
||||
RtlAcquireResourceShared(&(dsound->lock), TRUE);
|
||||
|
||||
if (dsound->ref) {
|
||||
DSOUND_PerformMix();
|
||||
}
|
||||
|
||||
RtlReleaseResource(&(dsound->lock));
|
||||
|
||||
TRACE("completed processing at %ld\n", GetTickCount());
|
||||
}
|
||||
|
||||
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
|
||||
|
@ -430,7 +430,7 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
|
||||
TRACE("(%p,%ld)\n",This,vol);
|
||||
|
||||
/* I'm not sure if we need this for primary buffer */
|
||||
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
|
||||
if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
|
||||
WARN("control unavailable\n");
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
}
|
||||
@ -480,6 +480,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
TRACE("(%p,%p)\n",This,vol);
|
||||
|
||||
if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
|
||||
WARN("control unavailable\n");
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
}
|
||||
|
||||
if (vol == NULL) {
|
||||
WARN("invalid parameter: vol = NULL\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
@ -555,29 +560,21 @@ static DWORD WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) {
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
DWORD ref;
|
||||
|
||||
TRACE("(%p) ref was %ld, thread is %lx\n",This, This->ref, GetCurrentThreadId());
|
||||
|
||||
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 PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) {
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
DWORD ref;
|
||||
|
||||
TRACE("(%p) ref was %ld, thread is %lx\n",This, This->ref, GetCurrentThreadId());
|
||||
|
||||
TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (ref == 0) {
|
||||
IDirectSound_Release((LPDIRECTSOUND)This->dsound);
|
||||
|
||||
if (This->dsound->listener) {
|
||||
IDirectSound3DListener_Release((LPDIRECTSOUND3DLISTENER)This->dsound->listener);
|
||||
This->dsound->listener = NULL;
|
||||
}
|
||||
if (ref == -1) {
|
||||
This->dsound->primary = NULL;
|
||||
HeapFree(GetProcessHeap(),0,This);
|
||||
}
|
||||
|
||||
@ -611,7 +608,7 @@ static HRESULT WINAPI PrimaryBufferImpl_GetStatus(
|
||||
LPDIRECTSOUNDBUFFER8 iface,LPDWORD status
|
||||
) {
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
TRACE("(%p,%p), thread is %lx\n",This,status,GetCurrentThreadId());
|
||||
TRACE("(%p,%p), thread is %04lx\n",This,status,GetCurrentThreadId());
|
||||
|
||||
if (status == NULL) {
|
||||
WARN("invalid parameter: status == NULL\n");
|
||||
@ -812,6 +809,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
|
||||
WARN("control unavailable\n");
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
}
|
||||
|
||||
*freq = This->dsound->wfx.nSamplesPerSec;
|
||||
TRACE("-> %ld\n", *freq);
|
||||
|
||||
@ -885,7 +887,7 @@ static HRESULT WINAPI PrimaryBufferImpl_GetCaps(
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
caps->dwFlags = This->dsbd.dwFlags;
|
||||
caps->dwFlags = This->dsound->dsbd.dwFlags;
|
||||
if (This->dsound->hwbuf) caps->dwFlags |= DSBCAPS_LOCHARDWARE;
|
||||
else caps->dwFlags |= DSBCAPS_LOCSOFTWARE;
|
||||
|
||||
@ -905,56 +907,58 @@ static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(
|
||||
LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj
|
||||
) {
|
||||
ICOM_THIS(PrimaryBufferImpl,iface);
|
||||
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
|
||||
|
||||
*ppobj = NULL; /* assume failure */
|
||||
|
||||
if ( IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
|
||||
IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)This);
|
||||
*ppobj = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* DirectSoundBuffer and DirectSoundBuffer8 are different and */
|
||||
/* a primary buffer can't have a DirectSoundBuffer8 interface */
|
||||
if ( IsEqualGUID( &IID_IDirectSoundBuffer8, riid ) ) {
|
||||
WARN("app requested DirectSoundBuffer8 on primary buffer\n");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
|
||||
ERR("app requested IDirectSoundNotify on primary buffer\n");
|
||||
/* FIXME: should we support this? */
|
||||
*ppobj = NULL;
|
||||
return E_FAIL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
|
||||
ERR("app requested IDirectSound3DBuffer on primary buffer\n");
|
||||
*ppobj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
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) {
|
||||
IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj);
|
||||
return DS_OK;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
WARN("IID_IDirectSound3DListener failed\n");
|
||||
*ppobj = NULL;
|
||||
return E_FAIL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
|
||||
#if 0
|
||||
if (!This->iks)
|
||||
IKsPropertySetImpl_Create(This, &This->iks);
|
||||
*ppobj = This->iks;
|
||||
if (*ppobj) {
|
||||
IKsPropertySet_AddRef((LPKSPROPERTYSET)*ppobj);
|
||||
return S_OK;
|
||||
}
|
||||
return E_FAIL;
|
||||
#else
|
||||
FIXME("app requested IKsPropertySet on primary buffer\n");
|
||||
*ppobj = NULL;
|
||||
return E_FAIL;
|
||||
#endif
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
|
||||
|
||||
*ppobj = NULL;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
@ -1010,11 +1014,11 @@ HRESULT WINAPI PrimaryBuffer_Create(
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
dsb->ref = 1;
|
||||
dsb->ref = -1;
|
||||
dsb->dsound = This;
|
||||
dsb->lpVtbl = &dspbvt;
|
||||
|
||||
memcpy(&dsb->dsbd, dsbd, sizeof(*dsbd));
|
||||
memcpy(&This->dsbd, dsbd, sizeof(*dsbd));
|
||||
|
||||
TRACE("Created primary buffer at %p\n", dsb);
|
||||
TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
|
||||
@ -1023,18 +1027,6 @@ HRESULT WINAPI PrimaryBuffer_Create(
|
||||
This->wfx.nAvgBytesPerSec, This->wfx.nBlockAlign,
|
||||
This->wfx.wBitsPerSample, This->wfx.cbSize);
|
||||
|
||||
if (dsbd->dwFlags & DSBCAPS_CTRL3D) {
|
||||
HRESULT hres;
|
||||
hres = IDirectSound3DListenerImpl_Create(dsb, &This->listener);
|
||||
if (hres != DS_OK) {
|
||||
WARN("IDirectSound3DListenerImpl_Create failed\n");
|
||||
} else {
|
||||
IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)This->listener);
|
||||
}
|
||||
}
|
||||
|
||||
IDirectSound8_AddRef((LPDIRECTSOUND8)This);
|
||||
|
||||
*pdsb = dsb;
|
||||
return S_OK;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,10 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define NONAMELESSSTRUCT
|
||||
#define NONAMELESSUNION
|
||||
#include <windows.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -26,6 +30,10 @@
|
||||
#include "initguid.h"
|
||||
#include "dsound.h"
|
||||
|
||||
#ifndef DSBCAPS_CTRLDEFAULT
|
||||
#define DSBCAPS_CTRLDEFAULT 0x000000E0
|
||||
#endif
|
||||
|
||||
static const unsigned int formats[][3]={
|
||||
{ 8000, 8, 1},
|
||||
{ 8000, 8, 2},
|
||||
@ -250,14 +258,23 @@ STOP:
|
||||
}
|
||||
|
||||
static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
int primary, int play)
|
||||
int is_primary, int play, int buffer3d,
|
||||
LPDIRECTSOUND3DLISTENER listener,
|
||||
int move_listener, int move_sound)
|
||||
{
|
||||
HRESULT rc;
|
||||
DSBCAPS dsbcaps;
|
||||
WAVEFORMATEX wfx,wfx2;
|
||||
DWORD size,status,freq;
|
||||
int ref;
|
||||
|
||||
dsbcaps.dwSize=0;
|
||||
/* DSOUND: Error: Invalid caps pointer */
|
||||
rc=IDirectSoundBuffer_GetCaps(dsbo,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
|
||||
|
||||
ZeroMemory(&dsbcaps, sizeof(dsbcaps));
|
||||
|
||||
/* DSOUND: Error: Invalid caps pointer */
|
||||
rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
|
||||
ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
|
||||
|
||||
@ -284,21 +301,42 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
|
||||
}
|
||||
|
||||
/* DSOUND: Error: Invalid frequency buffer */
|
||||
rc=IDirectSoundBuffer_GetFrequency(dsbo,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"GetFrequency should have failed: 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
|
||||
rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq);
|
||||
ok(rc==DS_OK || rc==DSERR_CONTROLUNAVAIL,"GetFrequency failed: 0x%lx\n",rc);
|
||||
ok((rc==DS_OK&&!is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary),
|
||||
"GetFrequency failed: 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
ok(freq==wfx.nSamplesPerSec,
|
||||
"The frequency returned by GetFrequency %ld does not match the format %ld\n",
|
||||
freq,wfx.nSamplesPerSec);
|
||||
}
|
||||
|
||||
/* DSOUND: Error: Invalid status pointer */
|
||||
rc=IDirectSoundBuffer_GetStatus(dsbo,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"GetStatus should have failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
|
||||
ok(rc==DS_OK,"GetStatus failed: 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
trace(" status=0x%04lx\n",status);
|
||||
}
|
||||
|
||||
if (primary) {
|
||||
if (is_primary) {
|
||||
/* We must call SetCooperativeLevel to be allowed to call SetFormat */
|
||||
/* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
|
||||
rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
|
||||
ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
|
||||
if(rc!=DS_OK)
|
||||
return;
|
||||
|
||||
/* DSOUND: Error: Invalid format pointer */
|
||||
rc=IDirectSoundBuffer_SetFormat(dsbo,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"SetFormat should have failed: 0x%lx\n",rc);
|
||||
|
||||
init_format(&wfx2,11025,16,2);
|
||||
rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2);
|
||||
ok(rc==DS_OK,"SetFormat failed: 0x%lx\n",rc);
|
||||
@ -314,15 +352,66 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
|
||||
wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
|
||||
}
|
||||
|
||||
/* Set the CooperativeLevel back to normal */
|
||||
/* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
|
||||
rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
|
||||
ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
|
||||
}
|
||||
|
||||
if (play) {
|
||||
play_state_t state;
|
||||
LONG volume;
|
||||
|
||||
trace(" Playing 440Hz LA at %ldx%2dx%d\n",
|
||||
LPDIRECTSOUND3DBUFFER buffer=NULL;
|
||||
DS3DBUFFER buffer_param;
|
||||
DS3DLISTENER listener_param;
|
||||
trace(" Playing 440Hz LA at %ldx%dx%d\n",
|
||||
wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels);
|
||||
|
||||
if (is_primary) {
|
||||
/* We must call SetCooperativeLevel to be allowed to call Lock */
|
||||
/* DSOUND: Setting DirectSound cooperative level to DSSCL_WRITEPRIMARY */
|
||||
rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_WRITEPRIMARY);
|
||||
ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
|
||||
if (rc!=DS_OK)
|
||||
return;
|
||||
}
|
||||
if (buffer3d) {
|
||||
LPDIRECTSOUNDBUFFER temp_buffer;
|
||||
|
||||
rc=IDirectSoundBuffer_QueryInterface(dsbo,&IID_IDirectSound3DBuffer,(LPVOID *)&buffer);
|
||||
ok(rc==DS_OK,"QueryInterface failed: 0x%lx\n",rc);
|
||||
if(rc!=DS_OK)
|
||||
return;
|
||||
|
||||
/* check the COM interface */
|
||||
rc=IDirectSoundBuffer_QueryInterface(dsbo, &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
|
||||
ok(rc==DS_OK&&temp_buffer!=NULL,"QueryInterface failed: 0x%lx\n",rc);
|
||||
ok(temp_buffer==dsbo,"COM interface broken: 0x%08lx != 0x%08lx\n",(DWORD)temp_buffer,(DWORD)dsbo);
|
||||
ref=IDirectSoundBuffer_Release(temp_buffer);
|
||||
ok(ref==1,"IDirectSoundBuffer_Release has %d references, should have 1\n",ref);
|
||||
|
||||
temp_buffer=NULL;
|
||||
rc=IDirectSound3DBuffer_QueryInterface(dsbo, &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
|
||||
ok(rc==DS_OK&&temp_buffer!=NULL,"IDirectSound3DBuffer_QueryInterface failed: 0x%lx\n",rc);
|
||||
ok(temp_buffer==dsbo,"COM interface broken: 0x%08lx != 0x%08lx\n",(DWORD)temp_buffer,(DWORD)dsbo);
|
||||
ref=IDirectSoundBuffer_Release(temp_buffer);
|
||||
ok(ref==1,"IDirectSoundBuffer_Release has %d references, should have 1\n",ref);
|
||||
|
||||
/* DSOUND: Error: Invalid buffer */
|
||||
rc=IDirectSound3DBuffer_GetAllParameters(buffer,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters failed: 0x%lx\n",rc);
|
||||
|
||||
ZeroMemory(&buffer_param, sizeof(buffer_param));
|
||||
|
||||
/* DSOUND: Error: Invalid buffer */
|
||||
rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters failed: 0x%lx\n",rc);
|
||||
|
||||
buffer_param.dwSize=sizeof(buffer_param);
|
||||
rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
|
||||
ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters failed: 0x%lx\n",rc);
|
||||
}
|
||||
if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
ok(rc==DS_OK,"GetVolume failed: 0x%lx\n",rc);
|
||||
@ -330,8 +419,10 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
rc=IDirectSoundBuffer_SetVolume(dsbo,-300);
|
||||
ok(rc==DS_OK,"SetVolume failed: 0x%lx\n",rc);
|
||||
}
|
||||
|
||||
/* DSOUND: Error: Buffer does not have CTRLVOLUME */
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
ok(rc==DS_OK,"GetVolume failed: 0x%lx\n",rc);
|
||||
ok((rc==DS_OK&&!is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary),"GetVolume failed: 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
trace(" volume=%ld\n",volume);
|
||||
}
|
||||
@ -352,8 +443,45 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING),
|
||||
"GetStatus: bad status: %lx",status);
|
||||
|
||||
/* FIXME: set position here someday */
|
||||
if (listener) {
|
||||
ZeroMemory(&listener_param,sizeof(listener_param));
|
||||
listener_param.dwSize=sizeof(listener_param);
|
||||
rc=IDirectSound3DListener_GetAllParameters(listener,&listener_param);
|
||||
ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters failed 0x%lx\n",rc);
|
||||
if (move_listener)
|
||||
listener_param.vPosition.u1.x = -5.0;
|
||||
else
|
||||
listener_param.vPosition.u1.x = 0.0;
|
||||
listener_param.vPosition.u2.y = 0.0;
|
||||
listener_param.vPosition.u3.z = 0.0;
|
||||
rc=IDirectSound3DListener_SetPosition(listener,listener_param.vPosition.u1.x,listener_param.vPosition.u2.y,listener_param.vPosition.u3.z,DS3D_IMMEDIATE);
|
||||
ok(rc==DS_OK,"IDirectSound3dListener_SetPosition failed 0x%lx\n",rc);
|
||||
}
|
||||
if (buffer3d) {
|
||||
if (move_sound)
|
||||
buffer_param.vPosition.u1.x = 5.0;
|
||||
else
|
||||
buffer_param.vPosition.u1.x = 0.0;
|
||||
buffer_param.vPosition.u2.y = 0.0;
|
||||
buffer_param.vPosition.u3.z = 0.0;
|
||||
rc=IDirectSound3DBuffer_SetPosition(buffer,buffer_param.vPosition.u1.x,buffer_param.vPosition.u2.y,buffer_param.vPosition.u3.z,DS3D_IMMEDIATE);
|
||||
ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition failed 0x%lx\n",rc);
|
||||
}
|
||||
|
||||
while (buffer_service(&state)) {
|
||||
WaitForSingleObject(GetCurrentProcess(),TIME_SLICE/2);
|
||||
/* FIXME: move positions here someday */
|
||||
if (listener&&move_listener) {
|
||||
listener_param.vPosition.u1.x += 0.5;
|
||||
rc=IDirectSound3DListener_SetPosition(listener,listener_param.vPosition.u1.x,listener_param.vPosition.u2.y,listener_param.vPosition.u3.z,DS3D_IMMEDIATE);
|
||||
ok(rc==DS_OK,"IDirectSound3dListener_SetPosition failed 0x%lx\n",rc);
|
||||
}
|
||||
if (buffer3d&&move_sound) {
|
||||
buffer_param.vPosition.u1.x -= 0.5;
|
||||
rc=IDirectSound3DBuffer_SetPosition(buffer,buffer_param.vPosition.u1.x,buffer_param.vPosition.u2.y,buffer_param.vPosition.u3.z,DS3D_IMMEDIATE);
|
||||
ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition failed 0x%lx\n",rc);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
|
||||
@ -362,6 +490,119 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
}
|
||||
|
||||
free(state.wave);
|
||||
if (is_primary) {
|
||||
/* Set the CooperativeLevel back to normal */
|
||||
/* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
|
||||
rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
|
||||
ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
|
||||
}
|
||||
if (buffer3d) {
|
||||
ref=IDirectSound3DBuffer_Release(buffer);
|
||||
ok(ref==0,"IDirectSound3DBuffer_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_secondary(LPDIRECTSOUND dso,
|
||||
int play, int has_3dbuffer,
|
||||
int has_listener, int has_duplicate,
|
||||
int move_listener, int move_sound)
|
||||
{
|
||||
HRESULT rc;
|
||||
LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
|
||||
LPDIRECTSOUND3DLISTENER listener=NULL;
|
||||
DSBUFFERDESC bufdesc;
|
||||
WAVEFORMATEX wfx;
|
||||
int f,ref;
|
||||
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
if (has_listener) {
|
||||
rc=IDirectSoundBuffer_QueryInterface(primary,&IID_IDirectSound3DListener,(void **)&listener);
|
||||
ok(rc==DS_OK&&listener!=NULL,"IDirectSoundBuffer_QueryInterface failed to get a 3D listener 0x%lx\n",rc);
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
if(rc==DS_OK&&listener!=NULL) {
|
||||
DS3DLISTENER listener_param;
|
||||
ZeroMemory(&listener_param,sizeof(listener_param));
|
||||
/* DSOUND: Error: Invalid buffer */
|
||||
rc=IDirectSound3DListener_GetAllParameters(listener,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound3dListener_GetAllParameters failed 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Invalid buffer */
|
||||
rc=IDirectSound3DListener_GetAllParameters(listener,&listener_param);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound3dListener_GetAllParameters failed 0x%lx\n",rc);
|
||||
|
||||
listener_param.dwSize=sizeof(listener_param);
|
||||
rc=IDirectSound3DListener_GetAllParameters(listener,&listener_param);
|
||||
ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters failed 0x%lx\n",rc);
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
||||
for (f=0;f<NB_FORMATS;f++) {
|
||||
init_format(&wfx,formats[f][0],formats[f][1],formats[f][2]);
|
||||
secondary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRL3D;
|
||||
bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
|
||||
bufdesc.lpwfxFormat=&wfx;
|
||||
trace(" Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d\n",
|
||||
has_3dbuffer?"3D ":"",
|
||||
has_duplicate?"duplicated ":"",
|
||||
listener!=NULL||move_sound?"with ":"",
|
||||
move_listener?"moving ":"",
|
||||
listener!=NULL?"listener ":"",
|
||||
listener&&move_sound?"and moving sound ":move_sound?"moving sound ":"",
|
||||
wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
|
||||
ok(rc==DS_OK&&secondary!=NULL,"CreateSoundBuffer failed to create a 3D secondary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&secondary!=NULL) {
|
||||
if (has_duplicate) {
|
||||
LPDIRECTSOUNDBUFFER duplicated=NULL;
|
||||
|
||||
/* DSOUND: Error: Invalid source buffer */
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,0,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Invalid dest buffer */
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Invalid source buffer */
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed 0x%lx\n",rc);
|
||||
|
||||
duplicated=NULL;
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,&duplicated);
|
||||
ok(rc==DS_OK&&duplicated!=NULL,"IDirectSound_DuplicateSoundBuffer failed to duplicate a secondary buffer 0x%lx\n",rc);
|
||||
|
||||
if (rc==DS_OK&&duplicated!=NULL) {
|
||||
ref=IDirectSoundBuffer_Release(secondary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release secondary has %d references, should have 0\n",ref);
|
||||
secondary=duplicated;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc==DS_OK&&secondary!=NULL) {
|
||||
test_buffer(dso,secondary,0,winetest_interactive,has_3dbuffer,listener,move_listener,move_sound);
|
||||
ref=IDirectSoundBuffer_Release(secondary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release %s has %d references, should have 0\n",has_duplicate?"duplicated":"secondary",ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has_listener) {
|
||||
ref=IDirectSound3DListener_Release(listener);
|
||||
ok(ref==0,"IDirectSound3dListener_Release listener has %d references, should have 0\n",ref);
|
||||
} else {
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,23 +611,36 @@ static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
{
|
||||
HRESULT rc;
|
||||
LPDIRECTSOUND dso=NULL;
|
||||
LPDIRECTSOUNDBUFFER dsbo=NULL;
|
||||
LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL,duplicated=NULL;
|
||||
DSBUFFERDESC bufdesc;
|
||||
WAVEFORMATEX wfx;
|
||||
DSCAPS dscaps;
|
||||
int f,ref;
|
||||
|
||||
trace("Testing %s - %s\n",lpcstrDescription,lpcstrModule);
|
||||
|
||||
/* DSOUND: Error: Invalid interface buffer */
|
||||
rc=DirectSoundCreate(lpGuid,0,NULL);
|
||||
ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: 0x%lx\n",rc);
|
||||
|
||||
rc=DirectSoundCreate(lpGuid,&dso,NULL);
|
||||
ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
|
||||
if (rc!=DS_OK)
|
||||
goto EXIT;
|
||||
|
||||
dscaps.dwSize=0;
|
||||
/* DSOUND: Error: Invalid caps buffer */
|
||||
rc=IDirectSound_GetCaps(dso,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
|
||||
|
||||
ZeroMemory(&dscaps, sizeof(dscaps));
|
||||
|
||||
/* DSOUND: Error: Invalid caps buffer */
|
||||
rc=IDirectSound_GetCaps(dso,&dscaps);
|
||||
ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
|
||||
|
||||
dscaps.dwSize=sizeof(dscaps);
|
||||
|
||||
/* DSOUND: Running on a certified driver */
|
||||
rc=IDirectSound_GetCaps(dso,&dscaps);
|
||||
ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
@ -395,43 +649,147 @@ static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
dscaps.dwMaxSecondarySampleRate);
|
||||
}
|
||||
|
||||
/* DSOUND: Error: Invalid buffer description pointer */
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL);
|
||||
ok(rc==DSERR_INVALIDPARAM,"CreateSoundBuffer should have failed: 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Invalid buffer description pointer */
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,0,&primary,NULL);
|
||||
ok(rc==DSERR_INVALIDPARAM && primary==0,"CreateSoundBuffer should have failed: rc=0x%lx,dsbo=0x%lx\n",rc,(DWORD)primary);
|
||||
|
||||
/* DSOUND: Error: Invalid buffer description pointer */
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,0,NULL);
|
||||
ok(rc==DSERR_INVALIDPARAM && primary==0,"CreateSoundBuffer should have failed: rc=0x%lx,dsbo=0x%lx\n",rc,(DWORD)primary);
|
||||
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
|
||||
/* DSOUND: Error: Invalid size */
|
||||
/* DSOUND: Error: Invalid buffer description */
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DSERR_INVALIDPARAM && primary==0,"CreateSoundBuffer should have failed: rc=0x%lx,primary=0x%lx\n",rc,(DWORD)primary);
|
||||
|
||||
/* We must call SetCooperativeLevel before calling CreateSoundBuffer */
|
||||
/* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
|
||||
rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
|
||||
ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
|
||||
if (rc!=DS_OK)
|
||||
goto EXIT;
|
||||
|
||||
/* Testing the primary buffer */
|
||||
primary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
|
||||
bufdesc.dwBufferBytes=0;
|
||||
bufdesc.dwReserved=0;
|
||||
bufdesc.lpwfxFormat=NULL;
|
||||
trace(" Testing the primary buffer\n");
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&dsbo,NULL);
|
||||
ok(rc==DS_OK,"CreateSoundBuffer failed to create a primary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
test_buffer(dso,dsbo,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER));
|
||||
ref=IDirectSoundBuffer_Release(dsbo);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release has %d references\n",ref);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a primary buffer: 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
/* Testing 3D primary buffer */
|
||||
primary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
|
||||
trace(" Testing 3D primary buffer\n");
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer: 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
primary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
|
||||
bufdesc.dwBufferBytes=0;
|
||||
bufdesc.dwReserved=0;
|
||||
bufdesc.lpwfxFormat=NULL;
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer: 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
|
||||
/* Testing the primary buffer with listener */
|
||||
primary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
|
||||
trace(" Testing 3D primary buffer\n");
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&dsbo,NULL);
|
||||
ok(rc==DS_OK,"CreateSoundBuffer failed to create a 3D primary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
test_buffer(dso,dsbo,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER));
|
||||
ref=IDirectSoundBuffer_Release(dsbo);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release has %d references\n",ref);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer: 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
primary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer: 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
LPDIRECTSOUND3DLISTENER listener=NULL;
|
||||
rc=IDirectSoundBuffer_QueryInterface(primary,&IID_IDirectSound3DListener,(void **)&listener);
|
||||
ok(rc==DS_OK&&listener!=NULL,"IDirectSoundBuffer_QueryInterface failed to get a 3D listener 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&listener) {
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,listener,0,0);
|
||||
ref=IDirectSound3DListener_Release(listener);
|
||||
ok(ref==0,"IDirectSound3DListener_Release listener has %d references, should have 0\n",ref);
|
||||
}
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
|
||||
/* Testing 3D primary buffer with listener */
|
||||
primary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
|
||||
trace(" Testing 3D primary buffer with listener\n");
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
LPDIRECTSOUND3DLISTENER listener=NULL;
|
||||
rc=IDirectSoundBuffer_QueryInterface(primary,&IID_IDirectSound3DListener,(void **)&listener);
|
||||
ok(rc==DS_OK&&listener!=NULL,"IDirectSoundBuffer_QueryInterface failed to get a 3D listener 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&listener!=NULL) {
|
||||
LPDIRECTSOUNDBUFFER temp_buffer=NULL;
|
||||
|
||||
/* Checking the COM interface */
|
||||
rc=IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
|
||||
ok(rc==DS_OK&&temp_buffer!=NULL,"IDirectSoundBuffer_QueryInterface failed: 0x%lx\n",rc);
|
||||
ok(temp_buffer==primary,"COM interface broken: 0x%08lx != 0x%08lx\n",(DWORD)temp_buffer,(DWORD)primary);
|
||||
if(rc==DS_OK&&temp_buffer!=NULL) {
|
||||
ref=IDirectSoundBuffer_Release(temp_buffer);
|
||||
ok(ref==1,"IDirectSoundBuffer_Release has %d references, should have 1\n",ref);
|
||||
|
||||
temp_buffer=NULL;
|
||||
rc=IDirectSound3DListener_QueryInterface(listener, &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
|
||||
ok(rc==DS_OK&&temp_buffer!=NULL,"IDirectSoundBuffer_QueryInterface failed: 0x%lx\n",rc);
|
||||
ok(temp_buffer==primary,"COM interface broken: 0x%08lx != 0x%08lx\n",(DWORD)temp_buffer,(DWORD)primary);
|
||||
ref=IDirectSoundBuffer_Release(temp_buffer);
|
||||
ok(ref==1,"IDirectSoundBuffer_Release has %d references, should have 1\n",ref);
|
||||
|
||||
/* Testing the buffer */
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,listener,0,0);
|
||||
}
|
||||
|
||||
/* Testing the reference counting */
|
||||
ref=IDirectSound3DListener_Release(listener);
|
||||
ok(ref==0,"IDirectSound3DListener_Release listener has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
/* Testing the reference counting */
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
/* Set the CooperativeLevel back to normal */
|
||||
/* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
|
||||
rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
|
||||
ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
|
||||
if (rc!=DS_OK)
|
||||
@ -440,45 +798,81 @@ static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
/* Testing secondary buffers */
|
||||
for (f=0;f<NB_FORMATS;f++) {
|
||||
init_format(&wfx,formats[f][0],formats[f][1],formats[f][2]);
|
||||
secondary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
|
||||
bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
|
||||
bufdesc.dwReserved=0;
|
||||
bufdesc.lpwfxFormat=&wfx;
|
||||
trace(" Testing a secondary buffer at %ldx%dx%d\n",
|
||||
wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&dsbo,NULL);
|
||||
ok(rc==DS_OK,"CreateSoundBuffer failed to create a secondary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
test_buffer(dso,dsbo,0,winetest_interactive);
|
||||
ref=IDirectSoundBuffer_Release(dsbo);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release has %d references\n",ref);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
|
||||
ok(rc==DS_OK&&secondary!=NULL,"CreateSoundBuffer failed to create a secondary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&secondary!=NULL) {
|
||||
test_buffer(dso,secondary,0,winetest_interactive,0,0,0,0);
|
||||
ref=IDirectSoundBuffer_Release(secondary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release secondary has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
|
||||
/* Testing duplicated secondary buffers */
|
||||
for (f=0;f<NB_FORMATS;f++) {
|
||||
init_format(&wfx,formats[f][0],formats[f][1],formats[f][2]);
|
||||
secondary=NULL;
|
||||
ZeroMemory(&bufdesc, sizeof(bufdesc));
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
|
||||
bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
|
||||
bufdesc.lpwfxFormat=&wfx;
|
||||
trace(" Testing a duplicated secondary buffer at %ldx%dx%d\n",
|
||||
wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
|
||||
ok(rc==DS_OK&&secondary!=NULL,"CreateSoundBuffer failed to create a secondary buffer 0x%lx\n",rc);
|
||||
if(rc==DS_OK&&secondary!=NULL) {
|
||||
/* DSOUND: Error: Invalid source buffer */
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,0,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Invalid dest buffer */
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed 0x%lx\n",rc);
|
||||
|
||||
/* DSOUND: Error: Invalid source buffer */
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated);
|
||||
ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer should have failed 0x%lx\n",rc);
|
||||
|
||||
duplicated=NULL;
|
||||
rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,&duplicated);
|
||||
ok(rc==DS_OK&&duplicated!=NULL,"IDirectSound_DuplicateSoundBuffer failed to duplicate a secondary buffer 0x%lx\n",rc);
|
||||
|
||||
ref=IDirectSoundBuffer_Release(secondary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release secondary has %d references, should have 0\n",ref);
|
||||
|
||||
if (rc==DS_OK&&duplicated!=NULL) {
|
||||
test_buffer(dso,duplicated,0,winetest_interactive,0,0,0,0);
|
||||
|
||||
ref=IDirectSoundBuffer_Release(duplicated);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release duplicated has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Testing 3D secondary buffers */
|
||||
for (f=0;f<NB_FORMATS;f++) {
|
||||
init_format(&wfx,formats[f][0],formats[f][1],formats[f][2]);
|
||||
bufdesc.dwSize=sizeof(bufdesc);
|
||||
bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRL3D;
|
||||
bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
|
||||
bufdesc.dwReserved=0;
|
||||
bufdesc.lpwfxFormat=&wfx;
|
||||
trace(" Testing a 3D secondary buffer at %ldx%dx%d\n",
|
||||
wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
|
||||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&dsbo,NULL);
|
||||
ok(rc==DS_OK,"CreateSoundBuffer failed to create a 3D secondary buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
test_buffer(dso,dsbo,0,winetest_interactive);
|
||||
ref=IDirectSoundBuffer_Release(dsbo);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release has %d references\n",ref);
|
||||
}
|
||||
}
|
||||
test_secondary(dso,winetest_interactive,0,0,0,0,0);
|
||||
test_secondary(dso,winetest_interactive,1,0,0,0,0);
|
||||
test_secondary(dso,winetest_interactive,1,0,1,0,0);
|
||||
test_secondary(dso,winetest_interactive,0,1,0,0,0);
|
||||
test_secondary(dso,winetest_interactive,0,1,1,0,0);
|
||||
test_secondary(dso,winetest_interactive,1,1,0,0,0);
|
||||
test_secondary(dso,winetest_interactive,1,1,1,0,0);
|
||||
test_secondary(dso,winetest_interactive,1,1,0,1,0);
|
||||
test_secondary(dso,winetest_interactive,1,1,0,0,1);
|
||||
test_secondary(dso,winetest_interactive,1,1,0,1,1);
|
||||
|
||||
EXIT:
|
||||
if (dso!=NULL) {
|
||||
ref=IDirectSound_Release(dso);
|
||||
ok(ref==0,"IDirectSound_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -537,7 +931,8 @@ static int capture_buffer_service(capture_state_t* state)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREBUFFER dscbo)
|
||||
static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
|
||||
LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
|
||||
{
|
||||
HRESULT rc;
|
||||
DSCBCAPS dscbcaps;
|
||||
@ -615,6 +1010,7 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
|
||||
if (rc!=DS_OK)
|
||||
return;
|
||||
|
||||
if (record) {
|
||||
rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
|
||||
ok(rc==DS_OK,"Start: 0x%lx\n",rc);
|
||||
if (rc!=DS_OK)
|
||||
@ -641,6 +1037,7 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco, LPDIRECTSOUNDCAPTUREB
|
||||
ok(rc==DS_OK,"Stop: 0x%lx\n",rc);
|
||||
if (rc!=DS_OK)
|
||||
return;
|
||||
}
|
||||
|
||||
rc=IDirectSoundNotify_Release(state.notify);
|
||||
ok(rc==0,"Release: 0x%lx\n",rc);
|
||||
@ -665,7 +1062,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate didn't fail: 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
ref=IDirectSoundCapture_Release(dsco);
|
||||
ok(ref==0,"IDirectSoundCapture_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCapture_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
rc=DirectSoundCaptureCreate(lpGuid,&dsco,NULL);
|
||||
@ -702,7 +1099,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
ref=IDirectSoundCaptureBuffer_Release(dscbo);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
/* Private dsound.dll: Error: Invalid buffer size */
|
||||
@ -717,7 +1114,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
ref=IDirectSoundCaptureBuffer_Release(dscbo);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
/* Private dsound.dll: Error: Invalid buffer size */
|
||||
@ -733,7 +1130,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
ref=IDirectSoundCaptureBuffer_Release(dscbo);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
/* Private dsound.dll: Error: Invalid buffer size */
|
||||
@ -749,7 +1146,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
ok(rc==DSERR_INVALIDPARAM,"CreateCaptureBuffer should have failed to create a capture buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
ref=IDirectSoundCaptureBuffer_Release(dscbo);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
for (f=0;f<NB_FORMATS;f++) {
|
||||
@ -765,9 +1162,9 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
|
||||
ok(rc==DS_OK,"CreateCaptureBuffer failed to create a capture buffer 0x%lx\n",rc);
|
||||
if (rc==DS_OK) {
|
||||
test_capture_buffer(dsco, dscbo);
|
||||
test_capture_buffer(dsco, dscbo, winetest_interactive);
|
||||
ref=IDirectSoundCaptureBuffer_Release(dscbo);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCaptureBuffer_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
}
|
||||
|
||||
@ -789,7 +1186,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
|
||||
EXIT:
|
||||
if (dsco!=NULL) {
|
||||
ref=IDirectSoundCapture_Release(dsco);
|
||||
ok(ref==0,"IDirectSoundCapture_Release has %d references\n",ref);
|
||||
ok(ref==0,"IDirectSoundCapture_Release has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user