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 /*******************************************************************************
45 static HRESULT WINAPI
IDirectSoundFullDuplex_IUnknown_QueryInterface(
50 IDirectSoundFullDuplex_IUnknown
*This
= (IDirectSoundFullDuplex_IUnknown
*)iface
;
51 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
52 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX
)This
->pdsfd
, riid
, ppobj
);
55 static ULONG WINAPI
IDirectSoundFullDuplex_IUnknown_AddRef(
58 IDirectSoundFullDuplex_IUnknown
*This
= (IDirectSoundFullDuplex_IUnknown
*)iface
;
59 ULONG ref
= InterlockedIncrement(&(This
->ref
));
60 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
64 static ULONG WINAPI
IDirectSoundFullDuplex_IUnknown_Release(
67 IDirectSoundFullDuplex_IUnknown
*This
= (IDirectSoundFullDuplex_IUnknown
*)iface
;
68 ULONG ref
= InterlockedDecrement(&(This
->ref
));
69 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
71 IDirectSound_Release(This
->pdsfd
->pUnknown
);
72 HeapFree(GetProcessHeap(), 0, This
);
73 TRACE("(%p) released\n", This
);
78 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl
=
80 IDirectSoundFullDuplex_IUnknown_QueryInterface
,
81 IDirectSoundFullDuplex_IUnknown_AddRef
,
82 IDirectSoundFullDuplex_IUnknown_Release
85 static HRESULT
IDirectSoundFullDuplex_IUnknown_Create(
86 LPDIRECTSOUNDFULLDUPLEX pdsfd
,
89 IDirectSoundFullDuplex_IUnknown
* pdsfdunk
;
90 TRACE("(%p,%p)\n",pdsfd
,ppunk
);
93 ERR("invalid parameter: pdsfd == NULL\n");
94 return DSERR_INVALIDPARAM
;
98 ERR("invalid parameter: ppunk == NULL\n");
99 return DSERR_INVALIDPARAM
;
102 pdsfdunk
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk
));
103 if (pdsfdunk
== NULL
) {
104 WARN("out of memory\n");
106 return DSERR_OUTOFMEMORY
;
109 pdsfdunk
->lpVtbl
= &DirectSoundFullDuplex_Unknown_Vtbl
;
111 pdsfdunk
->pdsfd
= (IDirectSoundFullDuplexImpl
*)pdsfd
;
113 *ppunk
= (LPUNKNOWN
)pdsfdunk
;
118 /*******************************************************************************
119 * IDirectSoundFullDuplex_IDirectSound
121 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_QueryInterface(
126 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
127 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
128 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX
)This
->pdsfd
, riid
, ppobj
);
131 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound_AddRef(
134 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
135 ULONG ref
= InterlockedIncrement(&(This
->ref
));
136 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
140 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound_Release(
143 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
144 ULONG ref
= InterlockedDecrement(&(This
->ref
));
145 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
147 IDirectSound_Release(This
->pdsfd
->pDS
);
148 HeapFree(GetProcessHeap(), 0, This
);
149 TRACE("(%p) released\n", This
);
154 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer(
156 LPCDSBUFFERDESC dsbd
,
157 LPLPDIRECTSOUNDBUFFER ppdsb
,
160 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
161 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
162 return DirectSoundDevice_CreateSoundBuffer(This
->pdsfd
->renderer_device
,dsbd
,ppdsb
,lpunk
,FALSE
);
165 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_GetCaps(
169 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
170 TRACE("(%p,%p)\n",This
,lpDSCaps
);
171 return DirectSoundDevice_GetCaps(This
->pdsfd
->renderer_device
, lpDSCaps
);
174 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer(
176 LPDIRECTSOUNDBUFFER psb
,
177 LPLPDIRECTSOUNDBUFFER ppdsb
)
179 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
180 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
181 return DirectSoundDevice_DuplicateSoundBuffer(This
->pdsfd
->renderer_device
,psb
,ppdsb
);
184 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel(
189 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
190 TRACE("(%p,%p,%s)\n",This
,hwnd
,dumpCooperativeLevel(level
));
191 return DirectSoundDevice_SetCooperativeLevel(This
->pdsfd
->renderer_device
,hwnd
,level
);
194 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_Compact(
197 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
198 TRACE("(%p)\n", This
);
199 return DirectSoundDevice_Compact(This
->pdsfd
->renderer_device
);
202 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig(
204 LPDWORD lpdwSpeakerConfig
)
206 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
207 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
208 return DirectSoundDevice_GetSpeakerConfig(This
->pdsfd
->renderer_device
,lpdwSpeakerConfig
);
211 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig(
215 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
216 TRACE("(%p,0x%08lx)\n",This
,config
);
217 return DirectSoundDevice_SetSpeakerConfig(This
->pdsfd
->renderer_device
,config
);
220 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound_Initialize(
224 IDirectSoundFullDuplex_IDirectSound
*This
= (IDirectSoundFullDuplex_IDirectSound
*)iface
;
225 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
226 return DirectSoundDevice_Initialize(&This
->pdsfd
->renderer_device
,lpcGuid
);
229 static const IDirectSoundVtbl DirectSoundFullDuplex_DirectSound_Vtbl
=
231 IDirectSoundFullDuplex_IDirectSound_QueryInterface
,
232 IDirectSoundFullDuplex_IDirectSound_AddRef
,
233 IDirectSoundFullDuplex_IDirectSound_Release
,
234 IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer
,
235 IDirectSoundFullDuplex_IDirectSound_GetCaps
,
236 IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer
,
237 IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel
,
238 IDirectSoundFullDuplex_IDirectSound_Compact
,
239 IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig
,
240 IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig
,
241 IDirectSoundFullDuplex_IDirectSound_Initialize
244 static HRESULT
IDirectSoundFullDuplex_IDirectSound_Create(
245 LPDIRECTSOUNDFULLDUPLEX pdsfd
,
246 LPDIRECTSOUND
* ppds
)
248 IDirectSoundFullDuplex_IDirectSound
* pdsfdds
;
249 TRACE("(%p,%p)\n",pdsfd
,ppds
);
252 ERR("invalid parameter: pdsfd == NULL\n");
253 return DSERR_INVALIDPARAM
;
257 ERR("invalid parameter: ppds == NULL\n");
258 return DSERR_INVALIDPARAM
;
261 if (((IDirectSoundFullDuplexImpl
*)pdsfd
)->renderer_device
== NULL
) {
262 WARN("not initialized\n");
264 return DSERR_UNINITIALIZED
;
267 pdsfdds
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds
));
268 if (pdsfdds
== NULL
) {
269 WARN("out of memory\n");
271 return DSERR_OUTOFMEMORY
;
274 pdsfdds
->lpVtbl
= &DirectSoundFullDuplex_DirectSound_Vtbl
;
276 pdsfdds
->pdsfd
= (IDirectSoundFullDuplexImpl
*)pdsfd
;
278 *ppds
= (LPDIRECTSOUND
)pdsfdds
;
283 /*******************************************************************************
284 * IDirectSoundFullDuplex_IDirectSound8
286 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
287 LPDIRECTSOUND8 iface
,
291 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
292 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
293 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX
)This
->pdsfd
, riid
, ppobj
);
296 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound8_AddRef(
297 LPDIRECTSOUND8 iface
)
299 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
300 ULONG ref
= InterlockedIncrement(&(This
->ref
));
301 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
305 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSound8_Release(
306 LPDIRECTSOUND8 iface
)
308 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
309 ULONG ref
= InterlockedDecrement(&(This
->ref
));
310 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
312 IDirectSound_Release(This
->pdsfd
->pDS8
);
313 HeapFree(GetProcessHeap(), 0, This
);
314 TRACE("(%p) released\n", This
);
319 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
320 LPDIRECTSOUND8 iface
,
321 LPCDSBUFFERDESC dsbd
,
322 LPLPDIRECTSOUNDBUFFER ppdsb
,
325 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
326 TRACE("(%p,%p,%p,%p)\n",This
,dsbd
,ppdsb
,lpunk
);
327 return DirectSoundDevice_CreateSoundBuffer(This
->pdsfd
->renderer_device
,dsbd
,ppdsb
,lpunk
,TRUE
);
330 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_GetCaps(
331 LPDIRECTSOUND8 iface
,
334 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
335 TRACE("(%p,%p)\n",This
,lpDSCaps
);
336 return DirectSoundDevice_GetCaps(This
->pdsfd
->renderer_device
, lpDSCaps
);
339 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
340 LPDIRECTSOUND8 iface
,
341 LPDIRECTSOUNDBUFFER psb
,
342 LPLPDIRECTSOUNDBUFFER ppdsb
)
344 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
345 TRACE("(%p,%p,%p)\n",This
,psb
,ppdsb
);
346 return DirectSoundDevice_DuplicateSoundBuffer(This
->pdsfd
->renderer_device
,psb
,ppdsb
);
349 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
350 LPDIRECTSOUND8 iface
,
354 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
355 TRACE("(%p,%p,%s)\n",This
,hwnd
,dumpCooperativeLevel(level
));
356 return DirectSoundDevice_SetCooperativeLevel(This
->pdsfd
->renderer_device
,hwnd
,level
);
359 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_Compact(
360 LPDIRECTSOUND8 iface
)
362 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
363 TRACE("(%p)\n", This
);
364 return DirectSoundDevice_Compact(This
->pdsfd
->renderer_device
);
367 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
368 LPDIRECTSOUND8 iface
,
369 LPDWORD lpdwSpeakerConfig
)
371 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
372 TRACE("(%p, %p)\n", This
, lpdwSpeakerConfig
);
373 return DirectSoundDevice_GetSpeakerConfig(This
->pdsfd
->renderer_device
,lpdwSpeakerConfig
);
376 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
377 LPDIRECTSOUND8 iface
,
380 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
381 TRACE("(%p,0x%08lx)\n",This
,config
);
382 return DirectSoundDevice_SetSpeakerConfig(This
->pdsfd
->renderer_device
,config
);
385 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSound8_Initialize(
386 LPDIRECTSOUND8 iface
,
389 IDirectSoundFullDuplex_IDirectSound8
*This
= (IDirectSoundFullDuplex_IDirectSound8
*)iface
;
390 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGuid
));
391 return DirectSoundDevice_Initialize(&This
->pdsfd
->renderer_device
,lpcGuid
);
394 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl
=
396 IDirectSoundFullDuplex_IDirectSound8_QueryInterface
,
397 IDirectSoundFullDuplex_IDirectSound8_AddRef
,
398 IDirectSoundFullDuplex_IDirectSound8_Release
,
399 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer
,
400 IDirectSoundFullDuplex_IDirectSound8_GetCaps
,
401 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer
,
402 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel
,
403 IDirectSoundFullDuplex_IDirectSound8_Compact
,
404 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig
,
405 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig
,
406 IDirectSoundFullDuplex_IDirectSound8_Initialize
409 static HRESULT
IDirectSoundFullDuplex_IDirectSound8_Create(
410 LPDIRECTSOUNDFULLDUPLEX pdsfd
,
411 LPDIRECTSOUND8
* ppds8
)
413 IDirectSoundFullDuplex_IDirectSound8
* pdsfdds8
;
414 TRACE("(%p,%p)\n",pdsfd
,ppds8
);
417 ERR("invalid parameter: pdsfd == NULL\n");
418 return DSERR_INVALIDPARAM
;
422 ERR("invalid parameter: ppds8 == NULL\n");
423 return DSERR_INVALIDPARAM
;
426 if (((IDirectSoundFullDuplexImpl
*)pdsfd
)->renderer_device
== NULL
) {
427 WARN("not initialized\n");
429 return DSERR_UNINITIALIZED
;
432 pdsfdds8
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8
));
433 if (pdsfdds8
== NULL
) {
434 WARN("out of memory\n");
436 return DSERR_OUTOFMEMORY
;
439 pdsfdds8
->lpVtbl
= &DirectSoundFullDuplex_DirectSound8_Vtbl
;
441 pdsfdds8
->pdsfd
= (IDirectSoundFullDuplexImpl
*)pdsfd
;
443 *ppds8
= (LPDIRECTSOUND8
)pdsfdds8
;
448 /*******************************************************************************
449 * IDirectSoundFullDuplex_IDirectSoundCapture
451 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
452 LPDIRECTSOUNDCAPTURE iface
,
456 IDirectSoundFullDuplex_IDirectSoundCapture
*This
= (IDirectSoundFullDuplex_IDirectSoundCapture
*)iface
;
457 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppobj
);
458 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX
)This
->pdsfd
, riid
, ppobj
);
461 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
462 LPDIRECTSOUNDCAPTURE iface
)
464 IDirectSoundFullDuplex_IDirectSoundCapture
*This
= (IDirectSoundFullDuplex_IDirectSoundCapture
*)iface
;
465 ULONG ref
= InterlockedIncrement(&(This
->ref
));
466 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
470 static ULONG WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_Release(
471 LPDIRECTSOUNDCAPTURE iface
)
473 IDirectSoundFullDuplex_IDirectSoundCapture
*This
= (IDirectSoundFullDuplex_IDirectSoundCapture
*)iface
;
474 ULONG ref
= InterlockedDecrement(&(This
->ref
));
475 TRACE("(%p) ref was %ld\n", This
, ref
+ 1);
477 IDirectSoundCapture_Release(This
->pdsfd
->pDSC
);
478 HeapFree(GetProcessHeap(), 0, This
);
479 TRACE("(%p) released\n", This
);
484 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
485 LPDIRECTSOUNDCAPTURE iface
,
486 LPCDSCBUFFERDESC lpcDSCBufferDesc
,
487 LPDIRECTSOUNDCAPTUREBUFFER
* lplpDSCaptureBuffer
,
490 IDirectSoundFullDuplex_IDirectSoundCapture
*This
= (IDirectSoundFullDuplex_IDirectSoundCapture
*)iface
;
491 TRACE("(%p,%p,%p,%p)\n",This
,lpcDSCBufferDesc
,lplpDSCaptureBuffer
,pUnk
);
492 return IDirectSoundCaptureImpl_CreateCaptureBuffer(This
->pdsfd
->pDSC
,lpcDSCBufferDesc
,lplpDSCaptureBuffer
,pUnk
);
495 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
496 LPDIRECTSOUNDCAPTURE iface
,
499 IDirectSoundFullDuplex_IDirectSoundCapture
*This
= (IDirectSoundFullDuplex_IDirectSoundCapture
*)iface
;
500 TRACE("(%p,%p)\n",This
,lpDSCCaps
);
501 return IDirectSoundCaptureImpl_GetCaps(This
->pdsfd
->pDSC
, lpDSCCaps
);
504 static HRESULT WINAPI
IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
505 LPDIRECTSOUNDCAPTURE iface
,
508 IDirectSoundFullDuplex_IDirectSoundCapture
*This
= (IDirectSoundFullDuplex_IDirectSoundCapture
*)iface
;
509 TRACE("(%p, %s)\n", This
, debugstr_guid(lpcGUID
));
510 return IDirectSoundCaptureImpl_Initialize(This
->pdsfd
->pDSC
,lpcGUID
);
513 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl
=
515 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface
,
516 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef
,
517 IDirectSoundFullDuplex_IDirectSoundCapture_Release
,
518 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer
,
519 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps
,
520 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
523 static HRESULT
IDirectSoundFullDuplex_IDirectSoundCapture_Create(
524 LPDIRECTSOUNDFULLDUPLEX pdsfd
,
525 LPDIRECTSOUNDCAPTURE8
* ppdsc8
)
527 IDirectSoundFullDuplex_IDirectSoundCapture
* pdsfddsc
;
528 TRACE("(%p,%p)\n",pdsfd
,ppdsc8
);
531 ERR("invalid parameter: pdsfd == NULL\n");
532 return DSERR_INVALIDPARAM
;
535 if (ppdsc8
== NULL
) {
536 ERR("invalid parameter: ppdsc8 == NULL\n");
537 return DSERR_INVALIDPARAM
;
540 if (((IDirectSoundFullDuplexImpl
*)pdsfd
)->capture_device
== NULL
) {
541 WARN("not initialized\n");
543 return DSERR_UNINITIALIZED
;
546 pdsfddsc
= HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc
));
547 if (pdsfddsc
== NULL
) {
548 WARN("out of memory\n");
550 return DSERR_OUTOFMEMORY
;
553 pdsfddsc
->lpVtbl
= &DirectSoundFullDuplex_DirectSoundCapture_Vtbl
;
555 pdsfddsc
->pdsfd
= (IDirectSoundFullDuplexImpl
*)pdsfd
;
557 *ppdsc8
= (LPDIRECTSOUNDCAPTURE
)pdsfddsc
;
562 /***************************************************************************
563 * IDirectSoundFullDuplexImpl
566 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface
)
568 IDirectSoundFullDuplexImpl
*This
= (IDirectSoundFullDuplexImpl
*)iface
;
569 ULONG ref
= InterlockedIncrement(&(This
->ref
));
570 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
574 static HRESULT WINAPI
575 IDirectSoundFullDuplexImpl_QueryInterface(
576 LPDIRECTSOUNDFULLDUPLEX iface
,
580 IDirectSoundFullDuplexImpl
*This
= (IDirectSoundFullDuplexImpl
*)iface
;
581 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
584 WARN("invalid parameter\n");
590 if (IsEqualIID(riid
, &IID_IUnknown
)) {
591 if (!This
->pUnknown
) {
592 IDirectSoundFullDuplex_IUnknown_Create(iface
, &This
->pUnknown
);
593 if (!This
->pUnknown
) {
594 WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
596 return E_NOINTERFACE
;
599 IDirectSoundFullDuplex_IUnknown_AddRef(This
->pUnknown
);
600 *ppobj
= This
->pUnknown
;
602 } else if (IsEqualIID(riid
, &IID_IDirectSoundFullDuplex
)) {
603 IDirectSoundFullDuplexImpl_AddRef(iface
);
606 } else if (IsEqualIID(riid
, &IID_IDirectSound
)) {
608 IDirectSoundFullDuplex_IDirectSound_Create(iface
, &This
->pDS
);
610 WARN("IDirectSoundFullDuplex_IDirectSound_Create() failed\n");
612 return E_NOINTERFACE
;
615 IDirectSoundFullDuplex_IDirectSound_AddRef(This
->pDS
);
618 } else if (IsEqualIID(riid
, &IID_IDirectSound8
)) {
620 IDirectSoundFullDuplex_IDirectSound8_Create(iface
, &This
->pDS8
);
622 WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
624 return E_NOINTERFACE
;
627 IDirectSoundFullDuplex_IDirectSound8_AddRef(This
->pDS8
);
630 } else if (IsEqualIID(riid
, &IID_IDirectSoundCapture
)) {
632 IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface
, &This
->pDSC
);
634 WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
636 return E_NOINTERFACE
;
639 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This
->pDSC
);
644 return E_NOINTERFACE
;
648 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface
)
650 IDirectSoundFullDuplexImpl
*This
= (IDirectSoundFullDuplexImpl
*)iface
;
651 ULONG ref
= InterlockedDecrement(&(This
->ref
));
652 TRACE("(%p) ref was %ld\n", This
, ref
- 1);
655 if (This
->capture_device
)
656 DirectSoundCaptureDevice_Release(This
->capture_device
);
657 if (This
->renderer_device
)
658 DirectSoundDevice_Release(This
->renderer_device
);
659 HeapFree( GetProcessHeap(), 0, This
);
660 TRACE("(%p) released\n", This
);
665 static HRESULT WINAPI
666 IDirectSoundFullDuplexImpl_Initialize(
667 LPDIRECTSOUNDFULLDUPLEX iface
,
668 LPCGUID pCaptureGuid
,
669 LPCGUID pRendererGuid
,
670 LPCDSCBUFFERDESC lpDscBufferDesc
,
671 LPCDSBUFFERDESC lpDsBufferDesc
,
674 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8
,
675 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8
)
678 IDirectSoundFullDuplexImpl
*This
= (IDirectSoundFullDuplexImpl
*)iface
;
679 IDirectSoundBufferImpl
* dsb
;
681 TRACE("(%p,%s,%s,%p,%p,%lx,%lx,%p,%p)\n", This
,
682 debugstr_guid(pCaptureGuid
), debugstr_guid(pRendererGuid
),
683 lpDscBufferDesc
, lpDsBufferDesc
, (DWORD
)hWnd
, dwLevel
,
684 lplpDirectSoundCaptureBuffer8
, lplpDirectSoundBuffer8
);
686 if (This
->renderer_device
!= NULL
|| This
->capture_device
!= NULL
) {
687 WARN("already initialized\n");
688 *lplpDirectSoundCaptureBuffer8
= NULL
;
689 *lplpDirectSoundBuffer8
= NULL
;
690 return DSERR_ALREADYINITIALIZED
;
693 hr
= DirectSoundDevice_Initialize(&This
->renderer_device
, pRendererGuid
);
695 WARN("DirectSoundDevice_Initialize() failed\n");
696 *lplpDirectSoundCaptureBuffer8
= NULL
;
697 *lplpDirectSoundBuffer8
= NULL
;
701 if (dwLevel
==DSSCL_PRIORITY
|| dwLevel
==DSSCL_EXCLUSIVE
) {
702 WARN("level=%s not fully supported\n",
703 dwLevel
==DSSCL_PRIORITY
? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
705 This
->renderer_device
->priolevel
= dwLevel
;
707 hr
= DSOUND_PrimarySetFormat(This
->renderer_device
, lpDsBufferDesc
->lpwfxFormat
);
709 WARN("DSOUND_PrimarySetFormat() failed\n");
710 *lplpDirectSoundCaptureBuffer8
= NULL
;
711 *lplpDirectSoundBuffer8
= NULL
;
714 hr
= IDirectSoundBufferImpl_Create(This
->renderer_device
, &dsb
, lpDsBufferDesc
);
716 WARN("IDirectSoundBufferImpl_Create() failed\n");
717 *lplpDirectSoundCaptureBuffer8
= NULL
;
718 *lplpDirectSoundBuffer8
= NULL
;
722 hr
= SecondaryBufferImpl_Create(dsb
, (SecondaryBufferImpl
**)lplpDirectSoundBuffer8
);
724 WARN("SecondaryBufferImpl_Create() failed\n");
725 *lplpDirectSoundCaptureBuffer8
= NULL
;
726 *lplpDirectSoundBuffer8
= NULL
;
729 IDirectSoundBuffer8_AddRef(*lplpDirectSoundBuffer8
);
731 hr
= DirectSoundCaptureDevice_Initialize(&This
->capture_device
, pCaptureGuid
);
733 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
734 *lplpDirectSoundCaptureBuffer8
= NULL
;
735 *lplpDirectSoundBuffer8
= NULL
;
739 hr
= IDirectSoundCaptureBufferImpl_Create(This
->capture_device
,
740 (IDirectSoundCaptureBufferImpl
**)lplpDirectSoundCaptureBuffer8
,
743 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
744 *lplpDirectSoundCaptureBuffer8
= NULL
;
745 *lplpDirectSoundBuffer8
= NULL
;
752 static const IDirectSoundFullDuplexVtbl dsfdvt
=
754 /* IUnknown methods */
755 IDirectSoundFullDuplexImpl_QueryInterface
,
756 IDirectSoundFullDuplexImpl_AddRef
,
757 IDirectSoundFullDuplexImpl_Release
,
759 /* IDirectSoundFullDuplex methods */
760 IDirectSoundFullDuplexImpl_Initialize
763 static HRESULT
DSOUND_FullDuplexCreate(LPDIRECTSOUNDFULLDUPLEX
* ppDSFD
, IUnknown
*pUnkOuter
)
765 IDirectSoundFullDuplexImpl
*This
= NULL
;
768 WARN("pUnkOuter != 0\n");
770 return DSERR_NOAGGREGATION
;
773 if (ppDSFD
== NULL
) {
774 WARN("invalid parameter: ppDSFD == NULL\n");
775 return DSERR_INVALIDPARAM
;
778 /* Get dsound configuration */
779 setup_dsound_options();
781 This
= HeapAlloc(GetProcessHeap(),
782 HEAP_ZERO_MEMORY
, sizeof(IDirectSoundFullDuplexImpl
));
785 WARN("out of memory\n");
787 return DSERR_OUTOFMEMORY
;
790 This
->lpVtbl
= &dsfdvt
;
792 This
->capture_device
= NULL
;
793 This
->renderer_device
= NULL
;
795 *ppDSFD
= (LPDIRECTSOUNDFULLDUPLEX
)This
;
800 /***************************************************************************
801 * DirectSoundFullDuplexCreate [DSOUND.10]
803 * Create and initialize a DirectSoundFullDuplex interface.
806 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
807 * pcGuidRenderDevice [I] Address of sound render device GUID.
808 * pcDSCBufferDesc [I] Address of capture buffer description.
809 * pcDSBufferDesc [I] Address of render buffer description.
810 * hWnd [I] Handle to application window.
811 * dwLevel [I] Cooperative level.
812 * ppDSFD [O] Address where full duplex interface returned.
813 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
814 * ppDSBuffer8 [0] Address where render buffer interface returned.
815 * pUnkOuter [I] Must be NULL.
819 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
820 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
823 DirectSoundFullDuplexCreate(
824 LPCGUID pcGuidCaptureDevice
,
825 LPCGUID pcGuidRenderDevice
,
826 LPCDSCBUFFERDESC pcDSCBufferDesc
,
827 LPCDSBUFFERDESC pcDSBufferDesc
,
830 LPDIRECTSOUNDFULLDUPLEX
*ppDSFD
,
831 LPDIRECTSOUNDCAPTUREBUFFER8
*ppDSCBuffer8
,
832 LPDIRECTSOUNDBUFFER8
*ppDSBuffer8
,
836 IDirectSoundFullDuplexImpl
*This
= NULL
;
837 TRACE("(%s,%s,%p,%p,%p,%lx,%p,%p,%p,%p)\n",
838 debugstr_guid(pcGuidCaptureDevice
), debugstr_guid(pcGuidRenderDevice
),
839 pcDSCBufferDesc
, pcDSBufferDesc
, hWnd
, dwLevel
, ppDSFD
, ppDSCBuffer8
,
840 ppDSBuffer8
, pUnkOuter
);
843 WARN("pUnkOuter != 0\n");
845 return DSERR_NOAGGREGATION
;
848 if (pcDSCBufferDesc
== NULL
) {
849 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
851 return DSERR_INVALIDPARAM
;
854 if (pcDSBufferDesc
== NULL
) {
855 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
857 return DSERR_INVALIDPARAM
;
860 if (ppDSFD
== NULL
) {
861 WARN("invalid parameter: ppDSFD == NULL\n");
862 return DSERR_INVALIDPARAM
;
865 if (ppDSCBuffer8
== NULL
) {
866 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
868 return DSERR_INVALIDPARAM
;
871 if (ppDSBuffer8
== NULL
) {
872 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
874 return DSERR_INVALIDPARAM
;
877 /* Get dsound configuration */
878 setup_dsound_options();
880 This
= HeapAlloc(GetProcessHeap(),
881 HEAP_ZERO_MEMORY
, sizeof(IDirectSoundFullDuplexImpl
));
884 WARN("out of memory\n");
886 return DSERR_OUTOFMEMORY
;
889 This
->lpVtbl
= &dsfdvt
;
891 This
->capture_device
= NULL
;
892 This
->renderer_device
= NULL
;
894 hres
= IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX
)This
,
899 hWnd
, dwLevel
, ppDSCBuffer8
,
902 HeapFree(GetProcessHeap(), 0, This
);
903 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
906 *ppDSFD
= (LPDIRECTSOUNDFULLDUPLEX
)This
;
911 /*******************************************************************************
912 * DirectSoundFullDuplex ClassFactory
915 static HRESULT WINAPI
916 DSFDCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
918 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
920 FIXME("(%p)->(%s,%p),stub!\n",This
,debugstr_guid(riid
),ppobj
);
921 return E_NOINTERFACE
;
925 DSFDCF_AddRef(LPCLASSFACTORY iface
)
927 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
928 TRACE("(%p) ref was %ld\n", This
, This
->ref
);
929 return InterlockedIncrement(&(This
->ref
));
933 DSFDCF_Release(LPCLASSFACTORY iface
)
935 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
936 /* static class, won't be freed */
937 TRACE("(%p) ref was %ld\n", This
, This
->ref
);
938 return InterlockedDecrement(&(This
->ref
));
941 static HRESULT WINAPI
942 DSFDCF_CreateInstance(
943 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
)
945 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
947 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
950 WARN("aggregation not supported\n");
951 return CLASS_E_NOAGGREGATION
;
955 WARN("invalid parameter\n");
961 if ( IsEqualGUID( &IID_IDirectSoundFullDuplex
, riid
) )
962 return DSOUND_FullDuplexCreate((LPDIRECTSOUNDFULLDUPLEX
*)ppobj
,pOuter
);
964 WARN("(%p,%p,%s,%p) Interface not found!\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
965 return E_NOINTERFACE
;
968 static HRESULT WINAPI
969 DSFDCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
)
971 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
972 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
976 static const IClassFactoryVtbl DSFDCF_Vtbl
=
978 DSFDCF_QueryInterface
,
981 DSFDCF_CreateInstance
,
985 IClassFactoryImpl DSOUND_FULLDUPLEX_CF
= { &DSFDCF_Vtbl
, 1 };