[DSOUND] full duplex support
Robert Reif
reif at earthlink.net
Mon Jan 16 17:45:34 CST 2006
Add full duplex support.
Applies on top of previous dsound patch.
-------------- next part --------------
--- dlls/dsound/dsound_private.h 2006-01-16 17:44:01.000000000 -0500
+++ dlls/dsound/dsound_private.h 2006-01-09 21:53:40.000000000 -0500
@@ -54,6 +54,10 @@ typedef struct IDirectSoundBufferImpl
typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
+typedef struct IDirectSoundFullDuplex_IUnknown IDirectSoundFullDuplex_IUnknown;
+typedef struct IDirectSoundFullDuplex_IDirectSound IDirectSoundFullDuplex_IDirectSound;
+typedef struct IDirectSoundFullDuplex_IDirectSound8 IDirectSoundFullDuplex_IDirectSound8;
+typedef struct IDirectSoundFullDuplex_IDirectSoundCapture IDirectSoundFullDuplex_IDirectSoundCapture;
typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
@@ -357,14 +361,11 @@ struct DirectSoundCaptureDevice
HRESULT DirectSoundCaptureDevice_Create(
DirectSoundCaptureDevice ** ppDevice);
-
HRESULT DirectSoundCaptureDevice_Initialize(
DirectSoundCaptureDevice ** ppDevice,
LPCGUID lpcGUID);
-
ULONG DirectSoundCaptureDevice_AddRef(
DirectSoundCaptureDevice * device);
-
ULONG DirectSoundCaptureDevice_Release(
DirectSoundCaptureDevice * device);
@@ -402,12 +403,62 @@ struct IDirectSoundFullDuplexImpl
{
/* IUnknown fields */
const IDirectSoundFullDuplexVtbl *lpVtbl;
- LONG ref;
+ LONG ref;
/* IDirectSoundFullDuplexImpl fields */
+ DirectSoundDevice *renderer_device;
+ DirectSoundCaptureDevice *capture_device;
+
+ LPUNKNOWN pUnknown;
+ LPDIRECTSOUND pDS;
+ LPDIRECTSOUND8 pDS8;
+ LPDIRECTSOUNDCAPTURE pDSC;
};
/*****************************************************************************
+ * IDirectSoundFullDuplex COM components
+ */
+struct IDirectSoundFullDuplex_IUnknown {
+ const IUnknownVtbl *lpVtbl;
+ LONG ref;
+ IDirectSoundFullDuplexImpl *pdsfd;
+};
+
+HRESULT IDirectSoundFullDuplex_IUnknown_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPUNKNOWN * ppunk);
+
+struct IDirectSoundFullDuplex_IDirectSound {
+ const IDirectSoundVtbl *lpVtbl;
+ LONG ref;
+ IDirectSoundFullDuplexImpl *pdsfd;
+};
+
+HRESULT IDirectSoundFullDuplex_IDirectSound_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPDIRECTSOUND * ppds);
+
+struct IDirectSoundFullDuplex_IDirectSound8 {
+ const IDirectSound8Vtbl *lpVtbl;
+ LONG ref;
+ IDirectSoundFullDuplexImpl *pdsfd;
+};
+
+HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPDIRECTSOUND8 * ppds8);
+
+struct IDirectSoundFullDuplex_IDirectSoundCapture {
+ const IDirectSoundCaptureVtbl *lpVtbl;
+ LONG ref;
+ IDirectSoundFullDuplexImpl *pdsfd;
+};
+
+HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPDIRECTSOUNDCAPTURE8 * ppdsc8);
+
+/*****************************************************************************
* IDirectSoundNotify implementation structure
*/
struct IDirectSoundNotifyImpl
@@ -555,6 +606,10 @@ void CALLBACK DSOUND_callback(HWAVEOUT h
void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
+/* duplex.c */
+
+HRESULT DSOUND_FullDuplexCreate(LPDIRECTSOUNDFULLDUPLEX* ppDSFD, IUnknown *pUnkOuter);
+
/* capture.c */
HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(
--- dlls/dsound/duplex.c 2006-01-16 09:31:14.000000000 -0500
+++ dlls/dsound/duplex.c 2006-01-16 18:23:51.000000000 -0500
@@ -19,10 +19,6 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/*
- * TODO:
- * Implement DirectSoundFullDuplex support.
- */
#include <stdarg.h>
@@ -43,6 +39,520 @@
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
+/*******************************************************************************
+ * IUnknown
+ */
+static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
+ LPUNKNOWN iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
+ LPUNKNOWN iface)
+{
+ IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref - 1);
+ return ref;
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
+ LPUNKNOWN iface)
+{
+ IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
+ ULONG ref = InterlockedDecrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref + 1);
+ if (!ref) {
+ IDirectSound_Release(This->pdsfd->pUnknown);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
+ }
+ return ref;
+}
+
+static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
+{
+ IDirectSoundFullDuplex_IUnknown_QueryInterface,
+ IDirectSoundFullDuplex_IUnknown_AddRef,
+ IDirectSoundFullDuplex_IUnknown_Release
+};
+
+HRESULT IDirectSoundFullDuplex_IUnknown_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPUNKNOWN * ppunk)
+{
+ IDirectSoundFullDuplex_IUnknown * pdsfdunk;
+ TRACE("(%p,%p)\n",pdsfd,ppunk);
+
+ if (pdsfd == NULL) {
+ ERR("invalid parameter: pdsfd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppunk == NULL) {
+ ERR("invalid parameter: ppunk == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
+ if (pdsfdunk == NULL) {
+ WARN("out of memory\n");
+ *ppunk = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
+ pdsfdunk->ref = 0;
+ pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
+
+ *ppunk = (LPUNKNOWN)pdsfdunk;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSoundFullDuplex_IDirectSound
+ */
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_QueryInterface(
+ LPDIRECTSOUND iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_AddRef(
+ LPDIRECTSOUND iface)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref - 1);
+ return ref;
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_Release(
+ LPDIRECTSOUND iface)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ ULONG ref = InterlockedDecrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref + 1);
+ if (!ref) {
+ IDirectSound_Release(This->pdsfd->pDS);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ return DirectSoundDevice_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk,FALSE);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_GetCaps(
+ LPDIRECTSOUND iface,
+ LPDSCAPS lpDSCaps)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+ return DirectSoundDevice_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer(
+ LPDIRECTSOUND iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel(
+ LPDIRECTSOUND iface,
+ HWND hwnd,
+ DWORD level)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
+ return DirectSoundDevice_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_Compact(
+ LPDIRECTSOUND iface)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p)\n", This);
+ return DirectSoundDevice_Compact(This->pdsfd->renderer_device);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return DirectSoundDevice_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig(
+ LPDIRECTSOUND iface,
+ DWORD config)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p,0x%08lx)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(This->pdsfd->renderer_device,config);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_Initialize(
+ LPDIRECTSOUND iface,
+ LPCGUID lpcGuid)
+{
+ IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid);
+}
+
+static const IDirectSoundVtbl DirectSoundFullDuplex_DirectSound_Vtbl =
+{
+ IDirectSoundFullDuplex_IDirectSound_QueryInterface,
+ IDirectSoundFullDuplex_IDirectSound_AddRef,
+ IDirectSoundFullDuplex_IDirectSound_Release,
+ IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer,
+ IDirectSoundFullDuplex_IDirectSound_GetCaps,
+ IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer,
+ IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel,
+ IDirectSoundFullDuplex_IDirectSound_Compact,
+ IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig,
+ IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig,
+ IDirectSoundFullDuplex_IDirectSound_Initialize
+};
+
+HRESULT IDirectSoundFullDuplex_IDirectSound_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPDIRECTSOUND * ppds)
+{
+ IDirectSoundFullDuplex_IDirectSound * pdsfdds;
+ TRACE("(%p,%p)\n",pdsfd,ppds);
+
+ if (pdsfd == NULL) {
+ ERR("invalid parameter: pdsfd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppds == NULL) {
+ ERR("invalid parameter: ppds == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsfdds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds));
+ if (pdsfdds == NULL) {
+ WARN("out of memory\n");
+ *ppds = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsfdds->lpVtbl = &DirectSoundFullDuplex_DirectSound_Vtbl;
+ pdsfdds->ref = 0;
+ pdsfdds->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
+
+ *ppds = (LPDIRECTSOUND)pdsfdds;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSoundFullDuplex_IDirectSound8
+ */
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
+ LPDIRECTSOUND8 iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
+ LPDIRECTSOUND8 iface)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref - 1);
+ return ref;
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
+ LPDIRECTSOUND8 iface)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ ULONG ref = InterlockedDecrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref + 1);
+ if (!ref) {
+ IDirectSound_Release(This->pdsfd->pDS8);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPCDSBUFFERDESC dsbd,
+ LPLPDIRECTSOUNDBUFFER ppdsb,
+ LPUNKNOWN lpunk)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+ return DirectSoundDevice_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk,TRUE);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
+ LPDIRECTSOUND8 iface,
+ LPDSCAPS lpDSCaps)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+ return DirectSoundDevice_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
+ LPDIRECTSOUND8 iface,
+ LPDIRECTSOUNDBUFFER psb,
+ LPLPDIRECTSOUNDBUFFER ppdsb)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+ return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
+ LPDIRECTSOUND8 iface,
+ HWND hwnd,
+ DWORD level)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
+ return DirectSoundDevice_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
+ LPDIRECTSOUND8 iface)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p)\n", This);
+ return DirectSoundDevice_Compact(This->pdsfd->renderer_device);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+ return DirectSoundDevice_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ DWORD config)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p,0x%08lx)\n",This,config);
+ return DirectSoundDevice_SetSpeakerConfig(This->pdsfd->renderer_device,config);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
+ LPDIRECTSOUND8 iface,
+ LPCGUID lpcGuid)
+{
+ IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid);
+}
+
+static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
+{
+ IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
+ IDirectSoundFullDuplex_IDirectSound8_AddRef,
+ IDirectSoundFullDuplex_IDirectSound8_Release,
+ IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
+ IDirectSoundFullDuplex_IDirectSound8_GetCaps,
+ IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
+ IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
+ IDirectSoundFullDuplex_IDirectSound8_Compact,
+ IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
+ IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
+ IDirectSoundFullDuplex_IDirectSound8_Initialize
+};
+
+HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPDIRECTSOUND8 * ppds8)
+{
+ IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
+ TRACE("(%p,%p)\n",pdsfd,ppds8);
+
+ if (pdsfd == NULL) {
+ ERR("invalid parameter: pdsfd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppds8 == NULL) {
+ ERR("invalid parameter: ppds8 == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
+ if (pdsfdds8 == NULL) {
+ WARN("out of memory\n");
+ *ppds8 = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
+ pdsfdds8->ref = 0;
+ pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
+
+ *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
+
+ return DS_OK;
+}
+
+/*******************************************************************************
+ * IDirectSoundFullDuplex_IDirectSoundCapture
+ */
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
+ LPDIRECTSOUNDCAPTURE iface,
+ REFIID riid,
+ LPVOID * ppobj)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
+ LPDIRECTSOUNDCAPTURE iface)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref - 1);
+ return ref;
+}
+
+static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
+ LPDIRECTSOUNDCAPTURE iface)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
+ ULONG ref = InterlockedDecrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref + 1);
+ if (!ref) {
+ IDirectSoundCapture_Release(This->pdsfd->pDSC);
+ HeapFree(GetProcessHeap(), 0, This);
+ TRACE("(%p) released\n", This);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
+ LPDIRECTSOUNDCAPTURE iface,
+ LPCDSCBUFFERDESC lpcDSCBufferDesc,
+ LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
+ LPUNKNOWN pUnk)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
+ TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
+ return IDirectSoundCaptureImpl_CreateCaptureBuffer(This->pdsfd->pDSC,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
+ LPDIRECTSOUNDCAPTURE iface,
+ LPDSCCAPS lpDSCCaps)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
+ TRACE("(%p,%p)\n",This,lpDSCCaps);
+ return IDirectSoundCaptureImpl_GetCaps(This->pdsfd->pDSC, lpDSCCaps);
+}
+
+static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
+ LPDIRECTSOUNDCAPTURE iface,
+ LPCGUID lpcGUID)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
+ return IDirectSoundCaptureImpl_Initialize(This->pdsfd->pDSC,lpcGUID);
+}
+
+static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
+ IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
+ IDirectSoundFullDuplex_IDirectSoundCapture_Release,
+ IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
+ IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
+ IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
+};
+
+HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
+ LPDIRECTSOUNDFULLDUPLEX pdsfd,
+ LPDIRECTSOUNDCAPTURE8 * ppdsc8)
+{
+ IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
+ TRACE("(%p,%p)\n",pdsfd,ppdsc8);
+
+ if (pdsfd == NULL) {
+ ERR("invalid parameter: pdsfd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsc8 == NULL) {
+ ERR("invalid parameter: ppdsc8 == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
+ if (pdsfddsc == NULL) {
+ WARN("out of memory\n");
+ *ppdsc8 = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
+ pdsfddsc->ref = 0;
+ pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
+
+ *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
+
+ return DS_OK;
+}
+
+/***************************************************************************
+ * IDirectSoundFullDuplexImpl
+ */
+static ULONG WINAPI
+IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
+{
+ IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
+ ULONG ref = InterlockedIncrement(&(This->ref));
+ TRACE("(%p) ref was %ld\n", This, ref - 1);
+ return ref;
+}
+
static HRESULT WINAPI
IDirectSoundFullDuplexImpl_QueryInterface(
LPDIRECTSOUNDFULLDUPLEX iface,
@@ -58,16 +568,62 @@ IDirectSoundFullDuplexImpl_QueryInterfac
}
*ppobj = NULL;
- return E_NOINTERFACE;
-}
-static ULONG WINAPI
-IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
-{
- IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
- ULONG ref = InterlockedIncrement(&(This->ref));
- TRACE("(%p) ref was %ld\n", This, ref - 1);
- return ref;
+ if (IsEqualIID(riid, &IID_IUnknown)) {
+ if (!This->pUnknown) {
+ IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
+ if (!This->pUnknown) {
+ WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
+ *ppobj = This->pUnknown;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
+ IDirectSoundFullDuplexImpl_AddRef(iface);
+ *ppobj = This;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSound)) {
+ if (!This->pDS) {
+ IDirectSoundFullDuplex_IDirectSound_Create(iface, &This->pDS);
+ if (!This->pDS) {
+ WARN("IDirectSoundFullDuplex_IDirectSound_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSoundFullDuplex_IDirectSound_AddRef(This->pDS);
+ *ppobj = This->pDS;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
+ if (!This->pDS8) {
+ IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
+ if (!This->pDS8) {
+ WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
+ *ppobj = This->pDS8;
+ return S_OK;
+ } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
+ if (!This->pDSC) {
+ IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
+ if (!This->pDSC) {
+ WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
+ *ppobj = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+ IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
+ *ppobj = This->pDSC;
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
}
static ULONG WINAPI
@@ -78,6 +634,10 @@ IDirectSoundFullDuplexImpl_Release( LPDI
TRACE("(%p) ref was %ld\n", This, ref - 1);
if (!ref) {
+ if (This->capture_device)
+ DirectSoundCaptureDevice_Release(This->capture_device);
+ if (This->renderer_device)
+ DirectSoundDevice_Release(This->renderer_device);
HeapFree( GetProcessHeap(), 0, This );
TRACE("(%p) released\n", This);
}
@@ -96,15 +656,79 @@ IDirectSoundFullDuplexImpl_Initialize(
LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
{
+ HRESULT hr;
IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
- IDirectSoundCaptureBufferImpl** ippdscb=(IDirectSoundCaptureBufferImpl**)lplpDirectSoundCaptureBuffer8;
- IDirectSoundBufferImpl** ippdsc=(IDirectSoundBufferImpl**)lplpDirectSoundBuffer8;
+ IDirectSoundBufferImpl * dsb;
- FIXME( "(%p,%s,%s,%p,%p,%p,%lx,%p,%p) stub!\n", This, debugstr_guid(pCaptureGuid),
- debugstr_guid(pRendererGuid), lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
- ippdscb, ippdsc);
+ TRACE("(%p,%s,%s,%p,%p,%lx,%lx,%p,%p)\n", This,
+ debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
+ lpDscBufferDesc, lpDsBufferDesc, (DWORD)hWnd, dwLevel,
+ lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
+
+ if (This->renderer_device != NULL || This->capture_device != NULL) {
+ WARN("already initialized\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return DSERR_ALREADYINITIALIZED;
+ }
+
+ hr = DirectSoundDevice_Initialize(&This->renderer_device, pRendererGuid);
+ if (hr != DS_OK) {
+ WARN("DirectSoundDevice_Initialize() failed\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return hr;
+ }
+
+ if (dwLevel==DSSCL_PRIORITY || dwLevel==DSSCL_EXCLUSIVE) {
+ WARN("level=%s not fully supported\n",
+ dwLevel==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
+ }
+ This->renderer_device->priolevel = dwLevel;
+
+ hr = DSOUND_PrimarySetFormat(This->renderer_device, lpDsBufferDesc->lpwfxFormat);
+ if (hr != DS_OK) {
+ WARN("DSOUND_PrimarySetFormat() failed\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return hr;
+ }
+ hr = IDirectSoundBufferImpl_Create(This->renderer_device, &dsb, lpDsBufferDesc);
+ if (hr != DS_OK) {
+ WARN("IDirectSoundBufferImpl_Create() failed\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return hr;
+ }
+
+ hr = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl **)lplpDirectSoundBuffer8);
+ if (hr != DS_OK) {
+ WARN("SecondaryBufferImpl_Create() failed\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return hr;
+ }
+ IDirectSoundBuffer8_AddRef(*lplpDirectSoundBuffer8);
+
+ hr = DirectSoundCaptureDevice_Initialize(&This->capture_device, pCaptureGuid);
+ if (hr != DS_OK) {
+ WARN("DirectSoundCaptureDevice_Initialize() failed\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return hr;
+ }
+
+ hr = IDirectSoundCaptureBufferImpl_Create(This->capture_device,
+ (IDirectSoundCaptureBufferImpl **)lplpDirectSoundCaptureBuffer8,
+ lpDscBufferDesc);
+ if (hr != DS_OK) {
+ WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
+ *lplpDirectSoundCaptureBuffer8 = NULL;
+ *lplpDirectSoundBuffer8 = NULL;
+ return hr;
+ }
- return E_FAIL;
+ return hr;
}
static const IDirectSoundFullDuplexVtbl dsfdvt =
@@ -118,6 +742,41 @@ static const IDirectSoundFullDuplexVtbl
IDirectSoundFullDuplexImpl_Initialize
};
+HRESULT DSOUND_FullDuplexCreate(LPDIRECTSOUNDFULLDUPLEX* ppDSFD, IUnknown *pUnkOuter)
+{
+ IDirectSoundFullDuplexImpl *This = NULL;
+
+ if (pUnkOuter) {
+ WARN("pUnkOuter != 0\n");
+ *ppDSFD = NULL;
+ return DSERR_NOAGGREGATION;
+ }
+
+ if (ppDSFD == NULL) {
+ WARN("invalid parameter: ppDSFD == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ This = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
+
+ if (This == NULL) {
+ WARN("out of memory\n");
+ *ppDSFD = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ This->lpVtbl = &dsfdvt;
+ This->ref = 1;
+ This->capture_device = NULL;
+ This->renderer_device = NULL;
+
+ return DS_OK;
+}
+
/***************************************************************************
* DirectSoundFullDuplexCreate [DSOUND.10]
*
@@ -153,37 +812,80 @@ DirectSoundFullDuplexCreate(
LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
LPUNKNOWN pUnkOuter)
{
- IDirectSoundFullDuplexImpl** ippDSFD=(IDirectSoundFullDuplexImpl**)ppDSFD;
- TRACE("(%s,%s,%p,%p,%p,%lx,%p,%p,%p,%p)\n", debugstr_guid(pcGuidCaptureDevice),
- debugstr_guid(pcGuidRenderDevice), pcDSCBufferDesc, pcDSBufferDesc,
- hWnd, dwLevel, ppDSFD, ppDSCBuffer8, ppDSBuffer8, pUnkOuter);
-
- if ( pUnkOuter ) {
- WARN("pUnkOuter != 0\n");
+ HRESULT hres;
+ IDirectSoundFullDuplexImpl *This = NULL;
+ TRACE("(%s,%s,%p,%p,%p,%lx,%p,%p,%p,%p)\n",
+ debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
+ pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
+ ppDSBuffer8, pUnkOuter);
+
+ if (pUnkOuter) {
+ WARN("pUnkOuter != 0\n");
+ *ppDSFD = NULL;
return DSERR_NOAGGREGATION;
}
- *ippDSFD = HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
+ if (pcDSCBufferDesc == NULL) {
+ WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
+ *ppDSFD = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (pcDSBufferDesc == NULL) {
+ WARN("invalid parameter: pcDSBufferDesc == NULL\n");
+ *ppDSFD = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppDSFD == NULL) {
+ WARN("invalid parameter: ppDSFD == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppDSCBuffer8 == NULL) {
+ WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
+ *ppDSFD = NULL;
+ return DSERR_INVALIDPARAM;
+ }
- if (*ippDSFD == NULL) {
- WARN("out of memory\n");
- return DSERR_OUTOFMEMORY;
- } else {
- HRESULT hres;
- IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)*ippDSFD;
-
- This->ref = 1;
- This->lpVtbl = &dsfdvt;
-
- hres = IDirectSoundFullDuplexImpl_Initialize( (LPDIRECTSOUNDFULLDUPLEX)This,
- pcGuidCaptureDevice, pcGuidRenderDevice,
- pcDSCBufferDesc, pcDSBufferDesc,
- hWnd, dwLevel, ppDSCBuffer8, ppDSBuffer8);
- if (hres != DS_OK)
- WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
- return hres;
+ if (ppDSBuffer8 == NULL) {
+ WARN("invalid parameter: ppDSBuffer8 == NULL\n");
+ *ppDSFD = NULL;
+ return DSERR_INVALIDPARAM;
}
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ This = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
+
+ if (This == NULL) {
+ WARN("out of memory\n");
+ *ppDSFD = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ This->lpVtbl = &dsfdvt;
+ This->ref = 1;
+ This->capture_device = NULL;
+ This->renderer_device = NULL;
+
+ hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
+ pcGuidCaptureDevice,
+ pcGuidRenderDevice,
+ pcDSCBufferDesc,
+ pcDSBufferDesc,
+ hWnd, dwLevel, ppDSCBuffer8,
+ ppDSBuffer8);
+ if (hres != DS_OK) {
+ HeapFree(GetProcessHeap(), 0, This);
+ WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
+ *ppDSFD = NULL;
+ } else
+ *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
+
+ return hres;
}
/*******************************************************************************
@@ -236,11 +938,8 @@ DSFDCF_CreateInstance(
*ppobj = NULL;
- if ( IsEqualGUID( &IID_IDirectSoundFullDuplex, riid ) ) {
- /* FIXME: how do we do this one ? */
- FIXME("not implemented\n");
- return E_NOINTERFACE;
- }
+ if ( IsEqualGUID( &IID_IDirectSoundFullDuplex, riid ) )
+ return DSOUND_FullDuplexCreate((LPDIRECTSOUNDFULLDUPLEX*)ppobj,pOuter);
WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
return E_NOINTERFACE;
More information about the wine-patches
mailing list