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
27 #define NONAMELESSSTRUCT
28 #define NONAMELESSUNION
37 #include "wine/debug.h"
41 #include "dsound_private.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(dsound
);
51 #include "dsound_private.h"
55 /*****************************************************************************
56 * IDirectSoundFullDuplex implementation structure
58 typedef struct IDirectSoundFullDuplexImpl
60 IDirectSoundFullDuplex IDirectSoundFullDuplex_iface
;
61 IUnknown IUnknown_iface
;
62 IDirectSound8 IDirectSound8_iface
;
63 IDirectSoundCapture IDirectSoundCapture_iface
;
64 LONG ref
, unkref
, ds8ref
, dscref
;
67 /* IDirectSoundFullDuplexImpl fields */
68 IDirectSound8
*renderer_device
;
69 IDirectSoundCapture
*capture_device
;
70 } IDirectSoundFullDuplexImpl
;
73 static void DSOUND_FullDuplexDestroy(IDirectSoundFullDuplexImpl
*This
)
75 if (This
->capture_device
)
76 IDirectSoundCapture_Release(This
->capture_device
);
77 if (This
->renderer_device
)
78 IDirectSound_Release(This
->renderer_device
);
79 HeapFree(GetProcessHeap(), 0, This
);
80 TRACE("(%p) released\n", This
);
83 /*******************************************************************************
86 static inline IDirectSoundFullDuplexImpl
*impl_from_IUnknown(IUnknown
*iface
)
88 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IUnknown_iface
);
91 static HRESULT WINAPI
IDirectSoundFullDuplex_IUnknown_QueryInterface(
92 IUnknown
*iface
, REFIID riid
, void **ppobj
)
94 IDirectSoundFullDuplexImpl
*This
= impl_from_IUnknown(iface
);
95 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
96 return IDirectSoundFullDuplex_QueryInterface(&This
->IDirectSoundFullDuplex_iface
, riid
, ppobj
);
99 static ULONG WINAPI
IDirectSoundFullDuplex_IUnknown_AddRef(IUnknown
*iface
)
101 IDirectSoundFullDuplexImpl
*This
= impl_from_IUnknown(iface
);
104 InterlockedIncrement(&(This
->all_ref
));
105 ref
= InterlockedIncrement(&(This
->unkref
));
106 TRACE("(%p) ref was %d\n", This
, ref
- 1);
111 static ULONG WINAPI
IDirectSoundFullDuplex_IUnknown_Release(IUnknown
*iface
)
113 IDirectSoundFullDuplexImpl
*This
= impl_from_IUnknown(iface
);
114 ULONG ref
= InterlockedDecrement(&(This
->unkref
));
115 TRACE("(%p) ref was %d\n", This
, ref
+ 1);
116 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
117 DSOUND_FullDuplexDestroy(This
);
121 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl
= {
122 IDirectSoundFullDuplex_IUnknown_QueryInterface
,
123 IDirectSoundFullDuplex_IUnknown_AddRef
,
124 IDirectSoundFullDuplex_IUnknown_Release
127 /*******************************************************************************
128 * IDirectSoundFullDuplex_IDirectSound8
130 static inline IDirectSoundFullDuplexImpl
*impl_from_IDirectSound8(IDirectSound8
*iface
)
132 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IDirectSound8_iface
);
135 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
136 IDirectSound8
*iface
, REFIID riid
, void **ppobj
)
138 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
139 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
140 return IDirectSoundFullDuplex_QueryInterface(&This
->IDirectSoundFullDuplex_iface
, riid
, ppobj
);
143 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound8_AddRef(IDirectSound8
*iface
)
145 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
148 InterlockedIncrement(&(This
->all_ref
));
149 ref
= InterlockedIncrement(&(This
->ds8ref
));
150 TRACE("(%p) ref was %d\n", This
, ref
- 1);
155 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound8_Release(IDirectSound8
*iface
)
157 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
158 ULONG ref
= InterlockedDecrement(&(This
->ds8ref
));
159 TRACE("(%p) ref was %d\n", This
, ref
+ 1);
160 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
161 DSOUND_FullDuplexDestroy(This
);
165 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
166 IDirectSound8
*iface
, LPCDSBUFFERDESC dsbd
, IDirectSoundBuffer
**ppdsb
,
169 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
170 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
171 return IDirectSound8_CreateSoundBuffer(This
->renderer_device
,dsbd
,ppdsb
,lpunk
);
174 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_GetCaps(
175 IDirectSound8
*iface
, DSCAPS
*lpDSCaps
)
177 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
178 TRACE("(%p,%p)\n",This
,lpDSCaps
);
179 return IDirectSound8_GetCaps(This
->renderer_device
, lpDSCaps
);
182 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
183 IDirectSound8
*iface
, IDirectSoundBuffer
*psb
, IDirectSoundBuffer
**ppdsb
)
185 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
186 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
187 return IDirectSound8_DuplicateSoundBuffer(This
->renderer_device
,psb
,ppdsb
);
190 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
191 IDirectSound8
*iface
, HWND hwnd
, DWORD level
)
193 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
194 TRACE("(%p,%p,%u)\n",This
,hwnd
,level
);
195 return IDirectSound8_SetCooperativeLevel(This
->renderer_device
,hwnd
,level
);
198 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_Compact(IDirectSound8
*iface
)
200 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
201 TRACE("(%p)\n", This
);
202 return IDirectSound8_Compact(This
->renderer_device
);
205 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
206 IDirectSound8
*iface
, DWORD
*lpdwSpeakerConfig
)
208 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
209 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
210 return IDirectSound8_GetSpeakerConfig(This
->renderer_device
,lpdwSpeakerConfig
);
213 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
214 IDirectSound8
*iface
, DWORD config
)
216 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
217 TRACE("(%p,0x%08x)\n",This
,config
);
218 return IDirectSound8_SetSpeakerConfig(This
->renderer_device
,config
);
221 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_Initialize(
222 IDirectSound8
*iface
, LPCGUID lpcGuid
)
224 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
225 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
226 return IDirectSound8_Initialize(This
->renderer_device
,lpcGuid
);
229 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
230 IDirectSound8
*iface
, DWORD
*cert
)
232 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSound8(iface
);
233 TRACE("(%p, %p)\n", This
, cert
);
234 return IDirectSound8_VerifyCertification(This
->renderer_device
,cert
);
237 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl
= {
238 IDirectSoundFullDuplex_IDirectSound8_QueryInterface
,
239 IDirectSoundFullDuplex_IDirectSound8_AddRef
,
240 IDirectSoundFullDuplex_IDirectSound8_Release
,
241 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer
,
242 IDirectSoundFullDuplex_IDirectSound8_GetCaps
,
243 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer
,
244 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel
,
245 IDirectSoundFullDuplex_IDirectSound8_Compact
,
246 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig
,
247 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig
,
248 IDirectSoundFullDuplex_IDirectSound8_Initialize
,
249 IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
252 /*******************************************************************************
253 * IDirectSoundFullDuplex_IDirectSoundCapture
255 static inline IDirectSoundFullDuplexImpl
*impl_from_IDirectSoundCapture(IDirectSoundCapture
*iface
)
257 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IDirectSoundCapture_iface
);
260 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
261 IDirectSoundCapture
*iface
, REFIID riid
, void **ppobj
)
263 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
264 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
265 return IDirectSoundFullDuplex_QueryInterface(&This
->IDirectSoundFullDuplex_iface
, riid
, ppobj
);
268 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(IDirectSoundCapture
*iface
)
270 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
273 InterlockedIncrement(&(This
->all_ref
));
274 ref
= InterlockedIncrement(&(This
->dscref
));
275 TRACE("(%p) ref was %d\n", This
, ref
- 1);
280 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_Release(IDirectSoundCapture
*iface
)
282 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
283 ULONG ref
= InterlockedDecrement(&(This
->dscref
));
284 TRACE("(%p) ref was %d\n", This
, ref
+ 1);
285 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
286 DSOUND_FullDuplexDestroy(This
);
290 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
291 IDirectSoundCapture
*iface
, LPCDSCBUFFERDESC lpcDSCBufferDesc
,
292 IDirectSoundCaptureBuffer
**lplpDSCaptureBuffer
, IUnknown
*pUnk
)
294 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
295 TRACE("(%p, %p, %p, %p)\n", This
, lpcDSCBufferDesc
, lplpDSCaptureBuffer
, pUnk
);
296 return IDirectSoundCapture_CreateCaptureBuffer(This
->capture_device
,lpcDSCBufferDesc
,lplpDSCaptureBuffer
,pUnk
);
299 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
300 IDirectSoundCapture
*iface
, LPDSCCAPS lpDSCCaps
)
302 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
303 TRACE("(%p, %p)\n", This
, lpDSCCaps
);
304 return IDirectSoundCapture_GetCaps(This
->capture_device
, lpDSCCaps
);
307 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
308 IDirectSoundCapture
*iface
, LPCGUID lpcGUID
)
310 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundCapture(iface
);
311 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGUID
));
312 return IDirectSoundCapture_Initialize(This
->capture_device
,lpcGUID
);
315 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl
= {
316 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface
,
317 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef
,
318 IDirectSoundFullDuplex_IDirectSoundCapture_Release
,
319 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer
,
320 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps
,
321 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
324 /***************************************************************************
325 * IDirectSoundFullDuplexImpl
327 static inline IDirectSoundFullDuplexImpl
*impl_from_IDirectSoundFullDuplex(IDirectSoundFullDuplex
*iface
)
329 return CONTAINING_RECORD(iface
, IDirectSoundFullDuplexImpl
, IDirectSoundFullDuplex_iface
);
332 static HRESULT WINAPI
IDirectSoundFullDuplexImpl_QueryInterface(
333 IDirectSoundFullDuplex
*iface
, REFIID riid
, void **ppobj
)
335 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
336 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
339 WARN("invalid parameter\n");
345 if (IsEqualIID(riid
, &IID_IUnknown
)) {
346 *ppobj
= &This
->IUnknown_iface
;
347 IUnknown_AddRef((IUnknown
*)*ppobj
);
349 } else if (IsEqualIID(riid
, &IID_IDirectSoundFullDuplex
)) {
350 *ppobj
= &This
->IDirectSoundFullDuplex_iface
;
351 IUnknown_AddRef((IUnknown
*)*ppobj
);
353 } else if (IsEqualIID(riid
, &IID_IDirectSound
) ||
354 IsEqualIID(riid
, &IID_IDirectSound8
)) {
355 *ppobj
= &This
->IDirectSound8_iface
;
356 IUnknown_AddRef((IUnknown
*)*ppobj
);
358 } else if (IsEqualIID(riid
, &IID_IDirectSoundCapture
)) {
359 *ppobj
= &This
->IDirectSoundCapture_iface
;
360 IUnknown_AddRef((IUnknown
*)*ppobj
);
364 return E_NOINTERFACE
;
367 static ULONG WINAPI
IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex
*iface
)
369 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
372 InterlockedIncrement(&(This
->all_ref
));
373 ref
= InterlockedIncrement(&(This
->ref
));
374 TRACE("(%p) ref was %d\n", This
, ref
- 1);
379 static ULONG WINAPI
IDirectSoundFullDuplexImpl_Release(IDirectSoundFullDuplex
*iface
)
381 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
382 ULONG ref
= InterlockedDecrement(&(This
->ref
));
383 TRACE("(%p) ref was %d\n", This
, ref
- 1);
384 if(InterlockedDecrement(&(This
->all_ref
)) == 0)
385 DSOUND_FullDuplexDestroy(This
);
389 static HRESULT WINAPI
IDirectSoundFullDuplexImpl_Initialize(
390 IDirectSoundFullDuplex
*iface
,
391 LPCGUID pCaptureGuid
, LPCGUID pRendererGuid
,
392 LPCDSCBUFFERDESC lpDscBufferDesc
, LPCDSBUFFERDESC lpDsBufferDesc
,
393 HWND hWnd
, DWORD dwLevel
,
394 IDirectSoundCaptureBuffer8
**lplpDirectSoundCaptureBuffer8
,
395 IDirectSoundBuffer8
**lplpDirectSoundBuffer8
)
397 IDirectSoundFullDuplexImpl
*This
= impl_from_IDirectSoundFullDuplex(iface
);
401 TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This
,
402 debugstr_guid(pCaptureGuid
), debugstr_guid(pRendererGuid
),
403 lpDscBufferDesc
, lpDsBufferDesc
, hWnd
, dwLevel
,
404 lplpDirectSoundCaptureBuffer8
, lplpDirectSoundBuffer8
);
406 *lplpDirectSoundCaptureBuffer8
= NULL
;
407 *lplpDirectSoundBuffer8
= NULL
;
409 if(This
->renderer_device
!= NULL
|| This
->capture_device
!= NULL
)
411 WARN("already initialized\n");
412 return DSERR_ALREADYINITIALIZED
;
415 hr
= DSOUND_Create8(&IID_IDirectSound8
, &device
);
418 This
->renderer_device
= device
;
419 hr
= IDirectSound_Initialize(This
->renderer_device
, pRendererGuid
);
423 WARN("DirectSoundDevice_Initialize() failed\n");
427 IDirectSound8_SetCooperativeLevel(This
->renderer_device
, hWnd
, dwLevel
);
429 hr
= IDirectSound8_CreateSoundBuffer(This
->renderer_device
, lpDsBufferDesc
,
430 (IDirectSoundBuffer
**)lplpDirectSoundBuffer8
, NULL
);
433 WARN("IDirectSoundBufferImpl_Create() failed\n");
437 hr
= DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8
, &device
);
440 This
->capture_device
= device
;
441 hr
= IDirectSoundCapture_Initialize(This
->capture_device
, pCaptureGuid
);
445 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
449 hr
= IDirectSoundCapture_CreateCaptureBuffer(This
->capture_device
, lpDscBufferDesc
,
450 (IDirectSoundCaptureBuffer
**)lplpDirectSoundCaptureBuffer8
, NULL
);
453 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
460 static const IDirectSoundFullDuplexVtbl dsfdvt
= {
461 /* IUnknown methods */
462 IDirectSoundFullDuplexImpl_QueryInterface
,
463 IDirectSoundFullDuplexImpl_AddRef
,
464 IDirectSoundFullDuplexImpl_Release
,
466 /* IDirectSoundFullDuplex methods */
467 IDirectSoundFullDuplexImpl_Initialize
470 HRESULT
DSOUND_FullDuplexCreate(
471 REFIID riid
, void **ppDSFD
)
473 IDirectSoundFullDuplexImpl
*This
= NULL
;
474 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppDSFD
);
478 WARN("invalid parameter: ppDSFD == NULL\n");
479 return DSERR_INVALIDPARAM
;
483 if(!IsEqualIID(riid
, &IID_IUnknown
) &&
484 !IsEqualIID(riid
, &IID_IDirectSoundFullDuplex
))
485 return E_NOINTERFACE
;
487 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectSoundFullDuplexImpl
));
490 WARN("out of memory\n");
491 return DSERR_OUTOFMEMORY
;
494 This
->IDirectSoundFullDuplex_iface
.lpVtbl
= (IDirectSoundFullDuplexVtbl
*)&dsfdvt
;
495 This
->IUnknown_iface
.lpVtbl
= (IUnknownVtbl
*)&DirectSoundFullDuplex_Unknown_Vtbl
;
496 This
->IDirectSound8_iface
.lpVtbl
= (IDirectSound8Vtbl
*)&DirectSoundFullDuplex_DirectSound8_Vtbl
;
497 This
->IDirectSoundCapture_iface
.lpVtbl
= (IDirectSoundCaptureVtbl
*)&DirectSoundFullDuplex_DirectSoundCapture_Vtbl
;
499 This
->all_ref
= This
->ref
= 1;
504 This
->capture_device
= NULL
;
505 This
->renderer_device
= NULL
;
507 *ppDSFD
= &This
->IDirectSoundFullDuplex_iface
;
511 /***************************************************************************
512 * DirectSoundFullDuplexCreate [DSOUND.10]
514 * Create and initialize a DirectSoundFullDuplex interface.
517 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
518 * pcGuidRenderDevice [I] Address of sound render device GUID.
519 * pcDSCBufferDesc [I] Address of capture buffer description.
520 * pcDSBufferDesc [I] Address of render buffer description.
521 * hWnd [I] Handle to application window.
522 * dwLevel [I] Cooperative level.
523 * ppDSFD [O] Address where full duplex interface returned.
524 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
525 * ppDSBuffer8 [0] Address where render buffer interface returned.
526 * pUnkOuter [I] Must be NULL.
530 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
531 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
534 DirectSoundFullDuplexCreate(
535 LPCGUID pcGuidCaptureDevice
, LPCGUID pcGuidRenderDevice
,
536 LPCDSCBUFFERDESC pcDSCBufferDesc
, LPCDSBUFFERDESC pcDSBufferDesc
,
537 HWND hWnd
, DWORD dwLevel
,
538 IDirectSoundFullDuplex
**ppDSFD
,
539 IDirectSoundCaptureBuffer8
**ppDSCBuffer8
,
540 IDirectSoundBuffer8
**ppDSBuffer8
,
546 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
547 debugstr_guid(pcGuidCaptureDevice
), debugstr_guid(pcGuidRenderDevice
),
548 pcDSCBufferDesc
, pcDSBufferDesc
, hWnd
, dwLevel
, ppDSFD
, ppDSCBuffer8
,
549 ppDSBuffer8
, pUnkOuter
);
553 WARN("invalid parameter: ppDSFD == NULL\n");
554 return DSERR_INVALIDPARAM
;
560 WARN("pUnkOuter != 0\n");
561 return DSERR_NOAGGREGATION
;
564 if(pcDSCBufferDesc
== NULL
)
566 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
567 return DSERR_INVALIDPARAM
;
570 if(pcDSBufferDesc
== NULL
)
572 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
573 return DSERR_INVALIDPARAM
;
577 if(ppDSCBuffer8
== NULL
)
579 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
580 return DSERR_INVALIDPARAM
;
583 if(ppDSBuffer8
== NULL
)
585 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
586 return DSERR_INVALIDPARAM
;
589 hres
= DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex
, &iface
);
590 if(FAILED(hres
)) return hres
;
593 hres
= IDirectSoundFullDuplexImpl_Initialize(*ppDSFD
,
603 IDirectSoundFullDuplex_Release(*ppDSFD
);
604 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");