*
* 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 <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
-#include "winreg.h"
+#include "winuser.h"
#include "mmsystem.h"
#include "winternl.h"
#include "mmddk.h"
+#include "wingdi.h"
+#include "mmreg.h"
+#include "ks.h"
+#include "ksmedia.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsdriver.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 HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice);
-static ULONG DirectSoundDevice_Release(DirectSoundDevice * device);
+/*****************************************************************************
+ * IDirectSound implementation structure
+ */
+struct IDirectSoundImpl
+{
+ LONG ref;
+
+ DirectSoundDevice *device;
+ LPUNKNOWN pUnknown;
+ LPDIRECTSOUND pDS;
+ LPDIRECTSOUND8 pDS8;
+};
+
+static HRESULT IDirectSoundImpl_Create(LPDIRECTSOUND8 * ppds);
+
+static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
+static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
-static const char * dumpCooperativeLevel(DWORD level)
+static HRESULT DirectSoundDevice_VerifyCertification(DirectSoundDevice * device, LPDWORD pdwCertified);
+
+const char * dumpCooperativeLevel(DWORD level)
{
static char unknown[32];
#define LE(x) case x: return #x
LE(DSSCL_WRITEPRIMARY);
}
#undef LE
- sprintf(unknown, "Unknown(%08lx)", level);
+ sprintf(unknown, "Unknown(%08x)", (UINT)level);
return unknown;
}
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) {
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;
ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
+ 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 = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref + 1);
+ 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 WINAPI IDirectSoundImpl_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
+static HRESULT IDirectSoundImpl_Create(
+ LPDIRECTSOUND8 * ppDS)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
- FIXME("shouldn't be called directly\n");
- return DSERR_GENERIC;
+ 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;
}
-static HRESULT WINAPI DSOUND_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPCDSBUFFERDESC dsbd,
- LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk,
- BOOL from8)
+/*******************************************************************************
+ * IDirectSound_IUnknown
+ */
+static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
+ LPUNKNOWN iface,
+ REFIID riid,
+ LPVOID * ppobj)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- HRESULT hres = DS_OK;
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface(This->pds, riid, ppobj);
+}
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+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;
+}
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
+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 (dsbd == NULL) {
- WARN("invalid parameter: dsbd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+static const IUnknownVtbl DirectSound_Unknown_Vtbl =
+{
+ IDirectSound_IUnknown_QueryInterface,
+ IDirectSound_IUnknown_AddRef,
+ IDirectSound_IUnknown_Release
+};
- if (dsbd->dwSize != sizeof(DSBUFFERDESC) &&
- dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
- WARN("invalid parameter: dsbd\n");
+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 (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->device->primary) {
- WARN("Primary Buffer already created\n");
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->device->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER)(This->device->primary);
- } else {
- This->device->dsbd = *dsbd;
- hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->device->primary), &(This->device->dsbd));
- if (This->device->primary) {
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->device->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER)(This->device->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;
- DirectSoundDevice *device;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
TRACE("(%p,%p)\n",This,lpDSCaps);
+ return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
+}
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- device = This->device;
+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);
+}
- if (device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+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);
+}
- if (lpDSCaps == NULL) {
- WARN("invalid parameter: lpDSCaps = NULL\n");
- return DSERR_INVALIDPARAM;
- }
+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);
+}
- /* 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 = device->drvcaps.dwFlags;
- if (TRACE_ON(dsound)) {
- TRACE("(flags=0x%08lx:\n",lpDSCaps->dwFlags);
- _dump_DSCAPS(lpDSCaps->dwFlags);
- DPRINTF(")\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;
+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 IDirectSoundImpl_DuplicateSoundBuffer(
- LPDIRECTSOUND8 iface,
- LPDIRECTSOUNDBUFFER psb,
- LPLPDIRECTSOUNDBUFFER ppdsb)
+static HRESULT WINAPI IDirectSound_IDirectSound_SetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ DWORD config)
{
- IDirectSoundBufferImpl* pdsb;
- IDirectSoundBufferImpl* dsb;
- HRESULT hres = DS_OK;
- int size;
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
+ IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
+ TRACE("(%p,0x%08x)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
+}
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+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);
+}
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+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
+};
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+static HRESULT IDirectSound_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds)
+{
+ IDirectSound_IDirectSound * pdsds;
+ TRACE("(%p,%p)\n",pds,ppds);
- if (psb == NULL) {
- WARN("invalid parameter: psb == NULL\n");
+ if (ppds == NULL) {
+ ERR("invalid parameter: ppds == NULL\n");
return DSERR_INVALIDPARAM;
}
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
+ if (pds == NULL) {
+ ERR("invalid parameter: pds == NULL\n");
+ *ppds = NULL;
return DSERR_INVALIDPARAM;
}
- /* FIXME: hack to make sure we have a secondary buffer */
- if ((IDirectSoundImpl *)((SecondaryBufferImpl *)psb)->dsb == 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) {
+ pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
+ if (pdsds == NULL) {
WARN("out of memory\n");
- *ppdsb = NULL;
+ *ppds = NULL;
return DSERR_OUTOFMEMORY;
}
- CopyMemory(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
-
- if (pdsb->hwbuf) {
- TRACE("duplicating hardware buffer\n");
-
- hres = IDsDriver_DuplicateSoundBuffer(This->device->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->device->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;
- }
-
- CopyMemory(dsb->pwfx, pdsb->pwfx, size);
-
- InitializeCriticalSection(&(dsb->lock));
- dsb->lock.DebugInfo->Spare[0] = (DWORD_PTR)"DSOUNDBUFFER_lock";
-
- /* register buffer */
- hres = DSOUND_AddBuffer(This, dsb);
- if (hres != DS_OK) {
- IDirectSoundBuffer8_Release(psb);
- dsb->lock.DebugInfo->Spare[0] = 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;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
- LPDIRECTSOUND8 iface,
- HWND hwnd,
- DWORD level)
-{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
+ pdsds->lpVtbl = &DirectSound_DirectSound_Vtbl;
+ pdsds->ref = 0;
+ pdsds->pds = pds;
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+ IDirectSoundImpl_AddRef(pds);
+ *ppds = (LPDIRECTSOUND)pdsds;
- if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
- WARN("level=%s not fully supported\n",
- level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
- }
- This->device->priolevel = level;
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundImpl_Compact(
- LPDIRECTSOUND8 iface)
+/*******************************************************************************
+ * IDirectSound8_IUnknown
+ */
+static HRESULT WINAPI IDirectSound8_IUnknown_QueryInterface(
+ LPUNKNOWN iface,
+ REFIID riid,
+ LPVOID * ppobj)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p)\n",This);
+ IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface8(This->pds, riid, ppobj);
+}
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+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;
+}
- if (This->device->priolevel != DSSCL_PRIORITY) {
- WARN("incorrect priority level\n");
- return DSERR_PRIOLEVELNEEDED;
+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 DS_OK;
+ return ref;
}
-static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- LPDWORD lpdwSpeakerConfig)
+static const IUnknownVtbl DirectSound8_Unknown_Vtbl =
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p, %p)\n",This,lpdwSpeakerConfig);
+ IDirectSound8_IUnknown_QueryInterface,
+ IDirectSound8_IUnknown_AddRef,
+ IDirectSound8_IUnknown_Release
+};
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
+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 (lpdwSpeakerConfig == NULL) {
- WARN("invalid parameter: lpdwSpeakerConfig == NULL\n");
+ if (pds == NULL) {
+ ERR("invalid parameter: pds == NULL\n");
+ *ppunk = NULL;
return DSERR_INVALIDPARAM;
}
- WARN("not fully functional\n");
- *lpdwSpeakerConfig = This->device->speaker_config;
- return DS_OK;
-}
+ pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
+ if (pdsunk == NULL) {
+ WARN("out of memory\n");
+ *ppunk = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
-static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- DWORD config)
-{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
+ pdsunk->lpVtbl = &DirectSound8_Unknown_Vtbl;
+ pdsunk->ref = 0;
+ pdsunk->pds = pds;
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
+ IDirectSoundImpl_AddRef(pds);
+ *ppunk = (LPUNKNOWN)pdsunk;
- This->device->speaker_config = config;
- WARN("not fully functional\n");
return DS_OK;
}
-static HRESULT WINAPI IDirectSoundImpl_Initialize(
- LPDIRECTSOUND8 iface,
- LPCGUID lpcGUID)
+/*******************************************************************************
+ * IDirectSound8_IDirectSound
+ */
+static HRESULT WINAPI IDirectSound8_IDirectSound_QueryInterface(
+ LPDIRECTSOUND iface,
+ REFIID riid,
+ LPVOID * ppobj)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- DirectSoundDevice *device = This->device;
- HRESULT hr = DS_OK;
- unsigned wod, wodn;
- BOOLEAN found = FALSE;
- GUID devGUID;
- TRACE("(%p,%s)\n",This,debugstr_guid(lpcGUID));
+ IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface8(This->pds, riid, ppobj);
+}
- if (device != NULL) {
- WARN("already initialized\n");
- return DSERR_ALREADYINITIALIZED;
+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;
+}
- /* 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];
- device->ref++;
- This->device = 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;
- }
- }
-
- This->device = device;
- device->guid = devGUID;
-
- /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
- WineWaveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&device->driver, 0);
-
- /* Disable the direct sound driver to force emulation if requested. */
- if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
- device->driver = NULL;
-
- /* Get driver description */
- if (device->driver) {
- hr = IDsDriver_GetDriverDesc(device->driver,&(device->drvdesc));
- if (hr != DS_OK) {
- WARN("IDsDriver_GetDriverDesc failed\n");
- return hr;
- }
- } else {
- /* if no DirectSound interface available, use WINMM API instead */
- device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
- }
-
- device->drvdesc.dnDevNode = wod;
-
- /* 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 (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- {
- DWORD flags = CALLBACK_FUNCTION;
-
- /* disable direct sound if requested */
- if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
- flags |= WAVE_DIRECTSOUND;
-
- hr = mmErr(waveOutOpen(&(device->hwo),
- device->drvdesc.dnDevNode, device->pwfx,
- (DWORD_PTR)DSOUND_callback, (DWORD)device,
- flags));
- if (hr != DS_OK) {
- WARN("waveOutOpen failed\n");
- return hr;
- }
- }
-
- if (device->driver) {
- hr = IDsDriver_Open(device->driver);
- if (hr != DS_OK) {
- WARN("IDsDriver_Open failed\n");
- return hr;
- }
-
- /* 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;
- device->drvcaps.dwPrimaryBuffers = 1;
- }
-
- hr = DSOUND_PrimaryCreate(device);
- if (hr == DS_OK) {
- DSOUND_renderer[device->drvdesc.dnDevNode] = device;
- timeBeginPeriod(DS_TIME_RES);
- DSOUND_renderer[device->drvdesc.dnDevNode]->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
- (DWORD_PTR)DSOUND_renderer[device->drvdesc.dnDevNode], TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- } else {
- WARN("DSOUND_PrimaryCreate failed\n");
- }
-
- return hr;
+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 IDirectSoundImpl_VerifyCertification(
- LPDIRECTSOUND8 iface,
- LPDWORD pdwCertified)
+static HRESULT WINAPI IDirectSound8_IDirectSound_GetCaps(
+ LPDIRECTSOUND iface,
+ LPDSCAPS lpDSCaps)
{
- IDirectSoundImpl *This = (IDirectSoundImpl *)iface;
- TRACE("(%p, %p)\n",This,pdwCertified);
-
- if (This->device == NULL) {
- WARN("not initialized\n");
- return DSERR_UNINITIALIZED;
- }
-
- if (This->device->drvcaps.dwFlags & DSCAPS_CERTIFIED)
- *pdwCertified = DS_CERTIFIED;
- else
- *pdwCertified = DS_UNCERTIFIED;
- return DS_OK;
+ IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+ return DirectSoundDevice_GetCaps(((IDirectSoundImpl *)This->pds)->device, lpDSCaps);
}
-static const 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
-};
-
-static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice)
+static HRESULT WINAPI IDirectSound8_IDirectSound_DuplicateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
{
- 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->driver = NULL;
- device->priolevel = DSSCL_NORMAL;
- device->fraglen = 0;
- device->hwbuf = NULL;
- device->buffer = NULL;
- device->buflen = 0;
- device->writelead = 0;
- device->state = STATE_STOPPED;
- device->nrofbuffers = 0;
- device->buffers = NULL;
- device->primary = NULL;
- device->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
- device->tmp_buffer = NULL;
- device->tmp_buffer_len = 0;
-
- /* 3D listener initial parameters */
- device->listener = NULL;
- 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 = 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;
-
- InitializeCriticalSection(&(device->mixlock));
- device->mixlock.DebugInfo->Spare[0] = (DWORD_PTR)"DSOUND_mixlock";
-
- RtlInitializeResource(&(device->buffer_list_lock));
-
- *ppDevice = device;
-
- return DS_OK;
+ IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ return DirectSoundDevice_DuplicateSoundBuffer(((IDirectSoundImpl *)This->pds)->device,psb,ppdsb);
}
-static ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
+static HRESULT WINAPI IDirectSound8_IDirectSound_SetCooperativeLevel(
+ LPDIRECTSOUND iface,
+ HWND hwnd,
+ DWORD level)
{
- int i;
- HRESULT hr;
- TRACE("(%p) ref was %lu\n", device, device->ref);
-
- device->ref--;
- if (device->ref == 0) {
- timeKillEvent(device->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(&(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]);
- }
+ IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
+ TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
+ return DirectSoundDevice_SetCooperativeLevel(((IDirectSoundImpl *)This->pds)->device, hwnd, level);
+}
- if (device->primary) {
- WARN("primary buffer not released\n");
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)device->primary);
- }
+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);
+}
- hr = DSOUND_PrimaryDestroy(device);
- if (hr != DS_OK)
- WARN("DSOUND_PrimaryDestroy failed\n");
+static HRESULT WINAPI IDirectSound8_IDirectSound_GetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return DirectSoundDevice_GetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,lpdwSpeakerConfig);
+}
- if (device->driver)
- IDsDriver_Close(device->driver);
+static HRESULT WINAPI IDirectSound8_IDirectSound_SetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ DWORD config)
+{
+ IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
+ TRACE("(%p,0x%08x)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(((IDirectSoundImpl *)This->pds)->device,config);
+}
- if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(device->hwo);
+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);
+}
- if (device->driver)
- IDsDriver_Release(device->driver);
+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
+};
- DSOUND_renderer[device->drvdesc.dnDevNode] = NULL;
+static HRESULT IDirectSound8_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds)
+{
+ IDirectSound8_IDirectSound * pdsds;
+ TRACE("(%p,%p)\n",pds,ppds);
- HeapFree(GetProcessHeap(),0,device->tmp_buffer);
- 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);
+ if (ppds == NULL) {
+ ERR("invalid parameter: ppds == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- return device->ref;
-}
-HRESULT WINAPI IDirectSoundImpl_Create(
- LPDIRECTSOUND8 * ppDS)
-{
- IDirectSoundImpl* pDS;
- TRACE("(%p)\n",ppDS);
+ if (pds == NULL) {
+ ERR("invalid parameter: pds == NULL\n");
+ *ppds = NULL;
+ return DSERR_INVALIDPARAM;
+ }
- /* Allocate memory */
- pDS = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
- if (pDS == NULL) {
+ pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
+ if (pdsds == NULL) {
WARN("out of memory\n");
- *ppDS = NULL;
+ *ppds = NULL;
return DSERR_OUTOFMEMORY;
}
- pDS->lpVtbl = &IDirectSoundImpl_Vtbl;
- pDS->ref = 0;
- pDS->device = NULL;
+ pdsds->lpVtbl = &DirectSound8_DirectSound_Vtbl;
+ pdsds->ref = 0;
+ pdsds->pds = pds;
- *ppDS = (LPDIRECTSOUND8)pDS;
+ IDirectSoundImpl_AddRef(pds);
+ *ppds = (LPDIRECTSOUND)pdsds;
return DS_OK;
}
/*******************************************************************************
- * IDirectSound_IUnknown
+ * IDirectSound8_IDirectSound8
*/
-static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
- LPUNKNOWN iface,
+static HRESULT WINAPI IDirectSound8_IDirectSound8_QueryInterface(
+ LPDIRECTSOUND8 iface,
REFIID riid,
LPVOID * ppobj)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)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(
- LPUNKNOWN iface)
+static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(
+ LPDIRECTSOUND8 iface)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
+ TRACE("(%p) ref was %d\n", This, ref - 1);
return ref;
}
-static ULONG WINAPI IDirectSound_IUnknown_Release(
- LPUNKNOWN iface)
+static ULONG WINAPI IDirectSound8_IDirectSound8_Release(
+ LPDIRECTSOUND8 iface)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
+ IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref + 1);
+ 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 const IUnknownVtbl DirectSound_Unknown_Vtbl =
+static HRESULT WINAPI IDirectSound8_IDirectSound8_CreateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
{
- IDirectSound_IUnknown_QueryInterface,
- IDirectSound_IUnknown_AddRef,
- IDirectSound_IUnknown_Release
+ 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
};
-HRESULT WINAPI IDirectSound_IUnknown_Create(
+static HRESULT IDirectSound8_IDirectSound8_Create(
LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk)
+ 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;
+ return E_NOINTERFACE;
+ }
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ hr = IDirectSoundImpl_Create(&pDS);
+ if (hr == DS_OK) {
+ hr = IDirectSound_IDirectSound_Create(pDS, ppDS);
+ if (*ppDS)
+ IDirectSound_IDirectSound_AddRef(*ppDS);
+ else {
+ WARN("IDirectSound_IDirectSound_Create failed\n");
+ IDirectSound8_Release(pDS);
+ }
+ } else {
+ WARN("IDirectSoundImpl_Create failed\n");
+ *ppDS = 0;
+ }
+
+ return hr;
+}
+
+/*******************************************************************************
+ * DirectSoundCreate (DSOUND.1)
+ *
+ * Creates and initializes a DirectSound interface.
+ *
+ * PARAMS
+ * lpcGUID [I] Address of the GUID that identifies the sound device.
+ * ppDS [O] Address of a variable to receive the interface pointer.
+ * pUnkOuter [I] Must be NULL.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
+ * DSERR_NODRIVER, DSERR_OUTOFMEMORY
+ */
+HRESULT WINAPI DirectSoundCreate(
+ LPCGUID lpcGUID,
+ LPDIRECTSOUND *ppDS,
+ IUnknown *pUnkOuter)
{
- IDirectSound_IUnknown * pdsunk;
- TRACE("(%p,%p)\n",pds,ppunk);
+ HRESULT hr;
+ LPDIRECTSOUND pDS;
- if (ppunk == NULL) {
- ERR("invalid parameter: ppunk == NULL\n");
+ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
+
+ if (ppDS == NULL) {
+ WARN("invalid parameter: ppDS == NULL\n");
return DSERR_INVALIDPARAM;
}
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppunk = NULL;
+ if (pUnkOuter != NULL) {
+ WARN("invalid parameter: pUnkOuter != NULL\n");
+ *ppDS = 0;
return DSERR_INVALIDPARAM;
}
- pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
- if (pdsunk == NULL) {
- WARN("out of memory\n");
- *ppunk = NULL;
- return DSERR_OUTOFMEMORY;
+ 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;
+ }
}
- pdsunk->lpVtbl = &DirectSound_Unknown_Vtbl;
- pdsunk->ref = 0;
- pdsunk->pds = pds;
-
- IDirectSoundImpl_AddRef(pds);
- *ppunk = (LPUNKNOWN)pdsunk;
+ *ppDS = pDS;
- return DS_OK;
+ return hr;
}
-/*******************************************************************************
- * IDirectSound_IDirectSound
- */
-static HRESULT WINAPI IDirectSound_IDirectSound_QueryInterface(
- LPDIRECTSOUND iface,
+HRESULT DSOUND_Create8(
REFIID riid,
- LPVOID * ppobj)
+ LPDIRECTSOUND8 *ppDS)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
- return DSOUND_QueryInterface(This->pds, riid, ppobj);
-}
+ LPDIRECTSOUND8 pDS;
+ HRESULT hr;
+ TRACE("(%s, %p)\n", debugstr_guid(riid), ppDS);
-static ULONG WINAPI IDirectSound_IDirectSound_AddRef(
- LPDIRECTSOUND iface)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
- return ref;
-}
+ if (!IsEqualIID(riid, &IID_IUnknown) &&
+ !IsEqualIID(riid, &IID_IDirectSound) &&
+ !IsEqualIID(riid, &IID_IDirectSound8)) {
+ *ppDS = 0;
+ return E_NOINTERFACE;
+ }
-static ULONG WINAPI IDirectSound_IDirectSound_Release(
- LPDIRECTSOUND iface)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref + 1);
- if (!ref) {
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
+ /* 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 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 DSOUND_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk,FALSE);
+ return hr;
}
-static HRESULT WINAPI IDirectSound_IDirectSound_GetCaps(
- LPDIRECTSOUND iface,
- LPDSCAPS lpDSCaps)
+/*******************************************************************************
+ * DirectSoundCreate8 (DSOUND.11)
+ *
+ * Creates and initializes a DirectSound8 interface.
+ *
+ * PARAMS
+ * lpcGUID [I] Address of the GUID that identifies the sound device.
+ * ppDS [O] Address of a variable to receive the interface pointer.
+ * pUnkOuter [I] Must be NULL.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
+ * DSERR_NODRIVER, DSERR_OUTOFMEMORY
+ */
+HRESULT WINAPI DirectSoundCreate8(
+ LPCGUID lpcGUID,
+ LPDIRECTSOUND8 *ppDS,
+ IUnknown *pUnkOuter)
{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
-}
+ HRESULT hr;
+ LPDIRECTSOUND8 pDS;
-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);
-}
+ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
-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 IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
-}
+ if (ppDS == NULL) {
+ WARN("invalid parameter: ppDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
-static HRESULT WINAPI IDirectSound_IDirectSound_Compact(
- LPDIRECTSOUND iface)
-{
- IDirectSound_IDirectSound *This = (IDirectSound_IDirectSound *)iface;
- TRACE("(%p)\n", This);
- return IDirectSoundImpl_Compact(This->pds);
-}
+ if (pUnkOuter != NULL) {
+ WARN("invalid parameter: pUnkOuter != NULL\n");
+ *ppDS = 0;
+ return DSERR_INVALIDPARAM;
+ }
-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);
-}
+ 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;
+ }
+ }
-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);
-}
+ *ppDS = pDS;
-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);
+ return hr;
}
-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
-};
-
-HRESULT WINAPI IDirectSound_IDirectSound_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND * ppds)
+/*******************************************************************************
+ * DirectSoundDevice
+ */
+static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice)
{
- IDirectSound_IDirectSound * pdsds;
- TRACE("(%p,%p)\n",pds,ppds);
+ DirectSoundDevice * device;
+ TRACE("(%p)\n", ppDevice);
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
- return DSERR_INVALIDPARAM;
+ /* Allocate memory */
+ device = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DirectSoundDevice));
+ if (device == NULL) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
}
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppds = NULL;
- return DSERR_INVALIDPARAM;
- }
+ device->ref = 1;
+ device->priolevel = DSSCL_NORMAL;
+ device->state = STATE_STOPPED;
+ device->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
- pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
- if (pdsds == NULL) {
+ /* 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");
- *ppds = NULL;
+ HeapFree(GetProcessHeap(),0,device);
return DSERR_OUTOFMEMORY;
}
- pdsds->lpVtbl = &DirectSound_DirectSound_Vtbl;
- pdsds->ref = 0;
- pdsds->pds = pds;
+ /* 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;
- IDirectSoundImpl_AddRef(pds);
- *ppds = (LPDIRECTSOUND)pdsds;
+ InitializeCriticalSection(&(device->mixlock));
+ device->mixlock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundDevice.mixlock");
- return DS_OK;
-}
+ RtlInitializeResource(&(device->buffer_list_lock));
-/*******************************************************************************
- * 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);
-}
+ *ppDevice = device;
-static ULONG WINAPI IDirectSound8_IUnknown_AddRef(
- LPUNKNOWN iface)
-{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
- return ref;
+ return DS_OK;
}
-static ULONG WINAPI IDirectSound8_IUnknown_Release(
- LPUNKNOWN iface)
+static ULONG DirectSoundDevice_AddRef(DirectSoundDevice * device)
{
- IDirectSound_IUnknown *This = (IDirectSound_IUnknown *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref + 1);
- if (!ref) {
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
- }
+ ULONG ref = InterlockedIncrement(&(device->ref));
+ TRACE("(%p) ref was %d\n", device, ref - 1);
return ref;
}
-static const IUnknownVtbl DirectSound8_Unknown_Vtbl =
-{
- IDirectSound8_IUnknown_QueryInterface,
- IDirectSound8_IUnknown_AddRef,
- IDirectSound8_IUnknown_Release
-};
-
-HRESULT WINAPI IDirectSound8_IUnknown_Create(
- LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk)
+ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
{
- IDirectSound8_IUnknown * pdsunk;
- TRACE("(%p,%p)\n",pds,ppunk);
+ 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);
- if (ppunk == NULL) {
- ERR("invalid parameter: ppunk == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ /* 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));
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppunk = NULL;
- return DSERR_INVALIDPARAM;
- }
+ /* 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]);
+ }
- pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
- if (pdsunk == NULL) {
- WARN("out of memory\n");
- *ppunk = NULL;
- return DSERR_OUTOFMEMORY;
- }
+ if (device->primary) {
+ WARN("primary buffer not released\n");
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)device->primary);
+ }
- pdsunk->lpVtbl = &DirectSound8_Unknown_Vtbl;
- pdsunk->ref = 0;
- pdsunk->pds = pds;
+ hr = DSOUND_PrimaryDestroy(device);
+ if (hr != DS_OK)
+ WARN("DSOUND_PrimaryDestroy failed\n");
- IDirectSoundImpl_AddRef(pds);
- *ppunk = (LPUNKNOWN)pdsunk;
+ if (device->driver)
+ IDsDriver_Close(device->driver);
- return DS_OK;
-}
+ if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ waveOutClose(device->hwo);
-/*******************************************************************************
- * 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);
-}
+ if (device->driver)
+ IDsDriver_Release(device->driver);
-static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(
- LPDIRECTSOUND iface)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
- return ref;
-}
+ DSOUND_renderer[device->drvdesc.dnDevNode] = NULL;
-static ULONG WINAPI IDirectSound8_IDirectSound_Release(
- LPDIRECTSOUND iface)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref + 1);
- if (!ref) {
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
+ 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;
}
-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 DSOUND_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk,TRUE);
-}
-
-static HRESULT WINAPI IDirectSound8_IDirectSound_GetCaps(
- LPDIRECTSOUND iface,
+HRESULT DirectSoundDevice_GetCaps(
+ DirectSoundDevice * device,
LPDSCAPS lpDSCaps)
{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
-}
+ TRACE("(%p,%p)\n",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 IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
-}
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
-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 IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
-}
+ if (lpDSCaps == NULL) {
+ WARN("invalid parameter: lpDSCaps = NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound_Compact(
- LPDIRECTSOUND iface)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p)\n", This);
- return IDirectSoundImpl_Compact(This->pds);
-}
+ /* check if there is enough room */
+ if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
+ WARN("invalid parameter: lpDSCaps->dwSize = %d\n", lpDSCaps->dwSize);
+ return DSERR_INVALIDPARAM;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound_GetSpeakerConfig(
- LPDIRECTSOUND iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
-}
+ 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;
-static HRESULT WINAPI IDirectSound8_IDirectSound_SetSpeakerConfig(
- LPDIRECTSOUND iface,
- DWORD config)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
- return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
-}
+ /* driver doesn't have these */
+ lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
+ lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
-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 IDirectSoundImpl_Initialize(This->pds,lpcGuid);
+ return DS_OK;
}
-static const IDirectSoundVtbl DirectSound8_DirectSound_Vtbl =
+HRESULT DirectSoundDevice_Initialize(DirectSoundDevice ** ppDevice, LPCGUID lpcGUID)
{
- 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
-};
+ 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;
+ }
-HRESULT WINAPI IDirectSound8_IDirectSound_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND * ppds)
-{
- IDirectSound8_IDirectSound * pdsds;
- TRACE("(%p,%p)\n",pds,ppds);
+ /* Default device? */
+ if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
+ lpcGUID = &DSDEVID_DefaultPlayback;
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
+ if (GetDeviceID(lpcGUID, &devGUID) != DS_OK) {
+ WARN("invalid parameter: lpcGUID\n");
return DSERR_INVALIDPARAM;
}
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppds = NULL;
- return DSERR_INVALIDPARAM;
+ /* Enumerate WINMM audio devices and find the one we want */
+ wodn = waveOutGetNumDevs();
+ if (!wodn) {
+ WARN("no driver\n");
+ return DSERR_NODRIVER;
}
- pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
- if (pdsds == NULL) {
- WARN("out of memory\n");
- *ppds = NULL;
- return DSERR_OUTOFMEMORY;
+ for (wod=0; wod<wodn; wod++) {
+ if (IsEqualGUID( &devGUID, &DSOUND_renderer_guids[wod])) {
+ found = TRUE;
+ break;
+ }
}
- pdsds->lpVtbl = &DirectSound8_DirectSound_Vtbl;
- pdsds->ref = 0;
- pdsds->pds = pds;
+ if (found == FALSE) {
+ WARN("No device found matching given ID!\n");
+ return DSERR_NODRIVER;
+ }
- IDirectSoundImpl_AddRef(pds);
- *ppds = (LPDIRECTSOUND)pdsds;
+ 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;
+ }
+ }
- return DS_OK;
-}
+ *ppDevice = device;
+ device->guid = devGUID;
+ device->driver = NULL;
-/*******************************************************************************
- * 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);
-}
+ device->drvdesc.dnDevNode = wod;
+ hr = DSOUND_ReopenDevice(device, FALSE);
+ if (FAILED(hr))
+ {
+ WARN("DSOUND_ReopenDevice failed: %08x\n", hr);
+ return hr;
+ }
-static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(
- LPDIRECTSOUND8 iface)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
- return ref;
-}
+ 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));
+ }
-static ULONG WINAPI IDirectSound8_IDirectSound8_Release(
- LPDIRECTSOUND8 iface)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- ULONG ref = InterlockedDecrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref + 1);
- if (!ref) {
- IDirectSoundImpl_Release(This->pds);
- HeapFree(GetProcessHeap(), 0, This);
- TRACE("(%p) released\n", This);
+ 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 ref;
+
+ return hr;
}
-static HRESULT WINAPI IDirectSound8_IDirectSound8_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,
+HRESULT DirectSoundDevice_CreateSoundBuffer(
+ DirectSoundDevice * device,
LPCDSBUFFERDESC dsbd,
LPLPDIRECTSOUNDBUFFER ppdsb,
- LPUNKNOWN lpunk)
+ LPUNKNOWN lpunk,
+ BOOL from8)
{
- 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);
-}
+ HRESULT hres = DS_OK;
+ TRACE("(%p,%p,%p,%p)\n",device,dsbd,ppdsb,lpunk);
-static HRESULT WINAPI IDirectSound8_IDirectSound8_GetCaps(
- LPDIRECTSOUND8 iface,
- LPDSCAPS lpDSCaps)
-{
- IDirectSound8_IDirectSound *This = (IDirectSound8_IDirectSound *)iface;
- TRACE("(%p,%p)\n",This,lpDSCaps);
- return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
-}
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
-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 IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
-}
+ if (dsbd == NULL) {
+ WARN("invalid parameter: dsbd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
-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 IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
-}
+ if (dsbd->dwSize != sizeof(DSBUFFERDESC) &&
+ dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
+ WARN("invalid parameter: dsbd\n");
+ return DSERR_INVALIDPARAM;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound8_Compact(
- LPDIRECTSOUND8 iface)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p)\n", This);
- return IDirectSoundImpl_Compact(This->pds);
-}
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+ *ppdsb = NULL;
-static HRESULT WINAPI IDirectSound8_IDirectSound8_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- LPDWORD lpdwSpeakerConfig)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
- return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
-}
+ 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);
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound8_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- DWORD config)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p,0x%08lx)\n",This,config);
- return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
-}
+ 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)
+ {
+ 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)))
+ {
+ 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);
-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 IDirectSoundImpl_Initialize(This->pds,lpcGuid);
-}
+ if (from8 && (dsbd->dwFlags & DSBCAPS_CTRL3D) && (dsbd->lpwfxFormat->nChannels != 1)) {
+ WARN("invalid parameter: 3D buffer format must be mono\n");
+ return DSERR_INVALIDPARAM;
+ }
-static HRESULT WINAPI IDirectSound8_IDirectSound8_VerifyCertification(
- LPDIRECTSOUND8 iface,
- LPDWORD pdwCertified)
-{
- IDirectSound8_IDirectSound8 *This = (IDirectSound8_IDirectSound8 *)iface;
- TRACE("(%p, %p)\n", This, pdwCertified);
- return IDirectSoundImpl_VerifyCertification(This->pds,pdwCertified);
+ 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;
}
-static const IDirectSound8Vtbl DirectSound8_DirectSound8_Vtbl =
+HRESULT DirectSoundDevice_DuplicateSoundBuffer(
+ DirectSoundDevice * device,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
{
- 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
-};
+ HRESULT hres = DS_OK;
+ IDirectSoundBufferImpl* dsb;
+ TRACE("(%p,%p,%p)\n",device,psb,ppdsb);
-HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND8 * ppds)
-{
- IDirectSound8_IDirectSound8 * pdsds;
- TRACE("(%p,%p)\n",pds,ppds);
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
- if (ppds == NULL) {
- ERR("invalid parameter: ppds == NULL\n");
+ if (psb == NULL) {
+ WARN("invalid parameter: psb == NULL\n");
return DSERR_INVALIDPARAM;
}
- if (pds == NULL) {
- ERR("invalid parameter: pds == NULL\n");
- *ppds = NULL;
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
return DSERR_INVALIDPARAM;
}
- pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
- if (pdsds == NULL) {
- WARN("out of memory\n");
- *ppds = NULL;
- return DSERR_OUTOFMEMORY;
+ /* make sure we have a secondary buffer */
+ if ((PrimaryBufferImpl *)psb == device->primary) {
+ WARN("trying to duplicate primary buffer\n");
+ *ppdsb = NULL;
+ return DSERR_INVALIDCALL;
}
- pdsds->lpVtbl = &DirectSound8_DirectSound8_Vtbl;
- pdsds->ref = 0;
- pdsds->pds = pds;
+ /* duplicate the actual buffer implementation */
+ hres = IDirectSoundBufferImpl_Duplicate(device, &dsb,
+ ((SecondaryBufferImpl *)psb)->dsb);
- IDirectSoundImpl_AddRef(pds);
- *ppds = (LPDIRECTSOUND8)pdsds;
+ 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 DS_OK;
+ return hres;
}
-HRESULT WINAPI DSOUND_Create(
- LPDIRECTSOUND *ppDS,
- IUnknown *pUnkOuter)
+HRESULT DirectSoundDevice_SetCooperativeLevel(
+ DirectSoundDevice * device,
+ HWND hwnd,
+ DWORD level)
{
- LPDIRECTSOUND8 pDS;
- HRESULT hr;
- TRACE("(%p,%p)\n",ppDS,pUnkOuter);
+ TRACE("(%p,%p,%s)\n",device,hwnd,dumpCooperativeLevel(level));
- /* Get dsound configuration */
- setup_dsound_options();
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
- 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;
+ if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
+ WARN("level=%s not fully supported\n",
+ level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
}
- return hr;
+ device->priolevel = level;
+ return DS_OK;
}
-/*******************************************************************************
- * DirectSoundCreate (DSOUND.1)
- *
- * Creates and initializes a DirectSound interface.
- *
- * PARAMS
- * lpcGUID [I] Address of the GUID that identifies the sound device.
- * ppDS [O] Address of a variable to receive the interface pointer.
- * pUnkOuter [I] Must be NULL.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
- * DSERR_NODRIVER, DSERR_OUTOFMEMORY
- */
-HRESULT WINAPI DirectSoundCreate(
- LPCGUID lpcGUID,
- LPDIRECTSOUND *ppDS,
- IUnknown *pUnkOuter)
+HRESULT DirectSoundDevice_Compact(
+ DirectSoundDevice * device)
{
- HRESULT hr;
- LPDIRECTSOUND pDS;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
-
- if (ppDS == NULL) {
- WARN("invalid parameter: ppDS == NULL\n");
- return DSERR_INVALIDPARAM;
- }
+ TRACE("(%p)\n", device);
- if (pUnkOuter != NULL) {
- WARN("invalid parameter: pUnkOuter != NULL\n");
- *ppDS = 0;
- return DSERR_INVALIDPARAM;
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
}
- hr = DSOUND_Create(&pDS, pUnkOuter);
- 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;
- }
+ if (device->priolevel < DSSCL_PRIORITY) {
+ WARN("incorrect priority level\n");
+ return DSERR_PRIOLEVELNEEDED;
}
- *ppDS = pDS;
-
- return hr;
+ return DS_OK;
}
-HRESULT WINAPI DSOUND_Create8(
- LPDIRECTSOUND8 *ppDS,
- IUnknown *pUnkOuter)
+HRESULT DirectSoundDevice_GetSpeakerConfig(
+ DirectSoundDevice * device,
+ LPDWORD lpdwSpeakerConfig)
{
- LPDIRECTSOUND8 pDS;
- HRESULT hr;
- TRACE("(%p,%p)\n",ppDS,pUnkOuter);
+ TRACE("(%p, %p)\n", device, lpdwSpeakerConfig);
- /* Get dsound configuration */
- setup_dsound_options();
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
+ }
- 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;
+ if (lpdwSpeakerConfig == NULL) {
+ WARN("invalid parameter: lpdwSpeakerConfig == NULL\n");
+ return DSERR_INVALIDPARAM;
}
- return hr;
+ WARN("not fully functional\n");
+ *lpdwSpeakerConfig = device->speaker_config;
+ return DS_OK;
}
-/*******************************************************************************
- * DirectSoundCreate8 (DSOUND.11)
- *
- * Creates and initializes a DirectSound8 interface.
- *
- * PARAMS
- * lpcGUID [I] Address of the GUID that identifies the sound device.
- * ppDS [O] Address of a variable to receive the interface pointer.
- * pUnkOuter [I] Must be NULL.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
- * DSERR_NODRIVER, DSERR_OUTOFMEMORY
- */
-HRESULT WINAPI DirectSoundCreate8(
- LPCGUID lpcGUID,
- LPDIRECTSOUND8 *ppDS,
- IUnknown *pUnkOuter)
+HRESULT DirectSoundDevice_SetSpeakerConfig(
+ DirectSoundDevice * device,
+ DWORD config)
{
- HRESULT hr;
- LPDIRECTSOUND8 pDS;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
+ TRACE("(%p,0x%08x)\n",device,config);
- if (ppDS == NULL) {
- WARN("invalid parameter: ppDS == NULL\n");
- return DSERR_INVALIDPARAM;
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
}
- if (pUnkOuter != NULL) {
- WARN("invalid parameter: pUnkOuter != NULL\n");
- *ppDS = 0;
- return DSERR_INVALIDPARAM;
- }
+ device->speaker_config = config;
+ WARN("not fully functional\n");
+ return DS_OK;
+}
- hr = DSOUND_Create8(&pDS, pUnkOuter);
- 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;
- }
+static HRESULT DirectSoundDevice_VerifyCertification(
+ DirectSoundDevice * device,
+ LPDWORD pdwCertified)
+{
+ TRACE("(%p, %p)\n",device,pdwCertified);
+
+ if (device == NULL) {
+ WARN("not initialized\n");
+ return DSERR_UNINITIALIZED;
}
- *ppDS = pDS;
+ if (device->drvcaps.dwFlags & DSCAPS_CERTIFIED)
+ *pdwCertified = DS_CERTIFIED;
+ else
+ *pdwCertified = DS_UNCERTIFIED;
- return hr;
+ 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->device->buffer_list_lock), TRUE);
+ RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
- if (pDS->device->buffers)
- newbuffers = HeapReAlloc(GetProcessHeap(),0,pDS->device->buffers,sizeof(IDirectSoundBufferImpl*)*(pDS->device->nrofbuffers+1));
+ if (device->buffers)
+ newbuffers = HeapReAlloc(GetProcessHeap(),0,device->buffers,sizeof(IDirectSoundBufferImpl*)*(device->nrofbuffers+1));
else
- newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(pDS->device->nrofbuffers+1));
+ newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl*)*(device->nrofbuffers+1));
if (newbuffers) {
- pDS->device->buffers = newbuffers;
- pDS->device->buffers[pDS->device->nrofbuffers] = pDSB;
- pDS->device->nrofbuffers++;
- TRACE("buffer count is now %d\n", pDS->device->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->device->nrofbuffers);
+ ERR("out of memory for buffer list! Current buffer count is %d\n", device->nrofbuffers);
hr = DSERR_OUTOFMEMORY;
}
- RtlReleaseResource(&(pDS->device->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->device->buffer_list_lock), TRUE);
+ RtlAcquireResourceExclusive(&(device->buffer_list_lock), TRUE);
- for (i = 0; i < pDS->device->nrofbuffers; i++)
- if (pDS->device->buffers[i] == pDSB)
+ for (i = 0; i < device->nrofbuffers; i++)
+ if (device->buffers[i] == pDSB)
break;
- if (i < pDS->device->nrofbuffers) {
+ if (i < device->nrofbuffers) {
/* Put the last buffer of the list in the (now empty) position */
- pDS->device->buffers[i] = pDS->device->buffers[pDS->device->nrofbuffers - 1];
- pDS->device->nrofbuffers--;
- pDS->device->buffers = HeapReAlloc(GetProcessHeap(),0,pDS->device->buffers,sizeof(LPDIRECTSOUNDBUFFER8)*pDS->device->nrofbuffers);
- TRACE("buffer count is now %d\n", pDS->device->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->device->nrofbuffers == 0) {
- HeapFree(GetProcessHeap(),0,pDS->device->buffers);
- pDS->device->buffers = NULL;
+ if (device->nrofbuffers == 0) {
+ HeapFree(GetProcessHeap(),0,device->buffers);
+ device->buffers = NULL;
}
- RtlReleaseResource(&(pDS->device->buffer_list_lock));
+ RtlReleaseResource(&(device->buffer_list_lock));
return hr;
}