revised dsound DirectSound/DirectSound8 split patch
Robert Reif
reif at earthlink.net
Thu Jul 1 06:01:53 CDT 2004
Sorry, had wrong second file attached.
Wine currently defines DirectSoundCreate and DirectSoundCreate8
as the same function and only supplies a DirectSound8 implementation.
They are two separate functions and interfaces in windows.
This patch separates DirectSoundCreate8 into two functions and
adds a IDirectSound implementation. Adds proper COM behavior
for QueryInterface for IDirectSound and IDirectSound8. The
DirectSound code is moved from dsound_main.c to a new file
dsound.c.
Fixes a bug in the dsound.h header file for IDirectSound8
CreateSoundBuffer and DuplicateSoundBuffer.
Adds new tests for proper COM behavior and enables some
commented out code for tests that work on windows . Adds
new tests for IDirectSound8.
To Do:
Do the same thing for DirectSoundCapture and DirectSoundBuffer.
Fix DirectSound to Release properly even when buffers are active.
-------------- next part --------------
Index: dlls/dsound/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/dsound/Makefile.in,v
retrieving revision 1.20
diff -u -r1.20 Makefile.in
--- dlls/dsound/Makefile.in 27 Jan 2004 00:11:17 -0000 1.20
+++ dlls/dsound/Makefile.in 1 Jul 2004 00:20:18 -0000
@@ -9,6 +9,7 @@
C_SRCS = \
buffer.c \
capture.c \
+ dsound.c \
dsound_main.c \
mixer.c \
primary.c \
Index: dlls/dsound/dsound.spec
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound.spec,v
retrieving revision 1.16
diff -u -r1.16 dsound.spec
--- dlls/dsound/dsound.spec 1 Oct 2003 03:05:25 -0000 1.16
+++ dlls/dsound/dsound.spec 1 Jul 2004 00:20:18 -0000
@@ -1,4 +1,4 @@
-1 stdcall DirectSoundCreate(ptr ptr ptr) DirectSoundCreate8
+1 stdcall DirectSoundCreate(ptr ptr ptr)
2 stdcall DirectSoundEnumerateA(ptr ptr)
3 stdcall DirectSoundEnumerateW(ptr ptr)
4 stdcall -private DllCanUnloadNow() DSOUND_DllCanUnloadNow
Index: dlls/dsound/dsound_main.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_main.c,v
retrieving revision 1.99
diff -u -r1.99 dsound_main.c
--- dlls/dsound/dsound_main.c 19 May 2004 03:22:56 -0000 1.99
+++ dlls/dsound/dsound_main.c 1 Jul 2004 00:20:18 -0000
@@ -438,773 +438,6 @@
return DS_OK;
}
-
-static void _dump_DSBCAPS(DWORD xmask) {
- struct {
- DWORD mask;
- char *name;
- } flags[] = {
-#define FE(x) { x, #x },
- FE(DSBCAPS_PRIMARYBUFFER)
- FE(DSBCAPS_STATIC)
- FE(DSBCAPS_LOCHARDWARE)
- FE(DSBCAPS_LOCSOFTWARE)
- FE(DSBCAPS_CTRL3D)
- FE(DSBCAPS_CTRLFREQUENCY)
- FE(DSBCAPS_CTRLPAN)
- FE(DSBCAPS_CTRLVOLUME)
- FE(DSBCAPS_CTRLPOSITIONNOTIFY)
- FE(DSBCAPS_CTRLDEFAULT)
- FE(DSBCAPS_CTRLALL)
- FE(DSBCAPS_STICKYFOCUS)
- FE(DSBCAPS_GLOBALFOCUS)
- FE(DSBCAPS_GETCURRENTPOSITION2)
- FE(DSBCAPS_MUTE3DATMAXDISTANCE)
-#undef FE
- };
- int i;
-
- for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
- if ((flags[i].mask & xmask) == flags[i].mask)
- DPRINTF("%s ",flags[i].name);
-}
-
-/*******************************************************************************
- * IDirectSound
- */
-
-static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
- LPDIRECTSOUND8 iface,HWND hwnd,DWORD level
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,%08lx,%ld(%s))\n",This,(DWORD)hwnd,level,
- level == DSSCL_NORMAL ? "DSSCL_NORMAL" :
- level == DSSCL_PRIORITY ? "DSSCL_PRIORITY" :
- level == DSSCL_EXCLUSIVE ? "DSSCL_EXCLUSIVE" :
- level == DSSCL_WRITEPRIMARY ? "DSSCL_WRITEPRIMARY" : "Unknown");
-
- if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
- FIXME("level=%s not fully supported\n",
- level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
- }
-
- This->priolevel = level;
-
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,LPCDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER8 ppdsb,LPUNKNOWN lpunk
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- LPWAVEFORMATEX wfex;
- HRESULT hres = DS_OK;
-
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (dsbd == NULL) {
- WARN("invalid parameter: dsbd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (dsbd->dwSize != sizeof(DSBUFFERDESC) && dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
- WARN("invalid parameter: dsbd\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- 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);
- }
-
- wfex = dsbd->lpwfxFormat;
-
- if (wfex)
- TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
- "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
- wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
- wfex->nAvgBytesPerSec, wfex->nBlockAlign,
- wfex->wBitsPerSample, wfex->cbSize);
-
- if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
- if (This->primary) {
- WARN("Primary Buffer already created\n");
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
- } else {
- This->dsbd = *dsbd;
- hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
- if (This->primary) {
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
- } else
- WARN("PrimaryBufferImpl_Create failed\n");
- }
- } else {
- IDirectSoundBufferImpl * dsb;
- hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
- if (dsb) {
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
- } else
- WARN("SecondaryBufferImpl_Create failed\n");
- } else
- WARN("IDirectSoundBufferImpl_Create failed\n");
- }
-
- return hres;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
- LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 psb,LPLPDIRECTSOUNDBUFFER8 ppdsb
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- IDirectSoundBufferImpl* pdsb;
- IDirectSoundBufferImpl* dsb;
- HRESULT hres = DS_OK;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (psb == NULL) {
- WARN("invalid parameter: psb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* FIXME: hack to make sure we have a secondary buffer */
- if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
- ERR("trying to duplicate primary buffer\n");
- *ppdsb = NULL;
- return DSERR_INVALIDCALL;
- }
-
- pdsb = ((SecondaryBufferImpl *)psb)->dsb;
-
- dsb = (IDirectSoundBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
-
- if (dsb == NULL) {
- WARN("out of memory\n");
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
-
- if (pdsb->hwbuf) {
- TRACE("duplicating hardware buffer\n");
-
- hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
- if (hres != DS_OK) {
- TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
- dsb->hwbuf = NULL;
- /* allocate buffer */
- if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
- dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
- if (dsb->buffer == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
- if (dsb->buffer->memory == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb);
- *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;
- memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
- InitializeCriticalSection(&(dsb->lock));
- /* register buffer */
- RtlAcquireResourceExclusive(&(This->lock), TRUE);
- {
- IDirectSoundBufferImpl **newbuffers;
- if (This->buffers)
- newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
- else
- newbuffers = (IDirectSoundBufferImpl**)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
-
- if (newbuffers) {
- This->buffers = newbuffers;
- This->buffers[This->nrofbuffers] = dsb;
- This->nrofbuffers++;
- TRACE("buffer count is now %d\n", This->nrofbuffers);
- } else {
- ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers);
- IDirectSoundBuffer8_Release(psb);
- DeleteCriticalSection(&(dsb->lock));
- RtlReleaseResource(&(This->lock));
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = 0;
- return DSERR_OUTOFMEMORY;
- }
- }
- RtlReleaseResource(&(This->lock));
- IDirectSound_AddRef(iface);
- 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_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS lpDSCaps) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,%p)\n",This,lpDSCaps);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (lpDSCaps == NULL) {
- WARN("invalid parameter: lpDSCaps = NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* check is there is enough room */
- if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
- WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
- lpDSCaps->dwSize, sizeof(*lpDSCaps));
- return DSERR_INVALIDPARAM;
- }
-
- lpDSCaps->dwFlags = This->drvcaps.dwFlags;
- TRACE("(flags=0x%08lx)\n",lpDSCaps->dwFlags);
-
- lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
- lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
-
- lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
-
- lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
- lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
- lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
-
- lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
- lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
- lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
-
- lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
- lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
- lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
-
- lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
- lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
- lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
-
- lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
-
- lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
-
- lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
-
- /* driver doesn't have these */
- lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
-
- lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
-
- return DS_OK;
-}
-
-static ULONG WINAPI IDirectSoundImpl_AddRef(LPDIRECTSOUND8 iface) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
-}
-
-static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) {
- ICOM_THIS(IDirectSoundImpl,iface);
- ULONG ulReturn;
-
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
- HRESULT hres;
- UINT i;
-
- timeKillEvent(This->timerID);
- timeEndPeriod(DS_TIME_RES);
- /* wait for timer to expire */
- Sleep(DS_TIME_RES+1);
-
- RtlAcquireResourceShared(&(This->lock), TRUE);
-
- if (This->buffers) {
- for( i=0;i<This->nrofbuffers;i++)
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
- }
-
- RtlReleaseResource(&(This->lock));
-
- if (This->primary) {
- WARN("primary buffer not released\n");
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
- }
-
- hres = DSOUND_PrimaryDestroy(This);
- if (hres != DS_OK)
- WARN("DSOUND_PrimaryDestroy failed\n");
-
- if (This->driver)
- IDsDriver_Close(This->driver);
-
- if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(This->hwo);
-
- if (This->driver)
- IDsDriver_Release(This->driver);
-
- RtlDeleteResource(&This->lock);
- DeleteCriticalSection(&This->mixlock);
- HeapFree(GetProcessHeap(),0,This);
- dsound = NULL;
- TRACE("(%p) released\n",This);
- }
-
- return ulReturn;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,DWORD config
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,0x%08lx)\n",This,config);
-
- This->speaker_config = config;
-
- WARN("not fully functional\n");
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
- LPDIRECTSOUND8 iface,REFIID riid,LPVOID *ppobj
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-
- if (ppobj == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
-
- *ppobj = NULL; /* assume failure */
-
- if ( IsEqualGUID(riid, &IID_IUnknown) ||
- IsEqualGUID(riid, &IID_IDirectSound) ||
- IsEqualGUID(riid, &IID_IDirectSound8) ) {
- IDirectSound8_AddRef((LPDIRECTSOUND8)This);
- *ppobj = This;
- return S_OK;
- }
-
- if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
- WARN("app requested IDirectSound3DListener on dsound object\n");
- return E_NOINTERFACE;
- }
-
- FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
- return E_NOINTERFACE;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_Compact(
- LPDIRECTSOUND8 iface)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p)\n", This);
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- LPDWORD lpdwSpeakerConfig)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
-
- if (lpdwSpeakerConfig == NULL) {
- WARN("invalid parameter\n");
- return DSERR_INVALIDPARAM;
- }
-
- WARN("not fully functional\n");
-
- *lpdwSpeakerConfig = This->speaker_config;
-
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_Initialize(
- LPDIRECTSOUND8 iface,
- LPCGUID lpcGuid)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
- LPDIRECTSOUND8 iface,
- LPDWORD pdwCertified)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p, %p)\n", This, pdwCertified);
- *pdwCertified = DS_CERTIFIED;
- return DS_OK;
-}
-
-static ICOM_VTABLE(IDirectSound8) dsvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- IDirectSoundImpl_QueryInterface,
- IDirectSoundImpl_AddRef,
- IDirectSoundImpl_Release,
- IDirectSoundImpl_CreateSoundBuffer,
- IDirectSoundImpl_GetCaps,
- IDirectSoundImpl_DuplicateSoundBuffer,
- IDirectSoundImpl_SetCooperativeLevel,
- IDirectSoundImpl_Compact,
- IDirectSoundImpl_GetSpeakerConfig,
- IDirectSoundImpl_SetSpeakerConfig,
- IDirectSoundImpl_Initialize,
- IDirectSoundImpl_VerifyCertification
-};
-
-
-/*******************************************************************************
- * 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 DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
-{
- IDirectSoundImpl** ippDS=(IDirectSoundImpl**)ppDS;
- PIDSDRIVER drv = NULL;
- unsigned wod, wodn;
- HRESULT err = DSERR_INVALIDPARAM;
- GUID devGuid;
- BOOLEAN found = FALSE;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ippDS,pUnkOuter);
-
- if (ippDS == NULL) {
- WARN("invalid parameter: ippDS == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* Get dsound configuration */
- setup_dsound_options();
-
- /* Default device? */
- if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
- lpcGUID = &DSDEVID_DefaultPlayback;
-
- if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
- WARN("invalid parameter: lpcGUID\n");
- *ippDS = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (dsound) {
- if (IsEqualGUID(&devGuid, &dsound->guid) ) {
- /* FIXME: this is wrong, need to create a new instance */
- ERR("dsound already opened\n");
- IDirectSound_AddRef((LPDIRECTSOUND)dsound);
- *ippDS = dsound;
- return DS_OK;
- } else {
- ERR("different dsound already opened\n");
- }
- }
-
- /* Enumerate WINMM audio devices and find the one we want */
- wodn = waveOutGetNumDevs();
- if (!wodn) {
- WARN("no driver\n");
- *ippDS = NULL;
- return DSERR_NODRIVER;
- }
-
- TRACE(" expecting GUID %s.\n", debugstr_guid(&devGuid));
-
- for (wod=0; wod<wodn; wod++) {
- GUID guid;
- err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
- if (err != DS_OK) {
- WARN("waveOutMessage failed; err=%lx\n",err);
- *ippDS = NULL;
- return err;
- }
- TRACE("got GUID %s for wod %d.\n", debugstr_guid(&guid), wod);
- if (IsEqualGUID( &devGuid, &guid) ) {
- err = DS_OK;
- found = TRUE;
- break;
- }
- }
-
- if (err != DS_OK) {
- WARN("invalid parameter\n");
- *ippDS = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (found == FALSE) {
- WARN("No device found matching given ID - trying with default one !\n");
- wod = ds_default_playback;
- }
-
- /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
- waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
-
- /* Disable the direct sound driver to force emulation if requested. */
- if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
- drv = NULL;
-
- /* Allocate memory */
- *ippDS = (IDirectSoundImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
- if (*ippDS == NULL) {
- WARN("out of memory\n");
- return DSERR_OUTOFMEMORY;
- }
-
- (*ippDS)->lpVtbl = &dsvt;
- (*ippDS)->ref = 1;
-
- (*ippDS)->driver = drv;
- (*ippDS)->priolevel = DSSCL_NORMAL;
- (*ippDS)->fraglen = 0;
- (*ippDS)->hwbuf = NULL;
- (*ippDS)->buffer = NULL;
- (*ippDS)->buflen = 0;
- (*ippDS)->writelead = 0;
- (*ippDS)->state = STATE_STOPPED;
- (*ippDS)->nrofbuffers = 0;
- (*ippDS)->buffers = NULL;
- (*ippDS)->primary = NULL;
- (*ippDS)->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
-
- /* 3D listener initial parameters */
- (*ippDS)->listener = NULL;
- (*ippDS)->ds3dl.dwSize = sizeof(DS3DLISTENER);
- (*ippDS)->ds3dl.vPosition.x = 0.0;
- (*ippDS)->ds3dl.vPosition.y = 0.0;
- (*ippDS)->ds3dl.vPosition.z = 0.0;
- (*ippDS)->ds3dl.vVelocity.x = 0.0;
- (*ippDS)->ds3dl.vVelocity.y = 0.0;
- (*ippDS)->ds3dl.vVelocity.z = 0.0;
- (*ippDS)->ds3dl.vOrientFront.x = 0.0;
- (*ippDS)->ds3dl.vOrientFront.y = 0.0;
- (*ippDS)->ds3dl.vOrientFront.z = 1.0;
- (*ippDS)->ds3dl.vOrientTop.x = 0.0;
- (*ippDS)->ds3dl.vOrientTop.y = 1.0;
- (*ippDS)->ds3dl.vOrientTop.z = 0.0;
- (*ippDS)->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
- (*ippDS)->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
- (*ippDS)->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
-
- (*ippDS)->prebuf = ds_snd_queue_max;
- (*ippDS)->guid = devGuid;
-
- /* Get driver description */
- if (drv) {
- err = IDsDriver_GetDriverDesc(drv,&((*ippDS)->drvdesc));
- if (err != DS_OK) {
- WARN("IDsDriver_GetDriverDesc failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- } else {
- /* if no DirectSound interface available, use WINMM API instead */
- (*ippDS)->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
- }
-
- (*ippDS)->drvdesc.dnDevNode = wod;
-
- /* Set default wave format (may need it for waveOutOpen) */
- (*ippDS)->wfx.wFormatTag = WAVE_FORMAT_PCM;
- /* We rely on the sound driver to return the actual sound format of
- * the device if it does not support 22050x8x2 and is given the
- * WAVE_DIRECTSOUND flag.
- */
- (*ippDS)->wfx.nSamplesPerSec = 22050;
- (*ippDS)->wfx.wBitsPerSample = 8;
- (*ippDS)->wfx.nChannels = 2;
- (*ippDS)->wfx.nBlockAlign = (*ippDS)->wfx.wBitsPerSample * (*ippDS)->wfx.nChannels / 8;
- (*ippDS)->wfx.nAvgBytesPerSec = (*ippDS)->wfx.nSamplesPerSec * (*ippDS)->wfx.nBlockAlign;
- (*ippDS)->wfx.cbSize = 0;
-
- /* If the driver requests being opened through MMSYSTEM
- * (which is recommended by the DDK), it is supposed to happen
- * before the DirectSound interface is opened */
- if ((*ippDS)->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- {
- DWORD flags = CALLBACK_FUNCTION;
-
- /* disable direct sound if requested */
- if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
- flags |= WAVE_DIRECTSOUND;
-
- err = mmErr(waveOutOpen(&((*ippDS)->hwo),
- (*ippDS)->drvdesc.dnDevNode, &((*ippDS)->wfx),
- (DWORD)DSOUND_callback, (DWORD)(*ippDS),
- flags));
- if (err != DS_OK) {
- WARN("waveOutOpen failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- }
-
- if (drv) {
- err = IDsDriver_Open(drv);
- if (err != DS_OK) {
- WARN("IDsDriver_Open failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
-
- /* the driver is now open, so it's now allowed to call GetCaps */
- err = IDsDriver_GetCaps(drv,&((*ippDS)->drvcaps));
- if (err != DS_OK) {
- WARN("IDsDriver_GetCaps failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- } else {
- WAVEOUTCAPSA woc;
- err = mmErr(waveOutGetDevCapsA((*ippDS)->drvdesc.dnDevNode, &woc, sizeof(woc)));
- if (err != DS_OK) {
- WARN("waveOutGetDevCaps failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- ZeroMemory(&(*ippDS)->drvcaps, sizeof((*ippDS)->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)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- (*ippDS)->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)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- (*ippDS)->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)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- (*ippDS)->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)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
- }
- if (ds_emuldriver)
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
- (*ippDS)->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
- (*ippDS)->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
- (*ippDS)->drvcaps.dwPrimaryBuffers = 1;
- }
-
- (*ippDS)->volpan.lVolume = 0;
- (*ippDS)->volpan.lPan = 0;
- DSOUND_RecalcVolPan(&((*ippDS)->volpan));
-
- InitializeCriticalSection(&((*ippDS)->mixlock));
- RtlInitializeResource(&((*ippDS)->lock));
-
- if (!dsound) {
- HRESULT hres;
- dsound = (*ippDS);
- hres = DSOUND_PrimaryCreate(dsound);
- if (hres != DS_OK) {
- WARN("DSOUND_PrimaryCreate failed\n");
- return hres;
- }
- timeBeginPeriod(DS_TIME_RES);
- dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
- (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- }
-
- return DS_OK;
-}
-
-
/*******************************************************************************
* DirectSound ClassFactory
*/
Index: dlls/dsound/dsound_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_private.h,v
retrieving revision 1.15
diff -u -r1.15 dsound_private.h
--- dlls/dsound/dsound_private.h 17 Mar 2004 01:44:15 -0000 1.15
+++ dlls/dsound/dsound_private.h 1 Jul 2004 00:20:18 -0000
@@ -44,20 +44,25 @@
/*****************************************************************************
* Predeclare the interface implementation structures
*/
-typedef struct IDirectSoundImpl IDirectSoundImpl;
-typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
-typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
+typedef struct IDirectSoundImpl IDirectSoundImpl;
+typedef struct IDirectSound_IUnknown IDirectSound_IUnknown;
+typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound;
+typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown;
+typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound;
+typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8;
+typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
+typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
-typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
-typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
+typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
+typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
-typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
-typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
-typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
-typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
-typedef struct PrimaryBufferImpl PrimaryBufferImpl;
-typedef struct SecondaryBufferImpl SecondaryBufferImpl;
-typedef struct IClassFactoryImpl IClassFactoryImpl;
+typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
+typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
+typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
+typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
+typedef struct PrimaryBufferImpl PrimaryBufferImpl;
+typedef struct SecondaryBufferImpl SecondaryBufferImpl;
+typedef struct IClassFactoryImpl IClassFactoryImpl;
/*****************************************************************************
* IDirectSound implementation structure
@@ -95,6 +100,10 @@
IDirectSound3DListenerImpl* listener;
DS3DLISTENER ds3dl;
BOOL ds3dl_need_recalc;
+
+ LPUNKNOWN pUnknown;
+ LPDIRECTSOUND pDS;
+ LPDIRECTSOUND8 pDS8;
};
/* reference counted buffer memory for duplicated buffer memory */
@@ -103,6 +112,66 @@
DWORD ref;
LPBYTE memory;
} BufferMemory;
+
+HRESULT WINAPI IDirectSoundImpl_Create(
+ LPCGUID lpcGUID,
+ LPDIRECTSOUND8 * ppds);
+
+/*****************************************************************************
+ * IDirectSound COM components
+ */
+struct IDirectSound_IUnknown {
+ ICOM_VFIELD(IUnknown);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk);
+
+struct IDirectSound_IDirectSound {
+ ICOM_VFIELD(IDirectSound);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds);
+
+/*****************************************************************************
+ * IDirectSound8 COM components
+ */
+struct IDirectSound8_IUnknown {
+ ICOM_VFIELD(IUnknown);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound8_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk);
+
+struct IDirectSound8_IDirectSound {
+ ICOM_VFIELD(IDirectSound);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound8_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds);
+
+struct IDirectSound8_IDirectSound8 {
+ ICOM_VFIELD(IDirectSound8);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND8 * ppds);
/*****************************************************************************
* IDirectSoundBuffer implementation structure
Index: dlls/dsound/tests/dsound.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/tests/dsound.c,v
retrieving revision 1.21
diff -u -r1.21 dsound.c
--- dlls/dsound/tests/dsound.c 17 Jun 2004 23:03:11 -0000 1.21
+++ dlls/dsound/tests/dsound.c 1 Jul 2004 00:20:19 -0000
@@ -36,6 +36,7 @@
#include "windef.h"
#include "wingdi.h"
#include "dsound.h"
+#include "dxerr9.h"
#include "dsound_test.h"
@@ -46,32 +47,51 @@
LPDIRECTSOUND dso=NULL;
DSCAPS dscaps;
int ref;
+ IUnknown * unknown;
+ IDirectSound * ds;
+ IDirectSound8 * ds8;
/* DSOUND: Error: Invalid interface buffer */
rc=DirectSoundCreate(lpGuid,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: 0x%lx\n",rc);
+ ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: %s\n",DXGetErrorString9(rc));
/* Create the DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc!=DS_OK)
return rc;
+ /* Try to Query for objects */
+ rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
+ ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound_Release(unknown);
+
+ rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
+ ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound_Release(ds);
+
+ rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
+ ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound8_Release(ds8);
+
/* DSOUND: Error: Invalid caps buffer */
rc=IDirectSound_GetCaps(dso,0);
- ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
ZeroMemory(&dscaps, sizeof(dscaps));
/* DSOUND: Error: Invalid caps buffer */
rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
dscaps.dwSize=sizeof(dscaps);
/* DSOUND: Running on a certified driver */
rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
trace(" DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
@@ -84,17 +104,15 @@
if (ref!=0)
return DSERR_GENERIC;
-#if 0
- /* FIXME: this works on windows */
/* Create a DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
LPDIRECTSOUND dso1=NULL;
/* Create a second DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso1,NULL);
- ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
/* Release the second DirectSound object */
ref=IDirectSound_Release(dso1);
@@ -109,7 +127,96 @@
return DSERR_GENERIC;
} else
return rc;
-#endif
+
+ return DS_OK;
+}
+
+static HRESULT test_dsound8(LPGUID lpGuid)
+{
+ HRESULT rc;
+ LPDIRECTSOUND8 dso=NULL;
+ DSCAPS dscaps;
+ int ref;
+ IUnknown * unknown;
+ IDirectSound * ds;
+ IDirectSound8 * ds8;
+
+ /* DSOUND: Error: Invalid interface buffer */
+ rc=DirectSoundCreate8(lpGuid,0,NULL);
+ ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8 should have failed: %s\n",DXGetErrorString9(rc));
+
+ /* Create the DirectSound8 object */
+ rc=DirectSoundCreate8(lpGuid,&dso,NULL);
+ ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
+ if (rc!=DS_OK)
+ return rc;
+
+ /* Try to Query for objects */
+ rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
+ ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound8_Release(unknown);
+
+ rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
+ ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound_Release(ds);
+
+ rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
+ ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound8_Release(ds8);
+
+ /* DSOUND: Error: Invalid caps buffer */
+ rc=IDirectSound8_GetCaps(dso,0);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
+
+ ZeroMemory(&dscaps, sizeof(dscaps));
+
+ /* DSOUND: Error: Invalid caps buffer */
+ rc=IDirectSound8_GetCaps(dso,&dscaps);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
+
+ dscaps.dwSize=sizeof(dscaps);
+
+ /* DSOUND: Running on a certified driver */
+ rc=IDirectSound8_GetCaps(dso,&dscaps);
+ ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK) {
+ trace(" DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
+ dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
+ dscaps.dwMaxSecondarySampleRate);
+ }
+
+ /* Release the DirectSound8 object */
+ ref=IDirectSound8_Release(dso);
+ ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+ if (ref!=0)
+ return DSERR_GENERIC;
+
+ /* Create a DirectSound8 object */
+ rc=DirectSoundCreate8(lpGuid,&dso,NULL);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK) {
+ LPDIRECTSOUND8 dso1=NULL;
+
+ /* Create a second DirectSound8 object */
+ rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
+ ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK) {
+ /* Release the second DirectSound8 object */
+ ref=IDirectSound8_Release(dso1);
+ ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
+ ok(dso!=dso1,"DirectSound8 objects should be unique: dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
+ }
+
+ /* Release the first DirectSound8 object */
+ ref=IDirectSound8_Release(dso);
+ ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
+ if (ref!=0)
+ return DSERR_GENERIC;
+ } else
+ return rc;
return DS_OK;
}
@@ -294,6 +401,7 @@
{
trace("*** Testing %s - %s\n",lpcstrDescription,lpcstrModule);
test_dsound(lpGuid);
+ test_dsound8(lpGuid);
test_primary(lpGuid);
test_secondary(lpGuid);
Index: include/dsound.h
===================================================================
RCS file: /home/wine/wine/include/dsound.h,v
retrieving revision 1.44
diff -u -r1.44 dsound.h
--- include/dsound.h 19 Apr 2004 02:58:45 -0000 1.44
+++ include/dsound.h 1 Jul 2004 00:20:33 -0000
@@ -456,9 +456,9 @@
#define INTERFACE IDirectSound8
#define IDirectSound8_METHODS \
IUnknown_METHODS \
- STDMETHOD(CreateSoundBuffer)(THIS_ LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer, IUnknown *pUnkOuter) PURE; \
+ STDMETHOD(CreateSoundBuffer)(THIS_ LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, IUnknown *pUnkOuter) PURE; \
STDMETHOD(GetCaps)(THIS_ LPDSCAPS lpDSCaps) PURE; \
- STDMETHOD(DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER8 lpDsbOriginal, LPLPDIRECTSOUNDBUFFER8 lplpDsbDuplicate) PURE; \
+ STDMETHOD(DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER lpDsbOriginal, LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate) PURE; \
STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwLevel) PURE; \
STDMETHOD(Compact)(THIS) PURE; \
STDMETHOD(GetSpeakerConfig)(THIS_ LPDWORD lpdwSpeakerConfig) PURE; \
-------------- next part --------------
diff -u -N wine.cvs/dlls/dsound/dsound.c wine/dlls/dsound/dsound.c
--- dlls/dsound/dsound.c 1969-12-31 19:00:00.000000000 -0500
+++ dlls/dsound/dsound.c 2004-06-30 19:33:32.000000000 -0400
@@ -0,0 +1,1674 @@
+/* DirectSound
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998 Rob Riggs
+ * Copyright 2000-2002 TransGaming Technologies, Inc.
+ * Copyright 2004 Robert Reif
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+//#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "mmsystem.h"
+#include "winternl.h"
+#include "mmddk.h"
+#include "wine/windef16.h"
+#include "wine/winbase16.h"
+#include "wine/debug.h"
+#include "dsound.h"
+#include "dsdriver.h"
+#include "dsound_private.h"
+#include "dsconf.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dsound);
+
+static ULONG WINAPI IDirectSound_IUnknown_AddRef(LPUNKNOWN iface);
+static ULONG WINAPI IDirectSound_IDirectSound_AddRef(LPDIRECTSOUND iface);
+static ULONG WINAPI IDirectSound8_IUnknown_AddRef(LPUNKNOWN iface);
+static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(LPDIRECTSOUND iface);
+static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(LPDIRECTSOUND8 iface);
+
+static const char * dumpCooperativeLevel(DWORD level)
+{
+ static char unknown[32];
+#define LE(x) case x: return #x
+ switch (level) {
+ LE(DSSCL_NORMAL);
+ LE(DSSCL_PRIORITY);
+ LE(DSSCL_EXCLUSIVE);
+ LE(DSSCL_WRITEPRIMARY);
+ }
+#undef LE
+ sprintf(unknown, "Unknown(%08lx)", level);
+ return unknown;
+}
+
+static void _dump_DSBCAPS(DWORD xmask) {
+ struct {
+ DWORD mask;
+ char *name;
+ } flags[] = {
+#define FE(x) { x, #x },
+ FE(DSBCAPS_PRIMARYBUFFER)
+ FE(DSBCAPS_STATIC)
+ FE(DSBCAPS_LOCHARDWARE)
+ FE(DSBCAPS_LOCSOFTWARE)
+ FE(DSBCAPS_CTRL3D)
+ FE(DSBCAPS_CTRLFREQUENCY)
+ FE(DSBCAPS_CTRLPAN)
+ FE(DSBCAPS_CTRLVOLUME)
+ FE(DSBCAPS_CTRLPOSITIONNOTIFY)
+ FE(DSBCAPS_CTRLDEFAULT)
+ FE(DSBCAPS_CTRLALL)
+ FE(DSBCAPS_STICKYFOCUS)
+ FE(DSBCAPS_GLOBALFOCUS)
+ FE(DSBCAPS_GETCURRENTPOSITION2)
+ FE(DSBCAPS_MUTE3DATMAXDISTANCE)
+#undef FE
+ };
+ int i;
+
+ for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+ if ((flags[i].mask & xmask) == flags[i].mask)
+ DPRINTF("%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("shouldnt be called directly\n");
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DSOUND_QueryInterface(
+ LPDIRECTSOUND8 iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
+ }
+
+ if (IsEqualIID(riid, &IID_IUnknown)) {
+ if (!This->pUnknown) {
+ IDirectSound_IUnknown_Create(iface, &This->pUnknown);
+ if (!This->pUnknown) {
+ WARN("IDirectSound_IUnknown_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSound_IUnknown_AddRef(This->pUnknown);
+ *ppobj = This->pUnknown;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSound)) {
+ if (!This->pDS) {
+ IDirectSound_IDirectSound_Create(iface, &This->pDS);
+ if (!This->pDS) {
+ WARN("IDirectSound_IDirectSound_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSound_IDirectSound_AddRef(This->pDS);
+ *ppobj = This->pDS;
+ return S_OK;
+ }
+
+ *ppobj = NULL;
+ WARN("Unknown IID %s\n",debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DSOUND_QueryInterface8(
+ LPDIRECTSOUND8 iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
+ }
+
+ if (IsEqualIID(riid, &IID_IUnknown)) {
+ if (!This->pUnknown) {
+ IDirectSound8_IUnknown_Create(iface, &This->pUnknown);
+ if (!This->pUnknown) {
+ WARN("IDirectSound8_IUnknown_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSound8_IUnknown_AddRef(This->pUnknown);
+ *ppobj = This->pUnknown;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSound)) {
+ if (!This->pDS) {
+ IDirectSound8_IDirectSound_Create(iface, &This->pDS);
+ if (!This->pDS) {
+ WARN("IDirectSound8_IDirectSound_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSound8_IDirectSound_AddRef(This->pDS);
+ *ppobj = This->pDS;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
+ if (!This->pDS8) {
+ IDirectSound8_IDirectSound8_Create(iface, &This->pDS8);
+ if (!This->pDS8) {
+ WARN("IDirectSound8_IDirectSound8_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSound8_IDirectSound8_AddRef(This->pDS8);
+ *ppobj = This->pDS8;
+ return S_OK;
+ }
+
+ *ppobj = NULL;
+ WARN("Unknown IID %s\n",debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IDirectSoundImpl_AddRef(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSoundImpl_Release(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ ULONG ref;
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+
+ ref = InterlockedDecrement(&This->ref);
+ if (ref == 0) {
+ HRESULT hres;
+ UINT i;
+
+ timeKillEvent(This->timerID);
+ timeEndPeriod(DS_TIME_RES);
+ /* wait for timer to expire */
+ Sleep(DS_TIME_RES+1);
+
+ RtlAcquireResourceShared(&(This->lock), TRUE);
+
+ if (This->buffers) {
+ for( i=0;i<This->nrofbuffers;i++)
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
+ }
+
+ RtlReleaseResource(&(This->lock));
+
+ if (This->primary) {
+ WARN("primary buffer not released\n");
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
+ }
+
+ hres = DSOUND_PrimaryDestroy(This);
+ if (hres != DS_OK)
+ WARN("DSOUND_PrimaryDestroy failed\n");
+
+ if (This->driver)
+ IDsDriver_Close(This->driver);
+
+ if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ waveOutClose(This->hwo);
+
+ if (This->driver)
+ IDsDriver_Release(This->driver);
+
+ RtlDeleteResource(&This->lock);
+ DeleteCriticalSection(&This->mixlock);
+ HeapFree(GetProcessHeap(),0,This);
+ dsound = NULL;
+ TRACE("(%p) released\n",This);
+ }
+
+ return ref;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ LPWAVEFORMATEX wfex;
+ HRESULT hres = DS_OK;
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsbd == NULL) {
+ WARN("invalid parameter: dsbd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsbd->dwSize != sizeof(DSBUFFERDESC) && dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
+ WARN("invalid parameter: dsbd\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ 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);
+ }
+
+ wfex = dsbd->lpwfxFormat;
+
+ if (wfex)
+ TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
+ "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
+ wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
+ wfex->nAvgBytesPerSec, wfex->nBlockAlign,
+ wfex->wBitsPerSample, wfex->cbSize);
+
+ if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
+ if (This->primary) {
+ WARN("Primary Buffer already created\n");
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+ *ppdsb = (LPDIRECTSOUNDBUFFER)(This->primary);
+ } else {
+ This->dsbd = *dsbd;
+ hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
+ if (This->primary) {
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+ *ppdsb = (LPDIRECTSOUNDBUFFER)(This->primary);
+ } else
+ WARN("PrimaryBufferImpl_Create failed\n");
+ }
+ } else {
+ IDirectSoundBufferImpl * dsb;
+ 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");
+ }
+
+ return hres;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_GetCaps(
+ LPDIRECTSOUND8 iface,
+ LPDSCAPS lpDSCaps)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (lpDSCaps == NULL) {
+ WARN("invalid parameter: lpDSCaps = NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* check if there is enough room */
+ if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
+ WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
+ lpDSCaps->dwSize, sizeof(*lpDSCaps));
+ return DSERR_INVALIDPARAM;
+ }
+
+ TRACE("(flags=0x%08lx)\n",lpDSCaps->dwFlags);
+ lpDSCaps->dwFlags = This->drvcaps.dwFlags;
+ lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
+ lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
+ lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
+ lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
+ lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
+ lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
+ lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
+ lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
+ lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
+ lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
+ lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
+ lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
+ lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
+ lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
+ lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
+ lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
+ lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
+ lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
+
+ /* driver doesn't have these */
+ lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
+ lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ IDirectSoundBufferImpl* pdsb;
+ IDirectSoundBufferImpl* dsb;
+ HRESULT hres = DS_OK;
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (psb == NULL) {
+ WARN("invalid parameter: psb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* FIXME: hack to make sure we have a secondary buffer */
+ if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
+ WARN("trying to duplicate primary buffer\n");
+ *ppdsb = NULL;
+ return DSERR_INVALIDCALL;
+ }
+
+ pdsb = ((SecondaryBufferImpl *)psb)->dsb;
+
+ dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
+
+ if (dsb == NULL) {
+ WARN("out of memory\n");
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
+
+ if (pdsb->hwbuf) {
+ TRACE("duplicating hardware buffer\n");
+
+ hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
+ if (hres != DS_OK) {
+ TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
+ dsb->hwbuf = NULL;
+ /* allocate buffer */
+ if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
+ dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
+ if (dsb->buffer == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
+ if (dsb->buffer->memory == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb->buffer);
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+ dsb->buffer->ref = 1;
+
+ /* FIXME: copy buffer ? */
+ }
+ }
+ } else {
+ dsb->hwbuf = NULL;
+ dsb->buffer->ref++;
+ }
+
+ dsb->ref = 0;
+ dsb->state = STATE_STOPPED;
+ dsb->playpos = 0;
+ dsb->buf_mixpos = 0;
+ dsb->dsound = This;
+ dsb->ds3db = NULL;
+ dsb->iks = NULL; /* FIXME? */
+ dsb->dsb = NULL;
+ memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
+ InitializeCriticalSection(&(dsb->lock));
+ /* register buffer */
+ RtlAcquireResourceExclusive(&(This->lock), TRUE);
+ {
+ IDirectSoundBufferImpl **newbuffers;
+ if (This->buffers)
+ newbuffers = HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
+ else
+ newbuffers = HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
+
+ if (newbuffers) {
+ This->buffers = newbuffers;
+ This->buffers[This->nrofbuffers] = dsb;
+ This->nrofbuffers++;
+ TRACE("buffer count is now %d\n", This->nrofbuffers);
+ } else {
+ ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers);
+ IDirectSoundBuffer8_Release(psb);
+ DeleteCriticalSection(&(dsb->lock));
+ RtlReleaseResource(&(This->lock));
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = 0;
+ return DSERR_OUTOFMEMORY;
+ }
+ }
+ RtlReleaseResource(&(This->lock));
+ IDirectSound_AddRef(iface);
+ 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)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
+
+ if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
+ FIXME("level=%s not fully supported\n",
+ level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
+ }
+ This->priolevel = level;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_Compact(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p)\n",This);
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %p)\n",This,lpdwSpeakerConfig);
+
+ if (lpdwSpeakerConfig == NULL) {
+ WARN("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ WARN("not fully functional\n");
+ *lpdwSpeakerConfig = This->speaker_config;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ DWORD config)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,0x%08lx)\n",This,config);
+
+ This->speaker_config = config;
+ WARN("not fully functional\n");
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_Initialize(
+ LPDIRECTSOUND8 iface,
+ LPCGUID lpcGuid)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%s)\n",This,debugstr_guid(lpcGuid));
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
+ LPDIRECTSOUND8 iface,
+ LPDWORD pdwCertified)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %p)\n",This,pdwCertified);
+
+ *pdwCertified = DS_CERTIFIED;
+ return DS_OK;
+}
+
+static ICOM_VTABLE(IDirectSound8) IDirectSoundImpl_Vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IDirectSoundImpl_QueryInterface,
+ IDirectSoundImpl_AddRef,
+ IDirectSoundImpl_Release,
+ IDirectSoundImpl_CreateSoundBuffer,
+ IDirectSoundImpl_GetCaps,
+ IDirectSoundImpl_DuplicateSoundBuffer,
+ IDirectSoundImpl_SetCooperativeLevel,
+ IDirectSoundImpl_Compact,
+ IDirectSoundImpl_GetSpeakerConfig,
+ IDirectSoundImpl_SetSpeakerConfig,
+ IDirectSoundImpl_Initialize,
+ IDirectSoundImpl_VerifyCertification
+};
+
+HRESULT WINAPI IDirectSoundImpl_Create(
+ LPCGUID lpcGUID,
+ LPDIRECTSOUND8 * ppDS)
+{
+ HRESULT err = DSERR_INVALIDPARAM;
+ PIDSDRIVER drv = NULL;
+ IDirectSoundImpl* pDS;
+ unsigned wod, wodn;
+ BOOLEAN found = FALSE;
+ TRACE("(%s,%p)\n",debugstr_guid(lpcGUID),ppDS);
+
+ /* Enumerate WINMM audio devices and find the one we want */
+ wodn = waveOutGetNumDevs();
+ if (!wodn) {
+ WARN("no driver\n");
+ *ppDS = NULL;
+ return DSERR_NODRIVER;
+ }
+
+ TRACE(" expecting GUID %s.\n", debugstr_guid(lpcGUID));
+
+ for (wod=0; wod<wodn; wod++) {
+ GUID guid;
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
+ if (err != DS_OK) {
+ WARN("waveOutMessage failed; err=%lx\n",err);
+ *ppDS = NULL;
+ return err;
+ }
+ TRACE("got GUID %s for wod %d.\n", debugstr_guid(&guid), wod);
+ if (IsEqualGUID( lpcGUID, &guid)) {
+ err = DS_OK;
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (err != DS_OK) {
+ WARN("invalid parameter\n");
+ *ppDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (found == FALSE) {
+ WARN("No device found matching given ID - trying with default one !\n");
+ wod = ds_default_playback;
+ }
+
+ /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
+ waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
+
+ /* Disable the direct sound driver to force emulation if requested. */
+ if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
+ drv = NULL;
+
+ /* Allocate memory */
+ pDS = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
+ if (ppDS == NULL) {
+ WARN("out of memory\n");
+ *ppDS = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pDS->lpVtbl = &IDirectSoundImpl_Vtbl;
+ pDS->ref = 0;
+
+ pDS->driver = drv;
+ pDS->priolevel = DSSCL_NORMAL;
+ pDS->fraglen = 0;
+ pDS->hwbuf = NULL;
+ pDS->buffer = NULL;
+ pDS->buflen = 0;
+ pDS->writelead = 0;
+ pDS->state = STATE_STOPPED;
+ pDS->nrofbuffers = 0;
+ pDS->buffers = NULL;
+ pDS->primary = NULL;
+ pDS->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
+
+ /* 3D listener initial parameters */
+ pDS->listener = NULL;
+ pDS->ds3dl.dwSize = sizeof(DS3DLISTENER);
+ pDS->ds3dl.vPosition.x = 0.0;
+ pDS->ds3dl.vPosition.y = 0.0;
+ pDS->ds3dl.vPosition.z = 0.0;
+ pDS->ds3dl.vVelocity.x = 0.0;
+ pDS->ds3dl.vVelocity.y = 0.0;
+ pDS->ds3dl.vVelocity.z = 0.0;
+ pDS->ds3dl.vOrientFront.x = 0.0;
+ pDS->ds3dl.vOrientFront.y = 0.0;
+ pDS->ds3dl.vOrientFront.z = 1.0;
+ pDS->ds3dl.vOrientTop.x = 0.0;
+ pDS->ds3dl.vOrientTop.y = 1.0;
+ pDS->ds3dl.vOrientTop.z = 0.0;
+ pDS->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
+ pDS->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
+ pDS->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
+
+ pDS->prebuf = ds_snd_queue_max;
+ pDS->guid = *lpcGUID;
+
+ /* Get driver description */
+ if (drv) {
+ err = IDsDriver_GetDriverDesc(drv,&(pDS->drvdesc));
+ if (err != DS_OK) {
+ WARN("IDsDriver_GetDriverDesc failed\n");
+ HeapFree(GetProcessHeap(),0,pDS);
+ *ppDS = NULL;
+ return err;
+ }
+ } else {
+ /* if no DirectSound interface available, use WINMM API instead */
+ pDS->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
+ }
+
+ pDS->drvdesc.dnDevNode = wod;
+
+ /* Set default wave format (may need it for waveOutOpen) */
+ pDS->wfx.wFormatTag = WAVE_FORMAT_PCM;
+ /* We rely on the sound driver to return the actual sound format of
+ * the device if it does not support 22050x8x2 and is given the
+ * WAVE_DIRECTSOUND flag.
+ */
+ pDS->wfx.nSamplesPerSec = 22050;
+ pDS->wfx.wBitsPerSample = 8;
+ pDS->wfx.nChannels = 2;
+ pDS->wfx.nBlockAlign = pDS->wfx.wBitsPerSample * pDS->wfx.nChannels / 8;
+ pDS->wfx.nAvgBytesPerSec = pDS->wfx.nSamplesPerSec * pDS->wfx.nBlockAlign;
+ pDS->wfx.cbSize = 0;
+
+ /* If the driver requests being opened through MMSYSTEM
+ * (which is recommended by the DDK), it is supposed to happen
+ * before the DirectSound interface is opened */
+ if (pDS->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ {
+ DWORD flags = CALLBACK_FUNCTION;
+
+ /* disable direct sound if requested */
+ if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
+ flags |= WAVE_DIRECTSOUND;
+
+ err = mmErr(waveOutOpen(&(pDS->hwo),
+ pDS->drvdesc.dnDevNode, &(pDS->wfx),
+ (DWORD)DSOUND_callback, (DWORD)pDS,
+ flags));
+ if (err != DS_OK) {
+ WARN("waveOutOpen failed\n");
+ HeapFree(GetProcessHeap(),0,pDS);
+ *ppDS = NULL;
+ return err;
+ }
+ }
+
+ if (drv) {
+ err = IDsDriver_Open(drv);
+ if (err != DS_OK) {
+ WARN("IDsDriver_Open failed\n");
+ HeapFree(GetProcessHeap(),0,pDS);
+ *ppDS = NULL;
+ return err;
+ }
+
+ /* the driver is now open, so it's now allowed to call GetCaps */
+ err = IDsDriver_GetCaps(drv,&(pDS->drvcaps));
+ if (err != DS_OK) {
+ WARN("IDsDriver_GetCaps failed\n");
+ HeapFree(GetProcessHeap(),0,pDS);
+ *ppDS = NULL;
+ return err;
+ }
+ } else {
+ WAVEOUTCAPSA woc;
+ err = mmErr(waveOutGetDevCapsA(pDS->drvdesc.dnDevNode, &woc, sizeof(woc)));
+ if (err != DS_OK) {
+ WARN("waveOutGetDevCaps failed\n");
+ HeapFree(GetProcessHeap(),0,pDS);
+ *ppDS = NULL;
+ return err;
+ }
+ ZeroMemory(&pDS->drvcaps, sizeof(pDS->drvcaps));
+ if ((woc.dwFormats & WAVE_FORMAT_1M08) ||
+ (woc.dwFormats & WAVE_FORMAT_2M08) ||
+ (woc.dwFormats & WAVE_FORMAT_4M08) ||
+ (woc.dwFormats & WAVE_FORMAT_48M08) ||
+ (woc.dwFormats & WAVE_FORMAT_96M08)) {
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1M16) ||
+ (woc.dwFormats & WAVE_FORMAT_2M16) ||
+ (woc.dwFormats & WAVE_FORMAT_4M16) ||
+ (woc.dwFormats & WAVE_FORMAT_48M16) ||
+ (woc.dwFormats & WAVE_FORMAT_96M16)) {
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1S08) ||
+ (woc.dwFormats & WAVE_FORMAT_2S08) ||
+ (woc.dwFormats & WAVE_FORMAT_4S08) ||
+ (woc.dwFormats & WAVE_FORMAT_48S08) ||
+ (woc.dwFormats & WAVE_FORMAT_96S08)) {
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1S16) ||
+ (woc.dwFormats & WAVE_FORMAT_2S16) ||
+ (woc.dwFormats & WAVE_FORMAT_4S16) ||
+ (woc.dwFormats & WAVE_FORMAT_48S16) ||
+ (woc.dwFormats & WAVE_FORMAT_96S16)) {
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
+ pDS->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
+ }
+ if (ds_emuldriver)
+ pDS->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
+ pDS->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
+ pDS->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
+ pDS->drvcaps.dwPrimaryBuffers = 1;
+ }
+
+ pDS->volpan.lVolume = 0;
+ pDS->volpan.lPan = 0;
+ DSOUND_RecalcVolPan(&(pDS->volpan));
+
+ InitializeCriticalSection(&(pDS->mixlock));
+ RtlInitializeResource(&(pDS->lock));
+
+ *ppDS = (LPDIRECTSOUND8)pDS;
+
+ return DS_OK;
+}
+/*******************************************************************************
+ * IDirectSound_IUnknown
+ */
+static HRESULT WINAPI IDirectSound_IUnknown_QueryInterface(
+ LPUNKNOWN iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSound_IUnknown,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface(This->pds, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSound_IUnknown_AddRef(
+ LPUNKNOWN iface)
+{
+ ICOM_THIS(IDirectSound_IUnknown,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSound_IUnknown_Release(
+ LPUNKNOWN iface)
+{
+ ICOM_THIS(IDirectSound_IUnknown,iface);
+ ULONG ulReturn;
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ IDirectSoundImpl_Release(This->pds);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+ return ulReturn;
+}
+
+static ICOM_VTABLE(IUnknown) DirectSound_Unknown_Vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IDirectSound_IUnknown_QueryInterface,
+ IDirectSound_IUnknown_AddRef,
+ IDirectSound_IUnknown_Release
+};
+
+HRESULT WINAPI IDirectSound_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk)
+{
+ IDirectSound_IUnknown * pdsunk;
+ TRACE("(%p,%p)\n",pds,ppunk);
+
+ if (ppunk == NULL) {
+ ERR("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pds == NULL) {
+ ERR("invalid parameter\n");
+ *ppunk = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
+ if (pdsunk == NULL) {
+ WARN("out of memory\n");
+ *ppunk = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsunk->lpVtbl = &DirectSound_Unknown_Vtbl;
+ pdsunk->ref = 0;
+ pdsunk->pds = pds;
+
+ IDirectSoundImpl_AddRef(pds);
+ *ppunk = (LPUNKNOWN)pdsunk;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSound_IDirectSound
+ */
+static HRESULT WINAPI IDirectSound_IDirectSound_QueryInterface(
+ LPDIRECTSOUND iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface(This->pds, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSound_IDirectSound_AddRef(
+ LPDIRECTSOUND iface)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSound_IDirectSound_Release(
+ LPDIRECTSOUND iface)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ ULONG ulReturn;
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ IDirectSoundImpl_Release(This->pds);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+ return ulReturn;
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_CreateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ return IDirectSoundImpl_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_GetCaps(
+ LPDIRECTSOUND iface,
+ LPDSCAPS lpDSCaps)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+ return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_DuplicateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_SetCooperativeLevel(
+ LPDIRECTSOUND iface,
+ HWND hwnd,
+ DWORD level)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
+ return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_Compact(
+ LPDIRECTSOUND iface)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p)\n", This);
+ return IDirectSoundImpl_Compact(This->pds);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_GetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_SetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ DWORD config)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p,0x%08lx)\n",This,config);
+ return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
+}
+
+static HRESULT WINAPI IDirectSound_IDirectSound_Initialize(
+ LPDIRECTSOUND iface,
+ LPCGUID lpcGuid)
+{
+ ICOM_THIS(IDirectSound_IDirectSound,iface);
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
+}
+
+static ICOM_VTABLE(IDirectSound) DirectSound_DirectSound_Vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IDirectSound_IDirectSound_QueryInterface,
+ IDirectSound_IDirectSound_AddRef,
+ IDirectSound_IDirectSound_Release,
+ IDirectSound_IDirectSound_CreateSoundBuffer,
+ IDirectSound_IDirectSound_GetCaps,
+ IDirectSound_IDirectSound_DuplicateSoundBuffer,
+ IDirectSound_IDirectSound_SetCooperativeLevel,
+ IDirectSound_IDirectSound_Compact,
+ IDirectSound_IDirectSound_GetSpeakerConfig,
+ IDirectSound_IDirectSound_SetSpeakerConfig,
+ IDirectSound_IDirectSound_Initialize
+};
+
+HRESULT WINAPI IDirectSound_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds)
+{
+ IDirectSound_IDirectSound * pdsds;
+ TRACE("(%p,%p)\n",pds,ppds);
+
+ if (ppds == NULL) {
+ ERR("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pds == NULL) {
+ ERR("invalid parameter\n");
+ *ppds = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
+ if (pdsds == NULL) {
+ WARN("out of memory\n");
+ *ppds = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsds->lpVtbl = &DirectSound_DirectSound_Vtbl;
+ pdsds->ref = 0;
+ pdsds->pds = pds;
+
+ IDirectSoundImpl_AddRef(pds);
+ *ppds = (LPDIRECTSOUND)pdsds;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSound8_IUnknown
+ */
+static HRESULT WINAPI IDirectSound8_IUnknown_QueryInterface(
+ LPUNKNOWN iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSound_IUnknown,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface8(This->pds, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSound8_IUnknown_AddRef(
+ LPUNKNOWN iface)
+{
+ ICOM_THIS(IDirectSound_IUnknown,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSound8_IUnknown_Release(
+ LPUNKNOWN iface)
+{
+ ICOM_THIS(IDirectSound_IUnknown,iface);
+ ULONG ulReturn;
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ IDirectSoundImpl_Release(This->pds);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+ return ulReturn;
+}
+
+static ICOM_VTABLE(IUnknown) DirectSound8_Unknown_Vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IDirectSound8_IUnknown_QueryInterface,
+ IDirectSound8_IUnknown_AddRef,
+ IDirectSound8_IUnknown_Release
+};
+
+HRESULT WINAPI IDirectSound8_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk)
+{
+ IDirectSound8_IUnknown * pdsunk;
+ TRACE("(%p,%p)\n",pds,ppunk);
+
+ if (ppunk == NULL) {
+ ERR("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pds == NULL) {
+ ERR("invalid parameter\n");
+ *ppunk = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsunk));
+ if (pdsunk == NULL) {
+ WARN("out of memory\n");
+ *ppunk = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsunk->lpVtbl = &DirectSound8_Unknown_Vtbl;
+ pdsunk->ref = 0;
+ pdsunk->pds = pds;
+
+ IDirectSoundImpl_AddRef(pds);
+ *ppunk = (LPUNKNOWN)pdsunk;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSound8_IDirectSound
+ */
+static HRESULT WINAPI IDirectSound8_IDirectSound_QueryInterface(
+ LPDIRECTSOUND iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface8(This->pds, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSound8_IDirectSound_AddRef(
+ LPDIRECTSOUND iface)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSound8_IDirectSound_Release(
+ LPDIRECTSOUND iface)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ ULONG ulReturn;
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ IDirectSoundImpl_Release(This->pds);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+ return ulReturn;
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_CreateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ return IDirectSoundImpl_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_GetCaps(
+ LPDIRECTSOUND iface,
+ LPDSCAPS lpDSCaps)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+ return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_DuplicateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_SetCooperativeLevel(
+ LPDIRECTSOUND iface,
+ HWND hwnd,
+ DWORD level)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
+ return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_Compact(
+ LPDIRECTSOUND iface)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p)\n", This);
+ return IDirectSoundImpl_Compact(This->pds);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_GetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_SetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ DWORD config)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,0x%08lx)\n",This,config);
+ return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound_Initialize(
+ LPDIRECTSOUND iface,
+ LPCGUID lpcGuid)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
+}
+
+static ICOM_VTABLE(IDirectSound) DirectSound8_DirectSound_Vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ 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 WINAPI IDirectSound8_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds)
+{
+ IDirectSound8_IDirectSound * pdsds;
+ TRACE("(%p,%p)\n",pds,ppds);
+
+ if (ppds == NULL) {
+ ERR("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pds == NULL) {
+ ERR("invalid parameter\n");
+ *ppds = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsds));
+ if (pdsds == NULL) {
+ WARN("out of memory\n");
+ *ppds = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsds->lpVtbl = &DirectSound8_DirectSound_Vtbl;
+ pdsds->ref = 0;
+ pdsds->pds = pds;
+
+ IDirectSoundImpl_AddRef(pds);
+ *ppds = (LPDIRECTSOUND)pdsds;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSound8_IDirectSound8
+ */
+static HRESULT WINAPI IDirectSound8_IDirectSound8_QueryInterface(
+ LPDIRECTSOUND8 iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return DSOUND_QueryInterface8(This->pds, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSound8_IDirectSound8_AddRef(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSound8_IDirectSound8_Release(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ ULONG ulReturn;
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ IDirectSoundImpl_Release(This->pds);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+ return ulReturn;
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_CreateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ return IDirectSoundImpl_CreateSoundBuffer(This->pds,dsbd,ppdsb,lpunk);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_GetCaps(
+ LPDIRECTSOUND8 iface,
+ LPDSCAPS lpDSCaps)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound,iface);
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+ return IDirectSoundImpl_GetCaps(This->pds, lpDSCaps);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_DuplicateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ return IDirectSoundImpl_DuplicateSoundBuffer(This->pds,psb,ppdsb);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_SetCooperativeLevel(
+ LPDIRECTSOUND8 iface,
+ HWND hwnd,
+ DWORD level)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p,%08lx,%s)\n",This,(DWORD)hwnd,dumpCooperativeLevel(level));
+ return IDirectSoundImpl_SetCooperativeLevel(This->pds,hwnd,level);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_Compact(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p)\n", This);
+ return IDirectSoundImpl_Compact(This->pds);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_GetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return IDirectSoundImpl_GetSpeakerConfig(This->pds,lpdwSpeakerConfig);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_SetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ DWORD config)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p,0x%08lx)\n",This,config);
+ return IDirectSoundImpl_SetSpeakerConfig(This->pds,config);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_Initialize(
+ LPDIRECTSOUND8 iface,
+ LPCGUID lpcGuid)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return IDirectSoundImpl_Initialize(This->pds,lpcGuid);
+}
+
+static HRESULT WINAPI IDirectSound8_IDirectSound8_VerifyCertification(
+ LPDIRECTSOUND8 iface,
+ LPDWORD pdwCertified)
+{
+ ICOM_THIS(IDirectSound8_IDirectSound8,iface);
+ TRACE("(%p, %p)\n", This, pdwCertified);
+ return IDirectSoundImpl_VerifyCertification(This->pds,pdwCertified);
+}
+
+static ICOM_VTABLE(IDirectSound8) DirectSound8_DirectSound8_Vtbl =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ 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 IDirectSound8_IDirectSound8_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND8 * ppds)
+{
+ IDirectSound8_IDirectSound8 * pdsds;
+ TRACE("(%p,%p)\n",pds,ppds);
+
+ if (ppds == NULL) {
+ ERR("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pds == NULL) {
+ ERR("invalid parameter\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;
+}
+
+/*******************************************************************************
+ * 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 hr;
+ GUID devGuid;
+
+ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
+
+ if (ppDS == NULL) {
+ WARN("invalid parameter: ppDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ /* Default device? */
+ if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
+ lpcGUID = &DSDEVID_DefaultPlayback;
+
+ if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
+ WARN("invalid parameter: lpcGUID\n");
+ *ppDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsound) {
+ if (IsEqualGUID(&devGuid, &dsound->guid)) {
+ hr = IDirectSound_IDirectSound_Create((LPDIRECTSOUND8)dsound, ppDS);
+ if (*ppDS)
+ IDirectSound_IDirectSound_AddRef(*ppDS);
+ return hr;
+ } else {
+ ERR("different dsound already opened (only support one sound card at a time now)\n");
+ *ppDS = NULL;
+ hr = DSERR_ALLOCATED;
+ }
+ } else {
+ LPDIRECTSOUND8 pDS;
+ hr = IDirectSoundImpl_Create(&devGuid, &pDS);
+ if (pDS) {
+ HRESULT hres;
+ dsound = (IDirectSoundImpl*)pDS;
+ hres = DSOUND_PrimaryCreate(dsound);
+ if (hres != DS_OK) {
+ WARN("DSOUND_PrimaryCreate failed\n");
+ return hres;
+ }
+ timeBeginPeriod(DS_TIME_RES);
+ dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
+ (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+ }
+ hr = IDirectSound_IDirectSound_Create(pDS, ppDS);
+ if (*ppDS)
+ IDirectSound_IDirectSound_AddRef(*ppDS);
+ }
+
+ return hr;
+}
+
+/*******************************************************************************
+ * 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 hr;
+ GUID devGuid;
+
+ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ppDS,pUnkOuter);
+
+ if (ppDS == NULL) {
+ WARN("invalid parameter: ppDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ /* Default device? */
+ if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
+ lpcGUID = &DSDEVID_DefaultPlayback;
+
+ if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
+ WARN("invalid parameter: lpcGUID\n");
+ *ppDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsound) {
+ if (IsEqualGUID(&devGuid, &dsound->guid)) {
+ hr = IDirectSound8_IDirectSound8_Create((LPDIRECTSOUND8)dsound, ppDS);
+ if (*ppDS)
+ IDirectSound8_IDirectSound8_AddRef(*ppDS);
+ return hr;
+ } else {
+ ERR("different dsound already opened (only support one sound card at a time now)\n");
+ *ppDS = NULL;
+ hr = DSERR_ALLOCATED;
+ }
+ } else {
+ LPDIRECTSOUND8 pDS;
+ hr = IDirectSoundImpl_Create(&devGuid, &pDS);
+ if (pDS) {
+ HRESULT hres;
+ dsound = (IDirectSoundImpl*)pDS;
+ hres = DSOUND_PrimaryCreate(dsound);
+ if (hres != DS_OK) {
+ WARN("DSOUND_PrimaryCreate failed\n");
+ return hres;
+ }
+ timeBeginPeriod(DS_TIME_RES);
+ dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
+ (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+ }
+ hr = IDirectSound8_IDirectSound8_Create(pDS, ppDS);
+ if (*ppDS)
+ IDirectSound8_IDirectSound8_AddRef(*ppDS);
+ }
+
+ return hr;
+}
+
More information about the wine-patches
mailing list