Avoid holding the device lock when it isn't needed
[dsound-openal.git] / duplex.c
blob02f481695f1c34272535cd4d3139cba22689502a
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
23 #include <stdarg.h>
25 #ifdef __WINESRC__
27 #define NONAMELESSSTRUCT
28 #define NONAMELESSUNION
29 #define CINTERFACE
30 #define COBJMACROS
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "mmsystem.h"
35 #include "mmddk.h"
36 #include "winternl.h"
37 #include "wine/debug.h"
38 #include "dsound.h"
39 #include "dsdriver.h"
41 #include "dsound_private.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
45 #else
47 #define WINVER 0x0600
48 #include <windows.h>
49 #include <dsound.h>
51 #include "dsound_private.h"
53 #endif
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;
65 LONG all_ref;
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 /*******************************************************************************
84 * IUnknown
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);
102 ULONG ref;
104 InterlockedIncrement(&(This->all_ref));
105 ref = InterlockedIncrement(&(This->unkref));
106 TRACE("(%p) ref was %"LONGFMT"u\n", This, ref - 1);
108 return ref;
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 %"LONGFMT"u\n", This, ref + 1);
116 if(InterlockedDecrement(&(This->all_ref)) == 0)
117 DSOUND_FullDuplexDestroy(This);
118 return ref;
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);
146 ULONG ref;
148 InterlockedIncrement(&(This->all_ref));
149 ref = InterlockedIncrement(&(This->ds8ref));
150 TRACE("(%p) ref was %"LONGFMT"u\n", This, ref - 1);
152 return ref;
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 %"LONGFMT"u\n", This, ref + 1);
160 if(InterlockedDecrement(&(This->all_ref)) == 0)
161 DSOUND_FullDuplexDestroy(This);
162 return ref;
165 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
166 IDirectSound8 *iface, LPCDSBUFFERDESC dsbd, IDirectSoundBuffer **ppdsb,
167 IUnknown *lpunk)
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,%"LONGFMT"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%08"LONGFMT"x)\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);
271 ULONG ref;
273 InterlockedIncrement(&(This->all_ref));
274 ref = InterlockedIncrement(&(This->dscref));
275 TRACE("(%p) ref was %"LONGFMT"u\n", This, ref - 1);
277 return ref;
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 %"LONGFMT"u\n", This, ref + 1);
285 if(InterlockedDecrement(&(This->all_ref)) == 0)
286 DSOUND_FullDuplexDestroy(This);
287 return ref;
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 );
338 if (ppobj == NULL) {
339 WARN("invalid parameter\n");
340 return E_INVALIDARG;
343 *ppobj = NULL;
345 if (IsEqualIID(riid, &IID_IUnknown)) {
346 *ppobj = &This->IUnknown_iface;
347 IUnknown_AddRef((IUnknown*)*ppobj);
348 return S_OK;
349 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
350 *ppobj = &This->IDirectSoundFullDuplex_iface;
351 IUnknown_AddRef((IUnknown*)*ppobj);
352 return S_OK;
353 } else if (IsEqualIID(riid, &IID_IDirectSound) ||
354 IsEqualIID(riid, &IID_IDirectSound8)) {
355 *ppobj = &This->IDirectSound8_iface;
356 IUnknown_AddRef((IUnknown*)*ppobj);
357 return S_OK;
358 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
359 *ppobj = &This->IDirectSoundCapture_iface;
360 IUnknown_AddRef((IUnknown*)*ppobj);
361 return S_OK;
364 return E_NOINTERFACE;
367 static ULONG WINAPI IDirectSoundFullDuplexImpl_AddRef(IDirectSoundFullDuplex *iface)
369 IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
370 ULONG ref;
372 InterlockedIncrement(&(This->all_ref));
373 ref = InterlockedIncrement(&(This->ref));
374 TRACE("(%p) ref was %"LONGFMT"u\n", This, ref - 1);
376 return ref;
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 %"LONGFMT"u\n", This, ref - 1);
384 if(InterlockedDecrement(&(This->all_ref)) == 0)
385 DSOUND_FullDuplexDestroy(This);
386 return ref;
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);
398 IDirectSoundCaptureBuffer *capbuffer;
399 IDirectSoundBuffer *buffer;
400 void *ptr;
401 HRESULT hr;
403 TRACE("(%p,%s,%s,%p,%p,%p,%"LONGFMT"x,%p,%p)\n", This,
404 debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
405 lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
406 lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
408 *lplpDirectSoundCaptureBuffer8 = NULL;
409 *lplpDirectSoundBuffer8 = NULL;
411 if(This->renderer_device != NULL || This->capture_device != NULL)
413 WARN("already initialized\n");
414 return DSERR_ALREADYINITIALIZED;
417 hr = DSOUND_Create8(&IID_IDirectSound8, &ptr);
418 if(SUCCEEDED(hr))
420 This->renderer_device = ptr;
421 hr = IDirectSound8_Initialize(This->renderer_device, pRendererGuid);
423 if(hr != DS_OK)
425 WARN("DirectSoundDevice_Initialize() failed\n");
426 return hr;
429 IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
431 hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
432 &buffer, NULL);
433 if(SUCCEEDED(hr))
435 hr = IDirectSoundBuffer_QueryInterface(buffer, &IID_IDirectSoundBuffer8, &ptr);
436 IDirectSoundBuffer_Release(buffer);
438 if(hr != DS_OK)
440 WARN("IDirectSoundBufferImpl_Create() failed\n");
441 return hr;
443 *lplpDirectSoundBuffer8 = ptr;
445 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture, &ptr);
446 if(SUCCEEDED(hr))
448 This->capture_device = ptr;
449 hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
451 if(hr != DS_OK)
453 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
454 return hr;
457 hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device, lpDscBufferDesc,
458 &capbuffer, NULL);
459 if(SUCCEEDED(hr))
461 hr = IDirectSoundCaptureBuffer_QueryInterface(capbuffer, &IID_IDirectSoundCaptureBuffer8, &ptr);
462 IDirectSoundCaptureBuffer_Release(capbuffer);
464 if(hr != DS_OK)
466 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
467 return hr;
469 *lplpDirectSoundCaptureBuffer8 = ptr;
471 return hr;
474 static const IDirectSoundFullDuplexVtbl dsfdvt = {
475 /* IUnknown methods */
476 IDirectSoundFullDuplexImpl_QueryInterface,
477 IDirectSoundFullDuplexImpl_AddRef,
478 IDirectSoundFullDuplexImpl_Release,
480 /* IDirectSoundFullDuplex methods */
481 IDirectSoundFullDuplexImpl_Initialize
484 HRESULT DSOUND_FullDuplexCreate(
485 REFIID riid, void **ppDSFD)
487 IDirectSoundFullDuplexImpl *This = NULL;
488 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
490 if(ppDSFD == NULL)
492 WARN("invalid parameter: ppDSFD == NULL\n");
493 return DSERR_INVALIDPARAM;
495 *ppDSFD = NULL;
497 if(!IsEqualIID(riid, &IID_IUnknown) &&
498 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex))
499 return E_NOINTERFACE;
501 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
502 if(This == NULL)
504 WARN("out of memory\n");
505 return DSERR_OUTOFMEMORY;
508 This->IDirectSoundFullDuplex_iface.lpVtbl = (IDirectSoundFullDuplexVtbl*)&dsfdvt;
509 This->IUnknown_iface.lpVtbl = (IUnknownVtbl*)&DirectSoundFullDuplex_Unknown_Vtbl;
510 This->IDirectSound8_iface.lpVtbl = (IDirectSound8Vtbl*)&DirectSoundFullDuplex_DirectSound8_Vtbl;
511 This->IDirectSoundCapture_iface.lpVtbl = (IDirectSoundCaptureVtbl*)&DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
513 This->all_ref = This->ref = 1;
514 This->unkref = 0;
515 This->ds8ref = 0;
516 This->dscref = 0;
518 This->capture_device = NULL;
519 This->renderer_device = NULL;
521 *ppDSFD = &This->IDirectSoundFullDuplex_iface;
522 return DS_OK;
525 /***************************************************************************
526 * DirectSoundFullDuplexCreate [DSOUND.10]
528 * Create and initialize a DirectSoundFullDuplex interface.
530 * PARAMS
531 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
532 * pcGuidRenderDevice [I] Address of sound render device GUID.
533 * pcDSCBufferDesc [I] Address of capture buffer description.
534 * pcDSBufferDesc [I] Address of render buffer description.
535 * hWnd [I] Handle to application window.
536 * dwLevel [I] Cooperative level.
537 * ppDSFD [O] Address where full duplex interface returned.
538 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
539 * ppDSBuffer8 [0] Address where render buffer interface returned.
540 * pUnkOuter [I] Must be NULL.
542 * RETURNS
543 * Success: DS_OK
544 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
545 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
547 HRESULT WINAPI
548 DirectSoundFullDuplexCreate(
549 LPCGUID pcGuidCaptureDevice, LPCGUID pcGuidRenderDevice,
550 LPCDSCBUFFERDESC pcDSCBufferDesc, LPCDSBUFFERDESC pcDSBufferDesc,
551 HWND hWnd, DWORD dwLevel,
552 IDirectSoundFullDuplex **ppDSFD,
553 IDirectSoundCaptureBuffer8 **ppDSCBuffer8,
554 IDirectSoundBuffer8 **ppDSBuffer8,
555 IUnknown *pUnkOuter)
557 void *iface = NULL;
558 HRESULT hres;
560 TRACE("(%s,%s,%p,%p,%p,%"LONGFMT"x,%p,%p,%p,%p)\n",
561 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
562 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
563 ppDSBuffer8, pUnkOuter);
565 if(ppDSFD == NULL)
567 WARN("invalid parameter: ppDSFD == NULL\n");
568 return DSERR_INVALIDPARAM;
570 *ppDSFD = NULL;
572 if(pUnkOuter)
574 WARN("pUnkOuter != 0\n");
575 return DSERR_NOAGGREGATION;
578 if(pcDSCBufferDesc == NULL)
580 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
581 return DSERR_INVALIDPARAM;
584 if(pcDSBufferDesc == NULL)
586 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
587 return DSERR_INVALIDPARAM;
591 if(ppDSCBuffer8 == NULL)
593 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
594 return DSERR_INVALIDPARAM;
597 if(ppDSBuffer8 == NULL)
599 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
600 return DSERR_INVALIDPARAM;
603 hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, &iface);
604 if(FAILED(hres)) return hres;
606 *ppDSFD = iface;
607 hres = IDirectSoundFullDuplexImpl_Initialize(*ppDSFD,
608 pcGuidCaptureDevice,
609 pcGuidRenderDevice,
610 pcDSCBufferDesc,
611 pcDSBufferDesc,
612 hWnd, dwLevel,
613 ppDSCBuffer8,
614 ppDSBuffer8);
615 if(hres != DS_OK)
617 IDirectSoundFullDuplex_Release(*ppDSFD);
618 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
619 *ppDSFD = NULL;
622 return hres;