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
25 #define NONAMELESSSTRUCT
26 #define NONAMELESSUNION
34 #include "wine/debug.h"
36 #include "dsound_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
40 /*****************************************************************************
41 * IDirectSoundFullDuplex implementation structure
43 typedef struct IDirectSoundFullDuplexImpl
46 const IDirectSoundFullDuplexVtbl *lpVtbl;
49 /* IDirectSoundFullDuplexImpl fields */
50 IDirectSound8 *renderer_device;
51 IDirectSoundCapture *capture_device;
55 LPDIRECTSOUNDCAPTURE pDSC;
56 } IDirectSoundFullDuplexImpl;
58 typedef struct IDirectSoundFullDuplex_IUnknown {
59 const IUnknownVtbl *lpVtbl;
61 IDirectSoundFullDuplexImpl *pdsfd;
62 } IDirectSoundFullDuplex_IUnknown;
64 typedef struct IDirectSoundFullDuplex_IDirectSound8 {
65 const IDirectSound8Vtbl *lpVtbl;
67 IDirectSoundFullDuplexImpl *pdsfd;
68 } IDirectSoundFullDuplex_IDirectSound8;
70 typedef struct IDirectSoundFullDuplex_IDirectSoundCapture {
71 const IDirectSoundCaptureVtbl *lpVtbl;
73 IDirectSoundFullDuplexImpl *pdsfd;
74 } IDirectSoundFullDuplex_IDirectSoundCapture;
76 /*******************************************************************************
79 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
84 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
85 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
86 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
89 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
92 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
93 ULONG ref = InterlockedIncrement(&(This->ref));
94 TRACE("(%p) ref was %d\n", This, ref - 1);
98 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
101 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
102 ULONG ref = InterlockedDecrement(&(This->ref));
103 TRACE("(%p) ref was %d\n", This, ref + 1);
105 This->pdsfd->pUnknown = NULL;
106 HeapFree(GetProcessHeap(), 0, This);
107 TRACE("(%p) released\n", This);
112 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
114 IDirectSoundFullDuplex_IUnknown_QueryInterface,
115 IDirectSoundFullDuplex_IUnknown_AddRef,
116 IDirectSoundFullDuplex_IUnknown_Release
119 static HRESULT IDirectSoundFullDuplex_IUnknown_Create(
120 LPDIRECTSOUNDFULLDUPLEX pdsfd,
123 IDirectSoundFullDuplex_IUnknown * pdsfdunk;
124 TRACE("(%p,%p)\n",pdsfd,ppunk);
127 ERR("invalid parameter: pdsfd == NULL\n");
128 return DSERR_INVALIDPARAM;
132 ERR("invalid parameter: ppunk == NULL\n");
133 return DSERR_INVALIDPARAM;
136 pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
137 if (pdsfdunk == NULL) {
138 WARN("out of memory\n");
140 return DSERR_OUTOFMEMORY;
143 pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
145 pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
147 *ppunk = (LPUNKNOWN)pdsfdunk;
152 /*******************************************************************************
153 * IDirectSoundFullDuplex_IDirectSound8
155 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
156 LPDIRECTSOUND8 iface,
160 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
161 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
162 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
165 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
166 LPDIRECTSOUND8 iface)
168 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
169 ULONG ref = InterlockedIncrement(&(This->ref));
170 TRACE("(%p) ref was %d\n", This, ref - 1);
174 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
175 LPDIRECTSOUND8 iface)
177 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
178 ULONG ref = InterlockedDecrement(&(This->ref));
179 TRACE("(%p) ref was %d\n", This, ref + 1);
181 This->pdsfd->pDS8 = NULL;
182 HeapFree(GetProcessHeap(), 0, This);
183 TRACE("(%p) released\n", This);
188 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
189 LPDIRECTSOUND8 iface,
190 LPCDSBUFFERDESC dsbd,
191 LPLPDIRECTSOUNDBUFFER ppdsb,
194 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
195 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
196 return IDirectSound8_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk);
199 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
200 LPDIRECTSOUND8 iface,
203 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
204 TRACE("(%p,%p)\n",This,lpDSCaps);
205 return IDirectSound8_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
208 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
209 LPDIRECTSOUND8 iface,
210 LPDIRECTSOUNDBUFFER psb,
211 LPLPDIRECTSOUNDBUFFER ppdsb)
213 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
214 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
215 return IDirectSound8_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
218 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
219 LPDIRECTSOUND8 iface,
223 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
224 TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
225 return IDirectSound8_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
228 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
229 LPDIRECTSOUND8 iface)
231 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
232 TRACE("(%p)\n", This);
233 return IDirectSound8_Compact(This->pdsfd->renderer_device);
236 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
237 LPDIRECTSOUND8 iface,
238 LPDWORD lpdwSpeakerConfig)
240 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
241 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
242 return IDirectSound8_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
245 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
246 LPDIRECTSOUND8 iface,
249 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
250 TRACE("(%p,0x%08x)\n",This,config);
251 return IDirectSound8_SetSpeakerConfig(This->pdsfd->renderer_device,config);
254 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
255 LPDIRECTSOUND8 iface,
258 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
259 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
260 return IDirectSound8_Initialize(This->pdsfd->renderer_device,lpcGuid);
263 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
264 LPDIRECTSOUND8 iface,
267 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
268 TRACE("(%p, %p)\n", This, cert);
269 return IDirectSound8_VerifyCertification(This->pdsfd->renderer_device,cert);
272 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
274 IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
275 IDirectSoundFullDuplex_IDirectSound8_AddRef,
276 IDirectSoundFullDuplex_IDirectSound8_Release,
277 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
278 IDirectSoundFullDuplex_IDirectSound8_GetCaps,
279 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
280 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
281 IDirectSoundFullDuplex_IDirectSound8_Compact,
282 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
283 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
284 IDirectSoundFullDuplex_IDirectSound8_Initialize,
285 IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
288 static HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
289 LPDIRECTSOUNDFULLDUPLEX pdsfd,
290 LPDIRECTSOUND8 * ppds8)
292 IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
293 TRACE("(%p,%p)\n",pdsfd,ppds8);
296 ERR("invalid parameter: pdsfd == NULL\n");
297 return DSERR_INVALIDPARAM;
301 ERR("invalid parameter: ppds8 == NULL\n");
302 return DSERR_INVALIDPARAM;
305 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
306 WARN("not initialized\n");
308 return DSERR_UNINITIALIZED;
311 pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
312 if (pdsfdds8 == NULL) {
313 WARN("out of memory\n");
315 return DSERR_OUTOFMEMORY;
318 pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
320 pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
322 *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
327 /*******************************************************************************
328 * IDirectSoundFullDuplex_IDirectSoundCapture
330 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
331 LPDIRECTSOUNDCAPTURE iface,
335 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
336 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
337 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
340 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
341 LPDIRECTSOUNDCAPTURE iface)
343 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
344 ULONG ref = InterlockedIncrement(&(This->ref));
345 TRACE("(%p) ref was %d\n", This, ref - 1);
349 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
350 LPDIRECTSOUNDCAPTURE iface)
352 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
353 ULONG ref = InterlockedDecrement(&(This->ref));
354 TRACE("(%p) ref was %d\n", This, ref + 1);
356 This->pdsfd->pDSC = NULL;
357 HeapFree(GetProcessHeap(), 0, This);
358 TRACE("(%p) released\n", This);
363 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
364 LPDIRECTSOUNDCAPTURE iface,
365 LPCDSCBUFFERDESC lpcDSCBufferDesc,
366 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
369 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
370 TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
371 return IDirectSoundCapture_CreateCaptureBuffer(This->pdsfd->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
374 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
375 LPDIRECTSOUNDCAPTURE iface,
378 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
379 TRACE("(%p,%p)\n",This,lpDSCCaps);
380 return IDirectSoundCapture_GetCaps(This->pdsfd->capture_device, lpDSCCaps);
383 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
384 LPDIRECTSOUNDCAPTURE iface,
387 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
388 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
389 return IDirectSoundCapture_Initialize(This->pdsfd->capture_device,lpcGUID);
392 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
394 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
395 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
396 IDirectSoundFullDuplex_IDirectSoundCapture_Release,
397 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
398 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
399 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
402 static HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
403 LPDIRECTSOUNDFULLDUPLEX pdsfd,
404 LPDIRECTSOUNDCAPTURE8 * ppdsc8)
406 IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
407 TRACE("(%p,%p)\n",pdsfd,ppdsc8);
410 ERR("invalid parameter: pdsfd == NULL\n");
411 return DSERR_INVALIDPARAM;
414 if (ppdsc8 == NULL) {
415 ERR("invalid parameter: ppdsc8 == NULL\n");
416 return DSERR_INVALIDPARAM;
419 if (((IDirectSoundFullDuplexImpl*)pdsfd)->capture_device == NULL) {
420 WARN("not initialized\n");
422 return DSERR_UNINITIALIZED;
425 pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
426 if (pdsfddsc == NULL) {
427 WARN("out of memory\n");
429 return DSERR_OUTOFMEMORY;
432 pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
434 pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
436 *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
441 /***************************************************************************
442 * IDirectSoundFullDuplexImpl
445 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
447 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
448 ULONG ref = InterlockedIncrement(&(This->ref));
449 TRACE("(%p) ref was %d\n", This, ref - 1);
453 static HRESULT WINAPI
454 IDirectSoundFullDuplexImpl_QueryInterface(
455 LPDIRECTSOUNDFULLDUPLEX iface,
459 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
460 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
463 WARN("invalid parameter\n");
469 if (IsEqualIID(riid, &IID_IUnknown)) {
470 if (!This->pUnknown) {
471 IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
472 if (!This->pUnknown) {
473 WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
475 return E_NOINTERFACE;
478 IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
479 *ppobj = This->pUnknown;
481 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
482 IDirectSoundFullDuplexImpl_AddRef(iface);
485 } else if (IsEqualIID(riid, &IID_IDirectSound)
486 || IsEqualIID(riid, &IID_IDirectSound8)) {
488 IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
490 WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
492 return E_NOINTERFACE;
495 IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
498 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
500 IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
502 WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
504 return E_NOINTERFACE;
507 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
512 return E_NOINTERFACE;
516 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
518 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
519 ULONG ref = InterlockedDecrement(&(This->ref));
520 TRACE("(%p) ref was %d\n", This, ref - 1);
523 if (This->capture_device)
524 IDirectSoundCapture_Release(This->capture_device);
525 if (This->renderer_device)
526 IDirectSound_Release(This->renderer_device);
527 HeapFree( GetProcessHeap(), 0, This );
528 TRACE("(%p) released\n", This);
533 static HRESULT WINAPI
534 IDirectSoundFullDuplexImpl_Initialize(
535 LPDIRECTSOUNDFULLDUPLEX iface,
536 LPCGUID pCaptureGuid,
537 LPCGUID pRendererGuid,
538 LPCDSCBUFFERDESC lpDscBufferDesc,
539 LPCDSBUFFERDESC lpDsBufferDesc,
542 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
543 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
546 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
548 TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
549 debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
550 lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
551 lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
553 if (This->renderer_device != NULL || This->capture_device != NULL) {
554 WARN("already initialized\n");
555 *lplpDirectSoundCaptureBuffer8 = NULL;
556 *lplpDirectSoundBuffer8 = NULL;
557 return DSERR_ALREADYINITIALIZED;
560 hr = DSOUND_Create8(&IID_IDirectSound8, &This->renderer_device);
562 hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
564 WARN("DirectSoundDevice_Initialize() failed\n");
565 *lplpDirectSoundCaptureBuffer8 = NULL;
566 *lplpDirectSoundBuffer8 = NULL;
570 IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
572 hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
573 (IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
575 WARN("IDirectSoundBufferImpl_Create() failed\n");
576 *lplpDirectSoundCaptureBuffer8 = NULL;
577 *lplpDirectSoundBuffer8 = NULL;
581 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &This->capture_device);
583 hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
585 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
586 *lplpDirectSoundCaptureBuffer8 = NULL;
587 *lplpDirectSoundBuffer8 = NULL;
591 hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,
593 (IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8,
596 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
597 *lplpDirectSoundCaptureBuffer8 = NULL;
598 *lplpDirectSoundBuffer8 = NULL;
605 static const IDirectSoundFullDuplexVtbl dsfdvt =
607 /* IUnknown methods */
608 IDirectSoundFullDuplexImpl_QueryInterface,
609 IDirectSoundFullDuplexImpl_AddRef,
610 IDirectSoundFullDuplexImpl_Release,
612 /* IDirectSoundFullDuplex methods */
613 IDirectSoundFullDuplexImpl_Initialize
616 HRESULT DSOUND_FullDuplexCreate(
618 LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
620 IDirectSoundFullDuplexImpl *This = NULL;
621 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
623 if (ppDSFD == NULL) {
624 WARN("invalid parameter: ppDSFD == NULL\n");
625 return DSERR_INVALIDPARAM;
628 if (!IsEqualIID(riid, &IID_IUnknown) &&
629 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
631 return E_NOINTERFACE;
634 /* Get dsound configuration */
635 setup_dsound_options();
637 This = HeapAlloc(GetProcessHeap(),
638 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
641 WARN("out of memory\n");
643 return DSERR_OUTOFMEMORY;
646 This->lpVtbl = &dsfdvt;
648 This->capture_device = NULL;
649 This->renderer_device = NULL;
651 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
656 /***************************************************************************
657 * DirectSoundFullDuplexCreate [DSOUND.10]
659 * Create and initialize a DirectSoundFullDuplex interface.
662 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
663 * pcGuidRenderDevice [I] Address of sound render device GUID.
664 * pcDSCBufferDesc [I] Address of capture buffer description.
665 * pcDSBufferDesc [I] Address of render buffer description.
666 * hWnd [I] Handle to application window.
667 * dwLevel [I] Cooperative level.
668 * ppDSFD [O] Address where full duplex interface returned.
669 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
670 * ppDSBuffer8 [0] Address where render buffer interface returned.
671 * pUnkOuter [I] Must be NULL.
675 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
676 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
679 DirectSoundFullDuplexCreate(
680 LPCGUID pcGuidCaptureDevice,
681 LPCGUID pcGuidRenderDevice,
682 LPCDSCBUFFERDESC pcDSCBufferDesc,
683 LPCDSBUFFERDESC pcDSBufferDesc,
686 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
687 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
688 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
692 IDirectSoundFullDuplexImpl *This = NULL;
693 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
694 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
695 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
696 ppDSBuffer8, pUnkOuter);
699 WARN("pUnkOuter != 0\n");
701 return DSERR_NOAGGREGATION;
704 if (pcDSCBufferDesc == NULL) {
705 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
707 return DSERR_INVALIDPARAM;
710 if (pcDSBufferDesc == NULL) {
711 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
713 return DSERR_INVALIDPARAM;
716 if (ppDSFD == NULL) {
717 WARN("invalid parameter: ppDSFD == NULL\n");
718 return DSERR_INVALIDPARAM;
721 if (ppDSCBuffer8 == NULL) {
722 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
724 return DSERR_INVALIDPARAM;
727 if (ppDSBuffer8 == NULL) {
728 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
730 return DSERR_INVALIDPARAM;
733 hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (LPDIRECTSOUNDFULLDUPLEX*)&This);
734 if (FAILED(hres)) return hres;
736 hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
741 hWnd, dwLevel, ppDSCBuffer8,
744 IUnknown_Release((LPDIRECTSOUNDFULLDUPLEX)This);
745 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
748 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;