* Sync with Wine 1.5.26.
svn path=/trunk/; revision=58752
add_definitions(
-D_WINE
- -D_USE_MATH_DEFINES)
+ -D_USE_MATH_DEFINES
+ -D__WINESRC__)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
mixer.c
primary.c
propset.c
- regsvr.c
sound3d.c
version.rc
${CMAKE_CURRENT_BINARY_DIR}/dsound.def)
set_module_type(dsound win32dll)
-
-target_link_libraries(dsound
- dxguid
- uuid
- wine)
-
-add_importlibs(dsound
- msvcrt
- user32
- advapi32
- ole32
- winmm
- kernel32
- ntdll)
-
+target_link_libraries(dsound dxguid uuid wine)
+add_importlibs(dsound winmm ole32 advapi32 user32 msvcrt kernel32 ntdll)
add_cd_file(TARGET dsound DESTINATION reactos/system32 FOR all)
-
//#include "winuser.h"
#include <mmsystem.h>
#include <winternl.h>
+#include <vfwmsgs.h>
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
+//#include <dsconf.h>
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-static HRESULT SecondaryBufferImpl_Destroy(SecondaryBufferImpl *pdsb);
-
/*******************************************************************************
* IDirectSoundNotify
*/
-struct IDirectSoundNotifyImpl
+static inline struct IDirectSoundBufferImpl *impl_from_IDirectSoundNotify(IDirectSoundNotify *iface)
{
- /* IUnknown fields */
- const IDirectSoundNotifyVtbl *lpVtbl;
- LONG ref;
- IDirectSoundBufferImpl* dsb;
-};
-
-static HRESULT IDirectSoundNotifyImpl_Create(IDirectSoundBufferImpl *dsb,
- IDirectSoundNotifyImpl **pdsn);
-static HRESULT IDirectSoundNotifyImpl_Destroy(IDirectSoundNotifyImpl *pdsn);
+ return CONTAINING_RECORD(iface, struct IDirectSoundBufferImpl, IDirectSoundNotify_iface);
+}
-static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(
- LPDIRECTSOUNDNOTIFY iface,REFIID riid,LPVOID *ppobj
-) {
- IDirectSoundNotifyImpl *This = (IDirectSoundNotifyImpl *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(IDirectSoundNotify *iface, REFIID riid,
+ void **ppobj)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundNotify(iface);
- if (This->dsb == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj);
- return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER)This->dsb, riid, ppobj);
+ return IDirectSoundBuffer8_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj);
}
-static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface)
+static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(IDirectSoundNotify *iface)
{
- IDirectSoundNotifyImpl *This = (IDirectSoundNotifyImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ ULONG ref = InterlockedIncrement(&This->refn);
+
TRACE("(%p) ref was %d\n", This, ref - 1);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+
return ref;
}
-static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface)
+static ULONG WINAPI IDirectSoundNotifyImpl_Release(IDirectSoundNotify *iface)
{
- IDirectSoundNotifyImpl *This = (IDirectSoundNotifyImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ ULONG ref = InterlockedDecrement(&This->refn);
+
TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER)This->dsb);
- This->dsb->notify = NULL;
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ secondarybuffer_destroy(This);
+
return ref;
}
-static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(
- LPDIRECTSOUNDNOTIFY iface,DWORD howmuch,LPCDSBPOSITIONNOTIFY notify
-) {
- IDirectSoundNotifyImpl *This = (IDirectSoundNotifyImpl *)iface;
+static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(IDirectSoundNotify *iface,
+ DWORD howmuch, const DSBPOSITIONNOTIFY *notify)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+
TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
if (howmuch > 0 && notify == NULL) {
notify[i].dwOffset,notify[i].hEventNotify);
}
- if (This->dsb->hwnotify) {
- HRESULT hres;
- hres = IDsDriverNotify_SetNotificationPositions(This->dsb->hwnotify, howmuch, notify);
- if (hres != DS_OK)
- WARN("IDsDriverNotify_SetNotificationPositions failed\n");
- return hres;
- } else if (howmuch > 0) {
+ if (howmuch > 0) {
/* Make an internal copy of the caller-supplied array.
* Replace the existing copy if one is already present. */
- HeapFree(GetProcessHeap(), 0, This->dsb->notifies);
- This->dsb->notifies = HeapAlloc(GetProcessHeap(), 0,
+ HeapFree(GetProcessHeap(), 0, This->notifies);
+ This->notifies = HeapAlloc(GetProcessHeap(), 0,
howmuch * sizeof(DSBPOSITIONNOTIFY));
- if (This->dsb->notifies == NULL) {
+ if (This->notifies == NULL) {
WARN("out of memory\n");
return DSERR_OUTOFMEMORY;
}
- CopyMemory(This->dsb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
- This->dsb->nrofnotifies = howmuch;
- } else {
- HeapFree(GetProcessHeap(), 0, This->dsb->notifies);
- This->dsb->notifies = NULL;
- This->dsb->nrofnotifies = 0;
- }
+ CopyMemory(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
+ This->nrofnotifies = howmuch;
+ } else {
+ HeapFree(GetProcessHeap(), 0, This->notifies);
+ This->notifies = NULL;
+ This->nrofnotifies = 0;
+ }
return S_OK;
}
IDirectSoundNotifyImpl_SetNotificationPositions,
};
-static HRESULT IDirectSoundNotifyImpl_Create(
- IDirectSoundBufferImpl * dsb,
- IDirectSoundNotifyImpl **pdsn)
-{
- IDirectSoundNotifyImpl * dsn;
- TRACE("(%p,%p)\n",dsb,pdsn);
-
- dsn = 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);
+/*******************************************************************************
+ * IDirectSoundBuffer
+ */
- *pdsn = dsn;
- return DS_OK;
+static inline IDirectSoundBufferImpl *impl_from_IDirectSoundBuffer8(IDirectSoundBuffer8 *iface)
+{
+ return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSoundBuffer8_iface);
}
-static HRESULT IDirectSoundNotifyImpl_Destroy(
- IDirectSoundNotifyImpl *pdsn)
+static inline BOOL is_primary_buffer(IDirectSoundBufferImpl *This)
{
- TRACE("(%p)\n",pdsn);
-
- while (IDirectSoundNotifyImpl_Release((LPDIRECTSOUNDNOTIFY)pdsn) > 0);
-
- return DS_OK;
+ return (This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) != 0;
}
-/*******************************************************************************
- * IDirectSoundBuffer
- */
+static HRESULT WINAPI IDirectSoundBufferImpl_SetFormat(IDirectSoundBuffer8 *iface,
+ LPCWAVEFORMATEX wfex)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
-static HRESULT WINAPI IDirectSoundBufferImpl_SetFormat(
- LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX wfex
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+ TRACE("(%p,%p)\n", iface, wfex);
- TRACE("(%p,%p)\n",This,wfex);
- /* This method is not available on secondary buffers */
- WARN("invalid call\n");
- return DSERR_INVALIDCALL;
+ if (is_primary_buffer(This))
+ return primarybuffer_SetFormat(This->device, wfex);
+ else {
+ WARN("not available for secondary buffers.\n");
+ return DSERR_INVALIDCALL;
+ }
}
-static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(
- LPDIRECTSOUNDBUFFER8 iface,LONG vol
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(IDirectSoundBuffer8 *iface, LONG vol)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
LONG oldVol;
+
HRESULT hres = DS_OK;
TRACE("(%p,%d)\n",This,vol);
DSOUND_RecalcVolPan(&(This->volpan));
}
- if (vol != oldVol) {
- if (This->hwbuf) {
- hres = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_SetVolumePan failed\n");
- }
- }
-
RtlReleaseResource(&This->lock);
/* **** */
return hres;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume(
- LPDIRECTSOUNDBUFFER8 iface,LPLONG vol
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume(IDirectSoundBuffer8 *iface, LONG *vol)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
TRACE("(%p,%p)\n",This,vol);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(
- LPDIRECTSOUNDBUFFER8 iface,DWORD freq
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *iface, DWORD freq)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
DWORD oldFreq;
TRACE("(%p,%d)\n",This,freq);
+ if (is_primary_buffer(This)) {
+ WARN("not available for primary buffers.\n");
+ return DSERR_CONTROLUNAVAIL;
+ }
+
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
WARN("control unavailable\n");
return DSERR_CONTROLUNAVAIL;
oldFreq = This->freq;
This->freq = freq;
if (freq != oldFreq) {
- This->freqAdjust = ((DWORD64)This->freq << DSOUND_FREQSHIFT) / This->device->pwfx->nSamplesPerSec;
+ This->freqAdjust = This->freq / (float)This->device->pwfx->nSamplesPerSec;
This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign;
DSOUND_RecalcFormat(This);
- DSOUND_MixToTemporary(This, 0, This->buflen, FALSE);
}
RtlReleaseResource(&This->lock);
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_Play(
- LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags
-) {
+static HRESULT WINAPI IDirectSoundBufferImpl_Play(IDirectSoundBuffer8 *iface, DWORD reserved1,
+ DWORD reserved2, DWORD flags)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+
TRACE("(%p,%08x,%08x,%08x)\n",This,reserved1,reserved2,flags);
/* **** */
RtlAcquireResourceExclusive(&This->lock, TRUE);
This->playflags = flags;
- if (This->state == STATE_STOPPED && !This->hwbuf) {
+ if (This->state == STATE_STOPPED) {
This->leadin = TRUE;
This->state = STATE_STARTING;
} else if (This->state == STATE_STOPPING)
This->state = STATE_PLAYING;
- if (This->hwbuf) {
- hres = IDsDriverBuffer_Play(This->hwbuf, 0, 0, This->playflags);
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_Play failed\n");
- else
- This->state = STATE_PLAYING;
- }
RtlReleaseResource(&This->lock);
/* **** */
return hres;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface)
+static HRESULT WINAPI IDirectSoundBufferImpl_Stop(IDirectSoundBuffer8 *iface)
{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+
TRACE("(%p)\n",This);
/* **** */
This->state = STATE_STOPPED;
DSOUND_CheckEvent(This, 0, 0);
}
- if (This->hwbuf) {
- hres = IDsDriverBuffer_Stop(This->hwbuf);
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_Stop failed\n");
- else
- This->state = STATE_STOPPED;
- }
RtlReleaseResource(&This->lock);
/* **** */
return hres;
}
-static ULONG WINAPI IDirectSoundBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface)
+static ULONG WINAPI IDirectSoundBufferImpl_AddRef(IDirectSoundBuffer8 *iface)
{
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
TRACE("(%p) ref was %d\n", This, ref - 1);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+
return ref;
}
-static ULONG WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface)
+static ULONG WINAPI IDirectSoundBufferImpl_Release(IDirectSoundBuffer8 *iface)
{
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+ ULONG ref;
- if (!ref) {
- DirectSoundDevice_RemoveBuffer(This->device, This);
- RtlDeleteResource(&This->lock);
-
- if (This->hwbuf)
- IDsDriverBuffer_Release(This->hwbuf);
- if (!This->hwbuf || (This->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)) {
- This->buffer->ref--;
- list_remove(&This->entry);
- if (This->buffer->ref==0) {
- HeapFree(GetProcessHeap(),0,This->buffer->memory);
- HeapFree(GetProcessHeap(),0,This->buffer);
- }
- }
+ if (is_primary_buffer(This)){
+ ref = capped_refcount_dec(&This->ref);
+ if(!ref)
+ capped_refcount_dec(&This->numIfaces);
+ TRACE("(%p) ref is now: %d\n", This, ref);
+ return ref;
+ }
- HeapFree(GetProcessHeap(), 0, This->tmp_buffer);
- HeapFree(GetProcessHeap(), 0, This->notifies);
- HeapFree(GetProcessHeap(), 0, This->pwfx);
- HeapFree(GetProcessHeap(), 0, This);
+ ref = InterlockedDecrement(&This->ref);
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ secondarybuffer_destroy(This);
+
+ TRACE("(%p) ref is now %d\n", This, ref);
- TRACE("(%p) released\n", This);
- }
return ref;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
- LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos
-) {
- HRESULT hres;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(IDirectSoundBuffer8 *iface,
+ DWORD *playpos, DWORD *writepos)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+ DWORD pos;
+
TRACE("(%p,%p,%p)\n",This,playpos,writepos);
RtlAcquireResourceShared(&This->lock, TRUE);
- if (This->hwbuf) {
- hres=IDsDriverBuffer_GetPosition(This->hwbuf,playpos,writepos);
- if (hres != DS_OK) {
- WARN("IDsDriverBuffer_GetPosition failed\n");
- return hres;
- }
- } else {
- DWORD pos = This->sec_mixpos;
- /* sanity */
- if (pos >= This->buflen){
- FIXME("Bad play position. playpos: %d, buflen: %d\n", pos, This->buflen);
- pos %= This->buflen;
- }
+ pos = This->sec_mixpos;
- if (playpos)
- *playpos = pos;
- if (writepos)
- *writepos = pos;
+ /* sanity */
+ if (pos >= This->buflen){
+ FIXME("Bad play position. playpos: %d, buflen: %d\n", pos, This->buflen);
+ pos %= This->buflen;
}
- if (writepos && This->state != STATE_STOPPED && (!This->hwbuf || !(This->device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD))) {
+
+ if (playpos)
+ *playpos = pos;
+ if (writepos)
+ *writepos = pos;
+
+ if (writepos && This->state != STATE_STOPPED) {
/* apply the documented 10ms lead to writepos */
*writepos += This->writelead;
*writepos %= This->buflen;
}
+
RtlReleaseResource(&This->lock);
TRACE("playpos = %d, writepos = %d, buflen=%d (%p, time=%d)\n",
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(
- LPDIRECTSOUNDBUFFER8 iface,LPDWORD status
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(IDirectSoundBuffer8 *iface, DWORD *status)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
TRACE("(%p,%p), thread is %04x\n",This,status,GetCurrentThreadId());
if (status == NULL) {
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat(
- LPDIRECTSOUNDBUFFER8 iface,
- LPWAVEFORMATEX lpwf,
- DWORD wfsize,
- LPDWORD wfwritten)
+static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat(IDirectSoundBuffer8 *iface,
+ LPWAVEFORMATEX lpwf, DWORD wfsize, DWORD *wfwritten)
{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
DWORD size;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+
TRACE("(%p,%p,%d,%p)\n",This,lpwf,wfsize,wfwritten);
size = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
- LPDIRECTSOUNDBUFFER8 iface,DWORD writecursor,DWORD writebytes,LPVOID *lplpaudioptr1,LPDWORD audiobytes1,LPVOID *lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
-) {
+static HRESULT WINAPI IDirectSoundBufferImpl_Lock(IDirectSoundBuffer8 *iface, DWORD writecursor,
+ DWORD writebytes, void **lplpaudioptr1, DWORD *audiobytes1, void **lplpaudioptr2,
+ DWORD *audiobytes2, DWORD flags)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
-
- TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n",
- This,
- writecursor,
- writebytes,
- lplpaudioptr1,
- audiobytes1,
- lplpaudioptr2,
- audiobytes2,
- flags,
- GetTickCount()
- );
+
+ TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n", This, writecursor, writebytes, lplpaudioptr1,
+ audiobytes1, lplpaudioptr2, audiobytes2, flags, GetTickCount());
if (!audiobytes1)
return DSERR_INVALIDPARAM;
/* **** */
RtlAcquireResourceShared(&This->lock, TRUE);
- if (!(This->device->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
- hres = IDsDriverBuffer_Lock(This->hwbuf,
- lplpaudioptr1, audiobytes1,
- lplpaudioptr2, audiobytes2,
- writecursor, writebytes,
- 0);
- if (hres != DS_OK) {
- WARN("IDsDriverBuffer_Lock failed\n");
- RtlReleaseResource(&This->lock);
- return hres;
- }
+ if (writecursor+writebytes <= This->buflen) {
+ *(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
+ if (This->sec_mixpos >= writecursor && This->sec_mixpos < writecursor + writebytes && This->state == STATE_PLAYING)
+ WARN("Overwriting mixing position, case 1\n");
+ *audiobytes1 = writebytes;
+ if (lplpaudioptr2)
+ *(LPBYTE*)lplpaudioptr2 = NULL;
+ if (audiobytes2)
+ *audiobytes2 = 0;
+ TRACE("Locked %p(%i bytes) and %p(%i bytes) writecursor=%d\n",
+ *(LPBYTE*)lplpaudioptr1, *audiobytes1, lplpaudioptr2 ? *(LPBYTE*)lplpaudioptr2 : NULL, audiobytes2 ? *audiobytes2: 0, writecursor);
+ TRACE("->%d.0\n",writebytes);
} else {
- if (writecursor+writebytes <= This->buflen) {
- *(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
- if (This->sec_mixpos >= writecursor && This->sec_mixpos < writecursor + writebytes && This->state == STATE_PLAYING)
- WARN("Overwriting mixing position, case 1\n");
- *audiobytes1 = writebytes;
- if (lplpaudioptr2)
- *(LPBYTE*)lplpaudioptr2 = NULL;
- if (audiobytes2)
- *audiobytes2 = 0;
- TRACE("Locked %p(%i bytes) and %p(%i bytes) writecursor=%d\n",
- *(LPBYTE*)lplpaudioptr1, *audiobytes1, lplpaudioptr2 ? *(LPBYTE*)lplpaudioptr2 : NULL, audiobytes2 ? *audiobytes2: 0, writecursor);
- TRACE("->%d.0\n",writebytes);
- } else {
- DWORD remainder = writebytes + writecursor - This->buflen;
- *(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
- *audiobytes1 = This->buflen-writecursor;
- if (This->sec_mixpos >= writecursor && This->sec_mixpos < writecursor + writebytes && This->state == STATE_PLAYING)
- WARN("Overwriting mixing position, case 2\n");
- if (lplpaudioptr2)
- *(LPBYTE*)lplpaudioptr2 = This->buffer->memory;
- if (audiobytes2)
- *audiobytes2 = writebytes-(This->buflen-writecursor);
- if (audiobytes2 && This->sec_mixpos < remainder && This->state == STATE_PLAYING)
- WARN("Overwriting mixing position, case 3\n");
- TRACE("Locked %p(%i bytes) and %p(%i bytes) writecursor=%d\n", *(LPBYTE*)lplpaudioptr1, *audiobytes1, lplpaudioptr2 ? *(LPBYTE*)lplpaudioptr2 : NULL, audiobytes2 ? *audiobytes2: 0, writecursor);
- }
+ DWORD remainder = writebytes + writecursor - This->buflen;
+ *(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
+ *audiobytes1 = This->buflen-writecursor;
+ if (This->sec_mixpos >= writecursor && This->sec_mixpos < writecursor + writebytes && This->state == STATE_PLAYING)
+ WARN("Overwriting mixing position, case 2\n");
+ if (lplpaudioptr2)
+ *(LPBYTE*)lplpaudioptr2 = This->buffer->memory;
+ if (audiobytes2)
+ *audiobytes2 = writebytes-(This->buflen-writecursor);
+ if (audiobytes2 && This->sec_mixpos < remainder && This->state == STATE_PLAYING)
+ WARN("Overwriting mixing position, case 3\n");
+ TRACE("Locked %p(%i bytes) and %p(%i bytes) writecursor=%d\n", *(LPBYTE*)lplpaudioptr1, *audiobytes1, lplpaudioptr2 ? *(LPBYTE*)lplpaudioptr2 : NULL, audiobytes2 ? *audiobytes2: 0, writecursor);
}
RtlReleaseResource(&This->lock);
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_SetCurrentPosition(
- LPDIRECTSOUNDBUFFER8 iface,DWORD newpos
-) {
+static HRESULT WINAPI IDirectSoundBufferImpl_SetCurrentPosition(IDirectSoundBuffer8 *iface,
+ DWORD newpos)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
- DWORD oldpos;
+
TRACE("(%p,%d)\n",This,newpos);
/* **** */
RtlAcquireResourceExclusive(&This->lock, TRUE);
- oldpos = This->sec_mixpos;
-
/* start mixing from this new location instead */
newpos %= This->buflen;
newpos -= newpos%This->pwfx->nBlockAlign;
This->sec_mixpos = newpos;
/* at this point, do not attempt to reset buffers, mess with primary mix position,
- or anything like that to reduce latancy. The data already prebuffered cannot be changed */
-
- /* position HW buffer if applicable, else just start mixing from new location instead */
- if (This->hwbuf) {
- hres = IDsDriverBuffer_SetPosition(This->hwbuf, This->buf_mixpos);
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_SetPosition failed\n");
- }
- else if (oldpos != newpos)
- /* FIXME: Perhaps add a call to DSOUND_MixToTemporary here? Not sure it's needed */
- This->buf_mixpos = DSOUND_secpos_to_bufpos(This, newpos, 0, NULL);
+ or anything like that to reduce latency. The data already prebuffered cannot be changed */
RtlReleaseResource(&This->lock);
/* **** */
return hres;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_SetPan(
- LPDIRECTSOUNDBUFFER8 iface,LONG pan
-) {
+static HRESULT WINAPI IDirectSoundBufferImpl_SetPan(IDirectSoundBuffer8 *iface, LONG pan)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
TRACE("(%p,%d)\n",This,pan);
if (This->volpan.lPan != pan) {
This->volpan.lPan = pan;
DSOUND_RecalcVolPan(&(This->volpan));
-
- if (This->hwbuf) {
- hres = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_SetVolumePan failed\n");
- }
}
RtlReleaseResource(&This->lock);
return hres;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetPan(
- LPDIRECTSOUNDBUFFER8 iface,LPLONG pan
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetPan(IDirectSoundBuffer8 *iface, LONG *pan)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
TRACE("(%p,%p)\n",This,pan);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
- LPDIRECTSOUNDBUFFER8 iface,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface, *iter;
+static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(IDirectSoundBuffer8 *iface, void *p1, DWORD x1,
+ void *p2, DWORD x2)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface), *iter;
HRESULT hres = DS_OK;
TRACE("(%p,%p,%d,%p,%d)\n", This,p1,x1,p2,x2);
- /* **** */
- RtlAcquireResourceShared(&This->lock, TRUE);
-
- if (!(This->device->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
- hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2);
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_Unlock failed\n");
- }
-
- RtlReleaseResource(&This->lock);
- /* **** */
-
if (!p2)
x2 = 0;
- if (!This->hwbuf && (x1 || x2))
+ if((p1 && ((BYTE*)p1 < This->buffer->memory || (BYTE*)p1 >= This->buffer->memory + This->buflen)) ||
+ (p2 && ((BYTE*)p2 < This->buffer->memory || (BYTE*)p2 >= This->buffer->memory + This->buflen)))
+ return DSERR_INVALIDPARAM;
+
+ if (x1 || x2)
{
RtlAcquireResourceShared(&This->device->buffer_list_lock, TRUE);
LIST_FOR_EACH_ENTRY(iter, &This->buffer->buffers, IDirectSoundBufferImpl, entry )
{
if(x1 + (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory > iter->buflen)
hres = DSERR_INVALIDPARAM;
- else
- DSOUND_MixToTemporary(iter, (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory, x1, FALSE);
}
- if (x2)
- DSOUND_MixToTemporary(iter, 0, x2, FALSE);
RtlReleaseResource(&iter->lock);
}
RtlReleaseResource(&This->device->buffer_list_lock);
return hres;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_Restore(
- LPDIRECTSOUNDBUFFER8 iface
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_Restore(IDirectSoundBuffer8 *iface)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
FIXME("(%p):stub\n",This);
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetFrequency(
- LPDIRECTSOUNDBUFFER8 iface,LPDWORD freq
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetFrequency(IDirectSoundBuffer8 *iface, DWORD *freq)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
TRACE("(%p,%p)\n",This,freq);
if (freq == NULL) {
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(
- LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(IDirectSoundBuffer8 *iface, DWORD dwEffectsCount,
+ LPDSEFFECTDESC pDSFXDesc, DWORD *pdwResultCodes)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
DWORD u;
FIXME("(%p,%u,%p,%p): stub\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes);
return DSERR_CONTROLUNAVAIL;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_AcquireResources(
- LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_AcquireResources(IDirectSoundBuffer8 *iface,
+ DWORD dwFlags, DWORD dwEffectsCount, DWORD *pdwResultCodes)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
DWORD u;
- FIXME("(%p,%08u,%u,%p): stub\n",This,dwFlags,dwEffectsCount,pdwResultCodes);
+ FIXME("(%p,%08u,%u,%p): stub, faking success\n",This,dwFlags,dwEffectsCount,pdwResultCodes);
if (pdwResultCodes)
for (u=0; u<dwEffectsCount; u++) pdwResultCodes[u] = DSFXR_UNKNOWN;
WARN("control unavailable\n");
- return DSERR_CONTROLUNAVAIL;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetObjectInPath(
- LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID* ppObject
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetObjectInPath(IDirectSoundBuffer8 *iface,
+ REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, void **ppObject)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
FIXME("(%p,%s,%u,%s,%p): stub\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject);
return DSERR_CONTROLUNAVAIL;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_Initialize(
- LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND dsound,LPCDSBUFFERDESC dbsd
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_Initialize(IDirectSoundBuffer8 *iface,
+ IDirectSound *dsound, LPCDSBUFFERDESC dbsd)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
WARN("(%p) already initialized\n", This);
return DSERR_ALREADYINITIALIZED;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_GetCaps(
- LPDIRECTSOUNDBUFFER8 iface,LPDSBCAPS caps
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_GetCaps(IDirectSoundBuffer8 *iface, LPDSBCAPS caps)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
+
TRACE("(%p)->(%p)\n",This,caps);
if (caps == NULL) {
}
caps->dwFlags = This->dsbd.dwFlags;
- if (This->hwbuf) caps->dwFlags |= DSBCAPS_LOCHARDWARE;
- else caps->dwFlags |= DSBCAPS_LOCSOFTWARE;
+ caps->dwFlags |= DSBCAPS_LOCSOFTWARE;
caps->dwBufferBytes = This->buflen;
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(
- LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj
-) {
- IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface;
+static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(IDirectSoundBuffer8 *iface, REFIID riid,
+ void **ppobj)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface);
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
if ( IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ||
IsEqualGUID(riid, &IID_IDirectSoundBuffer8) ) {
- if (!This->secondary)
- SecondaryBufferImpl_Create(This, &(This->secondary));
- if (This->secondary) {
- IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This->secondary);
- *ppobj = This->secondary;
- return S_OK;
- }
- WARN("IID_IDirectSoundBuffer\n");
- return E_NOINTERFACE;
+ IDirectSoundBuffer8_AddRef(iface);
+ *ppobj = iface;
+ return S_OK;
}
if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
- if (!This->notify)
- IDirectSoundNotifyImpl_Create(This, &(This->notify));
- if (This->notify) {
- IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
- *ppobj = This->notify;
- return S_OK;
- }
- WARN("IID_IDirectSoundNotify\n");
- return E_NOINTERFACE;
+ IDirectSoundNotify_AddRef(&This->IDirectSoundNotify_iface);
+ *ppobj = &This->IDirectSoundNotify_iface;
+ return S_OK;
}
if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
- if (!This->ds3db)
- IDirectSound3DBufferImpl_Create(This, &(This->ds3db));
- if (This->ds3db) {
- IDirectSound3DBuffer_AddRef((LPDIRECTSOUND3DBUFFER)This->ds3db);
- *ppobj = This->ds3db;
- return S_OK;
- }
- WARN("IID_IDirectSound3DBuffer\n");
- return E_NOINTERFACE;
+ if(This->dsbd.dwFlags & DSBCAPS_CTRL3D){
+ IDirectSound3DBuffer_AddRef(&This->IDirectSound3DBuffer_iface);
+ *ppobj = &This->IDirectSound3DBuffer_iface;
+ return S_OK;
+ }
+ TRACE("app requested IDirectSound3DBuffer on non-3D secondary buffer\n");
+ return E_NOINTERFACE;
}
if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
}
if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
- if (!This->iks)
- IKsBufferPropertySetImpl_Create(This, &(This->iks));
- if (This->iks) {
- IKsPropertySet_AddRef((LPKSPROPERTYSET)This->iks);
- *ppobj = This->iks;
- return S_OK;
- }
- WARN("IID_IKsPropertySet\n");
- return E_NOINTERFACE;
+ IKsPropertySet_AddRef(&This->IKsPropertySet_iface);
+ *ppobj = &This->IKsPropertySet_iface;
+ return S_OK;
}
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
LPWAVEFORMATEX wfex = dsbd->lpwfxFormat;
HRESULT err = DS_OK;
DWORD capf = 0;
- int use_hw, alloc_size, cp_size;
TRACE("(%p,%p,%p)\n",device,pdsb,dsbd);
if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) {
TRACE("Created buffer at %p\n", dsb);
dsb->ref = 0;
- dsb->secondary = 0;
+ dsb->refn = 0;
+ dsb->ref3D = 0;
+ dsb->refiks = 0;
+ dsb->numIfaces = 0;
dsb->device = device;
- dsb->lpVtbl = &dsbvt;
- dsb->iks = NULL;
+ dsb->IDirectSoundBuffer8_iface.lpVtbl = &dsbvt;
+ dsb->IDirectSoundNotify_iface.lpVtbl = &dsnvt;
+ dsb->IDirectSound3DBuffer_iface.lpVtbl = &ds3dbvt;
+ dsb->IKsPropertySet_iface.lpVtbl = &iksbvt;
/* size depends on version */
CopyMemory(&dsb->dsbd, dsbd, dsbd->dwSize);
- /* variable sized struct so calculate size based on format */
- if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
- alloc_size = sizeof(WAVEFORMATEX);
- cp_size = sizeof(PCMWAVEFORMAT);
- } else
- alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;
-
- dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,alloc_size);
+ dsb->pwfx = DSOUND_CopyFormat(wfex);
if (dsb->pwfx == NULL) {
- WARN("out of memory\n");
HeapFree(GetProcessHeap(),0,dsb);
*pdsb = NULL;
return DSERR_OUTOFMEMORY;
}
- CopyMemory(dsb->pwfx, wfex, cp_size);
-
if (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign)
dsb->buflen = dsbd->dwBufferBytes +
(dsbd->lpwfxFormat->nBlockAlign -
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;
if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT;
else capf |= DSCAPS_SECONDARY8BIT;
- use_hw = !!(dsbd->dwFlags & DSBCAPS_LOCHARDWARE);
- TRACE("use_hw = %d, capf = 0x%08x, device->drvcaps.dwFlags = 0x%08x\n", use_hw, capf, device->drvcaps.dwFlags);
- if (use_hw && ((device->drvcaps.dwFlags & capf) != capf || !device->driver))
- {
- if (device->driver)
- WARN("Format not supported for hardware buffer\n");
- HeapFree(GetProcessHeap(),0,dsb->pwfx);
- HeapFree(GetProcessHeap(),0,dsb);
- *pdsb = NULL;
- if ((device->drvcaps.dwFlags & capf) != capf)
- return DSERR_BADFORMAT;
- return DSERR_GENERIC;
- }
-
- /* FIXME: check hardware sample rate mixing capabilities */
- /* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */
- /* FIXME: check whether any hardware buffers are left */
- /* FIXME: handle DSDHEAP_CREATEHEAP for hardware buffers */
+ TRACE("capf = 0x%08x, device->drvcaps.dwFlags = 0x%08x\n", capf, device->drvcaps.dwFlags);
/* Allocate an empty buffer */
dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
return DSERR_OUTOFMEMORY;
}
- /* Allocate system memory for buffer if applicable */
- if ((device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) {
- dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
- if (dsb->buffer->memory == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb->pwfx);
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb);
- *pdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
- }
-
- /* Allocate the hardware buffer */
- if (use_hw) {
- err = IDsDriver_CreateSoundBuffer(device->driver,wfex,dsbd->dwFlags,0,
- &(dsb->buflen),&(dsb->buffer->memory),
- (LPVOID*)&(dsb->hwbuf));
- if (FAILED(err))
- {
- WARN("Failed to create hardware secondary buffer: %08x\n", err);
- if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)
- HeapFree(GetProcessHeap(),0,dsb->buffer->memory);
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb->pwfx);
- HeapFree(GetProcessHeap(),0,dsb);
- *pdsb = NULL;
- return DSERR_GENERIC;
- }
+ /* Allocate system memory for buffer */
+ dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
+ if (dsb->buffer->memory == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb->pwfx);
+ HeapFree(GetProcessHeap(),0,dsb->buffer);
+ HeapFree(GetProcessHeap(),0,dsb);
+ *pdsb = NULL;
+ return DSERR_OUTOFMEMORY;
}
dsb->buffer->ref = 1;
/* It's not necessary to initialize values to zero since */
/* we allocated this structure with HEAP_ZERO_MEMORY... */
- dsb->buf_mixpos = dsb->sec_mixpos = 0;
+ dsb->sec_mixpos = 0;
dsb->state = STATE_STOPPED;
- dsb->freqAdjust = ((DWORD64)dsb->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
+ dsb->freqAdjust = dsb->freq / (float)device->pwfx->nSamplesPerSec;
dsb->nAvgBytesPerSec = dsb->freq *
dsbd->lpwfxFormat->nBlockAlign;
}
}
+ IDirectSoundBuffer8_AddRef(&dsb->IDirectSoundBuffer8_iface);
*pdsb = dsb;
return err;
}
-HRESULT IDirectSoundBufferImpl_Destroy(
- IDirectSoundBufferImpl *pdsb)
+void secondarybuffer_destroy(IDirectSoundBufferImpl *This)
{
- TRACE("(%p)\n",pdsb);
+ ULONG ref = InterlockedIncrement(&This->numIfaces);
- /* This keeps the *_Destroy functions from possibly deleting
- * this object until it is ready to be deleted */
- IDirectSoundBufferImpl_AddRef((LPDIRECTSOUNDBUFFER8)pdsb);
+ if (ref > 1)
+ WARN("Destroying buffer with %u in use interfaces\n", ref - 1);
- if (pdsb->iks) {
- WARN("iks not NULL\n");
- IKsBufferPropertySetImpl_Destroy(pdsb->iks);
- pdsb->iks = NULL;
- }
+ DirectSoundDevice_RemoveBuffer(This->device, This);
+ RtlDeleteResource(&This->lock);
- if (pdsb->ds3db) {
- WARN("ds3db not NULL\n");
- IDirectSound3DBufferImpl_Destroy(pdsb->ds3db);
- pdsb->ds3db = NULL;
+ This->buffer->ref--;
+ list_remove(&This->entry);
+ if (This->buffer->ref == 0) {
+ HeapFree(GetProcessHeap(), 0, This->buffer->memory);
+ HeapFree(GetProcessHeap(), 0, This->buffer);
}
- if (pdsb->notify) {
- WARN("notify not NULL\n");
- IDirectSoundNotifyImpl_Destroy(pdsb->notify);
- pdsb->notify = NULL;
- }
+ HeapFree(GetProcessHeap(), 0, This->notifies);
+ HeapFree(GetProcessHeap(), 0, This->pwfx);
+ HeapFree(GetProcessHeap(), 0, This);
- if (pdsb->secondary) {
- WARN("dsb not NULL\n");
- SecondaryBufferImpl_Destroy(pdsb->secondary);
- pdsb->secondary = NULL;
- }
-
- while (IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)pdsb) > 0);
-
- return S_OK;
+ TRACE("(%p) released\n", This);
}
HRESULT IDirectSoundBufferImpl_Duplicate(
{
IDirectSoundBufferImpl *dsb;
HRESULT hres = DS_OK;
- int size;
- TRACE("(%p,%p,%p)\n", device, pdsb, pdsb);
-
- dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
+ TRACE("(%p,%p,%p)\n", device, ppdsb, pdsb);
+ dsb = HeapAlloc(GetProcessHeap(),0,sizeof(*dsb));
if (dsb == NULL) {
WARN("out of memory\n");
*ppdsb = NULL;
return DSERR_OUTOFMEMORY;
}
- CopyMemory(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
+ RtlAcquireResourceShared(&pdsb->lock, TRUE);
- if (pdsb->hwbuf) {
- TRACE("duplicating hardware buffer\n");
+ CopyMemory(dsb, pdsb, sizeof(*dsb));
- hres = IDsDriver_DuplicateSoundBuffer(device->driver, pdsb->hwbuf,
- (LPVOID *)&dsb->hwbuf);
- if (FAILED(hres)) {
- WARN("IDsDriver_DuplicateSoundBuffer failed (%08x)\n", hres);
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return hres;
- }
+ dsb->pwfx = DSOUND_CopyFormat(pdsb->pwfx);
+
+ RtlReleaseResource(&pdsb->lock);
+
+ if (dsb->pwfx == NULL) {
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
}
dsb->buffer->ref++;
list_add_head(&dsb->buffer->buffers, &dsb->entry);
dsb->ref = 0;
+ dsb->refn = 0;
+ dsb->ref3D = 0;
+ dsb->refiks = 0;
+ dsb->numIfaces = 0;
dsb->state = STATE_STOPPED;
- dsb->buf_mixpos = dsb->sec_mixpos = 0;
+ dsb->sec_mixpos = 0;
+ dsb->notifies = NULL;
+ dsb->nrofnotifies = 0;
dsb->device = device;
- dsb->ds3db = NULL;
- dsb->iks = NULL; /* FIXME? */
- dsb->secondary = NULL;
- dsb->tmp_buffer = NULL;
DSOUND_RecalcFormat(dsb);
- DSOUND_MixToTemporary(dsb, 0, dsb->buflen, FALSE);
-
- /* variable sized struct so calculate size based on format */
- size = sizeof(WAVEFORMATEX) + pdsb->pwfx->cbSize;
-
- dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
- if (dsb->pwfx == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- CopyMemory(dsb->pwfx, pdsb->pwfx, size);
RtlInitializeResource(&dsb->lock);
hres = DirectSoundDevice_AddBuffer(device, dsb);
if (hres != DS_OK) {
RtlDeleteResource(&dsb->lock);
- HeapFree(GetProcessHeap(),0,dsb->tmp_buffer);
- HeapFree(GetProcessHeap(),0,dsb->buffer);
+ list_remove(&dsb->entry);
+ dsb->buffer->ref--;
HeapFree(GetProcessHeap(),0,dsb->pwfx);
HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = 0;
+ dsb = NULL;
}
+ IDirectSoundBuffer8_AddRef(&dsb->IDirectSoundBuffer8_iface);
*ppdsb = dsb;
return hres;
}
/*******************************************************************************
- * SecondaryBuffer
+ * IKsPropertySet
*/
-static HRESULT WINAPI SecondaryBufferImpl_QueryInterface(
- LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-
- return IDirectSoundBufferImpl_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb,riid,ppobj);
-}
-
-static ULONG WINAPI SecondaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI SecondaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- ULONG ref;
- TRACE("(%p)\n", This);
- ref = InterlockedDecrement(&(This->ref));
- TRACE("ref was %d\n", ref + 1);
-
- if (!ref) {
- This->dsb->secondary = 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)
-{
- SecondaryBufferImpl *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)
-{
- SecondaryBufferImpl *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)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%p,%d,%p)\n",This,lpwf,wfsize,wfwritten);
-
- return IDirectSoundBufferImpl_GetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,lpwf,wfsize,wfwritten);
-}
-
-static HRESULT WINAPI SecondaryBufferImpl_GetVolume(
- LPDIRECTSOUNDBUFFER8 iface,LPLONG vol)
+static inline IDirectSoundBufferImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
{
- SecondaryBufferImpl *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)
-{
- SecondaryBufferImpl *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)
-{
- SecondaryBufferImpl *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)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%p)\n",This,status);
-
- return IDirectSoundBufferImpl_GetStatus((LPDIRECTSOUNDBUFFER8)This->dsb,status);
-}
-
-static HRESULT WINAPI SecondaryBufferImpl_Initialize(
- LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND dsound,LPCDSBUFFERDESC dbsd)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%p,%p)\n",This,dsound,dbsd);
-
- return IDirectSoundBufferImpl_Initialize((LPDIRECTSOUNDBUFFER8)This->dsb,dsound,dbsd);
+ return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IKsPropertySet_iface);
}
-static HRESULT WINAPI SecondaryBufferImpl_Lock(
- LPDIRECTSOUNDBUFFER8 iface,
- DWORD writecursor,
- DWORD writebytes,
- LPVOID *lplpaudioptr1,
- LPDWORD audiobytes1,
- LPVOID *lplpaudioptr2,
- LPDWORD audiobytes2,
- DWORD dwFlags)
+/* IUnknown methods */
+static HRESULT WINAPI IKsPropertySetImpl_QueryInterface(IKsPropertySet *iface, REFIID riid,
+ void **ppobj)
{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x)\n",
- This,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,dwFlags);
+ IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
- return IDirectSoundBufferImpl_Lock((LPDIRECTSOUNDBUFFER8)This->dsb,
- writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,dwFlags);
-}
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-static HRESULT WINAPI SecondaryBufferImpl_Play(
- LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%08x,%08x,%08x)\n",This,reserved1,reserved2,flags);
-
- return IDirectSoundBufferImpl_Play((LPDIRECTSOUNDBUFFER8)This->dsb,reserved1,reserved2,flags);
+ return IDirectSoundBuffer_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj);
}
-static HRESULT WINAPI SecondaryBufferImpl_SetCurrentPosition(
- LPDIRECTSOUNDBUFFER8 iface,DWORD newpos)
+static ULONG WINAPI IKsPropertySetImpl_AddRef(IKsPropertySet *iface)
{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%d)\n",This,newpos);
+ IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
+ ULONG ref = InterlockedIncrement(&This->refiks);
- return IDirectSoundBufferImpl_SetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,newpos);
-}
+ TRACE("(%p) ref was %d\n", This, ref - 1);
-static HRESULT WINAPI SecondaryBufferImpl_SetFormat(
- LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX wfex)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%p)\n",This,wfex);
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
- return IDirectSoundBufferImpl_SetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,wfex);
+ return ref;
}
-static HRESULT WINAPI SecondaryBufferImpl_SetVolume(
- LPDIRECTSOUNDBUFFER8 iface,LONG vol)
+static ULONG WINAPI IKsPropertySetImpl_Release(IKsPropertySet *iface)
{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%d)\n",This,vol);
-
- return IDirectSoundBufferImpl_SetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol);
-}
+ IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
+ ULONG ref;
-static HRESULT WINAPI SecondaryBufferImpl_SetPan(
- LPDIRECTSOUNDBUFFER8 iface,LONG pan)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%d)\n",This,pan);
+ if (is_primary_buffer(This)){
+ ref = capped_refcount_dec(&This->refiks);
+ if(!ref)
+ capped_refcount_dec(&This->numIfaces);
+ TRACE("(%p) ref is now: %d\n", This, ref);
+ return ref;
+ }
- return IDirectSoundBufferImpl_SetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan);
-}
+ ref = InterlockedDecrement(&This->refiks);
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ secondarybuffer_destroy(This);
-static HRESULT WINAPI SecondaryBufferImpl_SetFrequency(
- LPDIRECTSOUNDBUFFER8 iface,DWORD freq)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%d)\n",This,freq);
+ TRACE("(%p) ref is now %d\n", This, ref);
- return IDirectSoundBufferImpl_SetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq);
+ return ref;
}
-static HRESULT WINAPI SecondaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface)
+static HRESULT WINAPI IKsPropertySetImpl_Get(IKsPropertySet *iface, REFGUID guidPropSet,
+ ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
+ ULONG cbPropData, ULONG *pcbReturned)
{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p)\n",This);
+ IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
- return IDirectSoundBufferImpl_Stop((LPDIRECTSOUNDBUFFER8)This->dsb);
-}
+ TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
+ This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
-static HRESULT WINAPI SecondaryBufferImpl_Unlock(
- LPDIRECTSOUNDBUFFER8 iface,
- LPVOID lpvAudioPtr1,
- DWORD dwAudioBytes1,
- LPVOID lpvAudioPtr2,
- DWORD dwAudioBytes2)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%p,%d,%p,%d)\n",
- This, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
-
- return IDirectSoundBufferImpl_Unlock((LPDIRECTSOUNDBUFFER8)This->dsb,
- lpvAudioPtr1,dwAudioBytes1,lpvAudioPtr2,dwAudioBytes2);
+ return E_PROP_ID_UNSUPPORTED;
}
-static HRESULT WINAPI SecondaryBufferImpl_Restore(
- LPDIRECTSOUNDBUFFER8 iface)
+static HRESULT WINAPI IKsPropertySetImpl_Set(IKsPropertySet *iface, REFGUID guidPropSet,
+ ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
+ ULONG cbPropData)
{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p)\n",This);
-
- return IDirectSoundBufferImpl_Restore((LPDIRECTSOUNDBUFFER8)This->dsb);
-}
+ IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
-static HRESULT WINAPI SecondaryBufferImpl_SetFX(
- LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%u,%p,%p)\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes);
+ TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
- return IDirectSoundBufferImpl_SetFX((LPDIRECTSOUNDBUFFER8)This->dsb,dwEffectsCount,pDSFXDesc,pdwResultCodes);
+ return E_PROP_ID_UNSUPPORTED;
}
-static HRESULT WINAPI SecondaryBufferImpl_AcquireResources(
- LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes)
+static HRESULT WINAPI IKsPropertySetImpl_QuerySupport(IKsPropertySet *iface, REFGUID guidPropSet,
+ ULONG dwPropID, ULONG *pTypeSupport)
{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%08u,%u,%p)\n",This,dwFlags,dwEffectsCount,pdwResultCodes);
-
- return IDirectSoundBufferImpl_AcquireResources((LPDIRECTSOUNDBUFFER8)This->dsb,dwFlags,dwEffectsCount,pdwResultCodes);
-}
+ IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface);
-static HRESULT WINAPI SecondaryBufferImpl_GetObjectInPath(
- LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID* ppObject)
-{
- SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface;
- TRACE("(%p,%s,%u,%s,%p)\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject);
+ TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
- return IDirectSoundBufferImpl_GetObjectInPath((LPDIRECTSOUNDBUFFER8)This->dsb,rguidObject,dwIndex,rguidInterface,ppObject);
+ return E_PROP_ID_UNSUPPORTED;
}
-static const IDirectSoundBuffer8Vtbl sbvt =
-{
- 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
+const IKsPropertySetVtbl iksbvt = {
+ IKsPropertySetImpl_QueryInterface,
+ IKsPropertySetImpl_AddRef,
+ IKsPropertySetImpl_Release,
+ IKsPropertySetImpl_Get,
+ IKsPropertySetImpl_Set,
+ IKsPropertySetImpl_QuerySupport
};
-
-HRESULT SecondaryBufferImpl_Create(
- IDirectSoundBufferImpl *dsb,
- SecondaryBufferImpl **psb)
-{
- SecondaryBufferImpl *sb;
- TRACE("(%p,%p)\n",dsb,psb);
-
- sb = 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;
-}
-
-static HRESULT SecondaryBufferImpl_Destroy(
- SecondaryBufferImpl *pdsb)
-{
- TRACE("(%p)\n",pdsb);
-
- while (SecondaryBufferImpl_Release((LPDIRECTSOUNDBUFFER8)pdsb) > 0);
-
- return S_OK;
-}
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
-
+#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include <windef.h>
//#include "mmsystem.h"
#include <mmddk.h>
#include <winternl.h>
-#include <winnls.h>
+//#include "winnls.h"
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-/*****************************************************************************
- * IDirectSoundCapture implementation structure
- */
-struct IDirectSoundCaptureImpl
-{
- /* IUnknown fields */
- const IDirectSoundCaptureVtbl *lpVtbl;
- LONG ref;
-
- DirectSoundCaptureDevice *device;
-};
-
-static HRESULT IDirectSoundCaptureImpl_Create(LPDIRECTSOUNDCAPTURE8 * ppds);
+typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
-
-/*****************************************************************************
- * IDirectSoundCaptureNotify implementation structure
- */
-struct IDirectSoundCaptureNotifyImpl
+/* IDirectSoundCaptureBuffer implementation structure */
+typedef struct IDirectSoundCaptureBufferImpl
+{
+ IDirectSoundCaptureBuffer8 IDirectSoundCaptureBuffer8_iface;
+ IDirectSoundNotify IDirectSoundNotify_iface;
+ LONG numIfaces; /* "in use interfaces" refcount */
+ LONG ref, refn;
+ /* IDirectSoundCaptureBuffer fields */
+ DirectSoundCaptureDevice *device;
+ DSCBUFFERDESC *pdscbd;
+ DWORD flags;
+ /* IDirectSoundNotify fields */
+ DSBPOSITIONNOTIFY *notifies;
+ int nrofnotifies;
+} IDirectSoundCaptureBufferImpl;
+
+/* DirectSoundCaptureDevice implementation structure */
+struct DirectSoundCaptureDevice
{
- /* IUnknown fields */
- const IDirectSoundNotifyVtbl *lpVtbl;
- LONG ref;
- IDirectSoundCaptureBufferImpl* dscb;
+ GUID guid;
+ LONG ref;
+ DSCCAPS drvcaps;
+ BYTE *buffer;
+ DWORD buflen, write_pos_bytes;
+ WAVEFORMATEX *pwfx;
+ IDirectSoundCaptureBufferImpl *capture_buffer;
+ DWORD state;
+ UINT timerID;
+ CRITICAL_SECTION lock;
+ IMMDevice *mmdevice;
+ IAudioClient *client;
+ IAudioCaptureClient *capture;
+ struct list entry;
};
-static HRESULT IDirectSoundCaptureNotifyImpl_Create(IDirectSoundCaptureBufferImpl *dscb,
- IDirectSoundCaptureNotifyImpl ** pdscn);
-
-
-DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS];
-
-static HRESULT DirectSoundCaptureDevice_Create(DirectSoundCaptureDevice ** ppDevice);
-
-static const char * const captureStateString[] = {
- "STATE_STOPPED",
- "STATE_STARTING",
- "STATE_CAPTURING",
- "STATE_STOPPING"
-};
-HRESULT DSOUND_CaptureCreate(
- REFIID riid,
- LPDIRECTSOUNDCAPTURE *ppDSC)
+static void capturebuffer_destroy(IDirectSoundCaptureBufferImpl *This)
{
- LPDIRECTSOUNDCAPTURE pDSC;
- HRESULT hr;
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSC);
-
- if (!IsEqualIID(riid, &IID_IUnknown) &&
- !IsEqualIID(riid, &IID_IDirectSoundCapture)) {
- *ppDSC = 0;
- return E_NOINTERFACE;
- }
+ if (This->device->state == STATE_CAPTURING)
+ This->device->state = STATE_STOPPING;
- /* Get dsound configuration */
- setup_dsound_options();
+ HeapFree(GetProcessHeap(),0, This->pdscbd);
- hr = IDirectSoundCaptureImpl_Create(&pDSC);
- if (hr == DS_OK) {
- IDirectSoundCapture_AddRef(pDSC);
- *ppDSC = pDSC;
- } else {
- WARN("IDirectSoundCaptureImpl_Create failed\n");
- *ppDSC = 0;
+ if (This->device->client) {
+ IAudioClient_Release(This->device->client);
+ This->device->client = NULL;
}
- return hr;
-}
-
-HRESULT DSOUND_CaptureCreate8(
- REFIID riid,
- LPDIRECTSOUNDCAPTURE8 *ppDSC8)
-{
- LPDIRECTSOUNDCAPTURE8 pDSC8;
- HRESULT hr;
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSC8);
-
- if (!IsEqualIID(riid, &IID_IUnknown) &&
- !IsEqualIID(riid, &IID_IDirectSoundCapture8)) {
- *ppDSC8 = 0;
- return E_NOINTERFACE;
+ if (This->device->capture) {
+ IAudioCaptureClient_Release(This->device->capture);
+ This->device->capture = NULL;
}
- /* Get dsound configuration */
- setup_dsound_options();
-
- hr = IDirectSoundCaptureImpl_Create(&pDSC8);
- if (hr == DS_OK) {
- IDirectSoundCapture_AddRef(pDSC8);
- *ppDSC8 = pDSC8;
- } else {
- WARN("IDirectSoundCaptureImpl_Create failed\n");
- *ppDSC8 = 0;
- }
+ /* remove from DirectSoundCaptureDevice */
+ This->device->capture_buffer = NULL;
- return hr;
+ HeapFree(GetProcessHeap(), 0, This->notifies);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
}
-/***************************************************************************
- * DirectSoundCaptureCreate [DSOUND.6]
- *
- * Create and initialize a DirectSoundCapture interface.
- *
- * PARAMS
- * lpcGUID [I] Address of the GUID that identifies the sound capture device.
- * lplpDSC [O] Address of a variable to receive the interface pointer.
- * pUnkOuter [I] Must be NULL.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
- * DSERR_OUTOFMEMORY
- *
- * NOTES
- * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
- * or NULL for the default device or DSDEVID_DefaultCapture or
- * DSDEVID_DefaultVoiceCapture.
- *
- * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
+/*******************************************************************************
+ * IDirectSoundNotify
*/
-HRESULT WINAPI DirectSoundCaptureCreate(
- LPCGUID lpcGUID,
- LPDIRECTSOUNDCAPTURE *ppDSC,
- LPUNKNOWN pUnkOuter)
+static inline struct IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundNotify(IDirectSoundNotify *iface)
{
- HRESULT hr;
- LPDIRECTSOUNDCAPTURE pDSC;
- TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC, pUnkOuter);
-
- if (ppDSC == NULL) {
- WARN("invalid parameter: ppDSC == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (pUnkOuter) {
- WARN("invalid parameter: pUnkOuter != NULL\n");
- *ppDSC = NULL;
- return DSERR_NOAGGREGATION;
- }
+ return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundNotify_iface);
+}
- hr = DSOUND_CaptureCreate(&IID_IDirectSoundCapture, &pDSC);
- if (hr == DS_OK) {
- hr = IDirectSoundCapture_Initialize(pDSC, lpcGUID);
- if (hr != DS_OK) {
- IDirectSoundCapture_Release(pDSC);
- pDSC = 0;
- }
- }
+static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(IDirectSoundNotify *iface, REFIID riid,
+ void **ppobj)
+{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
- *ppDSC = pDSC;
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj);
- return hr;
+ return IDirectSoundCaptureBuffer_QueryInterface(&This->IDirectSoundCaptureBuffer8_iface, riid, ppobj);
}
-/***************************************************************************
- * DirectSoundCaptureCreate8 [DSOUND.12]
- *
- * Create and initialize a DirectSoundCapture interface.
- *
- * PARAMS
- * lpcGUID [I] Address of the GUID that identifies the sound capture device.
- * lplpDSC [O] Address of a variable to receive the interface pointer.
- * pUnkOuter [I] Must be NULL.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
- * DSERR_OUTOFMEMORY
- *
- * NOTES
- * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
- * or NULL for the default device or DSDEVID_DefaultCapture or
- * DSDEVID_DefaultVoiceCapture.
- *
- * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
- */
-HRESULT WINAPI DirectSoundCaptureCreate8(
- LPCGUID lpcGUID,
- LPDIRECTSOUNDCAPTURE8 *ppDSC8,
- LPUNKNOWN pUnkOuter)
+static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(IDirectSoundNotify *iface)
{
- HRESULT hr;
- LPDIRECTSOUNDCAPTURE8 pDSC8;
- TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC8, pUnkOuter);
-
- if (ppDSC8 == NULL) {
- WARN("invalid parameter: ppDSC8 == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (pUnkOuter) {
- WARN("invalid parameter: pUnkOuter != NULL\n");
- *ppDSC8 = NULL;
- return DSERR_NOAGGREGATION;
- }
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ ULONG ref = InterlockedIncrement(&This->refn);
- hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &pDSC8);
- if (hr == DS_OK) {
- hr = IDirectSoundCapture_Initialize(pDSC8, lpcGUID);
- if (hr != DS_OK) {
- IDirectSoundCapture_Release(pDSC8);
- pDSC8 = 0;
- }
- }
+ TRACE("(%p) ref was %d\n", This, ref - 1);
- *ppDSC8 = pDSC8;
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
- return hr;
+ return ref;
}
-/***************************************************************************
- * DirectSoundCaptureEnumerateA [DSOUND.7]
- *
- * Enumerate all DirectSound drivers installed in the system.
- *
- * PARAMS
- * lpDSEnumCallback [I] Address of callback function.
- * lpContext [I] Address of user defined context passed to callback function.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_INVALIDPARAM
- */
-HRESULT WINAPI
-DirectSoundCaptureEnumerateA(
- LPDSENUMCALLBACKA lpDSEnumCallback,
- LPVOID lpContext)
+static ULONG WINAPI IDirectSoundNotifyImpl_Release(IDirectSoundNotify *iface)
{
- unsigned devs, wid;
- DSDRIVERDESC desc;
- GUID guid;
- int err;
-
- TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
-
- if (lpDSEnumCallback == NULL) {
- WARN("invalid parameter: lpDSEnumCallback == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ ULONG ref = InterlockedDecrement(&This->refn);
- devs = waveInGetNumDevs();
- if (devs > 0) {
- if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
- for (wid = 0; wid < devs; ++wid) {
- if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
- "Primary Sound Capture Driver",desc.szDrvname,lpContext);
- if (lpDSEnumCallback(NULL, "Primary Sound Capture Driver", desc.szDrvname, lpContext) == FALSE)
- return DS_OK;
- }
- }
- }
- }
- }
+ TRACE("(%p) ref was %d\n", This, ref + 1);
- for (wid = 0; wid < devs; ++wid) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
- debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext);
- if (lpDSEnumCallback(&DSOUND_capture_guids[wid], desc.szDesc, desc.szDrvname, lpContext) == FALSE)
- return DS_OK;
- }
- }
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ capturebuffer_destroy(This);
- return DS_OK;
+ return ref;
}
-/***************************************************************************
- * DirectSoundCaptureEnumerateW [DSOUND.8]
- *
- * Enumerate all DirectSound drivers installed in the system.
- *
- * PARAMS
- * lpDSEnumCallback [I] Address of callback function.
- * lpContext [I] Address of user defined context passed to callback function.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_INVALIDPARAM
- */
-HRESULT WINAPI
-DirectSoundCaptureEnumerateW(
- LPDSENUMCALLBACKW lpDSEnumCallback,
- LPVOID lpContext)
+static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(IDirectSoundNotify *iface,
+ DWORD howmuch, const DSBPOSITIONNOTIFY *notify)
{
- unsigned devs, wid;
- DSDRIVERDESC desc;
- GUID guid;
- int err;
- WCHAR wDesc[MAXPNAMELEN];
- WCHAR wName[MAXPNAMELEN];
-
- TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
- if (lpDSEnumCallback == NULL) {
- WARN("invalid parameter: lpDSEnumCallback == NULL\n");
- return DSERR_INVALIDPARAM;
+ if (howmuch > 0 && notify == NULL) {
+ WARN("invalid parameter: notify == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- devs = waveInGetNumDevs();
- if (devs > 0) {
- if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
- for (wid = 0; wid < devs; ++wid) {
- if (IsEqualGUID( &guid, &DSOUND_capture_guids[wid] ) ) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
- "Primary Sound Capture Driver",desc.szDrvname,lpContext);
- MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
- wDesc, sizeof(wDesc)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
- wName, sizeof(wName)/sizeof(WCHAR) );
- if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
- return DS_OK;
- }
- }
- }
- }
+ if (TRACE_ON(dsound)) {
+ unsigned int i;
+ for (i=0;i<howmuch;i++)
+ TRACE("notify at %d to %p\n",
+ notify[i].dwOffset,notify[i].hEventNotify);
}
- for (wid = 0; wid < devs; ++wid) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
- debugstr_guid(&DSOUND_capture_guids[wid]),desc.szDesc,desc.szDrvname,lpContext);
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
- wDesc, sizeof(wDesc)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
- wName, sizeof(wName)/sizeof(WCHAR) );
- if (lpDSEnumCallback(&DSOUND_capture_guids[wid], wDesc, wName, lpContext) == FALSE)
- return DS_OK;
+ if (howmuch > 0) {
+ /* Make an internal copy of the caller-supplied array.
+ * Replace the existing copy if one is already present. */
+ if (This->notifies)
+ This->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->notifies,
+ howmuch * sizeof(DSBPOSITIONNOTIFY));
+ else
+ This->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ howmuch * sizeof(DSBPOSITIONNOTIFY));
+
+ if (!This->notifies) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
}
+ CopyMemory(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
+ This->nrofnotifies = howmuch;
+ } else {
+ HeapFree(GetProcessHeap(), 0, This->notifies);
+ This->notifies = NULL;
+ This->nrofnotifies = 0;
}
- return DS_OK;
+ return S_OK;
}
-static void capture_CheckNotify(IDirectSoundCaptureBufferImpl *This, DWORD from, DWORD len)
+static const IDirectSoundNotifyVtbl dscnvt =
{
- int i;
- for (i = 0; i < This->nrofnotifies; ++i) {
- LPDSBPOSITIONNOTIFY event = This->notifies + i;
- DWORD offset = event->dwOffset;
- TRACE("checking %d, position %d, event = %p\n", i, offset, event->hEventNotify);
+ IDirectSoundNotifyImpl_QueryInterface,
+ IDirectSoundNotifyImpl_AddRef,
+ IDirectSoundNotifyImpl_Release,
+ IDirectSoundNotifyImpl_SetNotificationPositions
+};
- if (offset == DSBPN_OFFSETSTOP) {
- if (!from && !len) {
- SetEvent(event->hEventNotify);
- TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
- return;
- }
- else return;
- }
- if (offset >= from && offset < (from + len))
- {
- TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
- SetEvent(event->hEventNotify);
- }
- }
-}
+static const char * const captureStateString[] = {
+ "STATE_STOPPED",
+ "STATE_STARTING",
+ "STATE_CAPTURING",
+ "STATE_STOPPING"
+};
-static void CALLBACK
-DSOUND_capture_callback(HWAVEIN hwi, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1,
- DWORD_PTR dw2)
-{
- DirectSoundCaptureDevice * This = (DirectSoundCaptureDevice*)dwUser;
- IDirectSoundCaptureBufferImpl * Moi = This->capture_buffer;
- TRACE("(%p,%08x(%s),%08lx,%08lx,%08lx) entering at %d\n",hwi,msg,
- msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" :
- msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount());
-
- if (msg == MM_WIM_DATA) {
- EnterCriticalSection( &(This->lock) );
- TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n",
- captureStateString[This->state],This->index);
- if (This->state != STATE_STOPPED) {
- int index = This->index;
- if (This->state == STATE_STARTING)
- This->state = STATE_CAPTURING;
- capture_CheckNotify(Moi, (DWORD_PTR)This->pwave[index].lpData - (DWORD_PTR)This->buffer, This->pwave[index].dwBufferLength);
- This->index = (This->index + 1) % This->nrofpwaves;
- if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
- TRACE("end of buffer\n");
- This->state = STATE_STOPPED;
- capture_CheckNotify(Moi, 0, 0);
- } else {
- if (This->state == STATE_CAPTURING) {
- waveInUnprepareHeader(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
- waveInPrepareHeader(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
- waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
- } else if (This->state == STATE_STOPPING) {
- TRACE("stopping\n");
- This->state = STATE_STOPPED;
- }
- }
- }
- TRACE("DirectSoundCapture new This->state=%s, new This->index=%d\n",
- captureStateString[This->state],This->index);
- LeaveCriticalSection( &(This->lock) );
- }
- TRACE("completed\n");
+/*******************************************************************************
+ * IDirectSoundCaptureBuffer
+ */
+static inline IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundCaptureBuffer8(IDirectSoundCaptureBuffer8 *iface)
+{
+ return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundCaptureBuffer8_iface);
}
-/***************************************************************************
- * IDirectSoundCaptureImpl
- */
-static HRESULT WINAPI
-IDirectSoundCaptureImpl_QueryInterface(
- LPDIRECTSOUNDCAPTURE iface,
- REFIID riid,
- LPVOID* ppobj )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_QueryInterface(IDirectSoundCaptureBuffer8 *iface,
+ REFIID riid, void **ppobj)
{
- IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+
TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
if (ppobj == NULL) {
*ppobj = NULL;
- if (IsEqualIID(riid, &IID_IUnknown)) {
- IDirectSoundCapture_AddRef((LPDIRECTSOUNDCAPTURE)This);
- *ppobj = This;
- return DS_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
- IDirectSoundCapture_AddRef((LPDIRECTSOUNDCAPTURE)This);
- *ppobj = This;
- return DS_OK;
+ if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer, riid ) ||
+ IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) {
+ IDirectSoundCaptureBuffer8_AddRef(iface);
+ *ppobj = iface;
+ return S_OK;
+ }
+
+ if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
+ IDirectSoundNotify_AddRef(&This->IDirectSoundNotify_iface);
+ *ppobj = &This->IDirectSoundNotify_iface;
+ return S_OK;
}
- WARN("unsupported riid: %s\n", debugstr_guid(riid));
+ FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
return E_NOINTERFACE;
}
-static ULONG WINAPI
-IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface )
+static ULONG WINAPI IDirectSoundCaptureBufferImpl_AddRef(IDirectSoundCaptureBuffer8 *iface)
{
- IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+
TRACE("(%p) ref was %d\n", This, ref - 1);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+
return ref;
}
-static ULONG WINAPI
-IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface )
+static ULONG WINAPI IDirectSoundCaptureBufferImpl_Release(IDirectSoundCaptureBuffer8 *iface)
{
- IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- if (This->device)
- DirectSoundCaptureDevice_Release(This->device);
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ capturebuffer_destroy(This);
- HeapFree( GetProcessHeap(), 0, This );
- TRACE("(%p) released\n", This);
- }
return ref;
}
-HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(
- LPDIRECTSOUNDCAPTURE iface,
- LPCDSCBUFFERDESC lpcDSCBufferDesc,
- LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
- LPUNKNOWN pUnk )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetCaps(IDirectSoundCaptureBuffer8 *iface,
+ DSCBCAPS *lpDSCBCaps)
{
- HRESULT hr;
- IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+ TRACE( "(%p,%p)\n", This, lpDSCBCaps );
- TRACE( "(%p,%p,%p,%p)\n",iface,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
+ if (lpDSCBCaps == NULL) {
+ WARN("invalid parameter: lpDSCBCaps == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
- if (lpcDSCBufferDesc == NULL) {
- WARN("invalid parameter: lpcDSCBufferDesc == NULL)\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (lplpDSCaptureBuffer == NULL) {
- WARN("invalid parameter: lplpDSCaptureBuffer == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (pUnk != NULL) {
- WARN("invalid parameter: pUnk != NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* FIXME: We can only have one buffer so what do we do here? */
- if (This->device->capture_buffer) {
- WARN("lnvalid parameter: already has buffer\n");
- return DSERR_INVALIDPARAM; /* DSERR_GENERIC ? */
- }
-
- hr = IDirectSoundCaptureBufferImpl_Create(This->device,
- (IDirectSoundCaptureBufferImpl **)lplpDSCaptureBuffer, lpcDSCBufferDesc);
-
- if (hr != DS_OK)
- WARN("IDirectSoundCaptureBufferImpl_Create failed\n");
-
- return hr;
-}
-
-HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(
- LPDIRECTSOUNDCAPTURE iface,
- LPDSCCAPS lpDSCCaps )
-{
- IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
- TRACE("(%p,%p)\n",This,lpDSCCaps);
-
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (lpDSCCaps== NULL) {
- WARN("invalid parameter: lpDSCCaps== NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (lpDSCCaps->dwSize < sizeof(*lpDSCCaps)) {
- WARN("invalid parameter: lpDSCCaps->dwSize = %d\n", lpDSCCaps->dwSize);
- return DSERR_INVALIDPARAM;
- }
-
- lpDSCCaps->dwFlags = This->device->drvcaps.dwFlags;
- lpDSCCaps->dwFormats = This->device->drvcaps.dwFormats;
- lpDSCCaps->dwChannels = This->device->drvcaps.dwChannels;
-
- TRACE("(flags=0x%08x,format=0x%08x,channels=%d)\n",lpDSCCaps->dwFlags,
- lpDSCCaps->dwFormats, lpDSCCaps->dwChannels);
-
- return DS_OK;
-}
-
-HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
- LPDIRECTSOUNDCAPTURE iface,
- LPCGUID lpcGUID )
-{
- IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
- TRACE("(%p,%s)\n", This, debugstr_guid(lpcGUID));
-
- if (This->device != NULL) {
- WARN("already initialized\n");
- return DSERR_ALREADYINITIALIZED;
- }
- return DirectSoundCaptureDevice_Initialize(&This->device, lpcGUID);
-}
-
-static const IDirectSoundCaptureVtbl dscvt =
-{
- /* IUnknown methods */
- IDirectSoundCaptureImpl_QueryInterface,
- IDirectSoundCaptureImpl_AddRef,
- IDirectSoundCaptureImpl_Release,
-
- /* IDirectSoundCapture methods */
- IDirectSoundCaptureImpl_CreateCaptureBuffer,
- IDirectSoundCaptureImpl_GetCaps,
- IDirectSoundCaptureImpl_Initialize
-};
-
-static HRESULT IDirectSoundCaptureImpl_Create(
- LPDIRECTSOUNDCAPTURE8 * ppDSC)
-{
- IDirectSoundCaptureImpl *pDSC;
- TRACE("(%p)\n", ppDSC);
-
- /* Allocate memory */
- pDSC = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundCaptureImpl));
- if (pDSC == NULL) {
- WARN("out of memory\n");
- *ppDSC = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pDSC->lpVtbl = &dscvt;
- pDSC->ref = 0;
- pDSC->device = NULL;
-
- *ppDSC = (LPDIRECTSOUNDCAPTURE8)pDSC;
-
- return DS_OK;
-}
-
-/*******************************************************************************
- * IDirectSoundCaptureNotify
- */
-static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_QueryInterface(
- LPDIRECTSOUNDNOTIFY iface,
- REFIID riid,
- LPVOID *ppobj)
-{
- IDirectSoundCaptureNotifyImpl *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)
-{
- IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI IDirectSoundCaptureNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface)
-{
- IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
-
- if (!ref) {
- if (This->dscb->hwnotify)
- IDsDriverNotify_Release(This->dscb->hwnotify);
- 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)
-{
- IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
- TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
-
- if (howmuch > 0 && notify == NULL) {
- WARN("invalid parameter: notify == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (TRACE_ON(dsound)) {
- unsigned int i;
- for (i=0;i<howmuch;i++)
- TRACE("notify at %d to %p\n",
- notify[i].dwOffset,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 if (howmuch > 0) {
- /* Make an internal copy of the caller-supplied array.
- * Replace the existing copy if one is already present. */
- if (This->dscb->notifies)
- This->dscb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- This->dscb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
- else
- This->dscb->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- howmuch * sizeof(DSBPOSITIONNOTIFY));
-
- if (This->dscb->notifies == NULL) {
- WARN("out of memory\n");
- return DSERR_OUTOFMEMORY;
- }
- CopyMemory(This->dscb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
- This->dscb->nrofnotifies = howmuch;
- } else {
- HeapFree(GetProcessHeap(), 0, This->dscb->notifies);
- This->dscb->notifies = NULL;
- This->dscb->nrofnotifies = 0;
- }
-
- return S_OK;
-}
-
-static const IDirectSoundNotifyVtbl dscnvt =
-{
- IDirectSoundCaptureNotifyImpl_QueryInterface,
- IDirectSoundCaptureNotifyImpl_AddRef,
- IDirectSoundCaptureNotifyImpl_Release,
- IDirectSoundCaptureNotifyImpl_SetNotificationPositions,
-};
-
-static HRESULT IDirectSoundCaptureNotifyImpl_Create(
- IDirectSoundCaptureBufferImpl *dscb,
- IDirectSoundCaptureNotifyImpl **pdscn)
-{
- IDirectSoundCaptureNotifyImpl * dscn;
- TRACE("(%p,%p)\n",dscb,pdscn);
-
- dscn = 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,
- REFIID riid,
- LPVOID* ppobj )
-{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
- HRESULT hres;
- TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
-
- if (ppobj == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
-
- *ppobj = NULL;
-
- if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
- if (!This->notify)
- hres = IDirectSoundCaptureNotifyImpl_Create(This, &This->notify);
- if (This->notify) {
- IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
- if (This->device->hwbuf && !This->hwnotify) {
- hres = IDsCaptureDriverBuffer_QueryInterface(This->device->hwbuf,
- &IID_IDsDriverNotify, (LPVOID*)&(This->hwnotify));
- if (hres != DS_OK) {
- WARN("IDsCaptureDriverBuffer_QueryInterface failed\n");
- IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
- *ppobj = 0;
- return hres;
- }
- }
-
- *ppobj = This->notify;
- return DS_OK;
- }
-
- WARN("IID_IDirectSoundNotify\n");
- return E_FAIL;
- }
-
- if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer, riid ) ||
- IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) {
- IDirectSoundCaptureBuffer8_AddRef(iface);
- *ppobj = This;
- return NO_ERROR;
- }
-
- FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
-{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI
-IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
-{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
-
- if (!ref) {
- TRACE("deleting object\n");
- if (This->device->state == STATE_CAPTURING)
- This->device->state = STATE_STOPPING;
-
- HeapFree(GetProcessHeap(),0, This->pdscbd);
-
- if (This->device->hwi) {
- waveInReset(This->device->hwi);
- waveInClose(This->device->hwi);
- HeapFree(GetProcessHeap(),0, This->device->pwave);
- This->device->pwave = 0;
- This->device->hwi = 0;
- }
-
- if (This->device->hwbuf)
- IDsCaptureDriverBuffer_Release(This->device->hwbuf);
-
- /* remove from DirectSoundCaptureDevice */
- This->device->capture_buffer = NULL;
-
- if (This->notify)
- IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
-
- /* If driver manages its own buffer, IDsCaptureDriverBuffer_Release
- should have freed the buffer. Prevent freeing it again in
- IDirectSoundCaptureBufferImpl_Create */
- if (!(This->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY))
- This->device->buffer = NULL;
-
- HeapFree(GetProcessHeap(), 0, This->notifies);
- HeapFree( GetProcessHeap(), 0, This );
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
-
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_GetCaps(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- LPDSCBCAPS lpDSCBCaps )
-{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
- TRACE( "(%p,%p)\n", This, lpDSCBCaps );
-
- if (lpDSCBCaps == NULL) {
- WARN("invalid parameter: lpDSCBCaps == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (lpDSCBCaps->dwSize < sizeof(DSCBCAPS)) {
- WARN("invalid parameter: lpDSCBCaps->dwSize = %d\n", lpDSCBCaps->dwSize);
- return DSERR_INVALIDPARAM;
+ if (lpDSCBCaps->dwSize < sizeof(DSCBCAPS)) {
+ WARN("invalid parameter: lpDSCBCaps->dwSize = %d\n", lpDSCBCaps->dwSize);
+ return DSERR_INVALIDPARAM;
}
if (This->device == NULL) {
return DS_OK;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_GetCurrentPosition(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- LPDWORD lpdwCapturePosition,
- LPDWORD lpdwReadPosition )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetCurrentPosition(IDirectSoundCaptureBuffer8 *iface,
+ DWORD *lpdwCapturePosition, DWORD *lpdwReadPosition)
{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
- HRESULT hres = DS_OK;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+
TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition );
if (This->device == NULL) {
return DSERR_INVALIDPARAM;
}
- if (This->device->driver) {
- hres = IDsCaptureDriverBuffer_GetPosition(This->device->hwbuf, lpdwCapturePosition, lpdwReadPosition );
- if (hres != DS_OK)
- WARN("IDsCaptureDriverBuffer_GetPosition failed\n");
- } else if (This->device->hwi) {
- DWORD pos;
+ EnterCriticalSection(&This->device->lock);
- EnterCriticalSection(&This->device->lock);
- pos = (DWORD_PTR)This->device->pwave[This->device->index].lpData - (DWORD_PTR)This->device->buffer;
- if (lpdwCapturePosition)
- *lpdwCapturePosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen;
- if (lpdwReadPosition)
- *lpdwReadPosition = pos;
+ if (!This->device->client) {
LeaveCriticalSection(&This->device->lock);
-
- } else {
WARN("no driver\n");
- hres = DSERR_NODRIVER;
+ return DSERR_NODRIVER;
}
+ if(lpdwCapturePosition)
+ *lpdwCapturePosition = This->device->write_pos_bytes;
+
+ if(lpdwReadPosition)
+ *lpdwReadPosition = This->device->write_pos_bytes;
+
+ LeaveCriticalSection(&This->device->lock);
+
TRACE("cappos=%d readpos=%d\n", (lpdwCapturePosition?*lpdwCapturePosition:-1), (lpdwReadPosition?*lpdwReadPosition:-1));
- TRACE("returning %08x\n", hres);
- return hres;
+ TRACE("returning DS_OK\n");
+
+ return DS_OK;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_GetFormat(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- LPWAVEFORMATEX lpwfxFormat,
- DWORD dwSizeAllocated,
- LPDWORD lpdwSizeWritten )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetFormat(IDirectSoundCaptureBuffer8 *iface,
+ WAVEFORMATEX *lpwfxFormat, DWORD dwSizeAllocated, DWORD *lpdwSizeWritten)
{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
HRESULT hres = DS_OK;
- TRACE( "(%p,%p,0x%08x,%p)\n", This, lpwfxFormat, dwSizeAllocated,
- lpdwSizeWritten );
+
+ TRACE("(%p,%p,0x%08x,%p)\n", This, lpwfxFormat, dwSizeAllocated, lpdwSizeWritten);
if (This->device == NULL) {
WARN("invalid parameter: This->device == NULL\n");
return hres;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_GetStatus(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- LPDWORD lpdwStatus )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetStatus(IDirectSoundCaptureBuffer8 *iface,
+ DWORD *lpdwStatus)
{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+
TRACE( "(%p, %p), thread is %04x\n", This, lpdwStatus, GetCurrentThreadId() );
if (This->device == NULL) {
return DS_OK;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_Initialize(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- LPDIRECTSOUNDCAPTURE lpDSC,
- LPCDSCBUFFERDESC lpcDSCBDesc )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Initialize(IDirectSoundCaptureBuffer8 *iface,
+ IDirectSoundCapture *lpDSC, const DSCBUFFERDESC *lpcDSCBDesc)
{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
FIXME( "(%p,%p,%p): stub\n", This, lpDSC, lpcDSCBDesc );
return DS_OK;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_Lock(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- DWORD dwReadCusor,
- DWORD dwReadBytes,
- LPVOID* lplpvAudioPtr1,
- LPDWORD lpdwAudioBytes1,
- LPVOID* lplpvAudioPtr2,
- LPDWORD lpdwAudioBytes2,
- DWORD dwFlags )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Lock(IDirectSoundCaptureBuffer8 *iface,
+ DWORD dwReadCusor, DWORD dwReadBytes, void **lplpvAudioPtr1, DWORD *lpdwAudioBytes1,
+ void **lplpvAudioPtr2, DWORD *lpdwAudioBytes2, DWORD dwFlags)
{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+
TRACE( "(%p,%08u,%08u,%p,%p,%p,%p,0x%08x) at %d\n", This, dwReadCusor,
dwReadBytes, lplpvAudioPtr1, lpdwAudioBytes1, lplpvAudioPtr2,
lpdwAudioBytes2, dwFlags, GetTickCount() );
EnterCriticalSection(&(This->device->lock));
- if (This->device->driver) {
- hres = IDsCaptureDriverBuffer_Lock(This->device->hwbuf, lplpvAudioPtr1,
- lpdwAudioBytes1, lplpvAudioPtr2,
- lpdwAudioBytes2, dwReadCusor,
- dwReadBytes, dwFlags);
- if (hres != DS_OK)
- WARN("IDsCaptureDriverBuffer_Lock failed\n");
- } else if (This->device->hwi) {
+ if (This->device->client) {
*lplpvAudioPtr1 = This->device->buffer + dwReadCusor;
if ( (dwReadCusor + dwReadBytes) > This->device->buflen) {
*lpdwAudioBytes1 = This->device->buflen - dwReadCusor;
return hres;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_Start(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- DWORD dwFlags )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Start(IDirectSoundCaptureBuffer8 *iface,
+ DWORD dwFlags)
{
- HRESULT hres = DS_OK;
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+ HRESULT hres;
+
TRACE( "(%p,0x%08x)\n", This, dwFlags );
if (This->device == NULL) {
return DSERR_INVALIDPARAM;
}
- if ( (This->device->driver == 0) && (This->device->hwi == 0) ) {
+ if ( !This->device->client ) {
WARN("no driver\n");
return DSERR_NODRIVER;
}
EnterCriticalSection(&(This->device->lock));
- This->flags = dwFlags;
- TRACE("old This->state=%s\n",captureStateString[This->device->state]);
if (This->device->state == STATE_STOPPED)
This->device->state = STATE_STARTING;
else if (This->device->state == STATE_STOPPING)
This->device->state = STATE_CAPTURING;
+ else
+ goto out;
TRACE("new This->device->state=%s\n",captureStateString[This->device->state]);
+ This->flags = dwFlags;
- LeaveCriticalSection(&(This->device->lock));
-
- if (This->device->driver) {
- hres = IDsCaptureDriverBuffer_Start(This->device->hwbuf, dwFlags);
- if (hres != DS_OK)
- WARN("IDsCaptureDriverBuffer_Start failed\n");
- } else if (This->device->hwi) {
- DirectSoundCaptureDevice *device = This->device;
-
- if (device->buffer) {
- int c;
- DWORD blocksize = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
- device->nrofpwaves = device->buflen / blocksize + !!(device->buflen % blocksize);
- TRACE("nrofpwaves=%d\n", device->nrofpwaves);
-
- /* prepare headers */
- if (device->pwave)
- device->pwave = HeapReAlloc(GetProcessHeap(), 0,device->pwave, device->nrofpwaves*sizeof(WAVEHDR));
- else
- device->pwave = HeapAlloc(GetProcessHeap(), 0, device->nrofpwaves*sizeof(WAVEHDR));
-
- for (c = 0; c < device->nrofpwaves; ++c) {
- device->pwave[c].lpData = (char *)device->buffer + c * blocksize;
- if (c + 1 == device->nrofpwaves)
- device->pwave[c].dwBufferLength = device->buflen - c * blocksize;
- else
- device->pwave[c].dwBufferLength = blocksize;
- device->pwave[c].dwBytesRecorded = 0;
- device->pwave[c].dwUser = (DWORD_PTR)device;
- device->pwave[c].dwFlags = 0;
- device->pwave[c].dwLoops = 0;
- hres = mmErr(waveInPrepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR)));
- if (hres != DS_OK) {
- WARN("waveInPrepareHeader failed\n");
- while (c--)
- waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
- break;
- }
-
- hres = mmErr(waveInAddBuffer(device->hwi, &(device->pwave[c]), sizeof(WAVEHDR)));
- if (hres != DS_OK) {
- WARN("waveInAddBuffer failed\n");
- while (c--)
- waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
- break;
- }
- }
-
- FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
- }
-
- device->index = 0;
-
- if (hres == DS_OK) {
- /* start filling the first buffer */
- hres = mmErr(waveInStart(device->hwi));
- if (hres != DS_OK)
- WARN("waveInStart failed\n");
- }
+ if (This->device->buffer)
+ FillMemory(This->device->buffer, This->device->buflen, (This->device->pwfx->wBitsPerSample == 8) ? 128 : 0);
- if (hres != DS_OK) {
- WARN("calling waveInClose because of error\n");
- waveInClose(device->hwi);
- device->hwi = 0;
- }
- } else {
- WARN("no driver\n");
- hres = DSERR_NODRIVER;
+ hres = IAudioClient_Start(This->device->client);
+ if(FAILED(hres)){
+ WARN("Start failed: %08x\n", hres);
+ LeaveCriticalSection(&This->device->lock);
+ return hres;
}
- TRACE("returning %08x\n", hres);
- return hres;
+out:
+ LeaveCriticalSection(&This->device->lock);
+
+ TRACE("returning DS_OK\n");
+ return DS_OK;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Stop(IDirectSoundCaptureBuffer8 *iface)
{
- HRESULT hres = DS_OK;
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
- TRACE( "(%p)\n", This );
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+ HRESULT hres;
+
+ TRACE("(%p)\n", This);
if (This->device == NULL) {
WARN("invalid parameter: This->device == NULL\n");
This->device->state = STATE_STOPPED;
TRACE("new This->device->state=%s\n",captureStateString[This->device->state]);
- LeaveCriticalSection(&(This->device->lock));
-
- if (This->device->driver) {
- hres = IDsCaptureDriverBuffer_Stop(This->device->hwbuf);
- if (hres != DS_OK)
- WARN("IDsCaptureDriverBuffer_Stop() failed\n");
- } else if (This->device->hwi) {
- hres = mmErr(waveInReset(This->device->hwi));
- if (hres != DS_OK)
- WARN("waveInReset() failed\n");
- } else {
- WARN("no driver\n");
- hres = DSERR_NODRIVER;
+ if(This->device->client){
+ hres = IAudioClient_Stop(This->device->client);
+ if(FAILED(hres)){
+ LeaveCriticalSection(&This->device->lock);
+ return hres;
+ }
}
- TRACE("returning %08x\n", hres);
- return hres;
+ LeaveCriticalSection(&(This->device->lock));
+
+ TRACE("returning DS_OK\n");
+ return DS_OK;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_Unlock(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- LPVOID lpvAudioPtr1,
- DWORD dwAudioBytes1,
- LPVOID lpvAudioPtr2,
- DWORD dwAudioBytes2 )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Unlock(IDirectSoundCaptureBuffer8 *iface,
+ void *lpvAudioPtr1, DWORD dwAudioBytes1, void *lpvAudioPtr2, DWORD dwAudioBytes2)
{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
HRESULT hres = DS_OK;
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+
TRACE( "(%p,%p,%08u,%p,%08u)\n", This, lpvAudioPtr1, dwAudioBytes1,
lpvAudioPtr2, dwAudioBytes2 );
return DSERR_INVALIDPARAM;
}
- if (This->device->driver) {
- hres = IDsCaptureDriverBuffer_Unlock(This->device->hwbuf, lpvAudioPtr1,
- dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
- if (hres != DS_OK)
- WARN("IDsCaptureDriverBuffer_Unlock failed\n");
- } else if (!This->device->hwi) {
+ if (!This->device->client) {
WARN("invalid call\n");
hres = DSERR_INVALIDCALL;
}
return hres;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_GetObjectInPath(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- REFGUID rguidObject,
- DWORD dwIndex,
- REFGUID rguidInterface,
- LPVOID* ppObject )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetObjectInPath(IDirectSoundCaptureBuffer8 *iface,
+ REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, void **ppObject)
{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
FIXME( "(%p,%s,%u,%s,%p): stub\n", This, debugstr_guid(rguidObject),
dwIndex, debugstr_guid(rguidInterface), ppObject );
- return DS_OK;
+ if (!ppObject)
+ return DSERR_INVALIDPARAM;
+
+ *ppObject = NULL;
+ return DSERR_CONTROLUNAVAIL;
}
-static HRESULT WINAPI
-IDirectSoundCaptureBufferImpl_GetFXStatus(
- LPDIRECTSOUNDCAPTUREBUFFER8 iface,
- DWORD dwFXCount,
- LPDWORD pdwFXStatus )
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetFXStatus(IDirectSoundCaptureBuffer8 *iface,
+ DWORD dwFXCount, DWORD *pdwFXStatus)
{
- IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
FIXME( "(%p,%u,%p): stub\n", This, dwFXCount, pdwFXStatus );
IDirectSoundCaptureBufferImpl_GetFXStatus
};
-HRESULT IDirectSoundCaptureBufferImpl_Create(
+static void capture_CheckNotify(IDirectSoundCaptureBufferImpl *This, DWORD from, DWORD len)
+{
+ int i;
+ for (i = 0; i < This->nrofnotifies; ++i) {
+ LPDSBPOSITIONNOTIFY event = This->notifies + i;
+ DWORD offset = event->dwOffset;
+ TRACE("checking %d, position %d, event = %p\n", i, offset, event->hEventNotify);
+
+ if (offset == DSBPN_OFFSETSTOP) {
+ if (!from && !len) {
+ SetEvent(event->hEventNotify);
+ TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
+ return;
+ }
+ else return;
+ }
+
+ if (offset >= from && offset < (from + len))
+ {
+ TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
+ SetEvent(event->hEventNotify);
+ }
+ }
+}
+
+static HRESULT IDirectSoundCaptureBufferImpl_Create(
DirectSoundCaptureDevice *device,
IDirectSoundCaptureBufferImpl ** ppobj,
LPCDSCBUFFERDESC lpcDSCBufferDesc)
{
LPWAVEFORMATEX wfex;
+ IDirectSoundCaptureBufferImpl *This;
TRACE( "(%p,%p,%p)\n", device, ppobj, lpcDSCBufferDesc);
if (ppobj == NULL) {
return DSERR_INVALIDPARAM;
}
+ *ppobj = NULL;
+
if (!device) {
WARN("not initialized\n");
- *ppobj = NULL;
return DSERR_UNINITIALIZED;
}
if (lpcDSCBufferDesc == NULL) {
WARN("invalid parameter: lpcDSCBufferDesc == NULL\n");
- *ppobj = NULL;
return DSERR_INVALIDPARAM;
}
if ( ((lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC)) &&
(lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC1))) ||
(lpcDSCBufferDesc->dwBufferBytes == 0) ||
- (lpcDSCBufferDesc->lpwfxFormat == NULL) ) {
+ (lpcDSCBufferDesc->lpwfxFormat == NULL) ) { /* FIXME: DSERR_BADFORMAT ? */
WARN("invalid lpcDSCBufferDesc\n");
- *ppobj = NULL;
return DSERR_INVALIDPARAM;
}
wfex = lpcDSCBufferDesc->lpwfxFormat;
- if (wfex) {
- TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
- "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
- wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
- wfex->nAvgBytesPerSec, wfex->nBlockAlign,
- wfex->wBitsPerSample, wfex->cbSize);
-
- if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
- device->pwfx = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEFORMATEX));
- *device->pwfx = *wfex;
- device->pwfx->cbSize = 0;
- } else {
- device->pwfx = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEFORMATEX)+wfex->cbSize);
- CopyMemory(device->pwfx, wfex, sizeof(WAVEFORMATEX)+wfex->cbSize);
- }
- } else {
- WARN("lpcDSCBufferDesc->lpwfxFormat == 0\n");
- *ppobj = NULL;
- return DSERR_INVALIDPARAM; /* FIXME: DSERR_BADFORMAT ? */
- }
+ TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
+ "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
+ wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
+ wfex->nAvgBytesPerSec, wfex->nBlockAlign,
+ wfex->wBitsPerSample, wfex->cbSize);
- *ppobj = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
+ device->pwfx = DSOUND_CopyFormat(wfex);
+ if ( device->pwfx == NULL )
+ return DSERR_OUTOFMEMORY;
+
+ This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
sizeof(IDirectSoundCaptureBufferImpl));
- if ( *ppobj == NULL ) {
+ if ( This == NULL ) {
WARN("out of memory\n");
- *ppobj = NULL;
return DSERR_OUTOFMEMORY;
} else {
- HRESULT err = DS_OK;
+ HRESULT err = DS_OK;
LPBYTE newbuf;
DWORD buflen;
- IDirectSoundCaptureBufferImpl *This = *ppobj;
- This->ref = 1;
+ This->numIfaces = 0;
+ This->ref = 0;
+ This->refn = 0;
This->device = device;
This->device->capture_buffer = This;
- This->notify = NULL;
- This->nrofnotifies = 0;
- This->hwnotify = NULL;
+ This->nrofnotifies = 0;
This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
lpcDSCBufferDesc->dwSize);
WARN("no memory\n");
This->device->capture_buffer = 0;
HeapFree( GetProcessHeap(), 0, This );
- *ppobj = NULL;
return DSERR_OUTOFMEMORY;
}
- This->lpVtbl = &dscbvt;
-
- if (device->driver) {
- if (This->device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- FIXME("DSDDESC_DOMMSYSTEMOPEN not supported\n");
-
- if (This->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
- /* allocate buffer from system memory */
- buflen = lpcDSCBufferDesc->dwBufferBytes;
- TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
- if (device->buffer)
- newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer,buflen);
- else
- newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
-
- if (newbuf == NULL) {
- WARN("failed to allocate capture buffer\n");
- err = DSERR_OUTOFMEMORY;
- /* but the old buffer might still exist and must be re-prepared */
- } else {
- device->buffer = newbuf;
- device->buflen = buflen;
- }
- } else {
- /* let driver allocate memory */
- device->buflen = lpcDSCBufferDesc->dwBufferBytes;
- /* FIXME: */
- HeapFree( GetProcessHeap(), 0, device->buffer);
- device->buffer = NULL;
- }
+ This->IDirectSoundCaptureBuffer8_iface.lpVtbl = &dscbvt;
+ This->IDirectSoundNotify_iface.lpVtbl = &dscnvt;
- err = IDsCaptureDriver_CreateCaptureBuffer(device->driver,
- device->pwfx,0,0,&(device->buflen),&(device->buffer),(LPVOID*)&(device->hwbuf));
- if (err != DS_OK) {
- WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n");
- This->device->capture_buffer = 0;
- HeapFree( GetProcessHeap(), 0, This );
- *ppobj = NULL;
- return err;
- }
- } else {
- DWORD flags = CALLBACK_FUNCTION;
- err = mmErr(waveInOpen(&(device->hwi),
- device->drvdesc.dnDevNode, device->pwfx,
- (DWORD_PTR)DSOUND_capture_callback, (DWORD_PTR)device, flags));
- if (err != DS_OK) {
- WARN("waveInOpen failed\n");
- This->device->capture_buffer = 0;
- HeapFree( GetProcessHeap(), 0, This );
- *ppobj = NULL;
- return err;
- }
+ err = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient,
+ CLSCTX_INPROC_SERVER, NULL, (void**)&device->client);
+ if(FAILED(err)){
+ WARN("Activate failed: %08x\n", err);
+ HeapFree(GetProcessHeap(), 0, This->pdscbd);
+ This->device->capture_buffer = 0;
+ HeapFree( GetProcessHeap(), 0, This );
+ return err;
+ }
- buflen = lpcDSCBufferDesc->dwBufferBytes;
- TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
- if (device->buffer)
- newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer,buflen);
- else
- newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
- if (newbuf == NULL) {
- WARN("failed to allocate capture buffer\n");
- err = DSERR_OUTOFMEMORY;
- /* but the old buffer might still exist and must be re-prepared */
- } else {
- device->buffer = newbuf;
- device->buflen = buflen;
- }
- }
+ err = IAudioClient_Initialize(device->client,
+ AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST,
+ 200 * 100000, 50000, device->pwfx, NULL);
+ if(FAILED(err)){
+ WARN("Initialize failed: %08x\n", err);
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ HeapFree(GetProcessHeap(), 0, This->pdscbd);
+ This->device->capture_buffer = 0;
+ HeapFree( GetProcessHeap(), 0, This );
+ if(err == AUDCLNT_E_UNSUPPORTED_FORMAT)
+ return DSERR_BADFORMAT;
+ return err;
+ }
+
+ err = IAudioClient_GetService(device->client, &IID_IAudioCaptureClient,
+ (void**)&device->capture);
+ if(FAILED(err)){
+ WARN("GetService failed: %08x\n", err);
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ HeapFree(GetProcessHeap(), 0, This->pdscbd);
+ This->device->capture_buffer = 0;
+ HeapFree( GetProcessHeap(), 0, This );
+ return err;
+ }
+
+ buflen = lpcDSCBufferDesc->dwBufferBytes;
+ TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
+ if (device->buffer)
+ newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer,buflen);
+ else
+ newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
+ if (newbuf == NULL) {
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ IAudioCaptureClient_Release(device->capture);
+ device->capture = NULL;
+ HeapFree(GetProcessHeap(), 0, This->pdscbd);
+ This->device->capture_buffer = 0;
+ HeapFree( GetProcessHeap(), 0, This );
+ return DSERR_OUTOFMEMORY;
+ }
+ device->buffer = newbuf;
+ device->buflen = buflen;
}
+ IDirectSoundCaptureBuffer_AddRef(&This->IDirectSoundCaptureBuffer8_iface);
+ *ppobj = This;
+
TRACE("returning DS_OK\n");
return DS_OK;
}
+
/*******************************************************************************
* DirectSoundCaptureDevice
*/
-HRESULT DirectSoundCaptureDevice_Initialize(
+static HRESULT DirectSoundCaptureDevice_Create(
+ DirectSoundCaptureDevice ** ppDevice)
+{
+ DirectSoundCaptureDevice * device;
+ TRACE("(%p)\n", ppDevice);
+
+ /* Allocate memory */
+ device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectSoundCaptureDevice));
+
+ if (device == NULL) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
+ }
+
+ device->ref = 1;
+ device->state = STATE_STOPPED;
+
+ InitializeCriticalSection( &(device->lock) );
+ device->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundCaptureDevice.lock");
+
+ *ppDevice = device;
+
+ return DS_OK;
+}
+
+static ULONG DirectSoundCaptureDevice_Release(
+ DirectSoundCaptureDevice * device)
+{
+ ULONG ref = InterlockedDecrement(&(device->ref));
+ TRACE("(%p) ref was %d\n", device, ref + 1);
+
+ if (!ref) {
+ TRACE("deleting object\n");
+
+ timeKillEvent(device->timerID);
+ timeEndPeriod(DS_TIME_RES);
+
+ EnterCriticalSection(&DSOUND_capturers_lock);
+ list_remove(&device->entry);
+ LeaveCriticalSection(&DSOUND_capturers_lock);
+
+ if (device->capture_buffer)
+ IDirectSoundCaptureBufferImpl_Release(&device->capture_buffer->IDirectSoundCaptureBuffer8_iface);
+
+ if(device->mmdevice)
+ IMMDevice_Release(device->mmdevice);
+ HeapFree(GetProcessHeap(), 0, device->pwfx);
+ device->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection( &(device->lock) );
+ HeapFree(GetProcessHeap(), 0, device);
+ TRACE("(%p) released\n", device);
+ }
+ return ref;
+}
+
+static void CALLBACK DSOUND_capture_timer(UINT timerID, UINT msg, DWORD_PTR user,
+ DWORD_PTR dw1, DWORD_PTR dw2)
+{
+ DirectSoundCaptureDevice *device = (DirectSoundCaptureDevice*)user;
+ UINT32 packet_frames, packet_bytes, avail_bytes;
+ DWORD flags;
+ BYTE *buf;
+ HRESULT hr;
+
+ if(!device->ref)
+ return;
+
+ EnterCriticalSection(&device->lock);
+
+ if(!device->capture_buffer || device->state == STATE_STOPPED){
+ LeaveCriticalSection(&device->lock);
+ return;
+ }
+
+ if(device->state == STATE_STOPPING){
+ device->state = STATE_STOPPED;
+ LeaveCriticalSection(&device->lock);
+ return;
+ }
+
+ if(device->state == STATE_STARTING)
+ device->state = STATE_CAPTURING;
+
+ hr = IAudioCaptureClient_GetBuffer(device->capture, &buf, &packet_frames,
+ &flags, NULL, NULL);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->lock);
+ WARN("GetBuffer failed: %08x\n", hr);
+ return;
+ }
+
+ packet_bytes = packet_frames * device->pwfx->nBlockAlign;
+
+ avail_bytes = device->buflen - device->write_pos_bytes;
+ if(avail_bytes > packet_bytes)
+ avail_bytes = packet_bytes;
+
+ memcpy(device->buffer + device->write_pos_bytes, buf, avail_bytes);
+ capture_CheckNotify(device->capture_buffer, device->write_pos_bytes, avail_bytes);
+
+ packet_bytes -= avail_bytes;
+ if(packet_bytes > 0){
+ if(device->capture_buffer->flags & DSCBSTART_LOOPING){
+ memcpy(device->buffer, buf + avail_bytes, packet_bytes);
+ capture_CheckNotify(device->capture_buffer, 0, packet_bytes);
+ }else{
+ device->state = STATE_STOPPED;
+ capture_CheckNotify(device->capture_buffer, 0, 0);
+ }
+ }
+
+ device->write_pos_bytes += avail_bytes + packet_bytes;
+ device->write_pos_bytes %= device->buflen;
+
+ hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_frames);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->lock);
+ WARN("ReleaseBuffer failed: %08x\n", hr);
+ return;
+ }
+
+ LeaveCriticalSection(&device->lock);
+}
+
+static struct _TestFormat {
+ DWORD flag;
+ DWORD rate;
+ DWORD depth;
+ WORD channels;
+} formats_to_test[] = {
+ { WAVE_FORMAT_1M08, 11025, 8, 1 },
+ { WAVE_FORMAT_1M16, 11025, 16, 1 },
+ { WAVE_FORMAT_1S08, 11025, 8, 2 },
+ { WAVE_FORMAT_1S16, 11025, 16, 2 },
+ { WAVE_FORMAT_2M08, 22050, 8, 1 },
+ { WAVE_FORMAT_2M16, 22050, 16, 1 },
+ { WAVE_FORMAT_2S08, 22050, 8, 2 },
+ { WAVE_FORMAT_2S16, 22050, 16, 2 },
+ { WAVE_FORMAT_4M08, 44100, 8, 1 },
+ { WAVE_FORMAT_4M16, 44100, 16, 1 },
+ { WAVE_FORMAT_4S08, 44100, 8, 2 },
+ { WAVE_FORMAT_4S16, 44100, 16, 2 },
+ { WAVE_FORMAT_48M08, 48000, 8, 1 },
+ { WAVE_FORMAT_48M16, 48000, 16, 1 },
+ { WAVE_FORMAT_48S08, 48000, 8, 2 },
+ { WAVE_FORMAT_48S16, 48000, 16, 2 },
+ { WAVE_FORMAT_96M08, 96000, 8, 1 },
+ { WAVE_FORMAT_96M16, 96000, 16, 1 },
+ { WAVE_FORMAT_96S08, 96000, 8, 2 },
+ { WAVE_FORMAT_96S16, 96000, 16, 2 },
+ {0}
+};
+
+static HRESULT DirectSoundCaptureDevice_Initialize(
DirectSoundCaptureDevice ** ppDevice,
LPCGUID lpcGUID)
{
- HRESULT err = DSERR_INVALIDPARAM;
- unsigned wid, widn;
- BOOLEAN found = FALSE;
+ HRESULT hr;
GUID devGUID;
- DirectSoundCaptureDevice *device = *ppDevice;
+ IMMDevice *mmdevice;
+ struct _TestFormat *fmt;
+ DirectSoundCaptureDevice *device;
+ IAudioClient *client;
+
TRACE("(%p, %s)\n", ppDevice, debugstr_guid(lpcGUID));
/* Default device? */
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
- lpcGUID = &DSDEVID_DefaultCapture;
+ lpcGUID = &DSDEVID_DefaultCapture;
+
+ if(IsEqualGUID(lpcGUID, &DSDEVID_DefaultPlayback) ||
+ IsEqualGUID(lpcGUID, &DSDEVID_DefaultVoicePlayback))
+ return DSERR_NODRIVER;
if (GetDeviceID(lpcGUID, &devGUID) != DS_OK) {
WARN("invalid parameter: lpcGUID\n");
return DSERR_INVALIDPARAM;
}
- widn = waveInGetNumDevs();
- if (!widn) {
- WARN("no audio devices found\n");
- return DSERR_NODRIVER;
- }
+ hr = get_mmdevice(eCapture, &devGUID, &mmdevice);
+ if(FAILED(hr))
+ return hr;
- /* enumerate WINMM audio devices and find the one we want */
- for (wid=0; wid<widn; wid++) {
- if (IsEqualGUID( &devGUID, &DSOUND_capture_guids[wid]) ) {
- found = TRUE;
- break;
- }
+ EnterCriticalSection(&DSOUND_capturers_lock);
+
+ LIST_FOR_EACH_ENTRY(device, &DSOUND_capturers, DirectSoundCaptureDevice, entry){
+ if(IsEqualGUID(&device->guid, &devGUID)){
+ IMMDevice_Release(mmdevice);
+ LeaveCriticalSection(&DSOUND_capturers_lock);
+ return DSERR_ALLOCATED;
+ }
}
- if (found == FALSE) {
- WARN("No device found matching given ID!\n");
- return DSERR_NODRIVER;
+ hr = DirectSoundCaptureDevice_Create(&device);
+ if (hr != DS_OK) {
+ WARN("DirectSoundCaptureDevice_Create failed\n");
+ LeaveCriticalSection(&DSOUND_capturers_lock);
+ return hr;
}
- if (DSOUND_capture[wid]) {
- WARN("already in use\n");
- return DSERR_ALLOCATED;
+ device->guid = devGUID;
+
+ device->mmdevice = mmdevice;
+
+ device->drvcaps.dwFlags = 0;
+
+ device->drvcaps.dwFormats = 0;
+ device->drvcaps.dwChannels = 0;
+ hr = IMMDevice_Activate(mmdevice, &IID_IAudioClient,
+ CLSCTX_INPROC_SERVER, NULL, (void**)&client);
+ if(FAILED(hr)){
+ device->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&device->lock);
+ HeapFree(GetProcessHeap(), 0, device);
+ LeaveCriticalSection(&DSOUND_capturers_lock);
+ return DSERR_NODRIVER;
}
- err = DirectSoundCaptureDevice_Create(&(device));
- if (err != DS_OK) {
- WARN("DirectSoundCaptureDevice_Create failed\n");
- return err;
+ for(fmt = formats_to_test; fmt->flag; ++fmt){
+ if(DSOUND_check_supported(client, fmt->rate, fmt->depth, fmt->channels)){
+ device->drvcaps.dwFormats |= fmt->flag;
+ if(fmt->channels > device->drvcaps.dwChannels)
+ device->drvcaps.dwChannels = fmt->channels;
+ }
}
+ IAudioClient_Release(client);
+
+ device->timerID = DSOUND_create_timer(DSOUND_capture_timer, (DWORD_PTR)device);
+
+ list_add_tail(&DSOUND_capturers, &device->entry);
*ppDevice = device;
- device->guid = devGUID;
- /* Disable the direct sound driver to force emulation if requested. */
- device->driver = NULL;
- if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
- {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&device->driver,0));
- if ( (err != DS_OK) && (err != DSERR_UNSUPPORTED) ) {
- WARN("waveInMessage failed; err=%x\n",err);
- return err;
- }
+ LeaveCriticalSection(&DSOUND_capturers_lock);
+
+ return S_OK;
+}
+
+
+/*****************************************************************************
+ * IDirectSoundCapture implementation structure
+ */
+typedef struct IDirectSoundCaptureImpl
+{
+ IUnknown IUnknown_inner;
+ IDirectSoundCapture IDirectSoundCapture_iface;
+ LONG ref, refdsc, numIfaces;
+ IUnknown *outer_unk; /* internal */
+ DirectSoundCaptureDevice *device;
+ BOOL has_dsc8;
+} IDirectSoundCaptureImpl;
+
+static void capture_destroy(IDirectSoundCaptureImpl *This)
+{
+ if (This->device)
+ DirectSoundCaptureDevice_Release(This->device);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n", This);
+}
+
+/*******************************************************************************
+ * IUnknown Implementation for DirectSoundCapture
+ */
+static inline IDirectSoundCaptureImpl *impl_from_IUnknown(IUnknown *iface)
+{
+ return CONTAINING_RECORD(iface, IDirectSoundCaptureImpl, IUnknown_inner);
+}
+
+static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
+
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
+
+ if (!ppv) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
}
- err = DS_OK;
+ *ppv = NULL;
- /* Get driver description */
- if (device->driver) {
- TRACE("using DirectSound driver\n");
- err = IDsCaptureDriver_GetDriverDesc(device->driver, &(device->drvdesc));
- if (err != DS_OK) {
- WARN("IDsCaptureDriver_GetDriverDesc failed\n");
- return err;
- }
- } else {
- TRACE("using WINMM\n");
- /* if no DirectSound interface available, use WINMM API instead */
- device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN |
- DSDDESC_DOMMSYSTEMSETFORMAT;
- }
-
- device->drvdesc.dnDevNode = wid;
-
- /* open the DirectSound driver if available */
- if (device->driver && (err == DS_OK))
- err = IDsCaptureDriver_Open(device->driver);
-
- if (err == DS_OK) {
- *ppDevice = device;
-
- /* the driver is now open, so it's now allowed to call GetCaps */
- if (device->driver) {
- device->drvcaps.dwSize = sizeof(device->drvcaps);
- err = IDsCaptureDriver_GetCaps(device->driver,&(device->drvcaps));
- if (err != DS_OK) {
- WARN("IDsCaptureDriver_GetCaps failed\n");
- return err;
- }
- } else /*if (device->hwi)*/ {
- WAVEINCAPSA wic;
- err = mmErr(waveInGetDevCapsA((UINT)device->drvdesc.dnDevNode, &wic, sizeof(wic)));
-
- if (err == DS_OK) {
- device->drvcaps.dwFlags = 0;
- lstrcpynA(device->drvdesc.szDrvname, wic.szPname,
- sizeof(device->drvdesc.szDrvname));
-
- device->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
- device->drvcaps.dwFormats = wic.dwFormats;
- device->drvcaps.dwChannels = wic.wChannels;
- }
- }
+ if (IsEqualIID(riid, &IID_IUnknown))
+ *ppv = &This->IUnknown_inner;
+ else if (IsEqualIID(riid, &IID_IDirectSoundCapture))
+ *ppv = &This->IDirectSoundCapture_iface;
+ else {
+ WARN("unknown IID %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
}
- return err;
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
}
-static HRESULT DirectSoundCaptureDevice_Create(
- DirectSoundCaptureDevice ** ppDevice)
+static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
{
- DirectSoundCaptureDevice * device;
- TRACE("(%p)\n", ppDevice);
+ IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
- /* Allocate memory */
- device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectSoundCaptureDevice));
+ TRACE("(%p) ref=%d\n", This, ref);
- if (device == NULL) {
- WARN("out of memory\n");
- return DSERR_OUTOFMEMORY;
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+ return ref;
+}
+
+static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ capture_destroy(This);
+ return ref;
+}
+
+static const IUnknownVtbl unk_vtbl =
+{
+ IUnknownImpl_QueryInterface,
+ IUnknownImpl_AddRef,
+ IUnknownImpl_Release
+};
+
+/***************************************************************************
+ * IDirectSoundCaptureImpl
+ */
+static inline struct IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
+{
+ return CONTAINING_RECORD(iface, struct IDirectSoundCaptureImpl, IDirectSoundCapture_iface);
+}
+
+static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture *iface,
+ REFIID riid, void **ppv)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
+ TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);
+ return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
+}
+
+static ULONG WINAPI IDirectSoundCaptureImpl_AddRef(IDirectSoundCapture *iface)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
+ ULONG ref = InterlockedIncrement(&This->refdsc);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+ return ref;
+}
+
+static ULONG WINAPI IDirectSoundCaptureImpl_Release(IDirectSoundCapture *iface)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
+ ULONG ref = InterlockedDecrement(&This->refdsc);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ capture_destroy(This);
+ return ref;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(IDirectSoundCapture *iface,
+ LPCDSCBUFFERDESC lpcDSCBufferDesc, IDirectSoundCaptureBuffer **lplpDSCaptureBuffer,
+ IUnknown *pUnk)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
+ HRESULT hr;
+
+ TRACE( "(%p,%p,%p,%p)\n",iface,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
+
+ if (pUnk) {
+ WARN("invalid parameter: pUnk != NULL\n");
+ return DSERR_NOAGGREGATION;
}
- device->ref = 1;
- device->state = STATE_STOPPED;
+ if (lpcDSCBufferDesc == NULL) {
+ WARN("invalid parameter: lpcDSCBufferDesc == NULL)\n");
+ return DSERR_INVALIDPARAM;
+ }
- InitializeCriticalSection( &(device->lock) );
- device->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundCaptureDevice.lock");
+ if (lplpDSCaptureBuffer == NULL) {
+ WARN("invalid parameter: lplpDSCaptureBuffer == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
- *ppDevice = device;
+ if (pUnk != NULL) {
+ WARN("invalid parameter: pUnk != NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* FIXME: We can only have one buffer so what do we do here? */
+ if (This->device->capture_buffer) {
+ WARN("invalid parameter: already has buffer\n");
+ return DSERR_INVALIDPARAM; /* DSERR_GENERIC ? */
+ }
+
+ hr = IDirectSoundCaptureBufferImpl_Create(This->device,
+ (IDirectSoundCaptureBufferImpl **)lplpDSCaptureBuffer, lpcDSCBufferDesc);
+
+ if (hr != DS_OK)
+ WARN("IDirectSoundCaptureBufferImpl_Create failed\n");
+
+ return hr;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(IDirectSoundCapture *iface,
+ LPDSCCAPS lpDSCCaps)
+{
+ IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
+
+ TRACE("(%p,%p)\n",This,lpDSCCaps);
+
+ if (This->device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ if (lpDSCCaps== NULL) {
+ WARN("invalid parameter: lpDSCCaps== NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (lpDSCCaps->dwSize < sizeof(*lpDSCCaps)) {
+ WARN("invalid parameter: lpDSCCaps->dwSize = %d\n", lpDSCCaps->dwSize);
+ return DSERR_INVALIDPARAM;
+ }
+
+ lpDSCCaps->dwFlags = This->device->drvcaps.dwFlags;
+ lpDSCCaps->dwFormats = This->device->drvcaps.dwFormats;
+ lpDSCCaps->dwChannels = This->device->drvcaps.dwChannels;
+
+ TRACE("(flags=0x%08x,format=0x%08x,channels=%d)\n",lpDSCCaps->dwFlags,
+ lpDSCCaps->dwFormats, lpDSCCaps->dwChannels);
return DS_OK;
}
-ULONG DirectSoundCaptureDevice_Release(
- DirectSoundCaptureDevice * device)
+static HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(IDirectSoundCapture *iface,
+ LPCGUID lpcGUID)
{
- ULONG ref = InterlockedDecrement(&(device->ref));
- TRACE("(%p) ref was %d\n", device, ref + 1);
+ IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
- if (!ref) {
- TRACE("deleting object\n");
- if (device->capture_buffer)
- IDirectSoundCaptureBufferImpl_Release(
- (LPDIRECTSOUNDCAPTUREBUFFER8) device->capture_buffer);
+ TRACE("(%p,%s)\n", This, debugstr_guid(lpcGUID));
+
+ if (This->device != NULL) {
+ WARN("already initialized\n");
+ return DSERR_ALREADYINITIALIZED;
+ }
+ return DirectSoundCaptureDevice_Initialize(&This->device, lpcGUID);
+}
+
+static const IDirectSoundCaptureVtbl dscvt =
+{
+ /* IUnknown methods */
+ IDirectSoundCaptureImpl_QueryInterface,
+ IDirectSoundCaptureImpl_AddRef,
+ IDirectSoundCaptureImpl_Release,
+
+ /* IDirectSoundCapture methods */
+ IDirectSoundCaptureImpl_CreateCaptureBuffer,
+ IDirectSoundCaptureImpl_GetCaps,
+ IDirectSoundCaptureImpl_Initialize
+};
+
+HRESULT IDirectSoundCaptureImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_dsc8)
+{
+ IDirectSoundCaptureImpl *obj;
+ HRESULT hr;
+
+ TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+ obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
+ if (obj == NULL) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
+ }
+
+ setup_dsound_options();
+
+ obj->IUnknown_inner.lpVtbl = &unk_vtbl;
+ obj->IDirectSoundCapture_iface.lpVtbl = &dscvt;
+ obj->ref = 1;
+ obj->refdsc = 0;
+ obj->numIfaces = 1;
+ obj->device = NULL;
+ obj->has_dsc8 = has_dsc8;
+
+ /* COM aggregation supported only internally */
+ if (outer_unk)
+ obj->outer_unk = outer_unk;
+ else
+ obj->outer_unk = &obj->IUnknown_inner;
+
+ hr = IUnknown_QueryInterface(&obj->IUnknown_inner, riid, ppv);
+ IUnknown_Release(&obj->IUnknown_inner);
+
+ return hr;
+}
- if (device->driver) {
- IDsCaptureDriver_Close(device->driver);
- IDsCaptureDriver_Release(device->driver);
+HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppv)
+{
+ return IDirectSoundCaptureImpl_Create(NULL, riid, ppv, FALSE);
+}
+
+HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppv)
+{
+ return IDirectSoundCaptureImpl_Create(NULL, riid, ppv, TRUE);
+}
+
+/***************************************************************************
+ * DirectSoundCaptureCreate [DSOUND.6]
+ *
+ * Create and initialize a DirectSoundCapture interface.
+ *
+ * PARAMS
+ * lpcGUID [I] Address of the GUID that identifies the sound capture device.
+ * lplpDSC [O] Address of a variable to receive the interface pointer.
+ * pUnkOuter [I] Must be NULL.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
+ * DSERR_OUTOFMEMORY
+ *
+ * NOTES
+ * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
+ * or NULL for the default device or DSDEVID_DefaultCapture or
+ * DSDEVID_DefaultVoiceCapture.
+ *
+ * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
+ */
+HRESULT WINAPI DirectSoundCaptureCreate(LPCGUID lpcGUID, IDirectSoundCapture **ppDSC,
+ IUnknown *pUnkOuter)
+{
+ HRESULT hr;
+ IDirectSoundCapture *pDSC;
+
+ TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC, pUnkOuter);
+
+ if (ppDSC == NULL) {
+ WARN("invalid parameter: ppDSC == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pUnkOuter) {
+ WARN("invalid parameter: pUnkOuter != NULL\n");
+ return DSERR_NOAGGREGATION;
+ }
+
+ hr = DSOUND_CaptureCreate(&IID_IDirectSoundCapture, (void**)&pDSC);
+ if (hr == DS_OK) {
+ hr = IDirectSoundCapture_Initialize(pDSC, lpcGUID);
+ if (hr != DS_OK) {
+ IDirectSoundCapture_Release(pDSC);
+ pDSC = 0;
}
+ }
- HeapFree(GetProcessHeap(), 0, device->pwfx);
- device->lock.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection( &(device->lock) );
- DSOUND_capture[device->drvdesc.dnDevNode] = NULL;
- HeapFree(GetProcessHeap(), 0, device);
- TRACE("(%p) released\n", device);
+ *ppDSC = pDSC;
+
+ return hr;
+}
+
+/***************************************************************************
+ * DirectSoundCaptureCreate8 [DSOUND.12]
+ *
+ * Create and initialize a DirectSoundCapture interface.
+ *
+ * PARAMS
+ * lpcGUID [I] Address of the GUID that identifies the sound capture device.
+ * lplpDSC [O] Address of a variable to receive the interface pointer.
+ * pUnkOuter [I] Must be NULL.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
+ * DSERR_OUTOFMEMORY
+ *
+ * NOTES
+ * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
+ * or NULL for the default device or DSDEVID_DefaultCapture or
+ * DSDEVID_DefaultVoiceCapture.
+ *
+ * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
+ */
+HRESULT WINAPI DirectSoundCaptureCreate8(
+ LPCGUID lpcGUID,
+ LPDIRECTSOUNDCAPTURE8 *ppDSC8,
+ LPUNKNOWN pUnkOuter)
+{
+ HRESULT hr;
+ LPDIRECTSOUNDCAPTURE8 pDSC8;
+ TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC8, pUnkOuter);
+
+ if (ppDSC8 == NULL) {
+ WARN("invalid parameter: ppDSC8 == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- return ref;
+
+ if (pUnkOuter) {
+ WARN("invalid parameter: pUnkOuter != NULL\n");
+ *ppDSC8 = NULL;
+ return DSERR_NOAGGREGATION;
+ }
+
+ hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, (void**)&pDSC8);
+ if (hr == DS_OK) {
+ hr = IDirectSoundCapture_Initialize(pDSC8, lpcGUID);
+ if (hr != DS_OK) {
+ IDirectSoundCapture_Release(pDSC8);
+ pDSC8 = 0;
+ }
+ }
+
+ *ppDSC8 = pDSC8;
+
+ return hr;
}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-//#include <stdarg.h>
-#include <stdio.h>
+#include <assert.h>
+#include <stdarg.h>
+//#include <stdio.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
-
+#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
-#include <windef.h>
-#include <winbase.h>
+//#include "windef.h"
+//#include "winbase.h"
//#include "winuser.h"
-#include <mmsystem.h>
#include <winternl.h>
-//#include "mmddk.h"
+#include "mmddk.h"
//#include "wingdi.h"
//#include "mmreg.h"
//#include "ks.h"
-#include <ksmedia.h>
+//#include "ksmedia.h"
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-/*****************************************************************************
- * IDirectSound COM components
- */
-struct IDirectSound_IUnknown {
- const IUnknownVtbl *lpVtbl;
- LONG ref;
- LPDIRECTSOUND8 pds;
-};
-
-static HRESULT IDirectSound_IUnknown_Create(LPDIRECTSOUND8 pds, LPUNKNOWN * ppunk);
+typedef struct IDirectSoundImpl {
+ IUnknown IUnknown_inner;
+ IDirectSound8 IDirectSound8_iface;
+ IUnknown *outer_unk; /* internal */
+ LONG ref, refds, numIfaces;
+ DirectSoundDevice *device;
+ BOOL has_ds8;
+} IDirectSoundImpl;
-struct IDirectSound_IDirectSound {
- const IDirectSoundVtbl *lpVtbl;
- LONG ref;
- LPDIRECTSOUND8 pds;
-};
-
-static HRESULT IDirectSound_IDirectSound_Create(LPDIRECTSOUND8 pds, LPDIRECTSOUND * ppds);
-
-/*****************************************************************************
- * IDirectSound8 COM components
- */
-struct IDirectSound8_IUnknown {
- const IUnknownVtbl *lpVtbl;
- LONG ref;
- LPDIRECTSOUND8 pds;
-};
-
-static HRESULT IDirectSound8_IUnknown_Create(LPDIRECTSOUND8 pds, LPUNKNOWN * ppunk);
-static ULONG WINAPI IDirectSound8_IUnknown_AddRef(LPUNKNOWN iface);
-
-struct IDirectSound8_IDirectSound {
- const IDirectSoundVtbl *lpVtbl;
- LONG ref;
- LPDIRECTSOUND8 pds;
-};
-
-static HRESULT IDirectSound8_IDirectSound_Create(LPDIRECTSOUND8 pds, LPDIRECTSOUND * ppds);
-static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(LPDIRECTSOUND iface);
-
-struct IDirectSound8_IDirectSound8 {
- const IDirectSound8Vtbl *lpVtbl;
- LONG ref;
- LPDIRECTSOUND8 pds;
-};
-
-static HRESULT IDirectSound8_IDirectSound8_Create(LPDIRECTSOUND8 pds, LPDIRECTSOUND8 * ppds);
-static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(LPDIRECTSOUND8 iface);
-
-/*****************************************************************************
- * IDirectSound implementation structure
- */
-struct IDirectSoundImpl
-{
- LONG ref;
-
- DirectSoundDevice *device;
- LPUNKNOWN pUnknown;
- LPDIRECTSOUND pDS;
- LPDIRECTSOUND8 pDS8;
-};
-
-static HRESULT IDirectSoundImpl_Create(LPDIRECTSOUND8 * ppds);
-
-static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
-static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
-
-static HRESULT DirectSoundDevice_VerifyCertification(DirectSoundDevice * device, LPDWORD pdwCertified);
-
-const char * dumpCooperativeLevel(DWORD level)
+static const char * dumpCooperativeLevel(DWORD level)
{
- static char unknown[32];
#define LE(x) case x: return #x
switch (level) {
LE(DSSCL_NORMAL);
LE(DSSCL_WRITEPRIMARY);
}
#undef LE
- sprintf(unknown, "Unknown(%08x)", (UINT)level);
- return unknown;
+ return wine_dbg_sprintf("Unknown(%08x)", level);
}
static void _dump_DSCAPS(DWORD xmask) {
TRACE("%s ",flags[i].name);
}
+static void directsound_destroy(IDirectSoundImpl *This)
+{
+ if (This->device)
+ DirectSoundDevice_Release(This->device);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n", This);
+}
+
/*******************************************************************************
- * IDirectSoundImpl_DirectSound
+ * IUnknown Implementation for DirectSound
*/
-static HRESULT DSOUND_QueryInterface(
- LPDIRECTSOUND8 iface,
- REFIID riid,
- LPVOID * ppobj)
+static inline IDirectSoundImpl *impl_from_IUnknown(IUnknown *iface)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-
- if (ppobj == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
-
- if (IsEqualIID(riid, &IID_IUnknown)) {
- if (!This->pUnknown) {
- IDirectSound_IUnknown_Create(iface, &This->pUnknown);
- if (!This->pUnknown) {
- WARN("IDirectSound_IUnknown_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSound_IUnknown_AddRef(This->pUnknown);
- *ppobj = This->pUnknown;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSound)) {
- if (!This->pDS) {
- IDirectSound_IDirectSound_Create(iface, &This->pDS);
- if (!This->pDS) {
- WARN("IDirectSound_IDirectSound_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSound_IDirectSound_AddRef(This->pDS);
- *ppobj = This->pDS;
- return S_OK;
- }
-
- *ppobj = NULL;
- WARN("Unknown IID %s\n",debugstr_guid(riid));
- return E_NOINTERFACE;
+ return CONTAINING_RECORD(iface, IDirectSoundImpl, IUnknown_inner);
}
-static HRESULT DSOUND_QueryInterface8(
- LPDIRECTSOUND8 iface,
- REFIID riid,
- LPVOID * ppobj)
+static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ IDirectSoundImpl *This = impl_from_IUnknown(iface);
- if (ppobj == NULL) {
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
+
+ if (!ppv) {
WARN("invalid parameter\n");
return E_INVALIDARG;
}
+ *ppv = NULL;
- if (IsEqualIID(riid, &IID_IUnknown)) {
- if (!This->pUnknown) {
- IDirectSound8_IUnknown_Create(iface, &This->pUnknown);
- if (!This->pUnknown) {
- WARN("IDirectSound8_IUnknown_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSound8_IUnknown_AddRef(This->pUnknown);
- *ppobj = This->pUnknown;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSound)) {
- if (!This->pDS) {
- IDirectSound8_IDirectSound_Create(iface, &This->pDS);
- if (!This->pDS) {
- WARN("IDirectSound8_IDirectSound_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSound8_IDirectSound_AddRef(This->pDS);
- *ppobj = This->pDS;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
- if (!This->pDS8) {
- IDirectSound8_IDirectSound8_Create(iface, &This->pDS8);
- if (!This->pDS8) {
- WARN("IDirectSound8_IDirectSound8_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSound8_IDirectSound8_AddRef(This->pDS8);
- *ppobj = This->pDS8;
- return S_OK;
+ if (IsEqualIID(riid, &IID_IUnknown))
+ *ppv = &This->IUnknown_inner;
+ else if (IsEqualIID(riid, &IID_IDirectSound) ||
+ (IsEqualIID(riid, &IID_IDirectSound8) && This->has_ds8))
+ *ppv = &This->IDirectSound8_iface;
+ else {
+ WARN("unknown IID %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
}
- *ppobj = NULL;
- WARN("Unknown IID %s\n",debugstr_guid(riid));
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
}
-static ULONG IDirectSoundImpl_AddRef(
- LPDIRECTSOUND8 iface)
+static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
+ IDirectSoundImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
-static ULONG IDirectSoundImpl_Release(
- LPDIRECTSOUND8 iface)
-{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
- if (!ref) {
- if (This->device)
- DirectSoundDevice_Release(This->device);
- HeapFree(GetProcessHeap(),0,This);
- TRACE("(%p) released\n", This);
- }
return ref;
}
-static HRESULT IDirectSoundImpl_Create(
- LPDIRECTSOUND8 * ppDS)
+static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
{
- IDirectSoundImpl* pDS;
- TRACE("(%p)\n",ppDS);
-
- /* Allocate memory */
- pDS = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
- if (pDS == NULL) {
- WARN("out of memory\n");
- *ppDS = NULL;
- return DSERR_OUTOFMEMORY;
- }
+ IDirectSoundImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
- pDS->ref = 0;
- pDS->device = NULL;
+ TRACE("(%p) ref=%d\n", This, ref);
- *ppDS = (LPDIRECTSOUND8)pDS;
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ directsound_destroy(This);
- return DS_OK;
-}
-
-/*******************************************************************************
- * IDirectSound_IUnknown
- */
-static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
- LPUNKNOWN iface,
- REFIID riid,
- LPVOID * ppobj)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface(This->pds, riid, ppobj);
-}
-
-static ULONG WINAPI IDirectSound_IUnknown_AddRef(
- LPUNKNOWN iface)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI IDirectSound_IUnknown_Release(
- LPUNKNOWN iface)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- ((IDirectSoundImpl*)This->pds)->pUnknown = NULL;
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
return ref;
}
-static const IUnknownVtbl DirectSound_Unknown_Vtbl =
+static const IUnknownVtbl unk_vtbl =
{
- IDirectSound_IUnknown_QueryInterface,
- IDirectSound_IUnknown_AddRef,
- IDirectSound_IUnknown_Release
+ IUnknownImpl_QueryInterface,
+ IUnknownImpl_AddRef,
+ IUnknownImpl_Release
};
-static HRESULT IDirectSound_IUnknown_Create(
- LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk)
-{
- IDirectSound_IUnknown * pdsunk;
- TRACE("(%p,%p)\n",pds,ppunk);
-
- if (ppunk == NULL) {
- ERR("invalid parameter: ppunk == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppunk = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
- if (pdsunk == NULL) {
- WARN("out of memory\n");
- *ppunk = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsunk->lpVtbl = &DirectSound_Unknown_Vtbl;
- pdsunk->ref = 0;
- pdsunk->pds = pds;
-
- IDirectSoundImpl_AddRef(pds);
- *ppunk = (LPUNKNOWN)pdsunk;
-
- return DS_OK;
-}
-
/*******************************************************************************
- * IDirectSound_IDirectSound
+ * IDirectSound and IDirectSound8 Implementation
*/
-static HRESULT WINAPI IDirectSound_IDirectSound_QueryInterface(
- LPDIRECTSOUND iface,
- REFIID riid,
- LPVOID * ppobj)
+static inline IDirectSoundImpl *impl_from_IDirectSound8(IDirectSound8 *iface)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface(This->pds, riid, ppobj);
+ return CONTAINING_RECORD(iface, IDirectSoundImpl, IDirectSound8_iface);
}
-static ULONG WINAPI IDirectSound_IDirectSound_AddRef(
- LPDIRECTSOUND iface)
+static HRESULT WINAPI IDirectSound8Impl_QueryInterface(IDirectSound8 *iface, REFIID riid,
+ void **ppv)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
+ return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
}
-static ULONG WINAPI IDirectSound_IDirectSound_Release(
- LPDIRECTSOUND iface)
+static ULONG WINAPI IDirectSound8Impl_AddRef(IDirectSound8 *iface)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- ((IDirectSoundImpl*)This->pds)->pDS = NULL;
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ ULONG ref = InterlockedIncrement(&This->refds);
-static HRESULT WINAPI IDirectSound_IDirectSound_CreateSoundBuffer(
- LPDIRECTSOUND iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DirectSoundDevice_CreateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,dsbd,ppdsb,lpunk,FALSE);
-}
+ TRACE("(%p) refds=%d\n", This, ref);
-static HRESULT WINAPI IDirectSound_IDirectSound_GetCaps(
- LPDIRECTSOUND iface,
- LPDSCAPS lpDSCaps)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
-}
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
-static HRESULT WINAPI IDirectSound_IDirectSound_DuplicateSoundBuffer(
- LPDIRECTSOUND iface,
- LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
+ return ref;
}
-static HRESULT WINAPI IDirectSound_IDirectSound_SetCooperativeLevel(
- LPDIRECTSOUND iface,
- HWND hwnd,
- DWORD level)
+static ULONG WINAPI IDirectSound8Impl_Release(IDirectSound8 *iface)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
- return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level);
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ ULONG ref = InterlockedDecrement(&(This->refds));
-static HRESULT WINAPI IDirectSound_IDirectSound_Compact(
- LPDIRECTSOUND iface)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p)\n", This);
- return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device);
-}
+ TRACE("(%p) refds=%d\n", This, ref);
-static HRESULT WINAPI IDirectSound_IDirectSound_GetSpeakerConfig(
- LPDIRECTSOUND iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
-}
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ directsound_destroy(This);
-static HRESULT WINAPI IDirectSound_IDirectSound_SetSpeakerConfig(
- LPDIRECTSOUND iface,
- DWORD config)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,0x%08x)\n",This,config);
- return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
+ return ref;
}
-static HRESULT WINAPI IDirectSound_IDirectSound_Initialize(
- LPDIRECTSOUND iface,
- LPCGUID lpcGuid)
+static HRESULT WINAPI IDirectSound8Impl_CreateSoundBuffer(IDirectSound8 *iface,
+ const DSBUFFERDESC *dsbd, IDirectSoundBuffer **ppdsb, IUnknown *lpunk)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid);
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ TRACE("(%p,%p,%p,%p)\n", This, dsbd, ppdsb, lpunk);
+ return DirectSoundDevice_CreateSoundBuffer(This->device, dsbd, ppdsb, lpunk, This->has_ds8);
}
-static const IDirectSoundVtbl DirectSound_DirectSound_Vtbl =
+static HRESULT WINAPI IDirectSound8Impl_GetCaps(IDirectSound8 *iface, DSCAPS *dscaps)
{
- IDirectSound_IDirectSound_QueryInterface,
- IDirectSound_IDirectSound_AddRef,
- IDirectSound_IDirectSound_Release,
- IDirectSound_IDirectSound_CreateSoundBuffer,
- IDirectSound_IDirectSound_GetCaps,
- IDirectSound_IDirectSound_DuplicateSoundBuffer,
- IDirectSound_IDirectSound_SetCooperativeLevel,
- IDirectSound_IDirectSound_Compact,
- IDirectSound_IDirectSound_GetSpeakerConfig,
- IDirectSound_IDirectSound_SetSpeakerConfig,
- IDirectSound_IDirectSound_Initialize
-};
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
-static HRESULT IDirectSound_IDirectSound_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND * ppds)
-{
- IDirectSound_IDirectSound * pdsds;
- TRACE("(%p,%p)\n",pds,ppds);
+ TRACE("(%p, %p)\n", This, dscaps);
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
- return DSERR_INVALIDPARAM;
+ if (!This->device) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
}
-
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppds = NULL;
+ if (!dscaps) {
+ WARN("invalid parameter: dscaps = NULL\n");
return DSERR_INVALIDPARAM;
}
-
- pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
- if (pdsds == NULL) {
- WARN("out of memory\n");
- *ppds = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsds->lpVtbl = &DirectSound_DirectSound_Vtbl;
- pdsds->ref = 0;
- pdsds->pds = pds;
-
- IDirectSoundImpl_AddRef(pds);
- *ppds = (LPDIRECTSOUND)pdsds;
-
- return DS_OK;
-}
-
-/*******************************************************************************
- * IDirectSound8_IUnknown
- */
-static HRESULT WINAPI IDirectSound8_IUnknown_QueryInterface(
- LPUNKNOWN iface,
- REFIID riid,
- LPVOID * ppobj)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface8(This->pds, riid, ppobj);
-}
-
-static ULONG WINAPI IDirectSound8_IUnknown_AddRef(
- LPUNKNOWN iface)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI IDirectSound8_IUnknown_Release(
- LPUNKNOWN iface)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- ((IDirectSoundImpl*)This->pds)->pUnknown = NULL;
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
-
-static const IUnknownVtbl DirectSound8_Unknown_Vtbl =
-{
- IDirectSound8_IUnknown_QueryInterface,
- IDirectSound8_IUnknown_AddRef,
- IDirectSound8_IUnknown_Release
-};
-
-static HRESULT IDirectSound8_IUnknown_Create(
- LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk)
-{
- IDirectSound8_IUnknown * pdsunk;
- TRACE("(%p,%p)\n",pds,ppunk);
-
- if (ppunk == NULL) {
- ERR("invalid parameter: ppunk == NULL\n");
+ if (dscaps->dwSize < sizeof(*dscaps)) {
+ WARN("invalid parameter: dscaps->dwSize = %d\n", dscaps->dwSize);
return DSERR_INVALIDPARAM;
}
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppunk = NULL;
- return DSERR_INVALIDPARAM;
- }
+ dscaps->dwFlags = This->device->drvcaps.dwFlags;
+ dscaps->dwMinSecondarySampleRate = This->device->drvcaps.dwMinSecondarySampleRate;
+ dscaps->dwMaxSecondarySampleRate = This->device->drvcaps.dwMaxSecondarySampleRate;
+ dscaps->dwPrimaryBuffers = This->device->drvcaps.dwPrimaryBuffers;
+ dscaps->dwMaxHwMixingAllBuffers = This->device->drvcaps.dwMaxHwMixingAllBuffers;
+ dscaps->dwMaxHwMixingStaticBuffers = This->device->drvcaps.dwMaxHwMixingStaticBuffers;
+ dscaps->dwMaxHwMixingStreamingBuffers = This->device->drvcaps.dwMaxHwMixingStreamingBuffers;
+ dscaps->dwFreeHwMixingAllBuffers = This->device->drvcaps.dwFreeHwMixingAllBuffers;
+ dscaps->dwFreeHwMixingStaticBuffers = This->device->drvcaps.dwFreeHwMixingStaticBuffers;
+ dscaps->dwFreeHwMixingStreamingBuffers = This->device->drvcaps.dwFreeHwMixingStreamingBuffers;
+ dscaps->dwMaxHw3DAllBuffers = This->device->drvcaps.dwMaxHw3DAllBuffers;
+ dscaps->dwMaxHw3DStaticBuffers = This->device->drvcaps.dwMaxHw3DStaticBuffers;
+ dscaps->dwMaxHw3DStreamingBuffers = This->device->drvcaps.dwMaxHw3DStreamingBuffers;
+ dscaps->dwFreeHw3DAllBuffers = This->device->drvcaps.dwFreeHw3DAllBuffers;
+ dscaps->dwFreeHw3DStaticBuffers = This->device->drvcaps.dwFreeHw3DStaticBuffers;
+ dscaps->dwFreeHw3DStreamingBuffers = This->device->drvcaps.dwFreeHw3DStreamingBuffers;
+ dscaps->dwTotalHwMemBytes = This->device->drvcaps.dwTotalHwMemBytes;
+ dscaps->dwFreeHwMemBytes = This->device->drvcaps.dwFreeHwMemBytes;
+ dscaps->dwMaxContigFreeHwMemBytes = This->device->drvcaps.dwMaxContigFreeHwMemBytes;
+ dscaps->dwUnlockTransferRateHwBuffers = This->device->drvcaps.dwUnlockTransferRateHwBuffers;
+ dscaps->dwPlayCpuOverheadSwBuffers = This->device->drvcaps.dwPlayCpuOverheadSwBuffers;
- pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
- if (pdsunk == NULL) {
- WARN("out of memory\n");
- *ppunk = NULL;
- return DSERR_OUTOFMEMORY;
+ if (TRACE_ON(dsound)) {
+ TRACE("(flags=0x%08x:\n", dscaps->dwFlags);
+ _dump_DSCAPS(dscaps->dwFlags);
+ TRACE(")\n");
}
- pdsunk->lpVtbl = &DirectSound8_Unknown_Vtbl;
- pdsunk->ref = 0;
- pdsunk->pds = pds;
-
- IDirectSoundImpl_AddRef(pds);
- *ppunk = (LPUNKNOWN)pdsunk;
-
return DS_OK;
}
-/*******************************************************************************
- * IDirectSound8_IDirectSound
- */
-static HRESULT WINAPI IDirectSound8_IDirectSound_QueryInterface(
- LPDIRECTSOUND iface,
- REFIID riid,
- LPVOID * ppobj)
+static HRESULT WINAPI IDirectSound8Impl_DuplicateSoundBuffer(IDirectSound8 *iface,
+ IDirectSoundBuffer *psb, IDirectSoundBuffer **ppdsb)
{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface8(This->pds, riid, ppobj);
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ TRACE("(%p,%p,%p)\n", This, psb, ppdsb);
+ return DirectSoundDevice_DuplicateSoundBuffer(This->device, psb, ppdsb);
}
-static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(
- LPDIRECTSOUND iface)
+static HRESULT WINAPI IDirectSound8Impl_SetCooperativeLevel(IDirectSound8 *iface, HWND hwnd,
+ DWORD level)
{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ DirectSoundDevice *device = This->device;
+ DWORD oldlevel;
+ HRESULT hr = S_OK;
-static ULONG WINAPI IDirectSound8_IDirectSound_Release(
- LPDIRECTSOUND iface)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- ((IDirectSoundImpl*)This->pds)->pDS = NULL;
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
+ TRACE("(%p,%p,%s)\n", This, hwnd, dumpCooperativeLevel(level));
-static HRESULT WINAPI IDirectSound8_IDirectSound_CreateSoundBuffer(
- LPDIRECTSOUND iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DirectSoundDevice_CreateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,dsbd,ppdsb,lpunk,TRUE);
-}
+ if (!device) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound_GetCaps(
- LPDIRECTSOUND iface,
- LPDSCAPS lpDSCaps)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
-}
+ if (level == DSSCL_PRIORITY || level == DSSCL_EXCLUSIVE) {
+ WARN("level=%s not fully supported\n",
+ level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound_DuplicateSoundBuffer(
- LPDIRECTSOUND iface,
- LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
+ RtlAcquireResourceExclusive(&device->buffer_list_lock, TRUE);
+ EnterCriticalSection(&device->mixlock);
+ oldlevel = device->priolevel;
+ device->priolevel = level;
+ if ((level == DSSCL_WRITEPRIMARY) != (oldlevel == DSSCL_WRITEPRIMARY)) {
+ hr = DSOUND_ReopenDevice(device, level == DSSCL_WRITEPRIMARY);
+ if (FAILED(hr))
+ device->priolevel = oldlevel;
+ else
+ DSOUND_PrimaryOpen(device);
+ }
+ LeaveCriticalSection(&device->mixlock);
+ RtlReleaseResource(&device->buffer_list_lock);
+ return hr;
}
-static HRESULT WINAPI IDirectSound8_IDirectSound_SetCooperativeLevel(
- LPDIRECTSOUND iface,
- HWND hwnd,
- DWORD level)
+static HRESULT WINAPI IDirectSound8Impl_Compact(IDirectSound8 *iface)
{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
- return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level);
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
-static HRESULT WINAPI IDirectSound8_IDirectSound_Compact(
- LPDIRECTSOUND iface)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p)\n", This);
- return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device);
-}
-static HRESULT WINAPI IDirectSound8_IDirectSound_GetSpeakerConfig(
- LPDIRECTSOUND iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
-}
+ if (!This->device) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound_SetSpeakerConfig(
- LPDIRECTSOUND iface,
- DWORD config)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,0x%08x)\n",This,config);
- return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
+ if (This->device->priolevel < DSSCL_PRIORITY) {
+ WARN("incorrect priority level\n");
+ return DSERR_PRIOLEVELNEEDED;
+ }
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound8_IDirectSound_Initialize(
- LPDIRECTSOUND iface,
- LPCGUID lpcGuid)
+static HRESULT WINAPI IDirectSound8Impl_GetSpeakerConfig(IDirectSound8 *iface, DWORD *config)
{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid);
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
-static const IDirectSoundVtbl DirectSound8_DirectSound_Vtbl =
-{
- IDirectSound8_IDirectSound_QueryInterface,
- IDirectSound8_IDirectSound_AddRef,
- IDirectSound8_IDirectSound_Release,
- IDirectSound8_IDirectSound_CreateSoundBuffer,
- IDirectSound8_IDirectSound_GetCaps,
- IDirectSound8_IDirectSound_DuplicateSoundBuffer,
- IDirectSound8_IDirectSound_SetCooperativeLevel,
- IDirectSound8_IDirectSound_Compact,
- IDirectSound8_IDirectSound_GetSpeakerConfig,
- IDirectSound8_IDirectSound_SetSpeakerConfig,
- IDirectSound8_IDirectSound_Initialize
-};
+ TRACE("(%p, %p)\n", This, config);
-static HRESULT IDirectSound8_IDirectSound_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND * ppds)
-{
- IDirectSound8_IDirectSound * pdsds;
- TRACE("(%p,%p)\n",pds,ppds);
-
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
- return DSERR_INVALIDPARAM;
+ if (!This->device) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
}
-
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppds = NULL;
+ if (!config) {
+ WARN("invalid parameter: config == NULL\n");
return DSERR_INVALIDPARAM;
}
- pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
- if (pdsds == NULL) {
- WARN("out of memory\n");
- *ppds = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsds->lpVtbl = &DirectSound8_DirectSound_Vtbl;
- pdsds->ref = 0;
- pdsds->pds = pds;
-
- IDirectSoundImpl_AddRef(pds);
- *ppds = (LPDIRECTSOUND)pdsds;
-
+ WARN("not fully functional\n");
+ *config = This->device->speaker_config;
return DS_OK;
}
-/*******************************************************************************
- * IDirectSound8_IDirectSound8
- */
-static HRESULT WINAPI IDirectSound8_IDirectSound8_QueryInterface(
- LPDIRECTSOUND8 iface,
- REFIID riid,
- LPVOID * ppobj)
+static HRESULT WINAPI IDirectSound8Impl_SetSpeakerConfig(IDirectSound8 *iface, DWORD config)
{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface8(This->pds, riid, ppobj);
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
-static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(
- LPDIRECTSOUND8 iface)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
+ TRACE("(%p,0x%08x)\n", This, config);
-static ULONG WINAPI IDirectSound8_IDirectSound8_Release(
- LPDIRECTSOUND8 iface)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- ((IDirectSoundImpl*)This->pds)->pDS8 = NULL;
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
+ if (!This->device) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
}
- return ref;
-}
-static HRESULT WINAPI IDirectSound8_IDirectSound8_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DirectSoundDevice_CreateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,dsbd,ppdsb,lpunk,TRUE);
-}
-
-static HRESULT WINAPI IDirectSound8_IDirectSound8_GetCaps(
- LPDIRECTSOUND8 iface,
- LPDSCAPS lpDSCaps)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
-}
-
-static HRESULT WINAPI IDirectSound8_IDirectSound8_DuplicateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
+ This->device->speaker_config = config;
+ WARN("not fully functional\n");
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound8_IDirectSound8_SetCooperativeLevel(
- LPDIRECTSOUND8 iface,
- HWND hwnd,
- DWORD level)
+static HRESULT WINAPI IDirectSound8Impl_Initialize(IDirectSound8 *iface, const GUID *lpcGuid)
{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
- return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level);
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return DirectSoundDevice_Initialize(&This->device, lpcGuid);
}
-static HRESULT WINAPI IDirectSound8_IDirectSound8_Compact(
- LPDIRECTSOUND8 iface)
+static HRESULT WINAPI IDirectSound8Impl_VerifyCertification(IDirectSound8 *iface, DWORD *certified)
{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p)\n", This);
- return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device);
-}
+ IDirectSoundImpl *This = impl_from_IDirectSound8(iface);
-static HRESULT WINAPI IDirectSound8_IDirectSound8_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
-}
+ TRACE("(%p, %p)\n", This, certified);
-static HRESULT WINAPI IDirectSound8_IDirectSound8_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- DWORD config)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,0x%08x)\n",This,config);
- return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
-}
+ if (!This->device) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound8_Initialize(
- LPDIRECTSOUND8 iface,
- LPCGUID lpcGuid)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid);
-}
+ if (This->device->drvcaps.dwFlags & DSCAPS_CERTIFIED)
+ *certified = DS_CERTIFIED;
+ else
+ *certified = DS_UNCERTIFIED;
-static HRESULT WINAPI IDirectSound8_IDirectSound8_VerifyCertification(
- LPDIRECTSOUND8 iface,
- LPDWORD pdwCertified)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p, %p)\n", This, pdwCertified);
- return DirectSoundDevice_VerifyCertification(((IDirectSoundImpl *)This->pds)->device,pdwCertified);
+ return DS_OK;
}
-static const IDirectSound8Vtbl DirectSound8_DirectSound8_Vtbl =
-{
- IDirectSound8_IDirectSound8_QueryInterface,
- IDirectSound8_IDirectSound8_AddRef,
- IDirectSound8_IDirectSound8_Release,
- IDirectSound8_IDirectSound8_CreateSoundBuffer,
- IDirectSound8_IDirectSound8_GetCaps,
- IDirectSound8_IDirectSound8_DuplicateSoundBuffer,
- IDirectSound8_IDirectSound8_SetCooperativeLevel,
- IDirectSound8_IDirectSound8_Compact,
- IDirectSound8_IDirectSound8_GetSpeakerConfig,
- IDirectSound8_IDirectSound8_SetSpeakerConfig,
- IDirectSound8_IDirectSound8_Initialize,
- IDirectSound8_IDirectSound8_VerifyCertification
+static const IDirectSound8Vtbl ds8_vtbl =
+{
+ IDirectSound8Impl_QueryInterface,
+ IDirectSound8Impl_AddRef,
+ IDirectSound8Impl_Release,
+ IDirectSound8Impl_CreateSoundBuffer,
+ IDirectSound8Impl_GetCaps,
+ IDirectSound8Impl_DuplicateSoundBuffer,
+ IDirectSound8Impl_SetCooperativeLevel,
+ IDirectSound8Impl_Compact,
+ IDirectSound8Impl_GetSpeakerConfig,
+ IDirectSound8Impl_SetSpeakerConfig,
+ IDirectSound8Impl_Initialize,
+ IDirectSound8Impl_VerifyCertification
};
-static HRESULT IDirectSound8_IDirectSound8_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND8 * ppds)
+HRESULT IDirectSoundImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_ds8)
{
- IDirectSound8_IDirectSound8 * pdsds;
- TRACE("(%p,%p)\n",pds,ppds);
-
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ IDirectSoundImpl *obj;
+ HRESULT hr;
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppds = NULL;
- return DSERR_INVALIDPARAM;
- }
+ TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
- pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
- if (pdsds == NULL) {
+ *ppv = NULL;
+ obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
+ if (!obj) {
WARN("out of memory\n");
- *ppds = NULL;
return DSERR_OUTOFMEMORY;
}
- pdsds->lpVtbl = &DirectSound8_DirectSound8_Vtbl;
- pdsds->ref = 0;
- pdsds->pds = pds;
+ setup_dsound_options();
+
+ obj->IUnknown_inner.lpVtbl = &unk_vtbl;
+ obj->IDirectSound8_iface.lpVtbl = &ds8_vtbl;
+ obj->ref = 1;
+ obj->refds = 0;
+ obj->numIfaces = 1;
+ obj->device = NULL;
+ obj->has_ds8 = has_ds8;
+
+ /* COM aggregation supported only internally */
+ if (outer_unk)
+ obj->outer_unk = outer_unk;
+ else
+ obj->outer_unk = &obj->IUnknown_inner;
- IDirectSoundImpl_AddRef(pds);
- *ppds = (LPDIRECTSOUND8)pdsds;
+ hr = IUnknown_QueryInterface(&obj->IUnknown_inner, riid, ppv);
+ IUnknown_Release(&obj->IUnknown_inner);
- return DS_OK;
+ return hr;
}
-HRESULT DSOUND_Create(
- REFIID riid,
- LPDIRECTSOUND *ppDS)
+HRESULT DSOUND_Create(REFIID riid, void **ppv)
{
- LPDIRECTSOUND8 pDS;
- HRESULT hr;
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppDS);
-
- if (!IsEqualIID(riid, &IID_IUnknown) &&
- !IsEqualIID(riid, &IID_IDirectSound)) {
- *ppDS = 0;
- return E_NOINTERFACE;
- }
-
- /* Get dsound configuration */
- setup_dsound_options();
-
- hr = IDirectSoundImpl_Create(&pDS);
- if (hr == DS_OK) {
- hr = IDirectSound_IDirectSound_Create(pDS, ppDS);
- if (*ppDS)
- IDirectSound_IDirectSound_AddRef(*ppDS);
- else {
- WARN("IDirectSound_IDirectSound_Create failed\n");
- IDirectSound8_Release(pDS);
- }
- } else {
- WARN("IDirectSoundImpl_Create failed\n");
- *ppDS = 0;
- }
+ return IDirectSoundImpl_Create(NULL, riid, ppv, FALSE);
+}
- return hr;
+HRESULT DSOUND_Create8(REFIID riid, void **ppv)
+{
+ return IDirectSoundImpl_Create(NULL, riid, ppv, TRUE);
}
/*******************************************************************************
return DSERR_INVALIDPARAM;
}
- hr = DSOUND_Create(&IID_IDirectSound, &pDS);
+ hr = DSOUND_Create(&IID_IDirectSound, (void **)&pDS);
if (hr == DS_OK) {
hr = IDirectSound_Initialize(pDS, lpcGUID);
if (hr != DS_OK) {
return hr;
}
-HRESULT DSOUND_Create8(
- REFIID riid,
- LPDIRECTSOUND8 *ppDS)
-{
- LPDIRECTSOUND8 pDS;
- HRESULT hr;
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppDS);
-
- if (!IsEqualIID(riid, &IID_IUnknown) &&
- !IsEqualIID(riid, &IID_IDirectSound) &&
- !IsEqualIID(riid, &IID_IDirectSound8)) {
- *ppDS = 0;
- return E_NOINTERFACE;
- }
-
- /* Get dsound configuration */
- setup_dsound_options();
-
- hr = IDirectSoundImpl_Create(&pDS);
- if (hr == DS_OK) {
- hr = IDirectSound8_IDirectSound8_Create(pDS, ppDS);
- if (*ppDS)
- IDirectSound8_IDirectSound8_AddRef(*ppDS);
- else {
- WARN("IDirectSound8_IDirectSound8_Create failed\n");
- IDirectSound8_Release(pDS);
- }
- } else {
- WARN("IDirectSoundImpl_Create failed\n");
- *ppDS = 0;
- }
-
- return hr;
-}
-
/*******************************************************************************
* DirectSoundCreate8 (DSOUND.11)
*
return DSERR_INVALIDPARAM;
}
- hr = DSOUND_Create8(&IID_IDirectSound8, &pDS);
+ hr = DSOUND_Create8(&IID_IDirectSound8, (void **)&pDS);
if (hr == DS_OK) {
hr = IDirectSound8_Initialize(pDS, lpcGUID);
if (hr != DS_OK) {
device->ref = 1;
device->priolevel = DSSCL_NORMAL;
device->state = STATE_STOPPED;
- device->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
+ device->speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE);
/* 3D listener initial parameters */
device->ds3dl.dwSize = sizeof(DS3DLISTENER);
device->guid = GUID_NULL;
/* Set default wave format (may need it for waveOutOpen) */
- device->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEX));
- if (device->pwfx == NULL) {
+ device->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEXTENSIBLE));
+ device->primary_pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEXTENSIBLE));
+ if (!device->pwfx || !device->primary_pwfx) {
WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,device->primary_pwfx);
+ HeapFree(GetProcessHeap(),0,device->pwfx);
HeapFree(GetProcessHeap(),0,device);
return DSERR_OUTOFMEMORY;
}
- /* We rely on the sound driver to return the actual sound format of
- * the device if it does not support 22050x8x2 and is given the
- * WAVE_DIRECTSOUND flag.
- */
device->pwfx->wFormatTag = WAVE_FORMAT_PCM;
- device->pwfx->nSamplesPerSec = ds_default_sample_rate;
- device->pwfx->wBitsPerSample = ds_default_bits_per_sample;
+ device->pwfx->nSamplesPerSec = 22050;
+ device->pwfx->wBitsPerSample = 8;
device->pwfx->nChannels = 2;
device->pwfx->nBlockAlign = device->pwfx->wBitsPerSample * device->pwfx->nChannels / 8;
device->pwfx->nAvgBytesPerSec = device->pwfx->nSamplesPerSec * device->pwfx->nBlockAlign;
device->pwfx->cbSize = 0;
+ memcpy(device->primary_pwfx, device->pwfx, sizeof(*device->pwfx));
InitializeCriticalSection(&(device->mixlock));
device->mixlock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundDevice.mixlock");
TRACE("(%p) ref was %u\n", device, ref + 1);
if (!ref) {
int i;
- timeKillEvent(device->timerID);
- timeEndPeriod(DS_TIME_RES);
- /* The kill event should have allowed the timer process to expire
- * but try to grab the lock just in case. Can't hold lock because
- * IDirectSoundBufferImpl_Destroy also grabs the lock */
- RtlAcquireResourceShared(&(device->buffer_list_lock), TRUE);
- RtlReleaseResource(&(device->buffer_list_lock));
+ SetEvent(device->sleepev);
+ if (device->thread) {
+ WaitForSingleObject(device->thread, INFINITE);
+ CloseHandle(device->thread);
+ }
+ CloseHandle(device->sleepev);
+
+ EnterCriticalSection(&DSOUND_renderers_lock);
+ list_remove(&device->entry);
+ LeaveCriticalSection(&DSOUND_renderers_lock);
/* It is allowed to release this object even when buffers are playing */
if (device->buffers) {
WARN("%d secondary buffers not released\n", device->nrofbuffers);
for( i=0;i<device->nrofbuffers;i++)
- IDirectSoundBufferImpl_Destroy(device->buffers[i]);
- }
-
- if (device->primary) {
- WARN("primary buffer not released\n");
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)device->primary);
+ secondarybuffer_destroy(device->buffers[i]);
}
hr = DSOUND_PrimaryDestroy(device);
if (hr != DS_OK)
WARN("DSOUND_PrimaryDestroy failed\n");
- if (device->driver)
- IDsDriver_Close(device->driver);
-
- if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(device->hwo);
-
- if (device->driver)
- IDsDriver_Release(device->driver);
-
- DSOUND_renderer[device->drvdesc.dnDevNode] = NULL;
+ if(device->client)
+ IAudioClient_Release(device->client);
+ if(device->render)
+ IAudioRenderClient_Release(device->render);
+ if(device->clock)
+ IAudioClock_Release(device->clock);
+ if(device->volume)
+ IAudioStreamVolume_Release(device->volume);
HeapFree(GetProcessHeap(), 0, device->tmp_buffer);
HeapFree(GetProcessHeap(), 0, device->mix_buffer);
- if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)
- HeapFree(GetProcessHeap(), 0, device->buffer);
+ HeapFree(GetProcessHeap(), 0, device->buffer);
RtlDeleteResource(&device->buffer_list_lock);
device->mixlock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&device->mixlock);
return ref;
}
-HRESULT DirectSoundDevice_GetCaps(
- DirectSoundDevice * device,
- LPDSCAPS lpDSCaps)
+BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate,
+ DWORD depth, WORD channels)
{
- TRACE("(%p,%p)\n",device,lpDSCaps);
+ WAVEFORMATEX fmt, *junk;
+ HRESULT hr;
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+ fmt.wFormatTag = WAVE_FORMAT_PCM;
+ fmt.nChannels = channels;
+ fmt.nSamplesPerSec = rate;
+ fmt.wBitsPerSample = depth;
+ fmt.nBlockAlign = (channels * depth) / 8;
+ fmt.nAvgBytesPerSec = rate * fmt.nBlockAlign;
+ fmt.cbSize = 0;
- if (lpDSCaps == NULL) {
- WARN("invalid parameter: lpDSCaps = NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &fmt, &junk);
+ if(SUCCEEDED(hr))
+ CoTaskMemFree(junk);
- /* check if there is enough room */
- if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
- WARN("invalid parameter: lpDSCaps->dwSize = %d\n", lpDSCaps->dwSize);
- return DSERR_INVALIDPARAM;
- }
+ return hr == S_OK;
+}
- lpDSCaps->dwFlags = device->drvcaps.dwFlags;
- if (TRACE_ON(dsound)) {
- TRACE("(flags=0x%08x:\n",lpDSCaps->dwFlags);
- _dump_DSCAPS(lpDSCaps->dwFlags);
- TRACE(")\n");
- }
- lpDSCaps->dwMinSecondarySampleRate = device->drvcaps.dwMinSecondarySampleRate;
- lpDSCaps->dwMaxSecondarySampleRate = device->drvcaps.dwMaxSecondarySampleRate;
- lpDSCaps->dwPrimaryBuffers = device->drvcaps.dwPrimaryBuffers;
- lpDSCaps->dwMaxHwMixingAllBuffers = device->drvcaps.dwMaxHwMixingAllBuffers;
- lpDSCaps->dwMaxHwMixingStaticBuffers = device->drvcaps.dwMaxHwMixingStaticBuffers;
- lpDSCaps->dwMaxHwMixingStreamingBuffers = device->drvcaps.dwMaxHwMixingStreamingBuffers;
- lpDSCaps->dwFreeHwMixingAllBuffers = device->drvcaps.dwFreeHwMixingAllBuffers;
- lpDSCaps->dwFreeHwMixingStaticBuffers = device->drvcaps.dwFreeHwMixingStaticBuffers;
- lpDSCaps->dwFreeHwMixingStreamingBuffers = device->drvcaps.dwFreeHwMixingStreamingBuffers;
- lpDSCaps->dwMaxHw3DAllBuffers = device->drvcaps.dwMaxHw3DAllBuffers;
- lpDSCaps->dwMaxHw3DStaticBuffers = device->drvcaps.dwMaxHw3DStaticBuffers;
- lpDSCaps->dwMaxHw3DStreamingBuffers = device->drvcaps.dwMaxHw3DStreamingBuffers;
- lpDSCaps->dwFreeHw3DAllBuffers = device->drvcaps.dwFreeHw3DAllBuffers;
- lpDSCaps->dwFreeHw3DStaticBuffers = device->drvcaps.dwFreeHw3DStaticBuffers;
- lpDSCaps->dwFreeHw3DStreamingBuffers = device->drvcaps.dwFreeHw3DStreamingBuffers;
- lpDSCaps->dwTotalHwMemBytes = device->drvcaps.dwTotalHwMemBytes;
- lpDSCaps->dwFreeHwMemBytes = device->drvcaps.dwFreeHwMemBytes;
- lpDSCaps->dwMaxContigFreeHwMemBytes = device->drvcaps.dwMaxContigFreeHwMemBytes;
-
- /* driver doesn't have these */
- lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
- lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
+UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user)
+{
+ UINT triggertime = DS_TIME_DEL, res = DS_TIME_RES, id;
+ TIMECAPS time;
- return DS_OK;
+ timeGetDevCaps(&time, sizeof(TIMECAPS));
+ TRACE("Minimum timer resolution: %u, max timer: %u\n", time.wPeriodMin, time.wPeriodMax);
+ if (triggertime < time.wPeriodMin)
+ triggertime = time.wPeriodMin;
+ if (res < time.wPeriodMin)
+ res = time.wPeriodMin;
+ if (timeBeginPeriod(res) == TIMERR_NOCANDO)
+ WARN("Could not set minimum resolution, don't expect sound\n");
+ id = timeSetEvent(triggertime, res, cb, user, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
+ if (!id)
+ {
+ WARN("Timer not created! Retrying without TIME_KILL_SYNCHRONOUS\n");
+ id = timeSetEvent(triggertime, res, cb, user, TIME_PERIODIC);
+ if (!id)
+ ERR("Could not create timer, sound playback will not occur\n");
+ }
+ return id;
}
HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcGUID)
{
HRESULT hr = DS_OK;
- unsigned wod, wodn;
- BOOLEAN found = FALSE;
GUID devGUID;
- DirectSoundDevice * device = *ppDevice;
+ DirectSoundDevice *device;
+ IMMDevice *mmdevice;
+
TRACE("(%p,%s)\n",ppDevice,debugstr_guid(lpcGUID));
if (*ppDevice != NULL) {
if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
lpcGUID = &DSDEVID_DefaultPlayback;
+ if(IsEqualGUID(lpcGUID, &DSDEVID_DefaultCapture) ||
+ IsEqualGUID(lpcGUID, &DSDEVID_DefaultVoiceCapture))
+ return DSERR_NODRIVER;
+
if (GetDeviceID(lpcGUID, &devGUID) != DS_OK) {
WARN("invalid parameter: lpcGUID\n");
return DSERR_INVALIDPARAM;
}
- /* Enumerate WINMM audio devices and find the one we want */
- wodn = waveOutGetNumDevs();
- if (!wodn) {
- WARN("no driver\n");
- return DSERR_NODRIVER;
- }
-
- for (wod=0; wod<wodn; wod++) {
- if (IsEqualGUID( &devGUID, &DSOUND_renderer_guids[wod])) {
- found = TRUE;
- break;
- }
- }
+ hr = get_mmdevice(eRender, &devGUID, &mmdevice);
+ if(FAILED(hr))
+ return hr;
- if (found == FALSE) {
- WARN("No device found matching given ID!\n");
- return DSERR_NODRIVER;
- }
+ EnterCriticalSection(&DSOUND_renderers_lock);
- if (DSOUND_renderer[wod]) {
- if (IsEqualGUID(&devGUID, &DSOUND_renderer[wod]->guid)) {
- device = DSOUND_renderer[wod];
+ LIST_FOR_EACH_ENTRY(device, &DSOUND_renderers, DirectSoundDevice, entry){
+ if(IsEqualGUID(&device->guid, &devGUID)){
+ IMMDevice_Release(mmdevice);
DirectSoundDevice_AddRef(device);
*ppDevice = device;
+ LeaveCriticalSection(&DSOUND_renderers_lock);
return DS_OK;
- } else {
- ERR("device GUID doesn't match\n");
- hr = DSERR_GENERIC;
- return hr;
- }
- } else {
- hr = DirectSoundDevice_Create(&device);
- if (hr != DS_OK) {
- WARN("DirectSoundDevice_Create failed\n");
- return hr;
}
}
- *ppDevice = device;
+ hr = DirectSoundDevice_Create(&device);
+ if(FAILED(hr)){
+ WARN("DirectSoundDevice_Create failed\n");
+ IMMDevice_Release(mmdevice);
+ LeaveCriticalSection(&DSOUND_renderers_lock);
+ return hr;
+ }
+
+ device->mmdevice = mmdevice;
device->guid = devGUID;
- device->driver = NULL;
+ device->sleepev = CreateEventW(0, 0, 0, 0);
- device->drvdesc.dnDevNode = wod;
hr = DSOUND_ReopenDevice(device, FALSE);
if (FAILED(hr))
{
+ HeapFree(GetProcessHeap(), 0, device);
+ LeaveCriticalSection(&DSOUND_renderers_lock);
+ IMMDevice_Release(mmdevice);
WARN("DSOUND_ReopenDevice failed: %08x\n", hr);
return hr;
}
- if (device->driver) {
- /* the driver is now open, so it's now allowed to call GetCaps */
- hr = IDsDriver_GetCaps(device->driver,&(device->drvcaps));
- if (hr != DS_OK) {
- WARN("IDsDriver_GetCaps failed\n");
- return hr;
- }
- } else {
- WAVEOUTCAPSA woc;
- hr = mmErr(waveOutGetDevCapsA(device->drvdesc.dnDevNode, &woc, sizeof(woc)));
- if (hr != DS_OK) {
- WARN("waveOutGetDevCaps failed\n");
- return hr;
- }
- ZeroMemory(&device->drvcaps, sizeof(device->drvcaps));
- if ((woc.dwFormats & WAVE_FORMAT_1M08) ||
- (woc.dwFormats & WAVE_FORMAT_2M08) ||
- (woc.dwFormats & WAVE_FORMAT_4M08) ||
- (woc.dwFormats & WAVE_FORMAT_48M08) ||
- (woc.dwFormats & WAVE_FORMAT_96M08)) {
- device->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- device->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
- }
- if ((woc.dwFormats & WAVE_FORMAT_1M16) ||
- (woc.dwFormats & WAVE_FORMAT_2M16) ||
- (woc.dwFormats & WAVE_FORMAT_4M16) ||
- (woc.dwFormats & WAVE_FORMAT_48M16) ||
- (woc.dwFormats & WAVE_FORMAT_96M16)) {
- device->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- device->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
- }
- if ((woc.dwFormats & WAVE_FORMAT_1S08) ||
- (woc.dwFormats & WAVE_FORMAT_2S08) ||
- (woc.dwFormats & WAVE_FORMAT_4S08) ||
- (woc.dwFormats & WAVE_FORMAT_48S08) ||
- (woc.dwFormats & WAVE_FORMAT_96S08)) {
- device->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- device->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
- }
- if ((woc.dwFormats & WAVE_FORMAT_1S16) ||
- (woc.dwFormats & WAVE_FORMAT_2S16) ||
- (woc.dwFormats & WAVE_FORMAT_4S16) ||
- (woc.dwFormats & WAVE_FORMAT_48S16) ||
- (woc.dwFormats & WAVE_FORMAT_96S16)) {
- device->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- device->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
- }
- if (ds_emuldriver)
- device->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
- device->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
- device->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
- ZeroMemory(&device->volpan, sizeof(device->volpan));
- }
+ ZeroMemory(&device->drvcaps, sizeof(device->drvcaps));
+
+ if(DSOUND_check_supported(device->client, 11025, 8, 1) ||
+ DSOUND_check_supported(device->client, 22050, 8, 1) ||
+ DSOUND_check_supported(device->client, 44100, 8, 1) ||
+ DSOUND_check_supported(device->client, 48000, 8, 1) ||
+ DSOUND_check_supported(device->client, 96000, 8, 1))
+ device->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT | DSCAPS_PRIMARYMONO;
+
+ if(DSOUND_check_supported(device->client, 11025, 16, 1) ||
+ DSOUND_check_supported(device->client, 22050, 16, 1) ||
+ DSOUND_check_supported(device->client, 44100, 16, 1) ||
+ DSOUND_check_supported(device->client, 48000, 16, 1) ||
+ DSOUND_check_supported(device->client, 96000, 16, 1))
+ device->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYMONO;
+
+ if(DSOUND_check_supported(device->client, 11025, 8, 2) ||
+ DSOUND_check_supported(device->client, 22050, 8, 2) ||
+ DSOUND_check_supported(device->client, 44100, 8, 2) ||
+ DSOUND_check_supported(device->client, 48000, 8, 2) ||
+ DSOUND_check_supported(device->client, 96000, 8, 2))
+ device->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT | DSCAPS_PRIMARYSTEREO;
+
+ if(DSOUND_check_supported(device->client, 11025, 16, 2) ||
+ DSOUND_check_supported(device->client, 22050, 16, 2) ||
+ DSOUND_check_supported(device->client, 44100, 16, 2) ||
+ DSOUND_check_supported(device->client, 48000, 16, 2) ||
+ DSOUND_check_supported(device->client, 96000, 16, 2))
+ device->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO;
+
+ /* the dsound mixer supports all of the following */
+ device->drvcaps.dwFlags |= DSCAPS_SECONDARY8BIT | DSCAPS_SECONDARY16BIT;
+ device->drvcaps.dwFlags |= DSCAPS_SECONDARYMONO | DSCAPS_SECONDARYSTEREO;
+ device->drvcaps.dwFlags |= DSCAPS_CONTINUOUSRATE;
+
+ device->drvcaps.dwPrimaryBuffers = 1;
+ device->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
+ device->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
+ device->drvcaps.dwMaxHwMixingAllBuffers = 1;
+ device->drvcaps.dwMaxHwMixingStaticBuffers = 1;
+ device->drvcaps.dwMaxHwMixingStreamingBuffers = 1;
+
+ ZeroMemory(&device->volpan, sizeof(device->volpan));
hr = DSOUND_PrimaryCreate(device);
if (hr == DS_OK) {
- UINT triggertime = DS_TIME_DEL, res = DS_TIME_RES, id;
- TIMECAPS time;
-
- DSOUND_renderer[device->drvdesc.dnDevNode] = device;
- timeGetDevCaps(&time, sizeof(TIMECAPS));
- TRACE("Minimum timer resolution: %u, max timer: %u\n", time.wPeriodMin, time.wPeriodMax);
- if (triggertime < time.wPeriodMin)
- triggertime = time.wPeriodMin;
- if (res < time.wPeriodMin)
- res = time.wPeriodMin;
- if (timeBeginPeriod(res) == TIMERR_NOCANDO)
- WARN("Could not set minimum resolution, don't expect sound\n");
- id = timeSetEvent(triggertime, res, DSOUND_timer, (DWORD_PTR)device, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
- if (!id)
- {
- WARN("Timer not created! Retrying without TIME_KILL_SYNCHRONOUS\n");
- id = timeSetEvent(triggertime, res, DSOUND_timer, (DWORD_PTR)device, TIME_PERIODIC);
- if (!id) ERR("Could not create timer, sound playback will not occur\n");
- }
- DSOUND_renderer[device->drvdesc.dnDevNode]->timerID = id;
- } else {
- WARN("DSOUND_PrimaryCreate failed\n");
- }
+ device->thread = CreateThread(0, 0, DSOUND_mixthread, device, 0, 0);
+ SetThreadPriority(device->thread, THREAD_PRIORITY_TIME_CRITICAL);
+ } else
+ WARN("DSOUND_PrimaryCreate failed: %08x\n", hr);
+
+ *ppDevice = device;
+ list_add_tail(&DSOUND_renderers, &device->entry);
+
+ LeaveCriticalSection(&DSOUND_renderers_lock);
return hr;
}
TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
}
+ if (dsbd->dwFlags & DSBCAPS_LOCHARDWARE &&
+ !(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
+ TRACE("LOCHARDWARE is not supported, returning E_NOTIMPL\n");
+ return E_NOTIMPL;
+ }
+
if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
if (dsbd->lpwfxFormat != NULL) {
WARN("invalid parameter: dsbd->lpwfxFormat must be NULL for "
IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(device->primary));
*ppdsb = (LPDIRECTSOUNDBUFFER)(device->primary);
} else {
- device->dsbd = *dsbd;
- device->dsbd.dwFlags &= ~(DSBCAPS_LOCHARDWARE | DSBCAPS_LOCSOFTWARE);
- if (device->hwbuf)
- device->dsbd.dwFlags |= DSBCAPS_LOCHARDWARE;
- else device->dsbd.dwFlags |= DSBCAPS_LOCSOFTWARE;
- hres = PrimaryBufferImpl_Create(device, &(device->primary), &(device->dsbd));
- if (device->primary) {
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(device->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER)(device->primary);
- } else
- WARN("PrimaryBufferImpl_Create failed\n");
+ hres = primarybuffer_create(device, &device->primary, dsbd);
+ if (device->primary) {
+ *ppdsb = (IDirectSoundBuffer*)&device->primary->IDirectSoundBuffer8_iface;
+ device->primary->dsbd.dwFlags &= ~(DSBCAPS_LOCHARDWARE | DSBCAPS_LOCSOFTWARE);
+ device->primary->dsbd.dwFlags |= DSBCAPS_LOCSOFTWARE;
+ } else
+ WARN("primarybuffer_create() failed\n");
}
} else {
IDirectSoundBufferImpl * dsb;
}
pwfxe = (WAVEFORMATEXTENSIBLE*)dsbd->lpwfxFormat;
- if (pwfxe->Format.wBitsPerSample != 16 && pwfxe->Format.wBitsPerSample != 8 && pwfxe->Format.wFormatTag != WAVE_FORMAT_EXTENSIBLE)
- {
- WARN("wBitsPerSample=%d needs a WAVEFORMATEXTENSIBLE\n", dsbd->lpwfxFormat->wBitsPerSample);
- return DSERR_CONTROLUNAVAIL;
- }
if (pwfxe->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
{
+ /* check if cbSize is at least 22 bytes */
if (pwfxe->Format.cbSize < (sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)))
{
WARN("Too small a cbSize %u\n", pwfxe->Format.cbSize);
return DSERR_INVALIDPARAM;
}
- if (pwfxe->Format.cbSize > (sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)))
+ /* cbSize should be 22 bytes, with one possible exception */
+ if (pwfxe->Format.cbSize > (sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) &&
+ !((IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) || IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) &&
+ pwfxe->Format.cbSize == sizeof(WAVEFORMATEXTENSIBLE)))
{
WARN("Too big a cbSize %u\n", pwfxe->Format.cbSize);
return DSERR_CONTROLUNAVAIL;
}
- if (!IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))
+ if ((!IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) && (!IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
{
if (!IsEqualGUID(&pwfxe->SubFormat, &GUID_NULL))
FIXME("SubFormat %s not supported right now.\n", debugstr_guid(&pwfxe->SubFormat));
}
hres = IDirectSoundBufferImpl_Create(device, &dsb, dsbd);
- if (dsb) {
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->secondary = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef(*ppdsb);
- } else
- WARN("SecondaryBufferImpl_Create failed\n");
- } else
- WARN("IDirectSoundBufferImpl_Create failed\n");
+ if (dsb)
+ *ppdsb = (IDirectSoundBuffer*)&dsb->IDirectSoundBuffer8_iface;
+ else
+ WARN("IDirectSoundBufferImpl_Create failed\n");
}
return hres;
}
/* make sure we have a secondary buffer */
- if ((PrimaryBufferImpl *)psb == device->primary) {
+ if (psb == (IDirectSoundBuffer *)&device->primary->IDirectSoundBuffer8_iface) {
WARN("trying to duplicate primary buffer\n");
*ppdsb = NULL;
return DSERR_INVALIDCALL;
}
/* duplicate the actual buffer implementation */
- hres = IDirectSoundBufferImpl_Duplicate(device, &dsb,
- ((SecondaryBufferImpl *)psb)->dsb);
-
- if (hres == DS_OK) {
- /* create a new secondary buffer using the new implementation */
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->secondary = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
- } else {
- WARN("SecondaryBufferImpl_Create failed\n");
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb);
- IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)dsb);
- }
- }
-
- return hres;
-}
-
-HRESULT DirectSoundDevice_SetCooperativeLevel(
- DirectSoundDevice * device,
- HWND hwnd,
- DWORD level)
-{
- TRACE("(%p,%p,%s)\n",device,hwnd,dumpCooperativeLevel(level));
-
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
- WARN("level=%s not fully supported\n",
- level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
- }
-
- device->priolevel = level;
- return DS_OK;
-}
-
-HRESULT DirectSoundDevice_Compact(
- DirectSoundDevice * device)
-{
- TRACE("(%p)\n", device);
-
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (device->priolevel < DSSCL_PRIORITY) {
- WARN("incorrect priority level\n");
- return DSERR_PRIOLEVELNEEDED;
- }
-
- return DS_OK;
-}
-
-HRESULT DirectSoundDevice_GetSpeakerConfig(
- DirectSoundDevice * device,
- LPDWORD lpdwSpeakerConfig)
-{
- TRACE("(%p, %p)\n", device, lpdwSpeakerConfig);
-
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (lpdwSpeakerConfig == NULL) {
- WARN("invalid parameter: lpdwSpeakerConfig == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- WARN("not fully functional\n");
- *lpdwSpeakerConfig = device->speaker_config;
- return DS_OK;
-}
-
-HRESULT DirectSoundDevice_SetSpeakerConfig(
- DirectSoundDevice * device,
- DWORD config)
-{
- TRACE("(%p,0x%08x)\n",device,config);
-
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- device->speaker_config = config;
- WARN("not fully functional\n");
- return DS_OK;
-}
-
-static HRESULT DirectSoundDevice_VerifyCertification(
- DirectSoundDevice * device,
- LPDWORD pdwCertified)
-{
- TRACE("(%p, %p)\n",device,pdwCertified);
-
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (device->drvcaps.dwFlags & DSCAPS_CERTIFIED)
- *pdwCertified = DS_CERTIFIED;
+ hres = IDirectSoundBufferImpl_Duplicate(device, &dsb, (IDirectSoundBufferImpl*)psb);
+ if (hres == DS_OK)
+ *ppdsb = (IDirectSoundBuffer*)&dsb->IDirectSoundBuffer8_iface;
else
- *pdwCertified = DS_UNCERTIFIED;
+ WARN("IDirectSoundBufferImpl_Duplicate failed\n");
- return DS_OK;
+ return hres;
}
/*
* Remove secondary buffer from buffer list.
* Gets exclusive access to buffer for writing.
*/
-HRESULT DirectSoundDevice_RemoveBuffer(
- DirectSoundDevice * device,
- IDirectSoundBufferImpl * pDSB)
+void DirectSoundDevice_RemoveBuffer(DirectSoundDevice * device, IDirectSoundBufferImpl * pDSB)
{
int i;
- HRESULT hr = DS_OK;
TRACE("(%p, %p)\n", device, pDSB);
RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
- for (i = 0; i < device->nrofbuffers; i++)
- if (device->buffers[i] == pDSB)
- break;
-
- if (i < device->nrofbuffers) {
- /* Put the last buffer of the list in the (now empty) position */
- device->buffers[i] = device->buffers[device->nrofbuffers - 1];
- device->nrofbuffers--;
- device->buffers = HeapReAlloc(GetProcessHeap(),0,device->buffers,sizeof(LPDIRECTSOUNDBUFFER8)*device->nrofbuffers);
- TRACE("buffer count is now %d\n", device->nrofbuffers);
- }
-
- if (device->nrofbuffers == 0) {
- HeapFree(GetProcessHeap(),0,device->buffers);
+ if (device->nrofbuffers == 1) {
+ assert(device->buffers[0] == pDSB);
+ HeapFree(GetProcessHeap(), 0, device->buffers);
device->buffers = NULL;
+ } else {
+ for (i = 0; i < device->nrofbuffers; i++) {
+ if (device->buffers[i] == pDSB) {
+ /* Put the last buffer of the list in the (now empty) position */
+ device->buffers[i] = device->buffers[device->nrofbuffers - 1];
+ break;
+ }
+ }
}
+ device->nrofbuffers--;
+ TRACE("buffer count is now %d\n", device->nrofbuffers);
RtlReleaseResource(&(device->buffer_list_lock));
-
- return hr;
}
--- /dev/null
+/*
+ * COM Classes for dsound
+ *
+ * Copyright 2010 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+[
+ helpstring("DirectSound Object"),
+ threading(both),
+ uuid(47d4d946-62e8-11cf-93bc-444553540000)
+]
+coclass DirectSound { interface IDirectSound; }
+
+[
+ helpstring("DirectSound 8.0 Object"),
+ threading(both),
+ uuid(3901cc3f-84b5-4fa4-ba35-aa8172b8a09b)
+]
+coclass DirectSound8 { interface IDirectSound8; }
+
+[
+ helpstring("DirectSoundBufferConfig Object"),
+ threading(both),
+ uuid(b2f586d4-5558-49d1-a07b-3249dbbb33c2)
+]
+coclass DirectSoundBufferConfig { interface IDirectSoundBufferConfig; }
+
+[
+ helpstring("DirectSoundCapture Object"),
+ threading(both),
+ uuid(b0210780-89cd-11d0-af08-00a0c925cd16)
+]
+coclass DirectSoundCapture { interface IDirectSoundCapture; }
+
+[
+ helpstring("DirectSoundCapture 8.0 Object"),
+ threading(both),
+ uuid(e4bcac13-7f99-4908-9a8e-74e3bf24b6e1)
+]
+coclass DirectSoundCapture8 { interface IDirectSoundCapture8; }
+
+[
+ helpstring("DirectSoundFullDuplex Object"),
+ threading(both),
+ uuid(fea4300c-7959-4147-b26a-2377b9e7a91d)
+]
+coclass DirectSoundFullDuplex { interface IDirectSoundFullDuplex; }
--- /dev/null
+HKCR
+{
+ NoRemove Interface
+ {
+ }
+ NoRemove CLSID
+ {
+ '{47D4D946-62E8-11CF-93BC-444553540000}' = s 'DirectSound Object'
+ {
+ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+ }
+ '{3901CC3F-84B5-4FA4-BA35-AA8172B8A09B}' = s 'DirectSound 8.0 Object'
+ {
+ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+ }
+ '{B2F586D4-5558-49D1-A07B-3249DBBB33C2}' = s 'DirectSoundBufferConfig Object'
+ {
+ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+ }
+ '{B0210780-89CD-11D0-AF08-00A0C925CD16}' = s 'DirectSoundCapture Object'
+ {
+ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+ }
+ '{E4BCAC13-7F99-4908-9A8E-74E3BF24B6E1}' = s 'DirectSoundCapture 8.0 Object'
+ {
+ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+ }
+ '{FEA4300C-7959-4147-B26A-2377B9E7A91D}' = s 'DirectSoundFullDuplex Object'
+ {
+ InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
+ }
+ }
+}
/* DirectSound format conversion and mixing routines
*
* Copyright 2007 Maarten Lankhorst
+ * Copyright 2011 Owen Rudge for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <config.h>
#include <stdarg.h>
+#include <math.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#include <winternl.h>
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
#define le32(x) (x)
#endif
-static inline void src_advance(const void **src, UINT stride, INT *count, UINT *freqAcc, UINT adj)
+/* This is an inlined version of lrintf. */
+#if defined(_M_IX86) && defined(_MSC_VER)
+FORCEINLINE
+int
+lrintf(float f)
{
- *freqAcc += adj;
- if (*freqAcc >= (1 << DSOUND_FREQSHIFT))
+ int result;
+ __asm
{
- ULONG adv = (*freqAcc >> DSOUND_FREQSHIFT);
- *freqAcc &= (1 << DSOUND_FREQSHIFT) - 1;
- *(const char **)src += adv * stride;
- *count -= adv;
+ fld f;
+ fistp result;
}
}
+#endif
-static void convert_8_to_8 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static float get8(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
{
- while (count > 0)
- {
- *(BYTE *)dst = *(const BYTE *)src;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ const BYTE* buf = dsb->buffer->memory;
+ buf += pos + channel;
+ return (buf[0] - 0x80) / (float)0x80;
}
-static void convert_8_to_16 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static float get16(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
{
- while (count > 0)
- {
- WORD dest = *(const BYTE *)src, *dest16 = dst;
- *dest16 = le16(dest * 257 - 32768);
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ const BYTE* buf = dsb->buffer->memory;
+ const SHORT *sbuf = (const SHORT*)(buf + pos + 2 * channel);
+ SHORT sample = (SHORT)le16(*sbuf);
+ return sample / (float)0x8000;
}
-static void convert_8_to_24 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static float get24(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
{
- while (count > 0)
- {
- BYTE dest = *(const BYTE *)src;
- BYTE *dest24 = dst;
- dest24[0] = dest;
- dest24[1] = dest;
- dest24[2] = dest - 0x80;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ LONG sample;
+ const BYTE* buf = dsb->buffer->memory;
+ buf += pos + 3 * channel;
+ /* The next expression deliberately has an overflow for buf[2] >= 0x80,
+ this is how negative values are made.
+ */
+ sample = (buf[0] << 8) | (buf[1] << 16) | (buf[2] << 24);
+ return sample / (float)0x80000000U;
}
-static void convert_8_to_32 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static float get32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
{
- while (count > 0)
- {
- DWORD dest = *(const BYTE *)src, *dest32 = dst;
- *dest32 = le32(dest * 16843009 - 2147483648U);
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ const BYTE* buf = dsb->buffer->memory;
+ const LONG *sbuf = (const LONG*)(buf + pos + 4 * channel);
+ LONG sample = le32(*sbuf);
+ return sample / (float)0x80000000U;
}
-static void convert_16_to_8 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static float getieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
{
- while (count > 0)
- {
- BYTE *dst8 = dst;
- *dst8 = (le16(*(const WORD *)src)) / 256;
- *dst8 -= 0x80;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ const BYTE* buf = dsb->buffer->memory;
+ const float *sbuf = (const float*)(buf + pos + 4 * channel);
+ /* The value will be clipped later, when put into some non-float buffer */
+ return *sbuf;
}
-static void convert_16_to_16 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
-{
- while (count > 0)
- {
- *(WORD *)dst = *(const WORD *)src;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
-}
+const bitsgetfunc getbpp[5] = {get8, get16, get24, get32, getieee32};
-static void convert_16_to_24 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+float get_mono(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
{
- while (count > 0)
- {
- WORD dest = le16(*(const WORD *)src);
- BYTE *dest24 = dst;
-
- dest24[0] = dest / 256;
- dest24[1] = dest;
- dest24[2] = dest / 256;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ DWORD channels = dsb->pwfx->nChannels;
+ DWORD c;
+ float val = 0;
+ /* XXX: does Windows include LFE into the mix? */
+ for (c = 0; c < channels; c++)
+ val += dsb->get_aux(dsb, pos, c);
+ val /= channels;
+ return val;
}
-static void convert_16_to_32 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static inline unsigned char f_to_8(float value)
{
- while (count > 0)
- {
- DWORD dest = *(const WORD *)src, *dest32 = dst;
- *dest32 = dest * 65537;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ if(value <= -1.f)
+ return 0;
+ if(value >= 1.f * 0x7f / 0x80)
+ return 0xFF;
+ return lrintf((value + 1.f) * 0x80);
}
-static void convert_24_to_8 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static inline SHORT f_to_16(float value)
{
- while (count > 0)
- {
- BYTE *dst8 = dst;
- *dst8 = ((const BYTE *)src)[2];
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ if(value <= -1.f)
+ return 0x8000;
+ if(value >= 1.f * 0x7FFF / 0x8000)
+ return 0x7FFF;
+ return le16(lrintf(value * 0x8000));
}
-static void convert_24_to_16 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static LONG f_to_24(float value)
{
- while (count > 0)
- {
- WORD *dest16 = dst;
- const BYTE *source = src;
- *dest16 = le16(source[2] * 256 + source[1]);
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ if(value <= -1.f)
+ return 0x80000000;
+ if(value >= 1.f * 0x7FFFFF / 0x800000)
+ return 0x7FFFFF00;
+ return lrintf(value * 0x80000000U);
}
-static void convert_24_to_24 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+static inline LONG f_to_32(float value)
{
- while (count > 0)
- {
- BYTE *dest24 = dst;
- const BYTE *src24 = src;
-
- dest24[0] = src24[0];
- dest24[1] = src24[1];
- dest24[2] = src24[2];
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ if(value <= -1.f)
+ return 0x80000000;
+ if(value >= 1.f * 0x7FFFFFFF / 0x80000000U) /* this rounds to 1.f */
+ return 0x7FFFFFFF;
+ return le32(lrintf(value * 0x80000000U));
}
-static void convert_24_to_32 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{
- while (count > 0)
- {
- DWORD *dest32 = dst;
- const BYTE *source = src;
- *dest32 = le32(source[2] * 16777217 + source[1] * 65536 + source[0] * 256);
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ BYTE *buf = (BYTE *)dsb->device->tmp_buffer;
+ float *fbuf = (float*)(buf + pos + sizeof(float) * channel);
+ *fbuf = value;
}
-static void convert_32_to_8 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
{
- while (count > 0)
- {
- BYTE *dst8 = dst;
- *dst8 = (le32(*(const DWORD *)src) / 16777216);
- *dst8 -= 0x80;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ dsb->put_aux(dsb, pos, 0, value);
+ dsb->put_aux(dsb, pos, 1, value);
}
-static void convert_32_to_16 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
+void mixieee32(float *src, float *dst, unsigned samples)
{
- while (count > 0)
- {
- WORD *dest16 = dst;
- *dest16 = le16(le32(*(const DWORD *)src) / 65536);
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
+ TRACE("%p - %p %d\n", src, dst, samples);
+ while (samples--)
+ *(dst++) += *(src++);
}
-static void convert_32_to_24 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
-{
- while (count > 0)
- {
- DWORD dest = le32(*(const DWORD *)src);
- BYTE *dest24 = dst;
-
- dest24[0] = dest / 256;
- dest24[1] = dest / 65536;
- dest24[2] = dest / 16777216;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
-}
-
-static void convert_32_to_32 (const void *src, void *dst, UINT src_stride,
- UINT dst_stride, INT count, UINT freqAcc, UINT adj)
-{
- while (count > 0)
- {
- DWORD *dest = dst;
- *dest = *(const DWORD *)src;
-
- dst = (char *)dst + dst_stride;
- src_advance(&src, src_stride, &count, &freqAcc, adj);
- }
-}
-
-const bitsconvertfunc convertbpp[4][4] = {
- { convert_8_to_8, convert_8_to_16, convert_8_to_24, convert_8_to_32 },
- { convert_16_to_8, convert_16_to_16, convert_16_to_24, convert_16_to_32 },
- { convert_24_to_8, convert_24_to_16, convert_24_to_24, convert_24_to_32 },
- { convert_32_to_8, convert_32_to_16, convert_32_to_24, convert_32_to_32 },
-};
-
-static void mix8(signed char *src, INT *dst, unsigned len)
-{
- TRACE("%p - %p %d\n", src, dst, len);
- while (len--)
- /* 8-bit WAV is unsigned, it's here converted to signed, normalize function will convert it back again */
- *(dst++) += (signed char)((BYTE)*(src++) - (BYTE)0x80);
-}
-
-static void mix16(SHORT *src, INT *dst, unsigned len)
-{
- TRACE("%p - %p %d\n", src, dst, len);
- len /= 2;
- while (len--)
- {
- *dst += le16(*src);
- ++dst; ++src;
- }
-}
-
-static void mix24(BYTE *src, INT *dst, unsigned len)
+static void norm8(float *src, unsigned char *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
- len /= 3;
while (len--)
{
- DWORD field;
- field = ((DWORD)src[2] << 16) + ((DWORD)src[1] << 8) + (DWORD)src[0];
- if (src[2] & 0x80)
- field |= 0xFF000000U;
- *(dst++) += field;
+ *dst = f_to_8(*src);
+ ++dst;
++src;
}
}
-static void mix32(INT *src, LONGLONG *dst, unsigned len)
-{
- TRACE("%p - %p %d\n", src, dst, len);
- len /= 4;
- while (len--)
- *(dst++) += le32(*(src++));
-}
-
-const mixfunc mixfunctions[4] = {
- (mixfunc)mix8,
- (mixfunc)mix16,
- (mixfunc)mix24,
- (mixfunc)mix32
-};
-
-static void norm8(INT *src, signed char *dst, unsigned len)
+static void norm16(float *src, SHORT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
+ len /= 2;
while (len--)
{
- *dst = (*src) + 0x80;
- if (*src < -0x80)
- *dst = 0;
- else if (*src > 0x7f)
- *dst = 0xff;
+ *dst = f_to_16(*src);
++dst;
++src;
}
}
-static void norm16(INT *src, SHORT *dst, unsigned len)
+static void norm24(float *src, BYTE *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
- len /= 2;
+ len /= 3;
while (len--)
{
- *dst = le16(*src);
- if (*src <= -0x8000)
- *dst = le16(0x8000);
- else if (*src > 0x7fff)
- *dst = le16(0x7fff);
- ++dst;
+ LONG t = f_to_24(*src);
+ dst[0] = (t >> 8) & 0xFF;
+ dst[1] = (t >> 16) & 0xFF;
+ dst[2] = t >> 24;
+ dst += 3;
++src;
}
}
-static void norm24(INT *src, BYTE *dst, unsigned len)
+static void norm32(float *src, INT *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
- len /= 3;
+ len /= 4;
while (len--)
{
- if (*src <= -0x800000)
- {
- dst[0] = 0;
- dst[1] = 0;
- dst[2] = 0x80;
- }
- else if (*src > 0x7fffff)
- {
- dst[0] = 0xff;
- dst[1] = 0xff;
- dst[2] = 0x7f;
- }
- else
- {
- dst[0] = *src;
- dst[1] = *src >> 8;
- dst[2] = *src >> 16;
- }
+ *dst = f_to_32(*src);
++dst;
++src;
}
}
-static void norm32(LONGLONG *src, INT *dst, unsigned len)
+static void normieee32(float *src, float *dst, unsigned len)
{
TRACE("%p - %p %d\n", src, dst, len);
len /= 4;
while (len--)
{
- *dst = le32(*src);
- if (*src <= -(LONGLONG)0x80000000)
- *dst = le32(0x80000000);
- else if (*src > 0x7fffffff)
- *dst = le32(0x7fffffff);
+ if(*src > 1)
+ *dst = 1;
+ else if(*src < -1)
+ *dst = -1;
+ else
+ *dst = *src;
++dst;
++src;
}
}
-const normfunc normfunctions[4] = {
+const normfunc normfunctions[5] = {
(normfunc)norm8,
(normfunc)norm16,
(normfunc)norm24,
(normfunc)norm32,
+ (normfunc)normieee32
};
#include <dsound.h>
#include <dsconf.h>
//#include "ks.h"
+#include <rpcproxy.h>
+//#include "rpc.h"
+//#include "rpcndr.h"
+//#include "unknwn.h"
+//#include "oleidl.h"
+//#include "shobjidl.h"
+
#include <initguid.h>
//#include "ksmedia.h"
-#include <dsdriver.h>
+//#include "propkey.h"
+#include <devpkey.h>
#include "dsound_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
+struct list DSOUND_renderers = LIST_INIT(DSOUND_renderers);
+CRITICAL_SECTION DSOUND_renderers_lock;
+static CRITICAL_SECTION_DEBUG DSOUND_renderers_lock_debug =
+{
+ 0, 0, &DSOUND_renderers_lock,
+ { &DSOUND_renderers_lock_debug.ProcessLocksList, &DSOUND_renderers_lock_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": DSOUND_renderers_lock") }
+};
+CRITICAL_SECTION DSOUND_renderers_lock = { &DSOUND_renderers_lock_debug, -1, 0, 0, 0, 0 };
+
+struct list DSOUND_capturers = LIST_INIT(DSOUND_capturers);
+CRITICAL_SECTION DSOUND_capturers_lock;
+static CRITICAL_SECTION_DEBUG DSOUND_capturers_lock_debug =
+{
+ 0, 0, &DSOUND_capturers_lock,
+ { &DSOUND_capturers_lock_debug.ProcessLocksList, &DSOUND_capturers_lock_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": DSOUND_capturers_lock") }
+};
+CRITICAL_SECTION DSOUND_capturers_lock = { &DSOUND_capturers_lock_debug, -1, 0, 0, 0, 0 };
+
GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
-HRESULT mmErr(UINT err)
-{
- switch(err) {
- case MMSYSERR_NOERROR:
- return DS_OK;
- case MMSYSERR_ALLOCATED:
- return DSERR_ALLOCATED;
- case MMSYSERR_ERROR:
- case MMSYSERR_INVALHANDLE:
- case WAVERR_STILLPLAYING:
- return DSERR_GENERIC; /* FIXME */
- case MMSYSERR_NODRIVER:
- return DSERR_NODRIVER;
- case MMSYSERR_NOMEM:
- return DSERR_OUTOFMEMORY;
- case MMSYSERR_INVALPARAM:
- case WAVERR_BADFORMAT:
- case WAVERR_UNPREPARED:
- return DSERR_INVALIDPARAM;
- case MMSYSERR_NOTSUPPORTED:
- return DSERR_UNSUPPORTED;
- default:
- FIXME("Unknown MMSYS error %d\n",err);
- return DSERR_GENERIC;
- }
-}
+WCHAR wine_vxd_drv[] = { 'w','i','n','e','m','m','.','v','x','d', 0 };
/* All default settings, you most likely don't want to touch these, see wiki on UsefulRegistryKeys */
-int ds_emuldriver = 0;
int ds_hel_buflen = 32768 * 2;
int ds_snd_queue_max = 10;
-int ds_snd_queue_min = 6;
-int ds_snd_shadow_maxsize = 2;
-int ds_hw_accel = DS_HW_ACCEL_FULL;
-int ds_default_sample_rate = 44100;
-int ds_default_bits_per_sample = 16;
-static int ds_default_playback;
-static int ds_default_capture;
+static HINSTANCE instance;
/*
* Get a config key from either the app-specific or the default config
/* get options */
- if (!get_config_key( hkey, appkey, "EmulDriver", buffer, MAX_PATH ))
- ds_emuldriver = strcmp(buffer, "N");
-
if (!get_config_key( hkey, appkey, "HelBuflen", buffer, MAX_PATH ))
ds_hel_buflen = atoi(buffer);
if (!get_config_key( hkey, appkey, "SndQueueMax", buffer, MAX_PATH ))
ds_snd_queue_max = atoi(buffer);
- if (!get_config_key( hkey, appkey, "SndQueueMin", buffer, MAX_PATH ))
- ds_snd_queue_min = atoi(buffer);
-
- if (!get_config_key( hkey, appkey, "HardwareAcceleration", buffer, MAX_PATH )) {
- if (strcmp(buffer, "Full") == 0)
- ds_hw_accel = DS_HW_ACCEL_FULL;
- else if (strcmp(buffer, "Standard") == 0)
- ds_hw_accel = DS_HW_ACCEL_STANDARD;
- else if (strcmp(buffer, "Basic") == 0)
- ds_hw_accel = DS_HW_ACCEL_BASIC;
- else if (strcmp(buffer, "Emulation") == 0)
- ds_hw_accel = DS_HW_ACCEL_EMULATION;
- }
-
- if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
- ds_default_playback = atoi(buffer);
-
- if (!get_config_key( hkey, appkey, "MaxShadowSize", buffer, MAX_PATH ))
- ds_snd_shadow_maxsize = atoi(buffer);
-
- if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
- ds_default_capture = atoi(buffer);
-
- if (!get_config_key( hkey, appkey, "DefaultSampleRate", buffer, MAX_PATH ))
- ds_default_sample_rate = atoi(buffer);
-
- if (!get_config_key( hkey, appkey, "DefaultBitsPerSample", buffer, MAX_PATH ))
- ds_default_bits_per_sample = atoi(buffer);
if (appkey) RegCloseKey( appkey );
if (hkey) RegCloseKey( hkey );
- TRACE("ds_emuldriver = %d\n", ds_emuldriver);
TRACE("ds_hel_buflen = %d\n", ds_hel_buflen);
TRACE("ds_snd_queue_max = %d\n", ds_snd_queue_max);
- TRACE("ds_snd_queue_min = %d\n", ds_snd_queue_min);
- TRACE("ds_hw_accel = %s\n",
- ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
- ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
- ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
- ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
- "Unknown");
- TRACE("ds_default_playback = %d\n", ds_default_playback);
- TRACE("ds_default_capture = %d\n", ds_default_playback);
- TRACE("ds_default_sample_rate = %d\n", ds_default_sample_rate);
- TRACE("ds_default_bits_per_sample = %d\n", ds_default_bits_per_sample);
- TRACE("ds_snd_shadow_maxsize = %d\n", ds_snd_shadow_maxsize);
}
static const char * get_device_id(LPCGUID pGuid)
return debugstr_guid(pGuid);
}
+static HRESULT get_mmdevenum(IMMDeviceEnumerator **devenum)
+{
+ HRESULT hr, init_hr;
+
+ init_hr = CoInitialize(NULL);
+
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)devenum);
+ if(FAILED(hr)){
+ CoUninitialize();
+ *devenum = NULL;
+ ERR("CoCreateInstance failed: %08x\n", hr);
+ return hr;
+ }
+
+ return init_hr;
+}
+
+static void release_mmdevenum(IMMDeviceEnumerator *devenum, HRESULT init_hr)
+{
+ IMMDeviceEnumerator_Release(devenum);
+ if(SUCCEEDED(init_hr))
+ CoUninitialize();
+}
+
+static HRESULT get_mmdevice_guid(IMMDevice *device, IPropertyStore *ps,
+ GUID *guid)
+{
+ PROPVARIANT pv;
+ HRESULT hr;
+
+ if(!ps){
+ hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
+ if(FAILED(hr)){
+ WARN("OpenPropertyStore failed: %08x\n", hr);
+ return hr;
+ }
+ }else
+ IPropertyStore_AddRef(ps);
+
+ PropVariantInit(&pv);
+
+ hr = IPropertyStore_GetValue(ps, &PKEY_AudioEndpoint_GUID, &pv);
+ if(FAILED(hr)){
+ IPropertyStore_Release(ps);
+ WARN("GetValue(GUID) failed: %08x\n", hr);
+ return hr;
+ }
+
+ CLSIDFromString(pv.u.pwszVal, guid);
+
+ PropVariantClear(&pv);
+ IPropertyStore_Release(ps);
+
+ return S_OK;
+}
+
/***************************************************************************
* GetDeviceID [DSOUND.9]
*
*/
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
{
+ IMMDeviceEnumerator *devenum;
+ EDataFlow flow = (EDataFlow)-1;
+ ERole role = (ERole)-1;
+ HRESULT hr, init_hr;
+
TRACE("(%s,%p)\n", get_device_id(pGuidSrc),pGuidDest);
- if ( pGuidSrc == NULL) {
- WARN("invalid parameter: pGuidSrc == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ if(!pGuidSrc || !pGuidDest)
+ return DSERR_INVALIDPARAM;
- if ( pGuidDest == NULL ) {
- WARN("invalid parameter: pGuidDest == NULL\n");
- return DSERR_INVALIDPARAM;
+ init_hr = get_mmdevenum(&devenum);
+ if(!devenum)
+ return init_hr;
+
+ if(IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc)){
+ role = eMultimedia;
+ flow = eRender;
+ }else if(IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuidSrc)){
+ role = eCommunications;
+ flow = eRender;
+ }else if(IsEqualGUID(&DSDEVID_DefaultCapture, pGuidSrc)){
+ role = eMultimedia;
+ flow = eCapture;
+ }else if(IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuidSrc)){
+ role = eCommunications;
+ flow = eCapture;
}
- if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
- IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
- *pGuidDest = DSOUND_renderer_guids[ds_default_playback];
- TRACE("returns %s\n", get_device_id(pGuidDest));
- return DS_OK;
- }
+ if(role != (ERole)-1 && flow != (EDataFlow)-1){
+ IMMDevice *device;
- if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
- IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
- *pGuidDest = DSOUND_capture_guids[ds_default_capture];
- TRACE("returns %s\n", get_device_id(pGuidDest));
- return DS_OK;
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum,
+ flow, role, &device);
+ if(FAILED(hr)){
+ WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
+ release_mmdevenum(devenum, init_hr);
+ return DSERR_NODRIVER;
+ }
+
+ hr = get_mmdevice_guid(device, NULL, pGuidDest);
+ IMMDevice_Release(device);
+
+ release_mmdevenum(devenum, init_hr);
+
+ return (hr == S_OK) ? DS_OK : hr;
}
+ release_mmdevenum(devenum, init_hr);
+
*pGuidDest = *pGuidSrc;
- TRACE("returns %s\n", get_device_id(pGuidDest));
return DS_OK;
}
+struct morecontext
+{
+ LPDSENUMCALLBACKA callA;
+ LPVOID data;
+};
+
+static BOOL CALLBACK a_to_w_callback(LPGUID guid, LPCWSTR descW, LPCWSTR modW, LPVOID data)
+{
+ struct morecontext *context = data;
+ char descA[MAXPNAMELEN], modA[MAXPNAMELEN];
+
+ WideCharToMultiByte(CP_ACP, 0, descW, -1, descA, sizeof(descA), NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, modW, -1, modA, sizeof(modA), NULL, NULL);
+
+ return context->callA(guid, descA, modA, context->data);
+}
/***************************************************************************
* DirectSoundEnumerateA [DSOUND.2]
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
- unsigned devs, wod;
- DSDRIVERDESC desc;
- GUID guid;
- int err;
-
- TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
- lpDSEnumCallback, lpContext);
+ struct morecontext context;
if (lpDSEnumCallback == NULL) {
- WARN("invalid parameter: lpDSEnumCallback == NULL\n");
- return DSERR_INVALIDPARAM;
+ WARN("invalid parameter: lpDSEnumCallback == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- devs = waveOutGetNumDevs();
- if (devs > 0) {
- if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
- for (wod = 0; wod < devs; ++wod) {
- if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod]) ) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
- "Primary Sound Driver","",lpContext);
- if (lpDSEnumCallback(NULL, "Primary Sound Driver", "", lpContext) == FALSE)
- return DS_OK;
- }
- }
- }
- }
+ context.callA = lpDSEnumCallback;
+ context.data = lpContext;
+
+ return DirectSoundEnumerateW(a_to_w_callback, &context);
+}
+
+HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device)
+{
+ IMMDeviceEnumerator *devenum;
+ IMMDeviceCollection *coll;
+ UINT count, i;
+ HRESULT hr, init_hr;
+
+ init_hr = get_mmdevenum(&devenum);
+ if(!devenum)
+ return init_hr;
+
+ hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
+ DEVICE_STATE_ACTIVE, &coll);
+ if(FAILED(hr)){
+ WARN("EnumAudioEndpoints failed: %08x\n", hr);
+ release_mmdevenum(devenum, init_hr);
+ return hr;
}
- for (wod = 0; wod < devs; ++wod) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
- debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
- if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], desc.szDesc, desc.szDrvname, lpContext) == FALSE)
- return DS_OK;
- }
+ hr = IMMDeviceCollection_GetCount(coll, &count);
+ if(FAILED(hr)){
+ IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
+ WARN("GetCount failed: %08x\n", hr);
+ return hr;
}
- return DS_OK;
+
+ for(i = 0; i < count; ++i){
+ GUID guid;
+
+ hr = IMMDeviceCollection_Item(coll, i, device);
+ if(FAILED(hr))
+ continue;
+
+ hr = get_mmdevice_guid(*device, NULL, &guid);
+ if(FAILED(hr)){
+ IMMDevice_Release(*device);
+ continue;
+ }
+
+ if(IsEqualGUID(&guid, tgt)){
+ IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
+ return DS_OK;
+ }
+
+ IMMDevice_Release(*device);
+ }
+
+ WARN("No device with GUID %s found!\n", wine_dbgstr_guid(tgt));
+
+ IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
+
+ return DSERR_INVALIDPARAM;
+}
+
+static BOOL send_device(IMMDevice *device, GUID *guid,
+ LPDSENUMCALLBACKW cb, void *user)
+{
+ IPropertyStore *ps;
+ PROPVARIANT pv;
+ BOOL keep_going;
+ HRESULT hr;
+
+ PropVariantInit(&pv);
+
+ hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &ps);
+ if(FAILED(hr)){
+ WARN("OpenPropertyStore failed: %08x\n", hr);
+ return TRUE;
+ }
+
+ hr = get_mmdevice_guid(device, ps, guid);
+ if(FAILED(hr)){
+ IPropertyStore_Release(ps);
+ return TRUE;
+ }
+
+ hr = IPropertyStore_GetValue(ps,
+ (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
+ if(FAILED(hr)){
+ IPropertyStore_Release(ps);
+ WARN("GetValue(FriendlyName) failed: %08x\n", hr);
+ return TRUE;
+ }
+
+ TRACE("Calling back with %s (%s)\n", wine_dbgstr_guid(guid),
+ wine_dbgstr_w(pv.u.pwszVal));
+
+ keep_going = cb(guid, pv.u.pwszVal, wine_vxd_drv, user);
+
+ PropVariantClear(&pv);
+ IPropertyStore_Release(ps);
+
+ return keep_going;
+}
+
+/* S_FALSE means the callback returned FALSE at some point
+ * S_OK means the callback always returned TRUE */
+HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
+ LPDSENUMCALLBACKW cb, void *user)
+{
+ IMMDeviceEnumerator *devenum;
+ IMMDeviceCollection *coll;
+ IMMDevice *defdev = NULL;
+ UINT count, i, n;
+ BOOL keep_going;
+ HRESULT hr, init_hr;
+
+ static const WCHAR primary_desc[] = {'P','r','i','m','a','r','y',' ',
+ 'S','o','u','n','d',' ','D','r','i','v','e','r',0};
+ static const WCHAR empty_drv[] = {0};
+
+ init_hr = get_mmdevenum(&devenum);
+ if(!devenum)
+ return init_hr;
+
+ hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flow,
+ DEVICE_STATE_ACTIVE, &coll);
+ if(FAILED(hr)){
+ release_mmdevenum(devenum, init_hr);
+ WARN("EnumAudioEndpoints failed: %08x\n", hr);
+ return DS_OK;
+ }
+
+ hr = IMMDeviceCollection_GetCount(coll, &count);
+ if(FAILED(hr)){
+ IMMDeviceCollection_Release(coll);
+ release_mmdevenum(devenum, init_hr);
+ WARN("GetCount failed: %08x\n", hr);
+ return DS_OK;
+ }
+
+ if(count == 0){
+ release_mmdevenum(devenum, init_hr);
+ return DS_OK;
+ }
+
+ TRACE("Calling back with NULL (%s)\n", wine_dbgstr_w(primary_desc));
+ keep_going = cb(NULL, primary_desc, empty_drv, user);
+
+ /* always send the default device first */
+ if(keep_going){
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flow,
+ eMultimedia, &defdev);
+ if(FAILED(hr)){
+ defdev = NULL;
+ n = 0;
+ }else{
+ keep_going = send_device(defdev, &guids[0], cb, user);
+ n = 1;
+ }
+ }
+
+ for(i = 0; keep_going && i < count; ++i){
+ IMMDevice *device;
+
+ hr = IMMDeviceCollection_Item(coll, i, &device);
+ if(FAILED(hr)){
+ WARN("Item failed: %08x\n", hr);
+ continue;
+ }
+
+ if(device != defdev){
+ send_device(device, &guids[n], cb, user);
+ ++n;
+ }
+
+ IMMDevice_Release(device);
+ }
+
+ if(defdev)
+ IMMDevice_Release(defdev);
+ IMMDeviceCollection_Release(coll);
+
+ release_mmdevenum(devenum, init_hr);
+
+ return (keep_going == TRUE) ? S_OK : S_FALSE;
}
/***************************************************************************
LPDSENUMCALLBACKW lpDSEnumCallback,
LPVOID lpContext )
{
- unsigned devs, wod;
- DSDRIVERDESC desc;
- GUID guid;
- int err;
- WCHAR wDesc[MAXPNAMELEN];
- WCHAR wName[MAXPNAMELEN];
+ HRESULT hr;
- TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
- lpDSEnumCallback, lpContext);
+ TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext);
if (lpDSEnumCallback == NULL) {
- WARN("invalid parameter: lpDSEnumCallback == NULL\n");
- return DSERR_INVALIDPARAM;
+ WARN("invalid parameter: lpDSEnumCallback == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- devs = waveOutGetNumDevs();
- if (devs > 0) {
- if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
- static const WCHAR empty[] = { 0 };
- for (wod = 0; wod < devs; ++wod) {
- if (IsEqualGUID( &guid, &DSOUND_renderer_guids[wod] ) ) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
- "Primary Sound Driver",desc.szDrvname,lpContext);
- MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1,
- wDesc, sizeof(wDesc)/sizeof(WCHAR) );
- if (lpDSEnumCallback(NULL, wDesc, empty, lpContext) == FALSE)
- return DS_OK;
- }
- }
- }
- }
+ setup_dsound_options();
+
+ hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
+ lpDSEnumCallback, lpContext);
+ return SUCCEEDED(hr) ? DS_OK : hr;
+}
+
+/***************************************************************************
+ * DirectSoundCaptureEnumerateA [DSOUND.7]
+ *
+ * Enumerate all DirectSound drivers installed in the system.
+ *
+ * PARAMS
+ * lpDSEnumCallback [I] Address of callback function.
+ * lpContext [I] Address of user defined context passed to callback function.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_INVALIDPARAM
+ */
+HRESULT WINAPI DirectSoundCaptureEnumerateA(
+ LPDSENUMCALLBACKA lpDSEnumCallback,
+ LPVOID lpContext)
+{
+ struct morecontext context;
+
+ if (lpDSEnumCallback == NULL) {
+ WARN("invalid parameter: lpDSEnumCallback == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- for (wod = 0; wod < devs; ++wod) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
- debugstr_guid(&DSOUND_renderer_guids[wod]),desc.szDesc,desc.szDrvname,lpContext);
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
- wDesc, sizeof(wDesc)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1,
- wName, sizeof(wName)/sizeof(WCHAR) );
- if (lpDSEnumCallback(&DSOUND_renderer_guids[wod], wDesc, wName, lpContext) == FALSE)
- return DS_OK;
- }
+ context.callA = lpDSEnumCallback;
+ context.data = lpContext;
+
+ return DirectSoundCaptureEnumerateW(a_to_w_callback, &context);
+}
+
+/***************************************************************************
+ * DirectSoundCaptureEnumerateW [DSOUND.8]
+ *
+ * Enumerate all DirectSound drivers installed in the system.
+ *
+ * PARAMS
+ * lpDSEnumCallback [I] Address of callback function.
+ * lpContext [I] Address of user defined context passed to callback function.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_INVALIDPARAM
+ */
+HRESULT WINAPI
+DirectSoundCaptureEnumerateW(
+ LPDSENUMCALLBACKW lpDSEnumCallback,
+ LPVOID lpContext)
+{
+ HRESULT hr;
+
+ TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
+
+ if (lpDSEnumCallback == NULL) {
+ WARN("invalid parameter: lpDSEnumCallback == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- return DS_OK;
+
+ setup_dsound_options();
+
+ hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
+ lpDSEnumCallback, lpContext);
+ return SUCCEEDED(hr) ? DS_OK : hr;
}
/*******************************************************************************
typedef HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj);
typedef struct {
- const IClassFactoryVtbl *lpVtbl;
- LONG ref;
+ IClassFactory IClassFactory_iface;
REFCLSID rclsid;
FnCreateInstance pfnCreateInstance;
} IClassFactoryImpl;
+static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+{
+ return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
+}
+
static HRESULT WINAPI
-DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj)
+DSCF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj)
{
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ IClassFactoryImpl *This = impl_from_IClassFactory(iface);
TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
if (ppobj == NULL)
return E_POINTER;
IsEqualIID(riid, &IID_IClassFactory))
{
*ppobj = iface;
- IUnknown_AddRef(iface);
+ IClassFactory_AddRef(iface);
return S_OK;
}
*ppobj = NULL;
static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
{
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
+ return 2;
}
static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
{
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
/* static class, won't be freed */
- return ref;
+ return 1;
}
static HRESULT WINAPI DSCF_CreateInstance(
REFIID riid,
LPVOID *ppobj)
{
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ IClassFactoryImpl *This = impl_from_IClassFactory(iface);
TRACE("(%p, %p, %s, %p)\n", This, pOuter, debugstr_guid(riid), ppobj);
if (pOuter)
static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
{
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ IClassFactoryImpl *This = impl_from_IClassFactory(iface);
FIXME("(%p, %d) stub!\n", This, dolock);
return S_OK;
}
};
static IClassFactoryImpl DSOUND_CF[] = {
- { &DSCF_Vtbl, 1, &CLSID_DirectSound, (FnCreateInstance)DSOUND_Create },
- { &DSCF_Vtbl, 1, &CLSID_DirectSound8, (FnCreateInstance)DSOUND_Create8 },
- { &DSCF_Vtbl, 1, &CLSID_DirectSoundCapture, (FnCreateInstance)DSOUND_CaptureCreate },
- { &DSCF_Vtbl, 1, &CLSID_DirectSoundCapture8, (FnCreateInstance)DSOUND_CaptureCreate8 },
- { &DSCF_Vtbl, 1, &CLSID_DirectSoundFullDuplex, (FnCreateInstance)DSOUND_FullDuplexCreate },
- { &DSCF_Vtbl, 1, &CLSID_DirectSoundPrivate, (FnCreateInstance)IKsPrivatePropertySetImpl_Create },
- { NULL, 0, NULL, NULL }
+ { { &DSCF_Vtbl }, &CLSID_DirectSound, DSOUND_Create },
+ { { &DSCF_Vtbl }, &CLSID_DirectSound8, DSOUND_Create8 },
+ { { &DSCF_Vtbl }, &CLSID_DirectSoundCapture, DSOUND_CaptureCreate },
+ { { &DSCF_Vtbl }, &CLSID_DirectSoundCapture8, DSOUND_CaptureCreate8 },
+ { { &DSCF_Vtbl }, &CLSID_DirectSoundFullDuplex, DSOUND_FullDuplexCreate },
+ { { &DSCF_Vtbl }, &CLSID_DirectSoundPrivate, IKsPrivatePropertySetImpl_Create },
+ { { NULL }, NULL, NULL }
};
/*******************************************************************************
while (NULL != DSOUND_CF[i].rclsid) {
if (IsEqualGUID(rclsid, DSOUND_CF[i].rclsid)) {
- DSCF_AddRef((IClassFactory*) &DSOUND_CF[i]);
+ DSCF_AddRef(&DSOUND_CF[i].IClassFactory_iface);
*ppv = &DSOUND_CF[i];
return S_OK;
}
* Determines whether the DLL is in use.
*
* RETURNS
- * Success: S_OK
- * Failure: S_FALSE
+ * Can unload now: S_OK
+ * Cannot unload now (the DLL is still active): S_FALSE
*/
HRESULT WINAPI DllCanUnloadNow(void)
{
- FIXME("(void): stub\n");
return S_FALSE;
}
*/
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
- int i;
TRACE("(%p %d %p)\n", hInstDLL, fdwReason, lpvReserved);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
TRACE("DLL_PROCESS_ATTACH\n");
- for (i = 0; i < MAXWAVEDRIVERS; i++) {
- DSOUND_renderer[i] = NULL;
- DSOUND_capture[i] = NULL;
- INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
- INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
- }
+ instance = hInstDLL;
DisableThreadLibraryCalls(hInstDLL);
/* Increase refcount on dsound by 1 */
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)hInstDLL, &hInstDLL);
break;
case DLL_PROCESS_DETACH:
TRACE("DLL_PROCESS_DETACH\n");
+ DeleteCriticalSection(&DSOUND_renderers_lock);
+ DeleteCriticalSection(&DSOUND_capturers_lock);
break;
default:
TRACE("UNKNOWN REASON\n");
}
return TRUE;
}
+
+/***********************************************************************
+ * DllRegisterServer (DSOUND.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+ return __wine_register_resources( instance );
+}
+
+/***********************************************************************
+ * DllUnregisterServer (DSOUND.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+ return __wine_unregister_resources( instance );
+}
#define DS_TIME_RES 2 /* Resolution of multimedia timer */
#define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
-#include <wine/list.h>
-
-/* direct sound hardware acceleration levels */
-#define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
-#define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
-#define DS_HW_ACCEL_BASIC 2
-#define DS_HW_ACCEL_EMULATION 3
-
-extern int ds_emuldriver;
-extern int ds_hel_buflen;
-extern int ds_snd_queue_max;
-extern int ds_snd_queue_min;
-extern int ds_snd_shadow_maxsize;
-extern int ds_hw_accel;
-extern int ds_default_sample_rate;
-extern int ds_default_bits_per_sample;
+#include "wingdi.h"
+#include "mmdeviceapi.h"
+#include "audioclient.h"
+#include "mmsystem.h"
+
+#include "wine/list.h"
+
+extern int ds_hel_buflen DECLSPEC_HIDDEN;
+extern int ds_snd_queue_max DECLSPEC_HIDDEN;
/*****************************************************************************
* Predeclare the interface implementation structures
*/
-typedef struct IDirectSoundImpl IDirectSoundImpl;
-typedef struct IDirectSound_IUnknown IDirectSound_IUnknown;
-typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound;
-typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown;
-typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound;
-typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8;
typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
-typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
-typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
-typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
-typedef struct IDirectSoundFullDuplex_IUnknown IDirectSoundFullDuplex_IUnknown;
-typedef struct IDirectSoundFullDuplex_IDirectSound IDirectSoundFullDuplex_IDirectSound;
-typedef struct IDirectSoundFullDuplex_IDirectSound8 IDirectSoundFullDuplex_IDirectSound8;
-typedef struct IDirectSoundFullDuplex_IDirectSoundCapture IDirectSoundFullDuplex_IDirectSoundCapture;
-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 DirectSoundDevice DirectSoundDevice;
-typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice;
/* dsound_convert.h */
-typedef void (*bitsconvertfunc)(const void *, void *, UINT, UINT, INT, UINT, UINT);
-extern const bitsconvertfunc convertbpp[4][4];
-typedef void (*mixfunc)(const void *, void *, unsigned);
-extern const mixfunc mixfunctions[4];
+typedef float (*bitsgetfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD);
+typedef void (*bitsputfunc)(const IDirectSoundBufferImpl *, DWORD, DWORD, float);
+extern const bitsgetfunc getbpp[5] DECLSPEC_HIDDEN;
+void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
+void mixieee32(float *src, float *dst, unsigned samples) DECLSPEC_HIDDEN;
typedef void (*normfunc)(const void *, void *, unsigned);
-extern const normfunc normfunctions[4];
+extern const normfunc normfunctions[5] DECLSPEC_HIDDEN;
+
+typedef struct _DSVOLUMEPAN
+{
+ DWORD dwTotalLeftAmpFactor;
+ DWORD dwTotalRightAmpFactor;
+ LONG lVolume;
+ DWORD dwVolAmpFactor;
+ LONG lPan;
+ DWORD dwPanLeftAmpFactor;
+ DWORD dwPanRightAmpFactor;
+} DSVOLUMEPAN,*PDSVOLUMEPAN;
/*****************************************************************************
* IDirectSoundDevice implementation structure
LONG ref;
GUID guid;
- PIDSDRIVER driver;
- DSDRIVERDESC drvdesc;
- DSDRIVERCAPS drvcaps;
- DWORD priolevel;
- PWAVEFORMATEX pwfx;
- HWAVEOUT hwo;
- LPWAVEHDR pwave;
- UINT timerID, pwplay, pwqueue, prebuf, helfrags;
+ DSCAPS drvcaps;
+ DWORD priolevel, sleeptime;
+ PWAVEFORMATEX pwfx, primary_pwfx;
+ UINT playing_offs_bytes, in_mmdev_bytes, prebuf;
DWORD fraglen;
- PIDSDRIVERBUFFER hwbuf;
LPBYTE buffer;
DWORD writelead, buflen, state, playpos, mixpos;
int nrofbuffers;
IDirectSoundBufferImpl** buffers;
RTL_RWLOCK buffer_list_lock;
CRITICAL_SECTION mixlock;
- PrimaryBufferImpl* primary;
- DSBUFFERDESC dsbd;
+ IDirectSoundBufferImpl *primary;
DWORD speaker_config;
- LPBYTE tmp_buffer, mix_buffer;
+ float *mix_buffer, *tmp_buffer;
DWORD tmp_buffer_len, mix_buffer_len;
DSVOLUMEPAN volpan;
- mixfunc mixfunction;
normfunc normfunction;
/* DirectSound3DListener fields */
- IDirectSound3DListenerImpl* listener;
DS3DLISTENER ds3dl;
BOOL ds3dl_need_recalc;
+
+ IMMDevice *mmdevice;
+ IAudioClient *client;
+ IAudioClock *clock;
+ IAudioStreamVolume *volume;
+ IAudioRenderClient *render;
+
+ HANDLE sleepev, thread;
+ struct list entry;
};
/* reference counted buffer memory for duplicated buffer memory */
struct list buffers;
} BufferMemory;
-ULONG DirectSoundDevice_Release(DirectSoundDevice * device);
+ULONG DirectSoundDevice_Release(DirectSoundDevice * device) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_Initialize(
DirectSoundDevice ** ppDevice,
- LPCGUID lpcGUID);
+ LPCGUID lpcGUID) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_AddBuffer(
DirectSoundDevice * device,
- IDirectSoundBufferImpl * pDSB);
-HRESULT DirectSoundDevice_RemoveBuffer(
- DirectSoundDevice * device,
- IDirectSoundBufferImpl * pDSB);
-HRESULT DirectSoundDevice_GetCaps(DirectSoundDevice * device, LPDSCAPS lpDSCaps);
+ IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
+void DirectSoundDevice_RemoveBuffer(DirectSoundDevice * device, IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_CreateSoundBuffer(
DirectSoundDevice * device,
LPCDSBUFFERDESC dsbd,
LPLPDIRECTSOUNDBUFFER ppdsb,
LPUNKNOWN lpunk,
- BOOL from8);
+ BOOL from8) DECLSPEC_HIDDEN;
HRESULT DirectSoundDevice_DuplicateSoundBuffer(
DirectSoundDevice * device,
LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb);
-HRESULT DirectSoundDevice_SetCooperativeLevel(
- DirectSoundDevice * devcie,
- HWND hwnd,
- DWORD level);
-HRESULT DirectSoundDevice_Compact(DirectSoundDevice * device);
-HRESULT DirectSoundDevice_GetSpeakerConfig(
- DirectSoundDevice * device,
- LPDWORD lpdwSpeakerConfig);
-HRESULT DirectSoundDevice_SetSpeakerConfig(
- DirectSoundDevice * device,
- DWORD config);
+ LPLPDIRECTSOUNDBUFFER ppdsb) DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirectSoundBuffer implementation structure
*/
struct IDirectSoundBufferImpl
{
- /* FIXME: document */
- /* IUnknown fields */
- const IDirectSoundBuffer8Vtbl *lpVtbl;
- LONG ref;
+ IDirectSoundBuffer8 IDirectSoundBuffer8_iface;
+ IDirectSoundNotify IDirectSoundNotify_iface;
+ IDirectSound3DListener IDirectSound3DListener_iface; /* only primary buffer */
+ IDirectSound3DBuffer IDirectSound3DBuffer_iface; /* only secondary buffer */
+ IKsPropertySet IKsPropertySet_iface;
+ LONG numIfaces; /* "in use interfaces" refcount */
+ LONG ref, refn, ref3D, refiks;
/* IDirectSoundBufferImpl fields */
- SecondaryBufferImpl* secondary;
DirectSoundDevice* device;
RTL_RWLOCK lock;
- PIDSDRIVERBUFFER hwbuf;
PWAVEFORMATEX pwfx;
BufferMemory* buffer;
- LPBYTE tmp_buffer;
DWORD playflags,state,leadin;
DWORD writelead,buflen;
DWORD nAvgBytesPerSec;
- DWORD freq, tmp_buffer_len, max_buffer_len;
+ DWORD freq;
DSVOLUMEPAN volpan;
DSBUFFERDESC dsbd;
/* used for frequency conversion (PerfectPitch) */
- ULONG freqneeded, freqAdjust, freqAcc, freqAccNext, resampleinmixer;
+ ULONG freqneeded;
+ DWORD firstep;
+ float freqAcc, freqAdjust, firgain;
/* used for mixing */
- DWORD primary_mixpos, buf_mixpos, sec_mixpos;
+ DWORD sec_mixpos;
- /* IDirectSoundNotifyImpl fields */
- IDirectSoundNotifyImpl* notify;
+ /* IDirectSoundNotify fields */
LPDSBPOSITIONNOTIFY notifies;
int nrofnotifies;
- PIDSDRIVERNOTIFY hwnotify;
-
/* DirectSound3DBuffer fields */
- IDirectSound3DBufferImpl* ds3db;
DS3DBUFFER ds3db_ds3db;
LONG ds3db_lVolume;
BOOL ds3db_need_recalc;
+ /* Used for bit depth conversion */
+ int mix_channels;
+ bitsgetfunc get, get_aux;
+ bitsputfunc put, put_aux;
- /* IKsPropertySet fields */
- IKsBufferPropertySetImpl* iks;
- bitsconvertfunc convert;
struct list entry;
};
+float get_mono(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel) DECLSPEC_HIDDEN;
+void put_mono2stereo(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value) DECLSPEC_HIDDEN;
+
HRESULT IDirectSoundBufferImpl_Create(
DirectSoundDevice *device,
IDirectSoundBufferImpl **ppdsb,
- LPCDSBUFFERDESC dsbd);
-HRESULT IDirectSoundBufferImpl_Destroy(
- IDirectSoundBufferImpl *pdsb);
+ LPCDSBUFFERDESC dsbd) DECLSPEC_HIDDEN;
HRESULT IDirectSoundBufferImpl_Duplicate(
DirectSoundDevice *device,
IDirectSoundBufferImpl **ppdsb,
- IDirectSoundBufferImpl *pdsb);
-
-/*****************************************************************************
- * SecondaryBuffer implementation structure
- */
-struct SecondaryBufferImpl
-{
- const IDirectSoundBuffer8Vtbl *lpVtbl;
- LONG ref;
- IDirectSoundBufferImpl* dsb;
-};
-
-HRESULT SecondaryBufferImpl_Create(
- IDirectSoundBufferImpl *dsb,
- SecondaryBufferImpl **pdsb);
-
-/*****************************************************************************
- * PrimaryBuffer implementation structure
- */
-struct PrimaryBufferImpl
-{
- const IDirectSoundBufferVtbl *lpVtbl;
- LONG ref;
- DirectSoundDevice* device;
-};
+ IDirectSoundBufferImpl *pdsb) DECLSPEC_HIDDEN;
+void secondarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
+const IDirectSound3DListenerVtbl ds3dlvt DECLSPEC_HIDDEN;
+const IDirectSound3DBufferVtbl ds3dbvt DECLSPEC_HIDDEN;
+const IKsPropertySetVtbl iksbvt DECLSPEC_HIDDEN;
-HRESULT PrimaryBufferImpl_Create(
- DirectSoundDevice * device,
- PrimaryBufferImpl **ppdsb,
- LPCDSBUFFERDESC dsbd);
-
-/*****************************************************************************
- * DirectSoundCaptureDevice implementation structure
- */
-struct DirectSoundCaptureDevice
-{
- /* IDirectSoundCaptureImpl fields */
- GUID guid;
- LONG ref;
-
- /* DirectSound driver stuff */
- PIDSCDRIVER driver;
- DSDRIVERDESC drvdesc;
- DSCDRIVERCAPS drvcaps;
- PIDSCDRIVERBUFFER hwbuf;
-
- /* wave driver info */
- HWAVEIN hwi;
-
- /* more stuff */
- LPBYTE buffer;
- DWORD buflen;
-
- PWAVEFORMATEX pwfx;
-
- IDirectSoundCaptureBufferImpl* capture_buffer;
- DWORD state;
- LPWAVEHDR pwave;
- int nrofpwaves;
- int index;
- CRITICAL_SECTION lock;
-};
-
-HRESULT DirectSoundCaptureDevice_Initialize(
- DirectSoundCaptureDevice ** ppDevice,
- LPCGUID lpcGUID);
-ULONG DirectSoundCaptureDevice_Release(
- DirectSoundCaptureDevice * device);
-
-/*****************************************************************************
- * IDirectSoundCaptureBuffer implementation structure
- */
-struct IDirectSoundCaptureBufferImpl
-{
- /* IUnknown fields */
- const IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
- LONG ref;
-
- /* IDirectSoundCaptureBufferImpl fields */
- DirectSoundCaptureDevice* device;
- /* FIXME: don't need this */
- LPDSCBUFFERDESC pdscbd;
- DWORD flags;
-
- /* IDirectSoundCaptureNotifyImpl fields */
- IDirectSoundCaptureNotifyImpl* notify;
- LPDSBPOSITIONNOTIFY notifies;
- int nrofnotifies;
- PIDSDRIVERNOTIFY hwnotify;
-};
-
-HRESULT IDirectSoundCaptureBufferImpl_Create(
- DirectSoundCaptureDevice *device,
- IDirectSoundCaptureBufferImpl ** ppobj,
- LPCDSCBUFFERDESC lpcDSCBufferDesc);
-
-/*****************************************************************************
- * IDirectSoundFullDuplex implementation structure
- */
-struct IDirectSoundFullDuplexImpl
-{
- /* IUnknown fields */
- const IDirectSoundFullDuplexVtbl *lpVtbl;
- LONG ref;
-
- /* IDirectSoundFullDuplexImpl fields */
- DirectSoundDevice *renderer_device;
- DirectSoundCaptureDevice *capture_device;
-
- LPUNKNOWN pUnknown;
- LPDIRECTSOUND pDS;
- LPDIRECTSOUND8 pDS8;
- LPDIRECTSOUNDCAPTURE pDSC;
-};
-
-/*****************************************************************************
- * IDirectSoundFullDuplex COM components
- */
-struct IDirectSoundFullDuplex_IUnknown {
- const IUnknownVtbl *lpVtbl;
- LONG ref;
- IDirectSoundFullDuplexImpl *pdsfd;
-};
-
-struct IDirectSoundFullDuplex_IDirectSound {
- const IDirectSoundVtbl *lpVtbl;
- LONG ref;
- IDirectSoundFullDuplexImpl *pdsfd;
-};
-
-struct IDirectSoundFullDuplex_IDirectSound8 {
- const IDirectSound8Vtbl *lpVtbl;
- LONG ref;
- IDirectSoundFullDuplexImpl *pdsfd;
-};
-
-struct IDirectSoundFullDuplex_IDirectSoundCapture {
- const IDirectSoundCaptureVtbl *lpVtbl;
- LONG ref;
- IDirectSoundFullDuplexImpl *pdsfd;
-};
-
-/*****************************************************************************
- * IDirectSound3DListener implementation structure
- */
-struct IDirectSound3DListenerImpl
-{
- /* IUnknown fields */
- const IDirectSound3DListenerVtbl *lpVtbl;
- LONG ref;
- /* IDirectSound3DListenerImpl fields */
- DirectSoundDevice* device;
-};
-
-HRESULT IDirectSound3DListenerImpl_Create(
- DirectSoundDevice *device,
- IDirectSound3DListenerImpl **pdsl);
-
-/*****************************************************************************
- * IKsBufferPropertySet implementation structure
- */
-struct IKsBufferPropertySetImpl
-{
- /* IUnknown fields */
- const IKsPropertySetVtbl *lpVtbl;
- LONG ref;
- /* IKsPropertySetImpl fields */
- IDirectSoundBufferImpl* dsb;
-};
-
-HRESULT IKsBufferPropertySetImpl_Create(
- IDirectSoundBufferImpl *dsb,
- IKsBufferPropertySetImpl **piks);
-HRESULT IKsBufferPropertySetImpl_Destroy(
- IKsBufferPropertySetImpl *piks);
-
-/*****************************************************************************
- * IKsPrivatePropertySet implementation structure
- */
-struct IKsPrivatePropertySetImpl
-{
- /* IUnknown fields */
- const IKsPropertySetVtbl *lpVtbl;
- LONG ref;
-};
-
-HRESULT IKsPrivatePropertySetImpl_Create(
- REFIID riid,
- IKsPrivatePropertySetImpl **piks);
-
-/*****************************************************************************
- * IDirectSound3DBuffer implementation structure
- */
-struct IDirectSound3DBufferImpl
-{
- /* IUnknown fields */
- const IDirectSound3DBufferVtbl *lpVtbl;
- LONG ref;
- /* IDirectSound3DBufferImpl fields */
- IDirectSoundBufferImpl* dsb;
-};
-
-HRESULT IDirectSound3DBufferImpl_Create(
- IDirectSoundBufferImpl *dsb,
- IDirectSound3DBufferImpl **pds3db);
-HRESULT IDirectSound3DBufferImpl_Destroy(
- IDirectSound3DBufferImpl *pds3db);
+HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
/*******************************************************************************
*/
/* dsound.c */
-HRESULT DSOUND_Create(REFIID riid, LPDIRECTSOUND *ppDS);
-HRESULT DSOUND_Create8(REFIID riid, LPDIRECTSOUND8 *ppDS);
+HRESULT DSOUND_Create(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
+HRESULT DSOUND_Create8(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
+HRESULT IDirectSoundImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_ds8) DECLSPEC_HIDDEN;
/* primary.c */
-DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign);
-HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device);
-HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device);
-HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device);
-HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device);
-HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos);
-HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex, BOOL forced);
-HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave);
+HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) DECLSPEC_HIDDEN;
+HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) DECLSPEC_HIDDEN;
+HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device) DECLSPEC_HIDDEN;
+HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device) DECLSPEC_HIDDEN;
+HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos) DECLSPEC_HIDDEN;
+LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
+HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave) DECLSPEC_HIDDEN;
+HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device) DECLSPEC_HIDDEN;
+HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb,
+ const DSBUFFERDESC *dsbd) DECLSPEC_HIDDEN;
+void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN;
+HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN;
+LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN;
/* duplex.c */
-
-HRESULT DSOUND_FullDuplexCreate(REFIID riid, LPDIRECTSOUNDFULLDUPLEX* ppDSFD);
+
+HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
/* mixer.c */
-DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos);
-void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len);
-void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
-void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan);
-void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
-void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer);
-DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot);
+void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
+void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
+void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
+void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
+DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, float *overshot) DECLSPEC_HIDDEN;
-void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
-void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
+DWORD CALLBACK DSOUND_mixthread(void *ptr) DECLSPEC_HIDDEN;
/* sound3d.c */
-void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
+void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
/* capture.c */
-HRESULT DSOUND_CaptureCreate(REFIID riid, LPDIRECTSOUNDCAPTURE *ppDSC);
-HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *ppDSC8);
-HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(
- LPDIRECTSOUNDCAPTURE iface,
- LPCDSCBUFFERDESC lpcDSCBufferDesc,
- LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
- LPUNKNOWN pUnk);
-HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(
- LPDIRECTSOUNDCAPTURE iface,
- LPDSCCAPS lpDSCCaps);
-HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
- LPDIRECTSOUNDCAPTURE iface,
- LPCGUID lpcGUID);
+HRESULT DSOUND_CaptureCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
+HRESULT DSOUND_CaptureCreate8(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
+HRESULT IDirectSoundCaptureImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_dsc8) DECLSPEC_HIDDEN;
#define STATE_STOPPED 0
#define STATE_STARTING 1
#define STATE_CAPTURING 2
#define STATE_STOPPING 3
-#define DSOUND_FREQSHIFT (20)
+extern CRITICAL_SECTION DSOUND_renderers_lock DECLSPEC_HIDDEN;
+extern CRITICAL_SECTION DSOUND_capturers_lock DECLSPEC_HIDDEN;
+extern struct list DSOUND_capturers DECLSPEC_HIDDEN;
+extern struct list DSOUND_renderers DECLSPEC_HIDDEN;
+
+extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
+extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN;
+
+extern WCHAR wine_vxd_drv[] DECLSPEC_HIDDEN;
-extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
-extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
+void setup_dsound_options(void) DECLSPEC_HIDDEN;
-extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS];
-extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
+HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device) DECLSPEC_HIDDEN;
-HRESULT mmErr(UINT err);
-void setup_dsound_options(void);
-const char * dumpCooperativeLevel(DWORD level);
+BOOL DSOUND_check_supported(IAudioClient *client, DWORD rate,
+ DWORD depth, WORD channels) DECLSPEC_HIDDEN;
+UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) DECLSPEC_HIDDEN;
+HRESULT enumerate_mmdevices(EDataFlow flow, GUID *guids,
+ LPDSENUMCALLBACKW cb, void *user) DECLSPEC_HIDDEN;
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
+#define COBJMACROS
#include <windef.h>
#include <winbase.h>
//#include "winuser.h"
#include <winternl.h>
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-/*******************************************************************************
- * IUnknown
+/*****************************************************************************
+ * IDirectSoundFullDuplex implementation structure
*/
-static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
- LPUNKNOWN iface,
- REFIID riid,
- LPVOID * ppobj)
+typedef struct IDirectSoundFullDuplexImpl
{
- IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
-}
+ IUnknown IUnknown_iface;
+ IDirectSoundFullDuplex IDirectSoundFullDuplex_iface;
+ LONG ref, refdsfd, numIfaces;
+ IUnknown *ds8_unk; /* Aggregated IDirectSound8 */
+ IUnknown *dsc8_unk; /* Aggregated IDirectSoundCapture8 */
+} IDirectSoundFullDuplexImpl;
-static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
- LPUNKNOWN iface)
+static void fullduplex_destroy(IDirectSoundFullDuplexImpl *This)
{
- IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
+ IDirectSound8 *ds8;
+ IDirectSoundCapture8 *dsc8;
-static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
- LPUNKNOWN iface)
-{
- IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- IDirectSound_Release(This->pdsfd->pUnknown);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
+ if (This->ds8_unk) {
+ IUnknown_QueryInterface(This->ds8_unk, &IID_IDirectSound8, (void**)&ds8);
+ while(IDirectSound8_Release(ds8) > 0);
+ IUnknown_Release(This->ds8_unk);
}
- return ref;
-}
-
-static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
-{
- IDirectSoundFullDuplex_IUnknown_QueryInterface,
- IDirectSoundFullDuplex_IUnknown_AddRef,
- IDirectSoundFullDuplex_IUnknown_Release
-};
-
-static HRESULT IDirectSoundFullDuplex_IUnknown_Create(
- LPDIRECTSOUNDFULLDUPLEX pdsfd,
- LPUNKNOWN * ppunk)
-{
- IDirectSoundFullDuplex_IUnknown * pdsfdunk;
- TRACE("(%p,%p)\n",pdsfd,ppunk);
-
- if (pdsfd == NULL) {
- ERR("invalid parameter: pdsfd == NULL\n");
- return DSERR_INVALIDPARAM;
+ if (This->dsc8_unk) {
+ IUnknown_QueryInterface(This->dsc8_unk, &IID_IDirectSoundCapture8, (void**)&dsc8);
+ while(IDirectSoundCapture_Release(dsc8) > 0);
+ IUnknown_Release(This->dsc8_unk);
}
-
- if (ppunk == NULL) {
- ERR("invalid parameter: ppunk == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
- if (pdsfdunk == NULL) {
- WARN("out of memory\n");
- *ppunk = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
- pdsfdunk->ref = 0;
- pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
-
- *ppunk = (LPUNKNOWN)pdsfdunk;
-
- return DS_OK;
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
}
/*******************************************************************************
- * IDirectSoundFullDuplex_IDirectSound
+ * IUnknown implemetation for DirectSoundFullDuplex
*/
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_QueryInterface(
- LPDIRECTSOUND iface,
- REFIID riid,
- LPVOID * ppobj)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
-}
-
-static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_AddRef(
- LPDIRECTSOUND iface)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_Release(
- LPDIRECTSOUND iface)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- IDirectSound_Release(This->pdsfd->pDS);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer(
- LPDIRECTSOUND iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DirectSoundDevice_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk,FALSE);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_GetCaps(
- LPDIRECTSOUND iface,
- LPDSCAPS lpDSCaps)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return DirectSoundDevice_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer(
- LPDIRECTSOUND iface,
- LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel(
- LPDIRECTSOUND iface,
- HWND hwnd,
- DWORD level)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
- return DirectSoundDevice_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_Compact(
- LPDIRECTSOUND iface)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p)\n", This);
- return DirectSoundDevice_Compact(This->pdsfd->renderer_device);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig(
- LPDIRECTSOUND iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return DirectSoundDevice_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig(
- LPDIRECTSOUND iface,
- DWORD config)
-{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p,0x%08x)\n",This,config);
- return DirectSoundDevice_SetSpeakerConfig(This->pdsfd->renderer_device,config);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_Initialize(
- LPDIRECTSOUND iface,
- LPCGUID lpcGuid)
+static inline IDirectSoundFullDuplexImpl *impl_from_IUnknown(IUnknown *iface)
{
- IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid);
+ return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IUnknown_iface);
}
-static const IDirectSoundVtbl DirectSoundFullDuplex_DirectSound_Vtbl =
+static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{
- IDirectSoundFullDuplex_IDirectSound_QueryInterface,
- IDirectSoundFullDuplex_IDirectSound_AddRef,
- IDirectSoundFullDuplex_IDirectSound_Release,
- IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer,
- IDirectSoundFullDuplex_IDirectSound_GetCaps,
- IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer,
- IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel,
- IDirectSoundFullDuplex_IDirectSound_Compact,
- IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig,
- IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig,
- IDirectSoundFullDuplex_IDirectSound_Initialize
-};
-
-static HRESULT IDirectSoundFullDuplex_IDirectSound_Create(
- LPDIRECTSOUNDFULLDUPLEX pdsfd,
- LPDIRECTSOUND * ppds)
-{
- IDirectSoundFullDuplex_IDirectSound * pdsfdds;
- TRACE("(%p,%p)\n",pdsfd,ppds);
-
- if (pdsfd == NULL) {
- ERR("invalid parameter: pdsfd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
- if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
- WARN("not initialized\n");
- *ppds = NULL;
- return DSERR_UNINITIALIZED;
+ if (!ppv) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
}
- pdsfdds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds));
- if (pdsfdds == NULL) {
- WARN("out of memory\n");
- *ppds = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsfdds->lpVtbl = &DirectSoundFullDuplex_DirectSound_Vtbl;
- pdsfdds->ref = 0;
- pdsfdds->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
-
- *ppds = (LPDIRECTSOUND)pdsfdds;
+ if (IsEqualIID(riid, &IID_IUnknown)) {
+ IUnknown_AddRef(&This->IUnknown_iface);
+ *ppv = &This->IUnknown_iface;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
+ IDirectSoundFullDuplex_AddRef(&This->IDirectSoundFullDuplex_iface);
+ *ppv = &This->IDirectSoundFullDuplex_iface;
+ return S_OK;
+ } else if (This->ds8_unk && (IsEqualIID(riid, &IID_IDirectSound) ||
+ IsEqualIID(riid, &IID_IDirectSound8)))
+ return IUnknown_QueryInterface(This->ds8_unk, riid, ppv);
+ else if (This->dsc8_unk && IsEqualIID(riid, &IID_IDirectSoundCapture))
+ return IUnknown_QueryInterface(This->dsc8_unk, riid, ppv);
- return DS_OK;
+ *ppv = NULL;
+ return E_NOINTERFACE;
}
-/*******************************************************************************
- * IDirectSoundFullDuplex_IDirectSound8
- */
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
- LPDIRECTSOUND8 iface,
- REFIID riid,
- LPVOID * ppobj)
+static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface)
{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
-}
+ IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
-static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
- LPDIRECTSOUND8 iface)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
+ TRACE("(%p) ref=%d\n", This, ref);
-static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
- LPDIRECTSOUND8 iface)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- IDirectSound_Release(This->pdsfd->pDS8);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
return ref;
}
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DirectSoundDevice_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk,TRUE);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
- LPDIRECTSOUND8 iface,
- LPDSCAPS lpDSCaps)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return DirectSoundDevice_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb)
+static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface)
{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
-}
+ IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
- LPDIRECTSOUND8 iface,
- HWND hwnd,
- DWORD level)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
- return DirectSoundDevice_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
-}
+ TRACE("(%p) ref=%d\n", This, ref);
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
- LPDIRECTSOUND8 iface)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p)\n", This);
- return DirectSoundDevice_Compact(This->pdsfd->renderer_device);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return DirectSoundDevice_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- DWORD config)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p,0x%08x)\n",This,config);
- return DirectSoundDevice_SetSpeakerConfig(This->pdsfd->renderer_device,config);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
- LPDIRECTSOUND8 iface,
- LPCGUID lpcGuid)
-{
- IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid);
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ fullduplex_destroy(This);
+ return ref;
}
-static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
+static const IUnknownVtbl unk_vtbl =
{
- IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
- IDirectSoundFullDuplex_IDirectSound8_AddRef,
- IDirectSoundFullDuplex_IDirectSound8_Release,
- IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
- IDirectSoundFullDuplex_IDirectSound8_GetCaps,
- IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
- IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
- IDirectSoundFullDuplex_IDirectSound8_Compact,
- IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
- IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
- IDirectSoundFullDuplex_IDirectSound8_Initialize
+ IUnknownImpl_QueryInterface,
+ IUnknownImpl_AddRef,
+ IUnknownImpl_Release
};
-static HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
- LPDIRECTSOUNDFULLDUPLEX pdsfd,
- LPDIRECTSOUND8 * ppds8)
-{
- IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
- TRACE("(%p,%p)\n",pdsfd,ppds8);
-
- if (pdsfd == NULL) {
- ERR("invalid parameter: pdsfd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppds8 == NULL) {
- ERR("invalid parameter: ppds8 == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
- WARN("not initialized\n");
- *ppds8 = NULL;
- return DSERR_UNINITIALIZED;
- }
-
- pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
- if (pdsfdds8 == NULL) {
- WARN("out of memory\n");
- *ppds8 = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
- pdsfdds8->ref = 0;
- pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
-
- *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
-
- return DS_OK;
-}
-
-/*******************************************************************************
- * IDirectSoundFullDuplex_IDirectSoundCapture
+/***************************************************************************
+ * IDirectSoundFullDuplex implementation
*/
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
- LPDIRECTSOUNDCAPTURE iface,
- REFIID riid,
- LPVOID * ppobj)
+static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex *iface)
{
- IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
+ return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundFullDuplex_iface);
}
-static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
- LPDIRECTSOUNDCAPTURE iface)
+static HRESULT WINAPI IDirectSoundFullDuplexImpl_QueryInterface(IDirectSoundFullDuplex *iface,
+ REFIID riid, void **ppv)
{
- IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
+ IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
+ TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
+ return IUnknown_QueryInterface(&This->IUnknown_iface, riid, ppv);
}
-static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
- LPDIRECTSOUNDCAPTURE iface)
+static ULONG WINAPI IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface)
{
- IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- IDirectSoundCapture_Release(This->pdsfd->pDSC);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
- LPDIRECTSOUNDCAPTURE iface,
- LPCDSCBUFFERDESC lpcDSCBufferDesc,
- LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
- LPUNKNOWN pUnk)
-{
- IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
- return IDirectSoundCaptureImpl_CreateCaptureBuffer(This->pdsfd->pDSC,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
- LPDIRECTSOUNDCAPTURE iface,
- LPDSCCAPS lpDSCCaps)
-{
- IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
- TRACE("(%p,%p)\n",This,lpDSCCaps);
- return IDirectSoundCaptureImpl_GetCaps(This->pdsfd->pDSC, lpDSCCaps);
-}
-
-static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
- LPDIRECTSOUNDCAPTURE iface,
- LPCGUID lpcGUID)
-{
- IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
- return IDirectSoundCaptureImpl_Initialize(This->pdsfd->pDSC,lpcGUID);
-}
-
-static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
-{
- IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
- IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
- IDirectSoundFullDuplex_IDirectSoundCapture_Release,
- IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
- IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
- IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
-};
-
-static HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
- LPDIRECTSOUNDFULLDUPLEX pdsfd,
- LPDIRECTSOUNDCAPTURE8 * ppdsc8)
-{
- IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
- TRACE("(%p,%p)\n",pdsfd,ppdsc8);
-
- if (pdsfd == NULL) {
- ERR("invalid parameter: pdsfd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppdsc8 == NULL) {
- ERR("invalid parameter: ppdsc8 == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (((IDirectSoundFullDuplexImpl*)pdsfd)->capture_device == NULL) {
- WARN("not initialized\n");
- *ppdsc8 = NULL;
- return DSERR_UNINITIALIZED;
- }
+ IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
+ ULONG ref = InterlockedIncrement(&This->refdsfd);
- pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
- if (pdsfddsc == NULL) {
- WARN("out of memory\n");
- *ppdsc8 = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
- pdsfddsc->ref = 0;
- pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
-
- *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
-
- return DS_OK;
-}
+ TRACE("(%p) ref=%d\n", This, ref);
-/***************************************************************************
- * IDirectSoundFullDuplexImpl
- */
-static ULONG WINAPI
-IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
-{
- IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
return ref;
}
-static HRESULT WINAPI
-IDirectSoundFullDuplexImpl_QueryInterface(
- LPDIRECTSOUNDFULLDUPLEX iface,
- REFIID riid,
- LPVOID* ppobj )
+static ULONG WINAPI IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex *iface)
{
- IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
- TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
+ IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
+ ULONG ref = InterlockedDecrement(&This->refdsfd);
- if (ppobj == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
+ TRACE("(%p) ref=%d\n", This, ref);
- *ppobj = NULL;
-
- if (IsEqualIID(riid, &IID_IUnknown)) {
- if (!This->pUnknown) {
- IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
- if (!This->pUnknown) {
- WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
- *ppobj = This->pUnknown;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
- IDirectSoundFullDuplexImpl_AddRef(iface);
- *ppobj = This;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSound)) {
- if (!This->pDS) {
- IDirectSoundFullDuplex_IDirectSound_Create(iface, &This->pDS);
- if (!This->pDS) {
- WARN("IDirectSoundFullDuplex_IDirectSound_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSoundFullDuplex_IDirectSound_AddRef(This->pDS);
- *ppobj = This->pDS;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
- if (!This->pDS8) {
- IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
- if (!This->pDS8) {
- WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
- *ppobj = This->pDS8;
- return S_OK;
- } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
- if (!This->pDSC) {
- IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
- if (!This->pDSC) {
- WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
- *ppobj = NULL;
- return E_NOINTERFACE;
- }
- }
- IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
- *ppobj = This->pDSC;
- return S_OK;
- }
-
- return E_NOINTERFACE;
-}
-
-static ULONG WINAPI
-IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
-{
- IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
-
- if (!ref) {
- if (This->capture_device)
- DirectSoundCaptureDevice_Release(This->capture_device);
- if (This->renderer_device)
- DirectSoundDevice_Release(This->renderer_device);
- HeapFree( GetProcessHeap(), 0, This );
- TRACE("(%p) released\n", This);
- }
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ fullduplex_destroy(This);
return ref;
}
-static HRESULT WINAPI
-IDirectSoundFullDuplexImpl_Initialize(
- LPDIRECTSOUNDFULLDUPLEX iface,
- LPCGUID pCaptureGuid,
- LPCGUID pRendererGuid,
- LPCDSCBUFFERDESC lpDscBufferDesc,
- LPCDSBUFFERDESC lpDsBufferDesc,
- HWND hWnd,
- DWORD dwLevel,
- LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
- LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
+static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(IDirectSoundFullDuplex *iface,
+ const GUID *capture_dev, const GUID *render_dev, const DSCBUFFERDESC *cbufdesc,
+ const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level, IDirectSoundCaptureBuffer8 **dscb8,
+ IDirectSoundBuffer8 **dsb8)
{
+ IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
+ IDirectSound8 *ds8 = NULL;
+ IDirectSoundCapture8 *dsc8 = NULL;
HRESULT hr;
- IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
- IDirectSoundBufferImpl * dsb;
- TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
- debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
- lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
- lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
+ TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This, debugstr_guid(capture_dev),
+ debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dscb8, dsb8);
+
+ if (!dscb8 || !dsb8)
+ return E_INVALIDARG;
- if (This->renderer_device != NULL || This->capture_device != NULL) {
+ *dscb8 = NULL;
+ *dsb8 = NULL;
+
+ if (This->ds8_unk || This->dsc8_unk) {
WARN("already initialized\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
return DSERR_ALREADYINITIALIZED;
}
- hr = DirectSoundDevice_Initialize(&This->renderer_device, pRendererGuid);
+ hr = IDirectSoundImpl_Create(&This->IUnknown_iface, &IID_IUnknown, (void**)&This->ds8_unk,
+ TRUE);
+ if (SUCCEEDED(hr)) {
+ IUnknown_QueryInterface(This->ds8_unk, &IID_IDirectSound8, (void**)&ds8);
+ hr = IDirectSound_Initialize(ds8, render_dev);
+ }
if (hr != DS_OK) {
- WARN("DirectSoundDevice_Initialize() failed\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
- return hr;
+ WARN("Creating/initializing IDirectSound8 failed\n");
+ goto error;
}
- if (dwLevel==DSSCL_PRIORITY || dwLevel==DSSCL_EXCLUSIVE) {
- WARN("level=%s not fully supported\n",
- dwLevel==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
- }
- This->renderer_device->priolevel = dwLevel;
+ IDirectSound8_SetCooperativeLevel(ds8, hwnd, level);
- hr = DSOUND_PrimarySetFormat(This->renderer_device, lpDsBufferDesc->lpwfxFormat, dwLevel == DSSCL_EXCLUSIVE);
- if (hr != DS_OK) {
- WARN("DSOUND_PrimarySetFormat() failed\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
- return hr;
- }
- hr = IDirectSoundBufferImpl_Create(This->renderer_device, &dsb, lpDsBufferDesc);
+ hr = IDirectSound8_CreateSoundBuffer(ds8, bufdesc, (IDirectSoundBuffer**)dsb8, NULL);
if (hr != DS_OK) {
- WARN("IDirectSoundBufferImpl_Create() failed\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
- return hr;
+ WARN("IDirectSoundBuffer_Create() failed\n");
+ goto error;
}
- hr = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl **)lplpDirectSoundBuffer8);
- if (hr != DS_OK) {
- WARN("SecondaryBufferImpl_Create() failed\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
- return hr;
+ hr = IDirectSoundCaptureImpl_Create(&This->IUnknown_iface, &IID_IUnknown,
+ (void**)&This->dsc8_unk, TRUE);
+ if (SUCCEEDED(hr)) {
+ IUnknown_QueryInterface(This->dsc8_unk, &IID_IDirectSoundCapture8, (void**)&dsc8);
+ hr = IDirectSoundCapture_Initialize(dsc8, capture_dev);
}
- IDirectSoundBuffer8_AddRef(*lplpDirectSoundBuffer8);
-
- hr = DirectSoundCaptureDevice_Initialize(&This->capture_device, pCaptureGuid);
if (hr != DS_OK) {
- WARN("DirectSoundCaptureDevice_Initialize() failed\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
- return hr;
+ WARN("Creating/initializing IDirectSoundCapture8 failed\n");
+ goto error;
}
- hr = IDirectSoundCaptureBufferImpl_Create(This->capture_device,
- (IDirectSoundCaptureBufferImpl **)lplpDirectSoundCaptureBuffer8,
- lpDscBufferDesc);
+ hr = IDirectSoundCapture_CreateCaptureBuffer(dsc8, cbufdesc,
+ (IDirectSoundCaptureBuffer**)dscb8, NULL);
if (hr != DS_OK) {
- WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
- *lplpDirectSoundCaptureBuffer8 = NULL;
- *lplpDirectSoundBuffer8 = NULL;
- return hr;
+ WARN("IDirectSoundCapture_CreateCaptureBuffer() failed\n");
+ goto error;
}
+ IDirectSound8_Release(ds8);
+ IDirectSoundCapture_Release(dsc8);
+ return DS_OK;
+
+error:
+ if (*dsb8) {
+ IDirectSoundBuffer8_Release(*dsb8);
+ *dsb8 = NULL;
+ }
+ if (ds8)
+ IDirectSound8_Release(ds8);
+ if (This->ds8_unk) {
+ IUnknown_Release(This->ds8_unk);
+ This->ds8_unk = NULL;
+ }
+ if (*dscb8) {
+ IDirectSoundCaptureBuffer8_Release(*dscb8);
+ *dscb8 = NULL;
+ }
+ if (dsc8)
+ IDirectSoundCapture_Release(dsc8);
+ if (This->dsc8_unk) {
+ IUnknown_Release(This->dsc8_unk);
+ This->dsc8_unk = NULL;
+ }
return hr;
}
-static const IDirectSoundFullDuplexVtbl dsfdvt =
+static const IDirectSoundFullDuplexVtbl dsfd_vtbl =
{
/* IUnknown methods */
IDirectSoundFullDuplexImpl_QueryInterface,
IDirectSoundFullDuplexImpl_Initialize
};
-HRESULT DSOUND_FullDuplexCreate(
- REFIID riid,
- LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
+HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv)
{
- IDirectSoundFullDuplexImpl *This = NULL;
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
-
- if (ppDSFD == NULL) {
- WARN("invalid parameter: ppDSFD == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (!IsEqualIID(riid, &IID_IUnknown) &&
- !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
- *ppDSFD = 0;
- return E_NOINTERFACE;
- }
-
- /* Get dsound configuration */
- setup_dsound_options();
+ IDirectSoundFullDuplexImpl *obj;
+ HRESULT hr;
- This = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
+ TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
- if (This == NULL) {
+ *ppv = NULL;
+ obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));
+ if (!obj) {
WARN("out of memory\n");
- *ppDSFD = NULL;
return DSERR_OUTOFMEMORY;
}
- This->lpVtbl = &dsfdvt;
- This->ref = 1;
- This->capture_device = NULL;
- This->renderer_device = NULL;
+ setup_dsound_options();
- *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
+ obj->IDirectSoundFullDuplex_iface.lpVtbl = &dsfd_vtbl;
+ obj->IUnknown_iface.lpVtbl = &unk_vtbl;
+ obj->ref = 1;
+ obj->refdsfd = 0;
+ obj->numIfaces = 1;
- return DS_OK;
+ hr = IUnknown_QueryInterface(&obj->IUnknown_iface, riid, ppv);
+ IUnknown_Release(&obj->IUnknown_iface);
+
+ return hr;
}
/***************************************************************************
* Create and initialize a DirectSoundFullDuplex interface.
*
* PARAMS
- * pcGuidCaptureDevice [I] Address of sound capture device GUID.
- * pcGuidRenderDevice [I] Address of sound render device GUID.
- * pcDSCBufferDesc [I] Address of capture buffer description.
- * pcDSBufferDesc [I] Address of render buffer description.
- * hWnd [I] Handle to application window.
- * dwLevel [I] Cooperative level.
- * ppDSFD [O] Address where full duplex interface returned.
- * ppDSCBuffer8 [0] Address where capture buffer interface returned.
- * ppDSBuffer8 [0] Address where render buffer interface returned.
- * pUnkOuter [I] Must be NULL.
+ * capture_dev [I] Address of sound capture device GUID.
+ * render_dev [I] Address of sound render device GUID.
+ * cbufdesc [I] Address of capture buffer description.
+ * bufdesc [I] Address of render buffer description.
+ * hwnd [I] Handle to application window.
+ * level [I] Cooperative level.
+ * dsfd [O] Address where full duplex interface returned.
+ * dscb8 [0] Address where capture buffer interface returned.
+ * dsb8 [0] Address where render buffer interface returned.
+ * outer_unk [I] Must be NULL.
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
* DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
*/
-HRESULT WINAPI
-DirectSoundFullDuplexCreate(
- LPCGUID pcGuidCaptureDevice,
- LPCGUID pcGuidRenderDevice,
- LPCDSCBUFFERDESC pcDSCBufferDesc,
- LPCDSBUFFERDESC pcDSBufferDesc,
- HWND hWnd,
- DWORD dwLevel,
- LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
- LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
- LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
- LPUNKNOWN pUnkOuter)
+HRESULT WINAPI DirectSoundFullDuplexCreate(const GUID *capture_dev, const GUID *render_dev,
+ const DSCBUFFERDESC *cbufdesc, const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level,
+ IDirectSoundFullDuplex **dsfd, IDirectSoundCaptureBuffer8 **dscb8,
+ IDirectSoundBuffer8 **dsb8, IUnknown *outer_unk)
{
- HRESULT hres;
- IDirectSoundFullDuplexImpl *This = NULL;
- TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
- debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
- pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
- ppDSBuffer8, pUnkOuter);
-
- if (pUnkOuter) {
- WARN("pUnkOuter != 0\n");
- *ppDSFD = NULL;
- return DSERR_NOAGGREGATION;
- }
-
- if (pcDSCBufferDesc == NULL) {
- WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
- *ppDSFD = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (pcDSBufferDesc == NULL) {
- WARN("invalid parameter: pcDSBufferDesc == NULL\n");
- *ppDSFD = NULL;
- return DSERR_INVALIDPARAM;
- }
+ HRESULT hr;
- if (ppDSFD == NULL) {
- WARN("invalid parameter: ppDSFD == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n", debugstr_guid(capture_dev),
+ debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dsfd, dscb8, dsb8,
+ outer_unk);
- if (ppDSCBuffer8 == NULL) {
- WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
- *ppDSFD = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (ppDSBuffer8 == NULL) {
- WARN("invalid parameter: ppDSBuffer8 == NULL\n");
- *ppDSFD = NULL;
+ if (!dsfd)
return DSERR_INVALIDPARAM;
+ if (outer_unk) {
+ *dsfd = NULL;
+ return DSERR_NOAGGREGATION;
}
- /* Get dsound configuration */
- setup_dsound_options();
-
- This = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
-
- if (This == NULL) {
- WARN("out of memory\n");
- *ppDSFD = NULL;
- return DSERR_OUTOFMEMORY;
+ hr = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (void**)dsfd);
+ if (hr == DS_OK) {
+ hr = IDirectSoundFullDuplex_Initialize(*dsfd, capture_dev, render_dev, cbufdesc, bufdesc,
+ hwnd, level, dscb8, dsb8);
+ if (hr != DS_OK) {
+ IDirectSoundFullDuplex_Release(*dsfd);
+ *dsfd = NULL;
+ WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
+ }
}
- This->lpVtbl = &dsfdvt;
- This->ref = 1;
- This->capture_device = NULL;
- This->renderer_device = NULL;
-
- hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
- pcGuidCaptureDevice,
- pcGuidRenderDevice,
- pcDSCBufferDesc,
- pcDSBufferDesc,
- hWnd, dwLevel, ppDSCBuffer8,
- ppDSBuffer8);
- if (hres != DS_OK) {
- HeapFree(GetProcessHeap(), 0, This);
- WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
- *ppDSFD = NULL;
- } else
- *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
-
- return hres;
+ return hr;
}
--- /dev/null
+#ifdef _MSC_VER
+#pragma warning (disable:4305)
+#endif
+
+/* generated by tools/make_fir; DO NOT EDIT! */
+static const int fir_len = 7907;
+static const int fir_step = 120;
+static const float fir[] = {
+-0.0000000000, -0.0000021601, -0.0000043304, -0.0000065096, -0.0000086969,
+-0.0000108911, -0.0000130912, -0.0000152960, -0.0000175046, -0.0000197157,
+-0.0000219284, -0.0000241414, -0.0000263537, -0.0000285642, -0.0000307717,
+-0.0000329751, -0.0000351732, -0.0000373650, -0.0000395493, -0.0000417249,
+-0.0000438907, -0.0000460456, -0.0000481885, -0.0000503180, -0.0000524333,
+-0.0000545330, -0.0000566161, -0.0000586814, -0.0000607277, -0.0000627541,
+-0.0000647592, -0.0000667421, -0.0000687015, -0.0000706365, -0.0000725458,
+-0.0000744284, -0.0000762832, -0.0000781091, -0.0000799051, -0.0000816701,
+-0.0000834030, -0.0000851028, -0.0000867685, -0.0000883990, -0.0000899935,
+-0.0000915507, -0.0000930699, -0.0000945500, -0.0000959901, -0.0000973892,
+-0.0000987464, -0.0001000609, -0.0001013318, -0.0001025581, -0.0001037391,
+-0.0001048739, -0.0001059617, -0.0001070018, -0.0001079932, -0.0001089354,
+-0.0001098276, -0.0001106690, -0.0001114590, -0.0001121969, -0.0001128821,
+-0.0001135140, -0.0001140920, -0.0001146154, -0.0001150839, -0.0001154968,
+-0.0001158536, -0.0001161540, -0.0001163974, -0.0001165834, -0.0001167117,
+-0.0001167819, -0.0001167937, -0.0001167467, -0.0001166408, -0.0001164755,
+-0.0001162508, -0.0001159664, -0.0001156222, -0.0001152181, -0.0001147539,
+-0.0001142295, -0.0001136450, -0.0001130003, -0.0001122954, -0.0001115305,
+-0.0001107055, -0.0001098205, -0.0001088758, -0.0001078715, -0.0001068078,
+-0.0001056850, -0.0001045032, -0.0001032628, -0.0001019642, -0.0001006076,
+-0.0000991935, -0.0000977224, -0.0000961945, -0.0000946105, -0.0000929709,
+-0.0000912761, -0.0000895269, -0.0000877237, -0.0000858672, -0.0000839581,
+-0.0000819970, -0.0000799848, -0.0000779221, -0.0000758098, -0.0000736486,
+-0.0000714395, -0.0000691832, -0.0000668807, -0.0000645329, -0.0000621407,
+-0.0000597052, -0.0000572273, -0.0000547082, -0.0000521487, -0.0000495501,
+-0.0000469135, -0.0000442399, -0.0000415306, -0.0000387867, -0.0000360095,
+-0.0000332001, -0.0000303599, -0.0000274901, -0.0000245920, -0.0000216669,
+-0.0000187162, -0.0000157412, -0.0000127433, -0.0000097239, -0.0000066844,
+-0.0000036262, -0.0000005509, 0.0000025402, 0.0000056456, 0.0000087637,
+0.0000118931, 0.0000150322, 0.0000181796, 0.0000213335, 0.0000244926,
+0.0000276553, 0.0000308199, 0.0000339848, 0.0000371486, 0.0000403095,
+0.0000434660, 0.0000466164, 0.0000497592, 0.0000528927, 0.0000560153,
+0.0000591253, 0.0000622212, 0.0000653013, 0.0000683639, 0.0000714075,
+0.0000744303, 0.0000774309, 0.0000804075, 0.0000833585, 0.0000862823,
+0.0000891774, 0.0000920420, 0.0000948747, 0.0000976737, 0.0001004377,
+0.0001031648, 0.0001058537, 0.0001085028, 0.0001111105, 0.0001136753,
+0.0001161957, 0.0001186702, 0.0001210974, 0.0001234757, 0.0001258038,
+0.0001280801, 0.0001303034, 0.0001324722, 0.0001345852, 0.0001366410,
+0.0001386382, 0.0001405757, 0.0001424521, 0.0001442661, 0.0001460166,
+0.0001477024, 0.0001493222, 0.0001508749, 0.0001523595, 0.0001537748,
+0.0001551198, 0.0001563934, 0.0001575947, 0.0001587227, 0.0001597764,
+0.0001607549, 0.0001616575, 0.0001624832, 0.0001632313, 0.0001639010,
+0.0001644915, 0.0001650023, 0.0001654325, 0.0001657817, 0.0001660492,
+0.0001662345, 0.0001663371, 0.0001663566, 0.0001662924, 0.0001661444,
+0.0001659120, 0.0001655949, 0.0001651931, 0.0001647061, 0.0001641339,
+0.0001634764, 0.0001627333, 0.0001619047, 0.0001609906, 0.0001599910,
+0.0001589060, 0.0001577357, 0.0001564803, 0.0001551400, 0.0001537151,
+0.0001522058, 0.0001506125, 0.0001489356, 0.0001471756, 0.0001453328,
+0.0001434079, 0.0001414014, 0.0001393138, 0.0001371460, 0.0001348984,
+0.0001325720, 0.0001301674, 0.0001276856, 0.0001251273, 0.0001224936,
+0.0001197852, 0.0001170033, 0.0001141489, 0.0001112231, 0.0001082270,
+0.0001051617, 0.0001020285, 0.0000988286, 0.0000955632, 0.0000922338,
+0.0000888417, 0.0000853883, 0.0000818750, 0.0000783033, 0.0000746747,
+0.0000709908, 0.0000672531, 0.0000634633, 0.0000596230, 0.0000557339,
+0.0000517978, 0.0000478164, 0.0000437914, 0.0000397247, 0.0000356181,
+0.0000314736, 0.0000272929, 0.0000230781, 0.0000188311, 0.0000145539,
+0.0000102485, 0.0000059168, 0.0000015611, -0.0000028167, -0.0000072145,
+-0.0000116301, -0.0000160614, -0.0000205062, -0.0000249624, -0.0000294277,
+-0.0000339001, -0.0000383772, -0.0000428568, -0.0000473367, -0.0000518146,
+-0.0000562883, -0.0000607554, -0.0000652138, -0.0000696610, -0.0000740949,
+-0.0000785131, -0.0000829133, -0.0000872932, -0.0000916505, -0.0000959829,
+-0.0001002881, -0.0001045638, -0.0001088077, -0.0001130175, -0.0001171909,
+-0.0001213257, -0.0001254195, -0.0001294702, -0.0001334754, -0.0001374329,
+-0.0001413406, -0.0001451961, -0.0001489973, -0.0001527420, -0.0001564281,
+-0.0001600534, -0.0001636158, -0.0001671132, -0.0001705435, -0.0001739047,
+-0.0001771947, -0.0001804116, -0.0001835533, -0.0001866179, -0.0001896036,
+-0.0001925083, -0.0001953304, -0.0001980679, -0.0002007190, -0.0002032820,
+-0.0002057553, -0.0002081370, -0.0002104256, -0.0002126195, -0.0002147171,
+-0.0002167169, -0.0002186173, -0.0002204171, -0.0002221147, -0.0002237089,
+-0.0002251983, -0.0002265817, -0.0002278578, -0.0002290256, -0.0002300839,
+-0.0002310316, -0.0002318677, -0.0002325913, -0.0002332015, -0.0002336975,
+-0.0002340783, -0.0002343433, -0.0002344918, -0.0002345232, -0.0002344368,
+-0.0002342322, -0.0002339089, -0.0002334665, -0.0002329046, -0.0002322229,
+-0.0002314213, -0.0002304995, -0.0002294574, -0.0002282950, -0.0002270123,
+-0.0002256094, -0.0002240864, -0.0002224434, -0.0002206808, -0.0002187988,
+-0.0002167979, -0.0002146784, -0.0002124409, -0.0002100859, -0.0002076141,
+-0.0002050261, -0.0002023227, -0.0001995047, -0.0001965730, -0.0001935285,
+-0.0001903722, -0.0001871051, -0.0001837284, -0.0001802433, -0.0001766509,
+-0.0001729527, -0.0001691499, -0.0001652439, -0.0001612363, -0.0001571285,
+-0.0001529222, -0.0001486190, -0.0001442206, -0.0001397288, -0.0001351454,
+-0.0001304723, -0.0001257113, -0.0001208645, -0.0001159339, -0.0001109216,
+-0.0001058298, -0.0001006605, -0.0000954161, -0.0000900988, -0.0000847109,
+-0.0000792549, -0.0000737331, -0.0000681481, -0.0000625023, -0.0000567983,
+-0.0000510387, -0.0000452261, -0.0000393633, -0.0000334528, -0.0000274975,
+-0.0000215001, -0.0000154635, -0.0000093905, -0.0000032841, 0.0000028530,
+0.0000090176, 0.0000152070, 0.0000214180, 0.0000276476, 0.0000338928,
+0.0000401505, 0.0000464177, 0.0000526912, 0.0000589678, 0.0000652446,
+0.0000715181, 0.0000777854, 0.0000840433, 0.0000902884, 0.0000965177,
+0.0001027279, 0.0001089158, 0.0001150782, 0.0001212119, 0.0001273136,
+0.0001333801, 0.0001394082, 0.0001453946, 0.0001513363, 0.0001572299,
+0.0001630723, 0.0001688602, 0.0001745906, 0.0001802603, 0.0001858661,
+0.0001914049, 0.0001968736, 0.0002022692, 0.0002075885, 0.0002128285,
+0.0002179862, 0.0002230587, 0.0002280430, 0.0002329361, 0.0002377352,
+0.0002424374, 0.0002470399, 0.0002515399, 0.0002559347, 0.0002602215,
+0.0002643977, 0.0002684607, 0.0002724079, 0.0002762367, 0.0002799448,
+0.0002835296, 0.0002869888, 0.0002903200, 0.0002935210, 0.0002965895,
+0.0002995235, 0.0003023207, 0.0003049791, 0.0003074968, 0.0003098718,
+0.0003121023, 0.0003141865, 0.0003161226, 0.0003179089, 0.0003195440,
+0.0003210261, 0.0003223540, 0.0003235261, 0.0003245412, 0.0003253981,
+0.0003260955, 0.0003266324, 0.0003270078, 0.0003272206, 0.0003272702,
+0.0003271556, 0.0003268761, 0.0003264312, 0.0003258202, 0.0003250428,
+0.0003240985, 0.0003229871, 0.0003217083, 0.0003202619, 0.0003186480,
+0.0003168666, 0.0003149178, 0.0003128017, 0.0003105187, 0.0003080692,
+0.0003054536, 0.0003026725, 0.0002997264, 0.0002966162, 0.0002933425,
+0.0002899064, 0.0002863087, 0.0002825506, 0.0002786332, 0.0002745577,
+0.0002703254, 0.0002659378, 0.0002613963, 0.0002567025, 0.0002518580,
+0.0002468647, 0.0002417243, 0.0002364387, 0.0002310100, 0.0002254401,
+0.0002197313, 0.0002138857, 0.0002079058, 0.0002017938, 0.0001955522,
+0.0001891836, 0.0001826906, 0.0001760759, 0.0001693423, 0.0001624925,
+0.0001555296, 0.0001484564, 0.0001412761, 0.0001339917, 0.0001266065,
+0.0001191237, 0.0001115465, 0.0001038785, 0.0000961230, 0.0000882835,
+0.0000803636, 0.0000723668, 0.0000642970, 0.0000561577, 0.0000479528,
+0.0000396861, 0.0000313614, 0.0000229828, 0.0000145541, 0.0000060793,
+-0.0000024374, -0.0000109920, -0.0000195804, -0.0000281984, -0.0000368418,
+-0.0000455063, -0.0000541878, -0.0000628818, -0.0000715842, -0.0000802906,
+-0.0000889965, -0.0000976976, -0.0001063896, -0.0001150680, -0.0001237283,
+-0.0001323662, -0.0001409772, -0.0001495568, -0.0001581006, -0.0001666042,
+-0.0001750629, -0.0001834725, -0.0001918284, -0.0002001262, -0.0002083615,
+-0.0002165298, -0.0002246267, -0.0002326478, -0.0002405888, -0.0002484452,
+-0.0002562128, -0.0002638872, -0.0002714641, -0.0002789393, -0.0002863086,
+-0.0002935678, -0.0003007127, -0.0003077392, -0.0003146432, -0.0003214208,
+-0.0003280679, -0.0003345805, -0.0003409549, -0.0003471871, -0.0003532734,
+-0.0003592101, -0.0003649934, -0.0003706199, -0.0003760859, -0.0003813879,
+-0.0003865227, -0.0003914867, -0.0003962768, -0.0004008897, -0.0004053224,
+-0.0004095717, -0.0004136348, -0.0004175087, -0.0004211906, -0.0004246778,
+-0.0004279676, -0.0004310576, -0.0004339452, -0.0004366281, -0.0004391040,
+-0.0004413708, -0.0004434263, -0.0004452685, -0.0004468956, -0.0004483058,
+-0.0004494974, -0.0004504687, -0.0004512184, -0.0004517450, -0.0004520473,
+-0.0004521241, -0.0004519743, -0.0004515970, -0.0004509913, -0.0004501566,
+-0.0004490922, -0.0004477977, -0.0004462725, -0.0004445166, -0.0004425296,
+-0.0004403116, -0.0004378626, -0.0004351828, -0.0004322726, -0.0004291324,
+-0.0004257626, -0.0004221641, -0.0004183374, -0.0004142837, -0.0004100037,
+-0.0004054988, -0.0004007702, -0.0003958191, -0.0003906472, -0.0003852560,
+-0.0003796473, -0.0003738228, -0.0003677846, -0.0003615348, -0.0003550754,
+-0.0003484089, -0.0003415377, -0.0003344642, -0.0003271912, -0.0003197214,
+-0.0003120577, -0.0003042030, -0.0002961605, -0.0002879334, -0.0002795249,
+-0.0002709385, -0.0002621777, -0.0002532462, -0.0002441476, -0.0002348857,
+-0.0002254646, -0.0002158883, -0.0002061608, -0.0001962863, -0.0001862693,
+-0.0001761140, -0.0001658250, -0.0001554068, -0.0001448641, -0.0001342017,
+-0.0001234244, -0.0001125370, -0.0001015446, -0.0000904522, -0.0000792650,
+-0.0000679881, -0.0000566268, -0.0000451865, -0.0000336725, -0.0000220904,
+-0.0000104456, 0.0000012563, 0.0000130097, 0.0000248089, 0.0000366481,
+0.0000485216, 0.0000604235, 0.0000723481, 0.0000842894, 0.0000962415,
+0.0001081984, 0.0001201541, 0.0001321027, 0.0001440381, 0.0001559542,
+0.0001678449, 0.0001797043, 0.0001915261, 0.0002033042, 0.0002150326,
+0.0002267052, 0.0002383157, 0.0002498582, 0.0002613264, 0.0002727144,
+0.0002840160, 0.0002952252, 0.0003063359, 0.0003173421, 0.0003282378,
+0.0003390171, 0.0003496739, 0.0003602026, 0.0003705970, 0.0003808515,
+0.0003909603, 0.0004009177, 0.0004107179, 0.0004203554, 0.0004298245,
+0.0004391199, 0.0004482360, 0.0004571676, 0.0004659092, 0.0004744556,
+0.0004828018, 0.0004909425, 0.0004988729, 0.0005065881, 0.0005140831,
+0.0005213533, 0.0005283939, 0.0005352006, 0.0005417688, 0.0005480941,
+0.0005541724, 0.0005599994, 0.0005655712, 0.0005708838, 0.0005759334,
+0.0005807164, 0.0005852291, 0.0005894681, 0.0005934301, 0.0005971119,
+0.0006005103, 0.0006036225, 0.0006064456, 0.0006089769, 0.0006112139,
+0.0006131542, 0.0006147954, 0.0006161355, 0.0006171725, 0.0006179045,
+0.0006183298, 0.0006184469, 0.0006182543, 0.0006177508, 0.0006169354,
+0.0006158069, 0.0006143647, 0.0006126081, 0.0006105366, 0.0006081498,
+0.0006054476, 0.0006024300, 0.0005990971, 0.0005954492, 0.0005914868,
+0.0005872105, 0.0005826210, 0.0005777193, 0.0005725066, 0.0005669840,
+0.0005611530, 0.0005550152, 0.0005485724, 0.0005418263, 0.0005347792,
+0.0005274332, 0.0005197908, 0.0005118544, 0.0005036269, 0.0004951109,
+0.0004863097, 0.0004772264, 0.0004678642, 0.0004582267, 0.0004483176,
+0.0004381406, 0.0004276998, 0.0004169991, 0.0004060428, 0.0003948354,
+0.0003833814, 0.0003716854, 0.0003597523, 0.0003475871, 0.0003351948,
+0.0003225808, 0.0003097503, 0.0002967089, 0.0002834622, 0.0002700161,
+0.0002563763, 0.0002425489, 0.0002285401, 0.0002143560, 0.0002000031,
+0.0001854879, 0.0001708168, 0.0001559967, 0.0001410343, 0.0001259365,
+0.0001107104, 0.0000953630, 0.0000799015, 0.0000643331, 0.0000486653,
+0.0000329055, 0.0000170612, 0.0000011400, -0.0000148505, -0.0000309025,
+-0.0000470081, -0.0000631597, -0.0000793491, -0.0000955685, -0.0001118099,
+-0.0001280652, -0.0001443262, -0.0001605849, -0.0001768330, -0.0001930624,
+-0.0002092648, -0.0002254319, -0.0002415556, -0.0002576275, -0.0002736393,
+-0.0002895827, -0.0003054494, -0.0003212311, -0.0003369196, -0.0003525065,
+-0.0003679835, -0.0003833426, -0.0003985753, -0.0004136736, -0.0004286292,
+-0.0004434340, -0.0004580801, -0.0004725592, -0.0004868635, -0.0005009850,
+-0.0005149159, -0.0005286483, -0.0005421744, -0.0005554866, -0.0005685774,
+-0.0005814391, -0.0005940644, -0.0006064459, -0.0006185763, -0.0006304484,
+-0.0006420553, -0.0006533899, -0.0006644455, -0.0006752151, -0.0006856923,
+-0.0006958705, -0.0007057433, -0.0007153045, -0.0007245480, -0.0007334676,
+-0.0007420577, -0.0007503124, -0.0007582263, -0.0007657937, -0.0007730096,
+-0.0007798688, -0.0007863663, -0.0007924973, -0.0007982572, -0.0008036415,
+-0.0008086459, -0.0008132662, -0.0008174987, -0.0008213393, -0.0008247847,
+-0.0008278313, -0.0008304759, -0.0008327155, -0.0008345473, -0.0008359687,
+-0.0008369770, -0.0008375702, -0.0008377461, -0.0008375030, -0.0008368390,
+-0.0008357529, -0.0008342432, -0.0008323091, -0.0008299497, -0.0008271644,
+-0.0008239527, -0.0008203145, -0.0008162498, -0.0008117589, -0.0008068421,
+-0.0008015002, -0.0007957340, -0.0007895447, -0.0007829336, -0.0007759022,
+-0.0007684523, -0.0007605858, -0.0007523049, -0.0007436121, -0.0007345100,
+-0.0007250014, -0.0007150893, -0.0007047771, -0.0006940683, -0.0006829665,
+-0.0006714757, -0.0006596000, -0.0006473437, -0.0006347115, -0.0006217080,
+-0.0006083382, -0.0005946073, -0.0005805207, -0.0005660839, -0.0005513028,
+-0.0005361833, -0.0005207315, -0.0005049539, -0.0004888569, -0.0004724474,
+-0.0004557322, -0.0004387185, -0.0004214136, -0.0004038248, -0.0003859599,
+-0.0003678267, -0.0003494331, -0.0003307873, -0.0003118976, -0.0002927724,
+-0.0002734204, -0.0002538504, -0.0002340711, -0.0002140918, -0.0001939216,
+-0.0001735697, -0.0001530458, -0.0001323593, -0.0001115200, -0.0000905376,
+-0.0000694222, -0.0000481837, -0.0000268323, -0.0000053783, 0.0000161680,
+0.0000377962, 0.0000594957, 0.0000812561, 0.0001030665, 0.0001249163,
+0.0001467946, 0.0001686906, 0.0001905934, 0.0002124920, 0.0002343754,
+0.0002562326, 0.0002780524, 0.0002998238, 0.0003215357, 0.0003431768,
+0.0003647361, 0.0003862023, 0.0004075644, 0.0004288111, 0.0004499314,
+0.0004709140, 0.0004917479, 0.0005124220, 0.0005329253, 0.0005532468,
+0.0005733755, 0.0005933005, 0.0006130110, 0.0006324962, 0.0006517454,
+0.0006707479, 0.0006894932, 0.0007079708, 0.0007261704, 0.0007440816,
+0.0007616942, 0.0007789982, 0.0007959837, 0.0008126407, 0.0008289596,
+0.0008449308, 0.0008605448, 0.0008757923, 0.0008906642, 0.0009051513,
+0.0009192450, 0.0009329365, 0.0009462171, 0.0009590787, 0.0009715130,
+0.0009835120, 0.0009950678, 0.0010061729, 0.0010168199, 0.0010270014,
+0.0010367105, 0.0010459403, 0.0010546843, 0.0010629361, 0.0010706894,
+0.0010779384, 0.0010846773, 0.0010909007, 0.0010966033, 0.0011017801,
+0.0011064263, 0.0011105375, 0.0011141094, 0.0011171379, 0.0011196193,
+0.0011215502, 0.0011229273, 0.0011237476, 0.0011240084, 0.0011237074,
+0.0011228423, 0.0011214113, 0.0011194127, 0.0011168454, 0.0011137081,
+0.0011100002, 0.0011057211, 0.0011008708, 0.0010954492, 0.0010894568,
+0.0010828942, 0.0010757624, 0.0010680626, 0.0010597965, 0.0010509657,
+0.0010415725, 0.0010316192, 0.0010211086, 0.0010100437, 0.0009984277,
+0.0009862642, 0.0009735571, 0.0009603105, 0.0009465290, 0.0009322172,
+0.0009173801, 0.0009020230, 0.0008861516, 0.0008697717, 0.0008528894,
+0.0008355112, 0.0008176438, 0.0007992941, 0.0007804694, 0.0007611772,
+0.0007414252, 0.0007212216, 0.0007005745, 0.0006794927, 0.0006579848,
+0.0006360599, 0.0006137274, 0.0005909967, 0.0005678777, 0.0005443804,
+0.0005205151, 0.0004962922, 0.0004717224, 0.0004468167, 0.0004215861,
+0.0003960420, 0.0003701960, 0.0003440598, 0.0003176453, 0.0002909647,
+0.0002640303, 0.0002368545, 0.0002094500, 0.0001818296, 0.0001540064,
+0.0001259933, 0.0000978039, 0.0000694513, 0.0000409493, 0.0000123115,
+-0.0000164483, -0.0000453161, -0.0000742779, -0.0001033196, -0.0001324268,
+-0.0001615854, -0.0001907807, -0.0002199984, -0.0002492239, -0.0002784426,
+-0.0003076398, -0.0003368006, -0.0003659105, -0.0003949545, -0.0004239178,
+-0.0004527857, -0.0004815431, -0.0005101753, -0.0005386673, -0.0005670044,
+-0.0005951717, -0.0006231543, -0.0006509376, -0.0006785067, -0.0007058470,
+-0.0007329438, -0.0007597826, -0.0007863489, -0.0008126283, -0.0008386063,
+-0.0008642689, -0.0008896018, -0.0009145911, -0.0009392227, -0.0009634830,
+-0.0009873583, -0.0010108350, -0.0010338998, -0.0010565395, -0.0010787410,
+-0.0011004914, -0.0011217780, -0.0011425883, -0.0011629099, -0.0011827307,
+-0.0012020388, -0.0012208223, -0.0012390699, -0.0012567701, -0.0012739120,
+-0.0012904848, -0.0013064777, -0.0013218805, -0.0013366832, -0.0013508758,
+-0.0013644489, -0.0013773932, -0.0013896996, -0.0014013595, -0.0014123644,
+-0.0014227062, -0.0014323770, -0.0014413695, -0.0014496762, -0.0014572904,
+-0.0014642055, -0.0014704152, -0.0014759136, -0.0014806951, -0.0014847545,
+-0.0014880868, -0.0014906875, -0.0014925524, -0.0014936777, -0.0014940597,
+-0.0014936955, -0.0014925821, -0.0014907172, -0.0014880988, -0.0014847251,
+-0.0014805949, -0.0014757072, -0.0014700615, -0.0014636576, -0.0014564957,
+-0.0014485764, -0.0014399006, -0.0014304698, -0.0014202856, -0.0014093503,
+-0.0013976662, -0.0013852363, -0.0013720639, -0.0013581526, -0.0013435065,
+-0.0013281301, -0.0013120281, -0.0012952058, -0.0012776687, -0.0012594229,
+-0.0012404746, -0.0012208306, -0.0012004980, -0.0011794844, -0.0011577974,
+-0.0011354454, -0.0011124369, -0.0010887809, -0.0010644867, -0.0010395640,
+-0.0010140227, -0.0009878733, -0.0009611264, -0.0009337931, -0.0009058849,
+-0.0008774134, -0.0008483907, -0.0008188291, -0.0007887415, -0.0007581408,
+-0.0007270403, -0.0006954536, -0.0006633947, -0.0006308778, -0.0005979174,
+-0.0005645283, -0.0005307256, -0.0004965245, -0.0004619406, -0.0004269898,
+-0.0003916882, -0.0003560521, -0.0003200980, -0.0002838427, -0.0002473033,
+-0.0002104968, -0.0001734408, -0.0001361528, -0.0000986506, -0.0000609521,
+-0.0000230756, 0.0000149607, 0.0000531385, 0.0000914390, 0.0001298435,
+0.0001683333, 0.0002068894, 0.0002454926, 0.0002841239, 0.0003227639,
+0.0003613934, 0.0003999929, 0.0004385430, 0.0004770241, 0.0005154167,
+0.0005537012, 0.0005918580, 0.0006298674, 0.0006677099, 0.0007053659,
+0.0007428156, 0.0007800396, 0.0008170183, 0.0008537322, 0.0008901619,
+0.0009262880, 0.0009620912, 0.0009975524, 0.0010326524, 0.0010673723,
+0.0011016931, 0.0011355960, 0.0011690626, 0.0012020743, 0.0012346128,
+0.0012666600, 0.0012981978, 0.0013292086, 0.0013596746, 0.0013895787,
+0.0014189035, 0.0014476321, 0.0014757478, 0.0015032342, 0.0015300751,
+0.0015562544, 0.0015817566, 0.0016065662, 0.0016306680, 0.0016540474,
+0.0016766897, 0.0016985808, 0.0017197068, 0.0017400541, 0.0017596096,
+0.0017783603, 0.0017962939, 0.0018133981, 0.0018296611, 0.0018450717,
+0.0018596186, 0.0018732914, 0.0018860799, 0.0018979741, 0.0019089647,
+0.0019190427, 0.0019281995, 0.0019364271, 0.0019437176, 0.0019500638,
+0.0019554590, 0.0019598967, 0.0019633710, 0.0019658766, 0.0019674083,
+0.0019679618, 0.0019675329, 0.0019661182, 0.0019637144, 0.0019603191,
+0.0019559301, 0.0019505458, 0.0019441651, 0.0019367874, 0.0019284124,
+0.0019190407, 0.0019086731, 0.0018973109, 0.0018849560, 0.0018716109,
+0.0018572784, 0.0018419618, 0.0018256652, 0.0018083930, 0.0017901499,
+0.0017709416, 0.0017507738, 0.0017296531, 0.0017075864, 0.0016845811,
+0.0016606451, 0.0016357870, 0.0016100155, 0.0015833403, 0.0015557711,
+0.0015273183, 0.0014979929, 0.0014678062, 0.0014367701, 0.0014048968,
+0.0013721991, 0.0013386903, 0.0013043841, 0.0012692947, 0.0012334365,
+0.0011968247, 0.0011594747, 0.0011214025, 0.0010826243, 0.0010431569,
+0.0010030174, 0.0009622235, 0.0009207930, 0.0008787443, 0.0008360961,
+0.0007928675, 0.0007490779, 0.0007047472, 0.0006598955, 0.0006145433,
+0.0005687114, 0.0005224210, 0.0004756935, 0.0004285507, 0.0003810145,
+0.0003331074, 0.0002848520, 0.0002362710, 0.0001873876, 0.0001382251,
+0.0000888071, 0.0000391574, -0.0000107000, -0.0000607409, -0.0001109410,
+-0.0001612757, -0.0002117203, -0.0002622499, -0.0003128396, -0.0003634642,
+-0.0004140985, -0.0004647171, -0.0005152948, -0.0005658059, -0.0006162249,
+-0.0006665263, -0.0007166843, -0.0007666733, -0.0008164676, -0.0008660416,
+-0.0009153695, -0.0009644258, -0.0010131848, -0.0010616211, -0.0011097090,
+-0.0011574233, -0.0012047386, -0.0012516297, -0.0012980715, -0.0013440391,
+-0.0013895077, -0.0014344526, -0.0014788493, -0.0015226735, -0.0015659012,
+-0.0016085084, -0.0016504714, -0.0016917669, -0.0017323716, -0.0017722626,
+-0.0018114173, -0.0018498132, -0.0018874283, -0.0019242408, -0.0019602293,
+-0.0019953726, -0.0020296500, -0.0020630411, -0.0020955259, -0.0021270845,
+-0.0021576979, -0.0021873471, -0.0022160136, -0.0022436795, -0.0022703270,
+-0.0022959392, -0.0023204992, -0.0023439908, -0.0023663983, -0.0023877064,
+-0.0024079004, -0.0024269658, -0.0024448891, -0.0024616569, -0.0024772565,
+-0.0024916758, -0.0025049031, -0.0025169273, -0.0025277381, -0.0025373253,
+-0.0025456797, -0.0025527924, -0.0025586554, -0.0025632609, -0.0025666021,
+-0.0025686724, -0.0025694663, -0.0025689784, -0.0025672043, -0.0025641401,
+-0.0025597826, -0.0025541290, -0.0025471774, -0.0025389266, -0.0025293756,
+-0.0025185247, -0.0025063742, -0.0024929256, -0.0024781806, -0.0024621419,
+-0.0024448128, -0.0024261971, -0.0024062993, -0.0023851246, -0.0023626791,
+-0.0023389690, -0.0023140018, -0.0022877851, -0.0022603275, -0.0022316382,
+-0.0022017270, -0.0021706043, -0.0021382811, -0.0021047694, -0.0020700814,
+-0.0020342302, -0.0019972294, -0.0019590932, -0.0019198367, -0.0018794753,
+-0.0018380252, -0.0017955030, -0.0017519262, -0.0017073126, -0.0016616808,
+-0.0016150498, -0.0015674393, -0.0015188696, -0.0014693614, -0.0014189360,
+-0.0013676154, -0.0013154219, -0.0012623785, -0.0012085085, -0.0011538359,
+-0.0010983851, -0.0010421811, -0.0009852491, -0.0009276151, -0.0008693052,
+-0.0008103463, -0.0007507654, -0.0006905900, -0.0006298483, -0.0005685683,
+-0.0005067789, -0.0004445092, -0.0003817885, -0.0003186466, -0.0002551136,
+-0.0001912198, -0.0001269959, -0.0000624728, 0.0000023182, 0.0000673457,
+0.0001325780, 0.0001979832, 0.0002635292, 0.0003291837, 0.0003949141,
+0.0004606880, 0.0005264724, 0.0005922346, 0.0006579415, 0.0007235600,
+0.0007890569, 0.0008543990, 0.0009195531, 0.0009844857, 0.0010491637,
+0.0011135537, 0.0011776223, 0.0012413365, 0.0013046629, 0.0013675684,
+0.0014300201, 0.0014919850, 0.0015534303, 0.0016143233, 0.0016746316,
+0.0017343229, 0.0017933649, 0.0018517259, 0.0019093741, 0.0019662779,
+0.0020224064, 0.0020777285, 0.0021322135, 0.0021858313, 0.0022385517,
+0.0022903452, 0.0023411825, 0.0023910345, 0.0024398728, 0.0024876693,
+0.0025343963, 0.0025800264, 0.0026245328, 0.0026678893, 0.0027100699,
+0.0027510492, 0.0027908024, 0.0028293051, 0.0028665336, 0.0029024645,
+0.0029370752, 0.0029703436, 0.0030022482, 0.0030327680, 0.0030618828,
+0.0030895730, 0.0031158194, 0.0031406037, 0.0031639083, 0.0031857162,
+0.0032060109, 0.0032247769, 0.0032419993, 0.0032576639, 0.0032717571,
+0.0032842663, 0.0032951796, 0.0033044855, 0.0033121739, 0.0033182348,
+0.0033226595, 0.0033254397, 0.0033265683, 0.0033260387, 0.0033238451,
+0.0033199827, 0.0033144474, 0.0033072359, 0.0032983458, 0.0032877756,
+0.0032755244, 0.0032615923, 0.0032459804, 0.0032286903, 0.0032097246,
+0.0031890869, 0.0031667815, 0.0031428134, 0.0031171889, 0.0030899146,
+0.0030609984, 0.0030304488, 0.0029982753, 0.0029644882, 0.0029290984,
+0.0028921181, 0.0028535600, 0.0028134378, 0.0027717659, 0.0027285596,
+0.0026838351, 0.0026376093, 0.0025899000, 0.0025407257, 0.0024901057,
+0.0024380603, 0.0023846105, 0.0023297778, 0.0022735848, 0.0022160549,
+0.0021572119, 0.0020970806, 0.0020356866, 0.0019730560, 0.0019092157,
+0.0018441934, 0.0017780175, 0.0017107168, 0.0016423212, 0.0015728608,
+0.0015023666, 0.0014308703, 0.0013584040, 0.0012850006, 0.0012106934,
+0.0011355164, 0.0010595042, 0.0009826917, 0.0009051145, 0.0008268089,
+0.0007478113, 0.0006681588, 0.0005878890, 0.0005070398, 0.0004256495,
+0.0003437572, 0.0002614018, 0.0001786230, 0.0000954606, 0.0000119550,
+-0.0000718533, -0.0001559234, -0.0002402143, -0.0003246844, -0.0004092923,
+-0.0004939960, -0.0005787535, -0.0006635226, -0.0007482608, -0.0008329258,
+-0.0009174749, -0.0010018654, -0.0010860544, -0.0011699992, -0.0012536568,
+-0.0013369845, -0.0014199393, -0.0015024785, -0.0015845592, -0.0016661388,
+-0.0017471747, -0.0018276244, -0.0019074456, -0.0019865962, -0.0020650342,
+-0.0021427177, -0.0022196054, -0.0022956558, -0.0023708281, -0.0024450815,
+-0.0025183756, -0.0025906704, -0.0026619261, -0.0027321035, -0.0028011637,
+-0.0028690681, -0.0029357788, -0.0030012581, -0.0030654689, -0.0031283747,
+-0.0031899394, -0.0032501275, -0.0033089041, -0.0033662347, -0.0034220855,
+-0.0034764236, -0.0035292163, -0.0035804318, -0.0036300389, -0.0036780073,
+-0.0037243070, -0.0037689092, -0.0038117856, -0.0038529085, -0.0038922514,
+-0.0039297883, -0.0039654940, -0.0039993444, -0.0040313159, -0.0040613860,
+-0.0040895329, -0.0041157359, -0.0041399751, -0.0041622314, -0.0041824868,
+-0.0042007241, -0.0042169271, -0.0042310807, -0.0042431705, -0.0042531833,
+-0.0042611069, -0.0042669299, -0.0042706422, -0.0042722345, -0.0042716985,
+-0.0042690272, -0.0042642143, -0.0042572549, -0.0042481449, -0.0042368814,
+-0.0042234624, -0.0042078873, -0.0041901562, -0.0041702705, -0.0041482326,
+-0.0041240461, -0.0040977156, -0.0040692468, -0.0040386465, -0.0040059225,
+-0.0039710838, -0.0039341405, -0.0038951038, -0.0038539859, -0.0038108001,
+-0.0037655608, -0.0037182836, -0.0036689849, -0.0036176824, -0.0035643948,
+-0.0035091419, -0.0034519445, -0.0033928243, -0.0033318045, -0.0032689087,
+-0.0032041620, -0.0031375904, -0.0030692209, -0.0029990813, -0.0029272006,
+-0.0028536087, -0.0027783366, -0.0027014160, -0.0026228797, -0.0025427614,
+-0.0024610956, -0.0023779179, -0.0022932646, -0.0022071730, -0.0021196811,
+-0.0020308278, -0.0019406529, -0.0018491969, -0.0017565011, -0.0016626076,
+-0.0015675591, -0.0014713993, -0.0013741725, -0.0012759234, -0.0011766978,
+-0.0010765418, -0.0009755024, -0.0008736271, -0.0007709638, -0.0006675613,
+-0.0005634687, -0.0004587356, -0.0003534123, -0.0002475493, -0.0001411978,
+-0.0000344092, 0.0000727645, 0.0001802712, 0.0002880581, 0.0003960723,
+0.0005042607, 0.0006125697, 0.0007209455, 0.0008293342, 0.0009376817,
+0.0010459336, 0.0011540355, 0.0012619327, 0.0013695707, 0.0014768947,
+0.0015838501, 0.0016903819, 0.0017964356, 0.0019019563, 0.0020068897,
+0.0021111811, 0.0022147762, 0.0023176209, 0.0024196611, 0.0025208431,
+0.0026211132, 0.0027204184, 0.0028187055, 0.0029159221, 0.0030120157,
+0.0031069345, 0.0032006271, 0.0032930424, 0.0033841298, 0.0034738392,
+0.0035621211, 0.0036489264, 0.0037342067, 0.0038179142, 0.0039000017,
+0.0039804224, 0.0040591307, 0.0041360811, 0.0042112294, 0.0042845317,
+0.0043559452, 0.0044254276, 0.0044929376, 0.0045584348, 0.0046218796,
+0.0046832332, 0.0047424579, 0.0047995168, 0.0048543739, 0.0049069944,
+0.0049573443, 0.0050053908, 0.0050511019, 0.0050944469, 0.0051353961,
+0.0051739208, 0.0052099936, 0.0052435880, 0.0052746789, 0.0053032421,
+0.0053292549, 0.0053526956, 0.0053735437, 0.0053917800, 0.0054073864,
+0.0054203464, 0.0054306444, 0.0054382662, 0.0054431990, 0.0054454311,
+0.0054449524, 0.0054417538, 0.0054358277, 0.0054271679, 0.0054157694,
+0.0054016287, 0.0053847435, 0.0053651130, 0.0053427377, 0.0053176194,
+0.0052897616, 0.0052591688, 0.0052258471, 0.0051898039, 0.0051510480,
+0.0051095896, 0.0050654404, 0.0050186133, 0.0049691226, 0.0049169842,
+0.0048622151, 0.0048048338, 0.0047448602, 0.0046823156, 0.0046172225,
+0.0045496048, 0.0044794879, 0.0044068984, 0.0043318642, 0.0042544146,
+0.0041745801, 0.0040923927, 0.0040078855, 0.0039210929, 0.0038320506,
+0.0037407955, 0.0036473659, 0.0035518011, 0.0034541416, 0.0033544293,
+0.0032527070, 0.0031490190, 0.0030434103, 0.0029359274, 0.0028266176,
+0.0027155294, 0.0026027124, 0.0024882172, 0.0023720954, 0.0022543995,
+0.0021351832, 0.0020145008, 0.0018924077, 0.0017689604, 0.0016442159,
+0.0015182322, 0.0013910681, 0.0012627833, 0.0011334381, 0.0010030935,
+0.0008718115, 0.0007396544, 0.0006066854, 0.0004729683, 0.0003385673,
+0.0002035473, 0.0000679738, -0.0000680874, -0.0002045699, -0.0003414068,
+-0.0004785311, -0.0006158750, -0.0007533707, -0.0008909501, -0.0010285445,
+-0.0011660854, -0.0013035038, -0.0014407305, -0.0015776965, -0.0017143323,
+-0.0018505686, -0.0019863359, -0.0021215650, -0.0022561863, -0.0023901305,
+-0.0025233286, -0.0026557114, -0.0027872101, -0.0029177559, -0.0030472806,
+-0.0031757159, -0.0033029941, -0.0034290478, -0.0035538097, -0.0036772133,
+-0.0037991925, -0.0039196815, -0.0040386151, -0.0041559288, -0.0042715586,
+-0.0043854410, -0.0044975134, -0.0046077137, -0.0047159807, -0.0048222538,
+-0.0049264734, -0.0050285805, -0.0051285171, -0.0052262260, -0.0053216511,
+-0.0054147371, -0.0055054298, -0.0055936757, -0.0056794229, -0.0057626201,
+-0.0058432173, -0.0059211657, -0.0059964175, -0.0060689262, -0.0061386464,
+-0.0062055342, -0.0062695467, -0.0063306424, -0.0063887812, -0.0064439242,
+-0.0064960339, -0.0065450743, -0.0065910108, -0.0066338102, -0.0066734406,
+-0.0067098718, -0.0067430751, -0.0067730233, -0.0067996905, -0.0068230526,
+-0.0068430871, -0.0068597730, -0.0068730909, -0.0068830230, -0.0068895532,
+-0.0068926670, -0.0068923516, -0.0068885959, -0.0068813904, -0.0068707273,
+-0.0068566006, -0.0068390059, -0.0068179406, -0.0067934038, -0.0067653964,
+-0.0067339208, -0.0066989815, -0.0066605844, -0.0066187374, -0.0065734501,
+-0.0065247337, -0.0064726014, -0.0064170679, -0.0063581499, -0.0062958655,
+-0.0062302350, -0.0061612801, -0.0060890242, -0.0060134928, -0.0059347128,
+-0.0058527128, -0.0057675233, -0.0056791763, -0.0055877057, -0.0054931469,
+-0.0053955370, -0.0052949147, -0.0051913206, -0.0050847965, -0.0049753861,
+-0.0048631346, -0.0047480887, -0.0046302969, -0.0045098089, -0.0043866761,
+-0.0042609514, -0.0041326891, -0.0040019449, -0.0038687761, -0.0037332412,
+-0.0035954003, -0.0034553146, -0.0033130467, -0.0031686607, -0.0030222217,
+-0.0028737961, -0.0027234517, -0.0025712572, -0.0024172826, -0.0022615991,
+-0.0021042788, -0.0019453950, -0.0017850218, -0.0016232347, -0.0014601097,
+-0.0012957241, -0.0011301557, -0.0009634835, -0.0007957871, -0.0006271469,
+-0.0004576441, -0.0002873606, -0.0001163788, 0.0000552181, 0.0002273465,
+0.0003999219, 0.0005728599, 0.0007460750, 0.0009194817, 0.0010929941,
+0.0012665257, 0.0014399901, 0.0016133002, 0.0017863692, 0.0019591096,
+0.0021314343, 0.0023032557, 0.0024744865, 0.0026450392, 0.0028148263,
+0.0029837607, 0.0031517551, 0.0033187227, 0.0034845767, 0.0036492306,
+0.0038125983, 0.0039745941, 0.0041351326, 0.0042941290, 0.0044514987,
+0.0046071580, 0.0047610235, 0.0049130126, 0.0050630433, 0.0052110344,
+0.0053569054, 0.0055005764, 0.0056419687, 0.0057810043, 0.0059176061,
+0.0060516980, 0.0061832049, 0.0063120528, 0.0064381688, 0.0065614810,
+0.0066819189, 0.0067994129, 0.0069138948, 0.0070252979, 0.0071335564,
+0.0072386063, 0.0073403846, 0.0074388300, 0.0075338826, 0.0076254839,
+0.0077135771, 0.0077981068, 0.0078790195, 0.0079562629, 0.0080297867,
+0.0080995421, 0.0081654823, 0.0082275620, 0.0082857377, 0.0083399679,
+0.0083902126, 0.0084364341, 0.0084785963, 0.0085166650, 0.0085506081,
+0.0085803953, 0.0086059984, 0.0086273912, 0.0086445494, 0.0086574509,
+0.0086660755, 0.0086704051, 0.0086704239, 0.0086661178, 0.0086574753,
+0.0086444866, 0.0086271443, 0.0086054431, 0.0085793798, 0.0085489535,
+0.0085141652, 0.0084750184, 0.0084315187, 0.0083836737, 0.0083314935,
+0.0082749902, 0.0082141782, 0.0081490739, 0.0080796962, 0.0080060659,
+0.0079282063, 0.0078461426, 0.0077599023, 0.0076695152, 0.0075750131,
+0.0074764299, 0.0073738019, 0.0072671672, 0.0071565665, 0.0070420421,
+0.0069236387, 0.0068014030, 0.0066753838, 0.0065456319, 0.0064122001,
+0.0062751433, 0.0061345183, 0.0059903840, 0.0058428010, 0.0056918321,
+0.0055375418, 0.0053799965, 0.0052192645, 0.0050554159, 0.0048885224,
+0.0047186578, 0.0045458972, 0.0043703178, 0.0041919982, 0.0040110187,
+0.0038274611, 0.0036414089, 0.0034529470, 0.0032621617, 0.0030691410,
+0.0028739740, 0.0026767514, 0.0024775651, 0.0022765082, 0.0020736751,
+0.0018691616, 0.0016630642, 0.0014554808, 0.0012465104, 0.0010362529,
+0.0008248091, 0.0006122807, 0.0003987705, 0.0001843818, -0.0000307810,
+-0.0002466130, -0.0004630087, -0.0006798618, -0.0008970655, -0.0011145124,
+-0.0013320949, -0.0015497047, -0.0017672333, -0.0019845719, -0.0022016113,
+-0.0024182424, -0.0026343555, -0.0028498413, -0.0030645902, -0.0032784925,
+-0.0034914390, -0.0037033203, -0.0039140271, -0.0041234507, -0.0043314824,
+-0.0045380139, -0.0047429375, -0.0049461458, -0.0051475318, -0.0053469893,
+-0.0055444126, -0.0057396967, -0.0059327375, -0.0061234313, -0.0063116757,
+-0.0064973689, -0.0066804102, -0.0068606997, -0.0070381389, -0.0072126301,
+-0.0073840769, -0.0075523841, -0.0077174578, -0.0078792054, -0.0080375355,
+-0.0081923585, -0.0083435859, -0.0084911310, -0.0086349083, -0.0087748343,
+-0.0089108270, -0.0090428060, -0.0091706929, -0.0092944108, -0.0094138849,
+-0.0095290421, -0.0096398114, -0.0097461236, -0.0098479117, -0.0099451104,
+-0.0100376569, -0.0101254902, -0.0102085518, -0.0102867850, -0.0103601356,
+-0.0104285517, -0.0104919834, -0.0105503836, -0.0106037071, -0.0106519113,
+-0.0106949562, -0.0107328038, -0.0107654191, -0.0107927692, -0.0108148239,
+-0.0108315555, -0.0108429390, -0.0108489518, -0.0108495740, -0.0108447883,
+-0.0108345802, -0.0108189376, -0.0107978513, -0.0107713147, -0.0107393238,
+-0.0107018776, -0.0106589775, -0.0106106278, -0.0105568355, -0.0104976103,
+-0.0104329648, -0.0103629142, -0.0102874763, -0.0102066721, -0.0101205249,
+-0.0100290609, -0.0099323091, -0.0098303012, -0.0097230716, -0.0096106574,
+-0.0094930984, -0.0093704371, -0.0092427188, -0.0091099913, -0.0089723051,
+-0.0088297134, -0.0086822719, -0.0085300391, -0.0083730758, -0.0082114456,
+-0.0080452144, -0.0078744508, -0.0076992258, -0.0075196129, -0.0073356879,
+-0.0071475291, -0.0069552170, -0.0067588348, -0.0065584675, -0.0063542028,
+-0.0061461303, -0.0059343419, -0.0057189316, -0.0054999956, -0.0052776322,
+-0.0050519414, -0.0048230256, -0.0045909889, -0.0043559371, -0.0041179783,
+-0.0038772221, -0.0036337797, -0.0033877643, -0.0031392906, -0.0028884748,
+-0.0026354347, -0.0023802898, -0.0021231606, -0.0018641693, -0.0016034392,
+-0.0013410951, -0.0010772627, -0.0008120690, -0.0005456421, -0.0002781110,
+-0.0000096058, 0.0002597426, 0.0005298025, 0.0008004413, 0.0010715259,
+0.0013429225, 0.0016144965, 0.0018861131, 0.0021576369, 0.0024289322,
+0.0026998629, 0.0029702926, 0.0032400851, 0.0035091036, 0.0037772115,
+0.0040442724, 0.0043101496, 0.0045747069, 0.0048378082, 0.0050993177,
+0.0053591000, 0.0056170202, 0.0058729437, 0.0061267367, 0.0063782659,
+0.0066273989, 0.0068740040, 0.0071179501, 0.0073591075, 0.0075973470,
+0.0078325408, 0.0080645621, 0.0082932854, 0.0085185861, 0.0087403414,
+0.0089584296, 0.0091727305, 0.0093831254, 0.0095894973, 0.0097917307,
+0.0099897118, 0.0101833288, 0.0103724714, 0.0105570314, 0.0107369026,
+0.0109119807, 0.0110821634, 0.0112473506, 0.0114074445, 0.0115623494,
+0.0117119718, 0.0118562209, 0.0119950079, 0.0121282468, 0.0122558537,
+0.0123777476, 0.0124938499, 0.0126040849, 0.0127083792, 0.0128066625,
+0.0128988671, 0.0129849281, 0.0130647837, 0.0131383746, 0.0132056448,
+0.0132665411, 0.0133210134, 0.0133690146, 0.0134105007, 0.0134454309,
+0.0134737674, 0.0134954756, 0.0135105241, 0.0135188849, 0.0135205330,
+0.0135154468, 0.0135036081, 0.0134850017, 0.0134596160, 0.0134274427,
+0.0133884768, 0.0133427167, 0.0132901641, 0.0132308244, 0.0131647059,
+0.0130918209, 0.0130121845, 0.0129258157, 0.0128327367, 0.0127329732,
+0.0126265542, 0.0125135122, 0.0123938831, 0.0122677061, 0.0121350239,
+0.0119958827, 0.0118503317, 0.0116984238, 0.0115402150, 0.0113757647,
+0.0112051357, 0.0110283940, 0.0108456087, 0.0106568524, 0.0104622007,
+0.0102617324, 0.0100555296, 0.0098436773, 0.0096262638, 0.0094033802,
+0.0091751208, 0.0089415828, 0.0087028663, 0.0084590744, 0.0082103130,
+0.0079566907, 0.0076983191, 0.0074353122, 0.0071677869, 0.0068958626,
+0.0066196614, 0.0063393077, 0.0060549285, 0.0057666532, 0.0054746135,
+0.0051789434, 0.0048797791, 0.0045772590, 0.0042715235, 0.0039627152,
+0.0036509786, 0.0033364600, 0.0030193077, 0.0026996717, 0.0023777036,
+0.0020535569, 0.0017273863, 0.0013993484, 0.0010696008, 0.0007383027,
+0.0004056145, 0.0000716978, -0.0002632848, -0.0005991694, -0.0009357916,
+-0.0012729856, -0.0016105852, -0.0019484233, -0.0022863322, -0.0026241437,
+-0.0029616890, -0.0032987991, -0.0036353045, -0.0039710357, -0.0043058228,
+-0.0046394962, -0.0049718859, -0.0053028224, -0.0056321361, -0.0059596580,
+-0.0062852192, -0.0066086514, -0.0069297868, -0.0072484582, -0.0075644993,
+-0.0078777443, -0.0081880284, -0.0084951880, -0.0087990603, -0.0090994836,
+-0.0093962976, -0.0096893433, -0.0099784629, -0.0102635002, -0.0105443006,
+-0.0108207111, -0.0110925803, -0.0113597589, -0.0116220991, -0.0118794553,
+-0.0121316840, -0.0123786435, -0.0126201946, -0.0128562002, -0.0130865257,
+-0.0133110387, -0.0135296094, -0.0137421107, -0.0139484179, -0.0141484092,
+-0.0143419654, -0.0145289703, -0.0147093105, -0.0148828756, -0.0150495583,
+-0.0152092543, -0.0153618625, -0.0155072851, -0.0156454275, -0.0157761985,
+-0.0158995102, -0.0160152781, -0.0161234215, -0.0162238629, -0.0163165287,
+-0.0164013487, -0.0164782565, -0.0165471894, -0.0166080887, -0.0166608992,
+-0.0167055697, -0.0167420530, -0.0167703057, -0.0167902885, -0.0168019658,
+-0.0168053065, -0.0168002831, -0.0167868725, -0.0167650556, -0.0167348174,
+-0.0166961471, -0.0166490381, -0.0165934878, -0.0165294981, -0.0164570748,
+-0.0163762282, -0.0162869726, -0.0161893267, -0.0160833133, -0.0159689596,
+-0.0158462969, -0.0157153607, -0.0155761910, -0.0154288318, -0.0152733313,
+-0.0151097420, -0.0149381205, -0.0147585277, -0.0145710286, -0.0143756923,
+-0.0141725921, -0.0139618053, -0.0137434133, -0.0135175016, -0.0132841597,
+-0.0130434809, -0.0127955627, -0.0125405063, -0.0122784169, -0.0120094035,
+-0.0117335789, -0.0114510595, -0.0111619655, -0.0108664208, -0.0105645529,
+-0.0102564926, -0.0099423745, -0.0096223365, -0.0092965198, -0.0089650690,
+-0.0086281320, -0.0082858597, -0.0079384063, -0.0075859290, -0.0072285880,
+-0.0068665463, -0.0064999700, -0.0061290276, -0.0057538906, -0.0053747331,
+-0.0049917315, -0.0046050648, -0.0042149145, -0.0038214642, -0.0034248998,
+-0.0030254092, -0.0026231826, -0.0022184119, -0.0018112910, -0.0014020154,
+-0.0009907824, -0.0005777908, -0.0001632411, 0.0002526650, 0.0006697246,
+0.0010877333, 0.0015064860, 0.0019257762, 0.0023453967, 0.0027651394,
+0.0031847958, 0.0036041564, 0.0040230114, 0.0044411507, 0.0048583636,
+0.0052744396, 0.0056891678, 0.0061023376, 0.0065137383, 0.0069231595,
+0.0073303912, 0.0077352238, 0.0081374483, 0.0085368563, 0.0089332402,
+0.0093263932, 0.0097161095, 0.0101021845, 0.0104844146, 0.0108625976,
+0.0112365327, 0.0116060206, 0.0119708635, 0.0123308655, 0.0126858322,
+0.0130355714, 0.0133798928, 0.0137186083, 0.0140515319, 0.0143784798,
+0.0146992710, 0.0150137267, 0.0153216706, 0.0156229295, 0.0159173327,
+0.0162047124, 0.0164849039, 0.0167577456, 0.0170230788, 0.0172807484,
+0.0175306024, 0.0177724922, 0.0180062730, 0.0182318033, 0.0184489453,
+0.0186575650, 0.0188575324, 0.0190487212, 0.0192310091, 0.0194042780,
+0.0195684137, 0.0197233063, 0.0198688503, 0.0200049443, 0.0201314915,
+0.0202483994, 0.0203555801, 0.0204529502, 0.0205404311, 0.0206179485,
+0.0206854333, 0.0207428209, 0.0207900516, 0.0208270705, 0.0208538278,
+0.0208702784, 0.0208763824, 0.0208721048, 0.0208574158, 0.0208322904,
+0.0207967092, 0.0207506574, 0.0206941258, 0.0206271102, 0.0205496115,
+0.0204616360, 0.0203631952, 0.0202543057, 0.0201349897, 0.0200052742,
+0.0198651918, 0.0197147802, 0.0195540825, 0.0193831468, 0.0192020266,
+0.0190107807, 0.0188094731, 0.0185981728, 0.0183769543, 0.0181458969,
+0.0179050854, 0.0176546096, 0.0173945641, 0.0171250491, 0.0168461693,
+0.0165580347, 0.0162607600, 0.0159544652, 0.0156392747, 0.0153153180,
+0.0149827292, 0.0146416472, 0.0142922156, 0.0139345826, 0.0135689006,
+0.0131953271, 0.0128140234, 0.0124251554, 0.0120288935, 0.0116254119,
+0.0112148892, 0.0107975079, 0.0103734546, 0.0099429197, 0.0095060974,
+0.0090631859, 0.0086143866, 0.0081599047, 0.0076999490, 0.0072347313,
+0.0067644670, 0.0062893745, 0.0058096753, 0.0053255940, 0.0048373579,
+0.0043451972, 0.0038493447, 0.0033500357, 0.0028475082, 0.0023420022,
+0.0018337601, 0.0013230264, 0.0008100476, 0.0002950720, -0.0002216501,
+-0.0007398671, -0.0012593256, -0.0017797709, -0.0023009471, -0.0028225970,
+-0.0033444625, -0.0038662845, -0.0043878030, -0.0049087577, -0.0054288875,
+-0.0059479308, -0.0064656261, -0.0069817115, -0.0074959251, -0.0080080052,
+-0.0085176902, -0.0090247190, -0.0095288312, -0.0100297665, -0.0105272660,
+-0.0110210713, -0.0115109251, -0.0119965714, -0.0124777553, -0.0129542235,
+-0.0134257242, -0.0138920072, -0.0143528243, -0.0148079291, -0.0152570773,
+-0.0157000268, -0.0161365379, -0.0165663733, -0.0169892981, -0.0174050805,
+-0.0178134913, -0.0182143041, -0.0186072958, -0.0189922466, -0.0193689396,
+-0.0197371617, -0.0200967031, -0.0204473579, -0.0207889239, -0.0211212026,
+-0.0214439997, -0.0217571249, -0.0220603922, -0.0223536199, -0.0226366307,
+-0.0229092517, -0.0231713149, -0.0234226568, -0.0236631188, -0.0238925473,
+-0.0241107934, -0.0243177136, -0.0245131696, -0.0246970280, -0.0248691612,
+-0.0250294468, -0.0251777677, -0.0253140129, -0.0254380765, -0.0255498588,
+-0.0256492655, -0.0257362083, -0.0258106050, -0.0258723791, -0.0259214603,
+-0.0259577843, -0.0259812930, -0.0259919344, -0.0259896629, -0.0259744389,
+-0.0259462294, -0.0259050075, -0.0258507529, -0.0257834515, -0.0257030959,
+-0.0256096849, -0.0255032239, -0.0253837247, -0.0252512059, -0.0251056924,
+-0.0249472155, -0.0247758133, -0.0245915303, -0.0243944177, -0.0241845329,
+-0.0239619403, -0.0237267103, -0.0234789202, -0.0232186535, -0.0229460004,
+-0.0226610575, -0.0223639275, -0.0220547199, -0.0217335503, -0.0214005407,
+-0.0210558192, -0.0206995203, -0.0203317846, -0.0199527589, -0.0195625960,
+-0.0191614546, -0.0187494996, -0.0183269017, -0.0178938372, -0.0174504885,
+-0.0169970434, -0.0165336956, -0.0160606440, -0.0155780931, -0.0150862529,
+-0.0145853384, -0.0140755700, -0.0135571731, -0.0130303781, -0.0124954204,
+-0.0119525400, -0.0114019817, -0.0108439950, -0.0102788338, -0.0097067561,
+-0.0091280246, -0.0085429059, -0.0079516706, -0.0073545932, -0.0067519520,
+-0.0061440290, -0.0055311097, -0.0049134828, -0.0042914406, -0.0036652782,
+-0.0030352938, -0.0024017885, -0.0017650660, -0.0011254327, -0.0004831972,
+0.0001613293, 0.0008078339, 0.0014560012, 0.0021055145, 0.0027560551,
+0.0034073028, 0.0040589362, 0.0047106324, 0.0053620678, 0.0060129176,
+0.0066628564, 0.0073115581, 0.0079586963, 0.0086039444, 0.0092469753,
+0.0098874625, 0.0105250794, 0.0111594997, 0.0117903979, 0.0124174490,
+0.0130403290, 0.0136587149, 0.0142722848, 0.0148807183, 0.0154836965,
+0.0160809021, 0.0166720197, 0.0172567358, 0.0178347393, 0.0184057213,
+0.0189693753, 0.0195253977, 0.0200734874, 0.0206133465, 0.0211446801,
+0.0216671967, 0.0221806081, 0.0226846298, 0.0231789810, 0.0236633848,
+0.0241375683, 0.0246012629, 0.0250542041, 0.0254961322, 0.0259267919,
+0.0263459327, 0.0267533090, 0.0271486805, 0.0275318116, 0.0279024723,
+0.0282604381, 0.0286054900, 0.0289374145, 0.0292560042, 0.0295610575,
+0.0298523789, 0.0301297791, 0.0303930749, 0.0306420898, 0.0308766536,
+0.0310966027, 0.0313017804, 0.0314920367, 0.0316672284, 0.0318272194,
+0.0319718809, 0.0321010909, 0.0322147348, 0.0323127056, 0.0323949034,
+0.0324612358, 0.0325116182, 0.0325459735, 0.0325642322, 0.0325663326,
+0.0325522210, 0.0325218512, 0.0324751853, 0.0324121930, 0.0323328523,
+0.0322371490, 0.0321250770, 0.0319966384, 0.0318518433, 0.0316907100,
+0.0315132649, 0.0313195427, 0.0311095860, 0.0308834460, 0.0306411817,
+0.0303828605, 0.0301085578, 0.0298183574, 0.0295123510, 0.0291906387,
+0.0288533284, 0.0285005363, 0.0281323866, 0.0277490115, 0.0273505511,
+0.0269371536, 0.0265089750, 0.0260661791, 0.0256089375, 0.0251374295,
+0.0246518421, 0.0241523699, 0.0236392150, 0.0231125868, 0.0225727023,
+0.0220197857, 0.0214540682, 0.0208757885, 0.0202851918, 0.0196825308,
+0.0190680644, 0.0184420586, 0.0178047860, 0.0171565254, 0.0164975622,
+0.0158281880, 0.0151487004, 0.0144594032, 0.0137606059, 0.0130526237,
+0.0123357777, 0.0116103940, 0.0108768043, 0.0101353455, 0.0093863594,
+0.0086301925, 0.0078671964, 0.0070977270, 0.0063221446, 0.0055408137,
+0.0047541030, 0.0039623850, 0.0031660360, 0.0023654356, 0.0015609671,
+0.0007530169, -0.0000580258, -0.0008717687, -0.0016878170, -0.0025057733,
+-0.0033252381, -0.0041458096, -0.0049670844, -0.0057886571, -0.0066101210,
+-0.0074310679, -0.0082510887, -0.0090697732, -0.0098867106, -0.0107014895,
+-0.0115136982, -0.0123229249, -0.0131287579, -0.0139307858, -0.0147285976,
+-0.0155217831, -0.0163099329, -0.0170926389, -0.0178694941, -0.0186400931,
+-0.0194040323, -0.0201609098, -0.0209103260, -0.0216518837, -0.0223851881,
+-0.0231098472, -0.0238254719, -0.0245316762, -0.0252280776, -0.0259142971,
+-0.0265899594, -0.0272546930, -0.0279081308, -0.0285499099, -0.0291796719,
+-0.0297970631, -0.0304017349, -0.0309933435, -0.0315715507, -0.0321360235,
+-0.0326864346, -0.0332224626, -0.0337437921, -0.0342501139, -0.0347411250,
+-0.0352165291, -0.0356760366, -0.0361193646, -0.0365462373, -0.0369563861,
+-0.0373495498, -0.0377254745, -0.0380839142, -0.0384246304, -0.0387473928,
+-0.0390519790, -0.0393381748, -0.0396057745, -0.0398545807, -0.0400844047,
+-0.0402950665, -0.0404863949, -0.0406582277, -0.0408104118, -0.0409428031,
+-0.0410552669, -0.0411476780, -0.0412199204, -0.0412718878, -0.0413034835,
+-0.0413146206, -0.0413052219, -0.0412752200, -0.0412245577, -0.0411531875,
+-0.0410610721, -0.0409481843, -0.0408145071, -0.0406600336, -0.0404847672,
+-0.0402887216, -0.0400719206, -0.0398343986, -0.0395762002, -0.0392973804,
+-0.0389980046, -0.0386781484, -0.0383378980, -0.0379773497, -0.0375966105,
+-0.0371957974, -0.0367750379, -0.0363344698, -0.0358742410, -0.0353945098,
+-0.0348954445, -0.0343772237, -0.0338400360, -0.0332840800, -0.0327095642,
+-0.0321167073, -0.0315057374, -0.0308768926, -0.0302304205, -0.0295665785,
+-0.0288856333, -0.0281878610, -0.0274735469, -0.0267429858, -0.0259964811,
+-0.0252343455, -0.0244569004, -0.0236644758, -0.0228574104, -0.0220360513,
+-0.0212007538, -0.0203518815, -0.0194898058, -0.0186149061, -0.0177275694,
+-0.0168281903, -0.0159171706, -0.0149949194, -0.0140618528, -0.0131183937,
+-0.0121649716, -0.0112020226, -0.0102299890, -0.0092493190, -0.0082604669,
+-0.0072638927, -0.0062600617, -0.0052494445, -0.0042325168, -0.0032097591,
+-0.0021816566, -0.0011486988, -0.0001113794, 0.0009298040, 0.0019743499,
+0.0030217536, 0.0040715069, 0.0051230987, 0.0061760151, 0.0072297398,
+0.0082837539, 0.0093375368, 0.0103905658, 0.0114423169, 0.0124922647,
+0.0135398828, 0.0145846438, 0.0156260201, 0.0166634836, 0.0176965062,
+0.0187245601, 0.0197471179, 0.0207636531, 0.0217736400, 0.0227765544,
+0.0237718735, 0.0247590762, 0.0257376438, 0.0267070595, 0.0276668094,
+0.0286163823, 0.0295552701, 0.0304829681, 0.0313989751, 0.0323027939,
+0.0331939315, 0.0340718990, 0.0349362125, 0.0357863927, 0.0366219656,
+0.0374424626, 0.0382474207, 0.0390363829, 0.0398088980, 0.0405645217,
+0.0413028159, 0.0420233496, 0.0427256986, 0.0434094465, 0.0440741841,
+0.0447195100, 0.0453450309, 0.0459503619, 0.0465351261, 0.0470989558,
+0.0476414918, 0.0481623841, 0.0486612920, 0.0491378843, 0.0495918395,
+0.0500228460, 0.0504306021, 0.0508148166, 0.0511752086, 0.0515115078,
+0.0518234548, 0.0521108010, 0.0523733090, 0.0526107526, 0.0528229172,
+0.0530095996, 0.0531706083, 0.0533057638, 0.0534148984, 0.0534978568,
+0.0535544955, 0.0535846837, 0.0535883030, 0.0535652475, 0.0535154239,
+0.0534387518, 0.0533351636, 0.0532046046, 0.0530470330, 0.0528624204,
+0.0526507512, 0.0524120231, 0.0521462471, 0.0518534476, 0.0515336620,
+0.0511869413, 0.0508133500, 0.0504129657, 0.0499858797, 0.0495321967,
+0.0490520346, 0.0485455250, 0.0480128128, 0.0474540563, 0.0468694272,
+0.0462591107, 0.0456233049, 0.0449622216, 0.0442760856, 0.0435651348,
+0.0428296204, 0.0420698064, 0.0412859698, 0.0404784006, 0.0396474015,
+0.0387932877, 0.0379163872, 0.0370170403, 0.0360955999, 0.0351524307,
+0.0341879100, 0.0332024265, 0.0321963813, 0.0311701866, 0.0301242667,
+0.0290590567, 0.0279750034, 0.0268725642, 0.0257522075, 0.0246144125,
+0.0234596687, 0.0222884760, 0.0211013441, 0.0198987930, 0.0186813520,
+0.0174495601, 0.0162039652, 0.0149451245, 0.0136736037, 0.0123899774,
+0.0110948280, 0.0097887463, 0.0084723306, 0.0071461869, 0.0058109285,
+0.0044671755, 0.0031155547, 0.0017566996, 0.0003912497, -0.0009801497,
+-0.0023568476, -0.0037381876, -0.0051235086, -0.0065121445, -0.0079034250,
+-0.0092966754, -0.0106912177, -0.0120863699, -0.0134814472, -0.0148757617,
+-0.0162686232, -0.0176593392, -0.0190472153, -0.0204315554, -0.0218116625,
+-0.0231868384, -0.0245563845, -0.0259196020, -0.0272757920, -0.0286242563,
+-0.0299642972, -0.0312952185, -0.0326163250, -0.0339269237, -0.0352263234,
+-0.0365138356, -0.0377887747, -0.0390504580, -0.0402982064, -0.0415313447,
+-0.0427492019, -0.0439511115, -0.0451364118, -0.0463044463, -0.0474545642,
+-0.0485861203, -0.0496984759, -0.0507909987, -0.0518630632, -0.0529140513,
+-0.0539433522, -0.0549503631, -0.0559344894, -0.0568951448, -0.0578317521,
+-0.0587437430, -0.0596305587, -0.0604916501, -0.0613264784, -0.0621345148,
+-0.0629152414, -0.0636681511, -0.0643927482, -0.0650885482, -0.0657550788,
+-0.0663918795, -0.0669985022, -0.0675745116, -0.0681194850, -0.0686330131,
+-0.0691146997, -0.0695641626, -0.0699810331, -0.0703649569, -0.0707155940,
+-0.0710326189, -0.0713157209, -0.0715646043, -0.0717789887, -0.0719586091,
+-0.0721032160, -0.0722125759, -0.0722864709, -0.0723246997, -0.0723270771,
+-0.0722934344, -0.0722236195, -0.0721174972, -0.0719749490, -0.0717958738,
+-0.0715801873, -0.0713278227, -0.0710387307, -0.0707128793, -0.0703502542,
+-0.0699508588, -0.0695147141, -0.0690418592, -0.0685323510, -0.0679862642,
+-0.0674036916, -0.0667847442, -0.0661295508, -0.0654382585, -0.0647110323,
+-0.0639480554, -0.0631495291, -0.0623156729, -0.0614467242, -0.0605429384,
+-0.0596045891, -0.0586319676, -0.0576253834, -0.0565851636, -0.0555116532,
+-0.0544052146, -0.0532662283, -0.0520950917, -0.0508922201, -0.0496580458,
+-0.0483930182, -0.0470976040, -0.0457722864, -0.0444175657, -0.0430339585,
+-0.0416219979, -0.0401822332, -0.0387152298, -0.0372215690, -0.0357018476,
+-0.0341566780, -0.0325866877, -0.0309925194, -0.0293748304, -0.0277342927,
+-0.0260715924, -0.0243874299, -0.0226825192, -0.0209575878, -0.0192133766,
+-0.0174506393, -0.0156701424, -0.0138726645, -0.0120589966, -0.0102299412,
+-0.0083863124, -0.0065289352, -0.0046586456, -0.0027762899, -0.0008827244,
+0.0010211847, 0.0029345619, 0.0048565227, 0.0067861739, 0.0087226141,
+0.0106649339, 0.0126122165, 0.0145635380, 0.0165179676, 0.0184745685,
+0.0204323977, 0.0223905068, 0.0243479423, 0.0263037461, 0.0282569558,
+0.0302066051, 0.0321517244, 0.0340913411, 0.0360244802, 0.0379501644,
+0.0398674149, 0.0417752518, 0.0436726943, 0.0455587612, 0.0474324718,
+0.0492928457, 0.0511389038, 0.0529696683, 0.0547841636, 0.0565814165,
+0.0583604566, 0.0601203169, 0.0618600345, 0.0635786504, 0.0652752107,
+0.0669487665, 0.0685983747, 0.0702230985, 0.0718220074, 0.0733941783,
+0.0749386954, 0.0764546512, 0.0779411463, 0.0793972906, 0.0808222031,
+0.0822150126, 0.0835748586, 0.0849008908, 0.0861922705, 0.0874481703,
+0.0886677751, 0.0898502822, 0.0909949018, 0.0921008575, 0.0931673867,
+0.0941937410, 0.0951791867, 0.0961230049, 0.0970244924, 0.0978829617,
+0.0986977416, 0.0994681776, 0.1001936321, 0.1008734849, 0.1015071339,
+0.1020939947, 0.1026335017, 0.1031251081, 0.1035682863, 0.1039625284,
+0.1043073461, 0.1046022718, 0.1048468579, 0.1050406782, 0.1051833274,
+0.1052744216, 0.1053135989, 0.1053005193, 0.1052348653, 0.1051163417,
+0.1049446764, 0.1047196204, 0.1044409479, 0.1041084567, 0.1037219686,
+0.1032813291, 0.1027864082, 0.1022371001, 0.1016333237, 0.1009750227,
+0.1002621657, 0.0994947463, 0.0986727834, 0.0977963213, 0.0968654299,
+0.0958802044, 0.0948407661, 0.0937472617, 0.0925998642, 0.0913987723,
+0.0901442107, 0.0888364304, 0.0874757082, 0.0860623475, 0.0845966773,
+0.0830790532, 0.0815098568, 0.0798894959, 0.0782184043, 0.0764970420,
+0.0747258951, 0.0729054754, 0.0710363210, 0.0691189955, 0.0671540883,
+0.0651422145, 0.0630840147, 0.0609801548, 0.0588313260, 0.0566382445,
+0.0544016516, 0.0521223131, 0.0498010197, 0.0474385862, 0.0450358517,
+0.0425936791, 0.0401129553, 0.0375945904, 0.0350395180, 0.0324486944,
+0.0298230988, 0.0271637328, 0.0244716200, 0.0217478060, 0.0189933578,
+0.0162093637, 0.0133969326, 0.0105571942, 0.0076912982, 0.0048004142,
+0.0018857311, -0.0010515431, -0.0040101818, -0.0069889400, -0.0099865552,
+-0.0130017470, -0.0160332186, -0.0190796561, -0.0221397300, -0.0252120948,
+-0.0282953900, -0.0313882404, -0.0344892565, -0.0375970350, -0.0407101596,
+-0.0438272010, -0.0469467180, -0.0500672573, -0.0531873547, -0.0563055352,
+-0.0594203139, -0.0625301961, -0.0656336781, -0.0687292478, -0.0718153853,
+-0.0748905633, -0.0779532475, -0.0810018979, -0.0840349685, -0.0870509084,
+-0.0900481623, -0.0930251712, -0.0959803727, -0.0989122018, -0.1018190916,
+-0.1046994738, -0.1075517791, -0.1103744383, -0.1131658825, -0.1159245439,
+-0.1186488564, -0.1213372563, -0.1239881827, -0.1266000784, -0.1291713903,
+-0.1317005702, -0.1341860754, -0.1366263692, -0.1390199217, -0.1413652104,
+-0.1436607206, -0.1459049465, -0.1480963913, -0.1502335681, -0.1523150008,
+-0.1543392240, -0.1563047842, -0.1582102405, -0.1600541646, -0.1618351421,
+-0.1635517727, -0.1652026708, -0.1667864664, -0.1683018055, -0.1697473506,
+-0.1711217816, -0.1724237959, -0.1736521096, -0.1748054577, -0.1758825945,
+-0.1768822946, -0.1778033533, -0.1786445870, -0.1794048340, -0.1800829546,
+-0.1806778324, -0.1811883740, -0.1816135100, -0.1819521956, -0.1822034106,
+-0.1823661605, -0.1824394765, -0.1824224162, -0.1823140643, -0.1821135324,
+-0.1818199604, -0.1814325160, -0.1809503957, -0.1803728252, -0.1796990596,
+-0.1789283840, -0.1780601136, -0.1770935947, -0.1760282042, -0.1748633509,
+-0.1735984751, -0.1722330493, -0.1707665787, -0.1691986010, -0.1675286871,
+-0.1657564415, -0.1638815022, -0.1619035412, -0.1598222647, -0.1576374137,
+-0.1553487634, -0.1529561244, -0.1504593422, -0.1478582978, -0.1451529077,
+-0.1423431241, -0.1394289353, -0.1364103652, -0.1332874743, -0.1300603591,
+-0.1267291528, -0.1232940247, -0.1197551811, -0.1161128647, -0.1123673549,
+-0.1085189679, -0.1045680566, -0.1005150108, -0.0963602570, -0.0921042585,
+-0.0877475152, -0.0832905640, -0.0787339781, -0.0740783674, -0.0693243784,
+-0.0644726937, -0.0595240325, -0.0544791499, -0.0493388371, -0.0441039212,
+-0.0387752649, -0.0333537664, -0.0278403591, -0.0222360119, -0.0165417281,
+-0.0107585458, -0.0048875377, 0.0010701897, 0.0071134959, 0.0132412068,
+0.0194521151, 0.0257449807, 0.0321185306, 0.0385714598, 0.0451024313,
+0.0517100765, 0.0583929957, 0.0651497585, 0.0719789041, 0.0788789416,
+0.0858483508, 0.0928855823, 0.0999890582, 0.1071571724, 0.1143882911,
+0.1216807533, 0.1290328713, 0.1364429314, 0.1439091941, 0.1514298947,
+0.1590032442, 0.1666274291, 0.1743006130, 0.1820209363, 0.1897865170,
+0.1975954515, 0.2054458153, 0.2133356630, 0.2212630296, 0.2292259307,
+0.2372223633, 0.2452503065, 0.2533077219, 0.2613925546, 0.2695027336,
+0.2776361727, 0.2857907708, 0.2939644130, 0.3021549712, 0.3103603046,
+0.3185782607, 0.3268066755, 0.3350433750, 0.3432861752, 0.3515328833,
+0.3597812980, 0.3680292108, 0.3762744061, 0.3845146625, 0.3927477532,
+0.4009714470, 0.4091835086, 0.4173817001, 0.4255637810, 0.4337275094,
+0.4418706427, 0.4499909381, 0.4580861540, 0.4661540499, 0.4741923878,
+0.4821989328, 0.4901714538, 0.4981077244, 0.5060055234, 0.5138626359,
+0.5216768538, 0.5294459766, 0.5371678125, 0.5448401785, 0.5524609020,
+0.5600278206, 0.5675387836, 0.5749916526, 0.5823843019, 0.5897146196,
+0.5969805081, 0.6041798851, 0.6113106841, 0.6183708551, 0.6253583655,
+0.6322712007, 0.6391073649, 0.6458648816, 0.6525417945, 0.6591361680,
+0.6656460881, 0.6720696629, 0.6784050234, 0.6846503240, 0.6908037433,
+0.6968634846, 0.7028277766, 0.7086948742, 0.7144630588, 0.7201306391,
+0.7256959517, 0.7311573616, 0.7365132628, 0.7417620790, 0.7469022639,
+0.7519323022, 0.7568507094, 0.7616560333, 0.7663468534, 0.7709217826,
+0.7753794666, 0.7797185851, 0.7839378519, 0.7880360158, 0.7920118604,
+0.7958642049, 0.7995919047, 0.8031938516, 0.8066689739, 0.8100162374,
+0.8132346454, 0.8163232389, 0.8192810973, 0.8221073386, 0.8248011197,
+0.8273616366, 0.8297881248, 0.8320798597, 0.8342361565, 0.8362563709,
+0.8381398988, 0.8398861771, 0.8414946834, 0.8429649364, 0.8442964963,
+0.8454889644, 0.8465419838, 0.8474552392, 0.8482284572, 0.8488614061,
+0.8493538965, 0.8497057807, 0.8499169534, 0.8499873514, 0.8499169534,
+0.8497057807, 0.8493538965, 0.8488614061, 0.8482284572, 0.8474552392,
+0.8465419838, 0.8454889644, 0.8442964963, 0.8429649364, 0.8414946834,
+0.8398861771, 0.8381398988, 0.8362563709, 0.8342361565, 0.8320798597,
+0.8297881248, 0.8273616366, 0.8248011197, 0.8221073386, 0.8192810973,
+0.8163232389, 0.8132346454, 0.8100162374, 0.8066689739, 0.8031938516,
+0.7995919047, 0.7958642049, 0.7920118604, 0.7880360158, 0.7839378519,
+0.7797185851, 0.7753794666, 0.7709217826, 0.7663468534, 0.7616560333,
+0.7568507094, 0.7519323022, 0.7469022639, 0.7417620790, 0.7365132628,
+0.7311573616, 0.7256959517, 0.7201306391, 0.7144630588, 0.7086948742,
+0.7028277766, 0.6968634846, 0.6908037433, 0.6846503240, 0.6784050234,
+0.6720696629, 0.6656460881, 0.6591361680, 0.6525417945, 0.6458648816,
+0.6391073649, 0.6322712007, 0.6253583655, 0.6183708551, 0.6113106841,
+0.6041798851, 0.5969805081, 0.5897146196, 0.5823843019, 0.5749916526,
+0.5675387836, 0.5600278206, 0.5524609020, 0.5448401785, 0.5371678125,
+0.5294459766, 0.5216768538, 0.5138626359, 0.5060055234, 0.4981077244,
+0.4901714538, 0.4821989328, 0.4741923878, 0.4661540499, 0.4580861540,
+0.4499909381, 0.4418706427, 0.4337275094, 0.4255637810, 0.4173817001,
+0.4091835086, 0.4009714470, 0.3927477532, 0.3845146625, 0.3762744061,
+0.3680292108, 0.3597812980, 0.3515328833, 0.3432861752, 0.3350433750,
+0.3268066755, 0.3185782607, 0.3103603046, 0.3021549712, 0.2939644130,
+0.2857907708, 0.2776361727, 0.2695027336, 0.2613925546, 0.2533077219,
+0.2452503065, 0.2372223633, 0.2292259307, 0.2212630296, 0.2133356630,
+0.2054458153, 0.1975954515, 0.1897865170, 0.1820209363, 0.1743006130,
+0.1666274291, 0.1590032442, 0.1514298947, 0.1439091941, 0.1364429314,
+0.1290328713, 0.1216807533, 0.1143882911, 0.1071571724, 0.0999890582,
+0.0928855823, 0.0858483508, 0.0788789416, 0.0719789041, 0.0651497585,
+0.0583929957, 0.0517100765, 0.0451024313, 0.0385714598, 0.0321185306,
+0.0257449807, 0.0194521151, 0.0132412068, 0.0071134959, 0.0010701897,
+-0.0048875377, -0.0107585458, -0.0165417281, -0.0222360119, -0.0278403591,
+-0.0333537664, -0.0387752649, -0.0441039212, -0.0493388371, -0.0544791499,
+-0.0595240325, -0.0644726937, -0.0693243784, -0.0740783674, -0.0787339781,
+-0.0832905640, -0.0877475152, -0.0921042585, -0.0963602570, -0.1005150108,
+-0.1045680566, -0.1085189679, -0.1123673549, -0.1161128647, -0.1197551811,
+-0.1232940247, -0.1267291528, -0.1300603591, -0.1332874743, -0.1364103652,
+-0.1394289353, -0.1423431241, -0.1451529077, -0.1478582978, -0.1504593422,
+-0.1529561244, -0.1553487634, -0.1576374137, -0.1598222647, -0.1619035412,
+-0.1638815022, -0.1657564415, -0.1675286871, -0.1691986010, -0.1707665787,
+-0.1722330493, -0.1735984751, -0.1748633509, -0.1760282042, -0.1770935947,
+-0.1780601136, -0.1789283840, -0.1796990596, -0.1803728252, -0.1809503957,
+-0.1814325160, -0.1818199604, -0.1821135324, -0.1823140643, -0.1824224162,
+-0.1824394765, -0.1823661605, -0.1822034106, -0.1819521956, -0.1816135100,
+-0.1811883740, -0.1806778324, -0.1800829546, -0.1794048340, -0.1786445870,
+-0.1778033533, -0.1768822946, -0.1758825945, -0.1748054577, -0.1736521096,
+-0.1724237959, -0.1711217816, -0.1697473506, -0.1683018055, -0.1667864664,
+-0.1652026708, -0.1635517727, -0.1618351421, -0.1600541646, -0.1582102405,
+-0.1563047842, -0.1543392240, -0.1523150008, -0.1502335681, -0.1480963913,
+-0.1459049465, -0.1436607206, -0.1413652104, -0.1390199217, -0.1366263692,
+-0.1341860754, -0.1317005702, -0.1291713903, -0.1266000784, -0.1239881827,
+-0.1213372563, -0.1186488564, -0.1159245439, -0.1131658825, -0.1103744383,
+-0.1075517791, -0.1046994738, -0.1018190916, -0.0989122018, -0.0959803727,
+-0.0930251712, -0.0900481623, -0.0870509084, -0.0840349685, -0.0810018979,
+-0.0779532475, -0.0748905633, -0.0718153853, -0.0687292478, -0.0656336781,
+-0.0625301961, -0.0594203139, -0.0563055352, -0.0531873547, -0.0500672573,
+-0.0469467180, -0.0438272010, -0.0407101596, -0.0375970350, -0.0344892565,
+-0.0313882404, -0.0282953900, -0.0252120948, -0.0221397300, -0.0190796561,
+-0.0160332186, -0.0130017470, -0.0099865552, -0.0069889400, -0.0040101818,
+-0.0010515431, 0.0018857311, 0.0048004142, 0.0076912982, 0.0105571942,
+0.0133969326, 0.0162093637, 0.0189933578, 0.0217478060, 0.0244716200,
+0.0271637328, 0.0298230988, 0.0324486944, 0.0350395180, 0.0375945904,
+0.0401129553, 0.0425936791, 0.0450358517, 0.0474385862, 0.0498010197,
+0.0521223131, 0.0544016516, 0.0566382445, 0.0588313260, 0.0609801548,
+0.0630840147, 0.0651422145, 0.0671540883, 0.0691189955, 0.0710363210,
+0.0729054754, 0.0747258951, 0.0764970420, 0.0782184043, 0.0798894959,
+0.0815098568, 0.0830790532, 0.0845966773, 0.0860623475, 0.0874757082,
+0.0888364304, 0.0901442107, 0.0913987723, 0.0925998642, 0.0937472617,
+0.0948407661, 0.0958802044, 0.0968654299, 0.0977963213, 0.0986727834,
+0.0994947463, 0.1002621657, 0.1009750227, 0.1016333237, 0.1022371001,
+0.1027864082, 0.1032813291, 0.1037219686, 0.1041084567, 0.1044409479,
+0.1047196204, 0.1049446764, 0.1051163417, 0.1052348653, 0.1053005193,
+0.1053135989, 0.1052744216, 0.1051833274, 0.1050406782, 0.1048468579,
+0.1046022718, 0.1043073461, 0.1039625284, 0.1035682863, 0.1031251081,
+0.1026335017, 0.1020939947, 0.1015071339, 0.1008734849, 0.1001936321,
+0.0994681776, 0.0986977416, 0.0978829617, 0.0970244924, 0.0961230049,
+0.0951791867, 0.0941937410, 0.0931673867, 0.0921008575, 0.0909949018,
+0.0898502822, 0.0886677751, 0.0874481703, 0.0861922705, 0.0849008908,
+0.0835748586, 0.0822150126, 0.0808222031, 0.0793972906, 0.0779411463,
+0.0764546512, 0.0749386954, 0.0733941783, 0.0718220074, 0.0702230985,
+0.0685983747, 0.0669487665, 0.0652752107, 0.0635786504, 0.0618600345,
+0.0601203169, 0.0583604566, 0.0565814165, 0.0547841636, 0.0529696683,
+0.0511389038, 0.0492928457, 0.0474324718, 0.0455587612, 0.0436726943,
+0.0417752518, 0.0398674149, 0.0379501644, 0.0360244802, 0.0340913411,
+0.0321517244, 0.0302066051, 0.0282569558, 0.0263037461, 0.0243479423,
+0.0223905068, 0.0204323977, 0.0184745685, 0.0165179676, 0.0145635380,
+0.0126122165, 0.0106649339, 0.0087226141, 0.0067861739, 0.0048565227,
+0.0029345619, 0.0010211847, -0.0008827244, -0.0027762899, -0.0046586456,
+-0.0065289352, -0.0083863124, -0.0102299412, -0.0120589966, -0.0138726645,
+-0.0156701424, -0.0174506393, -0.0192133766, -0.0209575878, -0.0226825192,
+-0.0243874299, -0.0260715924, -0.0277342927, -0.0293748304, -0.0309925194,
+-0.0325866877, -0.0341566780, -0.0357018476, -0.0372215690, -0.0387152298,
+-0.0401822332, -0.0416219979, -0.0430339585, -0.0444175657, -0.0457722864,
+-0.0470976040, -0.0483930182, -0.0496580458, -0.0508922201, -0.0520950917,
+-0.0532662283, -0.0544052146, -0.0555116532, -0.0565851636, -0.0576253834,
+-0.0586319676, -0.0596045891, -0.0605429384, -0.0614467242, -0.0623156729,
+-0.0631495291, -0.0639480554, -0.0647110323, -0.0654382585, -0.0661295508,
+-0.0667847442, -0.0674036916, -0.0679862642, -0.0685323510, -0.0690418592,
+-0.0695147141, -0.0699508588, -0.0703502542, -0.0707128793, -0.0710387307,
+-0.0713278227, -0.0715801873, -0.0717958738, -0.0719749490, -0.0721174972,
+-0.0722236195, -0.0722934344, -0.0723270771, -0.0723246997, -0.0722864709,
+-0.0722125759, -0.0721032160, -0.0719586091, -0.0717789887, -0.0715646043,
+-0.0713157209, -0.0710326189, -0.0707155940, -0.0703649569, -0.0699810331,
+-0.0695641626, -0.0691146997, -0.0686330131, -0.0681194850, -0.0675745116,
+-0.0669985022, -0.0663918795, -0.0657550788, -0.0650885482, -0.0643927482,
+-0.0636681511, -0.0629152414, -0.0621345148, -0.0613264784, -0.0604916501,
+-0.0596305587, -0.0587437430, -0.0578317521, -0.0568951448, -0.0559344894,
+-0.0549503631, -0.0539433522, -0.0529140513, -0.0518630632, -0.0507909987,
+-0.0496984759, -0.0485861203, -0.0474545642, -0.0463044463, -0.0451364118,
+-0.0439511115, -0.0427492019, -0.0415313447, -0.0402982064, -0.0390504580,
+-0.0377887747, -0.0365138356, -0.0352263234, -0.0339269237, -0.0326163250,
+-0.0312952185, -0.0299642972, -0.0286242563, -0.0272757920, -0.0259196020,
+-0.0245563845, -0.0231868384, -0.0218116625, -0.0204315554, -0.0190472153,
+-0.0176593392, -0.0162686232, -0.0148757617, -0.0134814472, -0.0120863699,
+-0.0106912177, -0.0092966754, -0.0079034250, -0.0065121445, -0.0051235086,
+-0.0037381876, -0.0023568476, -0.0009801497, 0.0003912497, 0.0017566996,
+0.0031155547, 0.0044671755, 0.0058109285, 0.0071461869, 0.0084723306,
+0.0097887463, 0.0110948280, 0.0123899774, 0.0136736037, 0.0149451245,
+0.0162039652, 0.0174495601, 0.0186813520, 0.0198987930, 0.0211013441,
+0.0222884760, 0.0234596687, 0.0246144125, 0.0257522075, 0.0268725642,
+0.0279750034, 0.0290590567, 0.0301242667, 0.0311701866, 0.0321963813,
+0.0332024265, 0.0341879100, 0.0351524307, 0.0360955999, 0.0370170403,
+0.0379163872, 0.0387932877, 0.0396474015, 0.0404784006, 0.0412859698,
+0.0420698064, 0.0428296204, 0.0435651348, 0.0442760856, 0.0449622216,
+0.0456233049, 0.0462591107, 0.0468694272, 0.0474540563, 0.0480128128,
+0.0485455250, 0.0490520346, 0.0495321967, 0.0499858797, 0.0504129657,
+0.0508133500, 0.0511869413, 0.0515336620, 0.0518534476, 0.0521462471,
+0.0524120231, 0.0526507512, 0.0528624204, 0.0530470330, 0.0532046046,
+0.0533351636, 0.0534387518, 0.0535154239, 0.0535652475, 0.0535883030,
+0.0535846837, 0.0535544955, 0.0534978568, 0.0534148984, 0.0533057638,
+0.0531706083, 0.0530095996, 0.0528229172, 0.0526107526, 0.0523733090,
+0.0521108010, 0.0518234548, 0.0515115078, 0.0511752086, 0.0508148166,
+0.0504306021, 0.0500228460, 0.0495918395, 0.0491378843, 0.0486612920,
+0.0481623841, 0.0476414918, 0.0470989558, 0.0465351261, 0.0459503619,
+0.0453450309, 0.0447195100, 0.0440741841, 0.0434094465, 0.0427256986,
+0.0420233496, 0.0413028159, 0.0405645217, 0.0398088980, 0.0390363829,
+0.0382474207, 0.0374424626, 0.0366219656, 0.0357863927, 0.0349362125,
+0.0340718990, 0.0331939315, 0.0323027939, 0.0313989751, 0.0304829681,
+0.0295552701, 0.0286163823, 0.0276668094, 0.0267070595, 0.0257376438,
+0.0247590762, 0.0237718735, 0.0227765544, 0.0217736400, 0.0207636531,
+0.0197471179, 0.0187245601, 0.0176965062, 0.0166634836, 0.0156260201,
+0.0145846438, 0.0135398828, 0.0124922647, 0.0114423169, 0.0103905658,
+0.0093375368, 0.0082837539, 0.0072297398, 0.0061760151, 0.0051230987,
+0.0040715069, 0.0030217536, 0.0019743499, 0.0009298040, -0.0001113794,
+-0.0011486988, -0.0021816566, -0.0032097591, -0.0042325168, -0.0052494445,
+-0.0062600617, -0.0072638927, -0.0082604669, -0.0092493190, -0.0102299890,
+-0.0112020226, -0.0121649716, -0.0131183937, -0.0140618528, -0.0149949194,
+-0.0159171706, -0.0168281903, -0.0177275694, -0.0186149061, -0.0194898058,
+-0.0203518815, -0.0212007538, -0.0220360513, -0.0228574104, -0.0236644758,
+-0.0244569004, -0.0252343455, -0.0259964811, -0.0267429858, -0.0274735469,
+-0.0281878610, -0.0288856333, -0.0295665785, -0.0302304205, -0.0308768926,
+-0.0315057374, -0.0321167073, -0.0327095642, -0.0332840800, -0.0338400360,
+-0.0343772237, -0.0348954445, -0.0353945098, -0.0358742410, -0.0363344698,
+-0.0367750379, -0.0371957974, -0.0375966105, -0.0379773497, -0.0383378980,
+-0.0386781484, -0.0389980046, -0.0392973804, -0.0395762002, -0.0398343986,
+-0.0400719206, -0.0402887216, -0.0404847672, -0.0406600336, -0.0408145071,
+-0.0409481843, -0.0410610721, -0.0411531875, -0.0412245577, -0.0412752200,
+-0.0413052219, -0.0413146206, -0.0413034835, -0.0412718878, -0.0412199204,
+-0.0411476780, -0.0410552669, -0.0409428031, -0.0408104118, -0.0406582277,
+-0.0404863949, -0.0402950665, -0.0400844047, -0.0398545807, -0.0396057745,
+-0.0393381748, -0.0390519790, -0.0387473928, -0.0384246304, -0.0380839142,
+-0.0377254745, -0.0373495498, -0.0369563861, -0.0365462373, -0.0361193646,
+-0.0356760366, -0.0352165291, -0.0347411250, -0.0342501139, -0.0337437921,
+-0.0332224626, -0.0326864346, -0.0321360235, -0.0315715507, -0.0309933435,
+-0.0304017349, -0.0297970631, -0.0291796719, -0.0285499099, -0.0279081308,
+-0.0272546930, -0.0265899594, -0.0259142971, -0.0252280776, -0.0245316762,
+-0.0238254719, -0.0231098472, -0.0223851881, -0.0216518837, -0.0209103260,
+-0.0201609098, -0.0194040323, -0.0186400931, -0.0178694941, -0.0170926389,
+-0.0163099329, -0.0155217831, -0.0147285976, -0.0139307858, -0.0131287579,
+-0.0123229249, -0.0115136982, -0.0107014895, -0.0098867106, -0.0090697732,
+-0.0082510887, -0.0074310679, -0.0066101210, -0.0057886571, -0.0049670844,
+-0.0041458096, -0.0033252381, -0.0025057733, -0.0016878170, -0.0008717687,
+-0.0000580258, 0.0007530169, 0.0015609671, 0.0023654356, 0.0031660360,
+0.0039623850, 0.0047541030, 0.0055408137, 0.0063221446, 0.0070977270,
+0.0078671964, 0.0086301925, 0.0093863594, 0.0101353455, 0.0108768043,
+0.0116103940, 0.0123357777, 0.0130526237, 0.0137606059, 0.0144594032,
+0.0151487004, 0.0158281880, 0.0164975622, 0.0171565254, 0.0178047860,
+0.0184420586, 0.0190680644, 0.0196825308, 0.0202851918, 0.0208757885,
+0.0214540682, 0.0220197857, 0.0225727023, 0.0231125868, 0.0236392150,
+0.0241523699, 0.0246518421, 0.0251374295, 0.0256089375, 0.0260661791,
+0.0265089750, 0.0269371536, 0.0273505511, 0.0277490115, 0.0281323866,
+0.0285005363, 0.0288533284, 0.0291906387, 0.0295123510, 0.0298183574,
+0.0301085578, 0.0303828605, 0.0306411817, 0.0308834460, 0.0311095860,
+0.0313195427, 0.0315132649, 0.0316907100, 0.0318518433, 0.0319966384,
+0.0321250770, 0.0322371490, 0.0323328523, 0.0324121930, 0.0324751853,
+0.0325218512, 0.0325522210, 0.0325663326, 0.0325642322, 0.0325459735,
+0.0325116182, 0.0324612358, 0.0323949034, 0.0323127056, 0.0322147348,
+0.0321010909, 0.0319718809, 0.0318272194, 0.0316672284, 0.0314920367,
+0.0313017804, 0.0310966027, 0.0308766536, 0.0306420898, 0.0303930749,
+0.0301297791, 0.0298523789, 0.0295610575, 0.0292560042, 0.0289374145,
+0.0286054900, 0.0282604381, 0.0279024723, 0.0275318116, 0.0271486805,
+0.0267533090, 0.0263459327, 0.0259267919, 0.0254961322, 0.0250542041,
+0.0246012629, 0.0241375683, 0.0236633848, 0.0231789810, 0.0226846298,
+0.0221806081, 0.0216671967, 0.0211446801, 0.0206133465, 0.0200734874,
+0.0195253977, 0.0189693753, 0.0184057213, 0.0178347393, 0.0172567358,
+0.0166720197, 0.0160809021, 0.0154836965, 0.0148807183, 0.0142722848,
+0.0136587149, 0.0130403290, 0.0124174490, 0.0117903979, 0.0111594997,
+0.0105250794, 0.0098874625, 0.0092469753, 0.0086039444, 0.0079586963,
+0.0073115581, 0.0066628564, 0.0060129176, 0.0053620678, 0.0047106324,
+0.0040589362, 0.0034073028, 0.0027560551, 0.0021055145, 0.0014560012,
+0.0008078339, 0.0001613293, -0.0004831972, -0.0011254327, -0.0017650660,
+-0.0024017885, -0.0030352938, -0.0036652782, -0.0042914406, -0.0049134828,
+-0.0055311097, -0.0061440290, -0.0067519520, -0.0073545932, -0.0079516706,
+-0.0085429059, -0.0091280246, -0.0097067561, -0.0102788338, -0.0108439950,
+-0.0114019817, -0.0119525400, -0.0124954204, -0.0130303781, -0.0135571731,
+-0.0140755700, -0.0145853384, -0.0150862529, -0.0155780931, -0.0160606440,
+-0.0165336956, -0.0169970434, -0.0174504885, -0.0178938372, -0.0183269017,
+-0.0187494996, -0.0191614546, -0.0195625960, -0.0199527589, -0.0203317846,
+-0.0206995203, -0.0210558192, -0.0214005407, -0.0217335503, -0.0220547199,
+-0.0223639275, -0.0226610575, -0.0229460004, -0.0232186535, -0.0234789202,
+-0.0237267103, -0.0239619403, -0.0241845329, -0.0243944177, -0.0245915303,
+-0.0247758133, -0.0249472155, -0.0251056924, -0.0252512059, -0.0253837247,
+-0.0255032239, -0.0256096849, -0.0257030959, -0.0257834515, -0.0258507529,
+-0.0259050075, -0.0259462294, -0.0259744389, -0.0259896629, -0.0259919344,
+-0.0259812930, -0.0259577843, -0.0259214603, -0.0258723791, -0.0258106050,
+-0.0257362083, -0.0256492655, -0.0255498588, -0.0254380765, -0.0253140129,
+-0.0251777677, -0.0250294468, -0.0248691612, -0.0246970280, -0.0245131696,
+-0.0243177136, -0.0241107934, -0.0238925473, -0.0236631188, -0.0234226568,
+-0.0231713149, -0.0229092517, -0.0226366307, -0.0223536199, -0.0220603922,
+-0.0217571249, -0.0214439997, -0.0211212026, -0.0207889239, -0.0204473579,
+-0.0200967031, -0.0197371617, -0.0193689396, -0.0189922466, -0.0186072958,
+-0.0182143041, -0.0178134913, -0.0174050805, -0.0169892981, -0.0165663733,
+-0.0161365379, -0.0157000268, -0.0152570773, -0.0148079291, -0.0143528243,
+-0.0138920072, -0.0134257242, -0.0129542235, -0.0124777553, -0.0119965714,
+-0.0115109251, -0.0110210713, -0.0105272660, -0.0100297665, -0.0095288312,
+-0.0090247190, -0.0085176902, -0.0080080052, -0.0074959251, -0.0069817115,
+-0.0064656261, -0.0059479308, -0.0054288875, -0.0049087577, -0.0043878030,
+-0.0038662845, -0.0033444625, -0.0028225970, -0.0023009471, -0.0017797709,
+-0.0012593256, -0.0007398671, -0.0002216501, 0.0002950720, 0.0008100476,
+0.0013230264, 0.0018337601, 0.0023420022, 0.0028475082, 0.0033500357,
+0.0038493447, 0.0043451972, 0.0048373579, 0.0053255940, 0.0058096753,
+0.0062893745, 0.0067644670, 0.0072347313, 0.0076999490, 0.0081599047,
+0.0086143866, 0.0090631859, 0.0095060974, 0.0099429197, 0.0103734546,
+0.0107975079, 0.0112148892, 0.0116254119, 0.0120288935, 0.0124251554,
+0.0128140234, 0.0131953271, 0.0135689006, 0.0139345826, 0.0142922156,
+0.0146416472, 0.0149827292, 0.0153153180, 0.0156392747, 0.0159544652,
+0.0162607600, 0.0165580347, 0.0168461693, 0.0171250491, 0.0173945641,
+0.0176546096, 0.0179050854, 0.0181458969, 0.0183769543, 0.0185981728,
+0.0188094731, 0.0190107807, 0.0192020266, 0.0193831468, 0.0195540825,
+0.0197147802, 0.0198651918, 0.0200052742, 0.0201349897, 0.0202543057,
+0.0203631952, 0.0204616360, 0.0205496115, 0.0206271102, 0.0206941258,
+0.0207506574, 0.0207967092, 0.0208322904, 0.0208574158, 0.0208721048,
+0.0208763824, 0.0208702784, 0.0208538278, 0.0208270705, 0.0207900516,
+0.0207428209, 0.0206854333, 0.0206179485, 0.0205404311, 0.0204529502,
+0.0203555801, 0.0202483994, 0.0201314915, 0.0200049443, 0.0198688503,
+0.0197233063, 0.0195684137, 0.0194042780, 0.0192310091, 0.0190487212,
+0.0188575324, 0.0186575650, 0.0184489453, 0.0182318033, 0.0180062730,
+0.0177724922, 0.0175306024, 0.0172807484, 0.0170230788, 0.0167577456,
+0.0164849039, 0.0162047124, 0.0159173327, 0.0156229295, 0.0153216706,
+0.0150137267, 0.0146992710, 0.0143784798, 0.0140515319, 0.0137186083,
+0.0133798928, 0.0130355714, 0.0126858322, 0.0123308655, 0.0119708635,
+0.0116060206, 0.0112365327, 0.0108625976, 0.0104844146, 0.0101021845,
+0.0097161095, 0.0093263932, 0.0089332402, 0.0085368563, 0.0081374483,
+0.0077352238, 0.0073303912, 0.0069231595, 0.0065137383, 0.0061023376,
+0.0056891678, 0.0052744396, 0.0048583636, 0.0044411507, 0.0040230114,
+0.0036041564, 0.0031847958, 0.0027651394, 0.0023453967, 0.0019257762,
+0.0015064860, 0.0010877333, 0.0006697246, 0.0002526650, -0.0001632411,
+-0.0005777908, -0.0009907824, -0.0014020154, -0.0018112910, -0.0022184119,
+-0.0026231826, -0.0030254092, -0.0034248998, -0.0038214642, -0.0042149145,
+-0.0046050648, -0.0049917315, -0.0053747331, -0.0057538906, -0.0061290276,
+-0.0064999700, -0.0068665463, -0.0072285880, -0.0075859290, -0.0079384063,
+-0.0082858597, -0.0086281320, -0.0089650690, -0.0092965198, -0.0096223365,
+-0.0099423745, -0.0102564926, -0.0105645529, -0.0108664208, -0.0111619655,
+-0.0114510595, -0.0117335789, -0.0120094035, -0.0122784169, -0.0125405063,
+-0.0127955627, -0.0130434809, -0.0132841597, -0.0135175016, -0.0137434133,
+-0.0139618053, -0.0141725921, -0.0143756923, -0.0145710286, -0.0147585277,
+-0.0149381205, -0.0151097420, -0.0152733313, -0.0154288318, -0.0155761910,
+-0.0157153607, -0.0158462969, -0.0159689596, -0.0160833133, -0.0161893267,
+-0.0162869726, -0.0163762282, -0.0164570748, -0.0165294981, -0.0165934878,
+-0.0166490381, -0.0166961471, -0.0167348174, -0.0167650556, -0.0167868725,
+-0.0168002831, -0.0168053065, -0.0168019658, -0.0167902885, -0.0167703057,
+-0.0167420530, -0.0167055697, -0.0166608992, -0.0166080887, -0.0165471894,
+-0.0164782565, -0.0164013487, -0.0163165287, -0.0162238629, -0.0161234215,
+-0.0160152781, -0.0158995102, -0.0157761985, -0.0156454275, -0.0155072851,
+-0.0153618625, -0.0152092543, -0.0150495583, -0.0148828756, -0.0147093105,
+-0.0145289703, -0.0143419654, -0.0141484092, -0.0139484179, -0.0137421107,
+-0.0135296094, -0.0133110387, -0.0130865257, -0.0128562002, -0.0126201946,
+-0.0123786435, -0.0121316840, -0.0118794553, -0.0116220991, -0.0113597589,
+-0.0110925803, -0.0108207111, -0.0105443006, -0.0102635002, -0.0099784629,
+-0.0096893433, -0.0093962976, -0.0090994836, -0.0087990603, -0.0084951880,
+-0.0081880284, -0.0078777443, -0.0075644993, -0.0072484582, -0.0069297868,
+-0.0066086514, -0.0062852192, -0.0059596580, -0.0056321361, -0.0053028224,
+-0.0049718859, -0.0046394962, -0.0043058228, -0.0039710357, -0.0036353045,
+-0.0032987991, -0.0029616890, -0.0026241437, -0.0022863322, -0.0019484233,
+-0.0016105852, -0.0012729856, -0.0009357916, -0.0005991694, -0.0002632848,
+0.0000716978, 0.0004056145, 0.0007383027, 0.0010696008, 0.0013993484,
+0.0017273863, 0.0020535569, 0.0023777036, 0.0026996717, 0.0030193077,
+0.0033364600, 0.0036509786, 0.0039627152, 0.0042715235, 0.0045772590,
+0.0048797791, 0.0051789434, 0.0054746135, 0.0057666532, 0.0060549285,
+0.0063393077, 0.0066196614, 0.0068958626, 0.0071677869, 0.0074353122,
+0.0076983191, 0.0079566907, 0.0082103130, 0.0084590744, 0.0087028663,
+0.0089415828, 0.0091751208, 0.0094033802, 0.0096262638, 0.0098436773,
+0.0100555296, 0.0102617324, 0.0104622007, 0.0106568524, 0.0108456087,
+0.0110283940, 0.0112051357, 0.0113757647, 0.0115402150, 0.0116984238,
+0.0118503317, 0.0119958827, 0.0121350239, 0.0122677061, 0.0123938831,
+0.0125135122, 0.0126265542, 0.0127329732, 0.0128327367, 0.0129258157,
+0.0130121845, 0.0130918209, 0.0131647059, 0.0132308244, 0.0132901641,
+0.0133427167, 0.0133884768, 0.0134274427, 0.0134596160, 0.0134850017,
+0.0135036081, 0.0135154468, 0.0135205330, 0.0135188849, 0.0135105241,
+0.0134954756, 0.0134737674, 0.0134454309, 0.0134105007, 0.0133690146,
+0.0133210134, 0.0132665411, 0.0132056448, 0.0131383746, 0.0130647837,
+0.0129849281, 0.0128988671, 0.0128066625, 0.0127083792, 0.0126040849,
+0.0124938499, 0.0123777476, 0.0122558537, 0.0121282468, 0.0119950079,
+0.0118562209, 0.0117119718, 0.0115623494, 0.0114074445, 0.0112473506,
+0.0110821634, 0.0109119807, 0.0107369026, 0.0105570314, 0.0103724714,
+0.0101833288, 0.0099897118, 0.0097917307, 0.0095894973, 0.0093831254,
+0.0091727305, 0.0089584296, 0.0087403414, 0.0085185861, 0.0082932854,
+0.0080645621, 0.0078325408, 0.0075973470, 0.0073591075, 0.0071179501,
+0.0068740040, 0.0066273989, 0.0063782659, 0.0061267367, 0.0058729437,
+0.0056170202, 0.0053591000, 0.0050993177, 0.0048378082, 0.0045747069,
+0.0043101496, 0.0040442724, 0.0037772115, 0.0035091036, 0.0032400851,
+0.0029702926, 0.0026998629, 0.0024289322, 0.0021576369, 0.0018861131,
+0.0016144965, 0.0013429225, 0.0010715259, 0.0008004413, 0.0005298025,
+0.0002597426, -0.0000096058, -0.0002781110, -0.0005456421, -0.0008120690,
+-0.0010772627, -0.0013410951, -0.0016034392, -0.0018641693, -0.0021231606,
+-0.0023802898, -0.0026354347, -0.0028884748, -0.0031392906, -0.0033877643,
+-0.0036337797, -0.0038772221, -0.0041179783, -0.0043559371, -0.0045909889,
+-0.0048230256, -0.0050519414, -0.0052776322, -0.0054999956, -0.0057189316,
+-0.0059343419, -0.0061461303, -0.0063542028, -0.0065584675, -0.0067588348,
+-0.0069552170, -0.0071475291, -0.0073356879, -0.0075196129, -0.0076992258,
+-0.0078744508, -0.0080452144, -0.0082114456, -0.0083730758, -0.0085300391,
+-0.0086822719, -0.0088297134, -0.0089723051, -0.0091099913, -0.0092427188,
+-0.0093704371, -0.0094930984, -0.0096106574, -0.0097230716, -0.0098303012,
+-0.0099323091, -0.0100290609, -0.0101205249, -0.0102066721, -0.0102874763,
+-0.0103629142, -0.0104329648, -0.0104976103, -0.0105568355, -0.0106106278,
+-0.0106589775, -0.0107018776, -0.0107393238, -0.0107713147, -0.0107978513,
+-0.0108189376, -0.0108345802, -0.0108447883, -0.0108495740, -0.0108489518,
+-0.0108429390, -0.0108315555, -0.0108148239, -0.0107927692, -0.0107654191,
+-0.0107328038, -0.0106949562, -0.0106519113, -0.0106037071, -0.0105503836,
+-0.0104919834, -0.0104285517, -0.0103601356, -0.0102867850, -0.0102085518,
+-0.0101254902, -0.0100376569, -0.0099451104, -0.0098479117, -0.0097461236,
+-0.0096398114, -0.0095290421, -0.0094138849, -0.0092944108, -0.0091706929,
+-0.0090428060, -0.0089108270, -0.0087748343, -0.0086349083, -0.0084911310,
+-0.0083435859, -0.0081923585, -0.0080375355, -0.0078792054, -0.0077174578,
+-0.0075523841, -0.0073840769, -0.0072126301, -0.0070381389, -0.0068606997,
+-0.0066804102, -0.0064973689, -0.0063116757, -0.0061234313, -0.0059327375,
+-0.0057396967, -0.0055444126, -0.0053469893, -0.0051475318, -0.0049461458,
+-0.0047429375, -0.0045380139, -0.0043314824, -0.0041234507, -0.0039140271,
+-0.0037033203, -0.0034914390, -0.0032784925, -0.0030645902, -0.0028498413,
+-0.0026343555, -0.0024182424, -0.0022016113, -0.0019845719, -0.0017672333,
+-0.0015497047, -0.0013320949, -0.0011145124, -0.0008970655, -0.0006798618,
+-0.0004630087, -0.0002466130, -0.0000307810, 0.0001843818, 0.0003987705,
+0.0006122807, 0.0008248091, 0.0010362529, 0.0012465104, 0.0014554808,
+0.0016630642, 0.0018691616, 0.0020736751, 0.0022765082, 0.0024775651,
+0.0026767514, 0.0028739740, 0.0030691410, 0.0032621617, 0.0034529470,
+0.0036414089, 0.0038274611, 0.0040110187, 0.0041919982, 0.0043703178,
+0.0045458972, 0.0047186578, 0.0048885224, 0.0050554159, 0.0052192645,
+0.0053799965, 0.0055375418, 0.0056918321, 0.0058428010, 0.0059903840,
+0.0061345183, 0.0062751433, 0.0064122001, 0.0065456319, 0.0066753838,
+0.0068014030, 0.0069236387, 0.0070420421, 0.0071565665, 0.0072671672,
+0.0073738019, 0.0074764299, 0.0075750131, 0.0076695152, 0.0077599023,
+0.0078461426, 0.0079282063, 0.0080060659, 0.0080796962, 0.0081490739,
+0.0082141782, 0.0082749902, 0.0083314935, 0.0083836737, 0.0084315187,
+0.0084750184, 0.0085141652, 0.0085489535, 0.0085793798, 0.0086054431,
+0.0086271443, 0.0086444866, 0.0086574753, 0.0086661178, 0.0086704239,
+0.0086704051, 0.0086660755, 0.0086574509, 0.0086445494, 0.0086273912,
+0.0086059984, 0.0085803953, 0.0085506081, 0.0085166650, 0.0084785963,
+0.0084364341, 0.0083902126, 0.0083399679, 0.0082857377, 0.0082275620,
+0.0081654823, 0.0080995421, 0.0080297867, 0.0079562629, 0.0078790195,
+0.0077981068, 0.0077135771, 0.0076254839, 0.0075338826, 0.0074388300,
+0.0073403846, 0.0072386063, 0.0071335564, 0.0070252979, 0.0069138948,
+0.0067994129, 0.0066819189, 0.0065614810, 0.0064381688, 0.0063120528,
+0.0061832049, 0.0060516980, 0.0059176061, 0.0057810043, 0.0056419687,
+0.0055005764, 0.0053569054, 0.0052110344, 0.0050630433, 0.0049130126,
+0.0047610235, 0.0046071580, 0.0044514987, 0.0042941290, 0.0041351326,
+0.0039745941, 0.0038125983, 0.0036492306, 0.0034845767, 0.0033187227,
+0.0031517551, 0.0029837607, 0.0028148263, 0.0026450392, 0.0024744865,
+0.0023032557, 0.0021314343, 0.0019591096, 0.0017863692, 0.0016133002,
+0.0014399901, 0.0012665257, 0.0010929941, 0.0009194817, 0.0007460750,
+0.0005728599, 0.0003999219, 0.0002273465, 0.0000552181, -0.0001163788,
+-0.0002873606, -0.0004576441, -0.0006271469, -0.0007957871, -0.0009634835,
+-0.0011301557, -0.0012957241, -0.0014601097, -0.0016232347, -0.0017850218,
+-0.0019453950, -0.0021042788, -0.0022615991, -0.0024172826, -0.0025712572,
+-0.0027234517, -0.0028737961, -0.0030222217, -0.0031686607, -0.0033130467,
+-0.0034553146, -0.0035954003, -0.0037332412, -0.0038687761, -0.0040019449,
+-0.0041326891, -0.0042609514, -0.0043866761, -0.0045098089, -0.0046302969,
+-0.0047480887, -0.0048631346, -0.0049753861, -0.0050847965, -0.0051913206,
+-0.0052949147, -0.0053955370, -0.0054931469, -0.0055877057, -0.0056791763,
+-0.0057675233, -0.0058527128, -0.0059347128, -0.0060134928, -0.0060890242,
+-0.0061612801, -0.0062302350, -0.0062958655, -0.0063581499, -0.0064170679,
+-0.0064726014, -0.0065247337, -0.0065734501, -0.0066187374, -0.0066605844,
+-0.0066989815, -0.0067339208, -0.0067653964, -0.0067934038, -0.0068179406,
+-0.0068390059, -0.0068566006, -0.0068707273, -0.0068813904, -0.0068885959,
+-0.0068923516, -0.0068926670, -0.0068895532, -0.0068830230, -0.0068730909,
+-0.0068597730, -0.0068430871, -0.0068230526, -0.0067996905, -0.0067730233,
+-0.0067430751, -0.0067098718, -0.0066734406, -0.0066338102, -0.0065910108,
+-0.0065450743, -0.0064960339, -0.0064439242, -0.0063887812, -0.0063306424,
+-0.0062695467, -0.0062055342, -0.0061386464, -0.0060689262, -0.0059964175,
+-0.0059211657, -0.0058432173, -0.0057626201, -0.0056794229, -0.0055936757,
+-0.0055054298, -0.0054147371, -0.0053216511, -0.0052262260, -0.0051285171,
+-0.0050285805, -0.0049264734, -0.0048222538, -0.0047159807, -0.0046077137,
+-0.0044975134, -0.0043854410, -0.0042715586, -0.0041559288, -0.0040386151,
+-0.0039196815, -0.0037991925, -0.0036772133, -0.0035538097, -0.0034290478,
+-0.0033029941, -0.0031757159, -0.0030472806, -0.0029177559, -0.0027872101,
+-0.0026557114, -0.0025233286, -0.0023901305, -0.0022561863, -0.0021215650,
+-0.0019863359, -0.0018505686, -0.0017143323, -0.0015776965, -0.0014407305,
+-0.0013035038, -0.0011660854, -0.0010285445, -0.0008909501, -0.0007533707,
+-0.0006158750, -0.0004785311, -0.0003414068, -0.0002045699, -0.0000680874,
+0.0000679738, 0.0002035473, 0.0003385673, 0.0004729683, 0.0006066854,
+0.0007396544, 0.0008718115, 0.0010030935, 0.0011334381, 0.0012627833,
+0.0013910681, 0.0015182322, 0.0016442159, 0.0017689604, 0.0018924077,
+0.0020145008, 0.0021351832, 0.0022543995, 0.0023720954, 0.0024882172,
+0.0026027124, 0.0027155294, 0.0028266176, 0.0029359274, 0.0030434103,
+0.0031490190, 0.0032527070, 0.0033544293, 0.0034541416, 0.0035518011,
+0.0036473659, 0.0037407955, 0.0038320506, 0.0039210929, 0.0040078855,
+0.0040923927, 0.0041745801, 0.0042544146, 0.0043318642, 0.0044068984,
+0.0044794879, 0.0045496048, 0.0046172225, 0.0046823156, 0.0047448602,
+0.0048048338, 0.0048622151, 0.0049169842, 0.0049691226, 0.0050186133,
+0.0050654404, 0.0051095896, 0.0051510480, 0.0051898039, 0.0052258471,
+0.0052591688, 0.0052897616, 0.0053176194, 0.0053427377, 0.0053651130,
+0.0053847435, 0.0054016287, 0.0054157694, 0.0054271679, 0.0054358277,
+0.0054417538, 0.0054449524, 0.0054454311, 0.0054431990, 0.0054382662,
+0.0054306444, 0.0054203464, 0.0054073864, 0.0053917800, 0.0053735437,
+0.0053526956, 0.0053292549, 0.0053032421, 0.0052746789, 0.0052435880,
+0.0052099936, 0.0051739208, 0.0051353961, 0.0050944469, 0.0050511019,
+0.0050053908, 0.0049573443, 0.0049069944, 0.0048543739, 0.0047995168,
+0.0047424579, 0.0046832332, 0.0046218796, 0.0045584348, 0.0044929376,
+0.0044254276, 0.0043559452, 0.0042845317, 0.0042112294, 0.0041360811,
+0.0040591307, 0.0039804224, 0.0039000017, 0.0038179142, 0.0037342067,
+0.0036489264, 0.0035621211, 0.0034738392, 0.0033841298, 0.0032930424,
+0.0032006271, 0.0031069345, 0.0030120157, 0.0029159221, 0.0028187055,
+0.0027204184, 0.0026211132, 0.0025208431, 0.0024196611, 0.0023176209,
+0.0022147762, 0.0021111811, 0.0020068897, 0.0019019563, 0.0017964356,
+0.0016903819, 0.0015838501, 0.0014768947, 0.0013695707, 0.0012619327,
+0.0011540355, 0.0010459336, 0.0009376817, 0.0008293342, 0.0007209455,
+0.0006125697, 0.0005042607, 0.0003960723, 0.0002880581, 0.0001802712,
+0.0000727645, -0.0000344092, -0.0001411978, -0.0002475493, -0.0003534123,
+-0.0004587356, -0.0005634687, -0.0006675613, -0.0007709638, -0.0008736271,
+-0.0009755024, -0.0010765418, -0.0011766978, -0.0012759234, -0.0013741725,
+-0.0014713993, -0.0015675591, -0.0016626076, -0.0017565011, -0.0018491969,
+-0.0019406529, -0.0020308278, -0.0021196811, -0.0022071730, -0.0022932646,
+-0.0023779179, -0.0024610956, -0.0025427614, -0.0026228797, -0.0027014160,
+-0.0027783366, -0.0028536087, -0.0029272006, -0.0029990813, -0.0030692209,
+-0.0031375904, -0.0032041620, -0.0032689087, -0.0033318045, -0.0033928243,
+-0.0034519445, -0.0035091419, -0.0035643948, -0.0036176824, -0.0036689849,
+-0.0037182836, -0.0037655608, -0.0038108001, -0.0038539859, -0.0038951038,
+-0.0039341405, -0.0039710838, -0.0040059225, -0.0040386465, -0.0040692468,
+-0.0040977156, -0.0041240461, -0.0041482326, -0.0041702705, -0.0041901562,
+-0.0042078873, -0.0042234624, -0.0042368814, -0.0042481449, -0.0042572549,
+-0.0042642143, -0.0042690272, -0.0042716985, -0.0042722345, -0.0042706422,
+-0.0042669299, -0.0042611069, -0.0042531833, -0.0042431705, -0.0042310807,
+-0.0042169271, -0.0042007241, -0.0041824868, -0.0041622314, -0.0041399751,
+-0.0041157359, -0.0040895329, -0.0040613860, -0.0040313159, -0.0039993444,
+-0.0039654940, -0.0039297883, -0.0038922514, -0.0038529085, -0.0038117856,
+-0.0037689092, -0.0037243070, -0.0036780073, -0.0036300389, -0.0035804318,
+-0.0035292163, -0.0034764236, -0.0034220855, -0.0033662347, -0.0033089041,
+-0.0032501275, -0.0031899394, -0.0031283747, -0.0030654689, -0.0030012581,
+-0.0029357788, -0.0028690681, -0.0028011637, -0.0027321035, -0.0026619261,
+-0.0025906704, -0.0025183756, -0.0024450815, -0.0023708281, -0.0022956558,
+-0.0022196054, -0.0021427177, -0.0020650342, -0.0019865962, -0.0019074456,
+-0.0018276244, -0.0017471747, -0.0016661388, -0.0015845592, -0.0015024785,
+-0.0014199393, -0.0013369845, -0.0012536568, -0.0011699992, -0.0010860544,
+-0.0010018654, -0.0009174749, -0.0008329258, -0.0007482608, -0.0006635226,
+-0.0005787535, -0.0004939960, -0.0004092923, -0.0003246844, -0.0002402143,
+-0.0001559234, -0.0000718533, 0.0000119550, 0.0000954606, 0.0001786230,
+0.0002614018, 0.0003437572, 0.0004256495, 0.0005070398, 0.0005878890,
+0.0006681588, 0.0007478113, 0.0008268089, 0.0009051145, 0.0009826917,
+0.0010595042, 0.0011355164, 0.0012106934, 0.0012850006, 0.0013584040,
+0.0014308703, 0.0015023666, 0.0015728608, 0.0016423212, 0.0017107168,
+0.0017780175, 0.0018441934, 0.0019092157, 0.0019730560, 0.0020356866,
+0.0020970806, 0.0021572119, 0.0022160549, 0.0022735848, 0.0023297778,
+0.0023846105, 0.0024380603, 0.0024901057, 0.0025407257, 0.0025899000,
+0.0026376093, 0.0026838351, 0.0027285596, 0.0027717659, 0.0028134378,
+0.0028535600, 0.0028921181, 0.0029290984, 0.0029644882, 0.0029982753,
+0.0030304488, 0.0030609984, 0.0030899146, 0.0031171889, 0.0031428134,
+0.0031667815, 0.0031890869, 0.0032097246, 0.0032286903, 0.0032459804,
+0.0032615923, 0.0032755244, 0.0032877756, 0.0032983458, 0.0033072359,
+0.0033144474, 0.0033199827, 0.0033238451, 0.0033260387, 0.0033265683,
+0.0033254397, 0.0033226595, 0.0033182348, 0.0033121739, 0.0033044855,
+0.0032951796, 0.0032842663, 0.0032717571, 0.0032576639, 0.0032419993,
+0.0032247769, 0.0032060109, 0.0031857162, 0.0031639083, 0.0031406037,
+0.0031158194, 0.0030895730, 0.0030618828, 0.0030327680, 0.0030022482,
+0.0029703436, 0.0029370752, 0.0029024645, 0.0028665336, 0.0028293051,
+0.0027908024, 0.0027510492, 0.0027100699, 0.0026678893, 0.0026245328,
+0.0025800264, 0.0025343963, 0.0024876693, 0.0024398728, 0.0023910345,
+0.0023411825, 0.0022903452, 0.0022385517, 0.0021858313, 0.0021322135,
+0.0020777285, 0.0020224064, 0.0019662779, 0.0019093741, 0.0018517259,
+0.0017933649, 0.0017343229, 0.0016746316, 0.0016143233, 0.0015534303,
+0.0014919850, 0.0014300201, 0.0013675684, 0.0013046629, 0.0012413365,
+0.0011776223, 0.0011135537, 0.0010491637, 0.0009844857, 0.0009195531,
+0.0008543990, 0.0007890569, 0.0007235600, 0.0006579415, 0.0005922346,
+0.0005264724, 0.0004606880, 0.0003949141, 0.0003291837, 0.0002635292,
+0.0001979832, 0.0001325780, 0.0000673457, 0.0000023182, -0.0000624728,
+-0.0001269959, -0.0001912198, -0.0002551136, -0.0003186466, -0.0003817885,
+-0.0004445092, -0.0005067789, -0.0005685683, -0.0006298483, -0.0006905900,
+-0.0007507654, -0.0008103463, -0.0008693052, -0.0009276151, -0.0009852491,
+-0.0010421811, -0.0010983851, -0.0011538359, -0.0012085085, -0.0012623785,
+-0.0013154219, -0.0013676154, -0.0014189360, -0.0014693614, -0.0015188696,
+-0.0015674393, -0.0016150498, -0.0016616808, -0.0017073126, -0.0017519262,
+-0.0017955030, -0.0018380252, -0.0018794753, -0.0019198367, -0.0019590932,
+-0.0019972294, -0.0020342302, -0.0020700814, -0.0021047694, -0.0021382811,
+-0.0021706043, -0.0022017270, -0.0022316382, -0.0022603275, -0.0022877851,
+-0.0023140018, -0.0023389690, -0.0023626791, -0.0023851246, -0.0024062993,
+-0.0024261971, -0.0024448128, -0.0024621419, -0.0024781806, -0.0024929256,
+-0.0025063742, -0.0025185247, -0.0025293756, -0.0025389266, -0.0025471774,
+-0.0025541290, -0.0025597826, -0.0025641401, -0.0025672043, -0.0025689784,
+-0.0025694663, -0.0025686724, -0.0025666021, -0.0025632609, -0.0025586554,
+-0.0025527924, -0.0025456797, -0.0025373253, -0.0025277381, -0.0025169273,
+-0.0025049031, -0.0024916758, -0.0024772565, -0.0024616569, -0.0024448891,
+-0.0024269658, -0.0024079004, -0.0023877064, -0.0023663983, -0.0023439908,
+-0.0023204992, -0.0022959392, -0.0022703270, -0.0022436795, -0.0022160136,
+-0.0021873471, -0.0021576979, -0.0021270845, -0.0020955259, -0.0020630411,
+-0.0020296500, -0.0019953726, -0.0019602293, -0.0019242408, -0.0018874283,
+-0.0018498132, -0.0018114173, -0.0017722626, -0.0017323716, -0.0016917669,
+-0.0016504714, -0.0016085084, -0.0015659012, -0.0015226735, -0.0014788493,
+-0.0014344526, -0.0013895077, -0.0013440391, -0.0012980715, -0.0012516297,
+-0.0012047386, -0.0011574233, -0.0011097090, -0.0010616211, -0.0010131848,
+-0.0009644258, -0.0009153695, -0.0008660416, -0.0008164676, -0.0007666733,
+-0.0007166843, -0.0006665263, -0.0006162249, -0.0005658059, -0.0005152948,
+-0.0004647171, -0.0004140985, -0.0003634642, -0.0003128396, -0.0002622499,
+-0.0002117203, -0.0001612757, -0.0001109410, -0.0000607409, -0.0000107000,
+0.0000391574, 0.0000888071, 0.0001382251, 0.0001873876, 0.0002362710,
+0.0002848520, 0.0003331074, 0.0003810145, 0.0004285507, 0.0004756935,
+0.0005224210, 0.0005687114, 0.0006145433, 0.0006598955, 0.0007047472,
+0.0007490779, 0.0007928675, 0.0008360961, 0.0008787443, 0.0009207930,
+0.0009622235, 0.0010030174, 0.0010431569, 0.0010826243, 0.0011214025,
+0.0011594747, 0.0011968247, 0.0012334365, 0.0012692947, 0.0013043841,
+0.0013386903, 0.0013721991, 0.0014048968, 0.0014367701, 0.0014678062,
+0.0014979929, 0.0015273183, 0.0015557711, 0.0015833403, 0.0016100155,
+0.0016357870, 0.0016606451, 0.0016845811, 0.0017075864, 0.0017296531,
+0.0017507738, 0.0017709416, 0.0017901499, 0.0018083930, 0.0018256652,
+0.0018419618, 0.0018572784, 0.0018716109, 0.0018849560, 0.0018973109,
+0.0019086731, 0.0019190407, 0.0019284124, 0.0019367874, 0.0019441651,
+0.0019505458, 0.0019559301, 0.0019603191, 0.0019637144, 0.0019661182,
+0.0019675329, 0.0019679618, 0.0019674083, 0.0019658766, 0.0019633710,
+0.0019598967, 0.0019554590, 0.0019500638, 0.0019437176, 0.0019364271,
+0.0019281995, 0.0019190427, 0.0019089647, 0.0018979741, 0.0018860799,
+0.0018732914, 0.0018596186, 0.0018450717, 0.0018296611, 0.0018133981,
+0.0017962939, 0.0017783603, 0.0017596096, 0.0017400541, 0.0017197068,
+0.0016985808, 0.0016766897, 0.0016540474, 0.0016306680, 0.0016065662,
+0.0015817566, 0.0015562544, 0.0015300751, 0.0015032342, 0.0014757478,
+0.0014476321, 0.0014189035, 0.0013895787, 0.0013596746, 0.0013292086,
+0.0012981978, 0.0012666600, 0.0012346128, 0.0012020743, 0.0011690626,
+0.0011355960, 0.0011016931, 0.0010673723, 0.0010326524, 0.0009975524,
+0.0009620912, 0.0009262880, 0.0008901619, 0.0008537322, 0.0008170183,
+0.0007800396, 0.0007428156, 0.0007053659, 0.0006677099, 0.0006298674,
+0.0005918580, 0.0005537012, 0.0005154167, 0.0004770241, 0.0004385430,
+0.0003999929, 0.0003613934, 0.0003227639, 0.0002841239, 0.0002454926,
+0.0002068894, 0.0001683333, 0.0001298435, 0.0000914390, 0.0000531385,
+0.0000149607, -0.0000230756, -0.0000609521, -0.0000986506, -0.0001361528,
+-0.0001734408, -0.0002104968, -0.0002473033, -0.0002838427, -0.0003200980,
+-0.0003560521, -0.0003916882, -0.0004269898, -0.0004619406, -0.0004965245,
+-0.0005307256, -0.0005645283, -0.0005979174, -0.0006308778, -0.0006633947,
+-0.0006954536, -0.0007270403, -0.0007581408, -0.0007887415, -0.0008188291,
+-0.0008483907, -0.0008774134, -0.0009058849, -0.0009337931, -0.0009611264,
+-0.0009878733, -0.0010140227, -0.0010395640, -0.0010644867, -0.0010887809,
+-0.0011124369, -0.0011354454, -0.0011577974, -0.0011794844, -0.0012004980,
+-0.0012208306, -0.0012404746, -0.0012594229, -0.0012776687, -0.0012952058,
+-0.0013120281, -0.0013281301, -0.0013435065, -0.0013581526, -0.0013720639,
+-0.0013852363, -0.0013976662, -0.0014093503, -0.0014202856, -0.0014304698,
+-0.0014399006, -0.0014485764, -0.0014564957, -0.0014636576, -0.0014700615,
+-0.0014757072, -0.0014805949, -0.0014847251, -0.0014880988, -0.0014907172,
+-0.0014925821, -0.0014936955, -0.0014940597, -0.0014936777, -0.0014925524,
+-0.0014906875, -0.0014880868, -0.0014847545, -0.0014806951, -0.0014759136,
+-0.0014704152, -0.0014642055, -0.0014572904, -0.0014496762, -0.0014413695,
+-0.0014323770, -0.0014227062, -0.0014123644, -0.0014013595, -0.0013896996,
+-0.0013773932, -0.0013644489, -0.0013508758, -0.0013366832, -0.0013218805,
+-0.0013064777, -0.0012904848, -0.0012739120, -0.0012567701, -0.0012390699,
+-0.0012208223, -0.0012020388, -0.0011827307, -0.0011629099, -0.0011425883,
+-0.0011217780, -0.0011004914, -0.0010787410, -0.0010565395, -0.0010338998,
+-0.0010108350, -0.0009873583, -0.0009634830, -0.0009392227, -0.0009145911,
+-0.0008896018, -0.0008642689, -0.0008386063, -0.0008126283, -0.0007863489,
+-0.0007597826, -0.0007329438, -0.0007058470, -0.0006785067, -0.0006509376,
+-0.0006231543, -0.0005951717, -0.0005670044, -0.0005386673, -0.0005101753,
+-0.0004815431, -0.0004527857, -0.0004239178, -0.0003949545, -0.0003659105,
+-0.0003368006, -0.0003076398, -0.0002784426, -0.0002492239, -0.0002199984,
+-0.0001907807, -0.0001615854, -0.0001324268, -0.0001033196, -0.0000742779,
+-0.0000453161, -0.0000164483, 0.0000123115, 0.0000409493, 0.0000694513,
+0.0000978039, 0.0001259933, 0.0001540064, 0.0001818296, 0.0002094500,
+0.0002368545, 0.0002640303, 0.0002909647, 0.0003176453, 0.0003440598,
+0.0003701960, 0.0003960420, 0.0004215861, 0.0004468167, 0.0004717224,
+0.0004962922, 0.0005205151, 0.0005443804, 0.0005678777, 0.0005909967,
+0.0006137274, 0.0006360599, 0.0006579848, 0.0006794927, 0.0007005745,
+0.0007212216, 0.0007414252, 0.0007611772, 0.0007804694, 0.0007992941,
+0.0008176438, 0.0008355112, 0.0008528894, 0.0008697717, 0.0008861516,
+0.0009020230, 0.0009173801, 0.0009322172, 0.0009465290, 0.0009603105,
+0.0009735571, 0.0009862642, 0.0009984277, 0.0010100437, 0.0010211086,
+0.0010316192, 0.0010415725, 0.0010509657, 0.0010597965, 0.0010680626,
+0.0010757624, 0.0010828942, 0.0010894568, 0.0010954492, 0.0011008708,
+0.0011057211, 0.0011100002, 0.0011137081, 0.0011168454, 0.0011194127,
+0.0011214113, 0.0011228423, 0.0011237074, 0.0011240084, 0.0011237476,
+0.0011229273, 0.0011215502, 0.0011196193, 0.0011171379, 0.0011141094,
+0.0011105375, 0.0011064263, 0.0011017801, 0.0010966033, 0.0010909007,
+0.0010846773, 0.0010779384, 0.0010706894, 0.0010629361, 0.0010546843,
+0.0010459403, 0.0010367105, 0.0010270014, 0.0010168199, 0.0010061729,
+0.0009950678, 0.0009835120, 0.0009715130, 0.0009590787, 0.0009462171,
+0.0009329365, 0.0009192450, 0.0009051513, 0.0008906642, 0.0008757923,
+0.0008605448, 0.0008449308, 0.0008289596, 0.0008126407, 0.0007959837,
+0.0007789982, 0.0007616942, 0.0007440816, 0.0007261704, 0.0007079708,
+0.0006894932, 0.0006707479, 0.0006517454, 0.0006324962, 0.0006130110,
+0.0005933005, 0.0005733755, 0.0005532468, 0.0005329253, 0.0005124220,
+0.0004917479, 0.0004709140, 0.0004499314, 0.0004288111, 0.0004075644,
+0.0003862023, 0.0003647361, 0.0003431768, 0.0003215357, 0.0002998238,
+0.0002780524, 0.0002562326, 0.0002343754, 0.0002124920, 0.0001905934,
+0.0001686906, 0.0001467946, 0.0001249163, 0.0001030665, 0.0000812561,
+0.0000594957, 0.0000377962, 0.0000161680, -0.0000053783, -0.0000268323,
+-0.0000481837, -0.0000694222, -0.0000905376, -0.0001115200, -0.0001323593,
+-0.0001530458, -0.0001735697, -0.0001939216, -0.0002140918, -0.0002340711,
+-0.0002538504, -0.0002734204, -0.0002927724, -0.0003118976, -0.0003307873,
+-0.0003494331, -0.0003678267, -0.0003859599, -0.0004038248, -0.0004214136,
+-0.0004387185, -0.0004557322, -0.0004724474, -0.0004888569, -0.0005049539,
+-0.0005207315, -0.0005361833, -0.0005513028, -0.0005660839, -0.0005805207,
+-0.0005946073, -0.0006083382, -0.0006217080, -0.0006347115, -0.0006473437,
+-0.0006596000, -0.0006714757, -0.0006829665, -0.0006940683, -0.0007047771,
+-0.0007150893, -0.0007250014, -0.0007345100, -0.0007436121, -0.0007523049,
+-0.0007605858, -0.0007684523, -0.0007759022, -0.0007829336, -0.0007895447,
+-0.0007957340, -0.0008015002, -0.0008068421, -0.0008117589, -0.0008162498,
+-0.0008203145, -0.0008239527, -0.0008271644, -0.0008299497, -0.0008323091,
+-0.0008342432, -0.0008357529, -0.0008368390, -0.0008375030, -0.0008377461,
+-0.0008375702, -0.0008369770, -0.0008359687, -0.0008345473, -0.0008327155,
+-0.0008304759, -0.0008278313, -0.0008247847, -0.0008213393, -0.0008174987,
+-0.0008132662, -0.0008086459, -0.0008036415, -0.0007982572, -0.0007924973,
+-0.0007863663, -0.0007798688, -0.0007730096, -0.0007657937, -0.0007582263,
+-0.0007503124, -0.0007420577, -0.0007334676, -0.0007245480, -0.0007153045,
+-0.0007057433, -0.0006958705, -0.0006856923, -0.0006752151, -0.0006644455,
+-0.0006533899, -0.0006420553, -0.0006304484, -0.0006185763, -0.0006064459,
+-0.0005940644, -0.0005814391, -0.0005685774, -0.0005554866, -0.0005421744,
+-0.0005286483, -0.0005149159, -0.0005009850, -0.0004868635, -0.0004725592,
+-0.0004580801, -0.0004434340, -0.0004286292, -0.0004136736, -0.0003985753,
+-0.0003833426, -0.0003679835, -0.0003525065, -0.0003369196, -0.0003212311,
+-0.0003054494, -0.0002895827, -0.0002736393, -0.0002576275, -0.0002415556,
+-0.0002254319, -0.0002092648, -0.0001930624, -0.0001768330, -0.0001605849,
+-0.0001443262, -0.0001280652, -0.0001118099, -0.0000955685, -0.0000793491,
+-0.0000631597, -0.0000470081, -0.0000309025, -0.0000148505, 0.0000011400,
+0.0000170612, 0.0000329055, 0.0000486653, 0.0000643331, 0.0000799015,
+0.0000953630, 0.0001107104, 0.0001259365, 0.0001410343, 0.0001559967,
+0.0001708168, 0.0001854879, 0.0002000031, 0.0002143560, 0.0002285401,
+0.0002425489, 0.0002563763, 0.0002700161, 0.0002834622, 0.0002967089,
+0.0003097503, 0.0003225808, 0.0003351948, 0.0003475871, 0.0003597523,
+0.0003716854, 0.0003833814, 0.0003948354, 0.0004060428, 0.0004169991,
+0.0004276998, 0.0004381406, 0.0004483176, 0.0004582267, 0.0004678642,
+0.0004772264, 0.0004863097, 0.0004951109, 0.0005036269, 0.0005118544,
+0.0005197908, 0.0005274332, 0.0005347792, 0.0005418263, 0.0005485724,
+0.0005550152, 0.0005611530, 0.0005669840, 0.0005725066, 0.0005777193,
+0.0005826210, 0.0005872105, 0.0005914868, 0.0005954492, 0.0005990971,
+0.0006024300, 0.0006054476, 0.0006081498, 0.0006105366, 0.0006126081,
+0.0006143647, 0.0006158069, 0.0006169354, 0.0006177508, 0.0006182543,
+0.0006184469, 0.0006183298, 0.0006179045, 0.0006171725, 0.0006161355,
+0.0006147954, 0.0006131542, 0.0006112139, 0.0006089769, 0.0006064456,
+0.0006036225, 0.0006005103, 0.0005971119, 0.0005934301, 0.0005894681,
+0.0005852291, 0.0005807164, 0.0005759334, 0.0005708838, 0.0005655712,
+0.0005599994, 0.0005541724, 0.0005480941, 0.0005417688, 0.0005352006,
+0.0005283939, 0.0005213533, 0.0005140831, 0.0005065881, 0.0004988729,
+0.0004909425, 0.0004828018, 0.0004744556, 0.0004659092, 0.0004571676,
+0.0004482360, 0.0004391199, 0.0004298245, 0.0004203554, 0.0004107179,
+0.0004009177, 0.0003909603, 0.0003808515, 0.0003705970, 0.0003602026,
+0.0003496739, 0.0003390171, 0.0003282378, 0.0003173421, 0.0003063359,
+0.0002952252, 0.0002840160, 0.0002727144, 0.0002613264, 0.0002498582,
+0.0002383157, 0.0002267052, 0.0002150326, 0.0002033042, 0.0001915261,
+0.0001797043, 0.0001678449, 0.0001559542, 0.0001440381, 0.0001321027,
+0.0001201541, 0.0001081984, 0.0000962415, 0.0000842894, 0.0000723481,
+0.0000604235, 0.0000485216, 0.0000366481, 0.0000248089, 0.0000130097,
+0.0000012563, -0.0000104456, -0.0000220904, -0.0000336725, -0.0000451865,
+-0.0000566268, -0.0000679881, -0.0000792650, -0.0000904522, -0.0001015446,
+-0.0001125370, -0.0001234244, -0.0001342017, -0.0001448641, -0.0001554068,
+-0.0001658250, -0.0001761140, -0.0001862693, -0.0001962863, -0.0002061608,
+-0.0002158883, -0.0002254646, -0.0002348857, -0.0002441476, -0.0002532462,
+-0.0002621777, -0.0002709385, -0.0002795249, -0.0002879334, -0.0002961605,
+-0.0003042030, -0.0003120577, -0.0003197214, -0.0003271912, -0.0003344642,
+-0.0003415377, -0.0003484089, -0.0003550754, -0.0003615348, -0.0003677846,
+-0.0003738228, -0.0003796473, -0.0003852560, -0.0003906472, -0.0003958191,
+-0.0004007702, -0.0004054988, -0.0004100037, -0.0004142837, -0.0004183374,
+-0.0004221641, -0.0004257626, -0.0004291324, -0.0004322726, -0.0004351828,
+-0.0004378626, -0.0004403116, -0.0004425296, -0.0004445166, -0.0004462725,
+-0.0004477977, -0.0004490922, -0.0004501566, -0.0004509913, -0.0004515970,
+-0.0004519743, -0.0004521241, -0.0004520473, -0.0004517450, -0.0004512184,
+-0.0004504687, -0.0004494974, -0.0004483058, -0.0004468956, -0.0004452685,
+-0.0004434263, -0.0004413708, -0.0004391040, -0.0004366281, -0.0004339452,
+-0.0004310576, -0.0004279676, -0.0004246778, -0.0004211906, -0.0004175087,
+-0.0004136348, -0.0004095717, -0.0004053224, -0.0004008897, -0.0003962768,
+-0.0003914867, -0.0003865227, -0.0003813879, -0.0003760859, -0.0003706199,
+-0.0003649934, -0.0003592101, -0.0003532734, -0.0003471871, -0.0003409549,
+-0.0003345805, -0.0003280679, -0.0003214208, -0.0003146432, -0.0003077392,
+-0.0003007127, -0.0002935678, -0.0002863086, -0.0002789393, -0.0002714641,
+-0.0002638872, -0.0002562128, -0.0002484452, -0.0002405888, -0.0002326478,
+-0.0002246267, -0.0002165298, -0.0002083615, -0.0002001262, -0.0001918284,
+-0.0001834725, -0.0001750629, -0.0001666042, -0.0001581006, -0.0001495568,
+-0.0001409772, -0.0001323662, -0.0001237283, -0.0001150680, -0.0001063896,
+-0.0000976976, -0.0000889965, -0.0000802906, -0.0000715842, -0.0000628818,
+-0.0000541878, -0.0000455063, -0.0000368418, -0.0000281984, -0.0000195804,
+-0.0000109920, -0.0000024374, 0.0000060793, 0.0000145541, 0.0000229828,
+0.0000313614, 0.0000396861, 0.0000479528, 0.0000561577, 0.0000642970,
+0.0000723668, 0.0000803636, 0.0000882835, 0.0000961230, 0.0001038785,
+0.0001115465, 0.0001191237, 0.0001266065, 0.0001339917, 0.0001412761,
+0.0001484564, 0.0001555296, 0.0001624925, 0.0001693423, 0.0001760759,
+0.0001826906, 0.0001891836, 0.0001955522, 0.0002017938, 0.0002079058,
+0.0002138857, 0.0002197313, 0.0002254401, 0.0002310100, 0.0002364387,
+0.0002417243, 0.0002468647, 0.0002518580, 0.0002567025, 0.0002613963,
+0.0002659378, 0.0002703254, 0.0002745577, 0.0002786332, 0.0002825506,
+0.0002863087, 0.0002899064, 0.0002933425, 0.0002966162, 0.0002997264,
+0.0003026725, 0.0003054536, 0.0003080692, 0.0003105187, 0.0003128017,
+0.0003149178, 0.0003168666, 0.0003186480, 0.0003202619, 0.0003217083,
+0.0003229871, 0.0003240985, 0.0003250428, 0.0003258202, 0.0003264312,
+0.0003268761, 0.0003271556, 0.0003272702, 0.0003272206, 0.0003270078,
+0.0003266324, 0.0003260955, 0.0003253981, 0.0003245412, 0.0003235261,
+0.0003223540, 0.0003210261, 0.0003195440, 0.0003179089, 0.0003161226,
+0.0003141865, 0.0003121023, 0.0003098718, 0.0003074968, 0.0003049791,
+0.0003023207, 0.0002995235, 0.0002965895, 0.0002935210, 0.0002903200,
+0.0002869888, 0.0002835296, 0.0002799448, 0.0002762367, 0.0002724079,
+0.0002684607, 0.0002643977, 0.0002602215, 0.0002559347, 0.0002515399,
+0.0002470399, 0.0002424374, 0.0002377352, 0.0002329361, 0.0002280430,
+0.0002230587, 0.0002179862, 0.0002128285, 0.0002075885, 0.0002022692,
+0.0001968736, 0.0001914049, 0.0001858661, 0.0001802603, 0.0001745906,
+0.0001688602, 0.0001630723, 0.0001572299, 0.0001513363, 0.0001453946,
+0.0001394082, 0.0001333801, 0.0001273136, 0.0001212119, 0.0001150782,
+0.0001089158, 0.0001027279, 0.0000965177, 0.0000902884, 0.0000840433,
+0.0000777854, 0.0000715181, 0.0000652446, 0.0000589678, 0.0000526912,
+0.0000464177, 0.0000401505, 0.0000338928, 0.0000276476, 0.0000214180,
+0.0000152070, 0.0000090176, 0.0000028530, -0.0000032841, -0.0000093905,
+-0.0000154635, -0.0000215001, -0.0000274975, -0.0000334528, -0.0000393633,
+-0.0000452261, -0.0000510387, -0.0000567983, -0.0000625023, -0.0000681481,
+-0.0000737331, -0.0000792549, -0.0000847109, -0.0000900988, -0.0000954161,
+-0.0001006605, -0.0001058298, -0.0001109216, -0.0001159339, -0.0001208645,
+-0.0001257113, -0.0001304723, -0.0001351454, -0.0001397288, -0.0001442206,
+-0.0001486190, -0.0001529222, -0.0001571285, -0.0001612363, -0.0001652439,
+-0.0001691499, -0.0001729527, -0.0001766509, -0.0001802433, -0.0001837284,
+-0.0001871051, -0.0001903722, -0.0001935285, -0.0001965730, -0.0001995047,
+-0.0002023227, -0.0002050261, -0.0002076141, -0.0002100859, -0.0002124409,
+-0.0002146784, -0.0002167979, -0.0002187988, -0.0002206808, -0.0002224434,
+-0.0002240864, -0.0002256094, -0.0002270123, -0.0002282950, -0.0002294574,
+-0.0002304995, -0.0002314213, -0.0002322229, -0.0002329046, -0.0002334665,
+-0.0002339089, -0.0002342322, -0.0002344368, -0.0002345232, -0.0002344918,
+-0.0002343433, -0.0002340783, -0.0002336975, -0.0002332015, -0.0002325913,
+-0.0002318677, -0.0002310316, -0.0002300839, -0.0002290256, -0.0002278578,
+-0.0002265817, -0.0002251983, -0.0002237089, -0.0002221147, -0.0002204171,
+-0.0002186173, -0.0002167169, -0.0002147171, -0.0002126195, -0.0002104256,
+-0.0002081370, -0.0002057553, -0.0002032820, -0.0002007190, -0.0001980679,
+-0.0001953304, -0.0001925083, -0.0001896036, -0.0001866179, -0.0001835533,
+-0.0001804116, -0.0001771947, -0.0001739047, -0.0001705435, -0.0001671132,
+-0.0001636158, -0.0001600534, -0.0001564281, -0.0001527420, -0.0001489973,
+-0.0001451961, -0.0001413406, -0.0001374329, -0.0001334754, -0.0001294702,
+-0.0001254195, -0.0001213257, -0.0001171909, -0.0001130175, -0.0001088077,
+-0.0001045638, -0.0001002881, -0.0000959829, -0.0000916505, -0.0000872932,
+-0.0000829133, -0.0000785131, -0.0000740949, -0.0000696610, -0.0000652138,
+-0.0000607554, -0.0000562883, -0.0000518146, -0.0000473367, -0.0000428568,
+-0.0000383772, -0.0000339001, -0.0000294277, -0.0000249624, -0.0000205062,
+-0.0000160614, -0.0000116301, -0.0000072145, -0.0000028167, 0.0000015611,
+0.0000059168, 0.0000102485, 0.0000145539, 0.0000188311, 0.0000230781,
+0.0000272929, 0.0000314736, 0.0000356181, 0.0000397247, 0.0000437914,
+0.0000478164, 0.0000517978, 0.0000557339, 0.0000596230, 0.0000634633,
+0.0000672531, 0.0000709908, 0.0000746747, 0.0000783033, 0.0000818750,
+0.0000853883, 0.0000888417, 0.0000922338, 0.0000955632, 0.0000988286,
+0.0001020285, 0.0001051617, 0.0001082270, 0.0001112231, 0.0001141489,
+0.0001170033, 0.0001197852, 0.0001224936, 0.0001251273, 0.0001276856,
+0.0001301674, 0.0001325720, 0.0001348984, 0.0001371460, 0.0001393138,
+0.0001414014, 0.0001434079, 0.0001453328, 0.0001471756, 0.0001489356,
+0.0001506125, 0.0001522058, 0.0001537151, 0.0001551400, 0.0001564803,
+0.0001577357, 0.0001589060, 0.0001599910, 0.0001609906, 0.0001619047,
+0.0001627333, 0.0001634764, 0.0001641339, 0.0001647061, 0.0001651931,
+0.0001655949, 0.0001659120, 0.0001661444, 0.0001662924, 0.0001663566,
+0.0001663371, 0.0001662345, 0.0001660492, 0.0001657817, 0.0001654325,
+0.0001650023, 0.0001644915, 0.0001639010, 0.0001632313, 0.0001624832,
+0.0001616575, 0.0001607549, 0.0001597764, 0.0001587227, 0.0001575947,
+0.0001563934, 0.0001551198, 0.0001537748, 0.0001523595, 0.0001508749,
+0.0001493222, 0.0001477024, 0.0001460166, 0.0001442661, 0.0001424521,
+0.0001405757, 0.0001386382, 0.0001366410, 0.0001345852, 0.0001324722,
+0.0001303034, 0.0001280801, 0.0001258038, 0.0001234757, 0.0001210974,
+0.0001186702, 0.0001161957, 0.0001136753, 0.0001111105, 0.0001085028,
+0.0001058537, 0.0001031648, 0.0001004377, 0.0000976737, 0.0000948747,
+0.0000920420, 0.0000891774, 0.0000862823, 0.0000833585, 0.0000804075,
+0.0000774309, 0.0000744303, 0.0000714075, 0.0000683639, 0.0000653013,
+0.0000622212, 0.0000591253, 0.0000560153, 0.0000528927, 0.0000497592,
+0.0000466164, 0.0000434660, 0.0000403095, 0.0000371486, 0.0000339848,
+0.0000308199, 0.0000276553, 0.0000244926, 0.0000213335, 0.0000181796,
+0.0000150322, 0.0000118931, 0.0000087637, 0.0000056456, 0.0000025402,
+-0.0000005509, -0.0000036262, -0.0000066844, -0.0000097239, -0.0000127433,
+-0.0000157412, -0.0000187162, -0.0000216669, -0.0000245920, -0.0000274901,
+-0.0000303599, -0.0000332001, -0.0000360095, -0.0000387867, -0.0000415306,
+-0.0000442399, -0.0000469135, -0.0000495501, -0.0000521487, -0.0000547082,
+-0.0000572273, -0.0000597052, -0.0000621407, -0.0000645329, -0.0000668807,
+-0.0000691832, -0.0000714395, -0.0000736486, -0.0000758098, -0.0000779221,
+-0.0000799848, -0.0000819970, -0.0000839581, -0.0000858672, -0.0000877237,
+-0.0000895269, -0.0000912761, -0.0000929709, -0.0000946105, -0.0000961945,
+-0.0000977224, -0.0000991935, -0.0001006076, -0.0001019642, -0.0001032628,
+-0.0001045032, -0.0001056850, -0.0001068078, -0.0001078715, -0.0001088758,
+-0.0001098205, -0.0001107055, -0.0001115305, -0.0001122954, -0.0001130003,
+-0.0001136450, -0.0001142295, -0.0001147539, -0.0001152181, -0.0001156222,
+-0.0001159664, -0.0001162508, -0.0001164755, -0.0001166408, -0.0001167467,
+-0.0001167937, -0.0001167819, -0.0001167117, -0.0001165834, -0.0001163974,
+-0.0001161540, -0.0001158536, -0.0001154968, -0.0001150839, -0.0001146154,
+-0.0001140920, -0.0001135140, -0.0001128821, -0.0001121969, -0.0001114590,
+-0.0001106690, -0.0001098276, -0.0001089354, -0.0001079932, -0.0001070018,
+-0.0001059617, -0.0001048739, -0.0001037391, -0.0001025581, -0.0001013318,
+-0.0001000609, -0.0000987464, -0.0000973892, -0.0000959901, -0.0000945500,
+-0.0000930699, -0.0000915507, -0.0000899935, -0.0000883990, -0.0000867685,
+-0.0000851028, -0.0000834030, -0.0000816701, -0.0000799051, -0.0000781091,
+-0.0000762832, -0.0000744284, -0.0000725458, -0.0000706365, -0.0000687015,
+-0.0000667421, -0.0000647592, -0.0000627541, -0.0000607277, -0.0000586814,
+-0.0000566161, -0.0000545330, -0.0000524333, -0.0000503180, -0.0000481885,
+-0.0000460456, -0.0000438907, -0.0000417249, -0.0000395493, -0.0000373650,
+-0.0000351732, -0.0000329751, -0.0000307717, -0.0000285642, -0.0000263537,
+-0.0000241414, -0.0000219284, -0.0000197157, -0.0000175046, -0.0000152960,
+-0.0000130912, -0.0000108911, -0.0000086969, -0.0000065096, -0.0000043304,
+-0.0000021601, -0.0000000000
+};
* Copyright 2000-2002 TransGaming Technologies, Inc.
* Copyright 2007 Peter Dons Tychsen
* Copyright 2007 Maarten Lankhorst
+ * Copyright 2011 Owen Rudge for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
-
+#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include <windef.h>
#include <winbase.h>
#include <mmsystem.h>
+//#include "wingdi.h"
+//#include "mmreg.h"
#include <winternl.h>
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
+//#include "ks.h"
+//#include "ksmedia.h"
#include "dsound_private.h"
+#include "fir.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
TRACE("Vol=%d Pan=%d\n", volpan->lVolume, volpan->lPan);
}
-/** Convert a primary buffer position to a pointer position for device->mix_buffer
- * device: DirectSoundDevice for which to calculate
- * pos: Primary buffer position to converts
- * Returns: Offset for mix_buffer
- */
-DWORD DSOUND_bufpos_to_mixpos(const DirectSoundDevice* device, DWORD pos)
-{
- DWORD ret = pos * 32 / device->pwfx->wBitsPerSample;
- if (device->pwfx->wBitsPerSample == 32)
- ret *= 2;
- return ret;
-}
-
-/* NOTE: Not all secpos have to always be mapped to a bufpos, other way around is always the case
- * DWORD64 is used here because a single DWORD wouldn't be big enough to fit the freqAcc for big buffers
- */
-/** This function converts a 'native' sample pointer to a resampled pointer that fits for primary
- * secmixpos is used to decide which freqAcc is needed
- * overshot tells what the 'actual' secpos is now (optional)
- */
-DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD* overshot)
-{
- DWORD64 framelen = secpos / dsb->pwfx->nBlockAlign;
- DWORD64 freqAdjust = dsb->freqAdjust;
- DWORD64 acc, freqAcc;
-
- if (secpos < secmixpos)
- freqAcc = dsb->freqAccNext;
- else freqAcc = dsb->freqAcc;
- acc = (framelen << DSOUND_FREQSHIFT) + (freqAdjust - 1 - freqAcc);
- acc /= freqAdjust;
- if (overshot)
- {
- DWORD64 oshot = acc * freqAdjust + freqAcc;
- assert(oshot >= framelen << DSOUND_FREQSHIFT);
- oshot -= framelen << DSOUND_FREQSHIFT;
- *overshot = (DWORD)oshot;
- assert(*overshot < dsb->freqAdjust);
- }
- return (DWORD)acc * dsb->device->pwfx->nBlockAlign;
-}
-
-/** Convert a resampled pointer that fits for primary to a 'native' sample pointer
- * freqAccNext is used here rather than freqAcc: In case the app wants to fill up to
- * the play position it won't overwrite it
- */
-static DWORD DSOUND_bufpos_to_secpos(const IDirectSoundBufferImpl *dsb, DWORD bufpos)
-{
- DWORD oAdv = dsb->device->pwfx->nBlockAlign, iAdv = dsb->pwfx->nBlockAlign, pos;
- DWORD64 framelen;
- DWORD64 acc;
-
- framelen = bufpos/oAdv;
- acc = framelen * (DWORD64)dsb->freqAdjust + (DWORD64)dsb->freqAccNext;
- acc = acc >> DSOUND_FREQSHIFT;
- pos = (DWORD)acc * iAdv;
- if (pos >= dsb->buflen)
- /* Because of differences between freqAcc and freqAccNext, this might happen */
- pos = dsb->buflen - iAdv;
- TRACE("Converted %d/%d to %d/%d\n", bufpos, dsb->tmp_buffer_len, pos, dsb->buflen);
- return pos;
-}
-
-/**
- * Move freqAccNext to freqAcc, and find new values for buffer length and freqAccNext
- */
-static void DSOUND_RecalcFreqAcc(IDirectSoundBufferImpl *dsb)
-{
- if (!dsb->freqneeded) return;
- dsb->freqAcc = dsb->freqAccNext;
- dsb->tmp_buffer_len = DSOUND_secpos_to_bufpos(dsb, dsb->buflen, 0, &dsb->freqAccNext);
- TRACE("New freqadjust: %04x, new buflen: %d\n", dsb->freqAccNext, dsb->tmp_buffer_len);
-}
-
/**
* Recalculate the size for temporary buffer, and new writelead
* Should be called when one of the following things occur:
* - Primary buffer format is changed
* - This buffer format (frequency) is changed
- *
- * After this, DSOUND_MixToTemporary(dsb, 0, dsb->buflen) should
- * be called to refill the temporary buffer with data.
*/
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
{
- BOOL needremix = TRUE, needresample = (dsb->freq != dsb->device->pwfx->nSamplesPerSec);
- DWORD bAlign = dsb->pwfx->nBlockAlign, pAlign = dsb->device->pwfx->nBlockAlign;
+ DWORD ichannels = dsb->pwfx->nChannels;
+ DWORD ochannels = dsb->device->pwfx->nChannels;
+ WAVEFORMATEXTENSIBLE *pwfxe;
+ BOOL ieee = FALSE;
TRACE("(%p)\n",dsb);
+ pwfxe = (WAVEFORMATEXTENSIBLE *) dsb->pwfx;
+ dsb->freqAdjust = (float)dsb->freq / dsb->device->pwfx->nSamplesPerSec;
+
+ if ((pwfxe->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) || ((pwfxe->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ && (IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))))
+ ieee = TRUE;
+
+ /**
+ * Recalculate FIR step and gain.
+ *
+ * firstep says how many points of the FIR exist per one
+ * sample in the secondary buffer. firgain specifies what
+ * to multiply the FIR output by in order to attenuate it correctly.
+ */
+ if (dsb->freqAdjust > 1.0f) {
+ /**
+ * Yes, round it a bit to make sure that the
+ * linear interpolation factor never changes.
+ */
+ dsb->firstep = ceil(fir_step / dsb->freqAdjust);
+ } else {
+ dsb->firstep = fir_step;
+ }
+ dsb->firgain = (float)dsb->firstep / fir_step;
+
/* calculate the 10ms write lead */
dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign;
- if ((dsb->pwfx->wBitsPerSample == dsb->device->pwfx->wBitsPerSample) &&
- (dsb->pwfx->nChannels == dsb->device->pwfx->nChannels) && !needresample)
- needremix = FALSE;
- HeapFree(GetProcessHeap(), 0, dsb->tmp_buffer);
- dsb->tmp_buffer = NULL;
- dsb->max_buffer_len = dsb->freqAcc = dsb->freqAccNext = 0;
- dsb->freqneeded = needresample;
+ dsb->freqAcc = 0;
- dsb->convert = convertbpp[dsb->pwfx->wBitsPerSample/8 - 1][dsb->device->pwfx->wBitsPerSample/8 - 1];
+ dsb->get_aux = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1];
+ dsb->put_aux = putieee32;
- dsb->resampleinmixer = FALSE;
+ dsb->get = dsb->get_aux;
+ dsb->put = dsb->put_aux;
- if (needremix)
+ if (ichannels == ochannels)
{
- if (needresample)
- DSOUND_RecalcFreqAcc(dsb);
- else
- dsb->tmp_buffer_len = dsb->buflen / bAlign * pAlign;
- dsb->max_buffer_len = dsb->tmp_buffer_len;
- if ((dsb->max_buffer_len <= dsb->device->buflen || dsb->max_buffer_len < ds_snd_shadow_maxsize * 1024 * 1024) && ds_snd_shadow_maxsize >= 0)
- dsb->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, dsb->max_buffer_len);
- if (dsb->tmp_buffer)
- FillMemory(dsb->tmp_buffer, dsb->tmp_buffer_len, dsb->device->pwfx->wBitsPerSample == 8 ? 128 : 0);
- else
- dsb->resampleinmixer = TRUE;
+ dsb->mix_channels = ichannels;
+ if (ichannels > 32) {
+ FIXME("Copying %u channels is unsupported, limiting to first 32\n", ichannels);
+ dsb->mix_channels = 32;
+ }
+ }
+ else if (ichannels == 1)
+ {
+ dsb->mix_channels = 1;
+ dsb->put = put_mono2stereo;
+ }
+ else if (ochannels == 1)
+ {
+ dsb->mix_channels = 1;
+ dsb->get = get_mono;
+ }
+ else
+ {
+ if (ichannels > 2)
+ FIXME("Conversion from %u to %u channels is not implemented, falling back to stereo\n", ichannels, ochannels);
+ dsb->mix_channels = 2;
}
- else dsb->max_buffer_len = dsb->tmp_buffer_len = dsb->buflen;
- dsb->buf_mixpos = DSOUND_secpos_to_bufpos(dsb, dsb->sec_mixpos, 0, NULL);
}
/**
}
}
-/**
- * Copy a single frame from the given input buffer to the given output buffer.
- * Translate 8 <-> 16 bits and mono <-> stereo
- */
-static inline void cp_fields(const IDirectSoundBufferImpl *dsb, const BYTE *ibuf, BYTE *obuf,
- UINT istride, UINT ostride, UINT count, UINT freqAcc, UINT adj)
+static inline float get_current_sample(const IDirectSoundBufferImpl *dsb,
+ DWORD mixpos, DWORD channel)
{
- DirectSoundDevice *device = dsb->device;
- INT istep = dsb->pwfx->wBitsPerSample / 8, ostep = device->pwfx->wBitsPerSample / 8;
+ if (mixpos >= dsb->buflen && !(dsb->playflags & DSBPLAY_LOOPING))
+ return 0.0f;
+ return dsb->get(dsb, mixpos % dsb->buflen, channel);
+}
- if (device->pwfx->nChannels == dsb->pwfx->nChannels) {
- dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
- if (device->pwfx->nChannels == 2)
- dsb->convert(ibuf + istep, obuf + ostep, istride, ostride, count, freqAcc, adj);
- }
+static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count)
+{
+ UINT istride = dsb->pwfx->nBlockAlign;
+ UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
+ DWORD channel, i;
+ for (i = 0; i < count; i++)
+ for (channel = 0; channel < dsb->mix_channels; channel++)
+ dsb->put(dsb, i * ostride, channel, get_current_sample(dsb,
+ dsb->sec_mixpos + i * istride, channel));
+ return count;
+}
- if (device->pwfx->nChannels == 1 && dsb->pwfx->nChannels == 2)
- {
- dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
+static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, float *freqAcc)
+{
+ UINT i, channel;
+ UINT istride = dsb->pwfx->nBlockAlign;
+ UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
+
+ float freqAdjust = dsb->freqAdjust;
+ float freqAcc_start = *freqAcc;
+ float freqAcc_end = freqAcc_start + count * freqAdjust;
+ UINT dsbfirstep = dsb->firstep;
+ UINT channels = dsb->mix_channels;
+ UINT max_ipos = freqAcc_start + count * freqAdjust;
+
+ UINT fir_cachesize = (fir_len + dsbfirstep - 2) / dsbfirstep;
+ UINT required_input = max_ipos + fir_cachesize;
+
+ float* intermediate = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(float) * required_input * channels);
+
+ float* fir_copy = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(float) * fir_cachesize);
+
+ /* Important: this buffer MUST be non-interleaved
+ * if you want -msse3 to have any effect.
+ * This is good for CPU cache effects, too.
+ */
+ float* itmp = intermediate;
+ for (channel = 0; channel < channels; channel++)
+ for (i = 0; i < required_input; i++)
+ *(itmp++) = get_current_sample(dsb,
+ dsb->sec_mixpos + i * istride, channel);
+
+ for(i = 0; i < count; ++i) {
+ float total_fir_steps = (freqAcc_start + i * freqAdjust) * dsbfirstep;
+ UINT int_fir_steps = total_fir_steps;
+ UINT ipos = int_fir_steps / dsbfirstep;
+
+ UINT idx = (ipos + 1) * dsbfirstep - int_fir_steps - 1;
+ float rem = int_fir_steps + 1.0 - total_fir_steps;
+
+ int fir_used = 0;
+ while (idx < fir_len - 1) {
+ fir_copy[fir_used++] = fir[idx] * (1.0 - rem) + fir[idx + 1] * rem;
+ idx += dsb->firstep;
+ }
+
+ assert(fir_used <= fir_cachesize);
+ assert(ipos + fir_used <= required_input);
+
+ for (channel = 0; channel < dsb->mix_channels; channel++) {
+ int j;
+ float sum = 0.0;
+ float* cache = &intermediate[channel * required_input + ipos];
+ for (j = 0; j < fir_used; j++)
+ sum += fir_copy[j] * cache[j];
+ dsb->put(dsb, i * ostride, channel, sum * dsb->firgain);
+ }
}
- if (device->pwfx->nChannels == 2 && dsb->pwfx->nChannels == 1)
- {
- dsb->convert(ibuf, obuf, istride, ostride, count, freqAcc, adj);
- dsb->convert(ibuf, obuf + ostep, istride, ostride, count, freqAcc, adj);
+ freqAcc_end -= (int)freqAcc_end;
+ *freqAcc = freqAcc_end;
+
+ HeapFree(GetProcessHeap(), 0, fir_copy);
+ HeapFree(GetProcessHeap(), 0, intermediate);
+
+ return max_ipos;
+}
+
+static void cp_fields(IDirectSoundBufferImpl *dsb, UINT count, float *freqAcc)
+{
+ DWORD ipos, adv;
+
+ if (dsb->freqAdjust == 1.0)
+ adv = cp_fields_noresample(dsb, count); /* *freqAcc is unmodified */
+ else
+ adv = cp_fields_resample(dsb, count, freqAcc);
+
+ ipos = dsb->sec_mixpos + adv * dsb->pwfx->nBlockAlign;
+ if (ipos >= dsb->buflen) {
+ if (dsb->playflags & DSBPLAY_LOOPING)
+ ipos %= dsb->buflen;
+ else {
+ ipos = 0;
+ dsb->state = STATE_STOPPED;
+ }
}
+
+ dsb->sec_mixpos = ipos;
}
/**
*
* NOTE: writepos + len <= buflen. When called by mixer, MixOne makes sure of this.
*/
-void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD len, BOOL inmixer)
+static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
{
- INT size;
- BYTE *ibp, *obp, *obp_begin;
- INT iAdvance = dsb->pwfx->nBlockAlign;
- INT oAdvance = dsb->device->pwfx->nBlockAlign;
- DWORD freqAcc, target_writepos = 0, overshot, maxlen;
-
- /* We resample only when needed */
- if ((dsb->tmp_buffer && inmixer) || (!dsb->tmp_buffer && !inmixer) || dsb->resampleinmixer != inmixer)
- return;
+ UINT size_bytes = frames * sizeof(float) * dsb->device->pwfx->nChannels;
- assert(writepos + len <= dsb->buflen);
- if (inmixer && writepos + len < dsb->buflen)
- len += dsb->pwfx->nBlockAlign;
-
- maxlen = DSOUND_secpos_to_bufpos(dsb, len, 0, NULL);
-
- ibp = dsb->buffer->memory + writepos;
- if (!inmixer)
- obp_begin = dsb->tmp_buffer;
- else if (dsb->device->tmp_buffer_len < maxlen || !dsb->device->tmp_buffer)
+ if (dsb->device->tmp_buffer_len < size_bytes || !dsb->device->tmp_buffer)
{
- dsb->device->tmp_buffer_len = maxlen;
+ dsb->device->tmp_buffer_len = size_bytes;
if (dsb->device->tmp_buffer)
- dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, maxlen);
+ dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, size_bytes);
else
- dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, maxlen);
- obp_begin = dsb->device->tmp_buffer;
- }
- else
- obp_begin = dsb->device->tmp_buffer;
-
- TRACE("(%p, %p)\n", dsb, ibp);
- size = len / iAdvance;
-
- /* Check for same sample rate */
- if (dsb->freq == dsb->device->pwfx->nSamplesPerSec) {
- TRACE("(%p) Same sample rate %d = primary %d\n", dsb,
- dsb->freq, dsb->device->pwfx->nSamplesPerSec);
- obp = obp_begin;
- if (!inmixer)
- obp += writepos/iAdvance*oAdvance;
-
- cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, 0, 1 << DSOUND_FREQSHIFT);
- return;
- }
-
- /* Mix in different sample rates */
- TRACE("(%p) Adjusting frequency: %d -> %d\n", dsb, dsb->freq, dsb->device->pwfx->nSamplesPerSec);
-
- target_writepos = DSOUND_secpos_to_bufpos(dsb, writepos, dsb->sec_mixpos, &freqAcc);
- overshot = freqAcc >> DSOUND_FREQSHIFT;
- if (overshot)
- {
- if (overshot >= size)
- return;
- size -= overshot;
- writepos += overshot * iAdvance;
- if (writepos >= dsb->buflen)
- return;
- ibp = dsb->buffer->memory + writepos;
- freqAcc &= (1 << DSOUND_FREQSHIFT) - 1;
- TRACE("Overshot: %d, freqAcc: %04x\n", overshot, freqAcc);
+ dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, size_bytes);
}
- if (!inmixer)
- obp = obp_begin + target_writepos;
- else obp = obp_begin;
-
- /* FIXME: Small problem here when we're overwriting buf_mixpos, it then STILL uses old freqAcc, not sure if it matters or not */
- cp_fields(dsb, ibp, obp, iAdvance, oAdvance, size, freqAcc, dsb->freqAdjust);
+ cp_fields(dsb, frames, &dsb->freqAcc);
}
-/** Apply volume to the given soundbuffer from (primary) position writepos and length len
- * Returns: NULL if no volume needs to be applied
- * or else a memory handle that holds 'len' volume adjusted buffer */
-static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len)
+static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
{
INT i;
- BYTE *bpc;
- INT16 *bps, *mems;
- DWORD vLeft, vRight;
- INT nChannels = dsb->device->pwfx->nChannels;
- LPBYTE mem = (dsb->tmp_buffer ? dsb->tmp_buffer : dsb->buffer->memory) + dsb->buf_mixpos;
-
- if (dsb->resampleinmixer)
- mem = dsb->device->tmp_buffer;
+ float vLeft, vRight;
+ UINT channels = dsb->device->pwfx->nChannels, chan;
- TRACE("(%p,%d)\n",dsb,len);
+ TRACE("(%p,%d)\n",dsb,frames);
TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor,
dsb->volpan.dwTotalRightAmpFactor);
if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->volpan.lPan == 0)) &&
(!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volpan.lVolume == 0)) &&
!(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
- return NULL; /* Nothing to do */
+ return; /* Nothing to do */
- if (nChannels != 1 && nChannels != 2)
+ if (channels != 1 && channels != 2)
{
- FIXME("There is no support for %d channels\n", nChannels);
- return NULL;
- }
-
- if (dsb->device->pwfx->wBitsPerSample != 8 && dsb->device->pwfx->wBitsPerSample != 16)
- {
- FIXME("There is no support for %d bpp\n", dsb->device->pwfx->wBitsPerSample);
- return NULL;
- }
-
- if (dsb->device->tmp_buffer_len < len || !dsb->device->tmp_buffer)
- {
- /* If we just resampled in DSOUND_MixToTemporary, we shouldn't need to resize here */
- assert(!dsb->resampleinmixer);
- dsb->device->tmp_buffer_len = len;
- if (dsb->device->tmp_buffer)
- dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, len);
- else
- dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, len);
+ FIXME("There is no support for %u channels\n", channels);
+ return;
}
- bpc = dsb->device->tmp_buffer;
- bps = (INT16 *)bpc;
- mems = (INT16 *)mem;
- vLeft = dsb->volpan.dwTotalLeftAmpFactor;
- if (nChannels > 1)
- vRight = dsb->volpan.dwTotalRightAmpFactor;
- else
- vRight = vLeft;
-
- switch (dsb->device->pwfx->wBitsPerSample) {
- case 8:
- /* 8-bit WAV is unsigned, but we need to operate */
- /* on signed data for this to work properly */
- for (i = 0; i < len-1; i+=2) {
- *(bpc++) = (((*(mem++) - 128) * vLeft) >> 16) + 128;
- *(bpc++) = (((*(mem++) - 128) * vRight) >> 16) + 128;
- }
- if (len % 2 == 1 && nChannels == 1)
- *(bpc++) = (((*(mem++) - 128) * vLeft) >> 16) + 128;
- break;
- case 16:
- /* 16-bit WAV is signed -- much better */
- for (i = 0; i < len-3; i += 4) {
- *(bps++) = (*(mems++) * vLeft) >> 16;
- *(bps++) = (*(mems++) * vRight) >> 16;
+ vLeft = dsb->volpan.dwTotalLeftAmpFactor / ((float)0xFFFF);
+ vRight = dsb->volpan.dwTotalRightAmpFactor / ((float)0xFFFF);
+ for(i = 0; i < frames; ++i){
+ for(chan = 0; chan < channels; ++chan){
+ if(chan == 0)
+ dsb->device->tmp_buffer[i * channels + chan] *= vLeft;
+ else
+ dsb->device->tmp_buffer[i * channels + chan] *= vRight;
}
- if (len % 4 == 2 && nChannels == 1)
- *(bps++) = ((INT)*(mems++) * vLeft) >> 16;
- break;
}
- return dsb->device->tmp_buffer;
}
/**
*/
static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen)
{
- INT len = fraglen, ilen;
- BYTE *ibuf = (dsb->tmp_buffer ? dsb->tmp_buffer : dsb->buffer->memory) + dsb->buf_mixpos, *volbuf;
- DWORD oldpos, mixbufpos;
+ INT len = fraglen;
+ float *ibuf;
+ DWORD oldpos;
+ UINT frames = fraglen / dsb->device->pwfx->nBlockAlign;
- TRACE("buf_mixpos=%d/%d sec_mixpos=%d/%d\n", dsb->buf_mixpos, dsb->tmp_buffer_len, dsb->sec_mixpos, dsb->buflen);
+ TRACE("sec_mixpos=%d/%d\n", dsb->sec_mixpos, dsb->buflen);
TRACE("(%p,%d,%d)\n",dsb,writepos,fraglen);
- assert(dsb->buf_mixpos + len <= dsb->tmp_buffer_len);
-
if (len % dsb->device->pwfx->nBlockAlign) {
INT nBlockAlign = dsb->device->pwfx->nBlockAlign;
ERR("length not a multiple of block size, len = %d, block size = %d\n", len, nBlockAlign);
}
/* Resample buffer to temporary buffer specifically allocated for this purpose, if needed */
- DSOUND_MixToTemporary(dsb, dsb->sec_mixpos, DSOUND_bufpos_to_secpos(dsb, dsb->buf_mixpos+len) - dsb->sec_mixpos, TRUE);
- if (dsb->resampleinmixer)
- ibuf = dsb->device->tmp_buffer;
+ oldpos = dsb->sec_mixpos;
+
+ DSOUND_MixToTemporary(dsb, frames);
+ ibuf = dsb->device->tmp_buffer;
/* Apply volume if needed */
- volbuf = DSOUND_MixerVol(dsb, len);
- if (volbuf)
- ibuf = volbuf;
-
- mixbufpos = DSOUND_bufpos_to_mixpos(dsb->device, writepos);
- /* Now mix the temporary buffer into the devices main buffer */
- if ((writepos + len) <= dsb->device->buflen)
- dsb->device->mixfunction(ibuf, dsb->device->mix_buffer + mixbufpos, len);
- else
- {
- DWORD todo = dsb->device->buflen - writepos;
- dsb->device->mixfunction(ibuf, dsb->device->mix_buffer + mixbufpos, todo);
- dsb->device->mixfunction(ibuf + todo, dsb->device->mix_buffer, len - todo);
- }
+ DSOUND_MixerVol(dsb, frames);
- oldpos = dsb->sec_mixpos;
- dsb->buf_mixpos += len;
-
- if (dsb->buf_mixpos >= dsb->tmp_buffer_len) {
- if (dsb->buf_mixpos > dsb->tmp_buffer_len)
- ERR("Mixpos (%u) past buflen (%u), capping...\n", dsb->buf_mixpos, dsb->tmp_buffer_len);
- if (dsb->playflags & DSBPLAY_LOOPING) {
- dsb->buf_mixpos -= dsb->tmp_buffer_len;
- } else if (dsb->buf_mixpos >= dsb->tmp_buffer_len) {
- dsb->buf_mixpos = dsb->sec_mixpos = 0;
- dsb->state = STATE_STOPPED;
- }
- DSOUND_RecalcFreqAcc(dsb);
- }
+ mixieee32(ibuf, dsb->device->mix_buffer, frames * dsb->device->pwfx->nChannels);
- dsb->sec_mixpos = DSOUND_bufpos_to_secpos(dsb, dsb->buf_mixpos);
- ilen = DSOUND_BufPtrDiff(dsb->buflen, dsb->sec_mixpos, oldpos);
/* check for notification positions */
if (dsb->dsbd.dwFlags & DSBCAPS_CTRLPOSITIONNOTIFY &&
dsb->state != STATE_STARTING) {
+ INT ilen = DSOUND_BufPtrDiff(dsb->buflen, dsb->sec_mixpos, oldpos);
DSOUND_CheckEvent(dsb, oldpos, ilen);
}
- /* increase mix position */
- dsb->primary_mixpos += len;
- if (dsb->primary_mixpos >= dsb->device->buflen)
- dsb->primary_mixpos -= dsb->device->buflen;
return len;
}
*/
static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen)
{
- /* The buffer's primary_mixpos may be before or after the device
- * buffer's mixpos, but both must be ahead of writepos. */
- DWORD primary_done;
+ DWORD primary_done = 0;
TRACE("(%p,%d,%d)\n",dsb,writepos,mixlen);
- TRACE("writepos=%d, buf_mixpos=%d, primary_mixpos=%d, mixlen=%d\n", writepos, dsb->buf_mixpos, dsb->primary_mixpos, mixlen);
- TRACE("looping=%d, leadin=%d, buflen=%d\n", dsb->playflags, dsb->leadin, dsb->tmp_buffer_len);
+ TRACE("writepos=%d, mixlen=%d\n", writepos, mixlen);
+ TRACE("looping=%d, leadin=%d\n", dsb->playflags, dsb->leadin);
/* If leading in, only mix about 20 ms, and 'skip' mixing the rest, for more fluid pointer advancement */
- if (dsb->leadin && dsb->state == STATE_STARTING)
- {
- if (mixlen > 2 * dsb->device->fraglen)
- {
- dsb->primary_mixpos += mixlen - 2 * dsb->device->fraglen;
- dsb->primary_mixpos %= dsb->device->buflen;
+ /* FIXME: Is this needed? */
+ if (dsb->leadin && dsb->state == STATE_STARTING) {
+ if (mixlen > 2 * dsb->device->fraglen) {
+ primary_done = mixlen - 2 * dsb->device->fraglen;
+ mixlen = 2 * dsb->device->fraglen;
+ writepos += primary_done;
+ dsb->sec_mixpos += (primary_done / dsb->device->pwfx->nBlockAlign) *
+ dsb->pwfx->nBlockAlign * dsb->freqAdjust;
}
}
- dsb->leadin = FALSE;
-
- /* calculate how much pre-buffering has already been done for this buffer */
- primary_done = DSOUND_BufPtrDiff(dsb->device->buflen, dsb->primary_mixpos, writepos);
- /* sanity */
- if(mixlen < primary_done)
- {
- /* Should *NEVER* happen */
- ERR("Fatal error. Under/Overflow? primary_done=%d, mixpos=%d/%d (%d/%d), primary_mixpos=%d, writepos=%d, mixlen=%d\n", primary_done,dsb->buf_mixpos,dsb->tmp_buffer_len,dsb->sec_mixpos, dsb->buflen, dsb->primary_mixpos, writepos, mixlen);
- return 0;
- }
-
- /* take into account already mixed data */
- mixlen -= primary_done;
-
- TRACE("primary_done=%d, mixlen (primary) = %i\n", primary_done, mixlen);
+ dsb->leadin = FALSE;
- if (!mixlen)
- return primary_done;
+ TRACE("mixlen (primary) = %i\n", mixlen);
/* First try to mix to the end of the buffer if possible
* Theoretically it would allow for better optimization
*/
- if (mixlen + dsb->buf_mixpos >= dsb->tmp_buffer_len)
- {
- DWORD newmixed, mixfirst = dsb->tmp_buffer_len - dsb->buf_mixpos;
- newmixed = DSOUND_MixInBuffer(dsb, dsb->primary_mixpos, mixfirst);
- mixlen -= newmixed;
-
- if (dsb->playflags & DSBPLAY_LOOPING)
- while (newmixed && mixlen)
- {
- mixfirst = (dsb->tmp_buffer_len < mixlen ? dsb->tmp_buffer_len : mixlen);
- newmixed = DSOUND_MixInBuffer(dsb, dsb->primary_mixpos, mixfirst);
- mixlen -= newmixed;
- }
- }
- else DSOUND_MixInBuffer(dsb, dsb->primary_mixpos, mixlen);
+ primary_done += DSOUND_MixInBuffer(dsb, writepos, mixlen);
- /* re-calculate the primary done */
- primary_done = DSOUND_BufPtrDiff(dsb->device->buflen, dsb->primary_mixpos, writepos);
-
- TRACE("new primary_mixpos=%d, total mixed data=%d\n", dsb->primary_mixpos, primary_done);
+ TRACE("total mixed data=%d\n", primary_done);
/* Report back the total prebuffered amount for this buffer */
return primary_done;
* writepos = the current safe-to-write position in the primary buffer
* mixlen = the maximum amount to mix into the primary buffer
* (beyond the current writepos)
- * mustlock = Do we have to fight for lock because we otherwise risk an underrun?
* recover = true if the sound device may have been reset and the write
* position in the device buffer changed
* all_stopped = reports back if all buffers have stopped
* Returns: the length beyond the writepos that was mixed to.
*/
-static DWORD DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, DWORD mixlen, BOOL mustlock, BOOL recover, BOOL *all_stopped)
+static void DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos, DWORD mixlen, BOOL recover, BOOL *all_stopped)
{
- INT i, len;
- DWORD minlen = 0;
+ INT i;
IDirectSoundBufferImpl *dsb;
- BOOL gotall = TRUE;
/* unless we find a running buffer, all have stopped */
*all_stopped = TRUE;
TRACE("MixToPrimary for %p, state=%d\n", dsb, dsb->state);
- if (dsb->buflen && dsb->state && !dsb->hwbuf) {
+ if (dsb->buflen && dsb->state) {
TRACE("Checking %p, mixlen=%d\n", dsb, mixlen);
- if (!RtlAcquireResourceShared(&dsb->lock, mustlock))
- {
- gotall = FALSE;
- continue;
- }
+ RtlAcquireResourceShared(&dsb->lock, TRUE);
/* if buffer is stopping it is stopped now */
if (dsb->state == STATE_STOPPING) {
dsb->state = STATE_STOPPED;
DSOUND_CheckEvent(dsb, 0, 0);
} else if (dsb->state != STATE_STOPPED) {
- /* if recovering, reset the mix position */
- if ((dsb->state == STATE_STARTING) || recover) {
- dsb->primary_mixpos = writepos;
- }
-
/* if the buffer was starting, it must be playing now */
if (dsb->state == STATE_STARTING)
dsb->state = STATE_PLAYING;
/* mix next buffer into the main buffer */
- len = DSOUND_MixOne(dsb, writepos, mixlen);
-
- if (!minlen) minlen = len;
-
- /* record the minimum length mixed from all buffers */
- /* we only want to return the length which *all* buffers have mixed */
- else if (len) minlen = (len < minlen) ? len : minlen;
+ DSOUND_MixOne(dsb, writepos, mixlen);
*all_stopped = FALSE;
}
RtlReleaseResource(&dsb->lock);
}
}
-
- TRACE("Mixed at least %d from all buffers\n", minlen);
- if (!gotall) return 0;
- return minlen;
}
/**
static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force)
{
- DWORD prebuf_frags, wave_writepos, wave_fragpos, i;
- TRACE("(%p)\n", device);
+ DWORD prebuf_frames, prebuf_bytes, read_offs_bytes;
+ BYTE *buffer;
+ HRESULT hr;
- /* calculate the current wave frag position */
- wave_fragpos = (device->pwplay + device->pwqueue) % device->helfrags;
+ TRACE("(%p)\n", device);
- /* calculate the current wave write position */
- wave_writepos = wave_fragpos * device->fraglen;
+ read_offs_bytes = (device->playing_offs_bytes + device->in_mmdev_bytes) % device->buflen;
- TRACE("wave_fragpos = %i, wave_writepos = %i, pwqueue = %i, prebuf = %i\n",
- wave_fragpos, wave_writepos, device->pwqueue, device->prebuf);
+ TRACE("read_offs_bytes = %u, playing_offs_bytes = %u, in_mmdev_bytes: %u, prebuf = %u\n",
+ read_offs_bytes, device->playing_offs_bytes, device->in_mmdev_bytes, device->prebuf);
if (!force)
{
- /* check remaining prebuffered frags */
- prebuf_frags = device->mixpos / device->fraglen;
- if (prebuf_frags == device->helfrags)
- --prebuf_frags;
- TRACE("wave_fragpos = %d, mixpos_frags = %d\n", wave_fragpos, prebuf_frags);
- if (prebuf_frags < wave_fragpos)
- prebuf_frags += device->helfrags;
- prebuf_frags -= wave_fragpos;
- TRACE("wanted prebuf_frags = %d\n", prebuf_frags);
+ if(device->mixpos < device->playing_offs_bytes)
+ prebuf_bytes = device->mixpos + device->buflen - device->playing_offs_bytes;
+ else
+ prebuf_bytes = device->mixpos - device->playing_offs_bytes;
}
else
/* buffer the maximum amount of frags */
- prebuf_frags = device->prebuf;
+ prebuf_bytes = device->prebuf * device->fraglen;
/* limit to the queue we have left */
- if ((prebuf_frags + device->pwqueue) > device->prebuf)
- prebuf_frags = device->prebuf - device->pwqueue;
+ if(device->in_mmdev_bytes + prebuf_bytes > device->prebuf * device->fraglen)
+ prebuf_bytes = device->prebuf * device->fraglen - device->in_mmdev_bytes;
- TRACE("prebuf_frags = %i\n", prebuf_frags);
+ TRACE("prebuf_bytes = %u\n", prebuf_bytes);
- /* adjust queue */
- device->pwqueue += prebuf_frags;
+ if(!prebuf_bytes)
+ return;
- /* get out of CS when calling the wave system */
- LeaveCriticalSection(&(device->mixlock));
- /* **** */
+ device->in_mmdev_bytes += prebuf_bytes;
- /* queue up the new buffers */
- for(i=0; i<prebuf_frags; i++){
- TRACE("queueing wave buffer %i\n", wave_fragpos);
- waveOutWrite(device->hwo, &device->pwave[wave_fragpos], sizeof(WAVEHDR));
- wave_fragpos++;
- wave_fragpos %= device->helfrags;
+ if(prebuf_bytes + read_offs_bytes > device->buflen){
+ DWORD chunk_bytes = device->buflen - read_offs_bytes;
+ prebuf_frames = chunk_bytes / device->pwfx->nBlockAlign;
+ prebuf_bytes -= chunk_bytes;
+ }else{
+ prebuf_frames = prebuf_bytes / device->pwfx->nBlockAlign;
+ prebuf_bytes = 0;
}
- /* **** */
- EnterCriticalSection(&(device->mixlock));
+ hr = IAudioRenderClient_GetBuffer(device->render, prebuf_frames, &buffer);
+ if(FAILED(hr)){
+ WARN("GetBuffer failed: %08x\n", hr);
+ return;
+ }
+
+ memcpy(buffer, device->buffer + read_offs_bytes,
+ prebuf_frames * device->pwfx->nBlockAlign);
+
+ hr = IAudioRenderClient_ReleaseBuffer(device->render, prebuf_frames, 0);
+ if(FAILED(hr)){
+ WARN("ReleaseBuffer failed: %08x\n", hr);
+ return;
+ }
+
+ /* check if anything wrapped */
+ if(prebuf_bytes > 0){
+ prebuf_frames = prebuf_bytes / device->pwfx->nBlockAlign;
+
+ hr = IAudioRenderClient_GetBuffer(device->render, prebuf_frames, &buffer);
+ if(FAILED(hr)){
+ WARN("GetBuffer failed: %08x\n", hr);
+ return;
+ }
+
+ memcpy(buffer, device->buffer, prebuf_frames * device->pwfx->nBlockAlign);
+
+ hr = IAudioRenderClient_ReleaseBuffer(device->render, prebuf_frames, 0);
+ if(FAILED(hr)){
+ WARN("ReleaseBuffer failed: %08x\n", hr);
+ return;
+ }
+ }
- TRACE("queue now = %i\n", device->pwqueue);
+ TRACE("in_mmdev_bytes now = %i\n", device->in_mmdev_bytes);
}
/**
* Perform mixing for a Direct Sound device. That is, go through all the
* secondary buffers (the sound bites currently playing) and mix them in
* to the primary buffer (the device buffer).
+ *
+ * The mixing procedure goes:
+ *
+ * secondary->buffer (secondary format)
+ * =[Resample]=> device->tmp_buffer (float format)
+ * =[Volume]=> device->tmp_buffer (float format)
+ * =[Mix]=> device->mix_buffer (float format)
+ * =[Reformat]=> device->buffer (device format)
*/
static void DSOUND_PerformMix(DirectSoundDevice *device)
{
+ UINT32 pad, to_mix_frags, to_mix_bytes;
+ HRESULT hr;
+
TRACE("(%p)\n", device);
/* **** */
- EnterCriticalSection(&(device->mixlock));
+ EnterCriticalSection(&device->mixlock);
+
+ hr = IAudioClient_GetCurrentPadding(device->client, &pad);
+ if(FAILED(hr)){
+ WARN("GetCurrentPadding failed: %08x\n", hr);
+ LeaveCriticalSection(&device->mixlock);
+ return;
+ }
+
+ to_mix_frags = device->prebuf - (pad * device->pwfx->nBlockAlign + device->fraglen - 1) / device->fraglen;
+
+ to_mix_bytes = to_mix_frags * device->fraglen;
+
+ if(device->in_mmdev_bytes > 0){
+ DWORD delta_bytes = min(to_mix_bytes, device->in_mmdev_bytes);
+ device->in_mmdev_bytes -= delta_bytes;
+ device->playing_offs_bytes += delta_bytes;
+ device->playing_offs_bytes %= device->buflen;
+ }
if (device->priolevel != DSSCL_WRITEPRIMARY) {
BOOL recover = FALSE, all_stopped = FALSE;
- DWORD playpos, writepos, writelead, maxq, frag, prebuff_max, prebuff_left, size1, size2, mixplaypos, mixplaypos2;
+ DWORD playpos, writepos, writelead, maxq, prebuff_max, prebuff_left, size1, size2;
LPVOID buf1, buf2;
- BOOL lock = (device->hwbuf && !(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK));
- BOOL mustlock = FALSE;
int nfiller;
/* the sound of silence */
}
TRACE("primary playpos=%d, writepos=%d, clrpos=%d, mixpos=%d, buflen=%d\n",
- playpos,writepos,device->playpos,device->mixpos,device->buflen);
+ playpos,writepos,device->playpos,device->mixpos,device->buflen);
assert(device->playpos < device->buflen);
- mixplaypos = DSOUND_bufpos_to_mixpos(device, device->playpos);
- mixplaypos2 = DSOUND_bufpos_to_mixpos(device, playpos);
-
/* calc maximum prebuff */
prebuff_max = (device->prebuf * device->fraglen);
- if (!device->hwbuf && playpos + prebuff_max >= device->helfrags * device->fraglen)
- prebuff_max += device->buflen - device->helfrags * device->fraglen;
/* check how close we are to an underrun. It occurs when the writepos overtakes the mixpos */
prebuff_left = DSOUND_BufPtrDiff(device->buflen, device->mixpos, playpos);
/* reset mix position to write position */
device->mixpos = writepos;
- ZeroMemory(device->mix_buffer, device->mix_buffer_len);
ZeroMemory(device->buffer, device->buflen);
} else if (playpos < device->playpos) {
buf1 = device->buffer + device->playpos;
buf2 = device->buffer;
size1 = device->buflen - device->playpos;
size2 = playpos;
- FillMemory(device->mix_buffer + mixplaypos, device->mix_buffer_len - mixplaypos, 0);
- FillMemory(device->mix_buffer, mixplaypos2, 0);
- if (lock)
- IDsDriverBuffer_Lock(device->hwbuf, &buf1, &size1, &buf2, &size2, device->playpos, size1+size2, 0);
FillMemory(buf1, size1, nfiller);
if (playpos && (!buf2 || !size2))
FIXME("%d: (%d, %d)=>(%d, %d) There should be an additional buffer here!!\n", __LINE__, device->playpos, device->mixpos, playpos, writepos);
FillMemory(buf2, size2, nfiller);
- if (lock)
- IDsDriverBuffer_Unlock(device->hwbuf, buf1, size1, buf2, size2);
} else {
buf1 = device->buffer + device->playpos;
buf2 = NULL;
size1 = playpos - device->playpos;
size2 = 0;
- FillMemory(device->mix_buffer + mixplaypos, mixplaypos2 - mixplaypos, 0);
- if (lock)
- IDsDriverBuffer_Lock(device->hwbuf, &buf1, &size1, &buf2, &size2, device->playpos, size1+size2, 0);
FillMemory(buf1, size1, nfiller);
- if (buf2 && size2)
- {
- FIXME("%d: There should be no additional buffer here!!\n", __LINE__);
- FillMemory(buf2, size2, nfiller);
- }
- if (lock)
- IDsDriverBuffer_Unlock(device->hwbuf, buf1, size1, buf2, size2);
}
device->playpos = playpos;
TRACE("prebuff_left = %d, prebuff_max = %dx%d=%d, writelead=%d\n",
prebuff_left, device->prebuf, device->fraglen, prebuff_max, writelead);
- /* Do we risk an 'underrun' if we don't advance pointer? */
- if (writelead/device->fraglen <= ds_snd_queue_min || recover)
- mustlock = TRUE;
-
- if (lock)
- IDsDriverBuffer_Lock(device->hwbuf, &buf1, &size1, &buf2, &size2, writepos, maxq, 0);
+ ZeroMemory(device->mix_buffer, device->mix_buffer_len);
/* do the mixing */
- frag = DSOUND_MixToPrimary(device, writepos, maxq, mustlock, recover, &all_stopped);
+ DSOUND_MixToPrimary(device, writepos, maxq, recover, &all_stopped);
- if (frag + writepos > device->buflen)
+ if (maxq + writepos > device->buflen)
{
DWORD todo = device->buflen - writepos;
- device->normfunction(device->mix_buffer + DSOUND_bufpos_to_mixpos(device, writepos), device->buffer + writepos, todo);
- device->normfunction(device->mix_buffer, device->buffer, frag - todo);
+ DWORD offs_float = (todo / device->pwfx->nBlockAlign) * device->pwfx->nChannels;
+ device->normfunction(device->mix_buffer, device->buffer + writepos, todo);
+ device->normfunction(device->mix_buffer + offs_float, device->buffer, maxq - todo);
}
else
- device->normfunction(device->mix_buffer + DSOUND_bufpos_to_mixpos(device, writepos), device->buffer + writepos, frag);
+ device->normfunction(device->mix_buffer, device->buffer + writepos, maxq);
/* update the mix position, taking wrap-around into account */
- device->mixpos = writepos + frag;
+ device->mixpos = writepos + maxq;
device->mixpos %= device->buflen;
- if (lock)
- {
- DWORD frag2 = (frag > size1 ? frag - size1 : 0);
- frag -= frag2;
- if (frag2 > size2)
- {
- FIXME("Buffering too much! (%d, %d, %d, %d)\n", maxq, frag, size2, frag2 - size2);
- frag2 = size2;
- }
- IDsDriverBuffer_Unlock(device->hwbuf, buf1, frag, buf2, frag2);
- }
-
/* update prebuff left */
prebuff_left = DSOUND_BufPtrDiff(device->buflen, device->mixpos, playpos);
/* check if have a whole fragment */
if (prebuff_left >= device->fraglen){
- /* update the wave queue if using wave system */
- if (!device->hwbuf)
- DSOUND_WaveQueue(device, FALSE);
+ /* update the wave queue */
+ DSOUND_WaveQueue(device, FALSE);
/* buffers are full. start playing if applicable */
if(device->state == STATE_STARTING){
DSOUND_PrimaryStop(device);
}
- } else {
+ } else if (device->state != STATE_STOPPED) {
- /* update the wave queue if using wave system */
- if (!device->hwbuf)
- DSOUND_WaveQueue(device, TRUE);
- else
- /* Keep alsa happy, which needs GetPosition called once every 10 ms */
- IDsDriverBuffer_GetPosition(device->hwbuf, NULL, NULL);
+ DSOUND_WaveQueue(device, TRUE);
/* in the DSSCL_WRITEPRIMARY mode, the app is totally in charge... */
if (device->state == STATE_STARTING) {
/* **** */
}
-void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD_PTR dwUser,
- DWORD_PTR dw1, DWORD_PTR dw2)
+DWORD CALLBACK DSOUND_mixthread(void *p)
{
- DirectSoundDevice * device = (DirectSoundDevice*)dwUser;
- DWORD start_time = GetTickCount();
- DWORD end_time;
- TRACE("(%d,%d,0x%lx,0x%lx,0x%lx)\n",timerID,msg,dwUser,dw1,dw2);
- TRACE("entering at %d\n", start_time);
-
- if (DSOUND_renderer[device->drvdesc.dnDevNode] != device) {
- ERR("dsound died without killing us?\n");
- timeKillEvent(timerID);
- timeEndPeriod(DS_TIME_RES);
- return;
- }
-
- RtlAcquireResourceShared(&(device->buffer_list_lock), TRUE);
-
- if (device->ref)
- DSOUND_PerformMix(device);
-
- RtlReleaseResource(&(device->buffer_list_lock));
-
- end_time = GetTickCount();
- TRACE("completed processing at %d, duration = %d\n", end_time, end_time - start_time);
-}
-
-void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
-{
- DirectSoundDevice * device = (DirectSoundDevice*)dwUser;
- TRACE("(%p,%x,%lx,%lx,%lx)\n",hwo,msg,dwUser,dw1,dw2);
- TRACE("entering at %d, 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");
-
- /* check if packet completed from wave driver */
- if (msg == MM_WOM_DONE) {
-
- /* **** */
- EnterCriticalSection(&(device->mixlock));
-
- TRACE("done playing primary pos=%d\n", device->pwplay * device->fraglen);
-
- /* update playpos */
- device->pwplay++;
- device->pwplay %= device->helfrags;
-
- /* sanity */
- if(device->pwqueue == 0){
- ERR("Wave queue corrupted!\n");
- }
-
- /* update queue */
- device->pwqueue--;
-
- LeaveCriticalSection(&(device->mixlock));
- /* **** */
+ DirectSoundDevice *dev = p;
+ TRACE("(%p)\n", dev);
+
+ while (dev->ref) {
+ DWORD ret;
+
+ /*
+ * Some audio drivers are retarded and won't fire after being
+ * stopped, add a timeout to handle this.
+ */
+ ret = WaitForSingleObject(dev->sleepev, dev->sleeptime);
+ if (ret == WAIT_FAILED)
+ WARN("wait returned error %u %08x!\n", GetLastError(), GetLastError());
+ else if (ret != WAIT_OBJECT_0)
+ WARN("wait returned %08x!\n", ret);
+ if (!dev->ref)
+ break;
+
+ RtlAcquireResourceShared(&(dev->buffer_list_lock), TRUE);
+ DSOUND_PerformMix(dev);
+ RtlReleaseResource(&(dev->buffer_list_lock));
}
- TRACE("completed\n");
+ return 0;
}
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * TODO:
+ * When PrimarySetFormat (via ReopenDevice or PrimaryOpen) fails,
+ * it leaves dsound in unusable (not really open) state.
*/
#include <stdarg.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
-
+#define COBJMACROS
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
//#include "windef.h"
#include <mmddk.h>
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-/** Calculate how long a fragment length of about 10 ms should be in frames
- *
- * nSamplesPerSec: Frequency rate in samples per second
- * nBlockAlign: Size of a single blockalign
- *
- * Returns:
- * Size in bytes of a single fragment
- */
-DWORD DSOUND_fraglen(DWORD nSamplesPerSec, DWORD nBlockAlign)
+static DWORD DSOUND_fraglen(DirectSoundDevice *device)
{
- /* Given a timer delay of 10ms, the fragment size is approximately:
- * fraglen = (nSamplesPerSec * 10 / 1000) * nBlockAlign
- * ==> fraglen = (nSamplesPerSec / 100) * nBlockSize
- *
- * ALSA uses buffers that are powers of 2. Because of this, fraglen
- * is rounded up to the nearest power of 2:
- */
-
- if (nSamplesPerSec <= 12800)
- return 128 * nBlockAlign;
-
- if (nSamplesPerSec <= 25600)
- return 256 * nBlockAlign;
-
- if (nSamplesPerSec <= 51200)
- return 512 * nBlockAlign;
-
- return 1024 * nBlockAlign;
+ REFERENCE_TIME period;
+ HRESULT hr;
+ DWORD ret;
+
+ hr = IAudioClient_GetDevicePeriod(device->client, &period, NULL);
+ if(FAILED(hr)){
+ /* just guess at 10ms */
+ WARN("GetDevicePeriod failed: %08x\n", hr);
+ ret = MulDiv(device->pwfx->nBlockAlign, device->pwfx->nSamplesPerSec, 100);
+ }else
+ ret = MulDiv(device->pwfx->nSamplesPerSec * device->pwfx->nBlockAlign, period, 10000000);
+
+ ret -= ret % device->pwfx->nBlockAlign;
+ return ret;
}
-static void DSOUND_RecalcPrimary(DirectSoundDevice *device)
+static HRESULT DSOUND_WaveFormat(DirectSoundDevice *device, IAudioClient *client,
+ BOOL forcewave, WAVEFORMATEX **wfx)
{
- TRACE("(%p)\n", device);
-
- device->fraglen = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
- device->helfrags = device->buflen / device->fraglen;
- TRACE("fraglen=%d helfrags=%d\n", device->fraglen, device->helfrags);
+ WAVEFORMATEXTENSIBLE *retwfe = NULL;
+ WAVEFORMATEX *w;
+ HRESULT hr;
+
+ if (!forcewave) {
+ WAVEFORMATEXTENSIBLE *mixwfe;
+ hr = IAudioClient_GetMixFormat(client, (WAVEFORMATEX**)&mixwfe);
+
+ if (FAILED(hr))
+ return hr;
+
+ if (mixwfe->Format.nChannels > 2) {
+ static int once;
+ if (!once++)
+ FIXME("Limiting channels to 2 due to lack of multichannel support\n");
+
+ mixwfe->Format.nChannels = 2;
+ mixwfe->Format.nBlockAlign = mixwfe->Format.nChannels * mixwfe->Format.wBitsPerSample / 8;
+ mixwfe->Format.nAvgBytesPerSec = mixwfe->Format.nSamplesPerSec * mixwfe->Format.nBlockAlign;
+ mixwfe->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ }
- if (device->hwbuf && device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD)
- device->writelead = 0;
- else
- /* calculate the 10ms write lead */
- device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;
+ if (!IsEqualGUID(&mixwfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
+ WAVEFORMATEXTENSIBLE testwfe = *mixwfe;
+
+ testwfe.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+ testwfe.Samples.wValidBitsPerSample = testwfe.Format.wBitsPerSample = 32;
+ testwfe.Format.nBlockAlign = testwfe.Format.nChannels * testwfe.Format.wBitsPerSample / 8;
+ testwfe.Format.nAvgBytesPerSec = testwfe.Format.nSamplesPerSec * testwfe.Format.nBlockAlign;
+
+ if (FAILED(IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &testwfe.Format, (WAVEFORMATEX**)&retwfe)))
+ w = DSOUND_CopyFormat(&mixwfe->Format);
+ else if (retwfe)
+ w = DSOUND_CopyFormat(&retwfe->Format);
+ else
+ w = DSOUND_CopyFormat(&testwfe.Format);
+ CoTaskMemFree(retwfe);
+ retwfe = NULL;
+ } else
+ w = DSOUND_CopyFormat(&mixwfe->Format);
+ CoTaskMemFree(mixwfe);
+ } else if (device->primary_pwfx->wFormatTag == WAVE_FORMAT_PCM ||
+ device->primary_pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
+ WAVEFORMATEX *wi = device->primary_pwfx;
+ WAVEFORMATEXTENSIBLE *wfe;
+
+ /* Convert to WAVEFORMATEXTENSIBLE */
+ w = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEXTENSIBLE));
+ wfe = (WAVEFORMATEXTENSIBLE*)w;
+ if (!wfe)
+ return DSERR_OUTOFMEMORY;
+
+ wfe->Format = *wi;
+ w->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ w->cbSize = sizeof(*wfe) - sizeof(*w);
+ w->nBlockAlign = w->nChannels * w->wBitsPerSample / 8;
+ w->nAvgBytesPerSec = w->nSamplesPerSec * w->nBlockAlign;
+
+ wfe->dwChannelMask = 0;
+ if (wi->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
+ w->wBitsPerSample = 32;
+ wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+ } else
+ wfe->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ wfe->Samples.wValidBitsPerSample = w->wBitsPerSample;
+ } else
+ w = DSOUND_CopyFormat(device->primary_pwfx);
+
+ if (!w)
+ return DSERR_OUTOFMEMORY;
+
+ hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, w, (WAVEFORMATEX**)&retwfe);
+ if (retwfe) {
+ memcpy(w, retwfe, sizeof(WAVEFORMATEX) + retwfe->Format.cbSize);
+ CoTaskMemFree(retwfe);
+ }
+ if (FAILED(hr)) {
+ WARN("IsFormatSupported failed: %08x\n", hr);
+ HeapFree(GetProcessHeap(), 0, w);
+ return hr;
+ }
+ *wfx = w;
+ return S_OK;
}
HRESULT DSOUND_ReopenDevice(DirectSoundDevice *device, BOOL forcewave)
{
- HRESULT hres = DS_OK;
- TRACE("(%p, %d)\n", device, forcewave);
-
- if (device->driver)
- {
- IDsDriver_Close(device->driver);
- if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(device->hwo);
- IDsDriver_Release(device->driver);
- device->driver = NULL;
- device->buffer = NULL;
- device->hwo = 0;
- }
- else if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(device->hwo);
-
- /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
- if (ds_hw_accel != DS_HW_ACCEL_EMULATION && !forcewave)
- waveOutMessage((HWAVEOUT)device->drvdesc.dnDevNode, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0);
-
- /* Get driver description */
- if (device->driver) {
- DWORD wod = device->drvdesc.dnDevNode;
- hres = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc));
- device->drvdesc.dnDevNode = wod;
- if (FAILED(hres)) {
- WARN("IDsDriver_GetDriverDesc failed: %08x\n", hres);
- IDsDriver_Release(device->driver);
- device->driver = NULL;
- }
- }
+ UINT prebuf_frames;
+ REFERENCE_TIME prebuf_rt;
+ WAVEFORMATEX *wfx = NULL;
+ HRESULT hres;
+ REFERENCE_TIME period;
+ DWORD period_ms;
+
+ TRACE("(%p, %d)\n", device, forcewave);
+
+ if(device->client){
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ }
+ if(device->render){
+ IAudioRenderClient_Release(device->render);
+ device->render = NULL;
+ }
+ if(device->clock){
+ IAudioClock_Release(device->clock);
+ device->clock = NULL;
+ }
+ if(device->volume){
+ IAudioStreamVolume_Release(device->volume);
+ device->volume = NULL;
+ }
- /* if no DirectSound interface available, use WINMM API instead */
- if (!device->driver)
- device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
+ hres = IMMDevice_Activate(device->mmdevice, &IID_IAudioClient,
+ CLSCTX_INPROC_SERVER, NULL, (void **)&device->client);
+ if(FAILED(hres)) {
+ WARN("Activate failed: %08x\n", hres);
+ return hres;
+ }
- if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- {
- DWORD flags = CALLBACK_FUNCTION;
+ hres = DSOUND_WaveFormat(device, device->client, forcewave, &wfx);
+ if (FAILED(hres)) {
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ return hres;
+ }
+ HeapFree(GetProcessHeap(), 0, device->pwfx);
+ device->pwfx = wfx;
+
+ prebuf_frames = device->prebuf * DSOUND_fraglen(device) / device->pwfx->nBlockAlign;
+ prebuf_rt = (10000000 * (UINT64)prebuf_frames) / device->pwfx->nSamplesPerSec;
+
+ hres = IAudioClient_Initialize(device->client,
+ AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_NOPERSIST |
+ AUDCLNT_STREAMFLAGS_EVENTCALLBACK, prebuf_rt, 0, device->pwfx, NULL);
+ if(FAILED(hres)){
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ WARN("Initialize failed: %08x\n", hres);
+ return hres;
+ }
+ IAudioClient_SetEventHandle(device->client, device->sleepev);
+
+ hres = IAudioClient_GetService(device->client, &IID_IAudioRenderClient,
+ (void**)&device->render);
+ if(FAILED(hres)){
+ IAudioClient_Release(device->client);
+ device->client = NULL;
+ WARN("GetService failed: %08x\n", hres);
+ return hres;
+ }
- if (device->driver)
- flags |= WAVE_DIRECTSOUND;
+ hres = IAudioClient_GetService(device->client, &IID_IAudioClock,
+ (void**)&device->clock);
+ if(FAILED(hres)){
+ IAudioClient_Release(device->client);
+ IAudioRenderClient_Release(device->render);
+ device->client = NULL;
+ device->render = NULL;
+ WARN("GetService failed: %08x\n", hres);
+ return hres;
+ }
- hres = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode, device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD_PTR)device, flags));
- if (FAILED(hres)) {
- WARN("waveOutOpen failed\n");
- if (device->driver)
- {
- IDsDriver_Release(device->driver);
- device->driver = NULL;
- }
- return hres;
- }
- }
+ hres = IAudioClient_GetService(device->client, &IID_IAudioStreamVolume,
+ (void**)&device->volume);
+ if(FAILED(hres)){
+ IAudioClient_Release(device->client);
+ IAudioRenderClient_Release(device->render);
+ IAudioClock_Release(device->clock);
+ device->client = NULL;
+ device->render = NULL;
+ device->clock = NULL;
+ WARN("GetService failed: %08x\n", hres);
+ return hres;
+ }
- if (device->driver)
- hres = IDsDriver_Open(device->driver);
+ /* Now kick off the timer so the event fires periodically */
+ hres = IAudioClient_Start(device->client);
+ if (FAILED(hres))
+ WARN("starting failed with %08x\n", hres);
+
+ hres = IAudioClient_GetStreamLatency(device->client, &period);
+ if (FAILED(hres)) {
+ WARN("GetStreamLatency failed with %08x\n", hres);
+ period_ms = 10;
+ } else
+ period_ms = (period + 9999) / 10000;
+ TRACE("period %u ms fraglen %u prebuf %u\n", period_ms, device->fraglen, device->prebuf);
+
+ if (period_ms < 3)
+ device->sleeptime = 5;
+ else
+ device->sleeptime = period_ms * 5 / 2;
- return hres;
+ return S_OK;
}
-static HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
+HRESULT DSOUND_PrimaryOpen(DirectSoundDevice *device)
{
- DWORD buflen;
- HRESULT err = DS_OK;
+ IDirectSoundBufferImpl** dsb = device->buffers;
+ LPBYTE newbuf;
+ int i;
+
TRACE("(%p)\n", device);
+ device->fraglen = DSOUND_fraglen(device);
+
/* on original windows, the buffer it set to a fixed size, no matter what the settings are.
on windows this size is always fixed (tested on win-xp) */
if (!device->buflen)
device->buflen = ds_hel_buflen;
- buflen = device->buflen;
- buflen -= buflen % device->pwfx->nBlockAlign;
- device->buflen = buflen;
-
- if (device->driver)
- {
- err = IDsDriver_CreateSoundBuffer(device->driver,device->pwfx,
- DSBCAPS_PRIMARYBUFFER,0,
- &(device->buflen),&(device->buffer),
- (LPVOID*)&(device->hwbuf));
-
- if (err != DS_OK) {
- WARN("IDsDriver_CreateSoundBuffer failed (%08x), falling back to waveout\n", err);
- err = DSOUND_ReopenDevice(device, TRUE);
- if (FAILED(err))
- {
- WARN("Falling back to waveout failed too! Giving up\n");
- return err;
- }
- }
- if (device->hwbuf)
- IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
-
- DSOUND_RecalcPrimary(device);
- device->prebuf = ds_snd_queue_max;
- if (device->helfrags < ds_snd_queue_min)
- {
- WARN("Too little sound buffer to be effective (%d/%d) falling back to waveout\n", device->buflen, ds_snd_queue_min * device->fraglen);
- device->buflen = buflen;
- IDsDriverBuffer_Release(device->hwbuf);
- device->hwbuf = NULL;
- err = DSOUND_ReopenDevice(device, TRUE);
- if (FAILED(err))
- {
- WARN("Falling back to waveout failed too! Giving up\n");
- return err;
- }
- }
- else if (device->helfrags < ds_snd_queue_max)
- device->prebuf = device->helfrags;
+ device->buflen -= device->buflen % device->pwfx->nBlockAlign;
+ while(device->buflen < device->fraglen * device->prebuf){
+ device->buflen += ds_hel_buflen;
+ device->buflen -= device->buflen % device->pwfx->nBlockAlign;
}
- device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
- device->mix_buffer = HeapAlloc(GetProcessHeap(), 0, device->mix_buffer_len);
+ HeapFree(GetProcessHeap(), 0, device->mix_buffer);
+ device->mix_buffer_len = (device->buflen / (device->pwfx->wBitsPerSample / 8)) * sizeof(float);
+ device->mix_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, device->mix_buffer_len);
if (!device->mix_buffer)
- {
- if (device->hwbuf)
- IDsDriverBuffer_Release(device->hwbuf);
- device->hwbuf = NULL;
return DSERR_OUTOFMEMORY;
- }
if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
- /* are we using waveOut stuff? */
- if (!device->driver) {
- LPBYTE newbuf;
- LPWAVEHDR headers = NULL;
- DWORD overshot;
- unsigned int c;
+ /* reallocate emulated primary buffer */
+ if (device->buffer)
+ newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer, device->buflen);
+ else
+ newbuf = HeapAlloc(GetProcessHeap(),0, device->buflen);
- /* Start in pause mode, to allow buffers to get filled */
- waveOutPause(device->hwo);
+ if (!newbuf) {
+ ERR("failed to allocate primary buffer\n");
+ return DSERR_OUTOFMEMORY;
+ /* but the old buffer might still exist and must be re-prepared */
+ }
- TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
+ device->writelead = (device->pwfx->nSamplesPerSec / 100) * device->pwfx->nBlockAlign;
- /* reallocate emulated primary buffer */
- if (device->buffer)
- newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer, buflen);
- else
- newbuf = HeapAlloc(GetProcessHeap(),0, buflen);
+ device->buffer = newbuf;
- if (!newbuf) {
- ERR("failed to allocate primary buffer\n");
- return DSERR_OUTOFMEMORY;
- /* but the old buffer might still exist and must be re-prepared */
- }
+ TRACE("buflen: %u, fraglen: %u, mix_buffer_len: %u\n",
+ device->buflen, device->fraglen, device->mix_buffer_len);
- DSOUND_RecalcPrimary(device);
- if (device->pwave)
- headers = HeapReAlloc(GetProcessHeap(),0,device->pwave, device->helfrags * sizeof(WAVEHDR));
- else
- headers = HeapAlloc(GetProcessHeap(),0,device->helfrags * sizeof(WAVEHDR));
+ if(device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
+ (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat,
+ &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
+ device->normfunction = normfunctions[4];
+ else
+ device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
- if (!headers) {
- ERR("failed to allocate wave headers\n");
- HeapFree(GetProcessHeap(), 0, newbuf);
- DSOUND_RecalcPrimary(device);
- return DSERR_OUTOFMEMORY;
- }
+ FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
+ FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
+ device->playpos = 0;
- device->buffer = newbuf;
- device->pwave = headers;
-
- /* prepare fragment headers */
- for (c=0; c<device->helfrags; c++) {
- device->pwave[c].lpData = (char*)device->buffer + c*device->fraglen;
- device->pwave[c].dwBufferLength = device->fraglen;
- device->pwave[c].dwUser = (DWORD_PTR)device;
- device->pwave[c].dwFlags = 0;
- device->pwave[c].dwLoops = 0;
- err = mmErr(waveOutPrepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR)));
- if (err != DS_OK) {
- while (c--)
- waveOutUnprepareHeader(device->hwo,&device->pwave[c],sizeof(WAVEHDR));
- break;
- }
- }
+ if (device->pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ||
+ (device->pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUID(&((WAVEFORMATEXTENSIBLE*)device->pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
+ device->normfunction = normfunctions[4];
+ else
+ device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
- overshot = device->buflen % device->fraglen;
- /* sanity */
- if(overshot)
- {
- overshot -= overshot % device->pwfx->nBlockAlign;
- device->pwave[device->helfrags - 1].dwBufferLength += overshot;
- }
+ for (i = 0; i < device->nrofbuffers; i++) {
+ RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE);
+ DSOUND_RecalcFormat(dsb[i]);
+ RtlReleaseResource(&dsb[i]->lock);
+ }
- TRACE("fraglen=%d, overshot=%d\n", device->fraglen, overshot);
- }
- device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
- device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
- FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
- FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
- device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
- return err;
+ return DS_OK;
}
static void DSOUND_PrimaryClose(DirectSoundDevice *device)
{
- TRACE("(%p)\n", device);
+ HRESULT hr;
- /* are we using waveOut stuff? */
- if (!device->hwbuf) {
- unsigned c;
+ TRACE("(%p)\n", device);
- /* get out of CS when calling the wave system */
- LeaveCriticalSection(&(device->mixlock));
- /* **** */
- device->pwqueue = (DWORD)-1; /* resetting queues */
- waveOutReset(device->hwo);
- for (c=0; c<device->helfrags; c++)
- waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR));
- /* **** */
- EnterCriticalSection(&(device->mixlock));
-
- /* clear the queue */
- device->pwqueue = 0;
- } else {
- ULONG ref = IDsDriverBuffer_Release(device->hwbuf);
- if (!ref)
- device->hwbuf = 0;
- else
- ERR("Still %d references on primary buffer, refcount leak?\n", ref);
- }
+ if(device->client){
+ hr = IAudioClient_Stop(device->client);
+ if(FAILED(hr))
+ WARN("Stop failed: %08x\n", hr);
+ }
+
+ /* clear the queue */
+ device->in_mmdev_bytes = 0;
}
HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device)
EnterCriticalSection(&(device->mixlock));
DSOUND_PrimaryClose(device);
- if (device->driver) {
- if (device->hwbuf) {
- if (IDsDriverBuffer_Release(device->hwbuf) == 0)
- device->hwbuf = 0;
- }
- } else
- HeapFree(GetProcessHeap(),0,device->pwave);
- HeapFree(GetProcessHeap(),0,device->pwfx);
- device->pwfx=NULL;
+
+ if(device->primary && (device->primary->ref || device->primary->numIfaces))
+ WARN("Destroying primary buffer while references held (%u %u)\n", device->primary->ref, device->primary->numIfaces);
+
+ HeapFree(GetProcessHeap(), 0, device->primary);
+ device->primary = NULL;
+
+ HeapFree(GetProcessHeap(),0,device->primary_pwfx);
+ HeapFree(GetProcessHeap(),0,device->pwfx);
+ device->pwfx=NULL;
LeaveCriticalSection(&(device->mixlock));
/* **** */
HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device)
{
- HRESULT err = DS_OK;
- TRACE("(%p)\n", device);
+ HRESULT hr;
- if (device->hwbuf) {
- err = IDsDriverBuffer_Play(device->hwbuf, 0, 0, DSBPLAY_LOOPING);
- if (err != DS_OK)
- WARN("IDsDriverBuffer_Play failed\n");
- } else {
- err = mmErr(waveOutRestart(device->hwo));
- if (err != DS_OK)
- WARN("waveOutRestart failed\n");
- }
+ TRACE("(%p)\n", device);
- return err;
+ hr = IAudioClient_Start(device->client);
+ if(FAILED(hr) && hr != AUDCLNT_E_NOT_STOPPED){
+ WARN("Start failed: %08x\n", hr);
+ return hr;
+ }
+
+ return DS_OK;
}
HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device)
{
- HRESULT err = DS_OK;
- TRACE("(%p)\n", device);
-
- if (device->hwbuf) {
- err = IDsDriverBuffer_Stop(device->hwbuf);
- if (err == DSERR_BUFFERLOST) {
- DSOUND_PrimaryClose(device);
- err = DSOUND_ReopenDevice(device, FALSE);
- if (FAILED(err))
- ERR("DSOUND_ReopenDevice failed\n");
- else
- {
- err = DSOUND_PrimaryOpen(device);
- if (FAILED(err))
- WARN("DSOUND_PrimaryOpen failed\n");
- }
- } else if (err != DS_OK) {
- WARN("IDsDriverBuffer_Stop failed\n");
- }
- } else {
-
- /* don't call the wave system with the lock set */
- LeaveCriticalSection(&(device->mixlock));
- /* **** */
+ HRESULT hr;
- err = mmErr(waveOutPause(device->hwo));
-
- /* **** */
- EnterCriticalSection(&(device->mixlock));
+ TRACE("(%p)\n", device);
- if (err != DS_OK)
- WARN("waveOutPause failed\n");
- }
+ hr = IAudioClient_Stop(device->client);
+ if(FAILED(hr)){
+ WARN("Stop failed: %08x\n", hr);
+ return hr;
+ }
- return err;
+ return DS_OK;
}
HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos)
{
TRACE("(%p,%p,%p)\n", device, playpos, writepos);
- if (device->hwbuf) {
- HRESULT err=IDsDriverBuffer_GetPosition(device->hwbuf,playpos,writepos);
- if (err != S_OK) {
- WARN("IDsDriverBuffer_GetPosition failed\n");
- return err;
- }
- } else {
- TRACE("pwplay=%i, pwqueue=%i\n", device->pwplay, device->pwqueue);
+ /* check if playpos was requested */
+ if (playpos)
+ *playpos = device->playing_offs_bytes;
- /* check if playpos was requested */
- if (playpos)
- /* use the cached play position */
- *playpos = device->pwplay * device->fraglen;
+ /* check if writepos was requested */
+ if (writepos)
+ /* the writepos is the first non-queued position */
+ *writepos = (device->playing_offs_bytes + device->in_mmdev_bytes) % device->buflen;
- /* check if writepos was requested */
- if (writepos)
- /* the writepos is the first non-queued position */
- *writepos = ((device->pwplay + device->pwqueue) % device->helfrags) * device->fraglen;
- }
TRACE("playpos = %d, writepos = %d (%p, time=%d)\n", playpos?*playpos:-1, writepos?*writepos:-1, device, GetTickCount());
return DS_OK;
}
-HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex, BOOL forced)
+static DWORD DSOUND_GetFormatSize(LPCWAVEFORMATEX wfex)
{
- HRESULT err = DSERR_BUFFERLOST;
- int i, alloc_size, cp_size;
- DWORD nSamplesPerSec, bpp, chans;
- TRACE("(%p,%p)\n", device, wfex);
+ if (wfex->wFormatTag == WAVE_FORMAT_PCM)
+ return sizeof(WAVEFORMATEX);
+ else
+ return sizeof(WAVEFORMATEX) + wfex->cbSize;
+}
+
+LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex)
+{
+ DWORD size = DSOUND_GetFormatSize(wfex);
+ LPWAVEFORMATEX pwfx = HeapAlloc(GetProcessHeap(),0,size);
+ if (pwfx == NULL) {
+ WARN("out of memory\n");
+ } else if (wfex->wFormatTag != WAVE_FORMAT_PCM) {
+ CopyMemory(pwfx, wfex, size);
+ } else {
+ CopyMemory(pwfx, wfex, sizeof(PCMWAVEFORMAT));
+ pwfx->cbSize=0;
+ if (pwfx->nBlockAlign != pwfx->nChannels * pwfx->wBitsPerSample/8) {
+ WARN("Fixing bad nBlockAlign (%u)\n", pwfx->nBlockAlign);
+ pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample/8;
+ }
+ if (pwfx->nAvgBytesPerSec != pwfx->nSamplesPerSec * pwfx->nBlockAlign) {
+ WARN("Fixing bad nAvgBytesPerSec (%u)\n", pwfx->nAvgBytesPerSec);
+ pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;
+ }
+ }
+ return pwfx;
+}
+
+HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX passed_fmt)
+{
+ HRESULT err = S_OK;
+ WAVEFORMATEX *old_fmt;
+ WAVEFORMATEXTENSIBLE *fmtex, *passed_fmtex = (WAVEFORMATEXTENSIBLE*)passed_fmt;
+ BOOL forced = (device->priolevel == DSSCL_WRITEPRIMARY);
+
+ TRACE("(%p,%p)\n", device, passed_fmt);
if (device->priolevel == DSSCL_NORMAL) {
WARN("failed priority check!\n");
}
/* Let's be pedantic! */
- if (wfex == NULL) {
- WARN("invalid parameter: wfex==NULL!\n");
+ if (passed_fmt == NULL) {
+ WARN("invalid parameter: passed_fmt==NULL!\n");
return DSERR_INVALIDPARAM;
}
TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
- "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
- wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
- wfex->nAvgBytesPerSec, wfex->nBlockAlign,
- wfex->wBitsPerSample, wfex->cbSize);
+ "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
+ passed_fmt->wFormatTag, passed_fmt->nChannels, passed_fmt->nSamplesPerSec,
+ passed_fmt->nAvgBytesPerSec, passed_fmt->nBlockAlign,
+ passed_fmt->wBitsPerSample, passed_fmt->cbSize);
+
+ if(passed_fmt->wBitsPerSample < 8 || passed_fmt->wBitsPerSample % 8 != 0 ||
+ passed_fmt->nChannels == 0 || passed_fmt->nSamplesPerSec == 0 ||
+ passed_fmt->nAvgBytesPerSec == 0 ||
+ passed_fmt->nBlockAlign != passed_fmt->nChannels * passed_fmt->wBitsPerSample / 8)
+ return DSERR_INVALIDPARAM;
+
+ if(passed_fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE){
+ if(passed_fmtex->Samples.wValidBitsPerSample > passed_fmtex->Format.wBitsPerSample)
+ return DSERR_INVALIDPARAM;
+ }
/* **** */
RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
EnterCriticalSection(&(device->mixlock));
- if (wfex->wFormatTag == WAVE_FORMAT_PCM) {
- alloc_size = sizeof(WAVEFORMATEX);
- cp_size = sizeof(PCMWAVEFORMAT);
- } else
- alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize;
-
- device->pwfx = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,device->pwfx,alloc_size);
-
- nSamplesPerSec = device->pwfx->nSamplesPerSec;
- bpp = device->pwfx->wBitsPerSample;
- chans = device->pwfx->nChannels;
-
- CopyMemory(device->pwfx, wfex, cp_size);
-
- if (!(device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) && device->hwbuf) {
- err = IDsDriverBuffer_SetFormat(device->hwbuf, device->pwfx);
-
- /* On bad format, try to re-create, big chance it will work then, only do this if we <HAVE> to */
- if (forced && (device->pwfx->nSamplesPerSec/100 != wfex->nSamplesPerSec/100 || err == DSERR_BADFORMAT))
- {
- err = DSERR_BUFFERLOST;
- CopyMemory(device->pwfx, wfex, cp_size);
+ if (device->priolevel == DSSCL_WRITEPRIMARY) {
+ old_fmt = device->primary_pwfx;
+ device->primary_pwfx = DSOUND_CopyFormat(passed_fmt);
+ fmtex = (WAVEFORMATEXTENSIBLE *)device->primary_pwfx;
+ if (device->primary_pwfx == NULL) {
+ err = DSERR_OUTOFMEMORY;
+ goto out;
}
- if (err != DSERR_BUFFERLOST && FAILED(err)) {
- WARN("IDsDriverBuffer_SetFormat failed\n");
- if (!forced)
- err = DS_OK;
- goto done;
+ if (fmtex->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ fmtex->Samples.wValidBitsPerSample == 0) {
+ TRACE("Correcting 0 valid bits per sample\n");
+ fmtex->Samples.wValidBitsPerSample = fmtex->Format.wBitsPerSample;
}
- if (err == S_FALSE)
- {
- /* ALSA specific: S_FALSE tells that recreation was successful,
- * but size and location may be changed, and buffer has to be restarted
- * I put it here, so if frequency doesn't match the error will be changed to DSERR_BUFFERLOST
- * and the entire re-initialization will occur anyway
- */
- IDsDriverBuffer_Lock(device->hwbuf, (LPVOID *)&device->buffer, &device->buflen, NULL, NULL, 0, 0, DSBLOCK_ENTIREBUFFER);
- IDsDriverBuffer_Unlock(device->hwbuf, device->buffer, 0, NULL, 0);
-
- if (device->state == STATE_PLAYING) device->state = STATE_STARTING;
- else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;
- device->pwplay = device->pwqueue = device->playpos = device->mixpos = 0;
- err = DS_OK;
- }
- DSOUND_RecalcPrimary(device);
- }
-
- if (err == DSERR_BUFFERLOST)
- {
DSOUND_PrimaryClose(device);
- err = DSOUND_ReopenDevice(device, FALSE);
- if (FAILED(err))
- {
- WARN("DSOUND_ReopenDevice failed: %08x\n", err);
+ err = DSOUND_ReopenDevice(device, forced);
+ if (FAILED(err)) {
+ ERR("No formats could be opened\n");
goto done;
}
+
err = DSOUND_PrimaryOpen(device);
if (err != DS_OK) {
- WARN("DSOUND_PrimaryOpen failed\n");
+ ERR("DSOUND_PrimaryOpen failed\n");
goto done;
}
- if (wfex->nSamplesPerSec/100 != device->pwfx->nSamplesPerSec/100 && forced && device->buffer)
- {
- DSOUND_PrimaryClose(device);
- device->pwfx->nSamplesPerSec = wfex->nSamplesPerSec;
- err = DSOUND_ReopenDevice(device, TRUE);
- if (FAILED(err))
- WARN("DSOUND_ReopenDevice(2) failed: %08x\n", err);
- else if (FAILED((err = DSOUND_PrimaryOpen(device))))
- WARN("DSOUND_PrimaryOpen(2) failed: %08x\n", err);
- }
- }
-
- device->mix_buffer_len = DSOUND_bufpos_to_mixpos(device, device->buflen);
- device->mix_buffer = HeapReAlloc(GetProcessHeap(), 0, device->mix_buffer, device->mix_buffer_len);
- FillMemory(device->mix_buffer, device->mix_buffer_len, 0);
- device->mixfunction = mixfunctions[device->pwfx->wBitsPerSample/8 - 1];
- device->normfunction = normfunctions[device->pwfx->wBitsPerSample/8 - 1];
-
- if (nSamplesPerSec != device->pwfx->nSamplesPerSec || bpp != device->pwfx->wBitsPerSample || chans != device->pwfx->nChannels) {
- IDirectSoundBufferImpl** dsb = device->buffers;
- for (i = 0; i < device->nrofbuffers; i++, dsb++) {
- /* **** */
- RtlAcquireResourceExclusive(&(*dsb)->lock, TRUE);
-
- (*dsb)->freqAdjust = ((DWORD64)(*dsb)->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
- DSOUND_RecalcFormat((*dsb));
- DSOUND_MixToTemporary((*dsb), 0, (*dsb)->buflen, FALSE);
- (*dsb)->primary_mixpos = 0;
-
- RtlReleaseResource(&(*dsb)->lock);
- /* **** */
+done:
+ if (err != DS_OK)
+ device->primary_pwfx = old_fmt;
+ else
+ HeapFree(GetProcessHeap(), 0, old_fmt);
+ } else if (passed_fmt->wFormatTag == WAVE_FORMAT_PCM ||
+ passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
+ /* Fill in "real" values to primary_pwfx */
+ WAVEFORMATEX *fmt = device->primary_pwfx;
+
+ *fmt = *device->pwfx;
+ fmtex = (void*)device->pwfx;
+
+ if (IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) &&
+ passed_fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {
+ fmt->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
+ } else {
+ fmt->wFormatTag = WAVE_FORMAT_PCM;
+ fmt->wBitsPerSample = 16;
}
+ fmt->nBlockAlign = fmt->nChannels * fmt->wBitsPerSample / 8;
+ fmt->nAvgBytesPerSec = fmt->nBlockAlign * fmt->nSamplesPerSec;
+ fmt->cbSize = 0;
+ } else {
+ device->primary_pwfx = HeapReAlloc(GetProcessHeap(), 0, device->primary_pwfx, sizeof(*fmtex));
+ memcpy(device->primary_pwfx, device->pwfx, sizeof(*fmtex));
}
-done:
+out:
LeaveCriticalSection(&(device->mixlock));
RtlReleaseResource(&(device->buffer_list_lock));
/* **** */
/*******************************************************************************
* PrimaryBuffer
*/
-/* This sets this format for the <em>Primary Buffer Only</em> */
-/* See file:///cdrom/sdk52/docs/worddoc/dsound.doc page 120 */
-static HRESULT WINAPI PrimaryBufferImpl_SetFormat(
- LPDIRECTSOUNDBUFFER iface,
- LPCWAVEFORMATEX wfex)
+static inline IDirectSoundBufferImpl *impl_from_IDirectSoundBuffer(IDirectSoundBuffer *iface)
+{
+ /* IDirectSoundBuffer and IDirectSoundBuffer8 use the same iface. */
+ return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSoundBuffer8_iface);
+}
+
+/* This sets this format for the primary buffer only */
+static HRESULT WINAPI PrimaryBufferImpl_SetFormat(IDirectSoundBuffer *iface,
+ const WAVEFORMATEX *wfex)
{
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
TRACE("(%p,%p)\n", iface, wfex);
- return DSOUND_PrimarySetFormat(device, wfex, device->priolevel == DSSCL_WRITEPRIMARY);
+ return primarybuffer_SetFormat(This->device, wfex);
}
-static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
- LPDIRECTSOUNDBUFFER iface,LONG vol
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
- DWORD ampfactors;
- HRESULT hres = DS_OK;
+static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LONG vol)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
+ HRESULT hr;
+ float lvol, rvol;
+
TRACE("(%p,%d)\n", iface, vol);
- if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
+ if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
WARN("control unavailable\n");
return DSERR_CONTROLUNAVAIL;
}
}
/* **** */
- EnterCriticalSection(&(device->mixlock));
+ EnterCriticalSection(&device->mixlock);
- waveOutGetVolume(device->hwo, &factors);
- device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
- device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
- DSOUND_AmpFactorToVolPan(&device->volpan);
- if (vol != device->volpan.lVolume) {
- device->volpan.lVolume=vol;
- DSOUND_RecalcVolPan(&device->volpan);
- if (device->hwbuf) {
- hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_SetVolumePan failed\n");
- } else {
- ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
- waveOutSetVolume(device->hwo, ampfactors);
- }
- }
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+
+ if(device->pwfx->nChannels > 1){
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+ }else
+ rvol = 1;
+
+ device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
+ device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
+
+ DSOUND_AmpFactorToVolPan(&device->volpan);
+ if (vol != device->volpan.lVolume) {
+ device->volpan.lVolume=vol;
+ DSOUND_RecalcVolPan(&device->volpan);
+ lvol = (float)((DWORD)(device->volpan.dwTotalLeftAmpFactor & 0xFFFF) / (float)0xFFFF);
+ hr = IAudioStreamVolume_SetChannelVolume(device->volume, 0, lvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("SetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+
+ if(device->pwfx->nChannels > 1){
+ rvol = (float)((DWORD)(device->volpan.dwTotalRightAmpFactor & 0xFFFF) / (float)0xFFFF);
+ hr = IAudioStreamVolume_SetChannelVolume(device->volume, 1, rvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("SetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+ }
+ }
LeaveCriticalSection(&(device->mixlock));
/* **** */
- return hres;
+ return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_GetVolume(
- LPDIRECTSOUNDBUFFER iface,LPLONG vol
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
- DWORD ampfactors;
+static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LONG *vol)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
+ float lvol, rvol;
+ HRESULT hr;
TRACE("(%p,%p)\n", iface, vol);
- if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
+ if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
WARN("control unavailable\n");
return DSERR_CONTROLUNAVAIL;
}
return DSERR_INVALIDPARAM;
}
- if (!device->hwbuf)
- {
- waveOutGetVolume(device->hwo, &factors);
- device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
- device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
- DSOUND_AmpFactorToVolPan(&device->volpan);
- }
- *vol = device->volpan.lVolume;
+ EnterCriticalSection(&device->mixlock);
+
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+
+ if(device->pwfx->nChannels > 1){
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+ }else
+ rvol = 1;
+
+ device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
+ device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
+
+ DSOUND_AmpFactorToVolPan(&device->volpan);
+ *vol = device->volpan.lVolume;
+
+ LeaveCriticalSection(&device->mixlock);
+
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(
- LPDIRECTSOUNDBUFFER iface,DWORD freq
-) {
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
+static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(IDirectSoundBuffer *iface, DWORD freq)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
TRACE("(%p,%d)\n",This,freq);
/* You cannot set the frequency of the primary buffer */
return DSERR_CONTROLUNAVAIL;
}
-static HRESULT WINAPI PrimaryBufferImpl_Play(
- LPDIRECTSOUNDBUFFER iface,DWORD reserved1,DWORD reserved2,DWORD flags
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+static HRESULT WINAPI PrimaryBufferImpl_Play(IDirectSoundBuffer *iface, DWORD reserved1,
+ DWORD reserved2, DWORD flags)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%08x,%08x,%08x)\n", iface, reserved1, reserved2, flags);
if (!(flags & DSBPLAY_LOOPING)) {
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER iface)
+static HRESULT WINAPI PrimaryBufferImpl_Stop(IDirectSoundBuffer *iface)
{
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p)\n", iface);
/* **** */
return DS_OK;
}
-static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER iface)
+static ULONG WINAPI PrimaryBufferImpl_AddRef(IDirectSoundBuffer *iface)
{
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
return ref;
}
-static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER iface)
+/* Decreases *out by 1 to no less than 0.
+ * Returns the new value of *out. */
+LONG capped_refcount_dec(LONG *out)
{
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
- DWORD ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
-
- if (!ref) {
- This->device->primary = NULL;
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
+ LONG ref, oldref;
+ do {
+ ref = *out;
+ if(!ref)
+ return 0;
+ oldref = InterlockedCompareExchange(out, ref - 1, ref);
+ } while(oldref != ref);
+ return ref - 1;
+}
+
+static ULONG WINAPI PrimaryBufferImpl_Release(IDirectSoundBuffer *iface)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ ULONG ref;
+
+ ref = capped_refcount_dec(&This->ref);
+ if(!ref)
+ capped_refcount_dec(&This->numIfaces);
+
+ TRACE("(%p) primary ref is now %d\n", This, ref);
+
return ref;
}
-static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(
- LPDIRECTSOUNDBUFFER iface,LPDWORD playpos,LPDWORD writepos
-) {
+static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(IDirectSoundBuffer *iface,
+ DWORD *playpos, DWORD *writepos)
+{
HRESULT hres;
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%p,%p)\n", iface, playpos, writepos);
/* **** */
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_GetStatus(
- LPDIRECTSOUNDBUFFER iface,LPDWORD status
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+static HRESULT WINAPI PrimaryBufferImpl_GetStatus(IDirectSoundBuffer *iface, DWORD *status)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%p)\n", iface, status);
if (status == NULL) {
}
-static HRESULT WINAPI PrimaryBufferImpl_GetFormat(
- LPDIRECTSOUNDBUFFER iface,
- LPWAVEFORMATEX lpwf,
- DWORD wfsize,
- LPDWORD wfwritten)
+static HRESULT WINAPI PrimaryBufferImpl_GetFormat(IDirectSoundBuffer *iface, WAVEFORMATEX *lpwf,
+ DWORD wfsize, DWORD *wfwritten)
{
DWORD size;
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%p,%d,%p)\n", iface, lpwf, wfsize, wfwritten);
- size = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
+ size = sizeof(WAVEFORMATEX) + device->primary_pwfx->cbSize;
if (lpwf) { /* NULL is valid */
if (wfsize >= size) {
- CopyMemory(lpwf,device->pwfx,size);
+ CopyMemory(lpwf,device->primary_pwfx,size);
if (wfwritten)
*wfwritten = size;
} else {
}
} else {
if (wfwritten)
- *wfwritten = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;
+ *wfwritten = sizeof(WAVEFORMATEX) + device->primary_pwfx->cbSize;
else {
WARN("invalid parameter: wfwritten == NULL\n");
return DSERR_INVALIDPARAM;
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_Lock(
- LPDIRECTSOUNDBUFFER iface,DWORD writecursor,DWORD writebytes,LPVOID *lplpaudioptr1,LPDWORD audiobytes1,LPVOID *lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
-) {
+static HRESULT WINAPI PrimaryBufferImpl_Lock(IDirectSoundBuffer *iface, DWORD writecursor,
+ DWORD writebytes, void **lplpaudioptr1, DWORD *audiobytes1, void **lplpaudioptr2,
+ DWORD *audiobytes2, DWORD flags)
+{
HRESULT hres;
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n",
iface,
writecursor,
return DSERR_INVALIDPARAM;
}
- if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
- hres = IDsDriverBuffer_Lock(device->hwbuf,
- lplpaudioptr1, audiobytes1,
- lplpaudioptr2, audiobytes2,
- writecursor, writebytes,
- 0);
- if (hres != DS_OK) {
- WARN("IDsDriverBuffer_Lock failed\n");
- return hres;
- }
+ if (writecursor+writebytes <= device->buflen) {
+ *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
+ *audiobytes1 = writebytes;
+ if (lplpaudioptr2)
+ *(LPBYTE*)lplpaudioptr2 = NULL;
+ if (audiobytes2)
+ *audiobytes2 = 0;
+ TRACE("->%d.0\n",writebytes);
} else {
- if (writecursor+writebytes <= device->buflen) {
- *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
- *audiobytes1 = writebytes;
- if (lplpaudioptr2)
- *(LPBYTE*)lplpaudioptr2 = NULL;
- if (audiobytes2)
- *audiobytes2 = 0;
- TRACE("->%d.0\n",writebytes);
- } else {
- *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
- *audiobytes1 = device->buflen-writecursor;
- if (lplpaudioptr2)
- *(LPBYTE*)lplpaudioptr2 = device->buffer;
- if (audiobytes2)
- *audiobytes2 = writebytes-(device->buflen-writecursor);
- TRACE("->%d.%d\n",*audiobytes1,audiobytes2?*audiobytes2:0);
- }
+ *(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;
+ *audiobytes1 = device->buflen-writecursor;
+ if (lplpaudioptr2)
+ *(LPBYTE*)lplpaudioptr2 = device->buffer;
+ if (audiobytes2)
+ *audiobytes2 = writebytes-(device->buflen-writecursor);
+ TRACE("->%d.%d\n",*audiobytes1,audiobytes2?*audiobytes2:0);
}
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition(
- LPDIRECTSOUNDBUFFER iface,DWORD newpos
-) {
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
+static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition(IDirectSoundBuffer *iface, DWORD newpos)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
TRACE("(%p,%d)\n",This,newpos);
/* You cannot set the position of the primary buffer */
return DSERR_INVALIDCALL;
}
-static HRESULT WINAPI PrimaryBufferImpl_SetPan(
- LPDIRECTSOUNDBUFFER iface,LONG pan
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
- DWORD ampfactors;
- HRESULT hres = DS_OK;
+static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG pan)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
+ float lvol, rvol;
+ HRESULT hr;
TRACE("(%p,%d)\n", iface, pan);
- if (!(device->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
+ if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
WARN("control unavailable\n");
return DSERR_CONTROLUNAVAIL;
}
}
/* **** */
- EnterCriticalSection(&(device->mixlock));
+ EnterCriticalSection(&device->mixlock);
- if (!device->hwbuf)
- {
- waveOutGetVolume(device->hwo, &factors);
- device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
- device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
- DSOUND_AmpFactorToVolPan(&device->volpan);
- }
- if (pan != device->volpan.lPan) {
- device->volpan.lPan=pan;
- DSOUND_RecalcVolPan(&device->volpan);
- if (device->hwbuf) {
- hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &device->volpan);
- if (hres != DS_OK)
- WARN("IDsDriverBuffer_SetVolumePan failed\n");
- } else {
- ampfactors = (device->volpan.dwTotalLeftAmpFactor & 0xffff) | (device->volpan.dwTotalRightAmpFactor << 16);
- waveOutSetVolume(device->hwo, ampfactors);
- }
- }
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
- LeaveCriticalSection(&(device->mixlock));
+ if(device->pwfx->nChannels > 1){
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+ }else
+ rvol = 1;
+
+ device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
+ device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
+
+ DSOUND_AmpFactorToVolPan(&device->volpan);
+ if (pan != device->volpan.lPan) {
+ device->volpan.lPan=pan;
+ DSOUND_RecalcVolPan(&device->volpan);
+
+ lvol = (float)((DWORD)(device->volpan.dwTotalLeftAmpFactor & 0xFFFF) / (float)0xFFFF);
+ hr = IAudioStreamVolume_SetChannelVolume(device->volume, 0, lvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("SetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+
+ if(device->pwfx->nChannels > 1){
+ rvol = (float)((DWORD)(device->volpan.dwTotalRightAmpFactor & 0xFFFF) / (float)0xFFFF);
+ hr = IAudioStreamVolume_SetChannelVolume(device->volume, 1, rvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("SetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+ }
+ }
+
+ LeaveCriticalSection(&device->mixlock);
/* **** */
- return hres;
+ return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_GetPan(
- LPDIRECTSOUNDBUFFER iface,LPLONG pan
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
- DWORD ampfactors;
+static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG *pan)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
+ float lvol, rvol;
+ HRESULT hr;
TRACE("(%p,%p)\n", iface, pan);
- if (!(device->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
+ if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
WARN("control unavailable\n");
return DSERR_CONTROLUNAVAIL;
}
return DSERR_INVALIDPARAM;
}
- if (!device->hwbuf)
- {
- waveOutGetVolume(device->hwo, &factors);
- device->volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
- device->volpan.dwTotalRightAmpFactor=ampfactors >> 16;
- DSOUND_AmpFactorToVolPan(&device->volpan);
- }
+ EnterCriticalSection(&device->mixlock);
+
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+
+ if(device->pwfx->nChannels > 1){
+ hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
+ if(FAILED(hr)){
+ LeaveCriticalSection(&device->mixlock);
+ WARN("GetChannelVolume failed: %08x\n", hr);
+ return hr;
+ }
+ }else
+ rvol = 1;
+
+ device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
+ device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
+
+ DSOUND_AmpFactorToVolPan(&device->volpan);
*pan = device->volpan.lPan;
+
+ LeaveCriticalSection(&device->mixlock);
+
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_Unlock(
- LPDIRECTSOUNDBUFFER iface,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+static HRESULT WINAPI PrimaryBufferImpl_Unlock(IDirectSoundBuffer *iface, void *p1, DWORD x1,
+ void *p2, DWORD x2)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%p,%d,%p,%d)\n", iface, p1, x1, p2, x2);
if (device->priolevel != DSSCL_WRITEPRIMARY) {
return DSERR_PRIOLEVELNEEDED;
}
- if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {
- HRESULT hres;
-
- if ((char *)p1 - (char *)device->buffer + x1 > device->buflen)
- hres = DSERR_INVALIDPARAM;
- else
- hres = IDsDriverBuffer_Unlock(device->hwbuf, p1, x1, p2, x2);
-
- if (hres != DS_OK) {
- WARN("IDsDriverBuffer_Unlock failed\n");
- return hres;
- }
- }
+ if ((p1 && ((BYTE*)p1 < device->buffer || (BYTE*)p1 >= device->buffer + device->buflen)) ||
+ (p2 && ((BYTE*)p2 < device->buffer || (BYTE*)p2 >= device->buffer + device->buflen)))
+ return DSERR_INVALIDPARAM;
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_Restore(
- LPDIRECTSOUNDBUFFER iface
-) {
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
+static HRESULT WINAPI PrimaryBufferImpl_Restore(IDirectSoundBuffer *iface)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
FIXME("(%p):stub\n",This);
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(
- LPDIRECTSOUNDBUFFER iface,LPDWORD freq
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+static HRESULT WINAPI PrimaryBufferImpl_GetFrequency(IDirectSoundBuffer *iface, DWORD *freq)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%p)\n", iface, freq);
if (freq == NULL) {
return DSERR_INVALIDPARAM;
}
- if (!(device->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
+ if (!(This->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
WARN("control unavailable\n");
return DSERR_CONTROLUNAVAIL;
}
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_Initialize(
- LPDIRECTSOUNDBUFFER iface,LPDIRECTSOUND dsound,LPCDSBUFFERDESC dbsd
-) {
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
+static HRESULT WINAPI PrimaryBufferImpl_Initialize(IDirectSoundBuffer *iface, IDirectSound *dsound,
+ const DSBUFFERDESC *dbsd)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
WARN("(%p) already initialized\n", This);
return DSERR_ALREADYINITIALIZED;
}
-static HRESULT WINAPI PrimaryBufferImpl_GetCaps(
- LPDIRECTSOUNDBUFFER iface,LPDSBCAPS caps
-) {
- DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device;
+static HRESULT WINAPI PrimaryBufferImpl_GetCaps(IDirectSoundBuffer *iface, DSBCAPS *caps)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+ DirectSoundDevice *device = This->device;
TRACE("(%p,%p)\n", iface, caps);
if (caps == NULL) {
return DSERR_INVALIDPARAM;
}
- caps->dwFlags = device->dsbd.dwFlags;
+ caps->dwFlags = This->dsbd.dwFlags;
caps->dwBufferBytes = device->buflen;
/* Windows reports these as zero */
return DS_OK;
}
-static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(
- LPDIRECTSOUNDBUFFER iface,REFIID riid,LPVOID *ppobj
-) {
- PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;
- DirectSoundDevice *device = This->device;
+static HRESULT WINAPI PrimaryBufferImpl_QueryInterface(IDirectSoundBuffer *iface, REFIID riid,
+ void **ppobj)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
+
TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj);
if (ppobj == NULL) {
if ( IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)This);
- *ppobj = This;
+ IDirectSoundBuffer_AddRef(iface);
+ *ppobj = iface;
return S_OK;
}
}
if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
- if (!device->listener)
- IDirectSound3DListenerImpl_Create(device, &device->listener);
- if (device->listener) {
- *ppobj = device->listener;
- IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)*ppobj);
- return S_OK;
- }
-
- WARN("IID_IDirectSound3DListener failed\n");
- return E_NOINTERFACE;
+ *ppobj = &This->IDirectSound3DListener_iface;
+ IDirectSound3DListener_AddRef(&This->IDirectSound3DListener_iface);
+ return S_OK;
}
if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
- FIXME("app requested IKsPropertySet on primary buffer\n");
- return E_NOINTERFACE;
+ *ppobj = &This->IKsPropertySet_iface;
+ IKsPropertySet_AddRef(&This->IKsPropertySet_iface);
+ return S_OK;
}
FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
PrimaryBufferImpl_Restore
};
-HRESULT PrimaryBufferImpl_Create(
- DirectSoundDevice * device,
- PrimaryBufferImpl ** ppdsb,
- LPCDSBUFFERDESC dsbd)
+HRESULT primarybuffer_create(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb,
+ const DSBUFFERDESC *dsbd)
{
- PrimaryBufferImpl *dsb;
+ IDirectSoundBufferImpl *dsb;
TRACE("%p,%p,%p)\n",device,ppdsb,dsbd);
if (dsbd->lpwfxFormat) {
return DSERR_OUTOFMEMORY;
}
- dsb->ref = 0;
+ dsb->ref = 0;
+ dsb->ref3D = 0;
+ dsb->refiks = 0;
+ dsb->numIfaces = 0;
dsb->device = device;
- dsb->lpVtbl = &dspbvt;
-
- device->dsbd = *dsbd;
+ dsb->IDirectSoundBuffer8_iface.lpVtbl = (IDirectSoundBuffer8Vtbl *)&dspbvt;
+ dsb->IDirectSound3DListener_iface.lpVtbl = &ds3dlvt;
+ dsb->IKsPropertySet_iface.lpVtbl = &iksbvt;
+ dsb->dsbd = *dsbd;
+
+ /* IDirectSound3DListener */
+ device->ds3dl.dwSize = sizeof(DS3DLISTENER);
+ device->ds3dl.vPosition.x = 0.0;
+ device->ds3dl.vPosition.y = 0.0;
+ device->ds3dl.vPosition.z = 0.0;
+ device->ds3dl.vVelocity.x = 0.0;
+ device->ds3dl.vVelocity.y = 0.0;
+ device->ds3dl.vVelocity.z = 0.0;
+ device->ds3dl.vOrientFront.x = 0.0;
+ device->ds3dl.vOrientFront.y = 0.0;
+ device->ds3dl.vOrientFront.z = 1.0;
+ device->ds3dl.vOrientTop.x = 0.0;
+ device->ds3dl.vOrientTop.y = 1.0;
+ device->ds3dl.vOrientTop.z = 0.0;
+ device->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
+ device->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
+ device->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
+ device->ds3dl_need_recalc = TRUE;
TRACE("Created primary buffer at %p\n", dsb);
TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
device->pwfx->nBlockAlign, device->pwfx->wBitsPerSample,
device->pwfx->cbSize);
+ IDirectSoundBuffer_AddRef(&dsb->IDirectSoundBuffer8_iface);
*ppdsb = dsb;
return S_OK;
}
*/
#define COBJMACROS
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#include <windef.h>
#include <winbase.h>
//#include "winuser.h"
-//#include "mmsystem.h"
+#include <mmsystem.h>
#include <winternl.h>
#include <winnls.h>
#include <vfwmsgs.h>
-#include <mmddk.h>
+#include <initguid.h>
+//#include <mmddk.h>
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
#include <dsconf.h>
-#ifdef NONAMELESSSTRUCT
-# define S(x) (x).s
-#else
-# define S(x) (x)
-#endif
+//#include "ksmedia.h"
+//#include "propkey.h"
+#include <devpkey.h>
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-/*******************************************************************************
- * IKsBufferPropertySet
- */
-
-/* IUnknown methods */
-static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface(
- LPKSPROPERTYSET iface,
- REFIID riid,
- LPVOID *ppobj )
-{
- IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-
- return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
-}
-
-static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface)
-{
- IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref - 1);
- return ref;
-}
-
-static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface)
-{
- IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
-
- if (!ref) {
- This->dsb->iks = 0;
- IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
- return ref;
-}
-
-static HRESULT WINAPI IKsBufferPropertySetImpl_Get(
- LPKSPROPERTYSET iface,
- REFGUID guidPropSet,
- ULONG dwPropID,
- LPVOID pInstanceData,
- ULONG cbInstanceData,
- LPVOID pPropData,
- ULONG cbPropData,
- PULONG pcbReturned )
-{
- IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
- PIDSDRIVERPROPERTYSET ps;
- TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
-
- if (This->dsb->hwbuf) {
- IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
-
- if (ps) {
- DSPROPERTY prop;
- HRESULT hres;
-
- S(prop).Set = *guidPropSet;
- S(prop).Id = dwPropID;
- S(prop).Flags = 0; /* unused */
- S(prop).InstanceId = (ULONG_PTR)This->dsb->device;
-
- hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
-
- IDsDriverPropertySet_Release(ps);
-
- return hres;
- }
- }
-
- return E_PROP_ID_UNSUPPORTED;
-}
-
-static HRESULT WINAPI IKsBufferPropertySetImpl_Set(
- LPKSPROPERTYSET iface,
- REFGUID guidPropSet,
- ULONG dwPropID,
- LPVOID pInstanceData,
- ULONG cbInstanceData,
- LPVOID pPropData,
- ULONG cbPropData )
-{
- IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
- PIDSDRIVERPROPERTYSET ps;
- TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
-
- if (This->dsb->hwbuf) {
- IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
-
- if (ps) {
- DSPROPERTY prop;
- HRESULT hres;
-
- S(prop).Set = *guidPropSet;
- S(prop).Id = dwPropID;
- S(prop).Flags = 0; /* unused */
- S(prop).InstanceId = (ULONG_PTR)This->dsb->device;
- hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData);
-
- IDsDriverPropertySet_Release(ps);
-
- return hres;
- }
- }
-
- return E_PROP_ID_UNSUPPORTED;
-}
+static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
-static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport(
- LPKSPROPERTYSET iface,
- REFGUID guidPropSet,
- ULONG dwPropID,
- PULONG pTypeSupport )
+typedef struct IKsPrivatePropertySetImpl
{
- IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
- PIDSDRIVERPROPERTYSET ps;
- TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
-
- if (This->dsb->hwbuf) {
- IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
-
- if (ps) {
- HRESULT hres;
-
- hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport);
-
- IDsDriverPropertySet_Release(ps);
-
- return hres;
- }
- }
-
- return E_PROP_ID_UNSUPPORTED;
-}
-
-static const IKsPropertySetVtbl iksbvt = {
- IKsBufferPropertySetImpl_QueryInterface,
- IKsBufferPropertySetImpl_AddRef,
- IKsBufferPropertySetImpl_Release,
- IKsBufferPropertySetImpl_Get,
- IKsBufferPropertySetImpl_Set,
- IKsBufferPropertySetImpl_QuerySupport
-};
+ IKsPropertySet IKsPropertySet_iface;
+ LONG ref;
+} IKsPrivatePropertySetImpl;
-HRESULT IKsBufferPropertySetImpl_Create(
- IDirectSoundBufferImpl *dsb,
- IKsBufferPropertySetImpl **piks)
+static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
{
- IKsBufferPropertySetImpl *iks;
- TRACE("(%p,%p)\n",dsb,piks);
- *piks = NULL;
-
- iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
- if (iks == 0) {
- WARN("out of memory\n");
- *piks = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- iks->ref = 0;
- iks->dsb = dsb;
- dsb->iks = iks;
- iks->lpVtbl = &iksbvt;
-
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
-
- *piks = iks;
- return S_OK;
-}
-
-HRESULT IKsBufferPropertySetImpl_Destroy(
- IKsBufferPropertySetImpl *piks)
-{
- TRACE("(%p)\n",piks);
-
- while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);
-
- return S_OK;
+ return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface);
}
/*******************************************************************************
/* IUnknown methods */
static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
- LPKSPROPERTYSET iface,
- REFIID riid,
- LPVOID *ppobj )
+ IKsPropertySet *iface, REFIID riid, void **ppobj)
{
- IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
+ IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IKsPropertySet)) {
*ppobj = iface;
- IUnknown_AddRef(iface);
+ IKsPropertySet_AddRef(iface);
return S_OK;
}
*ppobj = NULL;
static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
{
- IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
+ IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
ULONG ref = InterlockedIncrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref - 1);
return ref;
static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
{
- IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
+ IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
ULONG ref = InterlockedDecrement(&(This->ref));
TRACE("(%p) ref was %d\n", This, ref + 1);
return ref;
}
-static HRESULT DSPROPERTY_WaveDeviceMappingA(
+struct search_data {
+ const WCHAR *tgt_name;
+ GUID *found_guid;
+};
+
+static BOOL CALLBACK search_callback(GUID *guid, const WCHAR *desc,
+ const WCHAR *module, void *user)
+{
+ struct search_data *search = user;
+
+ if(!lstrcmpW(desc, search->tgt_name)){
+ *search->found_guid = *guid;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static HRESULT DSPROPERTY_WaveDeviceMappingW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
- HRESULT hr = DSERR_INVALIDPARAM;
- PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ HRESULT hr;
+ PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd = pPropData;
+ struct search_data search;
- ppd = pPropData;
+ TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
+ pPropData,cbPropData,pcbReturned);
if (!ppd) {
- WARN("invalid parameter: pPropData\n");
- return DSERR_INVALIDPARAM;
+ WARN("invalid parameter: pPropData\n");
+ return DSERR_INVALIDPARAM;
}
- if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
- ULONG wod;
- unsigned int wodn;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- WAVEOUTCAPSA capsA;
- MMRESULT res;
- res = waveOutGetDevCapsA(wod, &capsA, sizeof(capsA));
- if (res == MMSYSERR_NOERROR) {
- if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
- ppd->DeviceId = DSOUND_renderer_guids[wod];
- hr = DS_OK;
- TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
- ppd->DeviceName);
- break;
- }
- }
- }
- } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
- ULONG wid;
- unsigned int widn;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- WAVEINCAPSA capsA;
- MMRESULT res;
- res = waveInGetDevCapsA(wid, &capsA, sizeof(capsA));
- if (res == MMSYSERR_NOERROR) {
- if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
- ppd->DeviceId = DSOUND_capture_guids[wid];
- TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
- ppd->DeviceName);
- hr = DS_OK;
- break;
- }
- }
- }
- }
+ search.tgt_name = ppd->DeviceName;
+ search.found_guid = &ppd->DeviceId;
+
+ if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
+ hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
+ search_callback, &search);
+ else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE)
+ hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
+ search_callback, &search);
+ else
+ return DSERR_INVALIDPARAM;
+
+ if(hr != S_FALSE)
+ /* device was not found */
+ return DSERR_INVALIDPARAM;
if (pcbReturned)
- *pcbReturned = cbPropData;
+ *pcbReturned = cbPropData;
- return hr;
+ return DS_OK;
}
-static HRESULT DSPROPERTY_WaveDeviceMappingW(
+static HRESULT DSPROPERTY_WaveDeviceMappingA(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
- HRESULT hr = DSERR_INVALIDPARAM;
- PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
+ DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
+ DWORD len;
+ HRESULT hr;
- ppd = pPropData;
+ TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
+ pPropData,cbPropData,pcbReturned);
- if (!ppd) {
- WARN("invalid parameter: pPropData\n");
- return DSERR_INVALIDPARAM;
+ if (!ppd || !ppd->DeviceName) {
+ WARN("invalid parameter: ppd=%p\n", ppd);
+ return DSERR_INVALIDPARAM;
}
- if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
- ULONG wod;
- unsigned int wodn;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- WAVEOUTCAPSW capsW;
- MMRESULT res;
- res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
- if (res == MMSYSERR_NOERROR) {
- if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
- ppd->DeviceId = DSOUND_renderer_guids[wod];
- hr = DS_OK;
- TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
- debugstr_w(ppd->DeviceName));
- break;
- }
- }
- }
- } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
- ULONG wid;
- unsigned int widn;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- WAVEINCAPSW capsW;
- MMRESULT res;
- res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
- if (res == MMSYSERR_NOERROR) {
- if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
- ppd->DeviceId = DSOUND_capture_guids[wid];
- hr = DS_OK;
- TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
- debugstr_w(ppd->DeviceName));
- break;
- }
- }
- }
- }
+ data.DataFlow = ppd->DataFlow;
+ len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0);
+ data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!data.DeviceName)
+ return E_OUTOFMEMORY;
+ MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len);
+
+ hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
+ HeapFree(GetProcessHeap(), 0, data.DeviceName);
+ ppd->DeviceId = data.DeviceId;
if (pcbReturned)
*pcbReturned = cbPropData;
return hr;
}
-static HRESULT DSPROPERTY_Description1(
+static HRESULT DSPROPERTY_DescriptionW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
- HRESULT err;
- GUID guid, dev_guid;
- PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA ppd;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
-
- ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA) pPropData;
+ PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
+ GUID dev_guid;
+ IMMDevice *mmdevice;
+ IPropertyStore *ps;
+ PROPVARIANT pv;
+ DWORD desclen;
+ HRESULT hr;
- if (!ppd) {
- WARN("invalid parameter: pPropData\n");
- return DSERR_INVALIDPARAM;
- }
+ TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
+ pPropData,cbPropData,pcbReturned);
TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
- /* default device of type specified by ppd->DataFlow */
- if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- } else {
- TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
- }
- FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
- pPropData,cbPropData,pcbReturned);
- return E_PROP_ID_UNSUPPORTED;
+ /* default device of type specified by ppd->DataFlow */
+ if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
+ TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
+ ppd->DeviceId = DSDEVID_DefaultCapture;
+ } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
+ TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
+ ppd->DeviceId = DSDEVID_DefaultPlayback;
+ } else {
+ WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
+ return E_PROP_ID_UNSUPPORTED;
+ }
}
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
+ setup_dsound_options();
+
GetDeviceID(&ppd->DeviceId, &dev_guid);
- if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
- IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
- ULONG wod;
- unsigned int wodn;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
- DSDRIVERDESC desc;
- ppd->WaveDeviceId = wod;
- ppd->Devnode = wod;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
- lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- break;
- } else {
- WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
- IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
- ULONG wid;
- unsigned int widn;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- if (IsEqualGUID( &dev_guid, &guid) ) {
- DSDRIVERDESC desc;
- ppd->WaveDeviceId = wid;
- ppd->Devnode = wid;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
- lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- break;
- } else {
- WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- } else {
- BOOL found = FALSE;
- ULONG wod;
- unsigned int wodn;
- /* given specific device so try the render devices first */
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
- DSDRIVERDESC desc;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- ppd->WaveDeviceId = wod;
- ppd->Devnode = wod;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
- lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- found = TRUE;
- break;
- } else {
- WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
+ hr = get_mmdevice(eRender, &dev_guid, &mmdevice);
+ if(FAILED(hr)){
+ hr = get_mmdevice(eCapture, &dev_guid, &mmdevice);
+ if(FAILED(hr))
+ return hr;
+ }
- if (found == FALSE) {
- ULONG wid;
- unsigned int widn;
- /* given specific device so try the capture devices next */
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
- DSDRIVERDESC desc;
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- ppd->WaveDeviceId = wid;
- ppd->Devnode = wid;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
- lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
- err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- found = TRUE;
- break;
- } else {
- WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
-
- if (found == FALSE) {
- WARN("device not found\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
+ hr = IMMDevice_OpenPropertyStore(mmdevice, STGM_READ, &ps);
+ if(FAILED(hr)){
+ IMMDevice_Release(mmdevice);
+ WARN("OpenPropertyStore failed: %08x\n", hr);
+ return hr;
+ }
+
+ hr = IPropertyStore_GetValue(ps,
+ (const PROPERTYKEY *)&DEVPKEY_Device_FriendlyName, &pv);
+ if(FAILED(hr)){
+ IPropertyStore_Release(ps);
+ IMMDevice_Release(mmdevice);
+ WARN("GetValue(FriendlyName) failed: %08x\n", hr);
+ return hr;
}
+ desclen = lstrlenW(pv.u.pwszVal) + 1;
+ /* FIXME: Still a memory leak.. */
+ ppd->Description = HeapAlloc(GetProcessHeap(), 0, desclen * sizeof(WCHAR));
+ memcpy(ppd->Description, pv.u.pwszVal, desclen * sizeof(WCHAR));
+ ppd->Module = wine_vxd_drv;
+ ppd->Interface = wInterface;
+ ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
+
+ PropVariantClear(&pv);
+ IPropertyStore_Release(ps);
+ IMMDevice_Release(mmdevice);
+
if (pcbReturned) {
- *pcbReturned = cbPropData;
- TRACE("*pcbReturned=%d\n", *pcbReturned);
+ *pcbReturned = sizeof(*ppd);
+ TRACE("*pcbReturned=%d\n", *pcbReturned);
}
return S_OK;
}
-static HRESULT DSPROPERTY_DescriptionA(
- LPVOID pPropData,
- ULONG cbPropData,
- PULONG pcbReturned )
+static
+BOOL CALLBACK enum_callback(GUID *guid, const WCHAR *desc, const WCHAR *module,
+ void *user)
{
- PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = pPropData;
- HRESULT err;
- GUID dev_guid;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = user;
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
+ DWORD len;
+ BOOL ret;
- TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
- if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
- /* default device of type specified by ppd->DataFlow */
- if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- } else {
- TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
- }
- FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
- pPropData,cbPropData,pcbReturned);
- return E_PROP_ID_UNSUPPORTED;
- }
+ TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid), wine_dbgstr_w(desc),
+ wine_dbgstr_w(module), user);
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- GetDeviceID(&ppd->DeviceId, &dev_guid);
+ if(!guid)
+ return TRUE;
- if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
- IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
- ULONG wod;
- unsigned int wodn;
- if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
- TRACE("DSDEVID_DefaultPlayback\n");
- else
- TRACE("DSDEVID_DefaultVoicePlayback\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
- DSDRIVERDESC desc;
- ppd->WaveDeviceId = wod;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- /* FIXME: this is a memory leak */
- CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
- CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
- CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
-
- if (szDescription && szModule && szInterface) {
- strcpy(szDescription, desc.szDesc);
- strcpy(szModule, desc.szDrvname);
- strcpy(szInterface, "Interface");
-
- ppd->Description = szDescription;
- ppd->Module = szModule;
- ppd->Interface = szInterface;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, szDescription);
- HeapFree(GetProcessHeap(), 0, szModule);
- HeapFree(GetProcessHeap(), 0, szInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
- IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
- ULONG wid;
- unsigned int widn;
- if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) )
- TRACE("DSDEVID_DefaultCapture\n");
- else
- TRACE("DSDEVID_DefaultVoiceCapture\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
- DSDRIVERDESC desc;
- ppd->WaveDeviceId = wid;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- /* FIXME: this is a memory leak */
- CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
- CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
- CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
-
- if (szDescription && szModule && szInterface) {
- strcpy(szDescription, desc.szDesc);
- strcpy(szModule, desc.szDrvname);
- strcpy(szInterface, "Interface");
-
- ppd->Description = szDescription;
- ppd->Module = szModule;
- ppd->Interface = szInterface;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, szDescription);
- HeapFree(GetProcessHeap(), 0, szModule);
- HeapFree(GetProcessHeap(), 0, szInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- } else {
- BOOL found = FALSE;
- ULONG wod;
- unsigned int wodn;
- /* given specific device so try the render devices first */
- TRACE("Checking renderer devices\n");
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
- DSDRIVERDESC desc;
- TRACE("DSOUND_renderer_guids[%d]\n", wod);
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- ppd->WaveDeviceId = wod;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- /* FIXME: this is a memory leak */
- CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
- CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
- CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
-
- if (szDescription && szModule && szInterface) {
- strcpy(szDescription, desc.szDesc);
- strcpy(szModule, desc.szDrvname);
- strcpy(szInterface, "Interface");
-
- ppd->Description = szDescription;
- ppd->Module = szModule;
- ppd->Interface = szInterface;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- found = TRUE;
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, szDescription);
- HeapFree(GetProcessHeap(), 0, szModule);
- HeapFree(GetProcessHeap(), 0, szInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
+ data.DeviceId = *guid;
- if (found == FALSE) {
- ULONG wid;
- unsigned int widn;
- TRACE("Checking capture devices\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
- DSDRIVERDESC desc;
- TRACE("DSOUND_capture_guids[%d]\n", wid);
- ppd->WaveDeviceId = wid;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- /* FIXME: this is a memory leak */
- CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
- CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
- CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
-
- if (szDescription && szModule && szInterface) {
- strcpy(szDescription, desc.szDesc);
- strcpy(szModule, desc.szDrvname);
- strcpy(szInterface, "Interface");
-
- ppd->Description = szDescription;
- ppd->Module = szModule;
- ppd->Interface = szInterface;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- found = TRUE;
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, szDescription);
- HeapFree(GetProcessHeap(), 0, szModule);
- HeapFree(GetProcessHeap(), 0, szInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- }
+ len = lstrlenW(module) + 1;
+ data.Module = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ memcpy(data.Module, module, len * sizeof(WCHAR));
- if (found == FALSE) {
- WARN("device not found\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
+ len = lstrlenW(desc) + 1;
+ data.Description = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ memcpy(data.Description, desc, len * sizeof(WCHAR));
- if (pcbReturned) {
- *pcbReturned = cbPropData;
- TRACE("*pcbReturned=%d\n", *pcbReturned);
- }
+ data.Interface = wInterface;
- return S_OK;
+ ret = ppd->Callback(&data, ppd->Context);
+
+ HeapFree(GetProcessHeap(), 0, data.Module);
+ HeapFree(GetProcessHeap(), 0, data.Description);
+
+ return ret;
}
-static HRESULT DSPROPERTY_DescriptionW(
+static HRESULT DSPROPERTY_EnumerateW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
- PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
- HRESULT err;
- GUID dev_guid;
- TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
+ HRESULT hr;
- TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
- if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
- /* default device of type specified by ppd->DataFlow */
- if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
- } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
- TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
- } else {
- TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
- }
- FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
- pPropData,cbPropData,pcbReturned);
- return E_PROP_ID_UNSUPPORTED;
+ TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
+ pPropData,cbPropData,pcbReturned);
+
+ if (pcbReturned)
+ *pcbReturned = 0;
+
+ if (!ppd || !ppd->Callback)
+ {
+ WARN("Invalid ppd %p\n", ppd);
+ return E_PROP_ID_UNSUPPORTED;
}
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- GetDeviceID(&ppd->DeviceId, &dev_guid);
+ hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids,
+ enum_callback, ppd);
- if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
- IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
- ULONG wod;
- unsigned int wodn;
- if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
- TRACE("DSDEVID_DefaultPlayback\n");
- else
- TRACE("DSDEVID_DefaultVoicePlayback\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
- DSDRIVERDESC desc;
- TRACE("DSOUND_renderer_guids[%d]\n", wod);
- ppd->WaveDeviceId = wod;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- /* FIXME: this is a memory leak */
- WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
-
- if (wDescription && wModule && wInterface) {
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
-
- ppd->Description = wDescription;
- ppd->Module = wModule;
- ppd->Interface = wInterface;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, wDescription);
- HeapFree(GetProcessHeap(), 0, wModule);
- HeapFree(GetProcessHeap(), 0, wInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
- IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
- ULONG wid;
- unsigned int widn;
- if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture))
- TRACE("DSDEVID_DefaultCapture\n");
- else
- TRACE("DSDEVID_DefaultVoiceCapture\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
- DSDRIVERDESC desc;
- ppd->WaveDeviceId = wid;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- /* FIXME: this is a memory leak */
- WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
-
- if (wDescription && wModule && wInterface) {
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
-
- ppd->Description = wDescription;
- ppd->Module = wModule;
- ppd->Interface = wInterface;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, wDescription);
- HeapFree(GetProcessHeap(), 0, wModule);
- HeapFree(GetProcessHeap(), 0, wInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- } else {
- BOOL found = FALSE;
- ULONG wod;
- unsigned int wodn;
- TRACE("Checking renderer devices\n");
- /* given specific device so try the render devices first */
- wodn = waveOutGetNumDevs();
- for (wod = 0; wod < wodn; wod++) {
- if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
- DSDRIVERDESC desc;
- TRACE("DSOUND_renderer_guids[%d]\n", wod);
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- ppd->WaveDeviceId = wod;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSDRIVER drv = NULL;
- /* FIXME: this is a memory leak */
- WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
-
- if (wDescription && wModule && wInterface) {
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
-
- ppd->Description = wDescription;
- ppd->Module = wModule;
- ppd->Interface = wInterface;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- found = TRUE;
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, wDescription);
- HeapFree(GetProcessHeap(), 0, wModule);
- HeapFree(GetProcessHeap(), 0, wInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
+ if(hr == S_OK)
+ hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids,
+ enum_callback, ppd);
- if (found == FALSE) {
- ULONG wid;
- unsigned int widn;
- TRACE("Checking capture devices\n");
- ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- widn = waveInGetNumDevs();
- for (wid = 0; wid < widn; wid++) {
- if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
- DSDRIVERDESC desc;
- TRACE("DSOUND_capture_guids[%d]\n", wid);
- ppd->WaveDeviceId = wid;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- /* FIXME: this is a memory leak */
- WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
-
- if (wDescription && wModule && wInterface) {
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
-
- ppd->Description = wDescription;
- ppd->Module = wModule;
- ppd->Interface = wInterface;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
- if (err == DS_OK && drv)
- ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
- found = TRUE;
- break;
- } else {
- WARN("no memory\n");
- HeapFree(GetProcessHeap(), 0, wDescription);
- HeapFree(GetProcessHeap(), 0, wModule);
- HeapFree(GetProcessHeap(), 0, wInterface);
- return E_OUTOFMEMORY;
- }
- } else {
- WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
- return E_PROP_ID_UNSUPPORTED;
- }
- }
- }
- }
+ return SUCCEEDED(hr) ? DS_OK : hr;
+}
- if (found == FALSE) {
- WARN("device not found\n");
- return E_PROP_ID_UNSUPPORTED;
- }
+static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
+{
+ DWORD modlen, desclen;
+ static char Interface[] = "Interface";
+
+ modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL);
+ desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL);
+ dataA->Type = dataW->Type;
+ dataA->DataFlow = dataW->DataFlow;
+ dataA->DeviceId = dataW->DeviceId;
+ dataA->WaveDeviceId = dataW->WaveDeviceId;
+ dataA->Interface = Interface;
+ dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen);
+ dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen);
+ if (!dataA->Module || !dataA->Description)
+ {
+ HeapFree(GetProcessHeap(), 0, dataA->Module);
+ HeapFree(GetProcessHeap(), 0, dataA->Description);
+ dataA->Module = dataA->Description = NULL;
+ return FALSE;
}
- if (pcbReturned) {
- *pcbReturned = cbPropData;
- TRACE("*pcbReturned=%d\n", *pcbReturned);
- }
+ WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
+ return TRUE;
+}
- return S_OK;
+static void DSPROPERTY_descWto1(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
+{
+ data1->DeviceId = dataW->DeviceId;
+ lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW));
+ lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW));
+ WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL);
+ data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0;
+ data1->ModuleA[sizeof(data1->ModuleA)-1] = 0;
+ data1->Type = dataW->Type;
+ data1->DataFlow = dataW->DataFlow;
+ data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
}
-static HRESULT DSPROPERTY_Enumerate1(
+static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
+{
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
+ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
+ BOOL ret;
+
+ ret = DSPROPERTY_descWtoA(descW, &descA);
+ if (!ret)
+ return FALSE;
+ ret = ppd->Callback(&descA, ppd->Context);
+ HeapFree(GetProcessHeap(), 0, descA.Module);
+ HeapFree(GetProcessHeap(), 0, descA.Description);
+ return ret;
+}
+
+static HRESULT DSPROPERTY_EnumerateA(
LPVOID pPropData,
ULONG cbPropData,
- PULONG pcbReturned )
+ PULONG pcbReturned)
{
- PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA) pPropData;
- HRESULT err;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
+ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
- if (ppd) {
- if (ppd->Callback) {
- unsigned devs, wod, wid;
- DSDRIVERDESC desc;
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data;
-
- devs = waveOutGetNumDevs();
- for (wod = 0; wod < devs; ++wod) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- ZeroMemory(&data, sizeof(data));
- data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- data.WaveDeviceId = wod;
- data.DeviceId = DSOUND_renderer_guids[wod];
- lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
- lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
-
- MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );
-
- data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
-
- TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
- (ppd->Callback)(&data, ppd->Context);
- }
- }
-
- devs = waveInGetNumDevs();
- for (wid = 0; wid < devs; ++wid) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- ZeroMemory(&data, sizeof(data));
- data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- data.WaveDeviceId = wid;
- data.DeviceId = DSOUND_capture_guids[wid];
- lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
- lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
-
- MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
- MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );
-
- data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
-
- TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
- (ppd->Callback)(&data, ppd->Context);
- }
- }
-
- return S_OK;
- }
+ if (!ppd || !ppd->Callback)
+ {
+ WARN("Invalid ppd %p\n", ppd);
+ return E_PROP_ID_UNSUPPORTED;
}
- if (pcbReturned) {
- *pcbReturned = 0;
- FIXME("*pcbReturned=%d\n", *pcbReturned);
- }
+ data.Callback = DSPROPERTY_enumWtoA;
+ data.Context = ppd;
- return E_PROP_ID_UNSUPPORTED;
+ return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
}
-static HRESULT DSPROPERTY_EnumerateA(
+static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
+{
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
+ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
+ BOOL ret;
+
+ DSPROPERTY_descWto1(descW, &desc1);
+ ret = ppd->Callback(&desc1, ppd->Context);
+ return ret;
+}
+
+static HRESULT DSPROPERTY_Enumerate1(
LPVOID pPropData,
ULONG cbPropData,
- PULONG pcbReturned )
+ PULONG pcbReturned)
{
- PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = pPropData;
- HRESULT err;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
+ DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
- if (ppd) {
- if (ppd->Callback) {
- unsigned devs, wod, wid;
- DSDRIVERDESC desc;
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;
-
- devs = waveOutGetNumDevs();
- for (wod = 0; wod < devs; ++wod) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- DWORD size;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
- if (err == DS_OK) {
- WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
- if (nameW) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
- if (err == DS_OK) {
- CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
- if (szInterface) {
- PIDSCDRIVER drv;
- ZeroMemory(&data, sizeof(data));
- data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- data.WaveDeviceId = wod;
- data.DeviceId = DSOUND_renderer_guids[wod];
- data.Description = desc.szDesc;
- data.Module = desc.szDrvname;
- WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
- data.Interface = szInterface;
-
- data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
-
- TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
- (ppd->Callback)(&data, ppd->Context);
- }
- HeapFree(GetProcessHeap(),0,szInterface);
- }
- }
- HeapFree(GetProcessHeap(),0,nameW);
- }
- }
- }
-
- devs = waveInGetNumDevs();
- for (wid = 0; wid < devs; ++wid) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- DWORD size;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
- if (err == DS_OK) {
- WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
- if (nameW) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
- if (err == DS_OK) {
- CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
- if (szInterface) {
- PIDSCDRIVER drv;
- ZeroMemory(&data, sizeof(data));
- data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- data.WaveDeviceId = wid;
- data.DeviceId = DSOUND_capture_guids[wid];
- data.Description = desc.szDesc;
- data.Module = desc.szDrvname;
- WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
- data.Interface = szInterface;
-
- data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
-
- TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
- (ppd->Callback)(&data, ppd->Context);
- }
- HeapFree(GetProcessHeap(),0,szInterface);
- }
- }
- HeapFree(GetProcessHeap(),0,nameW);
- }
- }
- }
-
- return S_OK;
- }
+ if (!ppd || !ppd->Callback)
+ {
+ WARN("Invalid ppd %p\n", ppd);
+ return E_PROP_ID_UNSUPPORTED;
}
- if (pcbReturned) {
- *pcbReturned = 0;
- FIXME("*pcbReturned=%d\n", *pcbReturned);
- }
+ data.Callback = DSPROPERTY_enumWto1;
+ data.Context = ppd;
- return E_PROP_ID_UNSUPPORTED;
+ return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
}
-static HRESULT DSPROPERTY_EnumerateW(
+static HRESULT DSPROPERTY_DescriptionA(
LPVOID pPropData,
ULONG cbPropData,
- PULONG pcbReturned )
+ PULONG pcbReturned)
{
- PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
- HRESULT err;
- TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
- pPropData,cbPropData,pcbReturned);
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
+ HRESULT hr;
- if (ppd) {
- if (ppd->Callback) {
- unsigned devs, wod, wid;
- DSDRIVERDESC desc;
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
-
- devs = waveOutGetNumDevs();
- for (wod = 0; wod < devs; ++wod) {
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
- if (wDescription && wModule) {
- DWORD size;
- err = mmErr(waveOutMessage(UlongToHandle(wod),DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
- if (err == DS_OK) {
- WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
- if (wInterface) {
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- ZeroMemory(&data, sizeof(data));
- data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
- data.WaveDeviceId = wod;
- data.DeviceId = DSOUND_renderer_guids[wod];
-
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
-
- data.Description = wDescription;
- data.Module = wModule;
- data.Interface = wInterface;
-
- data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- err = mmErr(waveOutMessage(UlongToHandle(wod), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
-
- TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
- (ppd->Callback)(&data, ppd->Context);
- }
- }
- HeapFree(GetProcessHeap(),0,wInterface);
- }
- }
- HeapFree(GetProcessHeap(),0,wDescription);
- HeapFree(GetProcessHeap(),0,wModule);
- }
- }
-
- devs = waveInGetNumDevs();
- for (wid = 0; wid < devs; ++wid) {
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
- if (err == DS_OK) {
- WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
- WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
- if (wDescription && wModule) {
- DWORD size;
- err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
- if (err == DS_OK) {
- WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
- if (wInterface) {
- err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
- if (err == DS_OK) {
- PIDSCDRIVER drv;
- ZeroMemory(&data, sizeof(data));
- data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
- data.WaveDeviceId = wid;
- data.DeviceId = DSOUND_capture_guids[wid];
-
- MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
- MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
-
- data.Description = wDescription;
- data.Module = wModule;
- data.Interface = wInterface;
- data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
- err = mmErr(waveInMessage(UlongToHandle(wid), DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
- if (err == DS_OK && drv)
- data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
- else
- WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
-
- TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
- (ppd->Callback)(&data, ppd->Context);
- }
- }
- HeapFree(GetProcessHeap(),0,wInterface);
- }
- }
- HeapFree(GetProcessHeap(),0,wDescription);
- HeapFree(GetProcessHeap(),0,wModule);
- }
- }
-
- return S_OK;
- }
- }
+ if (pcbReturned)
+ *pcbReturned = sizeof(*ppd);
+ if (!pPropData)
+ return S_OK;
- if (pcbReturned) {
- *pcbReturned = 0;
- FIXME("*pcbReturned=%d\n", *pcbReturned);
- }
+ data.DeviceId = ppd->DeviceId;
+ data.DataFlow = ppd->DataFlow;
+ hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
+ if (FAILED(hr))
+ return hr;
+ if (!DSPROPERTY_descWtoA(&data, ppd))
+ hr = E_OUTOFMEMORY;
+ HeapFree(GetProcessHeap(), 0, data.Module);
+ HeapFree(GetProcessHeap(), 0, data.Interface);
+ return hr;
+}
- return E_PROP_ID_UNSUPPORTED;
+static HRESULT DSPROPERTY_Description1(
+ LPVOID pPropData,
+ ULONG cbPropData,
+ PULONG pcbReturned)
+{
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
+ DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
+ HRESULT hr;
+
+ if (pcbReturned)
+ *pcbReturned = sizeof(*ppd);
+ if (!pPropData)
+ return S_OK;
+
+ data.DeviceId = ppd->DeviceId;
+ data.DataFlow = ppd->DataFlow;
+ hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
+ if (FAILED(hr))
+ return hr;
+ DSPROPERTY_descWto1(&data, ppd);
+ HeapFree(GetProcessHeap(), 0, data.Module);
+ HeapFree(GetProcessHeap(), 0, data.Interface);
+ return hr;
}
static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
ULONG cbPropData,
PULONG pcbReturned )
{
- IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
+ IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
LPVOID pPropData,
ULONG cbPropData )
{
- IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
+ IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
return E_PROP_ID_UNSUPPORTED;
ULONG dwPropID,
PULONG pTypeSupport )
{
- IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
+ IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
IKsPrivatePropertySetImpl_QuerySupport
};
-HRESULT IKsPrivatePropertySetImpl_Create(
- REFIID riid,
- IKsPrivatePropertySetImpl **piks)
+HRESULT IKsPrivatePropertySetImpl_Create(REFIID riid, void **ppv)
{
IKsPrivatePropertySetImpl *iks;
- TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
+ HRESULT hr;
- if (!IsEqualIID(riid, &IID_IUnknown) &&
- !IsEqualIID(riid, &IID_IKsPropertySet)) {
- *piks = 0;
- return E_NOINTERFACE;
+ TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
+
+ iks = HeapAlloc(GetProcessHeap(), 0, sizeof(*iks));
+ if (!iks) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
}
- iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
iks->ref = 1;
- iks->lpVtbl = &ikspvt;
+ iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
- *piks = iks;
- return S_OK;
+ hr = IKsPropertySet_QueryInterface(&iks->IKsPropertySet_iface, riid, ppv);
+ IKsPropertySet_Release(&iks->IKsPropertySet_iface);
+
+ return hr;
}
+++ /dev/null
-/*
- * self-registerable dll functions for dsound.dll
- *
- * Copyright (C) 2003 John K. Hohm
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#include <windef.h>
-#include <winbase.h>
-//#include "winuser.h"
-#include <winreg.h>
-
-#include <mmsystem.h>
-#include <dsound.h>
-
-#include <wine/debug.h>
-#include <wine/unicode.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-
-static LSTATUS (WINAPI *pRegDeleteTreeW)(HKEY,LPCWSTR);
-static LSTATUS (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
-
-/*
- * Near the bottom of this file are the exported DllRegisterServer and
- * DllUnregisterServer, which make all this worthwhile.
- */
-
-/***********************************************************************
- * interface for self-registering
- */
-struct regsvr_interface
-{
- IID const *iid; /* NULL for end of list */
- LPCSTR name; /* can be NULL to omit */
- IID const *base_iid; /* can be NULL to omit */
- int num_methods; /* can be <0 to omit */
- CLSID const *ps_clsid; /* can be NULL to omit */
- CLSID const *ps_clsid32; /* can be NULL to omit */
-};
-
-static HRESULT register_interfaces(struct regsvr_interface const *list);
-static HRESULT unregister_interfaces(struct regsvr_interface const *list);
-
-struct regsvr_coclass
-{
- CLSID const *clsid; /* NULL for end of list */
- LPCSTR name; /* can be NULL to omit */
- LPCSTR ips; /* can be NULL to omit */
- LPCSTR ips32; /* can be NULL to omit */
- LPCSTR ips32_tmodel; /* can be NULL to omit */
- LPCSTR progid; /* can be NULL to omit */
- LPCSTR viprogid; /* can be NULL to omit */
- LPCSTR progid_extra; /* can be NULL to omit */
-};
-
-static HRESULT register_coclasses(struct regsvr_coclass const *list);
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
-
-/***********************************************************************
- * static string constants
- */
-static WCHAR const interface_keyname[10] = {
- 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
-static WCHAR const base_ifa_keyname[14] = {
- 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
- 'e', 0 };
-static WCHAR const num_methods_keyname[11] = {
- 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
-static WCHAR const ps_clsid_keyname[15] = {
- 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
- 'i', 'd', 0 };
-static WCHAR const ps_clsid32_keyname[17] = {
- 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
- 'i', 'd', '3', '2', 0 };
-static WCHAR const clsid_keyname[6] = {
- 'C', 'L', 'S', 'I', 'D', 0 };
-static WCHAR const curver_keyname[7] = {
- 'C', 'u', 'r', 'V', 'e', 'r', 0 };
-static WCHAR const ips_keyname[13] = {
- 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
- 0 };
-static WCHAR const ips32_keyname[15] = {
- 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
- '3', '2', 0 };
-static WCHAR const progid_keyname[7] = {
- 'P', 'r', 'o', 'g', 'I', 'D', 0 };
-static WCHAR const viprogid_keyname[25] = {
- 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
- 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
- 0 };
-static char const tmodel_valuename[] = "ThreadingModel";
-
-/***********************************************************************
- * static helper functions
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
-static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
- WCHAR const *value);
-static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
- char const *value);
-static LONG register_progid(WCHAR const *clsid,
- char const *progid, char const *curver_progid,
- char const *name, char const *extra);
-
-/***********************************************************************
- * register_interfaces
- */
-static HRESULT register_interfaces(struct regsvr_interface const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY interface_key;
-
- res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->iid; ++list) {
- WCHAR buf[39];
- HKEY iid_key;
-
- StringFromGUID2(list->iid, buf, 39);
- res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_interface_key;
-
- if (list->name) {
- res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
- (CONST BYTE*)(list->name),
- strlen(list->name) + 1);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (list->base_iid) {
- res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (0 <= list->num_methods) {
- static WCHAR const fmt[3] = { '%', 'd', 0 };
- HKEY key;
-
- res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
-
- sprintfW(buf, fmt, list->num_methods);
- res = RegSetValueExW(key, NULL, 0, REG_SZ,
- (CONST BYTE*)buf,
- (lstrlenW(buf) + 1) * sizeof(WCHAR));
- RegCloseKey(key);
-
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (list->ps_clsid) {
- res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- if (list->ps_clsid32) {
- res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
- if (res != ERROR_SUCCESS) goto error_close_iid_key;
- }
-
- error_close_iid_key:
- RegCloseKey(iid_key);
- }
-
-error_close_interface_key:
- RegCloseKey(interface_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * unregister_interfaces
- */
-static HRESULT unregister_interfaces(struct regsvr_interface const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY interface_key;
-
- res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
- KEY_READ | KEY_WRITE, &interface_key);
- if (res == ERROR_FILE_NOT_FOUND) return S_OK;
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->iid; ++list) {
- WCHAR buf[39];
-
- StringFromGUID2(list->iid, buf, 39);
- res = pRegDeleteTreeW(interface_key, buf);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- }
-
- RegCloseKey(interface_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * register_coclasses
- */
-static HRESULT register_coclasses(struct regsvr_coclass const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY coclass_key;
-
- res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->clsid; ++list) {
- WCHAR buf[39];
- HKEY clsid_key;
-
- StringFromGUID2(list->clsid, buf, 39);
- res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
- if (list->name) {
- res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
- (CONST BYTE*)(list->name),
- strlen(list->name) + 1);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->ips) {
- res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->ips32) {
- HKEY ips32_key;
-
- res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL,
- &ips32_key, NULL);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
- res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
- (CONST BYTE*)list->ips32,
- lstrlenA(list->ips32) + 1);
- if (res == ERROR_SUCCESS && list->ips32_tmodel)
- res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
- (CONST BYTE*)list->ips32_tmodel,
- strlen(list->ips32_tmodel) + 1);
- RegCloseKey(ips32_key);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->progid) {
- res = register_key_defvalueA(clsid_key, progid_keyname,
- list->progid);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
- res = register_progid(buf, list->progid, NULL,
- list->name, list->progid_extra);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- if (list->viprogid) {
- res = register_key_defvalueA(clsid_key, viprogid_keyname,
- list->viprogid);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
-
- res = register_progid(buf, list->viprogid, list->progid,
- list->name, list->progid_extra);
- if (res != ERROR_SUCCESS) goto error_close_clsid_key;
- }
-
- error_close_clsid_key:
- RegCloseKey(clsid_key);
- }
-
-error_close_coclass_key:
- RegCloseKey(coclass_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * unregister_coclasses
- */
-static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
-{
- LONG res = ERROR_SUCCESS;
- HKEY coclass_key;
-
- res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
- KEY_READ | KEY_WRITE, &coclass_key);
- if (res == ERROR_FILE_NOT_FOUND) return S_OK;
- if (res != ERROR_SUCCESS) goto error_return;
-
- for (; res == ERROR_SUCCESS && list->clsid; ++list) {
- WCHAR buf[39];
-
- StringFromGUID2(list->clsid, buf, 39);
- res = pRegDeleteTreeW(coclass_key, buf);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
-
- if (list->progid) {
- res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
- }
-
- if (list->viprogid) {
- res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
- if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
- if (res != ERROR_SUCCESS) goto error_close_coclass_key;
- }
- }
-
-error_close_coclass_key:
- RegCloseKey(coclass_key);
-error_return:
- return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
-}
-
-/***********************************************************************
- * regsvr_key_guid
- */
-static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
-{
- WCHAR buf[39];
-
- StringFromGUID2(guid, buf, 39);
- return register_key_defvalueW(base, name, buf);
-}
-
-/***********************************************************************
- * regsvr_key_defvalueW
- */
-static LONG register_key_defvalueW(
- HKEY base,
- WCHAR const *name,
- WCHAR const *value)
-{
- LONG res;
- HKEY key;
-
- res = RegCreateKeyExW(base, name, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &key, NULL);
- if (res != ERROR_SUCCESS) return res;
- res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
- (lstrlenW(value) + 1) * sizeof(WCHAR));
- RegCloseKey(key);
- return res;
-}
-
-/***********************************************************************
- * regsvr_key_defvalueA
- */
-static LONG register_key_defvalueA(
- HKEY base,
- WCHAR const *name,
- char const *value)
-{
- LONG res;
- HKEY key;
-
- res = RegCreateKeyExW(base, name, 0, NULL, 0,
- KEY_READ | KEY_WRITE, NULL, &key, NULL);
- if (res != ERROR_SUCCESS) return res;
- res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
- lstrlenA(value) + 1);
- RegCloseKey(key);
- return res;
-}
-
-/***********************************************************************
- * regsvr_progid
- */
-static LONG register_progid(
- WCHAR const *clsid,
- char const *progid,
- char const *curver_progid,
- char const *name,
- char const *extra)
-{
- LONG res;
- HKEY progid_key;
-
- res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
- NULL, 0, KEY_READ | KEY_WRITE, NULL,
- &progid_key, NULL);
- if (res != ERROR_SUCCESS) return res;
-
- if (name) {
- res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
- (CONST BYTE*)name, strlen(name) + 1);
- if (res != ERROR_SUCCESS) goto error_close_progid_key;
- }
-
- if (clsid) {
- res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
- if (res != ERROR_SUCCESS) goto error_close_progid_key;
- }
-
- if (curver_progid) {
- res = register_key_defvalueA(progid_key, curver_keyname,
- curver_progid);
- if (res != ERROR_SUCCESS) goto error_close_progid_key;
- }
-
- if (extra) {
- HKEY extra_key;
-
- res = RegCreateKeyExA(progid_key, extra, 0,
- NULL, 0, KEY_READ | KEY_WRITE, NULL,
- &extra_key, NULL);
- if (res == ERROR_SUCCESS)
- RegCloseKey(extra_key);
- }
-
-error_close_progid_key:
- RegCloseKey(progid_key);
- return res;
-}
-
-/***********************************************************************
- * coclass list
- */
-static GUID const CLSID_DirectSoundBufferConfig = {
- 0xB2F586D4, 0x5558, 0x49D1, {0xA0,0x7B,0x32,0x49,0xDB,0xBB,0x33,0xC2} };
-
-static struct regsvr_coclass const coclass_list[] = {
- { &CLSID_DirectSound,
- "DirectSound Object",
- NULL,
- "dsound.dll",
- "Both"
- },
- { &CLSID_DirectSound8,
- "DirectSound 8.0 Object",
- NULL,
- "dsound.dll",
- "Both"
- },
- { &CLSID_DirectSoundBufferConfig,
- "DirectSoundBufferConfig Object",
- NULL,
- "dsound.dll",
- "Both"
- },
- { &CLSID_DirectSoundCapture,
- "DirectSoundCapture Object",
- NULL,
- "dsound.dll",
- "Both"
- },
- { &CLSID_DirectSoundCapture8,
- "DirectSoundCapture 8.0 Object",
- NULL,
- "dsound.dll",
- "Both"
- },
- { &CLSID_DirectSoundFullDuplex,
- "DirectSoundFullDuplex Object",
- NULL,
- "dsound.dll",
- "Both"
- },
- { NULL } /* list terminator */
-};
-
-/***********************************************************************
- * interface list
- */
-
-static struct regsvr_interface const interface_list[] = {
- { NULL } /* list terminator */
-};
-
-/***********************************************************************
- * DllRegisterServer (DSOUND.@)
- */
-HRESULT WINAPI DllRegisterServer(void)
-{
- HRESULT hr;
-
- TRACE("\n");
-
- hr = register_coclasses(coclass_list);
- if (SUCCEEDED(hr))
- hr = register_interfaces(interface_list);
- return hr;
-}
-
-/***********************************************************************
- * DllUnregisterServer (DSOUND.@)
- */
-HRESULT WINAPI DllUnregisterServer(void)
-{
- HRESULT hr;
-
- HMODULE advapi32 = GetModuleHandleA("advapi32");
- if (!advapi32) return E_FAIL;
- pRegDeleteTreeA = (void *) GetProcAddress(advapi32, "RegDeleteTreeA");
- pRegDeleteTreeW = (void *) GetProcAddress(advapi32, "RegDeleteTreeW");
- if (!pRegDeleteTreeA || !pRegDeleteTreeW) return E_FAIL;
-
- TRACE("\n");
-
- hr = unregister_coclasses(coclass_list);
- if (SUCCEEDED(hr))
- hr = unregister_interfaces(interface_list);
- return hr;
-}
//#include "mmddk.h"
#include <wine/debug.h>
#include <dsound.h>
-#include <dsdriver.h>
#include "dsound_private.h"
/* default velocity of sound in the air */
* Auxiliary functions
*/
-/* scalar product (i believe it's called dot product in english) */
+/* scalar product (I believe it's called dot product in English) */
static inline D3DVALUE ScalarProduct (const D3DVECTOR *a, const D3DVECTOR *b)
{
D3DVALUE c;
return c;
}
-/* vector product (i believe it's called cross product in english */
+/* vector product (I believe it's called cross product in English */
static inline D3DVECTOR VectorProduct (const D3DVECTOR *a, const D3DVECTOR *b)
{
D3DVECTOR c;
D3DVALUE flAngle;
D3DVECTOR vLeft;
/* doppler shift related stuff */
-#if 0
- D3DVALUE flFreq, flBufferVel, flListenerVel;
-#endif
TRACE("(%p)\n",dsb);
TRACE("panning: Angle = %f rad, lPan = %d\n", flAngle, dsb->volpan.lPan);
/* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */
-#if 0
+if(0)
+{
+ D3DVALUE flFreq, flBufferVel, flListenerVel;
/* doppler shift*/
- if ((VectorMagnitude(&ds3db_ds3db.vVelocity) == 0) && (VectorMagnitude(&dsb->device->ds3dl.vVelocity) == 0))
+ if (!VectorMagnitude(&dsb->ds3db_ds3db.vVelocity) && !VectorMagnitude(&dsb->device->ds3dl.vVelocity))
{
TRACE("doppler: Buffer and Listener don't have velocities\n");
}
- else if (ds3db_ds3db.vVelocity != dsb->device->ds3dl.vVelocity)
+ else if (!(dsb->ds3db_ds3db.vVelocity.x == dsb->device->ds3dl.vVelocity.x &&
+ dsb->ds3db_ds3db.vVelocity.y == dsb->device->ds3dl.vVelocity.y &&
+ dsb->ds3db_ds3db.vVelocity.z == dsb->device->ds3dl.vVelocity.z))
{
/* calculate length of ds3db_ds3db.vVelocity component which causes Doppler Effect
NOTE: if buffer moves TOWARDS the listener, it's velocity component is NEGATIVE
/* formula taken from Gianicoli D.: Physics, 4th edition: */
/* FIXME: replace dsb->freq with appropriate frequency ! */
flFreq = dsb->freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel));
- TRACE("doppler: Buffer velocity (component) = %lf, Listener velocity (component) = %lf => Doppler shift: %ld Hz -> %lf Hz\n", flBufferVel, flListenerVel,
- dsb->freq, flFreq);
+ TRACE("doppler: Buffer velocity (component) = %f, Listener velocity (component) = %f => Doppler shift: %d Hz -> %f Hz\n",
+ flBufferVel, flListenerVel, dsb->freq, flFreq);
/* FIXME: replace following line with correct frequency setting ! */
dsb->freq = flFreq;
DSOUND_RecalcFormat(dsb);
- DSOUND_MixToTemporary(dsb, 0, dsb->buflen);
}
-#endif
+}
/* time for remix */
DSOUND_RecalcVolPan(&dsb->volpan);
DSOUND_Calc3DBuffer(dsb);
}
-static void DSOUND_ChangeListener(IDirectSound3DListenerImpl *ds3dl)
+static void DSOUND_ChangeListener(IDirectSoundBufferImpl *ds3dl)
{
int i;
TRACE("(%p)\n",ds3dl);
/*******************************************************************************
* IDirectSound3DBuffer
*/
+static inline IDirectSoundBufferImpl *impl_from_IDirectSound3DBuffer(IDirectSound3DBuffer *iface)
+{
+ return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSound3DBuffer_iface);
+}
/* IUnknown methods */
-static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface(
- LPDIRECTSOUND3DBUFFER iface, REFIID riid, LPVOID *ppobj)
+static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface(IDirectSound3DBuffer *iface,
+ REFIID riid, void **ppobj)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
+ return IDirectSoundBuffer8_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj);
}
-static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(LPDIRECTSOUND3DBUFFER iface)
+static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(IDirectSound3DBuffer *iface)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+ ULONG ref = InterlockedIncrement(&This->ref3D);
+
TRACE("(%p) ref was %d\n", This, ref - 1);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+
return ref;
}
-static ULONG WINAPI IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface)
+static ULONG WINAPI IDirectSound3DBufferImpl_Release(IDirectSound3DBuffer *iface)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+ ULONG ref = InterlockedDecrement(&This->ref3D);
+
TRACE("(%p) ref was %d\n", This, ref + 1);
- if (!ref) {
- This->dsb->ds3db = NULL;
- IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
+ if (!ref && !InterlockedDecrement(&This->numIfaces))
+ secondarybuffer_destroy(This);
+
return ref;
}
/* IDirectSound3DBuffer methods */
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters(
- LPDIRECTSOUND3DBUFFER iface,
- LPDS3DBUFFER lpDs3dBuffer)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters(IDirectSound3DBuffer *iface,
+ DS3DBUFFER *lpDs3dBuffer)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
TRACE("(%p,%p)\n",This,lpDs3dBuffer);
if (lpDs3dBuffer == NULL) {
}
TRACE("returning: all parameters\n");
- *lpDs3dBuffer = This->dsb->ds3db_ds3db;
+ *lpDs3dBuffer = This->ds3db_ds3db;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles(
- LPDIRECTSOUND3DBUFFER iface,
- LPDWORD lpdwInsideConeAngle,
- LPDWORD lpdwOutsideConeAngle)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles(IDirectSound3DBuffer *iface,
+ DWORD *lpdwInsideConeAngle, DWORD *lpdwOutsideConeAngle)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Inside Cone Angle = %d degrees; Outside Cone Angle = %d degrees\n",
- This->dsb->ds3db_ds3db.dwInsideConeAngle, This->dsb->ds3db_ds3db.dwOutsideConeAngle);
- *lpdwInsideConeAngle = This->dsb->ds3db_ds3db.dwInsideConeAngle;
- *lpdwOutsideConeAngle = This->dsb->ds3db_ds3db.dwOutsideConeAngle;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Inside Cone Angle = %d degrees; Outside Cone Angle = %d degrees\n",
+ This->ds3db_ds3db.dwInsideConeAngle, This->ds3db_ds3db.dwOutsideConeAngle);
+ *lpdwInsideConeAngle = This->ds3db_ds3db.dwInsideConeAngle;
+ *lpdwOutsideConeAngle = This->ds3db_ds3db.dwOutsideConeAngle;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation(
- LPDIRECTSOUND3DBUFFER iface,
- LPD3DVECTOR lpvConeOrientation)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation(IDirectSound3DBuffer *iface,
+ D3DVECTOR *lpvConeOrientation)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n",
- This->dsb->ds3db_ds3db.vConeOrientation.x,
- This->dsb->ds3db_ds3db.vConeOrientation.y,
- This->dsb->ds3db_ds3db.vConeOrientation.z);
- *lpvConeOrientation = This->dsb->ds3db_ds3db.vConeOrientation;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n",
+ This->ds3db_ds3db.vConeOrientation.x,
+ This->ds3db_ds3db.vConeOrientation.y,
+ This->ds3db_ds3db.vConeOrientation.z);
+ *lpvConeOrientation = This->ds3db_ds3db.vConeOrientation;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume(
- LPDIRECTSOUND3DBUFFER iface,
- LPLONG lplConeOutsideVolume)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume(IDirectSound3DBuffer *iface,
+ LONG *lplConeOutsideVolume)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Cone Outside Volume = %d\n", This->dsb->ds3db_ds3db.lConeOutsideVolume);
- *lplConeOutsideVolume = This->dsb->ds3db_ds3db.lConeOutsideVolume;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Cone Outside Volume = %d\n", This->ds3db_ds3db.lConeOutsideVolume);
+ *lplConeOutsideVolume = This->ds3db_ds3db.lConeOutsideVolume;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance(
- LPDIRECTSOUND3DBUFFER iface,
- LPD3DVALUE lpfMaxDistance)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance(IDirectSound3DBuffer *iface,
+ D3DVALUE *lpfMaxDistance)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Max Distance = %f\n", This->dsb->ds3db_ds3db.flMaxDistance);
- *lpfMaxDistance = This->dsb->ds3db_ds3db.flMaxDistance;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Max Distance = %f\n", This->ds3db_ds3db.flMaxDistance);
+ *lpfMaxDistance = This->ds3db_ds3db.flMaxDistance;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance(
- LPDIRECTSOUND3DBUFFER iface,
- LPD3DVALUE lpfMinDistance)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance(IDirectSound3DBuffer *iface,
+ D3DVALUE *lpfMinDistance)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Min Distance = %f\n", This->dsb->ds3db_ds3db.flMinDistance);
- *lpfMinDistance = This->dsb->ds3db_ds3db.flMinDistance;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Min Distance = %f\n", This->ds3db_ds3db.flMinDistance);
+ *lpfMinDistance = This->ds3db_ds3db.flMinDistance;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode(
- LPDIRECTSOUND3DBUFFER iface,
- LPDWORD lpdwMode)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode(IDirectSound3DBuffer *iface,
+ DWORD *lpdwMode)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Mode = %d\n", This->dsb->ds3db_ds3db.dwMode);
- *lpdwMode = This->dsb->ds3db_ds3db.dwMode;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Mode = %d\n", This->ds3db_ds3db.dwMode);
+ *lpdwMode = This->ds3db_ds3db.dwMode;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition(
- LPDIRECTSOUND3DBUFFER iface,
- LPD3DVECTOR lpvPosition)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition(IDirectSound3DBuffer *iface,
+ D3DVECTOR *lpvPosition)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Position vector = (%f,%f,%f)\n",
- This->dsb->ds3db_ds3db.vPosition.x,
- This->dsb->ds3db_ds3db.vPosition.y,
- This->dsb->ds3db_ds3db.vPosition.z);
- *lpvPosition = This->dsb->ds3db_ds3db.vPosition;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Position vector = (%f,%f,%f)\n", This->ds3db_ds3db.vPosition.x,
+ This->ds3db_ds3db.vPosition.y, This->ds3db_ds3db.vPosition.z);
+ *lpvPosition = This->ds3db_ds3db.vPosition;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity(
- LPDIRECTSOUND3DBUFFER iface,
- LPD3DVECTOR lpvVelocity)
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity(IDirectSound3DBuffer *iface,
+ D3DVECTOR *lpvVelocity)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("returning: Velocity vector = (%f,%f,%f)\n",
- This->dsb->ds3db_ds3db.vVelocity.x,
- This->dsb->ds3db_ds3db.vVelocity.y,
- This->dsb->ds3db_ds3db.vVelocity.z);
- *lpvVelocity = This->dsb->ds3db_ds3db.vVelocity;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->ds3db_ds3db.vVelocity.x,
+ This->ds3db_ds3db.vVelocity.y, This->ds3db_ds3db.vVelocity.z);
+ *lpvVelocity = This->ds3db_ds3db.vVelocity;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(
- LPDIRECTSOUND3DBUFFER iface,
- LPCDS3DBUFFER lpcDs3dBuffer,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(IDirectSound3DBuffer *iface,
+ const DS3DBUFFER *lpcDs3dBuffer, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
DWORD status = DSERR_INVALIDPARAM;
+
TRACE("(%p,%p,%x)\n",iface,lpcDs3dBuffer,dwApply);
if (lpcDs3dBuffer == NULL) {
}
TRACE("setting: all parameters; dwApply = %d\n", dwApply);
- This->dsb->ds3db_ds3db = *lpcDs3dBuffer;
+ This->ds3db_ds3db = *lpcDs3dBuffer;
if (dwApply == DS3D_IMMEDIATE)
{
- DSOUND_Mix3DBuffer(This->dsb);
+ DSOUND_Mix3DBuffer(This);
}
- This->dsb->ds3db_need_recalc = TRUE;
+ This->ds3db_need_recalc = TRUE;
status = DS_OK;
return status;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles(
- LPDIRECTSOUND3DBUFFER iface,
- DWORD dwInsideConeAngle,
- DWORD dwOutsideConeAngle,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles(IDirectSound3DBuffer *iface,
+ DWORD dwInsideConeAngle, DWORD dwOutsideConeAngle, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: Inside Cone Angle = %d; Outside Cone Angle = %d; dwApply = %d\n",
- dwInsideConeAngle, dwOutsideConeAngle, dwApply);
- This->dsb->ds3db_ds3db.dwInsideConeAngle = dwInsideConeAngle;
- This->dsb->ds3db_ds3db.dwOutsideConeAngle = dwOutsideConeAngle;
- if (dwApply == DS3D_IMMEDIATE)
- {
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: Inside Cone Angle = %d; Outside Cone Angle = %d; dwApply = %d\n",
+ dwInsideConeAngle, dwOutsideConeAngle, dwApply);
+ This->ds3db_ds3db.dwInsideConeAngle = dwInsideConeAngle;
+ This->ds3db_ds3db.dwOutsideConeAngle = dwOutsideConeAngle;
+ if (dwApply == DS3D_IMMEDIATE)
+ DSOUND_Mix3DBuffer(This);
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(
- LPDIRECTSOUND3DBUFFER iface,
- D3DVALUE x, D3DVALUE y, D3DVALUE z,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(IDirectSound3DBuffer *iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
- This->dsb->ds3db_ds3db.vConeOrientation.x = x;
- This->dsb->ds3db_ds3db.vConeOrientation.y = y;
- This->dsb->ds3db_ds3db.vConeOrientation.z = z;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
+ This->ds3db_ds3db.vConeOrientation.x = x;
+ This->ds3db_ds3db.vConeOrientation.y = y;
+ This->ds3db_ds3db.vConeOrientation.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(
- LPDIRECTSOUND3DBUFFER iface,
- LONG lConeOutsideVolume,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(IDirectSound3DBuffer *iface,
+ LONG lConeOutsideVolume, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: ConeOutsideVolume = %d; dwApply = %d\n", lConeOutsideVolume, dwApply);
- This->dsb->ds3db_ds3db.lConeOutsideVolume = lConeOutsideVolume;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: ConeOutsideVolume = %d; dwApply = %d\n", lConeOutsideVolume, dwApply);
+ This->ds3db_ds3db.lConeOutsideVolume = lConeOutsideVolume;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(
- LPDIRECTSOUND3DBUFFER iface,
- D3DVALUE fMaxDistance,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(IDirectSound3DBuffer *iface,
+ D3DVALUE fMaxDistance, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: MaxDistance = %f; dwApply = %d\n", fMaxDistance, dwApply);
- This->dsb->ds3db_ds3db.flMaxDistance = fMaxDistance;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: MaxDistance = %f; dwApply = %d\n", fMaxDistance, dwApply);
+ This->ds3db_ds3db.flMaxDistance = fMaxDistance;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(
- LPDIRECTSOUND3DBUFFER iface,
- D3DVALUE fMinDistance,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(IDirectSound3DBuffer *iface,
+ D3DVALUE fMinDistance, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: MinDistance = %f; dwApply = %d\n", fMinDistance, dwApply);
- This->dsb->ds3db_ds3db.flMinDistance = fMinDistance;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: MinDistance = %f; dwApply = %d\n", fMinDistance, dwApply);
+ This->ds3db_ds3db.flMinDistance = fMinDistance;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(
- LPDIRECTSOUND3DBUFFER iface,
- DWORD dwMode,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(IDirectSound3DBuffer *iface, DWORD dwMode,
+ DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: Mode = %d; dwApply = %d\n", dwMode, dwApply);
- This->dsb->ds3db_ds3db.dwMode = dwMode;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: Mode = %d; dwApply = %d\n", dwMode, dwApply);
+ This->ds3db_ds3db.dwMode = dwMode;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(
- LPDIRECTSOUND3DBUFFER iface,
- D3DVALUE x, D3DVALUE y, D3DVALUE z,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(IDirectSound3DBuffer *iface, D3DVALUE x,
+ D3DVALUE y, D3DVALUE z, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
- This->dsb->ds3db_ds3db.vPosition.x = x;
- This->dsb->ds3db_ds3db.vPosition.y = y;
- This->dsb->ds3db_ds3db.vPosition.z = z;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
+ This->ds3db_ds3db.vPosition.x = x;
+ This->ds3db_ds3db.vPosition.y = y;
+ This->ds3db_ds3db.vPosition.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(
- LPDIRECTSOUND3DBUFFER iface,
- D3DVALUE x, D3DVALUE y, D3DVALUE z,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(IDirectSound3DBuffer *iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply)
{
- IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface;
- TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
- This->dsb->ds3db_ds3db.vVelocity.x = x;
- This->dsb->ds3db_ds3db.vVelocity.y = y;
- This->dsb->ds3db_ds3db.vVelocity.z = z;
- if (dwApply == DS3D_IMMEDIATE)
- {
- This->dsb->ds3db_need_recalc = FALSE;
- DSOUND_Mix3DBuffer(This->dsb);
- }
- This->dsb->ds3db_need_recalc = TRUE;
- return DS_OK;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
+
+ TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
+ This->ds3db_ds3db.vVelocity.x = x;
+ This->ds3db_ds3db.vVelocity.y = y;
+ This->ds3db_ds3db.vVelocity.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This);
+ }
+ This->ds3db_need_recalc = TRUE;
+ return DS_OK;
}
-static const IDirectSound3DBufferVtbl ds3dbvt =
+const IDirectSound3DBufferVtbl ds3dbvt =
{
/* IUnknown methods */
IDirectSound3DBufferImpl_QueryInterface,
IDirectSound3DBufferImpl_SetVelocity,
};
-HRESULT IDirectSound3DBufferImpl_Create(
- IDirectSoundBufferImpl *dsb,
- IDirectSound3DBufferImpl **pds3db)
-{
- IDirectSound3DBufferImpl *ds3db;
- TRACE("(%p,%p)\n",dsb,pds3db);
-
- ds3db = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
-
- if (ds3db == NULL) {
- WARN("out of memory\n");
- *pds3db = 0;
- return DSERR_OUTOFMEMORY;
- }
-
- ds3db->ref = 0;
- ds3db->dsb = dsb;
- ds3db->lpVtbl = &ds3dbvt;
-
- ds3db->dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
- ds3db->dsb->ds3db_ds3db.vPosition.x = 0.0;
- ds3db->dsb->ds3db_ds3db.vPosition.y = 0.0;
- ds3db->dsb->ds3db_ds3db.vPosition.z = 0.0;
- ds3db->dsb->ds3db_ds3db.vVelocity.x = 0.0;
- ds3db->dsb->ds3db_ds3db.vVelocity.y = 0.0;
- ds3db->dsb->ds3db_ds3db.vVelocity.z = 0.0;
- ds3db->dsb->ds3db_ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
- ds3db->dsb->ds3db_ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
- ds3db->dsb->ds3db_ds3db.vConeOrientation.x = 0.0;
- ds3db->dsb->ds3db_ds3db.vConeOrientation.y = 0.0;
- ds3db->dsb->ds3db_ds3db.vConeOrientation.z = 0.0;
- ds3db->dsb->ds3db_ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME;
- ds3db->dsb->ds3db_ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE;
- ds3db->dsb->ds3db_ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE;
- ds3db->dsb->ds3db_ds3db.dwMode = DS3DMODE_NORMAL;
-
- ds3db->dsb->ds3db_need_recalc = TRUE;
-
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb);
-
- *pds3db = ds3db;
- return S_OK;
-}
-
-HRESULT IDirectSound3DBufferImpl_Destroy(
- IDirectSound3DBufferImpl *pds3db)
-{
- TRACE("(%p)\n",pds3db);
-
- while (IDirectSound3DBufferImpl_Release((LPDIRECTSOUND3DBUFFER)pds3db) > 0);
-
- return S_OK;
-}
/*******************************************************************************
* IDirectSound3DListener
*/
-
-/* IUnknown methods */
-static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface(
- LPDIRECTSOUND3DLISTENER iface, REFIID riid, LPVOID *ppobj)
+static inline IDirectSoundBufferImpl *impl_from_IDirectSound3DListener(IDirectSound3DListener *iface)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
-
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-
- if (ppobj == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
+ return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSound3DListener_iface);
+}
- *ppobj = NULL; /* assume failure */
- if ( IsEqualGUID(riid, &IID_IUnknown) ||
- IsEqualGUID(riid, &IID_IDirectSound3DListener ) ) {
- IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)This);
- *ppobj = This;
- return S_OK;
- }
+/* IUnknown methods */
+static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface(IDirectSound3DListener *iface,
+ REFIID riid, void **ppobj)
+{
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
- if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
- if (!This->device->primary)
- PrimaryBufferImpl_Create(This->device, &(This->device->primary), &(This->device->dsbd));
- if (This->device->primary) {
- *ppobj = This->device->primary;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj);
- return S_OK;
- }
- }
+ TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj);
- FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
- return E_NOINTERFACE;
+ return IDirectSoundBuffer_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj);
}
-static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface)
+static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(IDirectSound3DListener *iface)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+ ULONG ref = InterlockedIncrement(&This->ref3D);
+
TRACE("(%p) ref was %d\n", This, ref - 1);
+
+ if(ref == 1)
+ InterlockedIncrement(&This->numIfaces);
+
return ref;
}
-static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER iface)
+static ULONG WINAPI IDirectSound3DListenerImpl_Release(IDirectSound3DListener *iface)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %d\n", This, ref + 1);
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+ ULONG ref;
+
+ ref = capped_refcount_dec(&This->ref3D);
+ if(!ref)
+ capped_refcount_dec(&This->numIfaces);
+
+ TRACE("(%p) ref is now %d\n", This, ref);
- if (!ref) {
- This->device->listener = 0;
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
return ref;
}
/* IDirectSound3DListener methods */
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter(
- LPDIRECTSOUND3DLISTENER iface,
- LPDS3DLISTENER lpDS3DL)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter(IDirectSound3DListener *iface,
+ DS3DLISTENER *lpDS3DL)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("(%p,%p)\n",This,lpDS3DL);
if (lpDS3DL == NULL) {
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor(
- LPDIRECTSOUND3DLISTENER iface,
- LPD3DVALUE lpfDistanceFactor)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor(IDirectSound3DListener *iface,
+ D3DVALUE *lpfDistanceFactor)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("returning: Distance Factor = %f\n", This->device->ds3dl.flDistanceFactor);
*lpfDistanceFactor = This->device->ds3dl.flDistanceFactor;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor(
- LPDIRECTSOUND3DLISTENER iface,
- LPD3DVALUE lpfDopplerFactor)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor(IDirectSound3DListener *iface,
+ D3DVALUE *lpfDopplerFactor)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("returning: Doppler Factor = %f\n", This->device->ds3dl.flDopplerFactor);
*lpfDopplerFactor = This->device->ds3dl.flDopplerFactor;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation(
- LPDIRECTSOUND3DLISTENER iface,
- LPD3DVECTOR lpvOrientFront,
- LPD3DVECTOR lpvOrientTop)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation(IDirectSound3DListener *iface,
+ D3DVECTOR *lpvOrientFront, D3DVECTOR *lpvOrientTop)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("returning: OrientFront vector = (%f,%f,%f); OrientTop vector = (%f,%f,%f)\n", This->device->ds3dl.vOrientFront.x,
This->device->ds3dl.vOrientFront.y, This->device->ds3dl.vOrientFront.z, This->device->ds3dl.vOrientTop.x, This->device->ds3dl.vOrientTop.y,
This->device->ds3dl.vOrientTop.z);
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition(
- LPDIRECTSOUND3DLISTENER iface,
- LPD3DVECTOR lpvPosition)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition(IDirectSound3DListener *iface,
+ D3DVECTOR *lpvPosition)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("returning: Position vector = (%f,%f,%f)\n", This->device->ds3dl.vPosition.x, This->device->ds3dl.vPosition.y, This->device->ds3dl.vPosition.z);
*lpvPosition = This->device->ds3dl.vPosition;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor(
- LPDIRECTSOUND3DLISTENER iface,
- LPD3DVALUE lpfRolloffFactor)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor(IDirectSound3DListener *iface,
+ D3DVALUE *lpfRolloffFactor)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("returning: RolloffFactor = %f\n", This->device->ds3dl.flRolloffFactor);
*lpfRolloffFactor = This->device->ds3dl.flRolloffFactor;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity(
- LPDIRECTSOUND3DLISTENER iface,
- LPD3DVECTOR lpvVelocity)
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity(IDirectSound3DListener *iface,
+ D3DVECTOR *lpvVelocity)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->device->ds3dl.vVelocity.x, This->device->ds3dl.vVelocity.y, This->device->ds3dl.vVelocity.z);
*lpvVelocity = This->device->ds3dl.vVelocity;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters(
- LPDIRECTSOUND3DLISTENER iface,
- LPCDS3DLISTENER lpcDS3DL,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters(IDirectSound3DListener *iface,
+ const DS3DLISTENER *lpcDS3DL, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: all parameters; dwApply = %d\n", dwApply);
This->device->ds3dl = *lpcDS3DL;
if (dwApply == DS3D_IMMEDIATE)
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor(
- LPDIRECTSOUND3DLISTENER iface,
- D3DVALUE fDistanceFactor,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor(IDirectSound3DListener *iface,
+ D3DVALUE fDistanceFactor, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: Distance Factor = %f; dwApply = %d\n", fDistanceFactor, dwApply);
This->device->ds3dl.flDistanceFactor = fDistanceFactor;
if (dwApply == DS3D_IMMEDIATE)
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor(
- LPDIRECTSOUND3DLISTENER iface,
- D3DVALUE fDopplerFactor,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor(IDirectSound3DListener *iface,
+ D3DVALUE fDopplerFactor, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: Doppler Factor = %f; dwApply = %d\n", fDopplerFactor, dwApply);
This->device->ds3dl.flDopplerFactor = fDopplerFactor;
if (dwApply == DS3D_IMMEDIATE)
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation(
- LPDIRECTSOUND3DLISTENER iface,
- D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront,
- D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation(IDirectSound3DListener *iface,
+ D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront, D3DVALUE xTop, D3DVALUE yTop,
+ D3DVALUE zTop, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: Front vector = (%f,%f,%f); Top vector = (%f,%f,%f); dwApply = %d\n",
xFront, yFront, zFront, xTop, yTop, zTop, dwApply);
This->device->ds3dl.vOrientFront.x = xFront;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition(
- LPDIRECTSOUND3DLISTENER iface,
- D3DVALUE x, D3DVALUE y, D3DVALUE z,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition(IDirectSound3DListener *iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: Position vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
This->device->ds3dl.vPosition.x = x;
This->device->ds3dl.vPosition.y = y;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor(
- LPDIRECTSOUND3DLISTENER iface,
- D3DVALUE fRolloffFactor,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor(IDirectSound3DListener *iface,
+ D3DVALUE fRolloffFactor, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: Rolloff Factor = %f; dwApply = %d\n", fRolloffFactor, dwApply);
This->device->ds3dl.flRolloffFactor = fRolloffFactor;
if (dwApply == DS3D_IMMEDIATE)
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity(
- LPDIRECTSOUND3DLISTENER iface,
- D3DVALUE x, D3DVALUE y, D3DVALUE z,
- DWORD dwApply)
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity(IDirectSound3DListener *iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z, DWORD dwApply)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %d\n", x, y, z, dwApply);
This->device->ds3dl.vVelocity.x = x;
This->device->ds3dl.vVelocity.y = y;
return DS_OK;
}
-static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings(
- LPDIRECTSOUND3DLISTENER iface)
+static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings(IDirectSound3DListener *iface)
{
- IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface;
+ IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface);
+
TRACE("\n");
DSOUND_ChangeListener(This);
return DS_OK;
}
-static const IDirectSound3DListenerVtbl ds3dlvt =
+const IDirectSound3DListenerVtbl ds3dlvt =
{
/* IUnknown methods */
IDirectSound3DListenerImpl_QueryInterface,
IDirectSound3DListenerImpl_SetVelocity,
IDirectSound3DListenerImpl_CommitDeferredSettings,
};
-
-HRESULT IDirectSound3DListenerImpl_Create(
- DirectSoundDevice * device,
- IDirectSound3DListenerImpl ** ppdsl)
-{
- IDirectSound3DListenerImpl *pdsl;
- TRACE("(%p,%p)\n",device,ppdsl);
-
- pdsl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*pdsl));
-
- if (pdsl == NULL) {
- WARN("out of memory\n");
- *ppdsl = 0;
- return DSERR_OUTOFMEMORY;
- }
-
- pdsl->ref = 0;
- pdsl->lpVtbl = &ds3dlvt;
-
- pdsl->device = device;
-
- pdsl->device->ds3dl.dwSize = sizeof(DS3DLISTENER);
- pdsl->device->ds3dl.vPosition.x = 0.0;
- pdsl->device->ds3dl.vPosition.y = 0.0;
- pdsl->device->ds3dl.vPosition.z = 0.0;
- pdsl->device->ds3dl.vVelocity.x = 0.0;
- pdsl->device->ds3dl.vVelocity.y = 0.0;
- pdsl->device->ds3dl.vVelocity.z = 0.0;
- pdsl->device->ds3dl.vOrientFront.x = 0.0;
- pdsl->device->ds3dl.vOrientFront.y = 0.0;
- pdsl->device->ds3dl.vOrientFront.z = 1.0;
- pdsl->device->ds3dl.vOrientTop.x = 0.0;
- pdsl->device->ds3dl.vOrientTop.y = 1.0;
- pdsl->device->ds3dl.vOrientTop.z = 0.0;
- pdsl->device->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
- pdsl->device->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
- pdsl->device->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
-
- pdsl->device->ds3dl_need_recalc = TRUE;
-
- *ppdsl = pdsl;
- return S_OK;
-}
+++ /dev/null
-Makefile
-capture.ok
-ds3d.ok
-ds3d8.ok
-dsound.ok
-dsound8.ok
-propset.ok
-testlist.c
+++ /dev/null
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../../..
-SRCDIR = @srcdir@
-VPATH = @srcdir@
-TESTDLL = dsound.dll
-IMPORTS = dsound ole32 version user32 kernel32
-EXTRALIBS = -ldxguid -luuid -ldxerr8
-
-CTESTS = \
- capture.c \
- ds3d.c \
- ds3d8.c \
- dsound.c \
- dsound8.c \
- propset.c
-
-@MAKE_TEST_RULES@
-
-### Dependencies:
+++ /dev/null
-/*
- * Unit tests for capture functions
- *
- * Copyright (c) 2002 Francois Gouget
- * Copyright (c) 2003 Robert Reif
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#include <windows.h>
-
-#include <stdio.h>
-
-#include "wine/test.h"
-#include "dsound.h"
-#include "mmreg.h"
-#include "dxerr8.h"
-#include "dsconf.h"
-
-#include "dsound_test.h"
-
-#define NOTIFICATIONS 5
-
-static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
-static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
-
-static const char * get_format_str(WORD format)
-{
- static char msg[32];
-#define WAVE_FORMAT(f) case f: return #f
- switch (format) {
- WAVE_FORMAT(WAVE_FORMAT_PCM);
- WAVE_FORMAT(WAVE_FORMAT_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
- WAVE_FORMAT(WAVE_FORMAT_ALAW);
- WAVE_FORMAT(WAVE_FORMAT_MULAW);
- WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
- WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
- WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_SONARC);
- WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
- WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
- WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
- WAVE_FORMAT(WAVE_FORMAT_APTX);
- WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
- WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
- WAVE_FORMAT(WAVE_FORMAT_GSM610);
- WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
- WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
- WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
- WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
- WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
- WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
- WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_MPEG);
- WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
- WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
- WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
- WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
- WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
- WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
- WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
- WAVE_FORMAT(WAVE_FORMAT_OLICELP);
- WAVE_FORMAT(WAVE_FORMAT_OLISBC);
- WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
- WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
- WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
- }
-#undef WAVE_FORMAT
- sprintf(msg, "Unknown(0x%04x)", format);
- return msg;
-}
-
-static char * format_string(WAVEFORMATEX* wfx)
-{
- static char str[64];
-
- sprintf(str, "%5ldx%2dx%d %s",
- wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
- get_format_str(wfx->wFormatTag));
-
- return str;
-}
-
-static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco,
- BOOL initialized, LPCGUID lpGuid)
-{
- HRESULT rc;
- DSCCAPS dsccaps;
- int ref;
- IUnknown * unknown;
- IDirectSoundCapture * dsc;
-
- /* Try to Query for objects */
- rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IUnknown,
- (LPVOID*)&unknown);
- ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) "
- "failed: %s\n", DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSoundCapture_Release(unknown);
-
- rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture,
- (LPVOID*)&dsc);
- ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) "
- "failed: %s\n", DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSoundCapture_Release(dsc);
-
- if (initialized == FALSE) {
- /* try unitialized object */
- rc=IDirectSoundCapture_GetCaps(dsco,0);
- ok(rc==DSERR_UNINITIALIZED, "IDirectSoundCapture_GetCaps(NULL) "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "IDirectSoundCapture_Initialize() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DSERR_NODRIVER) {
- trace(" No Driver\n");
- goto EXIT;
- } else if (rc==E_FAIL) {
- trace(" No Device\n");
- goto EXIT;
- } else if (rc==DSERR_ALLOCATED) {
- trace(" Already In Use\n");
- goto EXIT;
- }
- }
-
- rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
- ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() "
- "should have returned DSERR_ALREADYINITIALIZED: %s\n",
- DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid caps buffer */
- rc=IDirectSoundCapture_GetCaps(dsco, 0);
- ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- ZeroMemory(&dsccaps, sizeof(dsccaps));
-
- /* DSOUND: Error: Invalid caps buffer */
- rc=IDirectSound_GetCaps(dsco, &dsccaps);
- ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- dsccaps.dwSize=sizeof(dsccaps);
-
- /* DSOUND: Running on a certified driver */
- rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
- ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSoundCapture_Release(dsco);
- ok(ref==0, "IDirectSoundCapture_Release() has %d references, "
- "should have 0\n", ref);
-}
-
-static void IDirectSoundCapture_tests(void)
-{
- HRESULT rc;
- LPDIRECTSOUNDCAPTURE dsco=NULL;
-
- trace("Testing IDirectSoundCapture\n");
-
- /* try the COM class factory method of creation with no device specified */
- rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSoundCapture, (void**)&dsco);
- ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==REGDB_E_CLASSNOTREG) {
- trace(" Class Not Registered\n");
- return;
- }
- if (dsco)
- IDirectSoundCapture_test(dsco, FALSE, NULL);
-
- /* try the COM class factory method of creation with default capture
- * device specified */
- rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSoundCapture, (void**)&dsco);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
- DXGetErrorString8(rc));
- if (dsco)
- IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultCapture);
-
- /* try the COM class factory method of creation with default voice
- * capture device specified */
- rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSoundCapture, (void**)&dsco);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
- DXGetErrorString8(rc));
- if (dsco)
- IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultVoiceCapture);
-
- /* try the COM class factory method of creation with a bad
- * IID specified */
- rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
- &CLSID_DirectSoundPrivate, (void**)&dsco);
- ok(rc==E_NOINTERFACE,
- "CoCreateInstance(CLSID_DirectSoundCapture,CLSID_DirectSoundPrivate) "
- "should have failed: %s\n",DXGetErrorString8(rc));
-
- /* try with no device specified */
- rc=pDirectSoundCaptureCreate(NULL,&dsco,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCaptureCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
- if (rc==S_OK && dsco)
- IDirectSoundCapture_test(dsco, TRUE, NULL);
-
- /* try with default capture device specified */
- rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultCapture,&dsco,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCaptureCreate(DSDEVID_DefaultCapture) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && dsco)
- IDirectSoundCapture_test(dsco, TRUE, NULL);
-
- /* try with default voice capture device specified */
- rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture,&dsco,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && dsco)
- IDirectSoundCapture_test(dsco, TRUE, NULL);
-
- /* try with a bad device specified */
- rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback,&dsco,NULL);
- ok(rc==DSERR_NODRIVER,
- "DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
- "should have failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && dsco)
- IDirectSoundCapture_Release(dsco);
-}
-
-typedef struct {
- char* wave;
- DWORD wave_len;
-
- LPDIRECTSOUNDCAPTUREBUFFER dscbo;
- LPWAVEFORMATEX wfx;
- DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
- HANDLE event[NOTIFICATIONS];
- LPDIRECTSOUNDNOTIFY notify;
-
- DWORD buffer_size;
- DWORD read;
- DWORD offset;
- DWORD size;
-
- DWORD last_pos;
-} capture_state_t;
-
-static int capture_buffer_service(capture_state_t* state)
-{
- HRESULT rc;
- LPVOID ptr1,ptr2;
- DWORD len1,len2;
- DWORD capture_pos,read_pos;
-
- rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
- &read_pos);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return 0;
-
- rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
- &ptr1,&len1,&ptr2,&len2,0);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return 0;
-
- rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return 0;
-
- state->offset = (state->offset + state->size) % state->buffer_size;
-
- return 1;
-}
-
-static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
- LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
-{
- HRESULT rc;
- DSCBCAPS dscbcaps;
- WAVEFORMATEX wfx;
- DWORD size,status;
- capture_state_t state;
- int i, ref;
-
- /* Private dsound.dll: Error: Invalid caps pointer */
- rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
- "have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- /* Private dsound.dll: Error: Invalid caps pointer */
- dscbcaps.dwSize=0;
- rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
- "have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- dscbcaps.dwSize=sizeof(dscbcaps);
- rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Caps: size = %ld flags=0x%08lx buffer size=%ld\n",
- dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
- }
-
- /* Query the format size. Note that it may not match sizeof(wfx) */
- /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
- * be non-NULL */
- rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
- "have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- size=0;
- rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
- ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
- "have returned the needed size: rc=%s, size=%ld\n",
- DXGetErrorString8(rc),size);
-
- rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Format: tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
- wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
- }
-
- /* Private dsound.dll: Error: Invalid status pointer */
- rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetStatus() should "
- "have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Status=0x%04lx\n",status);
- }
-
- ZeroMemory(&state, sizeof(state));
- state.dscbo=dscbo;
- state.wfx=&wfx;
- state.buffer_size = dscbcaps.dwBufferBytes;
- for (i = 0; i < NOTIFICATIONS; i++)
- state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
- state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
-
- rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
- (void **)&(state.notify));
- ok((rc==DS_OK)&&(state.notify!=NULL),
- "IDirectSoundCaptureBuffer_QueryInterface() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
-
- for (i = 0; i < NOTIFICATIONS; i++) {
- state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
- state.posnotify[i].hEventNotify = state.event[i];
- }
-
- rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,
- state.posnotify);
- ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
-
- ref=IDirectSoundNotify_Release(state.notify);
- ok(ref==0,"IDirectSoundNotify_Release(): has %d references, should have "
- "0\n",ref);
- if (ref!=0)
- return;
-
- if (record) {
- rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Start() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
-
- rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
- DXGetErrorString8(rc));
- ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING),
- "GetStatus: bad status: %lx\n",status);
- if (rc!=DS_OK)
- return;
-
- /* wait for the notifications */
- for (i = 0; i < (NOTIFICATIONS * 2); i++) {
- rc=WaitForMultipleObjects(NOTIFICATIONS,state.event,FALSE,3000);
- ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),
- "WaitForMultipleObjects failed: 0x%lx\n",rc);
- if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) {
- ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),
- "Wrong notification: should be %d, got %ld\n",
- i%NOTIFICATIONS,rc-WAIT_OBJECT_0);
- }
- if (!capture_buffer_service(&state))
- break;
- }
-
- rc=IDirectSoundCaptureBuffer_Stop(dscbo);
- ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Stop() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
- }
-}
-
-static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
- LPCSTR lpcstrModule, LPVOID lpContext)
-{
- HRESULT rc;
- LPDIRECTSOUNDCAPTURE dsco=NULL;
- LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
- DSCBUFFERDESC bufdesc;
- WAVEFORMATEX wfx;
- DSCCAPS dsccaps;
- DWORD f;
- int ref;
-
- /* Private dsound.dll: Error: Invalid interface buffer */
- trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
- rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
- ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- ref=IDirectSoundCapture_Release(dsco);
- ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
- "have 0\n",ref);
- }
-
- rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
- ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
- "DirectSoundCaptureCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- if (rc==DSERR_NODRIVER)
- trace(" No Driver\n");
- else if (rc==E_FAIL)
- trace(" No Device\n");
- else if (rc==DSERR_ALLOCATED)
- trace(" Already In Use\n");
- goto EXIT;
- }
-
- /* Private dsound.dll: Error: Invalid caps buffer */
- rc=IDirectSoundCapture_GetCaps(dsco,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* Private dsound.dll: Error: Invalid caps buffer */
- dsccaps.dwSize=0;
- rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- dsccaps.dwSize=sizeof(dsccaps);
- rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
- ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Caps: size=%ld flags=0x%08lx formats=%05lx channels=%ld\n",
- dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
- dsccaps.dwChannels);
- }
-
- /* Private dsound.dll: Error: Invalid size */
- /* Private dsound.dll: Error: Invalid capture buffer description */
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=0;
- bufdesc.dwFlags=0;
- bufdesc.dwBufferBytes=0;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=NULL;
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
-
- /* Private dsound.dll: Error: Invalid buffer size */
- /* Private dsound.dll: Error: Invalid capture buffer description */
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=0;
- bufdesc.dwBufferBytes=0;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=NULL;
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
- "should have returned DSERR_INVALIDPARAM, returned %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
-
- /* Private dsound.dll: Error: Invalid buffer size */
- /* Private dsound.dll: Error: Invalid capture buffer description */
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- ZeroMemory(&wfx, sizeof(wfx));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=0;
- bufdesc.dwBufferBytes=0;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=&wfx;
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
- "should have returned DSERR_INVALIDPARAM, returned :%s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
-
- /* Private dsound.dll: Error: Invalid buffer size */
- /* Private dsound.dll: Error: Invalid capture buffer description */
- init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=0;
- bufdesc.dwBufferBytes=0;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=&wfx;
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
-
- for (f=0;f<NB_FORMATS;f++) {
- dscbo=NULL;
- init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
- formats[f][2]);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=0;
- bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive)
- trace(" Testing the capture buffer at %s\n", format_string(&wfx));
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok(((rc==DS_OK)&&(dscbo!=NULL))||(rc==DSERR_BADFORMAT)||
- ((rc==DSERR_NODRIVER))||(rc==DSERR_ALLOCATED)||(rc==E_INVALIDARG),
- "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
- "%s capture buffer: %s\n",format_string(&wfx),DXGetErrorString8(rc));
- if (rc==DS_OK) {
- test_capture_buffer(dsco, dscbo, winetest_interactive);
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
- "should have 0\n",ref);
- } else if (rc==DSERR_BADFORMAT) {
- ok(!(dsccaps.dwFormats & formats[f][3]),
- "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
- "capture buffer: format listed as supported but using it failed\n");
- if (!(dsccaps.dwFormats & formats[f][3]))
- trace(" Format not supported: %s\n", format_string(&wfx));
- } else if (rc==DSERR_NODRIVER) {
- trace(" No Driver\n");
- } else if (rc==DSERR_ALLOCATED) {
- trace(" Already In Use\n");
- } else if (rc==E_INVALIDARG) { /* try the old version struct */
- DSCBUFFERDESC1 bufdesc1;
- ZeroMemory(&bufdesc1, sizeof(bufdesc1));
- bufdesc1.dwSize=sizeof(bufdesc1);
- bufdesc1.dwFlags=0;
- bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
- bufdesc1.dwReserved=0;
- bufdesc1.lpwfxFormat=&wfx;
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
- (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
- ok(rc==DS_OK,
- "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
- "%s capture buffer: %s\n",format_string(&wfx),
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- test_capture_buffer(dsco, dscbo, winetest_interactive);
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
- "references, should have 0\n",ref);
- }
- }
- }
-
- /* try a non PCM format */
-#if 0
- init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
- bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive)
- trace(" Testing the capture buffer at %s\n", format_string(&wfx));
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
- "failed to create a capture buffer: %s\n",DXGetErrorString8(rc));
- if ((rc==DS_OK)&&(dscbo!=NULL)) {
- test_capture_buffer(dsco, dscbo, winetest_interactive);
- ref=IDirectSoundCaptureBuffer_Release(dscbo);
- ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
-#endif
-
- /* Try an invalid format to test error handling */
-#if 0
- init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
- bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
- bufdesc.dwReserved=0;
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive)
- trace(" Testing the capture buffer at %s\n", format_string(&wfx));
- rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
- ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
- "at 2 MHz %s\n",DXGetErrorString8(rc));
-#endif
-
-EXIT:
- if (dsco!=NULL) {
- ref=IDirectSoundCapture_Release(dsco);
- ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
- "have 0\n",ref);
- }
-
- return TRUE;
-}
-
-static void capture_tests(void)
-{
- HRESULT rc;
- rc=pDirectSoundCaptureEnumerateA(&dscenum_callback,NULL);
- ok(rc==DS_OK,"DirectSoundCaptureEnumerateA() failed: %s\n",
- DXGetErrorString8(rc));
-}
-
-START_TEST(capture)
-{
- HMODULE hDsound;
-
- CoInitialize(NULL);
-
- hDsound = LoadLibraryA("dsound.dll");
- if (!hDsound) {
- trace("dsound.dll not found\n");
- return;
- }
-
- trace("DLL Version: %s\n", get_file_version("dsound.dll"));
-
- pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate");
- pDirectSoundCaptureEnumerateA=(void*)GetProcAddress(hDsound,"DirectSoundCaptureEnumerateA");
- if (!pDirectSoundCaptureCreate || !pDirectSoundCaptureEnumerateA)
- {
- trace("capture test skipped\n");
- return;
- }
-
- IDirectSoundCapture_tests();
- capture_tests();
-
- CoUninitialize();
-}
+++ /dev/null
-/*
- * Tests the panning and 3D functions of DirectSound
- *
- * Part of this test involves playing test tones. But this only makes
- * sense if someone is going to carefully listen to it, and would only
- * bother everyone else.
- * So this is only done if the test is being run in interactive mode.
- *
- * Copyright (c) 2002-2004 Francois Gouget
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#include <windows.h>
-
-#include <math.h>
-
-#include "wine/test.h"
-#include "dsound.h"
-#include "dxerr8.h"
-
-#include "dsound_test.h"
-
-#define PI 3.14159265358979323846
-char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
-{
- int i;
- int nb_samples;
- char* buf;
- char* b;
-
- nb_samples=(int)(duration*wfx->nSamplesPerSec);
- *size=nb_samples*wfx->nBlockAlign;
- b=buf=malloc(*size);
- for (i=0;i<nb_samples;i++) {
- double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
- if (wfx->wBitsPerSample==8) {
- unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
- *b++=sample;
- if (wfx->nChannels==2)
- *b++=sample;
- } else {
- signed short sample=(signed short)((double)32767.5*y-0.5);
- b[0]=sample & 0xff;
- b[1]=sample >> 8;
- b+=2;
- if (wfx->nChannels==2) {
- b[0]=sample & 0xff;
- b[1]=sample >> 8;
- b+=2;
- }
- }
- }
- return buf;
-}
-
-const char * getDSBCAPS(DWORD xmask) {
- static struct {
- DWORD mask;
- const char *name;
- } flags[] = {
-#define FE(x) { x, #x },
- FE(DSBCAPS_PRIMARYBUFFER)
- FE(DSBCAPS_STATIC)
- FE(DSBCAPS_LOCHARDWARE)
- FE(DSBCAPS_LOCSOFTWARE)
- FE(DSBCAPS_CTRL3D)
- FE(DSBCAPS_CTRLFREQUENCY)
- FE(DSBCAPS_CTRLPAN)
- FE(DSBCAPS_CTRLVOLUME)
- FE(DSBCAPS_CTRLPOSITIONNOTIFY)
- FE(DSBCAPS_STICKYFOCUS)
- FE(DSBCAPS_GLOBALFOCUS)
- FE(DSBCAPS_GETCURRENTPOSITION2)
- FE(DSBCAPS_MUTE3DATMAXDISTANCE)
-#undef FE
- };
- static char buffer[512];
- unsigned int i;
- BOOL first = TRUE;
-
- buffer[0] = 0;
-
- for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
- if ((flags[i].mask & xmask) == flags[i].mask) {
- if (first)
- first = FALSE;
- else
- strcat(buffer, "|");
- strcat(buffer, flags[i].name);
- }
- }
-
- return buffer;
-}
-
-HWND get_hwnd()
-{
- HWND hwnd=GetForegroundWindow();
- if (!hwnd)
- hwnd=GetDesktopWindow();
- return hwnd;
-}
-
-void init_format(WAVEFORMATEX* wfx, int format, int rate, int depth,
- int channels)
-{
- wfx->wFormatTag=format;
- wfx->nChannels=channels;
- wfx->wBitsPerSample=depth;
- wfx->nSamplesPerSec=rate;
- wfx->nBlockAlign=wfx->nChannels*wfx->wBitsPerSample/8;
- /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
- if (wfx->nBlockAlign==0)
- {
- /* align compressed formats to byte boundary */
- wfx->nBlockAlign=1;
- }
- wfx->nAvgBytesPerSec=wfx->nSamplesPerSec*wfx->nBlockAlign;
- wfx->cbSize=0;
-}
-
-typedef struct {
- char* wave;
- DWORD wave_len;
-
- LPDIRECTSOUNDBUFFER dsbo;
- LPWAVEFORMATEX wfx;
- DWORD buffer_size;
- DWORD written;
- DWORD played;
- DWORD offset;
-} play_state_t;
-
-static int buffer_refill(play_state_t* state, DWORD size)
-{
- LPVOID ptr1,ptr2;
- DWORD len1,len2;
- HRESULT rc;
-
- if (size>state->wave_len-state->written)
- size=state->wave_len-state->written;
-
- rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
- &ptr1,&len1,&ptr2,&len2,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
-
- memcpy(ptr1,state->wave+state->written,len1);
- state->written+=len1;
- if (ptr2!=NULL) {
- memcpy(ptr2,state->wave+state->written,len2);
- state->written+=len2;
- }
- state->offset=state->written % state->buffer_size;
- rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
- ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
- return size;
-}
-
-static int buffer_silence(play_state_t* state, DWORD size)
-{
- LPVOID ptr1,ptr2;
- DWORD len1,len2;
- HRESULT rc;
- BYTE s;
-
- rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
- &ptr1,&len1,&ptr2,&len2,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
-
- s=(state->wfx->wBitsPerSample==8?0x80:0);
- memset(ptr1,s,len1);
- if (ptr2!=NULL) {
- memset(ptr2,s,len2);
- }
- state->offset=(state->offset+size) % state->buffer_size;
- rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
- ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
- return size;
-}
-
-static int buffer_service(play_state_t* state)
-{
- DWORD last_play_pos,play_pos,buf_free;
- HRESULT rc;
-
- rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- goto STOP;
- }
-
- /* Update the amount played */
- last_play_pos=state->played % state->buffer_size;
- if (play_pos<last_play_pos)
- state->played+=state->buffer_size-last_play_pos+play_pos;
- else
- state->played+=play_pos-last_play_pos;
-
- if (winetest_debug > 1)
- trace("buf size=%ld last_play_pos=%ld play_pos=%ld played=%ld / %ld\n",
- state->buffer_size,last_play_pos,play_pos,state->played,
- state->wave_len);
-
- if (state->played>state->wave_len)
- {
- /* Everything has been played */
- goto STOP;
- }
-
- /* Refill the buffer */
- if (state->offset<=play_pos)
- buf_free=play_pos-state->offset;
- else
- buf_free=state->buffer_size-state->offset+play_pos;
-
- if (winetest_debug > 1)
- trace("offset=%ld free=%ld written=%ld / %ld\n",
- state->offset,buf_free,state->written,state->wave_len);
- if (buf_free==0)
- return 1;
-
- if (state->written<state->wave_len)
- {
- int w=buffer_refill(state,buf_free);
- if (w==-1)
- goto STOP;
- buf_free-=w;
- if (state->written==state->wave_len && winetest_debug > 1)
- trace("last sound byte at %ld\n",
- (state->written % state->buffer_size));
- }
-
- if (buf_free>0) {
- /* Fill with silence */
- if (winetest_debug > 1)
- trace("writing %ld bytes of silence\n",buf_free);
- if (buffer_silence(state,buf_free)==-1)
- goto STOP;
- }
- return 1;
-
-STOP:
- if (winetest_debug > 1)
- trace("stopping playback\n");
- rc=IDirectSoundBuffer_Stop(state->dsbo);
- ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %s\n",
- DXGetErrorString8(rc));
- return 0;
-}
-
-void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
- BOOL is_primary, BOOL set_volume, LONG volume,
- BOOL set_pan, LONG pan, BOOL play, double duration,
- BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener,
- BOOL move_listener, BOOL move_sound,
- BOOL set_frequency, DWORD frequency)
-{
- HRESULT rc;
- DSBCAPS dsbcaps;
- WAVEFORMATEX wfx,wfx2;
- DWORD size,status,freq;
- int ref;
-
- if (set_frequency) {
- rc=IDirectSoundBuffer_SetFrequency(dsbo,frequency);
- ok(rc==DS_OK||rc==DSERR_CONTROLUNAVAIL,
- "IDirectSoundBuffer_SetFrequency() failed to set frequency "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
- }
-
- /* DSOUND: Error: Invalid caps pointer */
- rc=IDirectSoundBuffer_GetCaps(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- ZeroMemory(&dsbcaps, sizeof(dsbcaps));
-
- /* DSOUND: Error: Invalid caps pointer */
- rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- dsbcaps.dwSize=sizeof(dsbcaps);
- rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Caps: flags=0x%08lx size=%ld\n",dsbcaps.dwFlags,
- dsbcaps.dwBufferBytes);
- }
-
- /* Query the format size. Note that it may not match sizeof(wfx) */
- size=0;
- rc=IDirectSoundBuffer_GetFormat(dsbo,NULL,0,&size);
- ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have "
- "returned the needed size: rc=%s size=%ld\n",DXGetErrorString8(rc),size);
-
- rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Format: %s tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- is_primary ? "Primary" : "Secondary",
- wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
- wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
- }
-
- /* DSOUND: Error: Invalid frequency buffer */
- rc=IDirectSoundBuffer_GetFrequency(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
- rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq);
- ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) ||
- (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)),
- "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- DWORD f = set_frequency?frequency:wfx.nSamplesPerSec;
- ok(freq==f,"The frequency returned by GetFrequency "
- "%ld does not match the format %ld\n",freq,f);
- }
-
- /* DSOUND: Error: Invalid status pointer */
- rc=IDirectSoundBuffer_GetStatus(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetStatus() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
- DXGetErrorString8(rc));
- ok(status==0,"status=0x%lx instead of 0\n",status);
-
- 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,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
-
- /* DSOUND: Error: Invalid format pointer */
- rc=IDirectSoundBuffer_SetFormat(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
- rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
- DXGetErrorString8(rc));
-
- /* There is no garantee that SetFormat will actually change the
- * format to what we asked for. It depends on what the soundcard
- * supports. So we must re-query the format.
- */
- rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK &&
- (wfx.wFormatTag!=wfx2.wFormatTag ||
- wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
- wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
- wfx.nChannels!=wfx2.nChannels)) {
- trace("Requested format tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
- wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
- trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- 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,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: "
- "%s\n",DXGetErrorString8(rc));
- }
-
- if (play) {
- play_state_t state;
- DS3DLISTENER listener_param;
- LPDIRECTSOUND3DBUFFER buffer=NULL;
- DS3DBUFFER buffer_param;
- DWORD start_time,now;
-
- if (winetest_interactive) {
- if (set_frequency)
- trace(" Playing %g second 440Hz tone at %ldx%dx%d with a "
- "frequency of %ld (%ldHz)\n", duration,
- wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nChannels,
- frequency, (440 * frequency) / wfx.nSamplesPerSec);
- else
- trace(" Playing %g second 440Hz tone at %ldx%dx%d\n", duration,
- 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,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
- "failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
- }
- if (buffer3d) {
- LPDIRECTSOUNDBUFFER temp_buffer;
-
- rc=IDirectSoundBuffer_QueryInterface(dsbo,&IID_IDirectSound3DBuffer,
- (LPVOID *)&buffer);
- ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
- DXGetErrorString8(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,
- "IDirectSoundBuffer_QueryInterface() failed: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n",
- temp_buffer,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: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n",
- temp_buffer,dsbo);
- ref=IDirectSoundBuffer_Release(temp_buffer);
- ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
- "should have 1\n",ref);
-
-#if 0
- /* FIXME: this works on windows */
- ref=IDirectSoundBuffer_Release(dsbo);
- ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
- "should have 0\n",ref);
-
- rc=IDirectSound3DBuffer_QueryInterface(buffer,
- &IID_IDirectSoundBuffer,
- (LPVOID *)&dsbo);
- ok(rc==DS_OK && dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface() "
- "failed: %s\n",DXGetErrorString8(rc));
-#endif
-
- /* DSOUND: Error: Invalid buffer */
- rc=IDirectSound3DBuffer_GetAllParameters(buffer,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
- "failed: %s\n",DXGetErrorString8(rc));
-
- ZeroMemory(&buffer_param, sizeof(buffer_param));
-
- /* DSOUND: Error: Invalid buffer */
- rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
- "failed: %s\n",DXGetErrorString8(rc));
-
- buffer_param.dwSize=sizeof(buffer_param);
- rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
- ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
- DXGetErrorString8(rc));
- }
- if (set_volume) {
- if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
- LONG val;
- rc=IDirectSoundBuffer_GetVolume(dsbo,&val);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_SetVolume(dsbo,volume);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume() failed: %s\n",
- DXGetErrorString8(rc));
- } else {
- /* DSOUND: Error: Buffer does not have CTRLVOLUME */
- rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
- ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetVolume() "
- "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
- DXGetErrorString8(rc));
- }
- }
-
- if (set_pan) {
- if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) {
- LONG val;
- rc=IDirectSoundBuffer_GetPan(dsbo,&val);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_SetPan(dsbo,pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan() failed: %s\n",
- DXGetErrorString8(rc));
- } else {
- /* DSOUND: Error: Buffer does not have CTRLPAN */
- rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
- ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetPan() "
- "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
- DXGetErrorString8(rc));
- }
- }
-
- if (set_frequency)
- state.wave=wave_generate_la(&wfx,(duration*frequency)/wfx.nSamplesPerSec,&state.wave_len);
- else
- state.wave=wave_generate_la(&wfx,duration,&state.wave_len);
-
- state.dsbo=dsbo;
- state.wfx=&wfx;
- state.buffer_size=dsbcaps.dwBufferBytes;
- state.played=state.written=state.offset=0;
- buffer_refill(&state,state.buffer_size);
-
- rc=IDirectSoundBuffer_Play(dsbo,0,0,DSBPLAY_LOOPING);
- ok(rc==DS_OK,"IDirectSoundBuffer_Play() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
- DXGetErrorString8(rc));
- ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING),
- "GetStatus: bad status: %lx\n",status);
-
- 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: %s\n",DXGetErrorString8(rc));
- if (move_listener) {
- listener_param.vPosition.x = -5.0;
- listener_param.vVelocity.x = 10.0/duration;
- }
- rc=IDirectSound3DListener_SetAllParameters(listener,
- &listener_param,
- DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %s\n",
- DXGetErrorString8(rc));
- }
- if (buffer3d) {
- if (move_sound) {
- buffer_param.vPosition.x = 100.0;
- buffer_param.vVelocity.x = -200.0/duration;
- }
- buffer_param.flMinDistance = 10;
- rc=IDirectSound3DBuffer_SetAllParameters(buffer,&buffer_param,
- DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
- DXGetErrorString8(rc));
- }
-
- start_time=GetTickCount();
- while (buffer_service(&state)) {
- WaitForSingleObject(GetCurrentProcess(),TIME_SLICE);
- now=GetTickCount();
- if (listener && move_listener) {
- listener_param.vPosition.x = -5.0+10.0*(now-start_time)/
- 1000/duration;
- if (winetest_debug>2)
- trace("listener position=%g\n",listener_param.vPosition.x);
- rc=IDirectSound3DListener_SetPosition(listener,
- listener_param.vPosition.x,listener_param.vPosition.y,
- listener_param.vPosition.z,DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: "
- "%s\n",DXGetErrorString8(rc));
- }
- if (buffer3d && move_sound) {
- buffer_param.vPosition.x = 100-200.0*(now-start_time)/
- 1000/duration;
- if (winetest_debug>2)
- trace("sound position=%g\n",buffer_param.vPosition.x);
- rc=IDirectSound3DBuffer_SetPosition(buffer,
- buffer_param.vPosition.x,buffer_param.vPosition.y,
- buffer_param.vPosition.z,DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
- DXGetErrorString8(rc));
- }
- }
- /* Check the sound duration was within 10% of the expected value */
- now=GetTickCount();
- ok(fabs(1000*duration-now+start_time)<=100*duration,
- "The sound played for %ld ms instead of %g ms\n",
- now-start_time,1000*duration);
-
- 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,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
- "failed: %s\n",DXGetErrorString8(rc));
- }
- if (buffer3d) {
- ref=IDirectSound3DBuffer_Release(buffer);
- ok(ref==0,"IDirectSound3DBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
- }
-}
-
-static HRESULT test_secondary(LPGUID lpGuid, int play,
- int has_3d, int has_3dbuffer,
- int has_listener, int has_duplicate,
- int move_listener, int move_sound)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- LPDIRECTSOUND3DLISTENER listener=NULL;
- DSBUFFERDESC bufdesc;
- WAVEFORMATEX wfx, wfx1;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- if (has_3d)
- bufdesc.dwFlags|=DSBCAPS_CTRL3D;
- else
- bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
- "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: "
- "%s\n",has_3d?"3D ":"", DXGetErrorString8(rc));
- if (rc==DSERR_CONTROLUNAVAIL)
- trace(" No Primary\n");
- else if (rc==DS_OK && primary!=NULL) {
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT1;
-
- 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: %s\n",DXGetErrorString8(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() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid buffer */
- rc=IDirectSound3DListener_GetAllParameters(listener,
- &listener_param);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound3dListener_GetAllParameters() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- listener_param.dwSize=sizeof(listener_param);
- rc=IDirectSound3DListener_GetAllParameters(listener,
- &listener_param);
- ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() "
- "failed: %s\n",DXGetErrorString8(rc));
- }
- else
- goto EXIT;
- }
-
- init_format(&wfx,WAVE_FORMAT_PCM,22050,16,2);
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- if (has_3d)
- bufdesc.dwFlags|=DSBCAPS_CTRL3D;
- else
- bufdesc.dwFlags|=
- (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive) {
- trace(" Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d "
- "with a primary buffer at %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,
- wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
- }
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,"IDirectSound_CreateSoundBuffer() "
- "failed to create a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d (%s): %s\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,
- getDSBCAPS(bufdesc.dwFlags),DXGetErrorString8(rc));
- if (rc==DS_OK && secondary!=NULL) {
- if (!has_3d) {
- LONG refvol,vol,refpan,pan;
-
- /* Check the initial secondary buffer's volume and pan */
- rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(vol==0,"wrong volume for a new secondary buffer: %ld\n",vol);
- rc=IDirectSoundBuffer_GetPan(secondary,&pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(pan==0,"wrong pan for a new secondary buffer: %ld\n",pan);
-
- /* Check that changing the secondary buffer's volume and pan
- * does not impact the primary buffer's volume and pan
- */
- rc=IDirectSoundBuffer_GetVolume(primary,&refvol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_GetPan(primary,&refpan);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_SetVolume(secondary,-1000);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(vol==-1000,"secondary: wrong volume %ld instead of -1000\n",
- vol);
- rc=IDirectSoundBuffer_SetPan(secondary,-1000);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_GetPan(secondary,&pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(pan==-1000,"secondary: wrong pan %ld instead of -1000\n",
- pan);
-
- rc=IDirectSoundBuffer_GetVolume(primary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(vol==refvol,"The primary volume changed from %ld to %ld\n",
- refvol,vol);
- rc=IDirectSoundBuffer_GetPan(primary,&pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
- DXGetErrorString8(rc));
- ok(pan==refpan,"The primary pan changed from %ld to %ld\n",
- refpan,pan);
-
- rc=IDirectSoundBuffer_SetVolume(secondary,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_SetPan(secondary,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- }
- 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 returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid dest buffer */
- rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound_DuplicateSoundBuffer() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid source buffer */
- rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound_DuplicateSoundBuffer() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- duplicated=NULL;
- rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,
- &duplicated);
- ok(rc==DS_OK && duplicated!=NULL,
- "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
- "a secondary buffer: %s\n",DXGetErrorString8(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) {
- double duration;
- duration=(move_listener || move_sound?4.0:1.0);
- test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,duration,has_3dbuffer,
- listener,move_listener,move_sound,FALSE,0);
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() %s has %d references, "
- "should have 0\n",has_duplicate?"duplicated":"secondary",
- ref);
- }
- }
- }
-EXIT1:
- 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);
- }
-
- /* 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,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_for_driver(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_primary(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- int ref, i;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* 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,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(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|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
- "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
- "%s\n",DXGetErrorString8(rc));
- if (rc==DSERR_CONTROLUNAVAIL)
- trace(" No Primary\n");
- else if (rc==DS_OK && primary!=NULL) {
- test_buffer(dso,primary,1,TRUE,0,TRUE,0,winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,NULL,0,0,
- FALSE,0);
- if (winetest_interactive) {
- LONG volume,pan;
-
- volume = DSBVOLUME_MAX;
- for (i = 0; i < 6; i++) {
- test_buffer(dso,primary,1,TRUE,volume,TRUE,0,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),
- 1.0,0,NULL,0,0,FALSE,0);
- volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40);
- }
-
- pan = DSBPAN_LEFT;
- for (i = 0; i < 7; i++) {
- test_buffer(dso,primary,1,TRUE,0,TRUE,pan,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0,FALSE,0);
- pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6);
- }
- }
- 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,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_primary_3d(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* 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,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
- "to create a primary buffer: %s\n",DXGetErrorString8(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,"IDirectSound_CreateSoundBuffer() "
- "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && primary!=NULL) {
- test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0,
- FALSE,0);
- 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,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_primary_3d_with_listener(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* 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,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
- 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,"IDirectSound_CreateSoundBuffer() failed "
- "to create a 3D primary buffer: %s\n",DXGetErrorString8(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: %s\n",DXGetErrorString8(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: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==primary,
- "COM interface broken: %p != %p\n",
- temp_buffer,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: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==primary,
- "COM interface broken: %p != %p\n",
- temp_buffer,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,FALSE,0,FALSE,0,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,
- listener,0,0,FALSE,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);
- }
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
-return DSERR_GENERIC;
-
- return rc;
-}
-
-static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
- LPCSTR lpcstrModule, LPVOID lpContext)
-{
- HRESULT rc;
- trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
-
- rc = test_for_driver(lpGuid);
- if (rc == DSERR_NODRIVER) {
- trace(" No Driver\n");
- return 1;
- } else if (rc == DSERR_ALLOCATED) {
- trace(" Already In Use\n");
- return 1;
- } else if (rc == E_FAIL) {
- trace(" No Device\n");
- return 1;
- }
-
- trace(" Testing the primary buffer\n");
- test_primary(lpGuid);
-
- trace(" Testing 3D primary buffer\n");
- test_primary_3d(lpGuid);
-
- trace(" Testing 3D primary buffer with listener\n");
- test_primary_3d_with_listener(lpGuid);
-
- /* Testing secondary buffers */
- test_secondary(lpGuid,winetest_interactive,0,0,0,0,0,0);
- test_secondary(lpGuid,winetest_interactive,0,0,0,1,0,0);
-
- /* Testing 3D secondary buffers */
- test_secondary(lpGuid,winetest_interactive,1,0,0,0,0,0);
- test_secondary(lpGuid,winetest_interactive,1,1,0,0,0,0);
- test_secondary(lpGuid,winetest_interactive,1,1,0,1,0,0);
- test_secondary(lpGuid,winetest_interactive,1,0,1,0,0,0);
- test_secondary(lpGuid,winetest_interactive,1,0,1,1,0,0);
- test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,0);
- test_secondary(lpGuid,winetest_interactive,1,1,1,1,0,0);
- test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,0);
- test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,1);
- test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,1);
-
- return 1;
-}
-
-static void ds3d_tests(void)
-{
- HRESULT rc;
- rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
- ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
-}
-
-START_TEST(ds3d)
-{
- CoInitialize(NULL);
-
- trace("DLL Version: %s\n", get_file_version("dsound.dll"));
-
- ds3d_tests();
-
- CoUninitialize();
-}
+++ /dev/null
-/*
- * Tests the panning and 3D functions of DirectSound
- *
- * Part of this test involves playing test tones. But this only makes
- * sense if someone is going to carefully listen to it, and would only
- * bother everyone else.
- * So this is only done if the test is being run in interactive mode.
- *
- * Copyright (c) 2002-2004 Francois Gouget
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#include <windows.h>
-
-#include <math.h>
-
-#include "wine/test.h"
-#include "dsound.h"
-#include "dxerr8.h"
-
-#include "dsound_test.h"
-
-static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
-
-typedef struct {
- char* wave;
- DWORD wave_len;
-
- LPDIRECTSOUNDBUFFER dsbo;
- LPWAVEFORMATEX wfx;
- DWORD buffer_size;
- DWORD written;
- DWORD played;
- DWORD offset;
-} play_state_t;
-
-static int buffer_refill8(play_state_t* state, DWORD size)
-{
- LPVOID ptr1,ptr2;
- DWORD len1,len2;
- HRESULT rc;
-
- if (size>state->wave_len-state->written)
- size=state->wave_len-state->written;
-
- rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
- &ptr1,&len1,&ptr2,&len2,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
-
- memcpy(ptr1,state->wave+state->written,len1);
- state->written+=len1;
- if (ptr2!=NULL) {
- memcpy(ptr2,state->wave+state->written,len2);
- state->written+=len2;
- }
- state->offset=state->written % state->buffer_size;
- rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
- ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
- return size;
-}
-
-static int buffer_silence8(play_state_t* state, DWORD size)
-{
- LPVOID ptr1,ptr2;
- DWORD len1,len2;
- HRESULT rc;
- BYTE s;
-
- rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
- &ptr1,&len1,&ptr2,&len2,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
-
- s=(state->wfx->wBitsPerSample==8?0x80:0);
- memset(ptr1,s,len1);
- if (ptr2!=NULL) {
- memset(ptr2,s,len2);
- }
- state->offset=(state->offset+size) % state->buffer_size;
- rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
- ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return -1;
- return size;
-}
-
-static int buffer_service8(play_state_t* state)
-{
- DWORD last_play_pos,play_pos,buf_free;
- HRESULT rc;
-
- rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- goto STOP;
- }
-
- /* Update the amount played */
- last_play_pos=state->played % state->buffer_size;
- if (play_pos<last_play_pos)
- state->played+=state->buffer_size-last_play_pos+play_pos;
- else
- state->played+=play_pos-last_play_pos;
-
- if (winetest_debug > 1)
- trace("buf size=%ld last_play_pos=%ld play_pos=%ld played=%ld / %ld\n",
- state->buffer_size,last_play_pos,play_pos,state->played,
- state->wave_len);
-
- if (state->played>state->wave_len)
- {
- /* Everything has been played */
- goto STOP;
- }
-
- /* Refill the buffer */
- if (state->offset<=play_pos)
- buf_free=play_pos-state->offset;
- else
- buf_free=state->buffer_size-state->offset+play_pos;
-
- if (winetest_debug > 1)
- trace("offset=%ld free=%ld written=%ld / %ld\n",
- state->offset,buf_free,state->written,state->wave_len);
- if (buf_free==0)
- return 1;
-
- if (state->written<state->wave_len)
- {
- int w=buffer_refill8(state,buf_free);
- if (w==-1)
- goto STOP;
- buf_free-=w;
- if (state->written==state->wave_len && winetest_debug > 1)
- trace("last sound byte at %ld\n",
- (state->written % state->buffer_size));
- }
-
- if (buf_free>0) {
- /* Fill with silence */
- if (winetest_debug > 1)
- trace("writing %ld bytes of silence\n",buf_free);
- if (buffer_silence8(state,buf_free)==-1)
- goto STOP;
- }
- return 1;
-
-STOP:
- if (winetest_debug > 1)
- trace("stopping playback\n");
- rc=IDirectSoundBuffer_Stop(state->dsbo);
- ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %s\n",
- DXGetErrorString8(rc));
- return 0;
-}
-
-void test_buffer8(LPDIRECTSOUND8 dso, LPDIRECTSOUNDBUFFER dsbo,
- BOOL is_primary, BOOL set_volume, LONG volume,
- BOOL set_pan, LONG pan, BOOL play, double duration,
- BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener,
- BOOL move_listener, BOOL move_sound)
-{
- HRESULT rc;
- DSBCAPS dsbcaps;
- WAVEFORMATEX wfx,wfx2;
- DWORD size,status,freq;
- int ref;
-
- /* DSOUND: Error: Invalid caps pointer */
- rc=IDirectSoundBuffer_GetCaps(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- ZeroMemory(&dsbcaps, sizeof(dsbcaps));
-
- /* DSOUND: Error: Invalid caps pointer */
- rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- dsbcaps.dwSize=sizeof(dsbcaps);
- rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Caps: flags=0x%08lx size=%ld\n",dsbcaps.dwFlags,
- dsbcaps.dwBufferBytes);
- }
-
- /* Query the format size. Note that it may not match sizeof(wfx) */
- size=0;
- rc=IDirectSoundBuffer_GetFormat(dsbo,NULL,0,&size);
- ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have "
- "returned the needed size: rc=%s size=%ld\n",DXGetErrorString8(rc),size);
-
- rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && winetest_debug > 1) {
- trace(" Format: %s tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- is_primary ? "Primary" : "Secondary",
- wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
- wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
- }
-
- /* DSOUND: Error: Invalid frequency buffer */
- rc=IDirectSoundBuffer_GetFrequency(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
- rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq);
- ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) ||
- (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)),
- "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(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,"IDirectSoundBuffer_GetStatus() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
- DXGetErrorString8(rc));
- ok(status==0,"status=0x%lx instead of 0\n",status);
-
- if (is_primary) {
- /* We must call SetCooperativeLevel to be allowed to call SetFormat */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) "
- "failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
-
- /* DSOUND: Error: Invalid format pointer */
- rc=IDirectSoundBuffer_SetFormat(dsbo,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
- rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
- DXGetErrorString8(rc));
-
- /* There is no garantee that SetFormat will actually change the
- * format to what we asked for. It depends on what the soundcard
- * supports. So we must re-query the format.
- */
- rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK &&
- (wfx.wFormatTag!=wfx2.wFormatTag ||
- wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
- wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
- wfx.nChannels!=wfx2.nChannels)) {
- trace("Requested format tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
- wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
- trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) "
- "failed: %s\n",DXGetErrorString8(rc));
- }
-
- if (play) {
- play_state_t state;
- DS3DLISTENER listener_param;
- LPDIRECTSOUND3DBUFFER buffer=NULL;
- DS3DBUFFER buffer_param;
- DWORD start_time,now;
-
- if (winetest_interactive) {
- trace(" Playing %g second 440Hz tone at %ldx%dx%d\n", duration,
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),
- DSSCL_WRITEPRIMARY);
- ok(rc==DS_OK,
- "IDirectSound8_SetCooperativeLevel(DSSCL_WRITEPRIMARY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return;
- }
- if (buffer3d) {
- LPDIRECTSOUNDBUFFER temp_buffer;
-
- rc=IDirectSoundBuffer_QueryInterface(dsbo,&IID_IDirectSound3DBuffer,
- (LPVOID *)&buffer);
- ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
- DXGetErrorString8(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,
- "IDirectSoundBuffer_QueryInterface() failed: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n",
- temp_buffer,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: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n",
- temp_buffer,dsbo);
- ref=IDirectSoundBuffer_Release(temp_buffer);
- ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
- "should have 1\n",ref);
-
-#if 0
- /* FIXME: this works on windows */
- ref=IDirectSoundBuffer_Release(dsbo);
- ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
- "should have 0\n",ref);
-
- rc=IDirectSound3DBuffer_QueryInterface(buffer,
- &IID_IDirectSoundBuffer,
- (LPVOID *)&dsbo);
- ok(rc==DS_OK && dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface() "
- "failed: %s\n",DXGetErrorString8(rc),
-#endif
-
- /* DSOUND: Error: Invalid buffer */
- rc=IDirectSound3DBuffer_GetAllParameters(buffer,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
- "failed: %s\n",DXGetErrorString8(rc));
-
- ZeroMemory(&buffer_param, sizeof(buffer_param));
-
- /* DSOUND: Error: Invalid buffer */
- rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
- "failed: %s\n",DXGetErrorString8(rc));
-
- buffer_param.dwSize=sizeof(buffer_param);
- rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
- ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
- DXGetErrorString8(rc));
- }
- if (set_volume) {
- if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
- LONG val;
- rc=IDirectSoundBuffer_GetVolume(dsbo,&val);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_SetVolume(dsbo,volume);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume() failed: %s\n",
- DXGetErrorString8(rc));
- } else {
- /* DSOUND: Error: Buffer does not have CTRLVOLUME */
- rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
- ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetVolume() "
- "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
- DXGetErrorString8(rc));
- }
- }
-
- if (set_pan) {
- if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) {
- LONG val;
- rc=IDirectSoundBuffer_GetPan(dsbo,&val);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_SetPan(dsbo,pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan() failed: %s\n",
- DXGetErrorString8(rc));
- } else {
- /* DSOUND: Error: Buffer does not have CTRLPAN */
- rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
- ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetPan() "
- "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
- DXGetErrorString8(rc));
- }
- }
-
- state.wave=wave_generate_la(&wfx,duration,&state.wave_len);
-
- state.dsbo=dsbo;
- state.wfx=&wfx;
- state.buffer_size=dsbcaps.dwBufferBytes;
- state.played=state.written=state.offset=0;
- buffer_refill8(&state,state.buffer_size);
-
- rc=IDirectSoundBuffer_Play(dsbo,0,0,DSBPLAY_LOOPING);
- ok(rc==DS_OK,"IDirectSoundBuffer_Play() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
- DXGetErrorString8(rc));
- ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING),
- "GetStatus: bad status: %lx\n",status);
-
- 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: %s\n",DXGetErrorString8(rc));
- if (move_listener) {
- listener_param.vPosition.x = -5.0;
- listener_param.vVelocity.x = 10.0/duration;
- }
- rc=IDirectSound3DListener_SetAllParameters(listener,
- &listener_param,
- DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %s\n",
- DXGetErrorString8(rc));
- }
- if (buffer3d) {
- if (move_sound) {
- buffer_param.vPosition.x = 100.0;
- buffer_param.vVelocity.x = -200.0/duration;
- }
- buffer_param.flMinDistance = 10;
- rc=IDirectSound3DBuffer_SetAllParameters(buffer,&buffer_param,
- DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
- DXGetErrorString8(rc));
- }
-
- start_time=GetTickCount();
- while (buffer_service8(&state)) {
- WaitForSingleObject(GetCurrentProcess(),TIME_SLICE);
- now=GetTickCount();
- if (listener && move_listener) {
- listener_param.vPosition.x = -5.0+10.0*(now-start_time)/
- 1000/duration;
- if (winetest_debug>2)
- trace("listener position=%g\n",listener_param.vPosition.x);
- rc=IDirectSound3DListener_SetPosition(listener,
- listener_param.vPosition.x,listener_param.vPosition.y,
- listener_param.vPosition.z,DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: "
- "%s\n",DXGetErrorString8(rc));
- }
- if (buffer3d && move_sound) {
- buffer_param.vPosition.x = 100-200.0*(now-start_time)/
- 1000/duration;
- if (winetest_debug>2)
- trace("sound position=%g\n",buffer_param.vPosition.x);
- rc=IDirectSound3DBuffer_SetPosition(buffer,
- buffer_param.vPosition.x,buffer_param.vPosition.y,
- buffer_param.vPosition.z,DS3D_IMMEDIATE);
- ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
- DXGetErrorString8(rc));
- }
- }
- /* Check the sound duration was within 10% of the expected value */
- now=GetTickCount();
- ok(fabs(1000*duration-now+start_time)<=100*duration,
- "The sound played for %ld ms instead of %g ms\n",
- now-start_time,1000*duration);
-
- free(state.wave);
- if (is_primary) {
- /* Set the CooperativeLevel back to normal */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) "
- "failed: %s\n",DXGetErrorString8(rc));
- }
- if (buffer3d) {
- ref=IDirectSound3DBuffer_Release(buffer);
- ok(ref==0,"IDirectSound3DBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
- }
-}
-
-static HRESULT test_secondary8(LPGUID lpGuid, int play,
- int has_3d, int has_3dbuffer,
- int has_listener, int has_duplicate,
- int move_listener, int move_sound)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- LPDIRECTSOUND3DLISTENER listener=NULL;
- DSBUFFERDESC bufdesc;
- WAVEFORMATEX wfx, wfx1;
- int ref;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- if (has_3d)
- bufdesc.dwFlags|=DSBCAPS_CTRL3D;
- else
- bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL) || (rc == DSERR_CONTROLUNAVAIL),
- "IDirectSound8_CreateSoundBuffer() failed to create a %sprimary buffer: "
- "%s\n",has_3d?"3D ":"", DXGetErrorString8(rc));
- if (rc == DSERR_CONTROLUNAVAIL)
- trace(" No Primary\n");
- else if (rc==DS_OK && primary!=NULL) {
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT1;
-
- 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 %s\n",DXGetErrorString8(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() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid buffer */
- rc=IDirectSound3DListener_GetAllParameters(listener,
- &listener_param);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound3dListener_GetAllParameters() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- listener_param.dwSize=sizeof(listener_param);
- rc=IDirectSound3DListener_GetAllParameters(listener,
- &listener_param);
- ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() "
- "failed: %s\n",DXGetErrorString8(rc));
- }
- else
- goto EXIT;
- }
-
- init_format(&wfx,WAVE_FORMAT_PCM,22050,16,2);
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- if (has_3d)
- bufdesc.dwFlags|=DSBCAPS_CTRL3D;
- else
- bufdesc.dwFlags|=
- (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- if (has_3d) {
- /* a stereo 3D buffer should fail */
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound8_CreateSoundBuffer(secondary) should have "
- "returned DSERR_INVALIDPARAM, returned %s\n",
- DXGetErrorString8(rc));
- if (secondary)
- ref=IDirectSoundBuffer_Release(secondary);
- init_format(&wfx,WAVE_FORMAT_PCM,22050,16,1);
- }
-
- if (winetest_interactive) {
- trace(" Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d "
- "with a primary buffer at %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,
- wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
- }
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,"IDirectSound8_CreateSoundBuffer() "
- "failed to create a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d (%s): %s\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,
- getDSBCAPS(bufdesc.dwFlags),DXGetErrorString8(rc));
- if (rc==DS_OK && secondary!=NULL) {
- if (!has_3d) {
- LONG refvol,vol,refpan,pan;
-
- /* Check the initial secondary buffer's volume and pan */
- rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(vol==0,"wrong volume for a new secondary buffer: %ld\n",vol);
- rc=IDirectSoundBuffer_GetPan(secondary,&pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(pan==0,"wrong pan for a new secondary buffer: %ld\n",pan);
-
- /* Check that changing the secondary buffer's volume and pan
- * does not impact the primary buffer's volume and pan
- */
- rc=IDirectSoundBuffer_GetVolume(primary,&refvol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_GetPan(primary,&refpan);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: "
- "%s\n",DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_SetVolume(secondary,-1000);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(vol==-1000,"secondary: wrong volume %ld instead of -1000\n",
- vol);
- rc=IDirectSoundBuffer_SetPan(secondary,-1000);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_GetPan(secondary,&pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(pan==-1000,"secondary: wrong pan %ld instead of -1000\n",
- pan);
-
- rc=IDirectSoundBuffer_GetVolume(primary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_`GetVolume(primary) failed: i"
- "%s\n",DXGetErrorString8(rc));
- ok(vol==refvol,"The primary volume changed from %ld to %ld\n",
- refvol,vol);
- rc=IDirectSoundBuffer_GetPan(primary,&pan);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: "
- "%s\n",DXGetErrorString8(rc));
- ok(pan==refpan,"The primary pan changed from %ld to %ld\n",
- refpan,pan);
-
- rc=IDirectSoundBuffer_SetVolume(secondary,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- rc=IDirectSoundBuffer_SetPan(secondary,0);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
- "%s\n",DXGetErrorString8(rc));
- }
- if (has_duplicate) {
- LPDIRECTSOUNDBUFFER duplicated=NULL;
-
- /* DSOUND: Error: Invalid source buffer */
- rc=IDirectSound8_DuplicateSoundBuffer(dso,0,0);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound8_DuplicateSoundBuffer() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid dest buffer */
- rc=IDirectSound8_DuplicateSoundBuffer(dso,secondary,0);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound8_DuplicateSoundBuffer() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid source buffer */
- rc=IDirectSound8_DuplicateSoundBuffer(dso,0,&duplicated);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound8_DuplicateSoundBuffer() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- duplicated=NULL;
- rc=IDirectSound8_DuplicateSoundBuffer(dso,secondary,
- &duplicated);
- ok(rc==DS_OK && duplicated!=NULL,
- "IDirectSound8_DuplicateSoundBuffer() failed to duplicate "
- "a secondary buffer: %s\n",DXGetErrorString8(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) {
- double duration;
- duration=(move_listener || move_sound?4.0:1.0);
- test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,duration,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);
- }
- }
- }
-EXIT1:
- 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);
- }
-
- /* Set the CooperativeLevel back to normal */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) failed: "
- "%s\n",DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_for_driver8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- int ref;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_primary8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- int ref, i;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(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|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL) || (rc == DSERR_CONTROLUNAVAIL),
- "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
- "%s\n",DXGetErrorString8(rc));
- if (rc == DSERR_CONTROLUNAVAIL)
- trace(" No Primary\n");
- else if (rc==DS_OK && primary!=NULL) {
- test_buffer8(dso,primary,1,TRUE,0,TRUE,0,winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,NULL,0,0);
- if (winetest_interactive) {
- LONG volume,pan;
-
- volume = DSBVOLUME_MAX;
- for (i = 0; i < 6; i++) {
- test_buffer8(dso,primary,1,TRUE,volume,TRUE,0,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),
- 1.0,0,NULL,0,0);
- volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40);
- }
-
- pan = DSBPAN_LEFT;
- for (i = 0; i < 7; i++) {
- test_buffer8(dso,primary,1,TRUE,0,TRUE,pan,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0);
- pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6);
- }
- }
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) failed: "
- "%s\n",DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_primary_3d8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- int ref;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,"IDirectSound8_CreateSoundBuffer() failed "
- "to create a primary buffer: %s\n",DXGetErrorString8(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=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,"IDirectSound8_CreateSoundBuffer() "
- "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && primary!=NULL) {
- test_buffer8(dso,primary,1,FALSE,0,FALSE,0,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0);
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) failed: "
- "%s\n",DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_primary_3d_with_listener8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- int ref;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
- "%s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,"IDirectSound8_CreateSoundBuffer() failed "
- "to create a 3D primary buffer %s\n",DXGetErrorString8(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: %s\n",DXGetErrorString8(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: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==primary,"COM interface broken: %p != %p\n",temp_buffer,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: %s\n",
- DXGetErrorString8(rc));
- ok(temp_buffer==primary,"COM interface broken: %p != %p\n",temp_buffer,primary);
- ref=IDirectSoundBuffer_Release(temp_buffer);
- ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
- "should have 1\n",ref);
-
- /* Testing the buffer */
- test_buffer8(dso,primary,1,FALSE,0,FALSE,0,
- winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),
- 1.0,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);
- }
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
-return DSERR_GENERIC;
-
- return rc;
-}
-
-static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
- LPCSTR lpcstrModule, LPVOID lpContext)
-{
- HRESULT rc;
- trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
-
- rc = test_for_driver8(lpGuid);
- if (rc == DSERR_NODRIVER) {
- trace(" No Driver\n");
- return 1;
- } else if (rc == DSERR_ALLOCATED) {
- trace(" Already In Use\n");
- return 1;
- } else if (rc == E_FAIL) {
- trace(" No Device\n");
- return 1;
- }
-
- trace(" Testing the primary buffer\n");
- test_primary8(lpGuid);
-
- trace(" Testing 3D primary buffer\n");
- test_primary_3d8(lpGuid);
-
- trace(" Testing 3D primary buffer with listener\n");
- test_primary_3d_with_listener8(lpGuid);
-
- /* Testing secondary buffers */
- test_secondary8(lpGuid,winetest_interactive,0,0,0,0,0,0);
- test_secondary8(lpGuid,winetest_interactive,0,0,0,1,0,0);
-
- /* Testing 3D secondary buffers */
- test_secondary8(lpGuid,winetest_interactive,1,0,0,0,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,1,0,0,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,1,0,1,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,0,1,0,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,0,1,1,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,1,1,0,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,1,1,1,0,0);
- test_secondary8(lpGuid,winetest_interactive,1,1,1,0,1,0);
- test_secondary8(lpGuid,winetest_interactive,1,1,1,0,0,1);
- test_secondary8(lpGuid,winetest_interactive,1,1,1,0,1,1);
-
- return 1;
-}
-
-static void ds3d8_tests(void)
-{
- HRESULT rc;
- rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
- ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
-}
-
-START_TEST(ds3d8)
-{
- HMODULE hDsound;
-
- CoInitialize(NULL);
-
- hDsound = LoadLibraryA("dsound.dll");
- if (!hDsound) {
- trace("dsound.dll not found\n");
- return;
- }
-
- trace("DLL Version: %s\n", get_file_version("dsound.dll"));
-
- pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
- if (!pDirectSoundCreate8) {
- trace("ds3d8 test skipped\n");
- return;
- }
-
- ds3d8_tests();
-
- CoUninitialize();
-}
+++ /dev/null
-/*
- * Tests basic sound playback in DirectSound.
- * In particular we test each standard Windows sound format to make sure
- * we handle the sound card/driver quirks correctly.
- *
- * Part of this test involves playing test tones. But this only makes
- * sense if someone is going to carefully listen to it, and would only
- * bother everyone else.
- * So this is only done if the test is being run in interactive mode.
- *
- * Copyright (c) 2002-2004 Francois Gouget
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#include <windows.h>
-
-#include "wine/test.h"
-#include "dsound.h"
-#include "dxerr8.h"
-#include "dsconf.h"
-
-#include "dsound_test.h"
-
-static void IDirectSound_test(LPDIRECTSOUND dso, BOOL initialized,
- LPCGUID lpGuid)
-{
- HRESULT rc;
- DSCAPS dscaps;
- int ref;
- IUnknown * unknown;
- IDirectSound * ds;
- IDirectSound8 * ds8;
- DWORD speaker_config, new_speaker_config;
-
- /* Try to Query for objects */
- rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
- ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSound_Release(unknown);
-
- rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
- ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSound_Release(ds);
-
- rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
- ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) "
- "should have failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSound8_Release(ds8);
-
- if (initialized == FALSE) {
- /* try unitialized object */
- rc=IDirectSound_GetCaps(dso,0);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps(NULL) "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_Compact(dso);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound_Compact() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetSpeakerConfig() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_Initialize(dso,lpGuid);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "IDirectSound_Initialize() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DSERR_NODRIVER) {
- trace(" No Driver\n");
- goto EXIT;
- } else if (rc==E_FAIL) {
- trace(" No Device\n");
- goto EXIT;
- } else if (rc==DSERR_ALLOCATED) {
- trace(" Already In Use\n");
- goto EXIT;
- }
- }
-
- rc=IDirectSound_Initialize(dso,lpGuid);
- ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound_Initialize() "
- "should have returned DSERR_ALREADYINITIALIZED: %s\n",
- DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid caps buffer */
- rc=IDirectSound_GetCaps(dso,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps(NULL) "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- ZeroMemory(&dscaps, sizeof(dscaps));
-
- /* DSOUND: Error: Invalid caps buffer */
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- dscaps.dwSize=sizeof(dscaps);
-
- /* DSOUND: Running on a certified driver */
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSound_Compact(dso);
- ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound_Compact() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_Compact(dso);
- ok(rc==DS_OK,"IDirectSound_Compact() failed: %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSound_GetSpeakerConfig(dso,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetSpeakerConfig(NULL) "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config);
- ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %s\n",
- DXGetErrorString8(rc));
-
- speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
- DSSPEAKER_GEOMETRY_WIDE);
- rc=IDirectSound_SetSpeakerConfig(dso,speaker_config);
- ok(rc==DS_OK,"IDirectSound_SetSpeakerConfig() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- rc=IDirectSound_GetSpeakerConfig(dso,&new_speaker_config);
- ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && speaker_config!=new_speaker_config)
- trace("IDirectSound_GetSpeakerConfig() failed to set speaker "
- "config: expected 0x%08lx, got 0x%08lx\n",
- speaker_config,new_speaker_config);
- }
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
-}
-
-static void IDirectSound_tests(void)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
-
- trace("Testing IDirectSound\n");
-
- /* try the COM class factory method of creation with no device specified */
- rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound_test(dso, FALSE, NULL);
-
- /* try the COM class factory method of creation with default playback
- * device specified */
- rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound_test(dso, FALSE, &DSDEVID_DefaultPlayback);
-
- /* try the COM class factory method of creation with default voice
- * playback device specified */
- rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
-
- /* try the COM class factory method of creation with a bad
- * IID specified */
- rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
- &CLSID_DirectSoundPrivate, (void**)&dso);
- ok(rc==E_NOINTERFACE,
- "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) "
- "should have failed: %s\n",DXGetErrorString8(rc));
-
- /* try the COM class factory method of creation with a bad
- * GUID and IID specified */
- rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound, (void**)&dso);
- ok(rc==REGDB_E_CLASSNOTREG,
- "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) "
- "should have failed: %s\n",DXGetErrorString8(rc));
-
- /* try with no device specified */
- rc=DirectSoundCreate(NULL,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
- if (rc==S_OK && dso)
- IDirectSound_test(dso, TRUE, NULL);
-
- /* try with default playback device specified */
- rc=DirectSoundCreate(&DSDEVID_DefaultPlayback,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && dso)
- IDirectSound_test(dso, TRUE, NULL);
-
- /* try with default voice playback device specified */
- rc=DirectSoundCreate(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && dso)
- IDirectSound_test(dso, TRUE, NULL);
-
- /* try with a bad device specified */
- rc=DirectSoundCreate(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
- ok(rc==DSERR_NODRIVER,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) "
- "should have failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && dso)
- IDirectSound_Release(dso);
-}
-
-static HRESULT test_dsound(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- int ref;
-
- /* DSOUND: Error: Invalid interface buffer */
- rc=DirectSoundCreate(lpGuid,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Try the enumerated device */
- IDirectSound_test(dso, TRUE, lpGuid);
-
- /* Try the COM class factory method of creation with enumerated device */
- rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound_test(dso, FALSE, lpGuid);
-
- /* Create a DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- LPDIRECTSOUND dso1=NULL;
-
- /* Create a second DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso1,NULL);
- ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- /* Release the second DirectSound object */
- ref=IDirectSound_Release(dso1);
- ok(ref==0,"IDirectSound_Release() has %d references, should have "
- "0\n",ref);
- ok(dso!=dso1,"DirectSound objects should be unique: dso=%p,dso1=%p\n",dso,dso1);
- }
-
- /* Release the first DirectSound object */
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
- ref);
- if (ref!=0)
- return DSERR_GENERIC;
- } else
- return rc;
-
- /* Create a DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- LPDIRECTSOUNDBUFFER secondary;
- DSBUFFERDESC bufdesc;
- WAVEFORMATEX wfx;
-
- init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a secondary "
- "buffer %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && secondary!=NULL) {
- LPDIRECTSOUND3DBUFFER buffer3d;
- rc=IDirectSound_QueryInterface(secondary, &IID_IDirectSound3DBuffer,
- (void **)&buffer3d);
- ok(rc==DS_OK && buffer3d!=NULL,"IDirectSound_QueryInterface() "
- "failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && buffer3d!=NULL) {
- ref=IDirectSound3DBuffer_AddRef(buffer3d);
- ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
- "should have 2\n",ref);
- }
- ref=IDirectSoundBuffer_AddRef(secondary);
- ok(ref==2,"IDirectSoundBuffer_AddRef() has %d references, "
- "should have 2\n",ref);
- }
- /* release with buffer */
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
- ref);
- if (ref!=0)
- return DSERR_GENERIC;
- } else
- return rc;
-
- return DS_OK;
-}
-
-static HRESULT test_primary(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* DSOUND: Error: Invalid buffer description pointer */
- rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound_CreateSoundBuffer() should have failed: %s\n",
- DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid buffer description pointer */
- rc=IDirectSound_CreateSoundBuffer(dso,0,&primary,NULL);
- ok(rc==DSERR_INVALIDPARAM && primary==0,
- "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
- "dsbo=%p\n",DXGetErrorString8(rc),primary);
-
- /* DSOUND: Error: Invalid buffer description pointer */
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,0,NULL);
- ok(rc==DSERR_INVALIDPARAM && primary==0,
- "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
- "dsbo=0x%p\n",DXGetErrorString8(rc),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,
- "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
- "primary=%p\n",DXGetErrorString8(rc),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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(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|DSBCAPS_CTRLVOLUME;
- bufdesc.lpwfxFormat = &wfx;
- init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
- if (rc==DS_OK && primary!=NULL)
- IDirectSoundBuffer_Release(primary);
-
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
- "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
- "%s\n",DXGetErrorString8(rc));
- if (rc==DSERR_CONTROLUNAVAIL)
- trace(" No Primary\n");
- else if (rc==DS_OK && primary!=NULL) {
- LONG vol;
-
- /* Try to create a second primary buffer */
- /* DSOUND: Error: The primary buffer already exists.
- * Any changes made to the buffer description will be ignored. */
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
- ok(rc==DS_OK && second==primary,
- "IDirectSound_CreateSoundBuffer() should have returned original "
- "primary buffer: %s\n",DXGetErrorString8(rc));
- ref=IDirectSoundBuffer_Release(second);
- ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
- "should have 1\n",ref);
-
- /* Try to duplicate a primary buffer */
- /* DSOUND: Error: Can't duplicate primary buffers */
- rc=IDirectSound_DuplicateSoundBuffer(dso,primary,&third);
- /* rc=0x88780032 */
- ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer() primary buffer "
- "should have failed %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_GetVolume(primary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
- DXGetErrorString8(rc));
-
- if (winetest_interactive) {
- trace("Playing a 5 seconds reference tone at the current "
- "volume.\n");
- if (rc==DS_OK)
- trace("(the current volume is %ld according to DirectSound)\n",
- vol);
- trace("All subsequent tones should be identical to this one.\n");
- trace("Listen for stutter, changes in pitch, volume, etc.\n");
- }
- test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0,FALSE,0);
-
- 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-/*
- * Test the primary buffer at different formats while keeping the
- * secondary buffer at a constant format.
- */
-static HRESULT test_primary_secondary(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx, wfx2;
- int f,ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
- "%s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && primary!=NULL) {
- for (f=0;f<NB_FORMATS;f++) {
- /* 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
- formats[f][2]);
- wfx2=wfx;
- rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
- DXGetErrorString8(rc));
-
- /* There is no garantee that SetFormat will actually change the
- * format to what we asked for. It depends on what the soundcard
- * supports. So we must re-query the format.
- */
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK &&
- (wfx.wFormatTag!=wfx2.wFormatTag ||
- wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
- wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
- wfx.nChannels!=wfx2.nChannels)) {
- trace("Requested primary format tag=0x%04x %ldx%dx%d "
- "avg.B/s=%ld align=%d\n",
- wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
- wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
- trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
- init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
-
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx2;
- if (winetest_interactive) {
- trace(" Testing a primary buffer at %ldx%dx%d with a "
- "secondary buffer at %ldx%dx%d\n",
- wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
- wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
- }
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a secondary "
- "buffer %s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && secondary!=NULL) {
- test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,1.0,0,NULL,0,0,FALSE,0);
-
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() 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);
- }
-
- /* 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_secondary(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx, wfx1;
- DWORD f;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
- "%s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && primary!=NULL) {
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT1;
-
- for (f=0;f<NB_FORMATS;f++) {
- init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
- formats[f][2]);
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && secondary!=NULL)
- IDirectSoundBuffer_Release(secondary);
-
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive) {
- trace(" Testing a secondary buffer at %ldx%dx%d "
- "with a primary buffer at %ldx%dx%d\n",
- wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
- wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
- }
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a secondary "
- "buffer %s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && secondary!=NULL) {
- test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,1.0,0,NULL,0,0,FALSE,0);
-
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
- }
-EXIT1:
- 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_block_align(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER secondary=NULL;
- DSBUFFERDESC bufdesc;
- DSBCAPS dsbcaps;
- WAVEFORMATEX wfx;
- int ref;
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- init_format(&wfx,WAVE_FORMAT_PCM,11025,16,2);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec + 1;
- bufdesc.lpwfxFormat=&wfx;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK,"IDirectSound_CreateSoundBuffer() "
- "should have returned DS_OK, returned: %s\n",
- DXGetErrorString8(rc));
-
- if (rc==DS_OK && secondary!=NULL) {
- ZeroMemory(&dsbcaps, sizeof(dsbcaps));
- dsbcaps.dwSize = sizeof(dsbcaps);
- rc=IDirectSoundBuffer_GetCaps(secondary,&dsbcaps);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, "
- "returned: %s\n", DXGetErrorString8(rc));
- if (rc==DS_OK)
- ok(dsbcaps.dwBufferBytes==(wfx.nAvgBytesPerSec + wfx.nBlockAlign),
- "Buffer size not a multiple of nBlockAlign: requested %ld, "
- "got %ld, should be %ld\n", bufdesc.dwBufferBytes,
- dsbcaps.dwBufferBytes, wfx.nAvgBytesPerSec + wfx.nBlockAlign);
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d references, "
- "should have 0\n",ref);
- }
-
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static struct fmt {
- int bits;
- int channels;
-} fmts[] = { { 8, 1 }, { 8, 2 }, { 16, 1 }, {16, 2 } };
-
-static HRESULT test_frequency(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx, wfx1;
- DWORD f, r;
- int ref;
- int rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
- 48000, 96000 };
-
- /* Create the DirectSound object */
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
- "%s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && primary!=NULL) {
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT1;
-
- for (f=0;f<sizeof(fmts)/sizeof(fmts[0]);f++) {
- for (r=0;r<sizeof(rates)/sizeof(rates[0]);r++) {
- init_format(&wfx,WAVE_FORMAT_PCM,11025,fmts[f].bits,
- fmts[f].channels);
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLFREQUENCY;
- bufdesc.dwBufferBytes=align((wfx.nAvgBytesPerSec*rates[r]/11025)*
- BUFFER_LEN/1000,wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive) {
- trace(" Testing a secondary buffer at %ldx%dx%d "
- "with a primary buffer at %ldx%dx%d\n",
- wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
- wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
- }
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a secondary "
- "buffer %s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && secondary!=NULL) {
- test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,1.0,0,NULL,0,0,TRUE,rates[r]);
-
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
- }
- }
-EXIT1:
- 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
- LPCSTR lpcstrModule, LPVOID lpContext)
-{
- HRESULT rc;
- trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
- rc = test_dsound(lpGuid);
- if (rc == DSERR_NODRIVER)
- trace(" No Driver\n");
- else if (rc == DSERR_ALLOCATED)
- trace(" Already In Use\n");
- else if (rc == E_FAIL)
- trace(" No Device\n");
- else {
- test_block_align(lpGuid);
- test_primary(lpGuid);
- test_primary_secondary(lpGuid);
- test_secondary(lpGuid);
- test_frequency(lpGuid);
- }
-
- return 1;
-}
-
-static void dsound_tests(void)
-{
- HRESULT rc;
- rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
- ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
-}
-
-START_TEST(dsound)
-{
- CoInitialize(NULL);
-
- trace("DLL Version: %s\n", get_file_version("dsound.dll"));
-
- IDirectSound_tests();
- dsound_tests();
-
- CoUninitialize();
-}
+++ /dev/null
-/*
- * Tests basic sound playback in DirectSound.
- * In particular we test each standard Windows sound format to make sure
- * we handle the sound card/driver quirks correctly.
- *
- * Part of this test involves playing test tones. But this only makes
- * sense if someone is going to carefully listen to it, and would only
- * bother everyone else.
- * So this is only done if the test is being run in interactive mode.
- *
- * Copyright (c) 2002-2004 Francois Gouget
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#include <windows.h>
-#include <stdio.h>
-
-#include "wine/test.h"
-#include "dsound.h"
-#include "dxerr8.h"
-#include "dsconf.h"
-
-#include "dsound_test.h"
-
-static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
-
-int align(int length, int align)
-{
- return (length / align) * align;
-}
-
-static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
- LPCGUID lpGuid)
-{
- HRESULT rc;
- DSCAPS dscaps;
- int ref;
- IUnknown * unknown;
- IDirectSound * ds;
- IDirectSound8 * ds8;
- DWORD speaker_config, new_speaker_config;
- DWORD certified;
-
- /* Try to Query for objects */
- rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
- ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSound8_Release(unknown);
-
- rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
- ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSound_Release(ds);
-
- rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
- ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK)
- IDirectSound8_Release(ds8);
-
- if (initialized == FALSE) {
- /* try unitialized object */
- rc=IDirectSound8_GetCaps(dso,0);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_Compact(dso);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_VerifyCertification(dso, &certified);
- ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
- "should have returned DSERR_UNINITIALIZED, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_Initialize(dso,lpGuid);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DSERR_NODRIVER) {
- trace(" No Driver\n");
- goto EXIT;
- } else if (rc==E_FAIL) {
- trace(" No Device\n");
- goto EXIT;
- } else if (rc==DSERR_ALLOCATED) {
- trace(" Already In Use\n");
- goto EXIT;
- }
- }
-
- rc=IDirectSound8_Initialize(dso,lpGuid);
- ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() "
- "should have returned DSERR_ALREADYINITIALIZED: %s\n",
- DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid caps buffer */
- rc=IDirectSound8_GetCaps(dso,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- ZeroMemory(&dscaps, sizeof(dscaps));
-
- /* DSOUND: Error: Invalid caps buffer */
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- dscaps.dwSize=sizeof(dscaps);
-
- /* DSOUND: Running on a certified driver */
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSound8_Compact(dso);
- ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_Compact(dso);
- ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSound8_GetSpeakerConfig(dso,0);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
-
- rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
- ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
- DXGetErrorString8(rc));
-
- speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
- DSSPEAKER_GEOMETRY_WIDE);
- rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
- ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK) {
- rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
- ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && speaker_config!=new_speaker_config)
- trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
- "config: expected 0x%08lx, got 0x%08lx\n",
- speaker_config,new_speaker_config);
- }
-
- rc=IDirectSound8_VerifyCertification(dso, &certified);
- ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
-}
-
-static void IDirectSound8_tests(void)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
-
- trace("Testing IDirectSound8\n");
-
- /* try the COM class factory method of creation with no device specified */
- rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound8, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
- if (dso)
- IDirectSound8_test(dso, FALSE, NULL);
-
- /* try the COM class factory method of creation with default playback
- * device specified */
- rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound8, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
-
- /* try the COM class factory method of creation with default voice
- * playback device specified */
- rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound8, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
-
- /* try the COM class factory method of creation with a bad
- * IID specified */
- rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
- &CLSID_DirectSoundPrivate, (void**)&dso);
- ok(rc==E_NOINTERFACE,
- "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
- "should have failed: %s\n",DXGetErrorString8(rc));
-
- /* try the COM class factory method of creation with a bad
- * GUID and IID specified */
- rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound8, (void**)&dso);
- ok(rc==REGDB_E_CLASSNOTREG,
- "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
- "should have failed: %s\n",DXGetErrorString8(rc));
-
- /* try with no device specified */
- rc=pDirectSoundCreate8(NULL,&dso,NULL);
- ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && dso)
- IDirectSound8_test(dso, TRUE, NULL);
-
- /* try with default playback device specified */
- rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
- ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && dso)
- IDirectSound8_test(dso, TRUE, NULL);
-
- /* try with default voice playback device specified */
- rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
- ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && dso)
- IDirectSound8_test(dso, TRUE, NULL);
-
- /* try with a bad device specified */
- rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
- ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
- "should have failed: %s\n",DXGetErrorString8(rc));
-}
-
-static HRESULT test_dsound8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- int ref;
-
- /* DSOUND: Error: Invalid interface buffer */
- rc=pDirectSoundCreate8(lpGuid,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* Create the DirectSound8 object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Try the enumerated device */
- IDirectSound8_test(dso, TRUE, lpGuid);
-
- /* Try the COM class factory method of creation with enumerated device */
- rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
- &IID_IDirectSound8, (void**)&dso);
- ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
- DXGetErrorString8(rc));
- if (dso)
- IDirectSound8_test(dso, FALSE, lpGuid);
-
- /* Create a DirectSound8 object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- LPDIRECTSOUND8 dso1=NULL;
-
- /* Create a second DirectSound8 object */
- rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
- ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- /* Release the second DirectSound8 object */
- ref=IDirectSound8_Release(dso1);
- ok(ref==0,"IDirectSound8_Release() has %d references, "
- "should have 0\n",ref);
- ok(dso!=dso1,"DirectSound8 objects should be unique: "
- "dso=%p,dso1=%p\n",dso,dso1);
- }
-
- /* Release the first DirectSound8 object */
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
- ref);
- if (ref!=0)
- return DSERR_GENERIC;
- } else
- return rc;
-
- /* Create a DirectSound8 object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK) {
- LPDIRECTSOUNDBUFFER secondary;
- DSBUFFERDESC bufdesc;
- WAVEFORMATEX wfx;
-
- init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
- "buffer: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK && secondary!=NULL) {
- LPDIRECTSOUND3DBUFFER buffer3d;
- LPDIRECTSOUNDBUFFER8 buffer8;
- rc=IDirectSound8_QueryInterface(secondary,
- &IID_IDirectSound3DBuffer,
- (void **)&buffer3d);
- ok(rc==DS_OK && buffer3d!=NULL,
- "IDirectSound8_QueryInterface() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && buffer3d!=NULL) {
- ref=IDirectSound3DBuffer_AddRef(buffer3d);
- ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
- "should have 2\n",ref);
- }
- rc=IDirectSound8_QueryInterface(secondary,
- &IID_IDirectSoundBuffer8,
- (void **)&buffer8);
- if (rc==DS_OK && buffer8!=NULL) {
- ref=IDirectSoundBuffer8_AddRef(buffer8);
- ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
- "should have 3\n",ref);
- }
- ref=IDirectSoundBuffer_AddRef(secondary);
- ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
- "should have 4\n",ref);
- }
- /* release with buffer */
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
- ref);
- if (ref!=0)
- return DSERR_GENERIC;
- } else
- return rc;
-
- return DS_OK;
-}
-
-static HRESULT test_primary8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx;
- int ref;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* DSOUND: Error: Invalid buffer description pointer */
- rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,
- "IDirectSound8_CreateSoundBuffer should have returned "
- "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- /* DSOUND: Error: Invalid buffer description pointer */
- rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
- ok(rc==DSERR_INVALIDPARAM && primary==0,
- "IDirectSound8_CreateSoundBuffer() should have returned "
- "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=%p\n",
- DXGetErrorString8(rc),primary);
-
- /* DSOUND: Error: Invalid buffer description pointer */
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
- ok(rc==DSERR_INVALIDPARAM && primary==0,
- "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
- "dsbo=%p\n",DXGetErrorString8(rc),primary);
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
-
- /* DSOUND: Error: Invalid size */
- /* DSOUND: Error: Invalid buffer description */
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DSERR_INVALIDPARAM && primary==0,
- "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
- "primary=%p\n",DXGetErrorString8(rc),primary);
-
- /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(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|DSBCAPS_CTRLVOLUME;
- bufdesc.lpwfxFormat = &wfx;
- init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
- if (rc==DS_OK && primary!=NULL)
- IDirectSoundBuffer_Release(primary);
-
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
- "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
- "%s\n",DXGetErrorString8(rc));
- if (rc==DSERR_CONTROLUNAVAIL)
- trace(" No Primary\n");
- else if (rc==DS_OK && primary!=NULL) {
- LONG vol;
-
- /* Try to create a second primary buffer */
- /* DSOUND: Error: The primary buffer already exists.
- * Any changes made to the buffer description will be ignored. */
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
- ok(rc==DS_OK && second==primary,
- "IDirectSound8_CreateSoundBuffer() should have returned original "
- "primary buffer: %s\n",DXGetErrorString8(rc));
- ref=IDirectSoundBuffer_Release(second);
- ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
- "should have 1\n",ref);
-
- /* Try to duplicate a primary buffer */
- /* DSOUND: Error: Can't duplicate primary buffers */
- rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
- /* rc=0x88780032 */
- ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
- "should have failed %s\n",DXGetErrorString8(rc));
-
- rc=IDirectSoundBuffer_GetVolume(primary,&vol);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
- DXGetErrorString8(rc));
-
- if (winetest_interactive) {
- trace("Playing a 5 seconds reference tone at the current volume.\n");
- if (rc==DS_OK)
- trace("(the current volume is %ld according to DirectSound)\n",
- vol);
- trace("All subsequent tones should be identical to this one.\n");
- trace("Listen for stutter, changes in pitch, volume, etc.\n");
- }
- test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
- !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
-
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-/*
- * Test the primary buffer at different formats while keeping the
- * secondary buffer at a constant format.
- */
-static HRESULT test_primary_secondary8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx, wfx2;
- int ref;
- unsigned int f;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,
- "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
- "%s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && primary!=NULL) {
- for (f=0;f<NB_FORMATS;f++) {
- /* We must call SetCooperativeLevel to be allowed to call
- * SetFormat */
- /* DSOUND: Setting DirectSound cooperative level to
- * DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
- formats[f][2]);
- wfx2=wfx;
- rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
- ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
- DXGetErrorString8(rc));
-
- /* There is no garantee that SetFormat will actually change the
- * format to what we asked for. It depends on what the soundcard
- * supports. So we must re-query the format.
- */
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK &&
- (wfx.wFormatTag!=wfx2.wFormatTag ||
- wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
- wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
- wfx.nChannels!=wfx2.nChannels)) {
- trace("Requested primary format tag=0x%04x %ldx%dx%d "
- "avg.B/s=%ld align=%d\n",
- wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
- wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
- trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
- init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
-
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx2;
- if (winetest_interactive) {
- trace(" Testing a primary buffer at %ldx%dx%d with a "
- "secondary buffer at %ldx%dx%d\n",
- wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
- wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
- }
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound_CreateSoundBuffer() failed to create a secondary "
- "buffer %s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && secondary!=NULL) {
- test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,1.0,0,NULL,0,0);
-
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() 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);
- }
-
- /* Set the CooperativeLevel back to normal */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static HRESULT test_secondary8(LPGUID lpGuid)
-{
- HRESULT rc;
- LPDIRECTSOUND8 dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- DSBUFFERDESC bufdesc;
- DSCAPS dscaps;
- WAVEFORMATEX wfx, wfx1;
- DWORD f;
- int ref;
-
- /* Create the DirectSound object */
- rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
- "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- return rc;
-
- /* Get the device capabilities */
- ZeroMemory(&dscaps, sizeof(dscaps));
- dscaps.dwSize=sizeof(dscaps);
- rc=IDirectSound8_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* We must call SetCooperativeLevel before creating primary buffer */
- /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
- rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK && primary!=NULL,
- "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
- "%s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && primary!=NULL) {
- rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
- ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT1;
-
- for (f=0;f<NB_FORMATS;f++) {
- init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
- formats[f][2]);
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
- "should have returned DSERR_INVALIDPARAM, returned: %s\n",
- DXGetErrorString8(rc));
- if (rc==DS_OK && secondary!=NULL)
- IDirectSoundBuffer_Release(secondary);
-
- secondary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
- wfx.nBlockAlign);
- bufdesc.lpwfxFormat=&wfx;
- if (winetest_interactive) {
- trace(" Testing a secondary buffer at %ldx%dx%d "
- "with a primary buffer at %ldx%dx%d\n",
- wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
- wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
- }
- rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
- ok(rc==DS_OK && secondary!=NULL,
- "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
- "buffer: %s\n",DXGetErrorString8(rc));
-
- if (rc==DS_OK && secondary!=NULL) {
- test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
- winetest_interactive,1.0,0,NULL,0,0);
-
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
- "should have 0\n",ref);
- }
- }
-EXIT1:
- 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=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
- ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
-
-EXIT:
- ref=IDirectSound8_Release(dso);
- ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
- if (ref!=0)
- return DSERR_GENERIC;
-
- return rc;
-}
-
-static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
- LPCSTR lpcstrModule, LPVOID lpContext)
-{
- HRESULT rc;
- trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
- rc = test_dsound8(lpGuid);
- if (rc == DSERR_NODRIVER)
- trace(" No Driver\n");
- else if (rc == DSERR_ALLOCATED)
- trace(" Already In Use\n");
- else if (rc == E_FAIL)
- trace(" No Device\n");
- else {
- test_primary8(lpGuid);
- test_primary_secondary8(lpGuid);
- test_secondary8(lpGuid);
- }
-
- return 1;
-}
-
-static void dsound8_tests(void)
-{
- HRESULT rc;
- rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
- ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
-}
-
-const char * get_file_version(const char * file_name)
-{
- static char version[32];
- DWORD size;
- DWORD handle;
-
- size = GetFileVersionInfoSizeA("dsound.dll", &handle);
- if (size) {
- char * data = HeapAlloc(GetProcessHeap(), 0, size);
- if (data) {
- if (GetFileVersionInfoA("dsound.dll", handle, size, data)) {
- VS_FIXEDFILEINFO *pFixedVersionInfo;
- UINT len;
- if (VerQueryValueA(data, "\\", (LPVOID *)&pFixedVersionInfo, &len)) {
- sprintf(version, "%ld.%ld.%ld.%ld",
- pFixedVersionInfo->dwFileVersionMS >> 16,
- pFixedVersionInfo->dwFileVersionMS & 0xffff,
- pFixedVersionInfo->dwFileVersionLS >> 16,
- pFixedVersionInfo->dwFileVersionLS & 0xffff);
- } else
- sprintf(version, "not available");
- } else
- sprintf(version, "failed");
-
- HeapFree(GetProcessHeap(), 0, data);
- } else
- sprintf(version, "failed");
- } else
- sprintf(version, "not available");
-
- return version;
-}
-
-START_TEST(dsound8)
-{
- HMODULE hDsound;
-
- CoInitialize(NULL);
-
- hDsound = LoadLibraryA("dsound.dll");
- if (!hDsound) {
- trace("dsound.dll not found\n");
- return;
- }
-
- trace("DLL Version: %s\n", get_file_version("dsound.dll"));
-
- pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
- if (!pDirectSoundCreate8) {
- trace("dsound8 test skipped\n");
- return;
- }
-
- IDirectSound8_tests();
- dsound8_tests();
-
- CoUninitialize();
-}
+++ /dev/null
-/*
- * Unit tests for dsound functions
- *
- * Copyright (c) 2004 Francois Gouget
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-static const unsigned int formats[][4]={
- { 8000, 8, 1, 0 },
- { 8000, 8, 2, 0 },
- { 8000, 16, 1, 0 },
- { 8000, 16, 2, 0 },
- {11025, 8, 1, WAVE_FORMAT_1M08 },
- {11025, 8, 2, WAVE_FORMAT_1S08 },
- {11025, 16, 1, WAVE_FORMAT_1M16 },
- {11025, 16, 2, WAVE_FORMAT_1S16 },
- {22050, 8, 1, WAVE_FORMAT_2M08 },
- {22050, 8, 2, WAVE_FORMAT_2S08 },
- {22050, 16, 1, WAVE_FORMAT_2M16 },
- {22050, 16, 2, WAVE_FORMAT_2S16 },
- {44100, 8, 1, WAVE_FORMAT_4M08 },
- {44100, 8, 2, WAVE_FORMAT_4S08 },
- {44100, 16, 1, WAVE_FORMAT_4M16 },
- {44100, 16, 2, WAVE_FORMAT_4S16 },
- {48000, 8, 1, WAVE_FORMAT_48M08 },
- {48000, 8, 2, WAVE_FORMAT_48S08 },
- {48000, 16, 1, WAVE_FORMAT_48M16 },
- {48000, 16, 2, WAVE_FORMAT_48S16 },
- {96000, 8, 1, WAVE_FORMAT_96M08 },
- {96000, 8, 2, WAVE_FORMAT_96S08 },
- {96000, 16, 1, WAVE_FORMAT_96M16 },
- {96000, 16, 2, WAVE_FORMAT_96S16 }
-};
-#define NB_FORMATS (sizeof(formats)/sizeof(*formats))
-
-/* The time slice determines how often we will service the buffer */
-#define TIME_SLICE 31
-#define BUFFER_LEN 400
-
-extern char* wave_generate_la(WAVEFORMATEX*,double,DWORD*);
-extern HWND get_hwnd(void);
-extern void init_format(WAVEFORMATEX*,int,int,int,int);
-extern void test_buffer(LPDIRECTSOUND,LPDIRECTSOUNDBUFFER,
- BOOL,BOOL,LONG,BOOL,LONG,BOOL,double,BOOL,
- LPDIRECTSOUND3DLISTENER,BOOL,BOOL,BOOL,DWORD);
-extern void test_buffer8(LPDIRECTSOUND8,LPDIRECTSOUNDBUFFER,
- BOOL,BOOL,LONG,BOOL,LONG,BOOL,double,BOOL,
- LPDIRECTSOUND3DLISTENER,BOOL,BOOL);
-extern const char * getDSBCAPS(DWORD xmask);
-extern int align(int length, int align);
-extern const char * get_file_version(const char * file_name);
+++ /dev/null
-/*
- * Unit tests for CLSID_DirectSoundPrivate property set functions
- * (used by dxdiag)
- *
- * Copyright (c) 2003 Robert Reif
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NONAMELESSSTRUCT
-#define NONAMELESSUNION
-#define COBJMACROS
-#include <windows.h>
-
-#include "wine/test.h"
-#include "dsound.h"
-#include "initguid.h"
-#include "dsconf.h"
-#include "dxerr8.h"
-
-#include "dsound_test.h"
-
-#ifndef DSBCAPS_CTRLDEFAULT
-#define DSBCAPS_CTRLDEFAULT \
- DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME
-#endif
-
-DEFINE_GUID(DSPROPSETID_VoiceManager, \
- 0x62A69BAE,0xDF9D,0x11D1,0x99,0xA6,0x00,0xC0,0x4F,0xC9,0x9D,0x46);
-DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties, \
- 0x306a6a8,0xb224,0x11d2,0x99,0xe5,0x0,0x0,0xe8,0xd8,0xc7,0x22);
-DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties, \
- 0x306a6a7,0xb224,0x11d2,0x99,0xe5,0x0,0x0,0xe8,0xd8,0xc7,0x22);
-DEFINE_GUID(DSPROPSETID_I3DL2_ListenerProperties, \
- 0xDA0F0520,0x300A,0x11D3,0x8A,0x2B,0x00,0x60,0x97,0x0D,0xB0,0x11);
-DEFINE_GUID(DSPROPSETID_I3DL2_BufferProperties, \
- 0xDA0F0521,0x300A,0x11D3,0x8A,0x2B,0x00,0x60,0x97,0x0D,0xB0,0x11);
-DEFINE_GUID(DSPROPSETID_ZOOMFX_BufferProperties, \
- 0xCD5368E0,0x3450,0x11D3,0x8B,0x6E,0x00,0x10,0x5A,0x9B,0x7B,0xBC);
-
-typedef HRESULT (CALLBACK * MYPROC)(REFCLSID, REFIID, LPVOID *);
-
-static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,
- LPUNKNOWN)=NULL;
-static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,
- LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
-static HRESULT (WINAPI *pDirectSoundCaptureCreate8)(LPCGUID,
- LPDIRECTSOUNDCAPTURE8*,LPUNKNOWN)=NULL;
-static HRESULT (WINAPI *pDirectSoundFullDuplexCreate)(LPCGUID,LPCGUID,
- LPCDSCBUFFERDESC,LPCDSBUFFERDESC,HWND,DWORD,LPDIRECTSOUNDFULLDUPLEX*,
- LPDIRECTSOUNDCAPTUREBUFFER8*,LPDIRECTSOUNDBUFFER8*,LPUNKNOWN)=NULL;
-
-BOOL CALLBACK callback(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA data,
- LPVOID context)
-{
- trace(" found device:\n");
- trace(" Type: %s\n",
- data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
- trace(" DataFlow: %s\n",
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
- "Capture" : "Unknown");
- trace(" DeviceId: {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
- data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
- data->DeviceId.Data4[0],data->DeviceId.Data4[1],
- data->DeviceId.Data4[2],data->DeviceId.Data4[3],
- data->DeviceId.Data4[4],data->DeviceId.Data4[5],
- data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
- trace(" Description: %s\n", data->Description);
- trace(" Module: %s\n", data->Module);
- trace(" Interface: %s\n", data->Interface);
- trace(" WaveDeviceId: %ld\n", data->WaveDeviceId);
-
- return TRUE;
-}
-
-BOOL CALLBACK callback1(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data,
- LPVOID context)
-{
- char descriptionA[0x100];
- char moduleA[MAX_PATH];
-
- trace(" found device:\n");
- trace(" Type: %s\n",
- data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
- trace(" DataFlow: %s\n",
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
- "Capture" : "Unknown");
- trace(" DeviceId: {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
- data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
- data->DeviceId.Data4[0],data->DeviceId.Data4[1],
- data->DeviceId.Data4[2],data->DeviceId.Data4[3],
- data->DeviceId.Data4[4],data->DeviceId.Data4[5],
- data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
- trace(" DescriptionA: %s\n", data->DescriptionA);
- WideCharToMultiByte(CP_ACP, 0, data->DescriptionW, -1, descriptionA, sizeof(descriptionA), NULL, NULL);
- trace(" DescriptionW: %s\n", descriptionA);
- trace(" ModuleA: %s\n", data->ModuleA);
- WideCharToMultiByte(CP_ACP, 0, data->ModuleW, -1, moduleA, sizeof(moduleA), NULL, NULL);
- trace(" ModuleW: %s\n", moduleA);
- trace(" WaveDeviceId: %ld\n", data->WaveDeviceId);
-
- return TRUE;
-}
-
-BOOL CALLBACK callbackA(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data,
- LPVOID context)
-{
- trace(" found device:\n");
- trace(" Type: %s\n",
- data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
- trace(" DataFlow: %s\n",
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
- "Capture" : "Unknown");
- trace(" DeviceId: {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
- data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
- data->DeviceId.Data4[0],data->DeviceId.Data4[1],
- data->DeviceId.Data4[2],data->DeviceId.Data4[3],
- data->DeviceId.Data4[4],data->DeviceId.Data4[5],
- data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
- trace(" Description: %s\n", data->Description);
- trace(" Module: %s\n", data->Module);
- trace(" Interface: %s\n", data->Interface);
- trace(" WaveDeviceId: %ld\n", data->WaveDeviceId);
-
- return TRUE;
-}
-
-BOOL CALLBACK callbackW(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data,
- LPVOID context)
-{
- char descriptionA[0x100];
- char moduleA[MAX_PATH];
- char interfaceA[MAX_PATH];
-
- trace("found device:\n");
- trace("\tType: %s\n",
- data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
- data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
- trace("\tDataFlow: %s\n",
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
- data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
- "Capture" : "Unknown");
- trace("\tDeviceId: {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
- data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
- data->DeviceId.Data4[0],data->DeviceId.Data4[1],
- data->DeviceId.Data4[2],data->DeviceId.Data4[3],
- data->DeviceId.Data4[4],data->DeviceId.Data4[5],
- data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
- WideCharToMultiByte(CP_ACP, 0, data->Description, -1, descriptionA, sizeof(descriptionA), NULL, NULL);
- WideCharToMultiByte(CP_ACP, 0, data->Module, -1, moduleA, sizeof(moduleA), NULL, NULL);
- WideCharToMultiByte(CP_ACP, 0, data->Interface, -1, interfaceA, sizeof(interfaceA), NULL, NULL);
- trace("\tDescription: %s\n", descriptionA);
- trace("\tModule: %s\n", moduleA);
- trace("\tInterface: %s\n", interfaceA);
- trace("\tWaveDeviceId: %ld\n", data->WaveDeviceId);
-
- return TRUE;
-}
-
-static void propset_private_tests(void)
-{
- HMODULE hDsound;
- HRESULT rc;
- IClassFactory * pcf;
- IKsPropertySet * pps;
- MYPROC fProc;
- ULONG support;
-
- hDsound = LoadLibrary("dsound.dll");
- ok(hDsound!=0,"LoadLibrary(dsound.dll) failed\n");
- if (hDsound==0)
- return;
-
- fProc = (MYPROC)GetProcAddress(hDsound, "DllGetClassObject");
-
- /* try direct sound first */
- /* DSOUND: Error: Invalid interface buffer */
- rc = (fProc)(&CLSID_DirectSound, &IID_IClassFactory, (void **)0);
- ok(rc==DSERR_INVALIDPARAM,"DllGetClassObject(CLSID_DirectSound, "
- "IID_IClassFactory) should have returned DSERR_INVALIDPARAM, "
- "returned: %s\n",DXGetErrorString8(rc));
-
- rc = (fProc)(&CLSID_DirectSound, &IID_IClassFactory, (void **)(&pcf));
- ok(pcf!=0, "DllGetClassObject(CLSID_DirectSound, IID_IClassFactory) "
- "failed: %s\n",DXGetErrorString8(rc));
- if (pcf==0)
- goto error;
-
- /* direct sound doesn't have an IKsPropertySet */
- /* DSOUND: Error: Invalid interface buffer */
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)0);
- ok(rc==DSERR_INVALIDPARAM, "CreateInstance(IID_IKsPropertySet) should have "
- "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
-
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)(&pps));
- ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
- "returned E_NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
-
- /* and the direct sound 8 version */
- if (pDirectSoundCreate8) {
- rc = (fProc)(&CLSID_DirectSound8, &IID_IClassFactory, (void **)(&pcf));
- ok(pcf!=0, "DllGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
- "failed: %s\n",DXGetErrorString8(rc));
- if (pcf==0)
- goto error;
-
- /* direct sound 8 doesn't have an IKsPropertySet */
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)(&pps));
- ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
- "returned E_NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
- }
-
- /* try direct sound capture next */
- if (pDirectSoundCaptureCreate) {
- rc = (fProc)(&CLSID_DirectSoundCapture, &IID_IClassFactory,
- (void **)(&pcf));
- ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundCapture, IID_IClassFactory) "
- "failed: %s\n",DXGetErrorString8(rc));
- if (pcf==0)
- goto error;
-
- /* direct sound capture doesn't have an IKsPropertySet */
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)(&pps));
- ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
- "returned E_NOINTERFACE,returned: %s\n",DXGetErrorString8(rc));
- }
-
- /* and the direct sound capture 8 version */
- if (pDirectSoundCaptureCreate8) {
- rc = (fProc)(&CLSID_DirectSoundCapture8, &IID_IClassFactory,
- (void **)(&pcf));
- ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundCapture8, "
- "IID_IClassFactory) failed: %s\n",DXGetErrorString8(rc));
- if (pcf==0)
- goto error;
-
- /* direct sound capture 8 doesn't have an IKsPropertySet */
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)(&pps));
- ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
- "returned E_NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
- }
-
- /* try direct sound full duplex next */
- if (pDirectSoundFullDuplexCreate) {
- rc = (fProc)(&CLSID_DirectSoundFullDuplex, &IID_IClassFactory,
- (void **)(&pcf));
- ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundFullDuplex, "
- "IID_IClassFactory) failed: %s\n",DXGetErrorString8(rc));
- if (pcf==0)
- goto error;
-
- /* direct sound full duplex doesn't have an IKsPropertySet */
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)(&pps));
- ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
- "returned NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
- }
-
- /* try direct sound private last */
- rc = (fProc)(&CLSID_DirectSoundPrivate, &IID_IClassFactory,
- (void **)(&pcf));
-
- /* some early versions of Direct Sound do not have this */
- if (pcf==0)
- goto error;
-
- /* direct sound private does have an IKsPropertySet */
- rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
- (void **)(&pps));
- ok(rc==DS_OK, "CreateInstance(IID_IKsPropertySet) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- /* test generic DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
- &support);
- ok(rc==DS_OK||rc==E_INVALIDARG,
- "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- if (rc==E_INVALIDARG)
- trace(" Not Supported\n");
- goto error;
- }
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),
- "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION: "
- "support = 0x%lx\n",support);
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1,
- &support);
- ok(rc==DS_OK||rc==E_INVALIDARG,
- "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- if (rc==E_INVALIDARG)
- trace(" Not Supported\n");
- goto error;
- }
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),
- "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: "
- "support = 0x%lx\n",support);
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A,
- &support);
- ok(rc==DS_OK||rc==E_INVALIDARG,
- "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- if (rc==E_INVALIDARG)
- trace(" Not Supported\n");
- goto error;
- }
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),
- "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: "
- "support = 0x%lx\n",support);
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W,
- &support);
- ok(rc==DS_OK||rc==E_INVALIDARG,
- "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- if (rc==E_INVALIDARG)
- trace(" Not Supported\n");
- goto error;
- }
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),
- "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: "
- "support = 0x%lx\n",support);
-
- /* test generic DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING, &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING: support = "
- "0x%lx\n",support);
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A, &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: support = "
- "0x%lx\n",support);
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W */
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W, &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: support = "
- "0x%lx\n",support);
-
- /* test generic DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE */
- trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE ***\n");
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE,
- &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE: support = 0x%lx\n",support);
-
- if (support & KSPROPERTY_SUPPORT_GET) {
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA data;
- ULONG bytes;
-
- data.Callback = callback;
- data.Context = 0;
-
- rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE,
- NULL, 0, &data, sizeof(data), &bytes);
- ok(rc==DS_OK, "Couldn't enumerate: 0x%lx\n",rc);
- }
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 */
- trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 ***\n");
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1,
- &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: support = 0x%lx\n",support);
-
- if (support & KSPROPERTY_SUPPORT_GET) {
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA data;
- ULONG bytes;
-
- data.Callback = callback1;
- data.Context = 0;
-
- rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1,
- NULL, 0, &data, sizeof(data), &bytes);
- ok(rc==DS_OK, "Couldn't enumerate: 0x%lx\n",rc);
- }
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A */
- trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A ***\n");
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A,
- &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: support = 0x%lx\n",support);
-
- if (support & KSPROPERTY_SUPPORT_GET) {
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA data;
- ULONG bytes;
-
- data.Callback = callbackA;
- data.Context = 0;
-
- rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A,
- NULL, 0, &data, sizeof(data), &bytes);
- ok(rc==DS_OK, "Couldn't enumerate: 0x%lx\n",rc);
- }
-
- /* test DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W */
- trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W ***\n");
- rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W,
- &support);
- ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W) failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto error;
-
- ok(support & KSPROPERTY_SUPPORT_GET,
- "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: "
- "support = 0x%lx\n",support);
- ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
- "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: support = 0x%lx\n",support);
-
- if (support & KSPROPERTY_SUPPORT_GET) {
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
- ULONG bytes;
-
- data.Callback = callbackW;
- data.Context = 0;
-
- rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
- DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W,
- NULL, 0, &data, sizeof(data), &bytes);
- ok(rc==DS_OK, "Couldn't enumerate: 0x%lx\n",rc);
- }
-
-error:
- FreeLibrary(hDsound);
-}
-
-static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
- LPCSTR lpcstrModule, LPVOID lpContext)
-{
- HRESULT rc;
- LPDIRECTSOUND dso=NULL;
- LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
- DSBUFFERDESC bufdesc;
- WAVEFORMATEX wfx;
- int ref;
-
- trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
-
- rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
- "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
- if (rc!=DS_OK) {
- if (rc==DSERR_NODRIVER)
- trace(" No Driver\n");
- else if (rc == DSERR_ALLOCATED)
- trace(" Already In Use\n");
- else if (rc == E_FAIL)
- trace(" No Device\n");
- goto EXIT;
- }
-
- /* 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,"IDirectSound_SetCooperativeLevel() failed: %s\n",
- DXGetErrorString8(rc));
- if (rc!=DS_OK)
- goto EXIT;
-
- /* Testing 3D buffers */
- primary=NULL;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_LOCHARDWARE|DSBCAPS_CTRL3D;
- rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
- ok(rc==DS_OK&&primary!=NULL,"IDirectSound_CreateSoundBuffer() failed to "
- "create a hardware 3D primary buffer: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK&&primary!=NULL) {
- ZeroMemory(&wfx, sizeof(wfx));
- wfx.wFormatTag=WAVE_FORMAT_PCM;
- wfx.nChannels=1;
- wfx.wBitsPerSample=16;
- wfx.nSamplesPerSec=44100;
- wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
- wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
- ZeroMemory(&bufdesc, sizeof(bufdesc));
- bufdesc.dwSize=sizeof(bufdesc);
- bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
- bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
- bufdesc.lpwfxFormat=&wfx;
- trace(" Testing a 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,"IDirectSound_CreateSoundBuffer() "
- "failed to create a secondary buffer: %s\n",DXGetErrorString8(rc));
- if (rc==DS_OK&&secondary!=NULL) {
- IKsPropertySet * pPropertySet=NULL;
- rc=IDirectSoundBuffer_QueryInterface(secondary,
- &IID_IKsPropertySet,
- (void **)&pPropertySet);
- /* it's not an error for this to fail */
- if(rc==DS_OK) {
- ULONG ulTypeSupport;
- trace(" Supports property sets\n");
- /* it's not an error for these to fail */
- rc=IKsPropertySet_QuerySupport(pPropertySet,
- &DSPROPSETID_VoiceManager,
- 0,&ulTypeSupport);
- if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
- KSPROPERTY_SUPPORT_SET)))
- trace(" DSPROPSETID_VoiceManager supported\n");
- else
- trace(" DSPROPSETID_VoiceManager not supported\n");
- rc=IKsPropertySet_QuerySupport(pPropertySet,
- &DSPROPSETID_EAX20_ListenerProperties,0,&ulTypeSupport);
- if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
- KSPROPERTY_SUPPORT_SET)))
- trace(" DSPROPSETID_EAX20_ListenerProperties "
- "supported\n");
- else
- trace(" DSPROPSETID_EAX20_ListenerProperties not "
- "supported\n");
- rc=IKsPropertySet_QuerySupport(pPropertySet,
- &DSPROPSETID_EAX20_BufferProperties,0,&ulTypeSupport);
- if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
- KSPROPERTY_SUPPORT_SET)))
- trace(" DSPROPSETID_EAX20_BufferProperties supported\n");
- else
- trace(" DSPROPSETID_EAX20_BufferProperties not "
- "supported\n");
- rc=IKsPropertySet_QuerySupport(pPropertySet,
- &DSPROPSETID_I3DL2_ListenerProperties,0,&ulTypeSupport);
- if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
- KSPROPERTY_SUPPORT_SET)))
- trace(" DSPROPSETID_I3DL2_ListenerProperties "
- "supported\n");
- else
- trace(" DSPROPSETID_I3DL2_ListenerProperties not "
- "supported\n");
- rc=IKsPropertySet_QuerySupport(pPropertySet,
- &DSPROPSETID_I3DL2_BufferProperties,0,&ulTypeSupport);
- if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
- KSPROPERTY_SUPPORT_SET)))
- trace(" DSPROPSETID_I3DL2_BufferProperties supported\n");
- else
- trace(" DSPROPSETID_I3DL2_BufferProperties not "
- "supported\n");
- rc=IKsPropertySet_QuerySupport(pPropertySet,
- &DSPROPSETID_ZOOMFX_BufferProperties,0,&ulTypeSupport);
- if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
- KSPROPERTY_SUPPORT_SET)))
- trace(" DSPROPSETID_ZOOMFX_BufferProperties "
- "supported\n");
- else
- trace(" DSPROPSETID_ZOOMFX_BufferProperties not "
- "supported\n");
- ref=IKsPropertySet_Release(pPropertySet);
- /* try a few common ones */
- ok(ref==0,"IKsPropertySet_Release() secondary has %d "
- "references, should have 0\n",ref);
- } else
- trace(" Doesn't support property sets\n");
-
- ref=IDirectSoundBuffer_Release(secondary);
- ok(ref==0,"IDirectSoundBuffer_Release() secondary 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);
- }
-
-EXIT:
- if (dso!=NULL) {
- ref=IDirectSound_Release(dso);
- ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
- ref);
- }
- return 1;
-}
-
-static void propset_buffer_tests(void)
-{
- HRESULT rc;
- rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
- ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
-}
-
-START_TEST(propset)
-{
- HMODULE hDsound;
-
- CoInitialize(NULL);
-
- hDsound = LoadLibraryA("dsound.dll");
- if (!hDsound) {
- trace("dsound.dll not found\n");
- return;
- }
-
- trace("DLL Version: %s\n", get_file_version("dsound.dll"));
-
- pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
- pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate");
- pDirectSoundCaptureCreate8=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate8");
- pDirectSoundFullDuplexCreate=(void*)GetProcAddress(hDsound,"DirectSoundFullDuplexCreate");
-
- propset_private_tests();
- propset_buffer_tests();
-
- CoUninitialize();
-}
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define WINE_OLESELFREGISTER
+1 WINE_REGISTRY dsound_classes.rgs
+
#define WINE_FILEDESCRIPTION_STR "Wine DirectSound"
#define WINE_FILENAME_STR "dsound.dll"
#define WINE_FILEVERSION 5,3,1,904
#define WINE_FILEVERSION_STR "5.3.1.904"
#define WINE_PRODUCTVERSION 5,3,1,904
#define WINE_PRODUCTVERSION_STR "5.3.1.904"
+#define WINE_EXTRAVALUES VALUE "OLESelfRegister",""
-#include "wine/wine_common_ver.rc"
+#include <wine/wine_common_ver.rc>
DEVPROPID pid;
} DEVPROPKEY, *PDEVPROPKEY;
-#endif /* DEVPROPKEY_DEFINED */
#define DEVPROPID_FIRST_USABLE 2
+#endif /* DEVPROPKEY_DEFINED */
+
#endif /* _DEVPROPDEF_H_ */
#ifdef DEFINE_DEVPROPKEY
#undef DEFINE_DEVPROPKEY
#endif
#ifdef INITGUID
-#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY name = {{ l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}, pid}
+#ifdef __cplusplus
+#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \
+ EXTERN_C const DEVPROPKEY DECLSPEC_HIDDEN DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
+#else
+#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \
+ const DEVPROPKEY DECLSPEC_HIDDEN DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
+#endif
#else
-#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY name
+#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \
+ EXTERN_C const DEVPROPKEY DECLSPEC_HIDDEN DECLSPEC_SELECTANY name
#endif /* INITGUID */
#ifndef IsEqualDevPropKey
+++ /dev/null
-/*
- * DirectSound driver
- * (DirectX 5 version)
- *
- * Copyright (C) 2000 Ove Kaaven
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __WINE_DSDRIVER_H
-#define __WINE_DSDRIVER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************************************************************
- * Predeclare the interfaces
- */
-DEFINE_GUID(IID_IDsDriver, 0x8C4233C0l, 0xB4CC, 0x11CE, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
-typedef struct IDsDriver *PIDSDRIVER;
-
-DEFINE_GUID(IID_IDsDriverBuffer, 0x8C4233C1l, 0xB4CC, 0x11CE, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
-typedef struct IDsDriverBuffer *PIDSDRIVERBUFFER;
-
-DEFINE_GUID(IID_IDsDriverPropertySet, 0x0F6F2E8E0, 0xD842, 0x11D0, 0x8F, 0x75, 0x00, 0xC0, 0x4F, 0xC2, 0x8A, 0xCA);
-typedef struct IDsDriverPropertySet *PIDSDRIVERPROPERTYSET;
-
-DEFINE_GUID(IID_IDsDriverNotify, 0x00363EF44, 0x3B57, 0x11D3, 0xAC, 0x79, 0x00, 0x10, 0x5A, 0x01, 0x7f, 0xe1);
-typedef struct IDsDriverNotify *PIDSDRIVERNOTIFY;
-
-DEFINE_GUID(IID_IDsCaptureDriver, 0x03DD10C47, 0x74FB, 0x11D3, 0x90, 0x49, 0xCB, 0xB4, 0xB3, 0x2E, 0xAA, 0x08);
-typedef struct IDsCaptureDriver *PIDSCDRIVER;
-
-DEFINE_GUID(IID_IDsCaptureDriverBuffer, 0x03DD10C48, 0x74FB, 0x11D3, 0x90, 0x49, 0xCB, 0xB4, 0xB3, 0x2E, 0xAA, 0x08);
-typedef struct IDsCaptureDriverBuffer *PIDSCDRIVERBUFFER;
-
-#define DSDDESC_DOMMSYSTEMOPEN 0x00000001
-#define DSDDESC_DOMMSYSTEMSETFORMAT 0x00000002
-#define DSDDESC_USESYSTEMMEMORY 0x00000004
-#define DSDDESC_DONTNEEDPRIMARYLOCK 0x00000008
-#define DSDDESC_DONTNEEDSECONDARYLOCK 0x00000010
-#define DSDDESC_DONTNEEDWRITELEAD 0x00000020
-
-#define DSDHEAP_NOHEAP 0
-#define DSDHEAP_CREATEHEAP 1
-#define DSDHEAP_USEDIRECTDRAWHEAP 2
-#define DSDHEAP_PRIVATEHEAP 3
-
-typedef struct _DSDRIVERDESC
-{
- DWORD dwFlags;
- TCHAR szDesc[256];
- TCHAR szDrvname[256];
- DWORD_PTR dnDevNode;
- WORD wVxdId;
- WORD wReserved;
- ULONG ulDeviceNum;
- DWORD dwHeapType;
- LPVOID pvDirectDrawHeap;
- DWORD dwMemStartAddress;
- DWORD dwMemEndAddress;
- DWORD dwMemAllocExtra;
- LPVOID pvReserved1;
- LPVOID pvReserved2;
-} DSDRIVERDESC,*PDSDRIVERDESC;
-
-
-
-
-typedef struct _DSDRIVERCAPS
-{
- DWORD dwFlags;
- DWORD dwMinSecondarySampleRate;
- DWORD dwMaxSecondarySampleRate;
- DWORD dwPrimaryBuffers;
- DWORD dwMaxHwMixingAllBuffers;
- DWORD dwMaxHwMixingStaticBuffers;
- DWORD dwMaxHwMixingStreamingBuffers;
- DWORD dwFreeHwMixingAllBuffers;
- DWORD dwFreeHwMixingStaticBuffers;
- DWORD dwFreeHwMixingStreamingBuffers;
- DWORD dwMaxHw3DAllBuffers;
- DWORD dwMaxHw3DStaticBuffers;
- DWORD dwMaxHw3DStreamingBuffers;
- DWORD dwFreeHw3DAllBuffers;
- DWORD dwFreeHw3DStaticBuffers;
- DWORD dwFreeHw3DStreamingBuffers;
- DWORD dwTotalHwMemBytes;
- DWORD dwFreeHwMemBytes;
- DWORD dwMaxContigFreeHwMemBytes;
-} DSDRIVERCAPS,*PDSDRIVERCAPS;
-
-typedef struct _DSVOLUMEPAN
-{
- DWORD dwTotalLeftAmpFactor;
- DWORD dwTotalRightAmpFactor;
- LONG lVolume;
- DWORD dwVolAmpFactor;
- LONG lPan;
- DWORD dwPanLeftAmpFactor;
- DWORD dwPanRightAmpFactor;
-} DSVOLUMEPAN,*PDSVOLUMEPAN;
-
-typedef union _DSPROPERTY
-{
- struct {
- GUID Set;
- ULONG Id;
- ULONG Flags;
- ULONG_PTR InstanceId;
- } DUMMYSTRUCTNAME;
- ULONGLONG Alignment;
-} DSPROPERTY,*PDSPROPERTY;
-
-typedef struct _DSCDRIVERCAPS
-{
- DWORD dwSize;
- DWORD dwFlags;
- DWORD dwFormats;
- DWORD dwChannels;
-} DSCDRIVERCAPS,*PDSCDRIVERCAPS;
-
-/*****************************************************************************
- * IDsDriver interface
- */
-#define INTERFACE IDsDriver
-DECLARE_INTERFACE_(IDsDriver,IUnknown)
-{
- /*** IUnknown methods ***/
- STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDsDriver methods ***/
- STDMETHOD(GetDriverDesc)(THIS_ PDSDRIVERDESC pDsDriverDesc) PURE;
- STDMETHOD(Open)(THIS) PURE;
- STDMETHOD(Close)(THIS) PURE;
- STDMETHOD(GetCaps)(THIS_ PDSDRIVERCAPS pDsDrvCaps) PURE;
- STDMETHOD(CreateSoundBuffer)(THIS_ LPWAVEFORMATEX pwfx,DWORD dwFlags,DWORD dwCardAddress,LPDWORD pdwcbBufferSize,LPBYTE *ppbBuffer,LPVOID *ppvObj) PURE;
- STDMETHOD(DuplicateSoundBuffer)(THIS_ PIDSDRIVERBUFFER pIDsDriverBuffer,LPVOID *ppvObj) PURE;
-};
-#undef INTERFACE
-
-#if !defined (__cplusplus) || defined(CINTERFACE)
- /*** IUnknown methods ***/
-#define IDsDriver_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
-#define IDsDriver_AddRef(p) (p)->lpVtbl->AddRef(p)
-#define IDsDriver_Release(p) (p)->lpVtbl->Release(p)
- /*** IDsDriver methods ***/
-#define IDsDriver_GetDriverDesc(p,a) (p)->lpVtbl->GetDriverDesc(p,a)
-#define IDsDriver_Open(p) (p)->lpVtbl->Open(p)
-#define IDsDriver_Close(p) (p)->lpVtbl->Close(p)
-#define IDsDriver_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
-#define IDsDriver_CreateSoundBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateSoundBuffer(p,a,b,c,d,e,f)
-#define IDsDriver_DuplicateSoundBuffer(p,a,b) (p)->lpVtbl->DuplicateSoundBuffer(p,a,b)
-#endif
-
-/*****************************************************************************
- * IDsDriverBuffer interface
- */
-#define INTERFACE IDsDriverBuffer
-DECLARE_INTERFACE_(IDsDriverBuffer,IUnknown)
-{
- /*** IUnknown methods ***/
- STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDsDriverBuffer methods ***/
- STDMETHOD(Lock)(THIS_ LPVOID *ppvAudio1,LPDWORD pdwLen1,LPVOID *pdwAudio2,LPDWORD pdwLen2,DWORD dwWritePosition,DWORD dwWriteLen,DWORD dwFlags) PURE;
- STDMETHOD(Unlock)(THIS_ LPVOID pvAudio1,DWORD dwLen1,LPVOID pvAudio2,DWORD dwLen2) PURE;
- STDMETHOD(SetFormat)(THIS_ LPWAVEFORMATEX pwfxToSet) PURE;
- STDMETHOD(SetFrequency)(THIS_ DWORD dwFrequency) PURE;
- STDMETHOD(SetVolumePan)(THIS_ PDSVOLUMEPAN pDsVolumePan) PURE;
- STDMETHOD(SetPosition)(THIS_ DWORD dwNewPosition) PURE;
- STDMETHOD(GetPosition)(THIS_ LPDWORD lpdwCurrentPlayCursor,LPDWORD lpdwCurrentWriteCursor) PURE;
- STDMETHOD(Play)(THIS_ DWORD dwReserved1,DWORD dwReserved2,DWORD dwFlags) PURE;
- STDMETHOD(Stop)(THIS) PURE;
-};
-#undef INTERFACE
-
-#if !defined (__cplusplus) || defined(CINTERFACE)
- /*** IUnknown methods ***/
-#define IDsDriverBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
-#define IDsDriverBuffer_AddRef(p) (p)->lpVtbl->AddRef(p)
-#define IDsDriverBuffer_Release(p) (p)->lpVtbl->Release(p)
- /*** IDsDriverBuffer methods ***/
-#define IDsDriverBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g)
-#define IDsDriverBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d)
-#define IDsDriverBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a)
-#define IDsDriverBuffer_SetFrequency(p,a) (p)->lpVtbl->SetFrequency(p,a)
-#define IDsDriverBuffer_SetVolumePan(p,a) (p)->lpVtbl->SetVolumePan(p,a)
-#define IDsDriverBuffer_SetPosition(p,a) (p)->lpVtbl->SetPosition(p,a)
-#define IDsDriverBuffer_GetPosition(p,a,b) (p)->lpVtbl->GetPosition(p,a,b)
-#define IDsDriverBuffer_Play(p,a,b,c) (p)->lpVtbl->Play(p,a,b,c)
-#define IDsDriverBuffer_Stop(p) (p)->lpVtbl->Stop(p)
-#endif
-
-/*****************************************************************************
- * IDsDriverPropertySet interface
- */
-#define INTERFACE IDsDriverPropertySet
-DECLARE_INTERFACE_(IDsDriverPropertySet,IUnknown)
-{
- /*** IUnknown methods ***/
- STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDsDriverPropertySet methods ***/
- STDMETHOD(Get)(THIS_ PDSPROPERTY pDsProperty,LPVOID pPropertyParams,ULONG cbPropertyParams,LPVOID pPropertyData,ULONG cbPropertyData,PULONG pcbReturnedData) PURE;
- STDMETHOD(Set)(THIS_ PDSPROPERTY pDsProperty,LPVOID pPropertyParams,ULONG cbPropertyParams,LPVOID pPropertyData,ULONG cbPropertyData) PURE;
- STDMETHOD(QuerySupport)(THIS_ REFGUID PropertySetId,ULONG PropertyId,PULONG pSupport) PURE;
-};
-#undef INTERFACE
-
-#if !defined (__cplusplus) || defined(CINTERFACE)
- /*** IUnknown methods ***/
-#define IDsDriverPropertySet_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
-#define IDsDriverPropertySet_AddRef(p) (p)->lpVtbl->AddRef(p)
-#define IDsDriverPropertySet_Release(p) (p)->lpVtbl->Release(p)
- /*** IDsDriverPropertySet methods ***/
-#define IDsDriverPropertySet_Get(p,a,b,c,d,e,f) (p)->lpVtbl->Get(p,a,b,c,d,e,f)
-#define IDsDriverPropertySet_Set(p,a,b,c,d,e) (p)->lpVtbl->Set(p,a,b,c,d,e)
-#define IDsDriverPropertySet_QuerySupport(p,a,b,c) (p)->lpVtbl->QuerySupport(p,a,b,c)
-#endif
-
-/* Defined property sets */
-DEFINE_GUID(DSPROPSETID_DirectSound3DListener, 0x6D047B40, 0x7AF9, 0x11D0, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
-typedef enum
-{
- DSPROPERTY_DIRECTSOUND3DLISTENER_ALL,
- DSPROPERTY_DIRECTSOUND3DLISTENER_POSITION,
- DSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY,
- DSPROPERTY_DIRECTSOUND3DLISTENER_ORIENTATION,
- DSPROPERTY_DIRECTSOUND3DLISTENER_DISTANCEFACTOR,
- DSPROPERTY_DIRECTSOUND3DLISTENER_ROLLOFFFACTOR,
- DSPROPERTY_DIRECTSOUND3DLISTENER_DOPPLERFACTOR,
- DSPROPERTY_DIRECTSOUND3DLISTENER_BATCH,
- DSPROPERTY_DIRECTSOUND3DLISTENER_ALLOCATION
-} DSPROPERTY_DIRECTSOUND3DLISTENER;
-
-DEFINE_GUID(DSPROPSETID_DirectSound3DBuffer, 0x6D047B41, 0x7AF9, 0x11D0, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
-typedef enum
-{
- DSPROPERTY_DIRECTSOUND3DBUFFER_ALL,
- DSPROPERTY_DIRECTSOUND3DBUFFER_POSITION,
- DSPROPERTY_DIRECTSOUND3DBUFFER_VELOCITY,
- DSPROPERTY_DIRECTSOUND3DBUFFER_CONEANGLES,
- DSPROPERTY_DIRECTSOUND3DBUFFER_CONEORIENTATION,
- DSPROPERTY_DIRECTSOUND3DBUFFER_CONEOUTSIDEVOLUME,
- DSPROPERTY_DIRECTSOUND3DBUFFER_MINDISTANCE,
- DSPROPERTY_DIRECTSOUND3DBUFFER_MAXDISTANCE,
- DSPROPERTY_DIRECTSOUND3DBUFFER_MODE
-} DSPROPERTY_DIRECTSOUND3DBUFFER;
-
-DEFINE_GUID(DSPROPSETID_DirectSoundSpeakerConfig, 0x6D047B42, 0x7AF9, 0x11D0, 0x92, 0x94, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
-typedef enum
-{
- DSPROPERTY_DIRECTSOUNDSPEAKERCONFIG_SPEAKERCONFIG
-} DSPROPERTY_DIRECTSOUNDSPEAKERCONFIG;
-
-/*****************************************************************************
- * IDsDriverNotify interface
- */
-#define INTERFACE IDsDriverNotify
-DECLARE_INTERFACE_(IDsDriverNotify,IUnknown)
-{
- /*** IUnknown methods ***/
- STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDsDriverNotify methods ***/
- STDMETHOD(SetNotificationPositions)(THIS_ DWORD dwPositionNotifies,LPCDSBPOSITIONNOTIFY pcPositionNotifies) PURE;
-};
-#undef INTERFACE
-
-#if !defined (__cplusplus) || defined(CINTERFACE)
- /*** IUnknown methods ***/
-#define IDsDriverNotify_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
-#define IDsDriverNotify_AddRef(p) (p)->lpVtbl->AddRef(p)
-#define IDsDriverNotify_Release(p) (p)->lpVtbl->Release(p)
- /*** IDsDriverNotify methods ***/
-#define IDsDriverNotify_SetNotificationPositions(p,a,b) (p)->lpVtbl->SetNotificationPositions(p,a,b)
-#endif
-
-/*****************************************************************************
- * IDsCaptureDriver interface
- */
-#define INTERFACE IDsCaptureDriver
-DECLARE_INTERFACE_(IDsCaptureDriver,IUnknown)
-{
- /*** IUnknown methods ***/
- STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDsCaptureDriver methods ***/
- STDMETHOD(GetDriverDesc)(THIS_ PDSDRIVERDESC pDsDriverDesc) PURE;
- STDMETHOD(Open)(THIS) PURE;
- STDMETHOD(Close)(THIS) PURE;
- STDMETHOD(GetCaps)(THIS_ PDSCDRIVERCAPS pDsDrvCaps) PURE;
- STDMETHOD(CreateCaptureBuffer)(THIS_ LPWAVEFORMATEX pwfx,DWORD dwFlags,DWORD dwCardAddress,LPDWORD pdwcbBufferSize,LPBYTE *ppbBuffer,LPVOID *ppvObj) PURE;
-};
-#undef INTERFACE
-
-#if !defined (__cplusplus) || defined(CINTERFACE)
- /*** IUnknown methods ***/
-#define IDsCaptureDriver_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
-#define IDsCaptureDriver_AddRef(p) (p)->lpVtbl->AddRef(p)
-#define IDsCaptureDriver_Release(p) (p)->lpVtbl->Release(p)
- /*** IDsCaptureDriver methods ***/
-#define IDsCaptureDriver_GetDriverDesc(p,a) (p)->lpVtbl->GetDriverDesc(p,a)
-#define IDsCaptureDriver_Open(p) (p)->lpVtbl->Open(p)
-#define IDsCaptureDriver_Close(p) (p)->lpVtbl->Close(p)
-#define IDsCaptureDriver_GetCaps(p,a) (p)->lpVtbl->GetCaps(p,a)
-#define IDsCaptureDriver_CreateCaptureBuffer(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCaptureBuffer(p,a,b,c,d,e,f)
-#endif
-
-/*****************************************************************************
- * IDsCaptureDriverBuffer interface
- */
-#define INTERFACE IDsCaptureDriverBuffer
-DECLARE_INTERFACE_(IDsCaptureDriverBuffer,IUnknown)
-{
- /*** IUnknown methods ***/
- STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
- STDMETHOD_(ULONG,AddRef)(THIS) PURE;
- STDMETHOD_(ULONG,Release)(THIS) PURE;
- /*** IDsCaptureDriverBuffer methods ***/
- STDMETHOD(Lock)(THIS_ LPVOID *ppvAudio1,LPDWORD pdwLen1,LPVOID *ppvAudio2,LPDWORD pdwLen2,DWORD dwWritePosition,DWORD dwWriteLen,DWORD dwFlags) PURE;
- STDMETHOD(Unlock)(THIS_ LPVOID pvAudio1,DWORD dwLen1,LPVOID pvAudio2,DWORD dwLen2) PURE;
- STDMETHOD(SetFormat)(THIS_ LPWAVEFORMATEX pwfxToSet) PURE;
- STDMETHOD(GetPosition)(THIS_ LPDWORD lpdwCurrentPlayCursor,LPDWORD lpdwCurrentWriteCursor) PURE;
- STDMETHOD(GetStatus)(THIS_ LPDWORD lpdwStatus) PURE;
- STDMETHOD(Start)(THIS_ DWORD dwFlags) PURE;
- STDMETHOD(Stop)(THIS) PURE;
-};
-#undef INTERFACE
-
-#if !defined (__cplusplus) || defined(CINTERFACE)
- /*** IUnknown methods ***/
-#define IDsCaptureDriverBuffer_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
-#define IDsCaptureDriverBuffer_AddRef(p) (p)->lpVtbl->AddRef(p)
-#define IDsCaptureDriverBuffer_Release(p) (p)->lpVtbl->Release(p)
- /*** IDsCaptureDriverBuffer methods ***/
-#define IDsCaptureDriverBuffer_Lock(p,a,b,c,d,e,f,g) (p)->lpVtbl->Lock(p,a,b,c,d,e,f,g)
-#define IDsCaptureDriverBuffer_Unlock(p,a,b,c,d) (p)->lpVtbl->Unlock(p,a,b,c,d)
-#define IDsCaptureDriverBuffer_SetFormat(p,a) (p)->lpVtbl->SetFormat(p,a)
-#define IDsCaptureDriverBuffer_GetPosition(p,a,b) (p)->lpVtbl->GetPosition(p,a,b)
-#define IDsCaptureDriverBuffer_GetStatus(p,a) (p)->lpVtbl->GetStatus(p,a)
-#define IDsCaptureDriverBuffer_Start(p,a) (p)->lpVtbl->Start(p,a)
-#define IDsCaptureDriverBuffer_Stop(p) (p)->lpVtbl->Stop(p)
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* __WINE_DSDRIVER_H */
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-
-
-#ifndef __WINE_DSOUND_H
-#define __WINE_DSOUND_H
-
-// hack
+#ifndef __DSOUND_INCLUDED__
#define __DSOUND_INCLUDED__
-
#ifndef DIRECTSOUND_VERSION
#define DIRECTSOUND_VERSION 0x0900
#endif
#define LPD3DVECTOR_DEFINED
#endif
-
-
#define DX_SHARED_DEFINES
#endif /* DX_SHARED_DEFINES */
#define DSBFREQUENCY_MAX 200000
#define DSBFREQUENCY_ORIGINAL 0
+#define DSBNOTIFICATIONS_MAX 100000U
+
typedef struct _DSBCAPS
{
DWORD dwSize;
} DSBPOSITIONNOTIFY,*LPDSBPOSITIONNOTIFY;
typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY;
+#define DSSPEAKER_DIRECTOUT 0
#define DSSPEAKER_HEADPHONE 1
#define DSSPEAKER_MONO 2
#define DSSPEAKER_QUAD 3
#define DSSPEAKER_STEREO 4
#define DSSPEAKER_SURROUND 5
#define DSSPEAKER_5POINT1 6
+#define DSSPEAKER_5POINT1_BACK 6
#define DSSPEAKER_7POINT1 7
+#define DSSPEAKER_7POINT1_WIDE 7
+#define DSSPEAKER_7POINT1_SURROUND 8
+#define DSSPEAKER_5POINT1_SURROUND 9
#define DSSPEAKER_GEOMETRY_MIN 0x00000005 /* 5 degrees */
#define DSSPEAKER_GEOMETRY_NARROW 0x0000000A /* 10 degrees */
typedef BOOL (CALLBACK *LPDSENUMCALLBACKW)(LPGUID,LPCWSTR,LPCWSTR,LPVOID);
typedef BOOL (CALLBACK *LPDSENUMCALLBACKA)(LPGUID,LPCSTR,LPCSTR,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDSENUMCALLBACK)
extern HRESULT WINAPI DirectSoundCreate(LPCGUID lpGUID,LPDIRECTSOUND *ppDS,LPUNKNOWN pUnkOuter);
extern HRESULT WINAPI DirectSoundEnumerateA(LPDSENUMCALLBACKA, LPVOID);
extern HRESULT WINAPI DirectSoundEnumerateW(LPDSENUMCALLBACKW, LPVOID);
-
+#define DirectSoundEnumerate WINELIB_NAME_AW(DirectSoundEnumerate)
extern HRESULT WINAPI DirectSoundCaptureCreate(LPCGUID lpGUID, LPDIRECTSOUNDCAPTURE *ppDSC, LPUNKNOWN pUnkOuter);
extern HRESULT WINAPI DirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA, LPVOID);
extern HRESULT WINAPI DirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW, LPVOID);
+#define DirectSoundCaptureEnumerate WINELIB_NAME_AW(DirectSoundCaptureEnumerate)
extern HRESULT WINAPI DirectSoundCreate8(LPCGUID lpGUID,LPDIRECTSOUND8 *ppDS8,LPUNKNOWN pUnkOuter);
extern HRESULT WINAPI DirectSoundCaptureCreate8(LPCGUID lpGUID, LPDIRECTSOUNDCAPTURE8 *ppDSC8, LPUNKNOWN pUnkOuter);
#define DirectSoundFullDuplexCreate8 DirectSoundFullDuplexCreate
extern HRESULT WINAPI GetDeviceID(LPCGUID lpGuidSrc, LPGUID lpGuidDest);
-#ifdef UNICODE
-# define DirectSoundEnumerate DirectSoundEnumerateW
-# define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateW
-# define LPDSENUMCALLBACK LPDSENUMCALLBACKW
-#else
-# define DirectSoundEnumerate DirectSoundEnumerateA
-# define DirectSoundCaptureEnumerate DirectSoundCaptureEnumerateA
-# define LPDSENUMCALLBACK LPDSENUMCALLBACKA
-#endif
/*****************************************************************************
* IDirectSound interface
STDMETHOD(GetFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
STDMETHOD(GetStatus)(THIS_ LPDWORD lpdwStatus) PURE;
STDMETHOD(Initialize)(THIS_ LPDIRECTSOUND lpDirectSound, LPCDSBUFFERDESC lpcDSBufferDesc) PURE;
- STDMETHOD(Lock)(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID *lplpvAudioPtr1, LPDWORD lpdwAudioBytes1, LPVOID *lplpvAudioPtr2, LPDWORD lpdwAudioBytes2, DWORD dwFlags) PURE;
+ STDMETHOD(Lock)(THIS_ DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE;
STDMETHOD(Play)(THIS_ DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags) PURE;
STDMETHOD(SetCurrentPosition)(THIS_ DWORD dwNewPosition) PURE;
STDMETHOD(SetFormat)(THIS_ LPCWAVEFORMATEX lpcfxFormat) PURE;
STDMETHOD(SetPan)(THIS_ LONG lPan) PURE;
STDMETHOD(SetFrequency)(THIS_ DWORD dwFrequency) PURE;
STDMETHOD(Stop)(THIS) PURE;
- STDMETHOD(Unlock)(THIS_ LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioPtr2) PURE;
+ STDMETHOD(Unlock)(THIS_ LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioPtr2) PURE;
STDMETHOD(Restore)(THIS) PURE;
};
#undef INTERFACE
STDMETHOD(GetFrequency)(THIS_ LPDWORD lpdwFrequency) PURE;
STDMETHOD(GetStatus)(THIS_ LPDWORD lpdwStatus) PURE;
STDMETHOD(Initialize)(THIS_ LPDIRECTSOUND lpDirectSound, LPCDSBUFFERDESC lpcDSBufferDesc) PURE;
- STDMETHOD(Lock)(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID *lplpvAudioPtr1, LPDWORD lpdwAudioBytes1, LPVOID *lplpvAudioPtr2, LPDWORD lpdwAudioBytes2, DWORD dwFlags) PURE;
+ STDMETHOD(Lock)(THIS_ DWORD dwOffset, DWORD dwBytes, LPVOID *ppvAudioPtr1, LPDWORD pdwAudioBytes1, LPVOID *ppvAudioPtr2, LPDWORD pdwAudioBytes2, DWORD dwFlags) PURE;
STDMETHOD(Play)(THIS_ DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags) PURE;
STDMETHOD(SetCurrentPosition)(THIS_ DWORD dwNewPosition) PURE;
STDMETHOD(SetFormat)(THIS_ LPCWAVEFORMATEX lpcfxFormat) PURE;
STDMETHOD(SetPan)(THIS_ LONG lPan) PURE;
STDMETHOD(SetFrequency)(THIS_ DWORD dwFrequency) PURE;
STDMETHOD(Stop)(THIS) PURE;
- STDMETHOD(Unlock)(THIS_ LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioPtr2) PURE;
+ STDMETHOD(Unlock)(THIS_ LPVOID pvAudioPtr1, DWORD dwAudioBytes1, LPVOID pvAudioPtr2, DWORD dwAudioPtr2) PURE;
STDMETHOD(Restore)(THIS) PURE;
STDMETHOD(SetFX)(THIS_ DWORD dwEffectsCount, LPDSEFFECTDESC pDSFXDesc, LPDWORD pdwResultCodes) PURE;
STDMETHOD(AcquireResources)(THIS_ DWORD dwFlags, DWORD dwEffectsCount, LPDWORD pdwResultCodes) PURE;
#define WINE_NOBUFFER 0x80000000
#define DSBPN_OFFSETSTOP -1
-#define DSBNOTIFICATIONS_MAX 100000UL
#define INTERFACE IDirectSoundNotify
DECLARE_INTERFACE_(IDirectSoundNotify,IUnknown)
#define IDirectSound3DBuffer_GetPosition(p,a) (p)->lpVtbl->GetPosition(p,a)
#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->lpVtbl->GetVelocity(p,a)
#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->lpVtbl->SetAllParameters(p,a,b)
-#define IDirectSound3DBuffer_SetConeAngles(p,a,b) (p)->lpVtbl->SetConeAngles(p,a,b)
+#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->lpVtbl->SetConeAngles(p,a,b,c)
#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->lpVtbl->SetConeOrientation(p,a,b,c,d)
#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b) (p)->lpVtbl->SetConeOutsideVolume(p,a,b)
#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->lpVtbl->SetMaxDistance(p,a,b)
#define IDirectSound3DBuffer_GetPosition(p,a) (p)->GetPosition(a)
#define IDirectSound3DBuffer_GetVelocity(p,a) (p)->GetVelocity(a)
#define IDirectSound3DBuffer_SetAllParameters(p,a,b) (p)->SetAllParameters(a,b)
-#define IDirectSound3DBuffer_SetConeAngles(p,a,b) (p)->SetConeAngles(a,b)
+#define IDirectSound3DBuffer_SetConeAngles(p,a,b,c) (p)->SetConeAngles(a,b,c)
#define IDirectSound3DBuffer_SetConeOrientation(p,a,b,c,d) (p)->SetConeOrientation(a,b,c,d)
#define IDirectSound3DBuffer_SetConeOutsideVolume(p,a,b) (p)->SetConeOutsideVolume(a,b)
#define IDirectSound3DBuffer_SetMaxDistance(p,a,b) (p)->SetMaxDistance(a,b)
} /* extern "C" */
#endif /* defined(__cplusplus) */
-#endif /* __WINE_DSOUND_H */
+#endif /* __DSOUND_INCLUDED__ */
#ifdef INITGUID
#ifdef __cplusplus
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \
- EXTERN_C const PROPERTYKEY name DECLSPEC_HIDDEN DECLSPEC_SELECTANY; \
- EXTERN_C const PROPERTYKEY name = \
+ EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY name DECLSPEC_HIDDEN = \
{ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
#else
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \
- const PROPERTYKEY name DECLSPEC_HIDDEN DECLSPEC_SELECTANY; \
- const PROPERTYKEY name = \
+ const PROPERTYKEY DECLSPEC_SELECTANY name DECLSPEC_HIDDEN = \
{ { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
#endif
#else
#define DEFINE_PROPERTYKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) \
- EXTERN_C const PROPERTYKEY name DECLSPEC_HIDDEN DECLSPEC_SELECTANY
+ EXTERN_C const PROPERTYKEY name DECLSPEC_HIDDEN
#endif
#ifndef IsEqualPropertyKey
#ifdef __cplusplus
extern "C++"
{
+
inline bool operator==(REFPROPERTYKEY guidOne, REFPROPERTYKEY guidOther)
{
return IsEqualPropertyKey(guidOne, guidOther);
{
return !(guidOne == guidOther);
}
-} //extern "C++"
+
+}
#endif
#endif
reactos/dll/directx/dmusic # Synced to Wine-1.5.26
reactos/dll/directx/dplay # Synced to Wine-1.5.26
reactos/dll/directx/dplayx # Synced to Wine-1.5.26
+reactos/dll/directx/dsound # Synced to Wine-1.5.26
reactos/dll/directx/dxdiagn # Synced to Wine-0_9_5
reactos/dll/directx/msdmo # Autosync
reactos/dll/directx/qedit # Autosync