*
* 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
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
-#include "winreg.h"
-#include "winuser.h"
-#include "wingdi.h"
#include "winuser.h"
-#include "winerror.h"
#include "mmsystem.h"
#include "winternl.h"
#include "mmddk.h"
-#include "wine/windef16.h"
-#include "wine/winbase16.h"
+#include "wingdi.h"
+#include "mmreg.h"
+#include "ks.h"
+#include "ksmedia.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsdriver.h"
#include "dsound_private.h"
-#include "dsconf.h"
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
-static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
-static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
+/*****************************************************************************
+ * IDirectSound COM components
+ */
+struct IDirectSound_IUnknown {
+ const IUnknownVtbl *lpVtbl;
+ LONG ref;
+ LPDIRECTSOUND8 pds;
+};
+
+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);
-static const char * dumpCooperativeLevel(DWORD level)
+/*****************************************************************************
+ * IDirectSound implementation structure
+ */
+struct IDirectSoundImpl
+{
+ LONG ref;
+
+ DirectSoundDevice *device;
+ LPUNKNOWN pUnknown;
+ LPDIRECTSOUND pDS;
+ LPDIRECTSOUND8 pDS8;
+};
+
+static HRESULT IDirectSoundImpl_Create(LPDIRECTSOUND8 * ppds);
+
+static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
+static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
+
+const char * dumpCooperativeLevel(DWORD level)
{
- static char unknown[32];
#define LE(x) case x: return #x
switch (level) {
LE(DSSCL_NORMAL);
LE(DSSCL_WRITEPRIMARY);
}
#undef LE
- sprintf(unknown, "Unknown(%08lx)", level);
- return unknown;
+ return wine_dbg_sprintf("Unknown(%08x)", level);
}
static void _dump_DSCAPS(DWORD xmask) {
struct {
DWORD mask;
- char *name;
+ const char *name;
} flags[] = {
#define FE(x) { x, #x },
FE(DSCAPS_PRIMARYMONO)
for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
if ((flags[i].mask & xmask) == flags[i].mask)
- DPRINTF("%s ",flags[i].name);
+ TRACE("%s ",flags[i].name);
}
static void _dump_DSBCAPS(DWORD xmask) {
struct {
DWORD mask;
- char *name;
+ const char *name;
} flags[] = {
#define FE(x) { x, #x },
FE(DSBCAPS_PRIMARYBUFFER)
for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
if ((flags[i].mask & xmask) == flags[i].mask)
- DPRINTF("%s ",flags[i].name);
+ TRACE("%s ",flags[i].name);
}
/*******************************************************************************
* IDirectSoundImpl_DirectSound
*/
-static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
- LPDIRECTSOUND8 iface,
- REFIID riid,
- LPVOID * ppobj)
-{
- TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),ppobj);
- FIXME("shouldn't be called directly\n");
- return E_NOINTERFACE;
-}
-
-static HRESULT WINAPI DSOUND_QueryInterface(
+static HRESULT DSOUND_QueryInterface(
LPDIRECTSOUND8 iface,
REFIID riid,
LPVOID * ppobj)
return E_NOINTERFACE;
}
-static HRESULT WINAPI DSOUND_QueryInterface8(
+static HRESULT DSOUND_QueryInterface8(
LPDIRECTSOUND8 iface,
REFIID riid,
LPVOID * ppobj)
return E_NOINTERFACE;
}
-static ULONG WINAPI IDirectSoundImpl_AddRef(
+static ULONG IDirectSoundImpl_AddRef(
LPDIRECTSOUND8 iface)
{
IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
-
- return InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %d\n", This, ref - 1);
+ return ref;
}
-static ULONG WINAPI IDirectSoundImpl_Release(
+static ULONG IDirectSoundImpl_Release(
LPDIRECTSOUND8 iface)
{
IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- ULONG ref;
- TRACE("(%p) ref was %ld, thread is %04lx\n",
- This, This->ref, GetCurrentThreadId());
-
- ref = InterlockedDecrement(&This->ref);
- if (ref == 0) {
- HRESULT hres;
- INT i;
-
- timeKillEvent(This->timerID);
- timeEndPeriod(DS_TIME_RES);
- /* wait for timer to expire */
- Sleep(DS_TIME_RES+1);
-
- /* The sleep above 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(&(This->buffer_list_lock), TRUE);
- RtlReleaseResource(&(This->buffer_list_lock));
-
- /* It is allowed to release this object even when buffers are playing */
- if (This->buffers) {
- WARN("%d secondary buffers not released\n", This->nrofbuffers);
- for( i=0;i<This->nrofbuffers;i++)
- IDirectSoundBufferImpl_Destroy(This->buffers[i]);
- }
-
- if (This->primary) {
- WARN("primary buffer not released\n");
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
- }
+ ULONG ref = InterlockedDecrement(&(This->ref));
+ TRACE("(%p) ref was %d\n", This, ref + 1);
- hres = DSOUND_PrimaryDestroy(This);
- if (hres != DS_OK)
- WARN("DSOUND_PrimaryDestroy failed\n");
+ if (!ref) {
+ if (This->device)
+ DirectSoundDevice_Release(This->device);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n", This);
+ }
+ return ref;
+}
- if (This->driver)
- IDsDriver_Close(This->driver);
+static HRESULT IDirectSoundImpl_Create(
+ LPDIRECTSOUND8 * ppDS)
+{
+ IDirectSoundImpl* pDS;
+ TRACE("(%p)\n",ppDS);
- if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(This->hwo);
+ /* Allocate memory */
+ pDS = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
+ if (pDS == NULL) {
+ WARN("out of memory\n");
+ *ppDS = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
- if (This->driver)
- IDsDriver_Release(This->driver);
+ pDS->ref = 0;
+ pDS->device = NULL;
- RtlDeleteResource(&This->buffer_list_lock);
- This->mixlock.DebugInfo->Spare[1] = 0;
- DeleteCriticalSection(&This->mixlock);
- HeapFree(GetProcessHeap(),0,This);
- dsound = NULL;
- TRACE("(%p) released\n",This);
- }
+ *ppDS = (LPDIRECTSOUND8)pDS;
- return ref;
+ return DS_OK;
}
-static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
+/*******************************************************************************
+ * IDirectSound_IUnknown
+ */
+static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
+ LPUNKNOWN iface,
+ REFIID riid,
+ LPVOID * ppobj)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- FIXME("shouldn't be called directly\n");
- return DSERR_GENERIC;
+ IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface(This->pds, riid, ppobj);
}
-static HRESULT WINAPI DSOUND_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk,
- BOOL from8)
+static ULONG WINAPI IDirectSound_IUnknown_AddRef(
+ LPUNKNOWN iface)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- HRESULT hres = DS_OK;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %d\n", This, ref - 1);
+ return ref;
+}
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
+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;
+}
- if (This->initialized == FALSE) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+static const IUnknownVtbl DirectSound_Unknown_Vtbl =
+{
+ IDirectSound_IUnknown_QueryInterface,
+ IDirectSound_IUnknown_AddRef,
+ IDirectSound_IUnknown_Release
+};
- if (dsbd == NULL) {
- WARN("invalid parameter: dsbd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+static HRESULT IDirectSound_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk)
+{
+ IDirectSound_IUnknown * pdsunk;
+ TRACE("(%p,%p)\n",pds,ppunk);
- if (dsbd->dwSize != sizeof(DSBUFFERDESC) &&
- dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
- WARN("invalid parameter: dsbd\n");
+ if (ppunk == NULL) {
+ ERR("invalid parameter: ppunk == NULL\n");
return DSERR_INVALIDPARAM;
}
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
+ if (pds == NULL) {
+ ERR("invalid parameter: pds == NULL\n");
+ *ppunk = NULL;
return DSERR_INVALIDPARAM;
}
- if (TRACE_ON(dsound)) {
- TRACE("(structsize=%ld)\n",dsbd->dwSize);
- TRACE("(flags=0x%08lx:\n",dsbd->dwFlags);
- _dump_DSBCAPS(dsbd->dwFlags);
- DPRINTF(")\n");
- TRACE("(bufferbytes=%ld)\n",dsbd->dwBufferBytes);
- TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
+ pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
+ if (pdsunk == NULL) {
+ WARN("out of memory\n");
+ *ppunk = NULL;
+ return DSERR_OUTOFMEMORY;
}
- if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
- if (dsbd->lpwfxFormat != NULL) {
- WARN("invalid parameter: dsbd->lpwfxFormat must be NULL for "
- "primary buffer\n");
- return DSERR_INVALIDPARAM;
- }
+ pdsunk->lpVtbl = &DirectSound_Unknown_Vtbl;
+ pdsunk->ref = 0;
+ pdsunk->pds = pds;
- if (This->primary) {
- WARN("Primary Buffer already created\n");
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER)(This->primary);
- } else {
- This->dsbd = *dsbd;
- hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
- if (This->primary) {
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER)(This->primary);
- } else
- WARN("PrimaryBufferImpl_Create failed\n");
- }
- } else {
- IDirectSoundBufferImpl * dsb;
+ IDirectSoundImpl_AddRef(pds);
+ *ppunk = (LPUNKNOWN)pdsunk;
- if (dsbd->lpwfxFormat == NULL) {
- WARN("invalid parameter: dsbd->lpwfxFormat can't be NULL for "
- "secondary buffer\n");
- return DSERR_INVALIDPARAM;
- }
+ return DS_OK;
+}
- TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
- "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
- dsbd->lpwfxFormat->wFormatTag, dsbd->lpwfxFormat->nChannels,
- dsbd->lpwfxFormat->nSamplesPerSec,
- dsbd->lpwfxFormat->nAvgBytesPerSec,
- dsbd->lpwfxFormat->nBlockAlign,
- dsbd->lpwfxFormat->wBitsPerSample, dsbd->lpwfxFormat->cbSize);
+/*******************************************************************************
+ * 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);
+}
- if (from8 && (dsbd->dwFlags & DSBCAPS_CTRL3D) && (dsbd->lpwfxFormat->nChannels != 1)) {
- WARN("invalid parameter: 3D buffer format must be mono\n");
- return DSERR_INVALIDPARAM;
- }
+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;
+}
- hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
- if (dsb) {
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppdsb);
- } else
- WARN("SecondaryBufferImpl_Create failed\n");
- } else
- WARN("IDirectSoundBufferImpl_Create failed\n");
- }
+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;
+}
- return hres;
+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 IDirectSoundImpl_GetCaps(
- LPDIRECTSOUND8 iface,
+static HRESULT WINAPI IDirectSound_IDirectSound_GetCaps(
+ LPDIRECTSOUND iface,
LPDSCAPS lpDSCaps)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
TRACE("(%p,%p)\n",This,lpDSCaps);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (This->initialized == FALSE) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- 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 = %ld < %d\n",
- lpDSCaps->dwSize, sizeof(*lpDSCaps));
- return DSERR_INVALIDPARAM;
- }
-
- lpDSCaps->dwFlags = This->drvcaps.dwFlags;
- if (TRACE_ON(dsound)) {
- TRACE("(flags=0x%08lx:\n",lpDSCaps->dwFlags);
- _dump_DSCAPS(lpDSCaps->dwFlags);
- DPRINTF(")\n");
- }
- lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
- lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
- lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
- lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
- lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
- lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
- lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
- lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
- lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
- lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
- lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
- lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
- lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
- lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
- lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
- lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
- lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
- lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
-
- /* driver doesn't have these */
- lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
- lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
-
- return DS_OK;
+ return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
}
-static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
- LPDIRECTSOUND8 iface,
+static HRESULT WINAPI IDirectSound_IDirectSound_DuplicateSoundBuffer(
+ LPDIRECTSOUND iface,
LPDIRECTSOUNDBUFFER psb,
LPLPDIRECTSOUNDBUFFER ppdsb)
{
- IDirectSoundBufferImpl* pdsb;
- IDirectSoundBufferImpl* dsb;
- HRESULT hres = DS_OK;
- int size;
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
-
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (This->initialized == FALSE) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (psb == NULL) {
- WARN("invalid parameter: psb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* FIXME: hack to make sure we have a secondary buffer */
- if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
- WARN("trying to duplicate primary buffer\n");
- *ppdsb = NULL;
- return DSERR_INVALIDCALL;
- }
-
- pdsb = ((SecondaryBufferImpl *)psb)->dsb;
-
- dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
-
- if (dsb == NULL) {
- WARN("out of memory\n");
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
-
- if (pdsb->hwbuf) {
- TRACE("duplicating hardware buffer\n");
-
- hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
- if (hres != DS_OK) {
- TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
- dsb->hwbuf = NULL;
- /* allocate buffer */
- if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
- dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
- if (dsb->buffer == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
- if (dsb->buffer->memory == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
- dsb->buffer->ref = 1;
-
- /* FIXME: copy buffer ? */
- }
- }
- } else {
- dsb->hwbuf = NULL;
- dsb->buffer->ref++;
- }
-
- dsb->ref = 0;
- dsb->state = STATE_STOPPED;
- dsb->playpos = 0;
- dsb->buf_mixpos = 0;
- dsb->dsound = This;
- dsb->ds3db = NULL;
- dsb->iks = NULL; /* FIXME? */
- dsb->dsb = NULL;
-
- /* 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;
- }
-
- memcpy(dsb->pwfx, pdsb->pwfx, size);
-
- InitializeCriticalSection(&(dsb->lock));
- dsb->lock.DebugInfo->Spare[1] = (DWORD)"DSOUNDBUFFER_lock";
-
- /* register buffer */
- hres = DSOUND_AddBuffer(This, dsb);
- if (hres != DS_OK) {
- IDirectSoundBuffer8_Release(psb);
- dsb->lock.DebugInfo->Spare[1] = 0;
- DeleteCriticalSection(&(dsb->lock));
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb->pwfx);
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = 0;
- } else {
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
- } else
- WARN("SecondaryBufferImpl_Create failed\n");
- }
-
- return hres;
+ return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
}
-static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
- LPDIRECTSOUND8 iface,
+static HRESULT WINAPI IDirectSound_IDirectSound_SetCooperativeLevel(
+ LPDIRECTSOUND iface,
HWND hwnd,
DWORD level)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
-
- if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
- FIXME("level=%s not fully supported\n",
- level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
- }
- This->priolevel = level;
- return DS_OK;
+ 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 IDirectSoundImpl_Compact(
- LPDIRECTSOUND8 iface)
+static HRESULT WINAPI IDirectSound_IDirectSound_Compact(
+ LPDIRECTSOUND iface)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p)\n",This);
-
- if (This->initialized == FALSE) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (This->priolevel != DSSCL_PRIORITY) {
- WARN("incorrect priority level\n");
- return DSERR_PRIOLEVELNEEDED;
- }
-
- return DS_OK;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
+ TRACE("(%p)\n", This);
+ return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device);
}
-static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
+static HRESULT WINAPI IDirectSound_IDirectSound_GetSpeakerConfig(
+ LPDIRECTSOUND iface,
LPDWORD lpdwSpeakerConfig)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p, %p)\n",This,lpdwSpeakerConfig);
-
- if (This->initialized == FALSE) {
- 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 = This->speaker_config;
- return DS_OK;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
}
-static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,
+static HRESULT WINAPI IDirectSound_IDirectSound_SetSpeakerConfig(
+ LPDIRECTSOUND iface,
DWORD config)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
-
- if (This->initialized == FALSE) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- This->speaker_config = config;
- WARN("not fully functional\n");
- return DS_OK;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
+ TRACE("(%p,0x%08x)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
}
-static HRESULT WINAPI IDirectSoundImpl_Initialize(
- LPDIRECTSOUND8 iface,
+static HRESULT WINAPI IDirectSound_IDirectSound_Initialize(
+ LPDIRECTSOUND iface,
LPCGUID lpcGuid)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%s)\n",This,debugstr_guid(lpcGuid));
-
- This->initialized = TRUE;
-
- return DS_OK;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid);
}
-static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
- LPDIRECTSOUND8 iface,
- LPDWORD pdwCertified)
+static const IDirectSoundVtbl DirectSound_DirectSound_Vtbl =
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p, %p)\n",This,pdwCertified);
-
- if (This->initialized == FALSE) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (This->drvcaps.dwFlags & DSCAPS_CERTIFIED)
- *pdwCertified = DS_CERTIFIED;
- else
- *pdwCertified = DS_UNCERTIFIED;
- return DS_OK;
-}
-
-static IDirectSound8Vtbl IDirectSoundImpl_Vtbl =
-{
- IDirectSoundImpl_QueryInterface,
- IDirectSoundImpl_AddRef,
- IDirectSoundImpl_Release,
- IDirectSoundImpl_CreateSoundBuffer,
- IDirectSoundImpl_GetCaps,
- IDirectSoundImpl_DuplicateSoundBuffer,
- IDirectSoundImpl_SetCooperativeLevel,
- IDirectSoundImpl_Compact,
- IDirectSoundImpl_GetSpeakerConfig,
- IDirectSoundImpl_SetSpeakerConfig,
- IDirectSoundImpl_Initialize,
- IDirectSoundImpl_VerifyCertification
+ 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
};
-HRESULT WINAPI IDirectSoundImpl_Create(
- LPCGUID lpcGUID,
- LPDIRECTSOUND8 * ppDS)
+static HRESULT IDirectSound_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds)
{
- HRESULT err;
- PIDSDRIVER drv = NULL;
- IDirectSoundImpl* pDS;
- unsigned wod, wodn;
- BOOLEAN found = FALSE;
- TRACE("(%s,%p)\n",debugstr_guid(lpcGUID),ppDS);
-
- /* Enumerate WINMM audio devices and find the one we want */
- wodn = waveOutGetNumDevs();
- if (!wodn) {
- WARN("no driver\n");
- *ppDS = NULL;
- return DSERR_NODRIVER;
- }
-
- TRACE(" expecting GUID %s.\n", debugstr_guid(lpcGUID));
-
- for (wod=0; wod<wodn; wod++) {
- if (IsEqualGUID( lpcGUID, &renderer_guids[wod])) {
- found = TRUE;
- break;
- }
- }
-
- if (found == FALSE) {
- WARN("No device found matching given ID!\n");
- *ppDS = NULL;
- return DSERR_NODRIVER;
- }
-
- /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
- waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
-
- /* Disable the direct sound driver to force emulation if requested. */
- if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
- drv = NULL;
+ IDirectSound_IDirectSound * pdsds;
+ TRACE("(%p,%p)\n",pds,ppds);
- /* Allocate memory */
- pDS = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
- if (ppDS == NULL) {
- WARN("out of memory\n");
- *ppDS = NULL;
- return DSERR_OUTOFMEMORY;
+ if (ppds == NULL) {
+ ERR("invalid parameter: ppds == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- pDS->lpVtbl = &IDirectSoundImpl_Vtbl;
- pDS->ref = 0;
-
- pDS->driver = drv;
- pDS->priolevel = DSSCL_NORMAL;
- pDS->fraglen = 0;
- pDS->hwbuf = NULL;
- pDS->buffer = NULL;
- pDS->buflen = 0;
- pDS->writelead = 0;
- pDS->state = STATE_STOPPED;
- pDS->nrofbuffers = 0;
- pDS->buffers = NULL;
- pDS->primary = NULL;
- pDS->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
- pDS->initialized = FALSE;
-
- /* 3D listener initial parameters */
- pDS->listener = NULL;
- pDS->ds3dl.dwSize = sizeof(DS3DLISTENER);
- pDS->ds3dl.vPosition.x = 0.0;
- pDS->ds3dl.vPosition.y = 0.0;
- pDS->ds3dl.vPosition.z = 0.0;
- pDS->ds3dl.vVelocity.x = 0.0;
- pDS->ds3dl.vVelocity.y = 0.0;
- pDS->ds3dl.vVelocity.z = 0.0;
- pDS->ds3dl.vOrientFront.x = 0.0;
- pDS->ds3dl.vOrientFront.y = 0.0;
- pDS->ds3dl.vOrientFront.z = 1.0;
- pDS->ds3dl.vOrientTop.x = 0.0;
- pDS->ds3dl.vOrientTop.y = 1.0;
- pDS->ds3dl.vOrientTop.z = 0.0;
- pDS->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
- pDS->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
- pDS->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
-
- pDS->prebuf = ds_snd_queue_max;
- pDS->guid = *lpcGUID;
-
- /* Get driver description */
- if (drv) {
- err = IDsDriver_GetDriverDesc(drv,&(pDS->drvdesc));
- if (err != DS_OK) {
- WARN("IDsDriver_GetDriverDesc failed\n");
- HeapFree(GetProcessHeap(),0,pDS);
- *ppDS = NULL;
- return err;
- }
- } else {
- /* if no DirectSound interface available, use WINMM API instead */
- pDS->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
+ if (pds == NULL) {
+ ERR("invalid parameter: pds == NULL\n");
+ *ppds = NULL;
+ return DSERR_INVALIDPARAM;
}
- pDS->drvdesc.dnDevNode = wod;
-
- /* Set default wave format (may need it for waveOutOpen) */
- pDS->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEFORMATEX));
- if (pDS->pwfx == NULL) {
+ pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
+ if (pdsds == NULL) {
WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,pDS);
- *ppDS = NULL;
+ *ppds = NULL;
return DSERR_OUTOFMEMORY;
}
- pDS->pwfx->wFormatTag = WAVE_FORMAT_PCM;
- /* 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.
- */
- pDS->pwfx->nSamplesPerSec = 22050;
- pDS->pwfx->wBitsPerSample = 8;
- pDS->pwfx->nChannels = 2;
- pDS->pwfx->nBlockAlign = pDS->pwfx->wBitsPerSample * pDS->pwfx->nChannels / 8;
- pDS->pwfx->nAvgBytesPerSec = pDS->pwfx->nSamplesPerSec * pDS->pwfx->nBlockAlign;
- pDS->pwfx->cbSize = 0;
-
- /* If the driver requests being opened through MMSYSTEM
- * (which is recommended by the DDK), it is supposed to happen
- * before the DirectSound interface is opened */
- if (pDS->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- {
- DWORD flags = CALLBACK_FUNCTION;
-
- /* disable direct sound if requested */
- if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
- flags |= WAVE_DIRECTSOUND;
-
- err = mmErr(waveOutOpen(&(pDS->hwo),
- pDS->drvdesc.dnDevNode, pDS->pwfx,
- (DWORD)DSOUND_callback, (DWORD)pDS,
- flags));
- if (err != DS_OK) {
- WARN("waveOutOpen failed\n");
- HeapFree(GetProcessHeap(),0,pDS);
- *ppDS = NULL;
- return err;
- }
- }
-
- if (drv) {
- err = IDsDriver_Open(drv);
- if (err != DS_OK) {
- WARN("IDsDriver_Open failed\n");
- HeapFree(GetProcessHeap(),0,pDS);
- *ppDS = NULL;
- return err;
- }
-
- /* the driver is now open, so it's now allowed to call GetCaps */
- err = IDsDriver_GetCaps(drv,&(pDS->drvcaps));
- if (err != DS_OK) {
- WARN("IDsDriver_GetCaps failed\n");
- HeapFree(GetProcessHeap(),0,pDS);
- *ppDS = NULL;
- return err;
- }
- } else {
- WAVEOUTCAPSA woc;
- err = mmErr(waveOutGetDevCapsA(pDS->drvdesc.dnDevNode, &woc, sizeof(woc)));
- if (err != DS_OK) {
- WARN("waveOutGetDevCaps failed\n");
- HeapFree(GetProcessHeap(),0,pDS);
- *ppDS = NULL;
- return err;
- }
- ZeroMemory(&pDS->drvcaps, sizeof(pDS->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)) {
- pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- pDS->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)) {
- pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- pDS->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)) {
- pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- pDS->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)) {
- pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
- }
- if (ds_emuldriver)
- pDS->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
- pDS->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
- pDS->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
- pDS->drvcaps.dwPrimaryBuffers = 1;
- }
-
- InitializeCriticalSection(&(pDS->mixlock));
- pDS->mixlock.DebugInfo->Spare[1] = (DWORD)"DSOUND_mixlock";
-
- RtlInitializeResource(&(pDS->buffer_list_lock));
+ pdsds->lpVtbl = &DirectSound_DirectSound_Vtbl;
+ pdsds->ref = 0;
+ pdsds->pds = pds;
- *ppDS = (LPDIRECTSOUND8)pDS;
+ IDirectSoundImpl_AddRef(pds);
+ *ppds = (LPDIRECTSOUND)pdsds;
return DS_OK;
}
+
/*******************************************************************************
- * IDirectSound_IUnknown
+ * IDirectSound8_IUnknown
*/
-static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
+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_QueryInterface(This->pds, riid, ppobj);
+ return DSOUND_QueryInterface8(This->pds, riid, ppobj);
}
-static ULONG WINAPI IDirectSound_IUnknown_AddRef(
+static ULONG WINAPI IDirectSound8_IUnknown_AddRef(
LPUNKNOWN iface)
{
IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %d\n", This, ref - 1);
+ return ref;
}
-static ULONG WINAPI IDirectSound_IUnknown_Release(
+static ULONG WINAPI IDirectSound8_IUnknown_Release(
LPUNKNOWN iface)
{
IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ulReturn;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
+ 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);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
}
- return ulReturn;
+ return ref;
}
-static IUnknownVtbl DirectSound_Unknown_Vtbl =
-{
- IDirectSound_IUnknown_QueryInterface,
- IDirectSound_IUnknown_AddRef,
- IDirectSound_IUnknown_Release
-};
-
-HRESULT WINAPI 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;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
-}
-
-static ULONG WINAPI IDirectSound_IDirectSound_Release(
- LPDIRECTSOUND iface)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- ULONG ulReturn;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(),0,This);
- TRACE("(%p) released\n",This);
- }
- return ulReturn;
-}
-
-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 DSOUND_CreateSoundBuffer(This->pds,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 IDirectSoundImpl_GetCaps(This->pds, 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 IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
-}
-
-static HRESULT WINAPI IDirectSound_IDirectSound_SetCooperativeLevel(
- LPDIRECTSOUND iface,
- HWND hwnd,
- DWORD level)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
- return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
-}
-
-static HRESULT WINAPI IDirectSound_IDirectSound_Compact(
- LPDIRECTSOUND iface)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p)\n", This);
- return IDirectSoundImpl_Compact(This->pds);
-}
-
-static HRESULT WINAPI IDirectSound_IDirectSound_GetSpeakerConfig(
- LPDIRECTSOUND iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
-}
-
-static HRESULT WINAPI IDirectSound_IDirectSound_SetSpeakerConfig(
- LPDIRECTSOUND iface,
- DWORD config)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
- return IDirectSoundImpl_SetSpeakerConfig(This->pds,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 IDirectSoundImpl_Initialize(This->pds,lpcGuid);
-}
-
-static 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
-};
-
-HRESULT WINAPI 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;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
-}
-
-static ULONG WINAPI IDirectSound8_IUnknown_Release(
- LPUNKNOWN iface)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ulReturn;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(),0,This);
- TRACE("(%p) released\n",This);
- }
- return ulReturn;
-}
-
-static IUnknownVtbl DirectSound8_Unknown_Vtbl =
+static const IUnknownVtbl DirectSound8_Unknown_Vtbl =
{
IDirectSound8_IUnknown_QueryInterface,
IDirectSound8_IUnknown_AddRef,
IDirectSound8_IUnknown_Release
};
-HRESULT WINAPI IDirectSound8_IUnknown_Create(
+static HRESULT IDirectSound8_IUnknown_Create(
LPDIRECTSOUND8 pds,
LPUNKNOWN * ppunk)
{
LPDIRECTSOUND iface)
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
+ 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 ulReturn;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
+ 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);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
}
- return ulReturn;
+ return ref;
}
static HRESULT WINAPI IDirectSound8_IDirectSound_CreateSoundBuffer(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DSOUND_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk,TRUE);
+ return DirectSoundDevice_CreateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,dsbd,ppdsb,lpunk,TRUE);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_GetCaps(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p,%p)\n",This,lpDSCaps);
- return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
+ return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_DuplicateSoundBuffer(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
+ return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_SetCooperativeLevel(
DWORD level)
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
- return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
+ TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
+ return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_Compact(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p)\n", This);
- return IDirectSoundImpl_Compact(This->pds);
+ return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_GetSpeakerConfig(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
+ return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_SetSpeakerConfig(
DWORD config)
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
- return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
+ TRACE("(%p,0x%08x)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
}
static HRESULT WINAPI IDirectSound8_IDirectSound_Initialize(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
+ return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid);
}
-static IDirectSoundVtbl DirectSound8_DirectSound_Vtbl =
+static const IDirectSoundVtbl DirectSound8_DirectSound_Vtbl =
{
IDirectSound8_IDirectSound_QueryInterface,
IDirectSound8_IDirectSound_AddRef,
IDirectSound8_IDirectSound_Initialize
};
-HRESULT WINAPI IDirectSound8_IDirectSound_Create(
+static HRESULT IDirectSound8_IDirectSound_Create(
LPDIRECTSOUND8 pds,
LPDIRECTSOUND * ppds)
{
LPDIRECTSOUND8 iface)
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
+ 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 ulReturn;
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
+ 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);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
}
- return ulReturn;
+ return ref;
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_CreateSoundBuffer(
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- return DSOUND_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk,TRUE);
+ return DirectSoundDevice_CreateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,dsbd,ppdsb,lpunk,TRUE);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_GetCaps(
{
IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
TRACE("(%p,%p)\n",This,lpDSCaps);
- return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
+ return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_DuplicateSoundBuffer(
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
- return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
+ return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_SetCooperativeLevel(
DWORD level)
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
- return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
+ TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
+ return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_Compact(
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
TRACE("(%p)\n", This);
- return IDirectSoundImpl_Compact(This->pds);
+ return DirectSoundDevice_Compact(((IDirectSoundImpl *)This->pds)->device);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_GetSpeakerConfig(
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
+ return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_SetSpeakerConfig(
DWORD config)
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
- return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
+ TRACE("(%p,0x%08x)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_Initialize(
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
+ return DirectSoundDevice_Initialize(&((IDirectSoundImpl *)This->pds)->device,lpcGuid);
}
static HRESULT WINAPI IDirectSound8_IDirectSound8_VerifyCertification(
{
IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
TRACE("(%p, %p)\n", This, pdwCertified);
- return IDirectSoundImpl_VerifyCertification(This->pds,pdwCertified);
+ return DirectSoundDevice_VerifyCertification(((IDirectSoundImpl *)This->pds)->device,pdwCertified);
}
-static IDirectSound8Vtbl DirectSound8_DirectSound8_Vtbl =
+static const IDirectSound8Vtbl DirectSound8_DirectSound8_Vtbl =
{
IDirectSound8_IDirectSound8_QueryInterface,
IDirectSound8_IDirectSound8_AddRef,
IDirectSound8_IDirectSound8_VerifyCertification
};
-HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
+static HRESULT IDirectSound8_IDirectSound8_Create(
LPDIRECTSOUND8 pds,
LPDIRECTSOUND8 * ppds)
{
return DS_OK;
}
-HRESULT WINAPI DSOUND_Create(
- LPCGUID lpcGUID,
- LPDIRECTSOUND *ppDS,
- IUnknown *pUnkOuter)
+HRESULT DSOUND_Create(
+ REFIID riid,
+ LPDIRECTSOUND *ppDS)
{
+ LPDIRECTSOUND8 pDS;
HRESULT hr;
- GUID devGuid;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
-
- if (pUnkOuter != NULL) {
- WARN("invalid parameter: pUnkOuter != NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ TRACE("(%s, %p)\n", debugstr_guid(riid), ppDS);
- if (ppDS == NULL) {
- WARN("invalid parameter: ppDS == NULL\n");
- return DSERR_INVALIDPARAM;
+ if (!IsEqualIID(riid, &IID_IUnknown) &&
+ !IsEqualIID(riid, &IID_IDirectSound)) {
+ *ppDS = 0;
+ return E_NOINTERFACE;
}
/* Get dsound configuration */
setup_dsound_options();
- /* Default device? */
- if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
- lpcGUID = &DSDEVID_DefaultPlayback;
-
- if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
- WARN("invalid parameter: lpcGUID\n");
- *ppDS = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (dsound) {
- if (IsEqualGUID(&devGuid, &dsound->guid)) {
- hr = IDirectSound_IDirectSound_Create((LPDIRECTSOUND8)dsound, ppDS);
- if (*ppDS)
- IDirectSound_IDirectSound_AddRef(*ppDS);
- else
- WARN("IDirectSound_IDirectSound_Create failed\n");
- } else {
- ERR("different dsound already opened (only support one sound card at a time now)\n");
- *ppDS = NULL;
- hr = DSERR_ALLOCATED;
+ 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 {
- LPDIRECTSOUND8 pDS;
- hr = IDirectSoundImpl_Create(&devGuid, &pDS);
- if (hr == DS_OK) {
- hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)pDS);
- if (hr == DS_OK) {
- hr = IDirectSound_IDirectSound_Create(pDS, ppDS);
- if (*ppDS) {
- IDirectSound_IDirectSound_AddRef(*ppDS);
-
- dsound = (IDirectSoundImpl*)pDS;
- timeBeginPeriod(DS_TIME_RES);
- dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
- (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- } else {
- WARN("IDirectSound_IDirectSound_Create failed\n");
- IDirectSound8_Release(pDS);
- }
- } else {
- WARN("DSOUND_PrimaryCreate failed\n");
- IDirectSound8_Release(pDS);
- }
- } else
- WARN("IDirectSoundImpl_Create failed\n");
+ WARN("IDirectSoundImpl_Create failed\n");
+ *ppDS = 0;
}
return hr;
IUnknown *pUnkOuter)
{
HRESULT hr;
+ LPDIRECTSOUND pDS;
TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
- hr = DSOUND_Create(lpcGUID, ppDS, pUnkOuter);
- if (hr == DS_OK)
- IDirectSoundImpl_Initialize((LPDIRECTSOUND8)dsound, lpcGUID);
-
- return hr;
-}
-
-HRESULT WINAPI DSOUND_Create8(
- LPCGUID lpcGUID,
- LPDIRECTSOUND8 *ppDS,
- IUnknown *pUnkOuter)
-{
- HRESULT hr;
- GUID devGuid;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
+ if (ppDS == NULL) {
+ WARN("invalid parameter: ppDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
if (pUnkOuter != NULL) {
WARN("invalid parameter: pUnkOuter != NULL\n");
+ *ppDS = 0;
return DSERR_INVALIDPARAM;
}
- if (ppDS == NULL) {
- WARN("invalid parameter: ppDS == NULL\n");
- return DSERR_INVALIDPARAM;
+ hr = DSOUND_Create(&IID_IDirectSound, &pDS);
+ if (hr == DS_OK) {
+ hr = IDirectSound_Initialize(pDS, lpcGUID);
+ if (hr != DS_OK) {
+ if (hr != DSERR_ALREADYINITIALIZED) {
+ IDirectSound_Release(pDS);
+ pDS = 0;
+ } else
+ hr = DS_OK;
+ }
}
- /* Get dsound configuration */
- setup_dsound_options();
+ *ppDS = pDS;
- /* Default device? */
- if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
- lpcGUID = &DSDEVID_DefaultPlayback;
+ return hr;
+}
- if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
- WARN("invalid parameter: lpcGUID\n");
- *ppDS = NULL;
- return DSERR_INVALIDPARAM;
+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;
}
- if (dsound) {
- if (IsEqualGUID(&devGuid, &dsound->guid)) {
- hr = IDirectSound8_IDirectSound8_Create((LPDIRECTSOUND8)dsound, ppDS);
- if (*ppDS)
- IDirectSound8_IDirectSound8_AddRef(*ppDS);
- else
- WARN("IDirectSound8_IDirectSound8_Create failed\n");
- } else {
- ERR("different dsound already opened (only support one sound card at a time now)\n");
- *ppDS = NULL;
- hr = DSERR_ALLOCATED;
+ /* 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 {
- LPDIRECTSOUND8 pDS;
- hr = IDirectSoundImpl_Create(&devGuid, &pDS);
- if (hr == DS_OK) {
- hr = DSOUND_PrimaryCreate((IDirectSoundImpl*)pDS);
- if (hr == DS_OK) {
- hr = IDirectSound8_IDirectSound8_Create(pDS, ppDS);
- if (*ppDS) {
- IDirectSound8_IDirectSound8_AddRef(*ppDS);
-
- dsound = (IDirectSoundImpl*)pDS;
- timeBeginPeriod(DS_TIME_RES);
- dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
- (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- } else {
- WARN("IDirectSound8_IDirectSound8_Create failed\n");
- IDirectSound8_Release(pDS);
- }
- } else {
- WARN("DSOUND_PrimaryCreate failed\n");
- IDirectSound8_Release(pDS);
- }
- } else
- WARN("IDirectSoundImpl_Create failed\n");
+ WARN("IDirectSoundImpl_Create failed\n");
+ *ppDS = 0;
}
return hr;
IUnknown *pUnkOuter)
{
HRESULT hr;
+ LPDIRECTSOUND8 pDS;
TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
- hr = DSOUND_Create8(lpcGUID, ppDS, pUnkOuter);
- if (hr == DS_OK)
- IDirectSoundImpl_Initialize((LPDIRECTSOUND8)dsound, lpcGUID);
+ if (ppDS == NULL) {
+ WARN("invalid parameter: ppDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pUnkOuter != NULL) {
+ WARN("invalid parameter: pUnkOuter != NULL\n");
+ *ppDS = 0;
+ return DSERR_INVALIDPARAM;
+ }
+
+ hr = DSOUND_Create8(&IID_IDirectSound8, &pDS);
+ if (hr == DS_OK) {
+ hr = IDirectSound8_Initialize(pDS, lpcGUID);
+ if (hr != DS_OK) {
+ if (hr != DSERR_ALREADYINITIALIZED) {
+ IDirectSound8_Release(pDS);
+ pDS = 0;
+ } else
+ hr = DS_OK;
+ }
+ }
+
+ *ppDS = pDS;
+
+ return hr;
+}
+
+/*******************************************************************************
+ * DirectSoundDevice
+ */
+static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice)
+{
+ DirectSoundDevice * device;
+ TRACE("(%p)\n", ppDevice);
+
+ /* Allocate memory */
+ device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DirectSoundDevice));
+ if (device == NULL) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
+ }
+
+ device->ref = 1;
+ device->priolevel = DSSCL_NORMAL;
+ device->state = STATE_STOPPED;
+ device->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
+
+ /* 3D listener initial parameters */
+ 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->prebuf = ds_snd_queue_max;
+ 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) {
+ WARN("out of memory\n");
+ 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->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;
+
+ InitializeCriticalSection(&(device->mixlock));
+ device->mixlock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundDevice.mixlock");
+
+ RtlInitializeResource(&(device->buffer_list_lock));
+
+ *ppDevice = device;
+
+ return DS_OK;
+}
+
+static ULONG DirectSoundDevice_AddRef(DirectSoundDevice * device)
+{
+ ULONG ref = InterlockedIncrement(&(device->ref));
+ TRACE("(%p) ref was %d\n", device, ref - 1);
+ return ref;
+}
+
+ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
+{
+ HRESULT hr;
+ ULONG ref = InterlockedDecrement(&(device->ref));
+ 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));
+
+ /* It is allowed to release this object even when buffers are playing */
+ if (device->buffers) {
+ WARN("%d secondary buffers not released\n", device->nrofbuffers);
+ for( i=0;i<device->nrofbuffers;i++)
+ IDirectSoundBufferImpl_Destroy(device->buffers[i]);
+ }
+
+ if (device->primary) {
+ WARN("primary buffer not released\n");
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)device->primary);
+ }
+
+ 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;
+
+ HeapFree(GetProcessHeap(), 0, device->tmp_buffer);
+ HeapFree(GetProcessHeap(), 0, device->mix_buffer);
+ if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)
+ HeapFree(GetProcessHeap(), 0, device->buffer);
+ RtlDeleteResource(&device->buffer_list_lock);
+ device->mixlock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&device->mixlock);
+ HeapFree(GetProcessHeap(),0,device);
+ TRACE("(%p) released\n", device);
+ }
+ return ref;
+}
+
+HRESULT DirectSoundDevice_GetCaps(
+ DirectSoundDevice * device,
+ LPDSCAPS lpDSCaps)
+{
+ TRACE("(%p,%p)\n",device,lpDSCaps);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ 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;
+}
+
+HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcGUID)
+{
+ HRESULT hr = DS_OK;
+ unsigned wod, wodn;
+ BOOLEAN found = FALSE;
+ GUID devGUID;
+ DirectSoundDevice * device = *ppDevice;
+ TRACE("(%p,%s)\n",ppDevice,debugstr_guid(lpcGUID));
+
+ if (*ppDevice != NULL) {
+ WARN("already initialized\n");
+ return DSERR_ALREADYINITIALIZED;
+ }
+
+ /* Default device? */
+ if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
+ lpcGUID = &DSDEVID_DefaultPlayback;
+
+ if (GetDeviceID(lpcGUID, &devGUID) != DS_OK) {
+ WARN("invalid parameter: lpcGUID\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* Enumerate WINMM audio devices and find the one we want */
+ wodn = waveOutGetNumDevs();
+ if (!wodn) {
+ WARN("no driver\n");
+ return DSERR_NODRIVER;
+ }
+
+ for (wod=0; wod<wodn; wod++) {
+ if (IsEqualGUID( &devGUID, &DSOUND_renderer_guids[wod])) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found == FALSE) {
+ WARN("No device found matching given ID!\n");
+ return DSERR_NODRIVER;
+ }
+
+ if (DSOUND_renderer[wod]) {
+ if (IsEqualGUID(&devGUID, &DSOUND_renderer[wod]->guid)) {
+ device = DSOUND_renderer[wod];
+ DirectSoundDevice_AddRef(device);
+ *ppDevice = device;
+ 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;
+
+ device->drvdesc.dnDevNode = wod;
+ hr = DSOUND_ReopenDevice(device, FALSE);
+ if (FAILED(hr))
+ {
+ 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));
+ }
+
+ hr = DSOUND_PrimaryCreate(device);
+ if (hr == DS_OK) {
+ UINT triggertime = DS_TIME_DEL, res = DS_TIME_RES, id;
+ TIMECAPS time;
+
+ DSOUND_renderer[device->drvdesc.dnDevNode] = device;
+ timeGetDevCaps(&time, sizeof(TIMECAPS));
+ TRACE("Minimum timer resolution: %u, max timer: %u\n", time.wPeriodMin, time.wPeriodMax);
+ if (triggertime < time.wPeriodMin)
+ triggertime = time.wPeriodMin;
+ if (res < time.wPeriodMin)
+ res = time.wPeriodMin;
+ if (timeBeginPeriod(res) == TIMERR_NOCANDO)
+ WARN("Could not set minimum resolution, don't expect sound\n");
+ id = timeSetEvent(triggertime, res, DSOUND_timer, (DWORD_PTR)device, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
+ if (!id)
+ {
+ WARN("Timer not created! Retrying without TIME_KILL_SYNCHRONOUS\n");
+ id = timeSetEvent(triggertime, res, DSOUND_timer, (DWORD_PTR)device, TIME_PERIODIC);
+ if (!id) ERR("Could not create timer, sound playback will not occur\n");
+ }
+ DSOUND_renderer[device->drvdesc.dnDevNode]->timerID = id;
+ } else {
+ WARN("DSOUND_PrimaryCreate failed\n");
+ }
return hr;
}
+HRESULT DirectSoundDevice_CreateSoundBuffer(
+ DirectSoundDevice * device,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk,
+ BOOL from8)
+{
+ HRESULT hres = DS_OK;
+ TRACE("(%p,%p,%p,%p)\n",device,dsbd,ppdsb,lpunk);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ if (dsbd == NULL) {
+ WARN("invalid parameter: dsbd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsbd->dwSize != sizeof(DSBUFFERDESC) &&
+ dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
+ WARN("invalid parameter: dsbd\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+ *ppdsb = NULL;
+
+ if (TRACE_ON(dsound)) {
+ TRACE("(structsize=%d)\n",dsbd->dwSize);
+ TRACE("(flags=0x%08x:\n",dsbd->dwFlags);
+ _dump_DSBCAPS(dsbd->dwFlags);
+ TRACE(")\n");
+ TRACE("(bufferbytes=%d)\n",dsbd->dwBufferBytes);
+ TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
+ }
+
+ if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
+ if (dsbd->lpwfxFormat != NULL) {
+ WARN("invalid parameter: dsbd->lpwfxFormat must be NULL for "
+ "primary buffer\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (device->primary) {
+ WARN("Primary Buffer already created\n");
+ 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");
+ }
+ } else {
+ IDirectSoundBufferImpl * dsb;
+ WAVEFORMATEXTENSIBLE *pwfxe;
+
+ if (dsbd->lpwfxFormat == NULL) {
+ WARN("invalid parameter: dsbd->lpwfxFormat can't be NULL for "
+ "secondary buffer\n");
+ return DSERR_INVALIDPARAM;
+ }
+ 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;
+ }
+
+ /* cbSize should be 22 bytes, with one possible exception */
+ if (pwfxe->Format.cbSize > (sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) &&
+ !(IsEqualGUID(&pwfxe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
+ 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, &GUID_NULL))
+ FIXME("SubFormat %s not supported right now.\n", debugstr_guid(&pwfxe->SubFormat));
+ return DSERR_INVALIDPARAM;
+ }
+ if (pwfxe->Samples.wValidBitsPerSample > dsbd->lpwfxFormat->wBitsPerSample)
+ {
+ WARN("Samples.wValidBitsPerSample(%d) > Format.wBitsPerSample (%d)\n", pwfxe->Samples.wValidBitsPerSample, pwfxe->Format.wBitsPerSample);
+ return DSERR_INVALIDPARAM;
+ }
+ if (pwfxe->Samples.wValidBitsPerSample && pwfxe->Samples.wValidBitsPerSample < dsbd->lpwfxFormat->wBitsPerSample)
+ {
+ FIXME("Non-packed formats not supported right now: %d/%d\n", pwfxe->Samples.wValidBitsPerSample, dsbd->lpwfxFormat->wBitsPerSample);
+ return DSERR_CONTROLUNAVAIL;
+ }
+ }
+
+ TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
+ "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
+ dsbd->lpwfxFormat->wFormatTag, dsbd->lpwfxFormat->nChannels,
+ dsbd->lpwfxFormat->nSamplesPerSec,
+ dsbd->lpwfxFormat->nAvgBytesPerSec,
+ dsbd->lpwfxFormat->nBlockAlign,
+ dsbd->lpwfxFormat->wBitsPerSample, dsbd->lpwfxFormat->cbSize);
+
+ if (from8 && (dsbd->dwFlags & DSBCAPS_CTRL3D) && (dsbd->lpwfxFormat->nChannels != 1)) {
+ WARN("invalid parameter: 3D buffer format must be mono\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ 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");
+ }
+
+ return hres;
+}
+
+HRESULT DirectSoundDevice_DuplicateSoundBuffer(
+ DirectSoundDevice * device,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ HRESULT hres = DS_OK;
+ IDirectSoundBufferImpl* dsb;
+ TRACE("(%p,%p,%p)\n",device,psb,ppdsb);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ if (psb == NULL) {
+ WARN("invalid parameter: psb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* make sure we have a secondary buffer */
+ if ((PrimaryBufferImpl *)psb == device->primary) {
+ WARN("trying to duplicate primary buffer\n");
+ *ppdsb = NULL;
+ return DSERR_INVALIDCALL;
+ }
+
+ /* duplicate the actual buffer implementation */
+ hres = IDirectSoundBufferImpl_Duplicate(device, &dsb,
+ ((SecondaryBufferImpl *)psb)->dsb);
+
+ if (hres == DS_OK) {
+ /* create a new secondary buffer using the new implementation */
+ hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+ if (*ppdsb) {
+ dsb->secondary = (SecondaryBufferImpl*)*ppdsb;
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+ } else {
+ WARN("SecondaryBufferImpl_Create failed\n");
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb);
+ IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)dsb);
+ }
+ }
+
+ return hres;
+}
+
+HRESULT DirectSoundDevice_SetCooperativeLevel(
+ DirectSoundDevice * device,
+ HWND hwnd,
+ DWORD level)
+{
+ TRACE("(%p,%p,%s)\n",device,hwnd,dumpCooperativeLevel(level));
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
+ WARN("level=%s not fully supported\n",
+ level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
+ }
+
+ device->priolevel = level;
+ return DS_OK;
+}
+
+HRESULT DirectSoundDevice_Compact(
+ DirectSoundDevice * device)
+{
+ TRACE("(%p)\n", device);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ if (device->priolevel < DSSCL_PRIORITY) {
+ WARN("incorrect priority level\n");
+ return DSERR_PRIOLEVELNEEDED;
+ }
+
+ return DS_OK;
+}
+
+HRESULT DirectSoundDevice_GetSpeakerConfig(
+ DirectSoundDevice * device,
+ LPDWORD lpdwSpeakerConfig)
+{
+ TRACE("(%p, %p)\n", device, lpdwSpeakerConfig);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ if (lpdwSpeakerConfig == NULL) {
+ WARN("invalid parameter: lpdwSpeakerConfig == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ WARN("not fully functional\n");
+ *lpdwSpeakerConfig = device->speaker_config;
+ return DS_OK;
+}
+
+HRESULT DirectSoundDevice_SetSpeakerConfig(
+ DirectSoundDevice * device,
+ DWORD config)
+{
+ TRACE("(%p,0x%08x)\n",device,config);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
+
+ device->speaker_config = config;
+ WARN("not fully functional\n");
+ return DS_OK;
+}
+
+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.
*/
-HRESULT DSOUND_AddBuffer(
- IDirectSoundImpl * pDS,
+HRESULT DirectSoundDevice_AddBuffer(
+ DirectSoundDevice * device,
IDirectSoundBufferImpl * pDSB)
{
IDirectSoundBufferImpl **newbuffers;
HRESULT hr = DS_OK;
- TRACE("(%p, %p)\n", pDS, pDSB);
+ TRACE("(%p, %p)\n", device, pDSB);
- RtlAcquireResourceExclusive(&(pDS->buffer_list_lock), TRUE);
+ RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
- if (pDS->buffers)
- newbuffers = HeapReAlloc(GetProcessHeap(),0,pDS->buffers,sizeof(IDirectSoundBufferImpl*)*(pDS->nrofbuffers+1));
+ if (device->buffers)
+ newbuffers = HeapReAlloc(GetProcessHeap(),0,device->buffers,sizeof(IDirectSoundBufferImpl*)*(device->nrofbuffers+1));
else
- newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(pDS->nrofbuffers+1));
+ newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(device->nrofbuffers+1));
if (newbuffers) {
- pDS->buffers = newbuffers;
- pDS->buffers[pDS->nrofbuffers] = pDSB;
- pDS->nrofbuffers++;
- TRACE("buffer count is now %d\n", pDS->nrofbuffers);
+ device->buffers = newbuffers;
+ device->buffers[device->nrofbuffers] = pDSB;
+ device->nrofbuffers++;
+ TRACE("buffer count is now %d\n", device->nrofbuffers);
} else {
- ERR("out of memory for buffer list! Current buffer count is %d\n", pDS->nrofbuffers);
+ ERR("out of memory for buffer list! Current buffer count is %d\n", device->nrofbuffers);
hr = DSERR_OUTOFMEMORY;
}
- RtlReleaseResource(&(pDS->buffer_list_lock));
+ RtlReleaseResource(&(device->buffer_list_lock));
return hr;
}
* Remove secondary buffer from buffer list.
* Gets exclusive access to buffer for writing.
*/
-HRESULT DSOUND_RemoveBuffer(
- IDirectSoundImpl * pDS,
+HRESULT DirectSoundDevice_RemoveBuffer(
+ DirectSoundDevice * device,
IDirectSoundBufferImpl * pDSB)
{
int i;
HRESULT hr = DS_OK;
- TRACE("(%p, %p)\n", pDS, pDSB);
+ TRACE("(%p, %p)\n", device, pDSB);
- RtlAcquireResourceExclusive(&(pDS->buffer_list_lock), TRUE);
+ RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
- for (i = 0; i < pDS->nrofbuffers; i++)
- if (pDS->buffers[i] == pDSB)
+ for (i = 0; i < device->nrofbuffers; i++)
+ if (device->buffers[i] == pDSB)
break;
- if (i < pDS->nrofbuffers) {
+ if (i < device->nrofbuffers) {
/* Put the last buffer of the list in the (now empty) position */
- pDS->buffers[i] = pDS->buffers[pDS->nrofbuffers - 1];
- pDS->nrofbuffers--;
- pDS->buffers = HeapReAlloc(GetProcessHeap(),0,pDS->buffers,sizeof(LPDIRECTSOUNDBUFFER8)*pDS->nrofbuffers);
- TRACE("buffer count is now %d\n", pDS->nrofbuffers);
+ 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 (pDS->nrofbuffers == 0) {
- HeapFree(GetProcessHeap(),0,pDS->buffers);
- pDS->buffers = NULL;
+ if (device->nrofbuffers == 0) {
+ HeapFree(GetProcessHeap(),0,device->buffers);
+ device->buffers = NULL;
}
- RtlReleaseResource(&(pDS->buffer_list_lock));
+ RtlReleaseResource(&(device->buffer_list_lock));
return hr;
}