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
35 #include "wine/debug.h"
38 #include "dsound_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
42 /*****************************************************************************
43 * IDirectSoundFullDuplex implementation structure
45 typedef struct IDirectSoundFullDuplexImpl
48 const IDirectSoundFullDuplexVtbl *lpVtbl;
51 /* IDirectSoundFullDuplexImpl fields */
52 IDirectSound8 *renderer_device;
53 IDirectSoundCapture *capture_device;
57 LPDIRECTSOUNDCAPTURE pDSC;
58 } IDirectSoundFullDuplexImpl;
60 typedef struct IDirectSoundFullDuplex_IUnknown {
61 const IUnknownVtbl *lpVtbl;
63 IDirectSoundFullDuplexImpl *pdsfd;
64 } IDirectSoundFullDuplex_IUnknown;
66 typedef struct IDirectSoundFullDuplex_IDirectSound8 {
67 const IDirectSound8Vtbl *lpVtbl;
69 IDirectSoundFullDuplexImpl *pdsfd;
70 } IDirectSoundFullDuplex_IDirectSound8;
72 typedef struct IDirectSoundFullDuplex_IDirectSoundCapture {
73 const IDirectSoundCaptureVtbl *lpVtbl;
75 IDirectSoundFullDuplexImpl *pdsfd;
76 } IDirectSoundFullDuplex_IDirectSoundCapture;
78 /*******************************************************************************
81 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
86 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
87 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
88 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
91 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
94 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
95 ULONG ref = InterlockedIncrement(&(This->ref));
96 TRACE("(%p) ref was %d\n", This, ref - 1);
100 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
103 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
104 ULONG ref = InterlockedDecrement(&(This->ref));
105 TRACE("(%p) ref was %d\n", This, ref + 1);
107 This->pdsfd->pUnknown = NULL;
108 HeapFree(GetProcessHeap(), 0, This);
109 TRACE("(%p) released\n", This);
114 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
116 IDirectSoundFullDuplex_IUnknown_QueryInterface,
117 IDirectSoundFullDuplex_IUnknown_AddRef,
118 IDirectSoundFullDuplex_IUnknown_Release
121 static HRESULT IDirectSoundFullDuplex_IUnknown_Create(
122 LPDIRECTSOUNDFULLDUPLEX pdsfd,
125 IDirectSoundFullDuplex_IUnknown * pdsfdunk;
126 TRACE("(%p,%p)\n",pdsfd,ppunk);
129 ERR("invalid parameter: pdsfd == NULL\n");
130 return DSERR_INVALIDPARAM;
134 ERR("invalid parameter: ppunk == NULL\n");
135 return DSERR_INVALIDPARAM;
138 pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
139 if (pdsfdunk == NULL) {
140 WARN("out of memory\n");
142 return DSERR_OUTOFMEMORY;
145 pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
147 pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
149 *ppunk = (LPUNKNOWN)pdsfdunk;
154 /*******************************************************************************
155 * IDirectSoundFullDuplex_IDirectSound8
157 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
158 LPDIRECTSOUND8 iface,
162 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
163 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
164 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
167 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
168 LPDIRECTSOUND8 iface)
170 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
171 ULONG ref = InterlockedIncrement(&(This->ref));
172 TRACE("(%p) ref was %d\n", This, ref - 1);
176 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
177 LPDIRECTSOUND8 iface)
179 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
180 ULONG ref = InterlockedDecrement(&(This->ref));
181 TRACE("(%p) ref was %d\n", This, ref + 1);
183 This->pdsfd->pDS8 = NULL;
184 HeapFree(GetProcessHeap(), 0, This);
185 TRACE("(%p) released\n", This);
190 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
191 LPDIRECTSOUND8 iface,
192 LPCDSBUFFERDESC dsbd,
193 LPLPDIRECTSOUNDBUFFER ppdsb,
196 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
197 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
198 return IDirectSound8_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk);
201 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
202 LPDIRECTSOUND8 iface,
205 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
206 TRACE("(%p,%p)\n",This,lpDSCaps);
207 return IDirectSound8_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
210 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
211 LPDIRECTSOUND8 iface,
212 LPDIRECTSOUNDBUFFER psb,
213 LPLPDIRECTSOUNDBUFFER ppdsb)
215 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
216 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
217 return IDirectSound8_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
220 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
221 LPDIRECTSOUND8 iface,
225 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
226 TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
227 return IDirectSound8_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
230 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
231 LPDIRECTSOUND8 iface)
233 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
234 TRACE("(%p)\n", This);
235 return IDirectSound8_Compact(This->pdsfd->renderer_device);
238 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
239 LPDIRECTSOUND8 iface,
240 LPDWORD lpdwSpeakerConfig)
242 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
243 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
244 return IDirectSound8_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
247 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
248 LPDIRECTSOUND8 iface,
251 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
252 TRACE("(%p,0x%08x)\n",This,config);
253 return IDirectSound8_SetSpeakerConfig(This->pdsfd->renderer_device,config);
256 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
257 LPDIRECTSOUND8 iface,
260 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
261 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
262 return IDirectSound8_Initialize(This->pdsfd->renderer_device,lpcGuid);
265 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_VerifyCertification(
266 LPDIRECTSOUND8 iface,
269 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
270 TRACE("(%p, %p)\n", This, cert);
271 return IDirectSound8_VerifyCertification(This->pdsfd->renderer_device,cert);
274 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
276 IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
277 IDirectSoundFullDuplex_IDirectSound8_AddRef,
278 IDirectSoundFullDuplex_IDirectSound8_Release,
279 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
280 IDirectSoundFullDuplex_IDirectSound8_GetCaps,
281 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
282 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
283 IDirectSoundFullDuplex_IDirectSound8_Compact,
284 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
285 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
286 IDirectSoundFullDuplex_IDirectSound8_Initialize,
287 IDirectSoundFullDuplex_IDirectSound8_VerifyCertification
290 static HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
291 LPDIRECTSOUNDFULLDUPLEX pdsfd,
292 LPDIRECTSOUND8 * ppds8)
294 IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
295 TRACE("(%p,%p)\n",pdsfd,ppds8);
298 ERR("invalid parameter: pdsfd == NULL\n");
299 return DSERR_INVALIDPARAM;
303 ERR("invalid parameter: ppds8 == NULL\n");
304 return DSERR_INVALIDPARAM;
307 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
308 WARN("not initialized\n");
310 return DSERR_UNINITIALIZED;
313 pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
314 if (pdsfdds8 == NULL) {
315 WARN("out of memory\n");
317 return DSERR_OUTOFMEMORY;
320 pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
322 pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
324 *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
329 /*******************************************************************************
330 * IDirectSoundFullDuplex_IDirectSoundCapture
332 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
333 LPDIRECTSOUNDCAPTURE iface,
337 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
338 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
339 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
342 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
343 LPDIRECTSOUNDCAPTURE iface)
345 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
346 ULONG ref = InterlockedIncrement(&(This->ref));
347 TRACE("(%p) ref was %d\n", This, ref - 1);
351 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
352 LPDIRECTSOUNDCAPTURE iface)
354 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
355 ULONG ref = InterlockedDecrement(&(This->ref));
356 TRACE("(%p) ref was %d\n", This, ref + 1);
358 This->pdsfd->pDSC = NULL;
359 HeapFree(GetProcessHeap(), 0, This);
360 TRACE("(%p) released\n", This);
365 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
366 LPDIRECTSOUNDCAPTURE iface,
367 LPCDSCBUFFERDESC lpcDSCBufferDesc,
368 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
371 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
372 TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
373 return IDirectSoundCapture_CreateCaptureBuffer(This->pdsfd->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
376 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
377 LPDIRECTSOUNDCAPTURE iface,
380 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
381 TRACE("(%p,%p)\n",This,lpDSCCaps);
382 return IDirectSoundCapture_GetCaps(This->pdsfd->capture_device, lpDSCCaps);
385 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
386 LPDIRECTSOUNDCAPTURE iface,
389 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
390 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
391 return IDirectSoundCapture_Initialize(This->pdsfd->capture_device,lpcGUID);
394 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
396 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
397 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
398 IDirectSoundFullDuplex_IDirectSoundCapture_Release,
399 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
400 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
401 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
404 static HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
405 LPDIRECTSOUNDFULLDUPLEX pdsfd,
406 LPDIRECTSOUNDCAPTURE8 * ppdsc8)
408 IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
409 TRACE("(%p,%p)\n",pdsfd,ppdsc8);
412 ERR("invalid parameter: pdsfd == NULL\n");
413 return DSERR_INVALIDPARAM;
416 if (ppdsc8 == NULL) {
417 ERR("invalid parameter: ppdsc8 == NULL\n");
418 return DSERR_INVALIDPARAM;
421 if (((IDirectSoundFullDuplexImpl*)pdsfd)->capture_device == NULL) {
422 WARN("not initialized\n");
424 return DSERR_UNINITIALIZED;
427 pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
428 if (pdsfddsc == NULL) {
429 WARN("out of memory\n");
431 return DSERR_OUTOFMEMORY;
434 pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
436 pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
438 *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
443 /***************************************************************************
444 * IDirectSoundFullDuplexImpl
447 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
449 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
450 ULONG ref = InterlockedIncrement(&(This->ref));
451 TRACE("(%p) ref was %d\n", This, ref - 1);
455 static HRESULT WINAPI
456 IDirectSoundFullDuplexImpl_QueryInterface(
457 LPDIRECTSOUNDFULLDUPLEX iface,
461 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
462 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
465 WARN("invalid parameter\n");
471 if (IsEqualIID(riid, &IID_IUnknown)) {
472 if (!This->pUnknown) {
473 IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
474 if (!This->pUnknown) {
475 WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
477 return E_NOINTERFACE;
480 IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
481 *ppobj = This->pUnknown;
483 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
484 IDirectSoundFullDuplexImpl_AddRef(iface);
487 } else if (IsEqualIID(riid, &IID_IDirectSound)
488 || IsEqualIID(riid, &IID_IDirectSound8)) {
490 IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
492 WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
494 return E_NOINTERFACE;
497 IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
500 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
502 IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
504 WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
506 return E_NOINTERFACE;
509 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
514 return E_NOINTERFACE;
518 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
520 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
521 ULONG ref = InterlockedDecrement(&(This->ref));
522 TRACE("(%p) ref was %d\n", This, ref - 1);
525 if (This->capture_device)
526 IDirectSoundCapture_Release(This->capture_device);
527 if (This->renderer_device)
528 IDirectSound_Release(This->renderer_device);
529 HeapFree( GetProcessHeap(), 0, This );
530 TRACE("(%p) released\n", This);
535 static HRESULT WINAPI
536 IDirectSoundFullDuplexImpl_Initialize(
537 LPDIRECTSOUNDFULLDUPLEX iface,
538 LPCGUID pCaptureGuid,
539 LPCGUID pRendererGuid,
540 LPCDSCBUFFERDESC lpDscBufferDesc,
541 LPCDSBUFFERDESC lpDsBufferDesc,
544 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
545 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
548 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
550 TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
551 debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
552 lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
553 lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
555 if (This->renderer_device != NULL || This->capture_device != NULL) {
556 WARN("already initialized\n");
557 *lplpDirectSoundCaptureBuffer8 = NULL;
558 *lplpDirectSoundBuffer8 = NULL;
559 return DSERR_ALREADYINITIALIZED;
562 hr = DSOUND_Create8(&IID_IDirectSound8, &This->renderer_device);
564 hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
566 WARN("DirectSoundDevice_Initialize() failed\n");
567 *lplpDirectSoundCaptureBuffer8 = NULL;
568 *lplpDirectSoundBuffer8 = NULL;
572 IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
574 hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
575 (IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
577 WARN("IDirectSoundBufferImpl_Create() failed\n");
578 *lplpDirectSoundCaptureBuffer8 = NULL;
579 *lplpDirectSoundBuffer8 = NULL;
583 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &This->capture_device);
585 hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
587 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
588 *lplpDirectSoundCaptureBuffer8 = NULL;
589 *lplpDirectSoundBuffer8 = NULL;
593 hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,
595 (IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8,
598 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
599 *lplpDirectSoundCaptureBuffer8 = NULL;
600 *lplpDirectSoundBuffer8 = NULL;
607 static const IDirectSoundFullDuplexVtbl dsfdvt =
609 /* IUnknown methods */
610 IDirectSoundFullDuplexImpl_QueryInterface,
611 IDirectSoundFullDuplexImpl_AddRef,
612 IDirectSoundFullDuplexImpl_Release,
614 /* IDirectSoundFullDuplex methods */
615 IDirectSoundFullDuplexImpl_Initialize
618 HRESULT DSOUND_FullDuplexCreate(
620 LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
622 IDirectSoundFullDuplexImpl *This = NULL;
623 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
625 if (ppDSFD == NULL) {
626 WARN("invalid parameter: ppDSFD == NULL\n");
627 return DSERR_INVALIDPARAM;
630 if (!IsEqualIID(riid, &IID_IUnknown) &&
631 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
633 return E_NOINTERFACE;
636 /* Get dsound configuration */
637 setup_dsound_options();
639 This = HeapAlloc(GetProcessHeap(),
640 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
643 WARN("out of memory\n");
645 return DSERR_OUTOFMEMORY;
648 This->lpVtbl = &dsfdvt;
650 This->capture_device = NULL;
651 This->renderer_device = NULL;
653 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
658 /***************************************************************************
659 * DirectSoundFullDuplexCreate [DSOUND.10]
661 * Create and initialize a DirectSoundFullDuplex interface.
664 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
665 * pcGuidRenderDevice [I] Address of sound render device GUID.
666 * pcDSCBufferDesc [I] Address of capture buffer description.
667 * pcDSBufferDesc [I] Address of render buffer description.
668 * hWnd [I] Handle to application window.
669 * dwLevel [I] Cooperative level.
670 * ppDSFD [O] Address where full duplex interface returned.
671 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
672 * ppDSBuffer8 [0] Address where render buffer interface returned.
673 * pUnkOuter [I] Must be NULL.
677 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
678 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
681 DirectSoundFullDuplexCreate(
682 LPCGUID pcGuidCaptureDevice,
683 LPCGUID pcGuidRenderDevice,
684 LPCDSCBUFFERDESC pcDSCBufferDesc,
685 LPCDSBUFFERDESC pcDSBufferDesc,
688 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
689 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
690 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
694 IDirectSoundFullDuplexImpl *This = NULL;
695 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
696 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
697 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
698 ppDSBuffer8, pUnkOuter);
701 WARN("pUnkOuter != 0\n");
703 return DSERR_NOAGGREGATION;
706 if (pcDSCBufferDesc == NULL) {
707 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
709 return DSERR_INVALIDPARAM;
712 if (pcDSBufferDesc == NULL) {
713 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
715 return DSERR_INVALIDPARAM;
718 if (ppDSFD == NULL) {
719 WARN("invalid parameter: ppDSFD == NULL\n");
720 return DSERR_INVALIDPARAM;
723 if (ppDSCBuffer8 == NULL) {
724 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
726 return DSERR_INVALIDPARAM;
729 if (ppDSBuffer8 == NULL) {
730 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
732 return DSERR_INVALIDPARAM;
735 hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (LPDIRECTSOUNDFULLDUPLEX*)&This);
736 if (FAILED(hres)) return hres;
738 hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
743 hWnd, dwLevel, ppDSCBuffer8,
746 IUnknown_Release((LPDIRECTSOUNDFULLDUPLEX)This);
747 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
750 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;