From 18e14e7e3e42009865d87ed02958de93beb604af Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 13 Apr 2013 23:33:54 +0000 Subject: [PATCH] [DSOUND] * Sync with Wine 1.5.26. svn path=/trunk/; revision=58752 --- reactos/dll/directx/dsound/CMakeLists.txt | 22 +- reactos/dll/directx/dsound/buffer.c | 1163 +++---- reactos/dll/directx/dsound/capture.c | 2717 ++++++++--------- reactos/dll/directx/dsound/dsound.c | 1854 ++++------- reactos/dll/directx/dsound/dsound_classes.idl | 61 + reactos/dll/directx/dsound/dsound_classes.rgs | 33 + reactos/dll/directx/dsound/dsound_convert.c | 398 +-- reactos/dll/directx/dsound/dsound_main.c | 652 ++-- reactos/dll/directx/dsound/dsound_private.h | 461 +-- reactos/dll/directx/dsound/duplex.c | 999 ++---- reactos/dll/directx/dsound/fir.h | 1591 ++++++++++ reactos/dll/directx/dsound/mixer.c | 867 +++--- reactos/dll/directx/dsound/primary.c | 1334 ++++---- reactos/dll/directx/dsound/propset.c | 1591 +++------- reactos/dll/directx/dsound/regsvr.c | 534 ---- reactos/dll/directx/dsound/sound3d.c | 765 ++--- reactos/dll/directx/dsound/tests/.cvsignore | 8 - reactos/dll/directx/dsound/tests/Makefile.in | 19 - reactos/dll/directx/dsound/tests/capture.c | 723 ----- reactos/dll/directx/dsound/tests/ds3d.c | 1243 -------- reactos/dll/directx/dsound/tests/ds3d8.c | 1148 ------- reactos/dll/directx/dsound/tests/dsound.c | 947 ------ reactos/dll/directx/dsound/tests/dsound8.c | 858 ------ .../dll/directx/dsound/tests/dsound_test.h | 64 - reactos/dll/directx/dsound/tests/propset.c | 734 ----- reactos/dll/directx/dsound/version.rc | 6 +- reactos/include/psdk/devpropdef.h | 14 +- reactos/include/psdk/dsdriver.h | 369 --- reactos/include/psdk/dsound.h | 47 +- reactos/include/psdk/propkeydef.h | 12 +- reactos/media/doc/README.WINE | 1 + 31 files changed, 6544 insertions(+), 14691 deletions(-) create mode 100644 reactos/dll/directx/dsound/dsound_classes.idl create mode 100644 reactos/dll/directx/dsound/dsound_classes.rgs create mode 100644 reactos/dll/directx/dsound/fir.h delete mode 100644 reactos/dll/directx/dsound/regsvr.c delete mode 100644 reactos/dll/directx/dsound/tests/.cvsignore delete mode 100644 reactos/dll/directx/dsound/tests/Makefile.in delete mode 100644 reactos/dll/directx/dsound/tests/capture.c delete mode 100644 reactos/dll/directx/dsound/tests/ds3d.c delete mode 100644 reactos/dll/directx/dsound/tests/ds3d8.c delete mode 100644 reactos/dll/directx/dsound/tests/dsound.c delete mode 100644 reactos/dll/directx/dsound/tests/dsound8.c delete mode 100644 reactos/dll/directx/dsound/tests/dsound_test.h delete mode 100644 reactos/dll/directx/dsound/tests/propset.c delete mode 100644 reactos/include/psdk/dsdriver.h diff --git a/reactos/dll/directx/dsound/CMakeLists.txt b/reactos/dll/directx/dsound/CMakeLists.txt index 5dfef621b30..37a695a2034 100644 --- a/reactos/dll/directx/dsound/CMakeLists.txt +++ b/reactos/dll/directx/dsound/CMakeLists.txt @@ -1,7 +1,8 @@ add_definitions( -D_WINE - -D_USE_MATH_DEFINES) + -D_USE_MATH_DEFINES + -D__WINESRC__) include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) @@ -17,26 +18,11 @@ add_library(dsound SHARED 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) - diff --git a/reactos/dll/directx/dsound/buffer.c b/reactos/dll/directx/dsound/buffer.c index c5ad35e29bc..522d3bd2a1b 100644 --- a/reactos/dll/directx/dsound/buffer.c +++ b/reactos/dll/directx/dsound/buffer.c @@ -32,72 +32,64 @@ //#include "winuser.h" #include #include +#include #include #include -#include #include "dsound_private.h" +//#include 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); - -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); - - if (This->dsb == NULL) { - WARN("invalid parameter\n"); - return E_INVALIDARG; - } - - return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER)This->dsb, riid, ppobj); + return CONTAINING_RECORD(iface, struct IDirectSoundBufferImpl, IDirectSoundNotify_iface); } -static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface) +static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(IDirectSoundNotify *iface, REFIID riid, + void **ppobj) { - IDirectSoundNotifyImpl *This = (IDirectSoundNotifyImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); + IDirectSoundBufferImpl *This = impl_from_IDirectSoundNotify(iface); + + TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj); + + return IDirectSoundBuffer8_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj); +} + +static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(IDirectSoundNotify *iface) +{ + 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) { @@ -112,30 +104,24 @@ static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions( 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; } @@ -148,60 +134,40 @@ static const IDirectSoundNotifyVtbl dsnvt = 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); - - *pdsn = dsn; - return DS_OK; -} - -static HRESULT IDirectSoundNotifyImpl_Destroy( - IDirectSoundNotifyImpl *pdsn) -{ - TRACE("(%p)\n",pdsn); - - while (IDirectSoundNotifyImpl_Release((LPDIRECTSOUNDNOTIFY)pdsn) > 0); - - return DS_OK; -} - /******************************************************************************* * IDirectSoundBuffer */ -static HRESULT WINAPI IDirectSoundBufferImpl_SetFormat( - LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX wfex -) { - IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface; - - TRACE("(%p,%p)\n",This,wfex); - /* This method is not available on secondary buffers */ - WARN("invalid call\n"); - return DSERR_INVALIDCALL; +static inline IDirectSoundBufferImpl *impl_from_IDirectSoundBuffer8(IDirectSoundBuffer8 *iface) +{ + return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSoundBuffer8_iface); } -static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume( - LPDIRECTSOUNDBUFFER8 iface,LONG vol -) { - IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface; +static inline BOOL is_primary_buffer(IDirectSoundBufferImpl *This) +{ + return (This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) != 0; +} + +static HRESULT WINAPI IDirectSoundBufferImpl_SetFormat(IDirectSoundBuffer8 *iface, + LPCWAVEFORMATEX wfex) +{ + IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface); + + TRACE("(%p,%p)\n", iface, wfex); + + 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(IDirectSoundBuffer8 *iface, LONG vol) +{ + IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface); LONG oldVol; + HRESULT hres = DS_OK; TRACE("(%p,%d)\n",This,vol); @@ -232,24 +198,16 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume( 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)) { @@ -267,14 +225,18 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume( 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; @@ -294,10 +256,9 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency( 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); @@ -306,29 +267,23 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency( 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); /* **** */ @@ -336,10 +291,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Play( 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); /* **** */ @@ -352,13 +308,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface) 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); /* **** */ @@ -366,78 +315,70 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface) 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); - } - } - - HeapFree(GetProcessHeap(), 0, This->tmp_buffer); - HeapFree(GetProcessHeap(), 0, This->notifies); - HeapFree(GetProcessHeap(), 0, This->pwfx); - HeapFree(GetProcessHeap(), 0, This); - - TRACE("(%p) released\n", This); + 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; } + + ref = InterlockedDecrement(&This->ref); + if (!ref && !InterlockedDecrement(&This->numIfaces)) + secondarybuffer_destroy(This); + + TRACE("(%p) ref is now %d\n", This, ref); + 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", @@ -446,10 +387,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition( 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) { @@ -471,14 +412,12 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus( } -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; @@ -507,23 +446,15 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat( 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; @@ -557,44 +488,31 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock( /* **** */ 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); @@ -603,36 +521,24 @@ static HRESULT WINAPI IDirectSoundBufferImpl_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); /* **** */ @@ -640,11 +546,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetCurrentPosition( 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); @@ -666,12 +571,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetPan( 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); @@ -680,10 +579,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetPan( 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)) { @@ -701,30 +600,22 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetPan( 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 ) @@ -734,11 +625,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock( { 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); @@ -747,18 +634,18 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock( 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) { @@ -772,10 +659,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetFrequency( 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); @@ -787,25 +674,25 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFX( 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(%p)\n",This,caps); if (caps == NULL) { @@ -838,8 +726,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCaps( } 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; @@ -850,10 +737,10 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCaps( 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); @@ -867,39 +754,25 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface( 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 ) ) { @@ -908,15 +781,9 @@ static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface( } 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 ) ); @@ -961,7 +828,6 @@ HRESULT IDirectSoundBufferImpl_Create( 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) { @@ -981,31 +847,26 @@ HRESULT IDirectSoundBufferImpl_Create( 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 - @@ -1014,10 +875,8 @@ HRESULT IDirectSoundBufferImpl_Create( dsb->buflen = dsbd->dwBufferBytes; dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec; - dsb->notify = NULL; dsb->notifies = NULL; dsb->nrofnotifies = 0; - dsb->hwnotify = 0; /* Check necessary hardware mixing capabilities */ if (wfex->nChannels==2) capf |= DSCAPS_SECONDARYSTEREO; @@ -1025,24 +884,7 @@ HRESULT IDirectSoundBufferImpl_Create( 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))); @@ -1054,35 +896,15 @@ HRESULT IDirectSoundBufferImpl_Create( 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; @@ -1092,10 +914,10 @@ HRESULT IDirectSoundBufferImpl_Create( /* 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; @@ -1140,46 +962,33 @@ HRESULT IDirectSoundBufferImpl_Create( } } + 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); + + 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->ds3db) { - WARN("ds3db not NULL\n"); - IDirectSound3DBufferImpl_Destroy(pdsb->ds3db); - pdsb->ds3db = NULL; - } + HeapFree(GetProcessHeap(), 0, This->notifies); + HeapFree(GetProcessHeap(), 0, This->pwfx); + HeapFree(GetProcessHeap(), 0, This); - if (pdsb->notify) { - WARN("notify not NULL\n"); - IDirectSoundNotifyImpl_Destroy(pdsb->notify); - pdsb->notify = NULL; - } - - 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( @@ -1189,58 +998,42 @@ 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); @@ -1248,315 +1041,111 @@ HRESULT IDirectSoundBufferImpl_Duplicate( 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) +static inline IDirectSoundBufferImpl *impl_from_IKsPropertySet(IKsPropertySet *iface) { - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - - return IDirectSoundBufferImpl_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb,riid,ppobj); + return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IKsPropertySet_iface); } -static ULONG WINAPI SecondaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface) +/* IUnknown methods */ +static HRESULT WINAPI IKsPropertySetImpl_QueryInterface(IKsPropertySet *iface, REFIID riid, + void **ppobj) { - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); + IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface); + + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + + return IDirectSoundBuffer_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj); +} + +static ULONG WINAPI IKsPropertySetImpl_AddRef(IKsPropertySet *iface) +{ + IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface); + ULONG ref = InterlockedIncrement(&This->refiks); + TRACE("(%p) ref was %d\n", This, ref - 1); + + if(ref == 1) + InterlockedIncrement(&This->numIfaces); + return ref; } -static ULONG WINAPI SecondaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) +static ULONG WINAPI IKsPropertySetImpl_Release(IKsPropertySet *iface) { - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; + IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(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); + 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; } + + ref = InterlockedDecrement(&This->refiks); + if (!ref && !InterlockedDecrement(&This->numIfaces)) + secondarybuffer_destroy(This); + + TRACE("(%p) ref is now %d\n", This, ref); + return ref; } -static HRESULT WINAPI SecondaryBufferImpl_GetCaps( - LPDIRECTSOUNDBUFFER8 iface,LPDSBCAPS caps) +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)->(%p)\n",This,caps); + IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface); - return IDirectSoundBufferImpl_GetCaps((LPDIRECTSOUNDBUFFER8)This->dsb,caps); + 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); + + return E_PROP_ID_UNSUPPORTED; } -static HRESULT WINAPI SecondaryBufferImpl_GetCurrentPosition( - LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos) +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,%p,%p)\n",This,playpos,writepos); + IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface); - return IDirectSoundBufferImpl_GetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,playpos,writepos); + TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData); + + return E_PROP_ID_UNSUPPORTED; } -static HRESULT WINAPI SecondaryBufferImpl_GetFormat( - LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten) +static HRESULT WINAPI IKsPropertySetImpl_QuerySupport(IKsPropertySet *iface, REFGUID guidPropSet, + ULONG dwPropID, ULONG *pTypeSupport) { - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%p,%d,%p)\n",This,lpwf,wfsize,wfwritten); + IDirectSoundBufferImpl *This = impl_from_IKsPropertySet(iface); - return IDirectSoundBufferImpl_GetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,lpwf,wfsize,wfwritten); + TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport); + + return E_PROP_ID_UNSUPPORTED; } -static HRESULT WINAPI SecondaryBufferImpl_GetVolume( - LPDIRECTSOUNDBUFFER8 iface,LPLONG vol) -{ - 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); -} - -static HRESULT WINAPI SecondaryBufferImpl_Lock( - LPDIRECTSOUNDBUFFER8 iface, - DWORD writecursor, - DWORD writebytes, - LPVOID *lplpaudioptr1, - LPDWORD audiobytes1, - LPVOID *lplpaudioptr2, - LPDWORD audiobytes2, - DWORD dwFlags) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x)\n", - This,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,dwFlags); - - return IDirectSoundBufferImpl_Lock((LPDIRECTSOUNDBUFFER8)This->dsb, - writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,dwFlags); -} - -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); -} - -static HRESULT WINAPI SecondaryBufferImpl_SetCurrentPosition( - LPDIRECTSOUNDBUFFER8 iface,DWORD newpos) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%d)\n",This,newpos); - - return IDirectSoundBufferImpl_SetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,newpos); -} - -static HRESULT WINAPI SecondaryBufferImpl_SetFormat( - LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX wfex) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%p)\n",This,wfex); - - return IDirectSoundBufferImpl_SetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,wfex); -} - -static HRESULT WINAPI SecondaryBufferImpl_SetVolume( - LPDIRECTSOUNDBUFFER8 iface,LONG vol) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%d)\n",This,vol); - - return IDirectSoundBufferImpl_SetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol); -} - -static HRESULT WINAPI SecondaryBufferImpl_SetPan( - LPDIRECTSOUNDBUFFER8 iface,LONG pan) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%d)\n",This,pan); - - return IDirectSoundBufferImpl_SetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan); -} - -static HRESULT WINAPI SecondaryBufferImpl_SetFrequency( - LPDIRECTSOUNDBUFFER8 iface,DWORD freq) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%d)\n",This,freq); - - return IDirectSoundBufferImpl_SetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq); -} - -static HRESULT WINAPI SecondaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p)\n",This); - - return IDirectSoundBufferImpl_Stop((LPDIRECTSOUNDBUFFER8)This->dsb); -} - -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); -} - -static HRESULT WINAPI SecondaryBufferImpl_Restore( - LPDIRECTSOUNDBUFFER8 iface) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p)\n",This); - - return IDirectSoundBufferImpl_Restore((LPDIRECTSOUNDBUFFER8)This->dsb); -} - -static HRESULT WINAPI SecondaryBufferImpl_SetFX( - LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%u,%p,%p)\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes); - - return IDirectSoundBufferImpl_SetFX((LPDIRECTSOUNDBUFFER8)This->dsb,dwEffectsCount,pDSFXDesc,pdwResultCodes); -} - -static HRESULT WINAPI SecondaryBufferImpl_AcquireResources( - LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%08u,%u,%p)\n",This,dwFlags,dwEffectsCount,pdwResultCodes); - - return IDirectSoundBufferImpl_AcquireResources((LPDIRECTSOUNDBUFFER8)This->dsb,dwFlags,dwEffectsCount,pdwResultCodes); -} - -static HRESULT WINAPI SecondaryBufferImpl_GetObjectInPath( - LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID* ppObject) -{ - SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; - TRACE("(%p,%s,%u,%s,%p)\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject); - - return IDirectSoundBufferImpl_GetObjectInPath((LPDIRECTSOUNDBUFFER8)This->dsb,rguidObject,dwIndex,rguidInterface,ppObject); -} - -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; -} diff --git a/reactos/dll/directx/dsound/capture.c b/reactos/dll/directx/dsound/capture.c index 221a7cb5f6c..df3fdcf7476 100644 --- a/reactos/dll/directx/dsound/capture.c +++ b/reactos/dll/directx/dsound/capture.c @@ -30,7 +30,7 @@ #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H - +#define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION #include @@ -39,47 +39,171 @@ //#include "mmsystem.h" #include #include -#include +//#include "winnls.h" #include #include -#include #include "dsound_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dsound); -/***************************************************************************** - * IDirectSoundCapture implementation structure - */ -struct IDirectSoundCaptureImpl -{ - /* IUnknown fields */ - const IDirectSoundCaptureVtbl *lpVtbl; - LONG ref; +typedef struct DirectSoundCaptureDevice DirectSoundCaptureDevice; - DirectSoundCaptureDevice *device; +/* 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 +{ + 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 IDirectSoundCaptureImpl_Create(LPDIRECTSOUNDCAPTURE8 * ppds); - -/***************************************************************************** - * IDirectSoundCaptureNotify implementation structure - */ -struct IDirectSoundCaptureNotifyImpl +static void capturebuffer_destroy(IDirectSoundCaptureBufferImpl *This) { - /* IUnknown fields */ - const IDirectSoundNotifyVtbl *lpVtbl; - LONG ref; - IDirectSoundCaptureBufferImpl* dscb; + if (This->device->state == STATE_CAPTURING) + This->device->state = STATE_STOPPING; + + HeapFree(GetProcessHeap(),0, This->pdscbd); + + if (This->device->client) { + IAudioClient_Release(This->device->client); + This->device->client = NULL; + } + + if (This->device->capture) { + IAudioCaptureClient_Release(This->device->capture); + This->device->capture = NULL; + } + + /* remove from DirectSoundCaptureDevice */ + This->device->capture_buffer = NULL; + + HeapFree(GetProcessHeap(), 0, This->notifies); + HeapFree(GetProcessHeap(), 0, This); + TRACE("(%p) released\n", This); +} + +/******************************************************************************* + * IDirectSoundNotify + */ +static inline struct IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundNotify(IDirectSoundNotify *iface) +{ + return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundNotify_iface); +} + +static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(IDirectSoundNotify *iface, REFIID riid, + void **ppobj) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface); + + TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj); + + return IDirectSoundCaptureBuffer_QueryInterface(&This->IDirectSoundCaptureBuffer8_iface, riid, ppobj); +} + +static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(IDirectSoundNotify *iface) +{ + IDirectSoundCaptureBufferImpl *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(IDirectSoundNotify *iface) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface); + ULONG ref = InterlockedDecrement(&This->refn); + + TRACE("(%p) ref was %d\n", This, ref + 1); + + if (!ref && !InterlockedDecrement(&This->numIfaces)) + capturebuffer_destroy(This); + + return ref; +} + +static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(IDirectSoundNotify *iface, + DWORD howmuch, const DSBPOSITIONNOTIFY *notify) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(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 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 S_OK; +} + +static const IDirectSoundNotifyVtbl dscnvt = +{ + IDirectSoundNotifyImpl_QueryInterface, + IDirectSoundNotifyImpl_AddRef, + IDirectSoundNotifyImpl_Release, + IDirectSoundNotifyImpl_SetNotificationPositions }; -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", @@ -88,64 +212,1106 @@ static const char * const captureStateString[] = { "STATE_STOPPING" }; -HRESULT DSOUND_CaptureCreate( - REFIID riid, - LPDIRECTSOUNDCAPTURE *ppDSC) -{ - LPDIRECTSOUNDCAPTURE pDSC; - HRESULT hr; - TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSC); - if (!IsEqualIID(riid, &IID_IUnknown) && - !IsEqualIID(riid, &IID_IDirectSoundCapture)) { - *ppDSC = 0; +/******************************************************************************* + * IDirectSoundCaptureBuffer + */ +static inline IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundCaptureBuffer8(IDirectSoundCaptureBuffer8 *iface) +{ + return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundCaptureBuffer8_iface); +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_QueryInterface(IDirectSoundCaptureBuffer8 *iface, + REFIID riid, void **ppobj) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + + 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_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; + } + + FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI IDirectSoundCaptureBufferImpl_AddRef(IDirectSoundCaptureBuffer8 *iface) +{ + 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 IDirectSoundCaptureBufferImpl_Release(IDirectSoundCaptureBuffer8 *iface) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref was %d\n", This, ref + 1); + + if (!ref && !InterlockedDecrement(&This->numIfaces)) + capturebuffer_destroy(This); + + return ref; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetCaps(IDirectSoundCaptureBuffer8 *iface, + DSCBCAPS *lpDSCBCaps) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(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 (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + lpDSCBCaps->dwSize = sizeof(DSCBCAPS); + lpDSCBCaps->dwFlags = This->flags; + lpDSCBCaps->dwBufferBytes = This->pdscbd->dwBufferBytes; + lpDSCBCaps->dwReserved = 0; + + TRACE("returning DS_OK\n"); + return DS_OK; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetCurrentPosition(IDirectSoundCaptureBuffer8 *iface, + DWORD *lpdwCapturePosition, DWORD *lpdwReadPosition) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + + TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition ); + + if (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + EnterCriticalSection(&This->device->lock); + + if (!This->device->client) { + LeaveCriticalSection(&This->device->lock); + WARN("no driver\n"); + 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 DS_OK\n"); + + return DS_OK; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetFormat(IDirectSoundCaptureBuffer8 *iface, + WAVEFORMATEX *lpwfxFormat, DWORD dwSizeAllocated, DWORD *lpdwSizeWritten) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + HRESULT hres = DS_OK; + + TRACE("(%p,%p,0x%08x,%p)\n", This, lpwfxFormat, dwSizeAllocated, lpdwSizeWritten); + + if (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (dwSizeAllocated > (sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize)) + dwSizeAllocated = sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize; + + if (lpwfxFormat) { /* NULL is valid (just want size) */ + CopyMemory(lpwfxFormat, This->device->pwfx, dwSizeAllocated); + if (lpdwSizeWritten) + *lpdwSizeWritten = dwSizeAllocated; + } else { + if (lpdwSizeWritten) + *lpdwSizeWritten = sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize; + else { + TRACE("invalid parameter: lpdwSizeWritten = NULL\n"); + hres = DSERR_INVALIDPARAM; + } + } + + TRACE("returning %08x\n", hres); + return hres; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetStatus(IDirectSoundCaptureBuffer8 *iface, + DWORD *lpdwStatus) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + + TRACE( "(%p, %p), thread is %04x\n", This, lpdwStatus, GetCurrentThreadId() ); + + if (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (lpdwStatus == NULL) { + WARN("invalid parameter: lpdwStatus == NULL\n"); + return DSERR_INVALIDPARAM; + } + + *lpdwStatus = 0; + EnterCriticalSection(&(This->device->lock)); + + TRACE("old This->device->state=%s, old lpdwStatus=%08x\n", + captureStateString[This->device->state],*lpdwStatus); + if ((This->device->state == STATE_STARTING) || + (This->device->state == STATE_CAPTURING)) { + *lpdwStatus |= DSCBSTATUS_CAPTURING; + if (This->flags & DSCBSTART_LOOPING) + *lpdwStatus |= DSCBSTATUS_LOOPING; + } + TRACE("new This->device->state=%s, new lpdwStatus=%08x\n", + captureStateString[This->device->state],*lpdwStatus); + LeaveCriticalSection(&(This->device->lock)); + + TRACE("status=%x\n", *lpdwStatus); + TRACE("returning DS_OK\n"); + return DS_OK; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Initialize(IDirectSoundCaptureBuffer8 *iface, + IDirectSoundCapture *lpDSC, const DSCBUFFERDESC *lpcDSCBDesc) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + + FIXME( "(%p,%p,%p): stub\n", This, lpDSC, lpcDSCBDesc ); + + return DS_OK; +} + +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; + + TRACE( "(%p,%08u,%08u,%p,%p,%p,%p,0x%08x) at %d\n", This, dwReadCusor, + dwReadBytes, lplpvAudioPtr1, lpdwAudioBytes1, lplpvAudioPtr2, + lpdwAudioBytes2, dwFlags, GetTickCount() ); + + if (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (lplpvAudioPtr1 == NULL) { + WARN("invalid parameter: lplpvAudioPtr1 == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (lpdwAudioBytes1 == NULL) { + WARN("invalid parameter: lpdwAudioBytes1 == NULL\n"); + return DSERR_INVALIDPARAM; + } + + EnterCriticalSection(&(This->device->lock)); + + if (This->device->client) { + *lplpvAudioPtr1 = This->device->buffer + dwReadCusor; + if ( (dwReadCusor + dwReadBytes) > This->device->buflen) { + *lpdwAudioBytes1 = This->device->buflen - dwReadCusor; + if (lplpvAudioPtr2) + *lplpvAudioPtr2 = This->device->buffer; + if (lpdwAudioBytes2) + *lpdwAudioBytes2 = dwReadBytes - *lpdwAudioBytes1; + } else { + *lpdwAudioBytes1 = dwReadBytes; + if (lplpvAudioPtr2) + *lplpvAudioPtr2 = 0; + if (lpdwAudioBytes2) + *lpdwAudioBytes2 = 0; + } + } else { + TRACE("invalid call\n"); + hres = DSERR_INVALIDCALL; /* DSERR_NODRIVER ? */ + } + + LeaveCriticalSection(&(This->device->lock)); + + TRACE("returning %08x\n", hres); + return hres; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Start(IDirectSoundCaptureBuffer8 *iface, + DWORD dwFlags) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + HRESULT hres; + + TRACE( "(%p,0x%08x)\n", This, dwFlags ); + + if (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if ( !This->device->client ) { + WARN("no driver\n"); + return DSERR_NODRIVER; + } + + EnterCriticalSection(&(This->device->lock)); + + 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; + + if (This->device->buffer) + FillMemory(This->device->buffer, This->device->buflen, (This->device->pwfx->wBitsPerSample == 8) ? 128 : 0); + + hres = IAudioClient_Start(This->device->client); + if(FAILED(hres)){ + WARN("Start failed: %08x\n", hres); + LeaveCriticalSection(&This->device->lock); + return hres; + } + +out: + LeaveCriticalSection(&This->device->lock); + + TRACE("returning DS_OK\n"); + return DS_OK; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Stop(IDirectSoundCaptureBuffer8 *iface) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + HRESULT hres; + + TRACE("(%p)\n", This); + + if (This->device == NULL) { + WARN("invalid parameter: This->device == NULL\n"); + return DSERR_INVALIDPARAM; + } + + EnterCriticalSection(&(This->device->lock)); + + TRACE("old This->device->state=%s\n",captureStateString[This->device->state]); + if (This->device->state == STATE_CAPTURING) + This->device->state = STATE_STOPPING; + else if (This->device->state == STATE_STARTING) + This->device->state = STATE_STOPPED; + TRACE("new This->device->state=%s\n",captureStateString[This->device->state]); + + if(This->device->client){ + hres = IAudioClient_Stop(This->device->client); + if(FAILED(hres)){ + LeaveCriticalSection(&This->device->lock); + return hres; + } + } + + LeaveCriticalSection(&(This->device->lock)); + + TRACE("returning DS_OK\n"); + return DS_OK; +} + +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; + + TRACE( "(%p,%p,%08u,%p,%08u)\n", This, lpvAudioPtr1, dwAudioBytes1, + lpvAudioPtr2, dwAudioBytes2 ); + + if (lpvAudioPtr1 == NULL) { + WARN("invalid parameter: lpvAudioPtr1 == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (!This->device->client) { + WARN("invalid call\n"); + hres = DSERR_INVALIDCALL; + } + + TRACE("returning %08x\n", hres); + return hres; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetObjectInPath(IDirectSoundCaptureBuffer8 *iface, + REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, void **ppObject) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + + FIXME( "(%p,%s,%u,%s,%p): stub\n", This, debugstr_guid(rguidObject), + dwIndex, debugstr_guid(rguidInterface), ppObject ); + + if (!ppObject) + return DSERR_INVALIDPARAM; + + *ppObject = NULL; + return DSERR_CONTROLUNAVAIL; +} + +static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetFXStatus(IDirectSoundCaptureBuffer8 *iface, + DWORD dwFXCount, DWORD *pdwFXStatus) +{ + IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface); + + FIXME( "(%p,%u,%p): stub\n", This, dwFXCount, pdwFXStatus ); + + return DS_OK; +} + +static const IDirectSoundCaptureBuffer8Vtbl dscbvt = +{ + /* IUnknown methods */ + IDirectSoundCaptureBufferImpl_QueryInterface, + IDirectSoundCaptureBufferImpl_AddRef, + IDirectSoundCaptureBufferImpl_Release, + + /* IDirectSoundCaptureBuffer methods */ + IDirectSoundCaptureBufferImpl_GetCaps, + IDirectSoundCaptureBufferImpl_GetCurrentPosition, + IDirectSoundCaptureBufferImpl_GetFormat, + IDirectSoundCaptureBufferImpl_GetStatus, + IDirectSoundCaptureBufferImpl_Initialize, + IDirectSoundCaptureBufferImpl_Lock, + IDirectSoundCaptureBufferImpl_Start, + IDirectSoundCaptureBufferImpl_Stop, + IDirectSoundCaptureBufferImpl_Unlock, + + /* IDirectSoundCaptureBuffer methods */ + IDirectSoundCaptureBufferImpl_GetObjectInPath, + IDirectSoundCaptureBufferImpl_GetFXStatus +}; + +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) { + WARN("invalid parameter: ppobj == NULL\n"); + return DSERR_INVALIDPARAM; + } + + *ppobj = NULL; + + if (!device) { + WARN("not initialized\n"); + return DSERR_UNINITIALIZED; + } + + if (lpcDSCBufferDesc == NULL) { + WARN("invalid parameter: lpcDSCBufferDesc == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if ( ((lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC)) && + (lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC1))) || + (lpcDSCBufferDesc->dwBufferBytes == 0) || + (lpcDSCBufferDesc->lpwfxFormat == NULL) ) { /* FIXME: DSERR_BADFORMAT ? */ + WARN("invalid lpcDSCBufferDesc\n"); + return DSERR_INVALIDPARAM; + } + + wfex = lpcDSCBufferDesc->lpwfxFormat; + + 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); + + device->pwfx = DSOUND_CopyFormat(wfex); + if ( device->pwfx == NULL ) + return DSERR_OUTOFMEMORY; + + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + sizeof(IDirectSoundCaptureBufferImpl)); + + if ( This == NULL ) { + WARN("out of memory\n"); + return DSERR_OUTOFMEMORY; + } else { + HRESULT err = DS_OK; + LPBYTE newbuf; + DWORD buflen; + + This->numIfaces = 0; + This->ref = 0; + This->refn = 0; + This->device = device; + This->device->capture_buffer = This; + This->nrofnotifies = 0; + + This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + lpcDSCBufferDesc->dwSize); + if (This->pdscbd) + CopyMemory(This->pdscbd, lpcDSCBufferDesc, lpcDSCBufferDesc->dwSize); + else { + WARN("no memory\n"); + This->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + return DSERR_OUTOFMEMORY; + } + + This->IDirectSoundCaptureBuffer8_iface.lpVtbl = &dscbvt; + This->IDirectSoundNotify_iface.lpVtbl = &dscnvt; + + 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; + } + + 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 + */ +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 hr; + GUID devGUID; + 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; + + 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; + } + + hr = get_mmdevice(eCapture, &devGUID, &mmdevice); + if(FAILED(hr)) + return hr; + + 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; + } + } + + hr = DirectSoundCaptureDevice_Create(&device); + if (hr != DS_OK) { + WARN("DirectSoundCaptureDevice_Create failed\n"); + LeaveCriticalSection(&DSOUND_capturers_lock); + return hr; + } + + 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; + } + + 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; + + 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; + } + *ppv = NULL; + + 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; } - /* Get dsound configuration */ - setup_dsound_options(); + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} - hr = IDirectSoundCaptureImpl_Create(&pDSC); - if (hr == DS_OK) { - IDirectSoundCapture_AddRef(pDSC); - *ppDSC = pDSC; - } else { - WARN("IDirectSoundCaptureImpl_Create failed\n"); - *ppDSC = 0; +static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface) +{ + IDirectSoundCaptureImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + 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; } + 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("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; } -HRESULT DSOUND_CaptureCreate8( - REFIID riid, - LPDIRECTSOUNDCAPTURE8 *ppDSC8) +static HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(IDirectSoundCapture *iface, + LPDSCCAPS lpDSCCaps) { - LPDIRECTSOUNDCAPTURE8 pDSC8; - HRESULT hr; - TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSC8); + IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface); - if (!IsEqualIID(riid, &IID_IUnknown) && - !IsEqualIID(riid, &IID_IDirectSoundCapture8)) { - *ppDSC8 = 0; - return E_NOINTERFACE; + 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; +} + +static HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(IDirectSoundCapture *iface, + LPCGUID lpcGUID) +{ + IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(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 +}; + +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; } - /* 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; - } + 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; } +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] * @@ -168,13 +1334,12 @@ HRESULT DSOUND_CaptureCreate8( * * DSERR_ALLOCATED is returned for sound devices that do not support full duplex. */ -HRESULT WINAPI DirectSoundCaptureCreate( - LPCGUID lpcGUID, - LPDIRECTSOUNDCAPTURE *ppDSC, - LPUNKNOWN pUnkOuter) +HRESULT WINAPI DirectSoundCaptureCreate(LPCGUID lpcGUID, IDirectSoundCapture **ppDSC, + IUnknown *pUnkOuter) { HRESULT hr; - LPDIRECTSOUNDCAPTURE pDSC; + IDirectSoundCapture *pDSC; + TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC, pUnkOuter); if (ppDSC == NULL) { @@ -184,11 +1349,10 @@ HRESULT WINAPI DirectSoundCaptureCreate( if (pUnkOuter) { WARN("invalid parameter: pUnkOuter != NULL\n"); - *ppDSC = NULL; return DSERR_NOAGGREGATION; } - hr = DSOUND_CaptureCreate(&IID_IDirectSoundCapture, &pDSC); + hr = DSOUND_CaptureCreate(&IID_IDirectSoundCapture, (void**)&pDSC); if (hr == DS_OK) { hr = IDirectSoundCapture_Initialize(pDSC, lpcGUID); if (hr != DS_OK) { @@ -244,7 +1408,7 @@ HRESULT WINAPI DirectSoundCaptureCreate8( return DSERR_NOAGGREGATION; } - hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &pDSC8); + hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, (void**)&pDSC8); if (hr == DS_OK) { hr = IDirectSoundCapture_Initialize(pDSC8, lpcGUID); if (hr != DS_OK) { @@ -257,1406 +1421,3 @@ HRESULT WINAPI DirectSoundCaptureCreate8( return 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) -{ - 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; - } - - 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; - } - } - } - } - } - - 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; - } - } - - return DS_OK; -} - -/*************************************************************************** - * 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) -{ - unsigned devs, wid; - DSDRIVERDESC desc; - GUID guid; - int err; - WCHAR wDesc[MAXPNAMELEN]; - WCHAR wName[MAXPNAMELEN]; - - TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext ); - - if (lpDSEnumCallback == NULL) { - WARN("invalid parameter: lpDSEnumCallback == 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; - } - } - } - } - } - - 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; - } - } - - return DS_OK; -} - -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 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"); -} - -/*************************************************************************** - * IDirectSoundCaptureImpl - */ -static HRESULT WINAPI -IDirectSoundCaptureImpl_QueryInterface( - LPDIRECTSOUNDCAPTURE iface, - REFIID riid, - LPVOID* ppobj ) -{ - IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface; - TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj ); - - if (ppobj == NULL) { - WARN("invalid parameter\n"); - return E_INVALIDARG; - } - - *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; - } - - WARN("unsupported riid: %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static ULONG WINAPI -IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface ) -{ - IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} - -static ULONG WINAPI -IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface ) -{ - IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface; - ULONG ref = InterlockedDecrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref + 1); - - if (!ref) { - if (This->device) - DirectSoundCaptureDevice_Release(This->device); - - HeapFree( GetProcessHeap(), 0, This ); - TRACE("(%p) released\n", This); - } - return ref; -} - -HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer( - LPDIRECTSOUNDCAPTURE iface, - LPCDSCBUFFERDESC lpcDSCBufferDesc, - LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer, - LPUNKNOWN pUnk ) -{ - HRESULT hr; - IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface; - - TRACE( "(%p,%p,%p,%p)\n",iface,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk); - - 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;idscb->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 (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - return DSERR_INVALIDPARAM; - } - - lpDSCBCaps->dwSize = sizeof(DSCBCAPS); - lpDSCBCaps->dwFlags = This->flags; - lpDSCBCaps->dwBufferBytes = This->pdscbd->dwBufferBytes; - lpDSCBCaps->dwReserved = 0; - - TRACE("returning DS_OK\n"); - return DS_OK; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_GetCurrentPosition( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - LPDWORD lpdwCapturePosition, - LPDWORD lpdwReadPosition ) -{ - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - HRESULT hres = DS_OK; - TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition ); - - if (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - 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); - 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; - LeaveCriticalSection(&This->device->lock); - - } else { - WARN("no driver\n"); - hres = DSERR_NODRIVER; - } - - TRACE("cappos=%d readpos=%d\n", (lpdwCapturePosition?*lpdwCapturePosition:-1), (lpdwReadPosition?*lpdwReadPosition:-1)); - TRACE("returning %08x\n", hres); - return hres; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_GetFormat( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - LPWAVEFORMATEX lpwfxFormat, - DWORD dwSizeAllocated, - LPDWORD lpdwSizeWritten ) -{ - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - HRESULT hres = DS_OK; - TRACE( "(%p,%p,0x%08x,%p)\n", This, lpwfxFormat, dwSizeAllocated, - lpdwSizeWritten ); - - if (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (dwSizeAllocated > (sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize)) - dwSizeAllocated = sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize; - - if (lpwfxFormat) { /* NULL is valid (just want size) */ - CopyMemory(lpwfxFormat, This->device->pwfx, dwSizeAllocated); - if (lpdwSizeWritten) - *lpdwSizeWritten = dwSizeAllocated; - } else { - if (lpdwSizeWritten) - *lpdwSizeWritten = sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize; - else { - TRACE("invalid parameter: lpdwSizeWritten = NULL\n"); - hres = DSERR_INVALIDPARAM; - } - } - - TRACE("returning %08x\n", hres); - return hres; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_GetStatus( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - LPDWORD lpdwStatus ) -{ - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - TRACE( "(%p, %p), thread is %04x\n", This, lpdwStatus, GetCurrentThreadId() ); - - if (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (lpdwStatus == NULL) { - WARN("invalid parameter: lpdwStatus == NULL\n"); - return DSERR_INVALIDPARAM; - } - - *lpdwStatus = 0; - EnterCriticalSection(&(This->device->lock)); - - TRACE("old This->device->state=%s, old lpdwStatus=%08x\n", - captureStateString[This->device->state],*lpdwStatus); - if ((This->device->state == STATE_STARTING) || - (This->device->state == STATE_CAPTURING)) { - *lpdwStatus |= DSCBSTATUS_CAPTURING; - if (This->flags & DSCBSTART_LOOPING) - *lpdwStatus |= DSCBSTATUS_LOOPING; - } - TRACE("new This->device->state=%s, new lpdwStatus=%08x\n", - captureStateString[This->device->state],*lpdwStatus); - LeaveCriticalSection(&(This->device->lock)); - - TRACE("status=%x\n", *lpdwStatus); - TRACE("returning DS_OK\n"); - return DS_OK; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_Initialize( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - LPDIRECTSOUNDCAPTURE lpDSC, - LPCDSCBUFFERDESC lpcDSCBDesc ) -{ - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)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 ) -{ - 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() ); - - if (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (lplpvAudioPtr1 == NULL) { - WARN("invalid parameter: lplpvAudioPtr1 == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (lpdwAudioBytes1 == NULL) { - WARN("invalid parameter: lpdwAudioBytes1 == NULL\n"); - return DSERR_INVALIDPARAM; - } - - 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) { - *lplpvAudioPtr1 = This->device->buffer + dwReadCusor; - if ( (dwReadCusor + dwReadBytes) > This->device->buflen) { - *lpdwAudioBytes1 = This->device->buflen - dwReadCusor; - if (lplpvAudioPtr2) - *lplpvAudioPtr2 = This->device->buffer; - if (lpdwAudioBytes2) - *lpdwAudioBytes2 = dwReadBytes - *lpdwAudioBytes1; - } else { - *lpdwAudioBytes1 = dwReadBytes; - if (lplpvAudioPtr2) - *lplpvAudioPtr2 = 0; - if (lpdwAudioBytes2) - *lpdwAudioBytes2 = 0; - } - } else { - TRACE("invalid call\n"); - hres = DSERR_INVALIDCALL; /* DSERR_NODRIVER ? */ - } - - LeaveCriticalSection(&(This->device->lock)); - - TRACE("returning %08x\n", hres); - return hres; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_Start( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - DWORD dwFlags ) -{ - HRESULT hres = DS_OK; - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - TRACE( "(%p,0x%08x)\n", This, dwFlags ); - - if (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if ( (This->device->driver == 0) && (This->device->hwi == 0) ) { - 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; - TRACE("new This->device->state=%s\n",captureStateString[This->device->state]); - - 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 (hres != DS_OK) { - WARN("calling waveInClose because of error\n"); - waveInClose(device->hwi); - device->hwi = 0; - } - } else { - WARN("no driver\n"); - hres = DSERR_NODRIVER; - } - - TRACE("returning %08x\n", hres); - return hres; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) -{ - HRESULT hres = DS_OK; - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - TRACE( "(%p)\n", This ); - - if (This->device == NULL) { - WARN("invalid parameter: This->device == NULL\n"); - return DSERR_INVALIDPARAM; - } - - EnterCriticalSection(&(This->device->lock)); - - TRACE("old This->device->state=%s\n",captureStateString[This->device->state]); - if (This->device->state == STATE_CAPTURING) - This->device->state = STATE_STOPPING; - else if (This->device->state == STATE_STARTING) - 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; - } - - TRACE("returning %08x\n", hres); - return hres; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_Unlock( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - LPVOID lpvAudioPtr1, - DWORD dwAudioBytes1, - LPVOID lpvAudioPtr2, - DWORD dwAudioBytes2 ) -{ - HRESULT hres = DS_OK; - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - TRACE( "(%p,%p,%08u,%p,%08u)\n", This, lpvAudioPtr1, dwAudioBytes1, - lpvAudioPtr2, dwAudioBytes2 ); - - if (lpvAudioPtr1 == NULL) { - WARN("invalid parameter: lpvAudioPtr1 == NULL\n"); - 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) { - WARN("invalid call\n"); - hres = DSERR_INVALIDCALL; - } - - TRACE("returning %08x\n", hres); - return hres; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_GetObjectInPath( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - REFGUID rguidObject, - DWORD dwIndex, - REFGUID rguidInterface, - LPVOID* ppObject ) -{ - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - - FIXME( "(%p,%s,%u,%s,%p): stub\n", This, debugstr_guid(rguidObject), - dwIndex, debugstr_guid(rguidInterface), ppObject ); - - return DS_OK; -} - -static HRESULT WINAPI -IDirectSoundCaptureBufferImpl_GetFXStatus( - LPDIRECTSOUNDCAPTUREBUFFER8 iface, - DWORD dwFXCount, - LPDWORD pdwFXStatus ) -{ - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface; - - FIXME( "(%p,%u,%p): stub\n", This, dwFXCount, pdwFXStatus ); - - return DS_OK; -} - -static const IDirectSoundCaptureBuffer8Vtbl dscbvt = -{ - /* IUnknown methods */ - IDirectSoundCaptureBufferImpl_QueryInterface, - IDirectSoundCaptureBufferImpl_AddRef, - IDirectSoundCaptureBufferImpl_Release, - - /* IDirectSoundCaptureBuffer methods */ - IDirectSoundCaptureBufferImpl_GetCaps, - IDirectSoundCaptureBufferImpl_GetCurrentPosition, - IDirectSoundCaptureBufferImpl_GetFormat, - IDirectSoundCaptureBufferImpl_GetStatus, - IDirectSoundCaptureBufferImpl_Initialize, - IDirectSoundCaptureBufferImpl_Lock, - IDirectSoundCaptureBufferImpl_Start, - IDirectSoundCaptureBufferImpl_Stop, - IDirectSoundCaptureBufferImpl_Unlock, - - /* IDirectSoundCaptureBuffer methods */ - IDirectSoundCaptureBufferImpl_GetObjectInPath, - IDirectSoundCaptureBufferImpl_GetFXStatus -}; - -HRESULT IDirectSoundCaptureBufferImpl_Create( - DirectSoundCaptureDevice *device, - IDirectSoundCaptureBufferImpl ** ppobj, - LPCDSCBUFFERDESC lpcDSCBufferDesc) -{ - LPWAVEFORMATEX wfex; - TRACE( "(%p,%p,%p)\n", device, ppobj, lpcDSCBufferDesc); - - if (ppobj == NULL) { - WARN("invalid parameter: ppobj == NULL\n"); - return DSERR_INVALIDPARAM; - } - - 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) ) { - 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 ? */ - } - - *ppobj = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, - sizeof(IDirectSoundCaptureBufferImpl)); - - if ( *ppobj == NULL ) { - WARN("out of memory\n"); - *ppobj = NULL; - return DSERR_OUTOFMEMORY; - } else { - HRESULT err = DS_OK; - LPBYTE newbuf; - DWORD buflen; - IDirectSoundCaptureBufferImpl *This = *ppobj; - - This->ref = 1; - This->device = device; - This->device->capture_buffer = This; - This->notify = NULL; - This->nrofnotifies = 0; - This->hwnotify = NULL; - - This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, - lpcDSCBufferDesc->dwSize); - if (This->pdscbd) - CopyMemory(This->pdscbd, lpcDSCBufferDesc, lpcDSCBufferDesc->dwSize); - else { - 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; - } - - 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; - } - - 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; - } - } - } - - TRACE("returning DS_OK\n"); - return DS_OK; -} - -/******************************************************************************* - * DirectSoundCaptureDevice - */ -HRESULT DirectSoundCaptureDevice_Initialize( - DirectSoundCaptureDevice ** ppDevice, - LPCGUID lpcGUID) -{ - HRESULT err = DSERR_INVALIDPARAM; - unsigned wid, widn; - BOOLEAN found = FALSE; - GUID devGUID; - DirectSoundCaptureDevice *device = *ppDevice; - TRACE("(%p, %s)\n", ppDevice, debugstr_guid(lpcGUID)); - - /* Default device? */ - if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) ) - lpcGUID = &DSDEVID_DefaultCapture; - - 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; - } - - /* enumerate WINMM audio devices and find the one we want */ - for (wid=0; widguid = 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; - } - } - err = DS_OK; - - /* 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; - } - } - } - - return err; -} - -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; -} - -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"); - if (device->capture_buffer) - IDirectSoundCaptureBufferImpl_Release( - (LPDIRECTSOUNDCAPTUREBUFFER8) device->capture_buffer); - - if (device->driver) { - IDsCaptureDriver_Close(device->driver); - IDsCaptureDriver_Release(device->driver); - } - - 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); - } - return ref; -} diff --git a/reactos/dll/directx/dsound/dsound.c b/reactos/dll/directx/dsound/dsound.c index 40d3132a516..3de24e57eb6 100644 --- a/reactos/dll/directx/dsound/dsound.c +++ b/reactos/dll/directx/dsound/dsound.c @@ -20,104 +20,42 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -//#include -#include +#include +#include +//#include #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H - +#define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION -#include -#include +//#include "windef.h" +//#include "winbase.h" //#include "winuser.h" -#include #include -//#include "mmddk.h" +#include "mmddk.h" //#include "wingdi.h" //#include "mmreg.h" //#include "ks.h" -#include +//#include "ksmedia.h" #include #include -#include #include "dsound_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dsound); -/***************************************************************************** - * IDirectSound COM components - */ -struct IDirectSound_IUnknown { - const IUnknownVtbl *lpVtbl; - LONG ref; - LPDIRECTSOUND8 pds; -}; +typedef struct IDirectSoundImpl { + IUnknown IUnknown_inner; + IDirectSound8 IDirectSound8_iface; + IUnknown *outer_unk; /* internal */ + LONG ref, refds, numIfaces; + DirectSoundDevice *device; + BOOL has_ds8; +} IDirectSoundImpl; -static HRESULT IDirectSound_IUnknown_Create(LPDIRECTSOUND8 pds, LPUNKNOWN * ppunk); - -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 +static const char * dumpCooperativeLevel(DWORD level) { - 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 char unknown[32]; #define LE(x) case x: return #x switch (level) { LE(DSSCL_NORMAL); @@ -126,8 +64,7 @@ const char * dumpCooperativeLevel(DWORD level) 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) { @@ -184,844 +121,367 @@ static void _dump_DSBCAPS(DWORD xmask) { TRACE("%s ",flags[i].name); } -/******************************************************************************* - * IDirectSoundImpl_DirectSound - */ -static HRESULT DSOUND_QueryInterface( - LPDIRECTSOUND8 iface, - REFIID riid, - LPVOID * ppobj) +static void directsound_destroy(IDirectSoundImpl *This) { - IDirectSoundImpl *This = (IDirectSoundImpl *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + if (This->device) + DirectSoundDevice_Release(This->device); + HeapFree(GetProcessHeap(),0,This); + TRACE("(%p) released\n", This); +} - if (ppobj == NULL) { +/******************************************************************************* + * IUnknown Implementation for DirectSound + */ +static inline IDirectSoundImpl *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, IDirectSoundImpl, IUnknown_inner); +} + +static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + IDirectSoundImpl *This = impl_from_IUnknown(iface); + + TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv); + + if (!ppv) { 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; -} - -static HRESULT DSOUND_QueryInterface8( - LPDIRECTSOUND8 iface, - REFIID riid, - LPVOID * ppobj) -{ - 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) { - 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; - } - - *ppobj = NULL; - WARN("Unknown IID %s\n",debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static ULONG IDirectSoundImpl_AddRef( - LPDIRECTSOUND8 iface) -{ - IDirectSoundImpl *This = (IDirectSoundImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return 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); - - 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) -{ - 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; - } - - pDS->ref = 0; - pDS->device = NULL; - - *ppDS = (LPDIRECTSOUND8)pDS; - - 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 = -{ - IDirectSound_IUnknown_QueryInterface, - IDirectSound_IUnknown_AddRef, - IDirectSound_IUnknown_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 - */ -static HRESULT WINAPI IDirectSound_IDirectSound_QueryInterface( - LPDIRECTSOUND iface, - REFIID riid, - LPVOID * ppobj) -{ - IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return DSOUND_QueryInterface(This->pds, riid, ppobj); -} - -static ULONG WINAPI IDirectSound_IDirectSound_AddRef( - LPDIRECTSOUND iface) -{ - IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} - -static ULONG WINAPI IDirectSound_IDirectSound_Release( - LPDIRECTSOUND 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; -} - -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); -} - -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); -} - -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); -} - -static HRESULT WINAPI IDirectSound_IDirectSound_SetCooperativeLevel( - LPDIRECTSOUND iface, - HWND hwnd, - DWORD level) -{ - IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface; - TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level)); - return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level); -} - -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); -} - -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); -} - -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); -} - -static HRESULT WINAPI IDirectSound_IDirectSound_Initialize( - LPDIRECTSOUND iface, - LPCGUID lpcGuid) -{ - IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface; - TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid)); - return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid); -} - -static const IDirectSoundVtbl DirectSound_DirectSound_Vtbl = -{ - 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 -}; - -static HRESULT IDirectSound_IDirectSound_Create( - LPDIRECTSOUND8 pds, - LPDIRECTSOUND * ppds) -{ - IDirectSound_IDirectSound * pdsds; - TRACE("(%p,%p)\n",pds,ppds); - - if (ppds == NULL) { - ERR("invalid parameter: ppds == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (pds == NULL) { - ERR("invalid parameter: pds == NULL\n"); - *ppds = NULL; - 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"); - 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 = &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) -{ - IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return DSOUND_QueryInterface8(This->pds, riid, ppobj); -} - -static ULONG WINAPI IDirectSound8_IDirectSound_AddRef( - LPDIRECTSOUND iface) -{ - IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} - -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; -} - -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); -} - -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); -} - -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); -} - -static HRESULT WINAPI IDirectSound8_IDirectSound_SetCooperativeLevel( - LPDIRECTSOUND iface, - HWND hwnd, - DWORD level) -{ - IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface; - TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level)); - return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level); -} - -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); -} - -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); -} - -static HRESULT WINAPI IDirectSound8_IDirectSound_Initialize( - LPDIRECTSOUND iface, - LPCGUID lpcGuid) -{ - IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface; - TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid)); - return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid); -} - -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 -}; - -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 (pds == NULL) { - ERR("invalid parameter: pds == NULL\n"); - *ppds = NULL; - 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; - - return DS_OK; -} - -/******************************************************************************* - * IDirectSound8_IDirectSound8 - */ -static HRESULT WINAPI IDirectSound8_IDirectSound8_QueryInterface( - LPDIRECTSOUND8 iface, - REFIID riid, - LPVOID * ppobj) -{ - IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return DSOUND_QueryInterface8(This->pds, riid, ppobj); -} - -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; -} - -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); - } - 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); -} - -static HRESULT WINAPI IDirectSound8_IDirectSound8_SetCooperativeLevel( - LPDIRECTSOUND8 iface, - HWND hwnd, - DWORD level) -{ - IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface; - TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level)); - return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level); -} - -static HRESULT WINAPI IDirectSound8_IDirectSound8_Compact( - LPDIRECTSOUND8 iface) -{ - IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface; - TRACE("(%p)\n", This); - return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device); -} - -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); -} - -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); -} - -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); -} - -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); -} - -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 HRESULT IDirectSound8_IDirectSound8_Create( - LPDIRECTSOUND8 pds, - LPDIRECTSOUND8 * ppds) -{ - IDirectSound8_IDirectSound8 * pdsds; - TRACE("(%p,%p)\n",pds,ppds); - - if (ppds == NULL) { - ERR("invalid parameter: ppds == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (pds == NULL) { - ERR("invalid parameter: pds == NULL\n"); - *ppds = NULL; - 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_DirectSound8_Vtbl; - pdsds->ref = 0; - pdsds->pds = pds; - - IDirectSoundImpl_AddRef(pds); - *ppds = (LPDIRECTSOUND8)pdsds; - - return DS_OK; -} - -HRESULT DSOUND_Create( - REFIID riid, - LPDIRECTSOUND *ppDS) -{ - LPDIRECTSOUND8 pDS; - HRESULT hr; - TRACE("(%s, %p)\n", debugstr_guid(riid), ppDS); - - if (!IsEqualIID(riid, &IID_IUnknown) && - !IsEqualIID(riid, &IID_IDirectSound)) { - *ppDS = 0; + *ppv = NULL; + + 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; } - /* Get dsound configuration */ - setup_dsound_options(); + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} - 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; +static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface) +{ + IDirectSoundImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(ref == 1) + InterlockedIncrement(&This->numIfaces); + + return ref; +} + +static ULONG WINAPI IUnknownImpl_Release(IUnknown *iface) +{ + IDirectSoundImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if (!ref && !InterlockedDecrement(&This->numIfaces)) + directsound_destroy(This); + + return ref; +} + +static const IUnknownVtbl unk_vtbl = +{ + IUnknownImpl_QueryInterface, + IUnknownImpl_AddRef, + IUnknownImpl_Release +}; + +/******************************************************************************* + * IDirectSound and IDirectSound8 Implementation + */ +static inline IDirectSoundImpl *impl_from_IDirectSound8(IDirectSound8 *iface) +{ + return CONTAINING_RECORD(iface, IDirectSoundImpl, IDirectSound8_iface); +} + +static HRESULT WINAPI IDirectSound8Impl_QueryInterface(IDirectSound8 *iface, REFIID riid, + void **ppv) +{ + 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 IDirectSound8Impl_AddRef(IDirectSound8 *iface) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + ULONG ref = InterlockedIncrement(&This->refds); + + TRACE("(%p) refds=%d\n", This, ref); + + if(ref == 1) + InterlockedIncrement(&This->numIfaces); + + return ref; +} + +static ULONG WINAPI IDirectSound8Impl_Release(IDirectSound8 *iface) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + ULONG ref = InterlockedDecrement(&(This->refds)); + + TRACE("(%p) refds=%d\n", This, ref); + + if (!ref && !InterlockedDecrement(&This->numIfaces)) + directsound_destroy(This); + + return ref; +} + +static HRESULT WINAPI IDirectSound8Impl_CreateSoundBuffer(IDirectSound8 *iface, + const DSBUFFERDESC *dsbd, IDirectSoundBuffer **ppdsb, IUnknown *lpunk) +{ + 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 HRESULT WINAPI IDirectSound8Impl_GetCaps(IDirectSound8 *iface, DSCAPS *dscaps) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + + TRACE("(%p, %p)\n", This, dscaps); + + if (!This->device) { + WARN("not initialized\n"); + return DSERR_UNINITIALIZED; + } + if (!dscaps) { + WARN("invalid parameter: dscaps = NULL\n"); + return DSERR_INVALIDPARAM; + } + if (dscaps->dwSize < sizeof(*dscaps)) { + WARN("invalid parameter: dscaps->dwSize = %d\n", dscaps->dwSize); + 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; + + if (TRACE_ON(dsound)) { + TRACE("(flags=0x%08x:\n", dscaps->dwFlags); + _dump_DSCAPS(dscaps->dwFlags); + TRACE(")\n"); + } + + return DS_OK; +} + +static HRESULT WINAPI IDirectSound8Impl_DuplicateSoundBuffer(IDirectSound8 *iface, + IDirectSoundBuffer *psb, IDirectSoundBuffer **ppdsb) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + TRACE("(%p,%p,%p)\n", This, psb, ppdsb); + return DirectSoundDevice_DuplicateSoundBuffer(This->device, psb, ppdsb); +} + +static HRESULT WINAPI IDirectSound8Impl_SetCooperativeLevel(IDirectSound8 *iface, HWND hwnd, + DWORD level) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + DirectSoundDevice *device = This->device; + DWORD oldlevel; + HRESULT hr = S_OK; + + TRACE("(%p,%p,%s)\n", This, hwnd, dumpCooperativeLevel(level)); + + if (!device) { + 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"); + } + + 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 IDirectSound8Impl_Compact(IDirectSound8 *iface) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + + TRACE("(%p)\n", This); + + if (!This->device) { + WARN("not initialized\n"); + return DSERR_UNINITIALIZED; + } + + if (This->device->priolevel < DSSCL_PRIORITY) { + WARN("incorrect priority level\n"); + return DSERR_PRIOLEVELNEEDED; + } + return DS_OK; +} + +static HRESULT WINAPI IDirectSound8Impl_GetSpeakerConfig(IDirectSound8 *iface, DWORD *config) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + + TRACE("(%p, %p)\n", This, config); + + if (!This->device) { + WARN("not initialized\n"); + return DSERR_UNINITIALIZED; + } + if (!config) { + WARN("invalid parameter: config == NULL\n"); + return DSERR_INVALIDPARAM; + } + + WARN("not fully functional\n"); + *config = This->device->speaker_config; + return DS_OK; +} + +static HRESULT WINAPI IDirectSound8Impl_SetSpeakerConfig(IDirectSound8 *iface, DWORD config) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + + TRACE("(%p,0x%08x)\n", This, config); + + if (!This->device) { + WARN("not initialized\n"); + return DSERR_UNINITIALIZED; + } + + This->device->speaker_config = config; + WARN("not fully functional\n"); + return DS_OK; +} + +static HRESULT WINAPI IDirectSound8Impl_Initialize(IDirectSound8 *iface, const GUID *lpcGuid) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid)); + return DirectSoundDevice_Initialize(&This->device, lpcGuid); +} + +static HRESULT WINAPI IDirectSound8Impl_VerifyCertification(IDirectSound8 *iface, DWORD *certified) +{ + IDirectSoundImpl *This = impl_from_IDirectSound8(iface); + + TRACE("(%p, %p)\n", This, certified); + + if (!This->device) { + WARN("not initialized\n"); + return DSERR_UNINITIALIZED; + } + + if (This->device->drvcaps.dwFlags & DSCAPS_CERTIFIED) + *certified = DS_CERTIFIED; + else + *certified = DS_UNCERTIFIED; + + return DS_OK; +} + +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 +}; + +HRESULT IDirectSoundImpl_Create(IUnknown *outer_unk, REFIID riid, void **ppv, BOOL has_ds8) +{ + IDirectSoundImpl *obj; + HRESULT hr; + + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); + + *ppv = NULL; + obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj)); + if (!obj) { + WARN("out of memory\n"); + return DSERR_OUTOFMEMORY; + } + + 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; + + hr = IUnknown_QueryInterface(&obj->IUnknown_inner, riid, ppv); + IUnknown_Release(&obj->IUnknown_inner); + + return hr; +} + +HRESULT DSOUND_Create(REFIID riid, void **ppv) +{ + return IDirectSoundImpl_Create(NULL, riid, ppv, FALSE); +} + +HRESULT DSOUND_Create8(REFIID riid, void **ppv) +{ + return IDirectSoundImpl_Create(NULL, riid, ppv, TRUE); +} + /******************************************************************************* * DirectSoundCreate (DSOUND.1) * @@ -1058,7 +518,7 @@ HRESULT WINAPI DirectSoundCreate( 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) { @@ -1075,41 +535,6 @@ HRESULT WINAPI DirectSoundCreate( 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) * @@ -1146,7 +571,7 @@ HRESULT WINAPI DirectSoundCreate8( 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) { @@ -1181,7 +606,7 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice) 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); @@ -1205,24 +630,24 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice) 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"); @@ -1248,46 +673,41 @@ ULONG DirectSoundDevice_Release(DirectSoundDevice * device) 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;inrofbuffers;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); @@ -1297,67 +717,58 @@ ULONG DirectSoundDevice_Release(DirectSoundDevice * device) 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; + + hr = IAudioClient_IsFormatSupported(client, AUDCLNT_SHAREMODE_SHARED, &fmt, &junk); + if(SUCCEEDED(hr)) + CoTaskMemFree(junk); + + return hr == S_OK; +} + +UINT DSOUND_create_timer(LPTIMECALLBACK cb, DWORD_PTR user) +{ + UINT triggertime = DS_TIME_DEL, res = DS_TIME_RES, id; + TIMECAPS time; + + 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"); } - - if (lpDSCaps == NULL) { - WARN("invalid parameter: lpDSCaps = NULL\n"); - return DSERR_INVALIDPARAM; - } - - /* check if there is enough room */ - if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) { - WARN("invalid parameter: lpDSCaps->dwSize = %d\n", lpDSCaps->dwSize); - return DSERR_INVALIDPARAM; - } - - 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% */ - - return DS_OK; + 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) { @@ -1369,140 +780,108 @@ HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcG 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; - } + hr = get_mmdevice(eRender, &devGUID, &mmdevice); + if(FAILED(hr)) + return hr; - for (wod=0; wodguid)) { - 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; - device->guid = devGUID; - device->driver = NULL; + 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->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; + 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); - 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"); - } + *ppDevice = device; + list_add_tail(&DSOUND_renderers, &device->entry); + + LeaveCriticalSection(&DSOUND_renderers_lock); return hr; } @@ -1548,6 +927,12 @@ HRESULT DirectSoundDevice_CreateSoundBuffer( 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 " @@ -1560,17 +945,13 @@ HRESULT DirectSoundDevice_CreateSoundBuffer( 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; @@ -1583,26 +964,25 @@ HRESULT DirectSoundDevice_CreateSoundBuffer( } 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)); @@ -1634,15 +1014,10 @@ HRESULT DirectSoundDevice_CreateSoundBuffer( } 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; @@ -1673,127 +1048,22 @@ HRESULT DirectSoundDevice_DuplicateSoundBuffer( } /* 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); - } - } + hres = IDirectSoundBufferImpl_Duplicate(device, &dsb, (IDirectSoundBufferImpl*)psb); + if (hres == DS_OK) + *ppdsb = (IDirectSoundBuffer*)&dsb->IDirectSoundBuffer8_iface; + else + WARN("IDirectSoundBufferImpl_Duplicate failed\n"); 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; - else - *pdwCertified = DS_UNCERTIFIED; - - return DS_OK; -} - /* * Add secondary buffer to buffer list. * Gets exclusive access to buffer for writing. @@ -1833,35 +1103,29 @@ HRESULT DirectSoundDevice_AddBuffer( * 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; } diff --git a/reactos/dll/directx/dsound/dsound_classes.idl b/reactos/dll/directx/dsound/dsound_classes.idl new file mode 100644 index 00000000000..c47db2138d4 --- /dev/null +++ b/reactos/dll/directx/dsound/dsound_classes.idl @@ -0,0 +1,61 @@ +/* + * 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; } diff --git a/reactos/dll/directx/dsound/dsound_classes.rgs b/reactos/dll/directx/dsound/dsound_classes.rgs new file mode 100644 index 00000000000..66301b68b22 --- /dev/null +++ b/reactos/dll/directx/dsound/dsound_classes.rgs @@ -0,0 +1,33 @@ +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' } + } + } +} diff --git a/reactos/dll/directx/dsound/dsound_convert.c b/reactos/dll/directx/dsound/dsound_convert.c index 03f5fc45e1d..5617a746879 100644 --- a/reactos/dll/directx/dsound/dsound_convert.c +++ b/reactos/dll/directx/dsound/dsound_convert.c @@ -1,6 +1,7 @@ /* 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 @@ -36,6 +37,7 @@ #include #include +#include #define WIN32_NO_STATUS #define _INC_WINDOWS @@ -49,7 +51,6 @@ #include #include #include -#include #include "dsound_private.h" WINE_DEFAULT_DEBUG_CHANNEL(dsound); @@ -62,378 +63,205 @@ 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; +const bitsgetfunc getbpp[5] = {get8, get16, get24, get32, getieee32}; - dst = (char *)dst + dst_stride; - src_advance(&src, src_stride, &count, &freqAcc, adj); - } +float get_mono(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel) +{ + 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_24 (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) - { - 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); - } + if(value <= -1.f) + return 0; + if(value >= 1.f * 0x7f / 0x80) + return 0xFF; + return lrintf((value + 1.f) * 0x80); } -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 SHORT f_to_16(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 0x8000; + if(value >= 1.f * 0x7FFF / 0x8000) + return 0x7FFF; + return le16(lrintf(value * 0x8000)); } -static void convert_24_to_8 (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) - { - 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 0x80000000; + if(value >= 1.f * 0x7FFFFF / 0x800000) + return 0x7FFFFF00; + return lrintf(value * 0x80000000U); } -static void convert_24_to_16 (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) - { - 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 * 0x7FFFFFFF / 0x80000000U) /* this rounds to 1.f */ + return 0x7FFFFFFF; + return le32(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) +void putieee32(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, 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); - } + BYTE *buf = (BYTE *)dsb->device->tmp_buffer; + float *fbuf = (float*)(buf + pos + sizeof(float) * channel); + *fbuf = value; } -static void convert_24_to_32 (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) - { - 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); - } + dsb->put_aux(dsb, pos, 0, value); + dsb->put_aux(dsb, pos, 1, 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 mixieee32(float *src, float *dst, unsigned samples) { - 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); - } + TRACE("%p - %p %d\n", src, dst, samples); + while (samples--) + *(dst++) += *(src++); } -static void convert_32_to_16 (const void *src, void *dst, UINT src_stride, - UINT dst_stride, INT count, UINT freqAcc, UINT adj) -{ - 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); - } -} - -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) +static void norm8(float *src, unsigned char *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); + { + *dst = f_to_8(*src); + ++dst; + ++src; + } } -static void mix16(SHORT *src, INT *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 += le16(*src); - ++dst; ++src; + *dst = f_to_16(*src); + ++dst; + ++src; } } -static void mix24(BYTE *src, INT *dst, unsigned len) +static void norm24(float *src, BYTE *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; + 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 mix32(INT *src, LONGLONG *dst, unsigned len) +static void norm32(float *src, INT *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) -{ - TRACE("%p - %p %d\n", src, dst, len); while (len--) { - *dst = (*src) + 0x80; - if (*src < -0x80) - *dst = 0; - else if (*src > 0x7f) - *dst = 0xff; + *dst = f_to_32(*src); ++dst; ++src; } } -static void norm16(INT *src, SHORT *dst, unsigned len) +static void normieee32(float *src, float *dst, unsigned len) { TRACE("%p - %p %d\n", src, dst, len); - len /= 2; + len /= 4; while (len--) { - *dst = le16(*src); - if (*src <= -0x8000) - *dst = le16(0x8000); - else if (*src > 0x7fff) - *dst = le16(0x7fff); - ++dst; - ++src; - } -} - -static void norm24(INT *src, BYTE *dst, unsigned len) -{ - TRACE("%p - %p %d\n", src, dst, len); - len /= 3; - 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; - } + if(*src > 1) + *dst = 1; + else if(*src < -1) + *dst = -1; else - { - dst[0] = *src; - dst[1] = *src >> 8; - dst[2] = *src >> 16; - } + *dst = *src; ++dst; ++src; } } -static void norm32(LONGLONG *src, INT *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); - ++dst; - ++src; - } -} - -const normfunc normfunctions[4] = { +const normfunc normfunctions[5] = { (normfunc)norm8, (normfunc)norm16, (normfunc)norm24, (normfunc)norm32, + (normfunc)normieee32 }; diff --git a/reactos/dll/directx/dsound/dsound_main.c b/reactos/dll/directx/dsound/dsound_main.c index 4958966b354..a4e5e7125bb 100644 --- a/reactos/dll/directx/dsound/dsound_main.c +++ b/reactos/dll/directx/dsound/dsound_main.c @@ -53,56 +53,51 @@ #include #include //#include "ks.h" +#include +//#include "rpc.h" +//#include "rpcndr.h" +//#include "unknwn.h" +//#include "oleidl.h" +//#include "shobjidl.h" + #include //#include "ksmedia.h" -#include +//#include "propkey.h" +#include #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 @@ -151,62 +146,18 @@ void setup_dsound_options(void) /* 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) @@ -222,6 +173,63 @@ 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] * @@ -244,38 +252,76 @@ static const char * get_device_id(LPCGUID pGuid) */ 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; + + 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 ( pGuidDest == NULL ) { - WARN("invalid parameter: pGuidDest == NULL\n"); - return DSERR_INVALIDPARAM; + if(role != (ERole)-1 && flow != (EDataFlow)-1){ + IMMDevice *device; + + 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; } - 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 ( 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; - } + 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] @@ -294,46 +340,198 @@ HRESULT WINAPI DirectSoundEnumerateA( 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; } /*************************************************************************** @@ -353,55 +551,84 @@ HRESULT WINAPI DirectSoundEnumerateW( 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; } /******************************************************************************* @@ -411,16 +638,20 @@ HRESULT WINAPI DirectSoundEnumerateW( typedef HRESULT (*FnCreateInstance)(REFIID riid, LPVOID *ppobj); typedef struct { - const IClassFactoryVtbl *lpVtbl; - LONG ref; + IClassFactory IClassFactory_iface; REFCLSID rclsid; FnCreateInstance pfnCreateInstance; } IClassFactoryImpl; -static HRESULT WINAPI -DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj) +static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); +} + +static HRESULT WINAPI +DSCF_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj) +{ + IClassFactoryImpl *This = impl_from_IClassFactory(iface); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); if (ppobj == NULL) return E_POINTER; @@ -428,7 +659,7 @@ DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj) IsEqualIID(riid, &IID_IClassFactory)) { *ppobj = iface; - IUnknown_AddRef(iface); + IClassFactory_AddRef(iface); return S_OK; } *ppobj = NULL; @@ -437,19 +668,13 @@ DSCF_QueryInterface(LPCLASSFACTORY iface, REFIID riid, LPVOID *ppobj) 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( @@ -458,7 +683,7 @@ 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) @@ -474,7 +699,7 @@ static HRESULT WINAPI DSCF_CreateInstance( 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; } @@ -488,13 +713,13 @@ static const IClassFactoryVtbl DSCF_Vtbl = { }; 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 } }; /******************************************************************************* @@ -534,7 +759,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 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; } @@ -552,12 +777,11 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) * 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; } @@ -572,24 +796,20 @@ HRESULT WINAPI DllCanUnloadNow(void) */ 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"); @@ -597,3 +817,19 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) } return TRUE; } + +/*********************************************************************** + * DllRegisterServer (DSOUND.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources( instance ); +} + +/*********************************************************************** + * DllUnregisterServer (DSOUND.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources( instance ); +} diff --git a/reactos/dll/directx/dsound/dsound_private.h b/reactos/dll/directx/dsound/dsound_private.h index 9947b85d032..1a3900c4870 100644 --- a/reactos/dll/directx/dsound/dsound_private.h +++ b/reactos/dll/directx/dsound/dsound_private.h @@ -23,58 +23,41 @@ #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 +#include "wingdi.h" +#include "mmdeviceapi.h" +#include "audioclient.h" +#include "mmsystem.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 +#include "wine/list.h" -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; +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 @@ -84,37 +67,38 @@ struct DirectSoundDevice 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 */ @@ -125,356 +109,135 @@ typedef struct BufferMemory 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); + 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; -/***************************************************************************** - * 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; -}; - -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 @@ -482,14 +245,22 @@ HRESULT WINAPI IDirectSoundCaptureImpl_Initialize( #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 DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS]; -extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]; +extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN; +extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS] DECLSPEC_HIDDEN; -extern DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS]; -extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS]; +extern WCHAR wine_vxd_drv[] DECLSPEC_HIDDEN; -HRESULT mmErr(UINT err); -void setup_dsound_options(void); -const char * dumpCooperativeLevel(DWORD level); +void setup_dsound_options(void) DECLSPEC_HIDDEN; + +HRESULT get_mmdevice(EDataFlow flow, const GUID *tgt, IMMDevice **device) DECLSPEC_HIDDEN; + +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; diff --git a/reactos/dll/directx/dsound/duplex.c b/reactos/dll/directx/dsound/duplex.c index 42095c221fc..fad20c2e9da 100644 --- a/reactos/dll/directx/dsound/duplex.c +++ b/reactos/dll/directx/dsound/duplex.c @@ -28,6 +28,7 @@ #define NONAMELESSSTRUCT #define NONAMELESSUNION +#define COBJMACROS #include #include //#include "winuser.h" @@ -36,722 +37,239 @@ #include #include #include -#include #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) +static inline IDirectSoundFullDuplexImpl *impl_from_IUnknown(IUnknown *iface) { - IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj); + return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IUnknown_iface); } -static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_AddRef( - LPDIRECTSOUND iface) +static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) { - IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} + IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface); -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); + TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv); + + if (!ppv) { + WARN("invalid parameter\n"); + return E_INVALIDARG; } - 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) -{ - IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface; - TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid)); - return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid); -} - -static const IDirectSoundVtbl DirectSoundFullDuplex_DirectSound_Vtbl = -{ - 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; - } - - if (ppds == NULL) { - ERR("invalid parameter: ppds == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) { - WARN("not initialized\n"); - *ppds = NULL; - return DSERR_UNINITIALIZED; - } - - 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; - - return DS_OK; -} - -/******************************************************************************* - * IDirectSoundFullDuplex_IDirectSound8 - */ -static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface( - LPDIRECTSOUND8 iface, - REFIID riid, - LPVOID * ppobj) -{ - IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj); -} - -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; -} - -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); - } - 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) -{ - IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface; - TRACE("(%p,%p,%p)\n",This,psb,ppdsb); - return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb); -} - -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); -} - -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); -} - -static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_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 -}; - -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 - */ -static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface( - LPDIRECTSOUNDCAPTURE iface, - REFIID riid, - LPVOID * ppobj) -{ - IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj); -} - -static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef( - LPDIRECTSOUNDCAPTURE iface) -{ - IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); - return ref; -} - -static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release( - LPDIRECTSOUNDCAPTURE 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; - } - - 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; -} - -/*************************************************************************** - * 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); - return ref; -} - -static HRESULT WINAPI -IDirectSoundFullDuplexImpl_QueryInterface( - LPDIRECTSOUNDFULLDUPLEX iface, - REFIID riid, - LPVOID* ppobj ) -{ - IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface; - TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj ); - - if (ppobj == NULL) { - WARN("invalid parameter\n"); - return E_INVALIDARG; - } - - *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; + IUnknown_AddRef(&This->IUnknown_iface); + *ppv = &This->IUnknown_iface; return S_OK; } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) { - IDirectSoundFullDuplexImpl_AddRef(iface); - *ppobj = This; + IDirectSoundFullDuplex_AddRef(&This->IDirectSoundFullDuplex_iface); + *ppv = &This->IDirectSoundFullDuplex_iface; 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; - } + } 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); + *ppv = NULL; return E_NOINTERFACE; } -static ULONG WINAPI -IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface ) +static ULONG WINAPI IUnknownImpl_AddRef(IUnknown *iface) { - IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface; - ULONG ref = InterlockedDecrement(&(This->ref)); - TRACE("(%p) ref was %d\n", This, ref - 1); + IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedIncrement(&This->ref); - 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); - } + TRACE("(%p) ref=%d\n", This, ref); + + if(ref == 1) + InterlockedIncrement(&This->numIfaces); 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 ULONG WINAPI IUnknownImpl_Release(IUnknown *iface) { + IDirectSoundFullDuplexImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if (!ref && !InterlockedDecrement(&This->numIfaces)) + fullduplex_destroy(This); + return ref; +} + +static const IUnknownVtbl unk_vtbl = +{ + IUnknownImpl_QueryInterface, + IUnknownImpl_AddRef, + IUnknownImpl_Release +}; + +/*************************************************************************** + * IDirectSoundFullDuplex implementation + */ +static inline IDirectSoundFullDuplexImpl *impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex *iface) +{ + return CONTAINING_RECORD(iface, IDirectSoundFullDuplexImpl, IDirectSoundFullDuplex_iface); +} + +static HRESULT WINAPI IDirectSoundFullDuplexImpl_QueryInterface(IDirectSoundFullDuplex *iface, + REFIID riid, void **ppv) +{ + 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 IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface) +{ + IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface); + ULONG ref = InterlockedIncrement(&This->refdsfd); + + TRACE("(%p) ref=%d\n", This, ref); + + if(ref == 1) + InterlockedIncrement(&This->numIfaces); + return ref; +} + +static ULONG WINAPI IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex *iface) +{ + IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface); + ULONG ref = InterlockedDecrement(&This->refdsfd); + + TRACE("(%p) ref=%d\n", This, ref); + + if (!ref && !InterlockedDecrement(&This->numIfaces)) + fullduplex_destroy(This); + return ref; +} + +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 (This->renderer_device != NULL || This->capture_device != NULL) { + if (!dscb8 || !dsb8) + return E_INVALIDARG; + + *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); + hr = IDirectSound8_CreateSoundBuffer(ds8, bufdesc, (IDirectSoundBuffer**)dsb8, NULL); if (hr != DS_OK) { - WARN("DSOUND_PrimarySetFormat() failed\n"); - *lplpDirectSoundCaptureBuffer8 = NULL; - *lplpDirectSoundBuffer8 = NULL; - return hr; - } - hr = IDirectSoundBufferImpl_Create(This->renderer_device, &dsb, lpDsBufferDesc); - 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, @@ -762,44 +280,32 @@ static const IDirectSoundFullDuplexVtbl dsfdvt = 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); + IDirectSoundFullDuplexImpl *obj; + HRESULT hr; - if (ppDSFD == NULL) { - WARN("invalid parameter: ppDSFD == NULL\n"); - return DSERR_INVALIDPARAM; - } + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); - if (!IsEqualIID(riid, &IID_IUnknown) && - !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) { - *ppDSFD = 0; - return E_NOINTERFACE; - } - - /* Get dsound configuration */ - setup_dsound_options(); - - This = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl)); - - 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; } /*************************************************************************** @@ -808,107 +314,50 @@ HRESULT DSOUND_FullDuplexCreate( * 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); + HRESULT hr; - if (pUnkOuter) { - WARN("pUnkOuter != 0\n"); - *ppDSFD = NULL; + 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 (!dsfd) + return DSERR_INVALIDPARAM; + if (outer_unk) { + *dsfd = NULL; return DSERR_NOAGGREGATION; } - if (pcDSCBufferDesc == NULL) { - WARN("invalid parameter: pcDSCBufferDesc == NULL\n"); - *ppDSFD = NULL; - return DSERR_INVALIDPARAM; + 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"); + } } - if (pcDSBufferDesc == NULL) { - WARN("invalid parameter: pcDSBufferDesc == NULL\n"); - *ppDSFD = NULL; - return DSERR_INVALIDPARAM; - } - - if (ppDSFD == NULL) { - WARN("invalid parameter: ppDSFD == NULL\n"); - return DSERR_INVALIDPARAM; - } - - 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; - return DSERR_INVALIDPARAM; - } - - /* 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; - } - - 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; } diff --git a/reactos/dll/directx/dsound/fir.h b/reactos/dll/directx/dsound/fir.h new file mode 100644 index 00000000000..399fbd4d414 --- /dev/null +++ b/reactos/dll/directx/dsound/fir.h @@ -0,0 +1,1591 @@ +#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 +}; diff --git a/reactos/dll/directx/dsound/mixer.c b/reactos/dll/directx/dsound/mixer.c index 1e073790a2d..05a1ca35a1c 100644 --- a/reactos/dll/directx/dsound/mixer.c +++ b/reactos/dll/directx/dsound/mixer.c @@ -5,6 +5,7 @@ * 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 @@ -28,17 +29,21 @@ #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H - +#define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION #include #include #include +//#include "wingdi.h" +//#include "mmreg.h" #include #include #include -#include +//#include "ks.h" +//#include "ksmedia.h" #include "dsound_private.h" +#include "fir.h" WINE_DEFAULT_DEBUG_CHANNEL(dsound); @@ -94,127 +99,81 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) 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); } /** @@ -271,32 +230,114 @@ void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len } } -/** - * 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; +} + +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 == 1 && dsb->pwfx->nChannels == 2) - { - dsb->convert(ibuf, obuf, 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; + } } - 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); - } + dsb->sec_mixpos = ipos; } /** @@ -327,158 +368,53 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2) * * 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; + UINT size_bytes = frames * sizeof(float) * dsb->device->pwfx->nChannels; - /* We resample only when needed */ - if ((dsb->tmp_buffer && inmixer) || (!dsb->tmp_buffer && !inmixer) || dsb->resampleinmixer != inmixer) - return; - - 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; + dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, size_bytes); } - /* 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); - } - - 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; + float vLeft, vRight; + UINT channels = dsb->device->pwfx->nChannels, chan; - if (dsb->resampleinmixer) - mem = dsb->device->tmp_buffer; - - 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; + FIXME("There is no support for %u channels\n", channels); + return; } - 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); - } - - 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; + 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 % 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; - } - if (len % 4 == 2 && nChannels == 1) - *(bps++) = ((INT)*(mems++) * vLeft) >> 16; - break; } - return dsb->device->tmp_buffer; } /** @@ -496,15 +432,14 @@ static LPBYTE DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT len) */ 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); @@ -512,53 +447,23 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO } /* 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; + DSOUND_MixerVol(dsb, frames); - 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); - } + mixieee32(ibuf, dsb->device->mix_buffer, frames * dsb->device->pwfx->nChannels); - 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); - } - - 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; } @@ -576,67 +481,34 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO */ 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); - - 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; + primary_done += DSOUND_MixInBuffer(dsb, writepos, mixlen); - 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); - - /* 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; @@ -649,7 +521,6 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi * 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 @@ -657,12 +528,10 @@ static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mi * 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; @@ -673,46 +542,27 @@ static DWORD DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos 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; } /** @@ -727,79 +577,130 @@ static DWORD DSOUND_MixToPrimary(const DirectSoundDevice *device, DWORD writepos static void DSOUND_WaveQueue(DirectSoundDevice *device, BOOL force) { - DWORD prebuf_frags, wave_writepos, wave_fragpos, i; + DWORD prebuf_frames, prebuf_bytes, read_offs_bytes; + BYTE *buffer; + HRESULT hr; + TRACE("(%p)\n", device); - /* calculate the current wave frag position */ - wave_fragpos = (device->pwplay + device->pwqueue) % device->helfrags; + read_offs_bytes = (device->playing_offs_bytes + device->in_mmdev_bytes) % device->buflen; - /* calculate the current wave write position */ - wave_writepos = wave_fragpos * device->fraglen; - - 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; ihwo, &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; + } - TRACE("queue now = %i\n", device->pwqueue); + 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("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 */ @@ -812,16 +713,11 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) } 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); @@ -840,39 +736,22 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) /* 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; @@ -882,50 +761,33 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) 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){ @@ -961,14 +823,9 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) 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) { @@ -989,63 +846,29 @@ static void DSOUND_PerformMix(DirectSoundDevice *device) /* **** */ } -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); + DirectSoundDevice *dev = p; + TRACE("(%p)\n", dev); - if (DSOUND_renderer[device->drvdesc.dnDevNode] != device) { - ERR("dsound died without killing us?\n"); - timeKillEvent(timerID); - timeEndPeriod(DS_TIME_RES); - return; + 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)); } - - 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)); - /* **** */ - } - TRACE("completed\n"); + return 0; } diff --git a/reactos/dll/directx/dsound/primary.c b/reactos/dll/directx/dsound/primary.c index c4dd2dcc5bf..15a97896d12 100644 --- a/reactos/dll/directx/dsound/primary.c +++ b/reactos/dll/directx/dsound/primary.c @@ -17,6 +17,10 @@ * 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 @@ -24,7 +28,7 @@ #define WIN32_NO_STATUS #define _INC_WINDOWS #define COM_NO_WINDOWS_H - +#define COBJMACROS #define NONAMELESSSTRUCT #define NONAMELESSUNION //#include "windef.h" @@ -35,285 +39,319 @@ #include #include #include -#include #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: - */ + REFERENCE_TIME period; + HRESULT hr; + DWORD ret; - if (nSamplesPerSec <= 12800) - return 128 * nBlockAlign; + 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); - if (nSamplesPerSec <= 25600) - return 256 * nBlockAlign; - - if (nSamplesPerSec <= 51200) - return 512 * nBlockAlign; - - return 1024 * nBlockAlign; + 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); + WAVEFORMATEXTENSIBLE *retwfe = NULL; + WAVEFORMATEX *w; + HRESULT hr; - 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); + if (!forcewave) { + WAVEFORMATEXTENSIBLE *mixwfe; + hr = IAudioClient_GetMixFormat(client, (WAVEFORMATEX**)&mixwfe); - 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 (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 (!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); + UINT prebuf_frames; + REFERENCE_TIME prebuf_rt; + WAVEFORMATEX *wfx = NULL; + HRESULT hres; + REFERENCE_TIME period; + DWORD period_ms; - 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); + TRACE("(%p, %d)\n", device, forcewave); - /* 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); + 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; + } - /* 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; - } - } + 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 no DirectSound interface available, use WINMM API instead */ - if (!device->driver) - device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT; + 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; - if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) - { - DWORD flags = CALLBACK_FUNCTION; + prebuf_frames = device->prebuf * DSOUND_fraglen(device) / device->pwfx->nBlockAlign; + prebuf_rt = (10000000 * (UINT64)prebuf_frames) / device->pwfx->nSamplesPerSec; - if (device->driver) - flags |= WAVE_DIRECTSOUND; + 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 = 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_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) - hres = IDsDriver_Open(device->driver); + 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; + } - 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; + } + + /* 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 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; + 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]; - /* prepare fragment headers */ - for (c=0; chelfrags; 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; - } - } + for (i = 0; i < device->nrofbuffers; i++) { + RtlAcquireResourceExclusive(&dsb[i]->lock, TRUE); + DSOUND_RecalcFormat(dsb[i]); + RtlReleaseResource(&dsb[i]->lock); + } - overshot = device->buflen % device->fraglen; - /* sanity */ - if(overshot) - { - overshot -= overshot % device->pwfx->nBlockAlign; - device->pwave[device->helfrags - 1].dwBufferLength += overshot; - } - - 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; chelfrags; c++) - waveOutUnprepareHeader(device->hwo, &device->pwave[c], sizeof(WAVEHDR)); - /* **** */ - EnterCriticalSection(&(device->mixlock)); + if(device->client){ + hr = IAudioClient_Stop(device->client); + if(FAILED(hr)) + WARN("Stop failed: %08x\n", hr); + } - /* 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); - } + /* clear the queue */ + device->in_mmdev_bytes = 0; } HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device) @@ -341,15 +379,16 @@ HRESULT DSOUND_PrimaryDestroy(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)); /* **** */ @@ -359,94 +398,90 @@ HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device) 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); + HRESULT hr; - 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 { + TRACE("(%p)\n", device); - /* don't call the wave system with the lock set */ - LeaveCriticalSection(&(device->mixlock)); - /* **** */ + hr = IAudioClient_Stop(device->client); + if(FAILED(hr)){ + WARN("Stop failed: %08x\n", hr); + return hr; + } - err = mmErr(waveOutPause(device->hwo)); - - /* **** */ - EnterCriticalSection(&(device->mixlock)); - - if (err != DS_OK) - WARN("waveOutPause failed\n"); - } - - 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"); @@ -454,120 +489,89 @@ HRESULT DSOUND_PrimarySetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex, } /* 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 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)); + } + +out: LeaveCriticalSection(&(device->mixlock)); RtlReleaseResource(&(device->buffer_list_lock)); /* **** */ @@ -578,26 +582,31 @@ done: /******************************************************************************* * PrimaryBuffer */ -/* This sets this format for the Primary Buffer Only */ -/* 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) { - DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device; - TRACE("(%p,%p)\n", iface, wfex); - return DSOUND_PrimarySetFormat(device, wfex, device->priolevel == DSSCL_WRITEPRIMARY); + /* IDirectSoundBuffer and IDirectSoundBuffer8 use the same iface. */ + return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSoundBuffer8_iface); } -static HRESULT WINAPI PrimaryBufferImpl_SetVolume( - LPDIRECTSOUNDBUFFER iface,LONG vol -) { - DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->device; - DWORD ampfactors; - HRESULT hres = DS_OK; +/* This sets this format for the primary buffer only */ +static HRESULT WINAPI PrimaryBufferImpl_SetFormat(IDirectSoundBuffer *iface, + const WAVEFORMATEX *wfex) +{ + IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); + TRACE("(%p,%p)\n", iface, wfex); + return primarybuffer_SetFormat(This->device, wfex); +} + +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; } @@ -608,39 +617,66 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume( } /* **** */ - 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; } @@ -650,21 +686,39 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume( 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 */ @@ -672,10 +726,11 @@ static HRESULT WINAPI PrimaryBufferImpl_SetFrequency( 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)) { @@ -697,9 +752,10 @@ static HRESULT WINAPI PrimaryBufferImpl_Play( 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); /* **** */ @@ -716,33 +772,50 @@ static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER 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); + 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); - if (!ref) { - This->device->primary = NULL; - HeapFree(GetProcessHeap(), 0, This); - TRACE("(%p) released\n", This); - } 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); /* **** */ @@ -768,10 +841,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition( 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) { @@ -789,21 +862,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetStatus( } -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 { @@ -814,7 +885,7 @@ static HRESULT WINAPI PrimaryBufferImpl_GetFormat( } } 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; @@ -824,11 +895,13 @@ static HRESULT WINAPI PrimaryBufferImpl_GetFormat( 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, @@ -875,42 +948,29 @@ static HRESULT WINAPI PrimaryBufferImpl_Lock( 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 */ @@ -918,15 +978,15 @@ static HRESULT WINAPI PrimaryBufferImpl_SetCurrentPosition( 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; } @@ -937,42 +997,67 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan( } /* **** */ - 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; } @@ -982,21 +1067,41 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan( 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) { @@ -1004,35 +1109,24 @@ static HRESULT WINAPI PrimaryBufferImpl_Unlock( 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) { @@ -1040,7 +1134,7 @@ static HRESULT WINAPI PrimaryBufferImpl_GetFrequency( return DSERR_INVALIDPARAM; } - if (!(device->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) { + if (!(This->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) { WARN("control unavailable\n"); return DSERR_CONTROLUNAVAIL; } @@ -1051,18 +1145,18 @@ static HRESULT WINAPI PrimaryBufferImpl_GetFrequency( 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) { @@ -1075,7 +1169,7 @@ static HRESULT WINAPI PrimaryBufferImpl_GetCaps( return DSERR_INVALIDPARAM; } - caps->dwFlags = device->dsbd.dwFlags; + caps->dwFlags = This->dsbd.dwFlags; caps->dwBufferBytes = device->buflen; /* Windows reports these as zero */ @@ -1085,11 +1179,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetCaps( 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) { @@ -1101,8 +1195,8 @@ static HRESULT WINAPI PrimaryBufferImpl_QueryInterface( if ( IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) { - IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)This); - *ppobj = This; + IDirectSoundBuffer_AddRef(iface); + *ppobj = iface; return S_OK; } @@ -1125,21 +1219,15 @@ static HRESULT WINAPI PrimaryBufferImpl_QueryInterface( } 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 ) ); @@ -1171,12 +1259,10 @@ static const IDirectSoundBufferVtbl dspbvt = 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) { @@ -1193,11 +1279,34 @@ HRESULT PrimaryBufferImpl_Create( return DSERR_OUTOFMEMORY; } - dsb->ref = 0; + dsb->ref = 0; + dsb->ref3D = 0; + dsb->refiks = 0; + dsb->numIfaces = 0; dsb->device = device; - dsb->lpVtbl = &dspbvt; + dsb->IDirectSoundBuffer8_iface.lpVtbl = (IDirectSoundBuffer8Vtbl *)&dspbvt; + dsb->IDirectSound3DListener_iface.lpVtbl = &ds3dlvt; + dsb->IKsPropertySet_iface.lpVtbl = &iksbvt; + dsb->dsbd = *dsbd; - device->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," @@ -1207,6 +1316,7 @@ HRESULT PrimaryBufferImpl_Create( device->pwfx->nBlockAlign, device->pwfx->wBitsPerSample, device->pwfx->cbSize); + IDirectSoundBuffer_AddRef(&dsb->IDirectSoundBuffer8_iface); *ppdsb = dsb; return S_OK; } diff --git a/reactos/dll/directx/dsound/propset.c b/reactos/dll/directx/dsound/propset.c index df81a22e36e..c19ff9f7d0d 100644 --- a/reactos/dll/directx/dsound/propset.c +++ b/reactos/dll/directx/dsound/propset.c @@ -20,6 +20,8 @@ */ #define COBJMACROS +#define NONAMELESSSTRUCT +#define NONAMELESSUNION #define WIN32_NO_STATUS #define _INC_WINDOWS @@ -30,207 +32,34 @@ #include #include //#include "winuser.h" -//#include "mmsystem.h" +#include #include #include #include -#include +#include +//#include #include #include -#include #include "dsound_private.h" #include -#ifdef NONAMELESSSTRUCT -# define S(x) (x).s -#else -# define S(x) (x) -#endif +//#include "ksmedia.h" +//#include "propkey.h" +#include WINE_DEFAULT_DEBUG_CHANNEL(dsound); -/******************************************************************************* - * IKsBufferPropertySet - */ +static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 }; -/* IUnknown methods */ -static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface( - LPKSPROPERTYSET iface, - REFIID riid, - LPVOID *ppobj ) +typedef struct IKsPrivatePropertySetImpl { - IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface; - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); + IKsPropertySet IKsPropertySet_iface; + LONG ref; +} IKsPrivatePropertySetImpl; - return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj); -} - -static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface) +static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *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 HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport( - LPKSPROPERTYSET iface, - REFGUID guidPropSet, - ULONG dwPropID, - PULONG pTypeSupport ) -{ - 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 -}; - -HRESULT IKsBufferPropertySetImpl_Create( - IDirectSoundBufferImpl *dsb, - IKsBufferPropertySetImpl **piks) -{ - 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); } /******************************************************************************* @@ -239,17 +68,15 @@ HRESULT IKsBufferPropertySetImpl_Destroy( /* 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; @@ -258,7 +85,7 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface( 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; @@ -266,7 +93,7 @@ static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface) 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); @@ -277,67 +104,22 @@ static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface) return ref; } -static HRESULT DSPROPERTY_WaveDeviceMappingA( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) +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) { - HRESULT hr = DSERR_INVALIDPARAM; - PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); + struct search_data *search = user; - ppd = pPropData; - - if (!ppd) { - WARN("invalid parameter: pPropData\n"); - return DSERR_INVALIDPARAM; + if(!lstrcmpW(desc, search->tgt_name)){ + *search->found_guid = *guid; + return FALSE; } - 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; - } - } - } - } - - if (pcbReturned) - *pcbReturned = cbPropData; - - return hr; + return TRUE; } static HRESULT DSPROPERTY_WaveDeviceMappingW( @@ -345,915 +127,186 @@ static HRESULT DSPROPERTY_WaveDeviceMappingW( 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); + 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++) { - 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; - } - } - } + 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; + + return DS_OK; +} + +static HRESULT DSPROPERTY_WaveDeviceMappingA( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned ) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data; + DWORD len; + HRESULT hr; + + TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", + pPropData,cbPropData,pcbReturned); + + if (!ppd || !ppd->DeviceName) { + WARN("invalid parameter: ppd=%p\n", ppd); + return DSERR_INVALIDPARAM; } + 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( - 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; - - if (!ppd) { - WARN("invalid parameter: pPropData\n"); - return DSERR_INVALIDPARAM; - } - - 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; - } - - ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - 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; - } - } - } - - 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; - } - } - } - - if (pcbReturned) { - *pcbReturned = cbPropData; - TRACE("*pcbReturned=%d\n", *pcbReturned); - } - - return S_OK; -} - -static HRESULT DSPROPERTY_DescriptionA( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = pPropData; - HRESULT err; - GUID dev_guid; - 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; - } - - ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED; - GetDeviceID(&ppd->DeviceId, &dev_guid); - - 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; - } - } - } - - 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; - } - } - } - } - - if (found == FALSE) { - WARN("device not found\n"); - return E_PROP_ID_UNSUPPORTED; - } - } - - if (pcbReturned) { - *pcbReturned = cbPropData; - TRACE("*pcbReturned=%d\n", *pcbReturned); - } - - return S_OK; -} - static HRESULT DSPROPERTY_DescriptionW( LPVOID pPropData, ULONG cbPropData, PULONG pcbReturned ) { PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData; - HRESULT err; GUID dev_guid; + IMMDevice *mmdevice; + IPropertyStore *ps; + PROPVARIANT pv; + DWORD desclen; + HRESULT hr; + TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); + 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; - 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 (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; - } - } - } - } - - if (found == FALSE) { - WARN("device not found\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; } + 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_Enumerate1( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) +static +BOOL CALLBACK enum_callback(GUID *guid, const WCHAR *desc, const WCHAR *module, + void *user) { - 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); + PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = user; + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; + DWORD len; + BOOL ret; - if (ppd) { - if (ppd->Callback) { - unsigned devs, wod, wid; - DSDRIVERDESC desc; - DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data; + TRACE("%s %s %s %p\n", wine_dbgstr_guid(guid), wine_dbgstr_w(desc), + wine_dbgstr_w(module), user); - 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)); + if(!guid) + return TRUE; - 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.DeviceId = *guid; - 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"); + len = lstrlenW(module) + 1; + data.Module = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + memcpy(data.Module, module, len * sizeof(WCHAR)); - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - } + len = lstrlenW(desc) + 1; + data.Description = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + memcpy(data.Description, desc, len * sizeof(WCHAR)); - 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)); + data.Interface = wInterface; - 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) ); + ret = ppd->Callback(&data, ppd->Context); - 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"); + HeapFree(GetProcessHeap(), 0, data.Module); + HeapFree(GetProcessHeap(), 0, data.Description); - TRACE("calling Callback(%p,%p)\n", &data, ppd->Context); - (ppd->Callback)(&data, ppd->Context); - } - } - - return S_OK; - } - } - - if (pcbReturned) { - *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); - } - - return E_PROP_ID_UNSUPPORTED; -} - -static HRESULT DSPROPERTY_EnumerateA( - LPVOID pPropData, - ULONG cbPropData, - PULONG pcbReturned ) -{ - PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = pPropData; - HRESULT err; - TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", - pPropData,cbPropData,pcbReturned); - - 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 (pcbReturned) { - *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); - } - - return E_PROP_ID_UNSUPPORTED; + return ret; } static HRESULT DSPROPERTY_EnumerateW( @@ -1262,117 +315,188 @@ static HRESULT DSPROPERTY_EnumerateW( PULONG pcbReturned ) { PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData; - HRESULT err; + HRESULT hr; + TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n", pPropData,cbPropData,pcbReturned); - 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) { + if (pcbReturned) *pcbReturned = 0; - FIXME("*pcbReturned=%d\n", *pcbReturned); + + if (!ppd || !ppd->Callback) + { + WARN("Invalid ppd %p\n", ppd); + return E_PROP_ID_UNSUPPORTED; } - return E_PROP_ID_UNSUPPORTED; + hr = enumerate_mmdevices(eRender, DSOUND_renderer_guids, + enum_callback, ppd); + + if(hr == S_OK) + hr = enumerate_mmdevices(eCapture, DSOUND_capture_guids, + enum_callback, ppd); + + return SUCCEEDED(hr) ? DS_OK : hr; +} + +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; + } + + 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; +} + +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 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) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; + + if (!ppd || !ppd->Callback) + { + WARN("Invalid ppd %p\n", ppd); + return E_PROP_ID_UNSUPPORTED; + } + + data.Callback = DSPROPERTY_enumWtoA; + data.Context = ppd; + + return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned); +} + +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) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData; + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data; + + if (!ppd || !ppd->Callback) + { + WARN("Invalid ppd %p\n", ppd); + return E_PROP_ID_UNSUPPORTED; + } + + data.Callback = DSPROPERTY_enumWto1; + data.Context = ppd; + + return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned); +} + +static HRESULT DSPROPERTY_DescriptionA( + LPVOID pPropData, + ULONG cbPropData, + PULONG pcbReturned) +{ + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data; + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_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; + if (!DSPROPERTY_descWtoA(&data, ppd)) + hr = E_OUTOFMEMORY; + HeapFree(GetProcessHeap(), 0, data.Module); + HeapFree(GetProcessHeap(), 0, data.Interface); + return hr; +} + +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( @@ -1385,7 +509,7 @@ 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); @@ -1432,7 +556,7 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_Set( 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; @@ -1444,7 +568,7 @@ static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport( 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) ) { @@ -1493,23 +617,24 @@ static const IKsPropertySetVtbl ikspvt = { 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; } diff --git a/reactos/dll/directx/dsound/regsvr.c b/reactos/dll/directx/dsound/regsvr.c deleted file mode 100644 index a1335633498..00000000000 --- a/reactos/dll/directx/dsound/regsvr.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * 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 - -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - -#define NONAMELESSSTRUCT -#define NONAMELESSUNION -#include -#include -//#include "winuser.h" -#include - -#include -#include - -#include -#include - -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; -} diff --git a/reactos/dll/directx/dsound/sound3d.c b/reactos/dll/directx/dsound/sound3d.c index 6c0285a1e8c..04a3e329bab 100644 --- a/reactos/dll/directx/dsound/sound3d.c +++ b/reactos/dll/directx/dsound/sound3d.c @@ -54,7 +54,6 @@ //#include "mmddk.h" #include #include -#include #include "dsound_private.h" /* default velocity of sound in the air */ @@ -66,7 +65,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound3d); * 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; @@ -76,7 +75,7 @@ static inline D3DVALUE ScalarProduct (const D3DVECTOR *a, const D3DVECTOR *b) 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; @@ -167,9 +166,6 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) D3DVALUE flAngle; D3DVECTOR vLeft; /* doppler shift related stuff */ -#if 0 - D3DVALUE flFreq, flBufferVel, flListenerVel; -#endif TRACE("(%p)\n",dsb); @@ -268,13 +264,17 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *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 @@ -287,14 +287,13 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) /* 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); @@ -307,7 +306,7 @@ static void DSOUND_Mix3DBuffer(IDirectSoundBufferImpl *dsb) DSOUND_Calc3DBuffer(dsb); } -static void DSOUND_ChangeListener(IDirectSound3DListenerImpl *ds3dl) +static void DSOUND_ChangeListener(IDirectSoundBufferImpl *ds3dl) { int i; TRACE("(%p)\n",ds3dl); @@ -324,46 +323,54 @@ static void DSOUND_ChangeListener(IDirectSound3DListenerImpl *ds3dl) /******************************************************************************* * IDirectSound3DBuffer */ - -/* IUnknown methods */ -static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface( - LPDIRECTSOUND3DBUFFER iface, REFIID riid, LPVOID *ppobj) +static inline IDirectSoundBufferImpl *impl_from_IDirectSound3DBuffer(IDirectSound3DBuffer *iface) { - IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; - - TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); - return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj); + return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSound3DBuffer_iface); } -static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(LPDIRECTSOUND3DBUFFER iface) +/* IUnknown methods */ +static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface(IDirectSound3DBuffer *iface, + REFIID riid, void **ppobj) { - IDirectSound3DBufferImpl *This = (IDirectSound3DBufferImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); + IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface); + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); + + return IDirectSoundBuffer8_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj); +} + +static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(IDirectSound3DBuffer *iface) +{ + 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) { @@ -377,109 +384,103 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters( } 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) { @@ -493,163 +494,152 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters( } 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, @@ -676,128 +666,60 @@ static const IDirectSound3DBufferVtbl ds3dbvt = 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; - } - - *ppobj = NULL; /* assume failure */ - - if ( IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IDirectSound3DListener ) ) { - IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)This); - *ppobj = This; - return S_OK; - } - - 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; - } - } - - FIXME( "Unknown IID %s\n", debugstr_guid( riid ) ); - return E_NOINTERFACE; + return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSound3DListener_iface); } -static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface) + +/* IUnknown methods */ +static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface(IDirectSound3DListener *iface, + REFIID riid, void **ppobj) { - IDirectSound3DListenerImpl *This = (IDirectSound3DListenerImpl *)iface; - ULONG ref = InterlockedIncrement(&(This->ref)); + IDirectSoundBufferImpl *This = impl_from_IDirectSound3DListener(iface); + + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppobj); + + return IDirectSoundBuffer_QueryInterface(&This->IDirectSoundBuffer8_iface, riid, ppobj); +} + +static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(IDirectSound3DListener *iface) +{ + 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) { @@ -815,32 +737,31 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter( 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); @@ -849,42 +770,41 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation( 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) @@ -896,12 +816,11 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters( 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) @@ -913,12 +832,11 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor( 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) @@ -930,13 +848,12 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor( 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; @@ -954,12 +871,11 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation( 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; @@ -973,12 +889,11 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition( 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) @@ -990,12 +905,11 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor( 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; @@ -1009,16 +923,16 @@ static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity( 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, @@ -1041,46 +955,3 @@ static const IDirectSound3DListenerVtbl ds3dlvt = 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; -} diff --git a/reactos/dll/directx/dsound/tests/.cvsignore b/reactos/dll/directx/dsound/tests/.cvsignore deleted file mode 100644 index 2a11dff94d5..00000000000 --- a/reactos/dll/directx/dsound/tests/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -Makefile -capture.ok -ds3d.ok -ds3d8.ok -dsound.ok -dsound8.ok -propset.ok -testlist.c diff --git a/reactos/dll/directx/dsound/tests/Makefile.in b/reactos/dll/directx/dsound/tests/Makefile.in deleted file mode 100644 index 506ca752ab0..00000000000 --- a/reactos/dll/directx/dsound/tests/Makefile.in +++ /dev/null @@ -1,19 +0,0 @@ -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: diff --git a/reactos/dll/directx/dsound/tests/capture.c b/reactos/dll/directx/dsound/tests/capture.c deleted file mode 100644 index d2cb51cc87b..00000000000 --- a/reactos/dll/directx/dsound/tests/capture.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - * 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 - -#include - -#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 - -#include - -#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;inSamplesPerSec); - 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;iwFormatTag=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_posplayed+=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->writtenwave_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(); -} diff --git a/reactos/dll/directx/dsound/tests/ds3d8.c b/reactos/dll/directx/dsound/tests/ds3d8.c deleted file mode 100644 index e217e40f448..00000000000 --- a/reactos/dll/directx/dsound/tests/ds3d8.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * 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 - -#include - -#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_posplayed+=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->writtenwave_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(); -} diff --git a/reactos/dll/directx/dsound/tests/dsound.c b/reactos/dll/directx/dsound/tests/dsound.c deleted file mode 100644 index a353acf3e92..00000000000 --- a/reactos/dll/directx/dsound/tests/dsound.c +++ /dev/null @@ -1,947 +0,0 @@ -/* - * 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 - -#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 -#include - -#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;fdwFileVersionMS >> 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(); -} diff --git a/reactos/dll/directx/dsound/tests/dsound_test.h b/reactos/dll/directx/dsound/tests/dsound_test.h deleted file mode 100644 index 9c84de44871..00000000000 --- a/reactos/dll/directx/dsound/tests/dsound_test.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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); diff --git a/reactos/dll/directx/dsound/tests/propset.c b/reactos/dll/directx/dsound/tests/propset.c deleted file mode 100644 index 0ca4e00f1ca..00000000000 --- a/reactos/dll/directx/dsound/tests/propset.c +++ /dev/null @@ -1,734 +0,0 @@ -/* - * 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 - -#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(); -} diff --git a/reactos/dll/directx/dsound/version.rc b/reactos/dll/directx/dsound/version.rc index 5ea532f2b04..b3c091e7df1 100644 --- a/reactos/dll/directx/dsound/version.rc +++ b/reactos/dll/directx/dsound/version.rc @@ -16,12 +16,14 @@ * 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 diff --git a/reactos/include/psdk/devpropdef.h b/reactos/include/psdk/devpropdef.h index 23d8b9bf8d0..f53086efcc4 100644 --- a/reactos/include/psdk/devpropdef.h +++ b/reactos/include/psdk/devpropdef.h @@ -77,19 +77,27 @@ typedef struct _DEVPROPKEY { 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) EXTERN_C const DEVPROPKEY name +#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 DECLSPEC_HIDDEN DECLSPEC_SELECTANY name #endif /* INITGUID */ #ifndef IsEqualDevPropKey diff --git a/reactos/include/psdk/dsdriver.h b/reactos/include/psdk/dsdriver.h deleted file mode 100644 index 93ae20a8bee..00000000000 --- a/reactos/include/psdk/dsdriver.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - * 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 */ diff --git a/reactos/include/psdk/dsound.h b/reactos/include/psdk/dsound.h index 7243daeb48b..3c4348f2272 100644 --- a/reactos/include/psdk/dsound.h +++ b/reactos/include/psdk/dsound.h @@ -13,18 +13,12 @@ * * 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 @@ -60,8 +54,6 @@ typedef D3DVECTOR *LPD3DVECTOR; #define LPD3DVECTOR_DEFINED #endif - - #define DX_SHARED_DEFINES #endif /* DX_SHARED_DEFINES */ @@ -240,6 +232,8 @@ typedef const DSCAPS *LPCDSCAPS; #define DSBFREQUENCY_MAX 200000 #define DSBFREQUENCY_ORIGINAL 0 +#define DSBNOTIFICATIONS_MAX 100000U + typedef struct _DSBCAPS { DWORD dwSize; @@ -307,13 +301,18 @@ typedef struct _DSBPOSITIONNOTIFY } 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 */ @@ -404,14 +403,16 @@ typedef const GUID *LPCGUID; 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); @@ -421,15 +422,6 @@ extern HRESULT WINAPI DirectSoundFullDuplexCreate(LPCGUID pcGuidCaptureDevice, L #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 @@ -562,7 +554,7 @@ DECLARE_INTERFACE_(IDirectSoundBuffer,IUnknown) 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; @@ -570,7 +562,7 @@ DECLARE_INTERFACE_(IDirectSoundBuffer,IUnknown) 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 @@ -645,7 +637,7 @@ DECLARE_INTERFACE_(IDirectSoundBuffer8,IUnknown) 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; @@ -653,7 +645,7 @@ DECLARE_INTERFACE_(IDirectSoundBuffer8,IUnknown) 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; @@ -882,7 +874,6 @@ DECLARE_INTERFACE_(IDirectSoundCaptureBuffer8,IDirectSoundCaptureBuffer) #define WINE_NOBUFFER 0x80000000 #define DSBPN_OFFSETSTOP -1 -#define DSBNOTIFICATIONS_MAX 100000UL #define INTERFACE IDirectSoundNotify DECLARE_INTERFACE_(IDirectSoundNotify,IUnknown) @@ -1091,7 +1082,7 @@ DECLARE_INTERFACE_(IDirectSound3DBuffer,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) @@ -1115,7 +1106,7 @@ DECLARE_INTERFACE_(IDirectSound3DBuffer,IUnknown) #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) @@ -1209,4 +1200,4 @@ DECLARE_INTERFACE_(IDirectSoundFullDuplex,IUnknown) } /* extern "C" */ #endif /* defined(__cplusplus) */ -#endif /* __WINE_DSOUND_H */ +#endif /* __DSOUND_INCLUDED__ */ diff --git a/reactos/include/psdk/propkeydef.h b/reactos/include/psdk/propkeydef.h index 85b29647caa..189af7faa26 100644 --- a/reactos/include/psdk/propkeydef.h +++ b/reactos/include/psdk/propkeydef.h @@ -33,18 +33,16 @@ #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 @@ -60,6 +58,7 @@ #ifdef __cplusplus extern "C++" { + inline bool operator==(REFPROPERTYKEY guidOne, REFPROPERTYKEY guidOther) { return IsEqualPropertyKey(guidOne, guidOther); @@ -68,6 +67,7 @@ inline bool operator!=(REFPROPERTYKEY guidOne, REFPROPERTYKEY guidOther) { return !(guidOne == guidOther); } -} //extern "C++" + +} #endif #endif diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index c733d295382..9b5afa9407b 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -33,6 +33,7 @@ reactos/dll/directx/dinput8 # Synced to Wine-20090208 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