1 /* DirectSoundFullDuplex
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2001 TransGaming Technologies, Inc.
6 * Copyright 2005 Robert Reif
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "dsound_private.h"
32 /*****************************************************************************
33 * IDirectSoundFullDuplex implementation structure
35 typedef struct IDirectSoundFullDuplexImpl
37 IDirectSoundFullDuplex IDirectSoundFullDuplex_iface
;
38 IUnknown IUnknown_iface
;
39 IDirectSound8 IDirectSound8_iface
;
40 IDirectSoundCapture IDirectSoundCapture_iface
;
41 LONG ref
, unkref
, ds8ref
, dscref
;
44 /* IDirectSoundFullDuplexImpl fields */
45 IDirectSound8
*renderer_device
;
46 IDirectSoundCapture
*capture_device
;
47 } IDirectSoundFullDuplexImpl
;
50 static void DSOUND_FullDuplexDestroy(IDirectSoundFullDuplexImpl
*This
)
52 if (This
->capture_device
)
53 IDirectSoundCapture_Release(This
->capture_device
);
54 if (This
->renderer_device
)
55 IDirectSound_Release(This
->renderer_device
);
56 HeapFree(GetProcessHeap(), 0, This
);
57 TRACE("(%p) released\n", This
);
60 /*******************************************************************************
63 static inline IDirectSoundFullDuplexImpl
*impl_from_IUnknown(IUnknown
*iface
)
65 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IUnknown_iface
);
68 static HRESULT WINAPI
IDirectSoundFullDuplex_IUnknown_QueryInterface(
69 IUnknown
*iface
, REFIID riid
, void **ppobj
)
71 IDirectSoundFullDuplexImpl
*This
= impl_from_IUnknown(iface
);
72 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
73 return IDirectSoundFullDuplex_QueryInterface(&This
->IDirectSoundFullDuplex_iface
, riid
, ppobj
);
76 static ULONG WINAPI
IDirectSoundFullDuplex_IUnknown_AddRef(IUnknown
*iface
)
78 IDirectSoundFullDuplexImpl
*This
= impl_from_IUnknown(iface
);
81 InterlockedIncrement(&(This
->all_ref
));
82 ref
= InterlockedIncrement(&(This
->unkref
));
83 TRACE("(%p) ref was %lu\n", This
, ref
- 1);
88 static ULONG WINAPI
IDirectSoundFullDuplex_IUnknown_Release(IUnknown
*iface
)
90 IDirectSoundFullDuplexImpl
*This
= impl_from_IUnknown(iface
);
91 ULONG ref
= InterlockedDecrement(&(This
->unkref
));
92 TRACE("(%p) ref was %lu\n", This
, ref
+ 1);
93 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
94 DSOUND_FullDuplexDestroy(This
);
98 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl
= {
99 IDirectSoundFullDuplex_IUnknown_QueryInterface
,
100 IDirectSoundFullDuplex_IUnknown_AddRef
,
101 IDirectSoundFullDuplex_IUnknown_Release
104 /*******************************************************************************
105 * IDirectSoundFullDuplex_IDirectSound8
107 static inline IDirectSoundFullDuplexImpl
*impl_from_IDirectSound8(IDirectSound8
*iface
)
109 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IDirectSound8_iface
);
112 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
113 IDirectSound8
*iface
, REFIID riid
, void **ppobj
)
115 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
116 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
117 return IDirectSoundFullDuplex_QueryInterface(&This
->IDirectSoundFullDuplex_iface
, riid
, ppobj
);
120 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound8_AddRef(IDirectSound8
*iface
)
122 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
125 InterlockedIncrement(&(This
->all_ref
));
126 ref
= InterlockedIncrement(&(This
->ds8ref
));
127 TRACE("(%p) ref was %lu\n", This
, ref
- 1);
132 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound8_Release(IDirectSound8
*iface
)
134 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
135 ULONG ref
= InterlockedDecrement(&(This
->ds8ref
));
136 TRACE("(%p) ref was %lu\n", This
, ref
+ 1);
137 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
138 DSOUND_FullDuplexDestroy(This
);
142 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
143 IDirectSound8
*iface
, LPCDSBUFFERDESC dsbd
, IDirectSoundBuffer
**ppdsb
,
146 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
147 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
148 return IDirectSound8_CreateSoundBuffer(This
->renderer_device
,dsbd
,ppdsb
,lpunk
);
151 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_GetCaps(
152 IDirectSound8
*iface
, DSCAPS
*lpDSCaps
)
154 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
155 TRACE("(%p,%p)\n",This
,lpDSCaps
);
156 return IDirectSound8_GetCaps(This
->renderer_device
, lpDSCaps
);
159 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
160 IDirectSound8
*iface
, IDirectSoundBuffer
*psb
, IDirectSoundBuffer
**ppdsb
)
162 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
163 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
164 return IDirectSound8_DuplicateSoundBuffer(This
->renderer_device
,psb
,ppdsb
);
167 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
168 IDirectSound8
*iface
, HWND hwnd
, DWORD level
)
170 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
171 TRACE("(%p,%p,%lu)\n",This
,hwnd
,level
);
172 return IDirectSound8_SetCooperativeLevel(This
->renderer_device
,hwnd
,level
);
175 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_Compact(IDirectSound8
*iface
)
177 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
178 TRACE("(%p)\n", This
);
179 return IDirectSound8_Compact(This
->renderer_device
);
182 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
183 IDirectSound8
*iface
, DWORD
*lpdwSpeakerConfig
)
185 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
186 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
187 return IDirectSound8_GetSpeakerConfig(This
->renderer_device
,lpdwSpeakerConfig
);
190 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
191 IDirectSound8
*iface
, DWORD config
)
193 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
194 TRACE("(%p,0x%08lx)\n",This
,config
);
195 return IDirectSound8_SetSpeakerConfig(This
->renderer_device
,config
);
198 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_Initialize(
199 IDirectSound8
*iface
, LPCGUID lpcGuid
)
201 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
202 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
203 return IDirectSound8_Initialize(This
->renderer_device
,lpcGuid
);
206 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
207 IDirectSound8
*iface
, DWORD
*cert
)
209 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
210 TRACE("(%p, %p)\n", This
, cert
);
211 return IDirectSound8_VerifyCertification(This
->renderer_device
,cert
);
214 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl
= {
215 IDirectSoundFullDuplex_IDirectSound8_QueryInterface
,
216 IDirectSoundFullDuplex_IDirectSound8_AddRef
,
217 IDirectSoundFullDuplex_IDirectSound8_Release
,
218 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer
,
219 IDirectSoundFullDuplex_IDirectSound8_GetCaps
,
220 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer
,
221 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel
,
222 IDirectSoundFullDuplex_IDirectSound8_Compact
,
223 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig
,
224 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig
,
225 IDirectSoundFullDuplex_IDirectSound8_Initialize
,
226 IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
229 /*******************************************************************************
230 * IDirectSoundFullDuplex_IDirectSoundCapture
232 static inline IDirectSoundFullDuplexImpl
*impl_from_IDirectSoundCapture(IDirectSoundCapture
*iface
)
234 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IDirectSoundCapture_iface
);
237 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
238 IDirectSoundCapture
*iface
, REFIID riid
, void **ppobj
)
240 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
241 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
242 return IDirectSoundFullDuplex_QueryInterface(&This
->IDirectSoundFullDuplex_iface
, riid
, ppobj
);
245 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(IDirectSoundCapture
*iface
)
247 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
250 InterlockedIncrement(&(This
->all_ref
));
251 ref
= InterlockedIncrement(&(This
->dscref
));
252 TRACE("(%p) ref was %lu\n", This
, ref
- 1);
257 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_Release(IDirectSoundCapture
*iface
)
259 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
260 ULONG ref
= InterlockedDecrement(&(This
->dscref
));
261 TRACE("(%p) ref was %lu\n", This
, ref
+ 1);
262 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
263 DSOUND_FullDuplexDestroy(This
);
267 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
268 IDirectSoundCapture
*iface
, LPCDSCBUFFERDESC lpcDSCBufferDesc
,
269 IDirectSoundCaptureBuffer
**lplpDSCaptureBuffer
, IUnknown
*pUnk
)
271 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
272 TRACE("(%p, %p, %p, %p)\n", This
, lpcDSCBufferDesc
, lplpDSCaptureBuffer
, pUnk
);
273 return IDirectSoundCapture_CreateCaptureBuffer(This
->capture_device
,lpcDSCBufferDesc
,lplpDSCaptureBuffer
,pUnk
);
276 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
277 IDirectSoundCapture
*iface
, LPDSCCAPS lpDSCCaps
)
279 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
280 TRACE("(%p, %p)\n", This
, lpDSCCaps
);
281 return IDirectSoundCapture_GetCaps(This
->capture_device
, lpDSCCaps
);
284 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
285 IDirectSoundCapture
*iface
, LPCGUID lpcGUID
)
287 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
288 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGUID
));
289 return IDirectSoundCapture_Initialize(This
->capture_device
,lpcGUID
);
292 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl
= {
293 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface
,
294 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef
,
295 IDirectSoundFullDuplex_IDirectSoundCapture_Release
,
296 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer
,
297 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps
,
298 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
301 /***************************************************************************
302 * IDirectSoundFullDuplexImpl
304 static inline IDirectSoundFullDuplexImpl
*impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex
*iface
)
306 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IDirectSoundFullDuplex_iface
);
309 static HRESULT WINAPI
IDirectSoundFullDuplexImpl_QueryInterface(
310 IDirectSoundFullDuplex
*iface
, REFIID riid
, void **ppobj
)
312 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
313 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
316 WARN("invalid parameter\n");
322 if (IsEqualIID(riid
, &IID_IUnknown
)) {
323 *ppobj
= &This
->IUnknown_iface
;
324 IUnknown_AddRef((IUnknown
*)*ppobj
);
326 } else if (IsEqualIID(riid
, &IID_IDirectSoundFullDuplex
)) {
327 *ppobj
= &This
->IDirectSoundFullDuplex_iface
;
328 IUnknown_AddRef((IUnknown
*)*ppobj
);
330 } else if (IsEqualIID(riid
, &IID_IDirectSound
) ||
331 IsEqualIID(riid
, &IID_IDirectSound8
)) {
332 *ppobj
= &This
->IDirectSound8_iface
;
333 IUnknown_AddRef((IUnknown
*)*ppobj
);
335 } else if (IsEqualIID(riid
, &IID_IDirectSoundCapture
)) {
336 *ppobj
= &This
->IDirectSoundCapture_iface
;
337 IUnknown_AddRef((IUnknown
*)*ppobj
);
341 return E_NOINTERFACE
;
344 static ULONG WINAPI
IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex
*iface
)
346 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
349 InterlockedIncrement(&(This
->all_ref
));
350 ref
= InterlockedIncrement(&(This
->ref
));
351 TRACE("(%p) ref was %lu\n", This
, ref
- 1);
356 static ULONG WINAPI
IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex
*iface
)
358 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
359 ULONG ref
= InterlockedDecrement(&(This
->ref
));
360 TRACE("(%p) ref was %lu\n", This
, ref
- 1);
361 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
362 DSOUND_FullDuplexDestroy(This
);
366 static HRESULT WINAPI
IDirectSoundFullDuplexImpl_Initialize(
367 IDirectSoundFullDuplex
*iface
,
368 LPCGUID pCaptureGuid
, LPCGUID pRendererGuid
,
369 LPCDSCBUFFERDESC lpDscBufferDesc
, LPCDSBUFFERDESC lpDsBufferDesc
,
370 HWND hWnd
, DWORD dwLevel
,
371 IDirectSoundCaptureBuffer8
**lplpDirectSoundCaptureBuffer8
,
372 IDirectSoundBuffer8
**lplpDirectSoundBuffer8
)
374 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
375 IDirectSoundCaptureBuffer
*capbuffer
;
376 IDirectSoundBuffer
*buffer
;
380 TRACE("(%p,%s,%s,%p,%p,%p,%lx,%p,%p)\n", This
,
381 debugstr_guid(pCaptureGuid
), debugstr_guid(pRendererGuid
),
382 lpDscBufferDesc
, lpDsBufferDesc
, hWnd
, dwLevel
,
383 lplpDirectSoundCaptureBuffer8
, lplpDirectSoundBuffer8
);
385 *lplpDirectSoundCaptureBuffer8
= NULL
;
386 *lplpDirectSoundBuffer8
= NULL
;
388 if(This
->renderer_device
!= NULL
|| This
->capture_device
!= NULL
)
390 WARN("already initialized\n");
391 return DSERR_ALREADYINITIALIZED
;
394 hr
= DSOUND_Create8(&IID_IDirectSound8
, &ptr
);
397 This
->renderer_device
= ptr
;
398 hr
= IDirectSound8_Initialize(This
->renderer_device
, pRendererGuid
);
402 WARN("DirectSoundDevice_Initialize() failed\n");
406 IDirectSound8_SetCooperativeLevel(This
->renderer_device
, hWnd
, dwLevel
);
408 hr
= IDirectSound8_CreateSoundBuffer(This
->renderer_device
, lpDsBufferDesc
,
412 hr
= IDirectSoundBuffer_QueryInterface(buffer
, &IID_IDirectSoundBuffer8
, &ptr
);
413 IDirectSoundBuffer_Release(buffer
);
417 WARN("IDirectSoundBufferImpl_Create() failed\n");
420 *lplpDirectSoundBuffer8
= ptr
;
422 hr
= DSOUND_CaptureCreate8(&IID_IDirectSoundCapture
, &ptr
);
425 This
->capture_device
= ptr
;
426 hr
= IDirectSoundCapture_Initialize(This
->capture_device
, pCaptureGuid
);
430 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
434 hr
= IDirectSoundCapture_CreateCaptureBuffer(This
->capture_device
, lpDscBufferDesc
,
438 hr
= IDirectSoundCaptureBuffer_QueryInterface(capbuffer
, &IID_IDirectSoundCaptureBuffer8
, &ptr
);
439 IDirectSoundCaptureBuffer_Release(capbuffer
);
443 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
446 *lplpDirectSoundCaptureBuffer8
= ptr
;
451 static const IDirectSoundFullDuplexVtbl dsfdvt
= {
452 /* IUnknown methods */
453 IDirectSoundFullDuplexImpl_QueryInterface
,
454 IDirectSoundFullDuplexImpl_AddRef
,
455 IDirectSoundFullDuplexImpl_Release
,
457 /* IDirectSoundFullDuplex methods */
458 IDirectSoundFullDuplexImpl_Initialize
461 HRESULT
DSOUND_FullDuplexCreate(
462 REFIID riid
, void **ppDSFD
)
464 IDirectSoundFullDuplexImpl
*This
= NULL
;
465 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppDSFD
);
469 WARN("invalid parameter: ppDSFD == NULL\n");
470 return DSERR_INVALIDPARAM
;
474 if(!IsEqualIID(riid
, &IID_IUnknown
) &&
475 !IsEqualIID(riid
, &IID_IDirectSoundFullDuplex
))
476 return E_NOINTERFACE
;
478 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectSoundFullDuplexImpl
));
481 WARN("out of memory\n");
482 return DSERR_OUTOFMEMORY
;
485 This
->IDirectSoundFullDuplex_iface
.lpVtbl
= &dsfdvt
;
486 This
->IUnknown_iface
.lpVtbl
= &DirectSoundFullDuplex_Unknown_Vtbl
;
487 This
->IDirectSound8_iface
.lpVtbl
= &DirectSoundFullDuplex_DirectSound8_Vtbl
;
488 This
->IDirectSoundCapture_iface
.lpVtbl
= &DirectSoundFullDuplex_DirectSoundCapture_Vtbl
;
490 This
->all_ref
= This
->ref
= 1;
495 This
->capture_device
= NULL
;
496 This
->renderer_device
= NULL
;
498 *ppDSFD
= &This
->IDirectSoundFullDuplex_iface
;
502 /***************************************************************************
503 * DirectSoundFullDuplexCreate [DSOUND.10]
505 * Create and initialize a DirectSoundFullDuplex interface.
508 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
509 * pcGuidRenderDevice [I] Address of sound render device GUID.
510 * pcDSCBufferDesc [I] Address of capture buffer description.
511 * pcDSBufferDesc [I] Address of render buffer description.
512 * hWnd [I] Handle to application window.
513 * dwLevel [I] Cooperative level.
514 * ppDSFD [O] Address where full duplex interface returned.
515 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
516 * ppDSBuffer8 [0] Address where render buffer interface returned.
517 * pUnkOuter [I] Must be NULL.
521 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
522 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
525 DirectSoundFullDuplexCreate(
526 LPCGUID pcGuidCaptureDevice
, LPCGUID pcGuidRenderDevice
,
527 LPCDSCBUFFERDESC pcDSCBufferDesc
, LPCDSBUFFERDESC pcDSBufferDesc
,
528 HWND hWnd
, DWORD dwLevel
,
529 IDirectSoundFullDuplex
**ppDSFD
,
530 IDirectSoundCaptureBuffer8
**ppDSCBuffer8
,
531 IDirectSoundBuffer8
**ppDSBuffer8
,
537 TRACE("(%s,%s,%p,%p,%p,%lx,%p,%p,%p,%p)\n",
538 debugstr_guid(pcGuidCaptureDevice
), debugstr_guid(pcGuidRenderDevice
),
539 pcDSCBufferDesc
, pcDSBufferDesc
, hWnd
, dwLevel
, ppDSFD
, ppDSCBuffer8
,
540 ppDSBuffer8
, pUnkOuter
);
544 WARN("invalid parameter: ppDSFD == NULL\n");
545 return DSERR_INVALIDPARAM
;
551 WARN("pUnkOuter != 0\n");
552 return DSERR_NOAGGREGATION
;
555 if(pcDSCBufferDesc
== NULL
)
557 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
558 return DSERR_INVALIDPARAM
;
561 if(pcDSBufferDesc
== NULL
)
563 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
564 return DSERR_INVALIDPARAM
;
568 if(ppDSCBuffer8
== NULL
)
570 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
571 return DSERR_INVALIDPARAM
;
574 if(ppDSBuffer8
== NULL
)
576 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
577 return DSERR_INVALIDPARAM
;
580 hres
= DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex
, &iface
);
581 if(FAILED(hres
)) return hres
;
584 hres
= IDirectSoundFullDuplexImpl_Initialize(*ppDSFD
,
594 IDirectSoundFullDuplex_Release(*ppDSFD
);
595 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");