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 %d\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 %d\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 %d\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 %d\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%08x)\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 %d\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 %d\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%08x)\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 %d\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 %d\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 %d\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 %d\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,%x,%x,%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 HRESULT DSOUND_FullDuplexCreate(
765 LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
767 IDirectSoundFullDuplexImpl *This = NULL;
768 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
770 if (ppDSFD == NULL) {
771 WARN("invalid parameter: ppDSFD == NULL\n");
772 return DSERR_INVALIDPARAM;
775 if (!IsEqualIID(riid, &IID_IUnknown) &&
776 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
778 return E_NOINTERFACE;
781 /* Get dsound configuration */
782 setup_dsound_options();
784 This = HeapAlloc(GetProcessHeap(),
785 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
788 WARN("out of memory\n");
790 return DSERR_OUTOFMEMORY;
793 This->lpVtbl = &dsfdvt;
795 This->capture_device = NULL;
796 This->renderer_device = NULL;
798 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
803 /***************************************************************************
804 * DirectSoundFullDuplexCreate [DSOUND.10]
806 * Create and initialize a DirectSoundFullDuplex interface.
809 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
810 * pcGuidRenderDevice [I] Address of sound render device GUID.
811 * pcDSCBufferDesc [I] Address of capture buffer description.
812 * pcDSBufferDesc [I] Address of render buffer description.
813 * hWnd [I] Handle to application window.
814 * dwLevel [I] Cooperative level.
815 * ppDSFD [O] Address where full duplex interface returned.
816 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
817 * ppDSBuffer8 [0] Address where render buffer interface returned.
818 * pUnkOuter [I] Must be NULL.
822 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
823 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
826 DirectSoundFullDuplexCreate(
827 LPCGUID pcGuidCaptureDevice,
828 LPCGUID pcGuidRenderDevice,
829 LPCDSCBUFFERDESC pcDSCBufferDesc,
830 LPCDSBUFFERDESC pcDSBufferDesc,
833 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
834 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
835 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
839 IDirectSoundFullDuplexImpl *This = NULL;
840 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
841 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
842 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
843 ppDSBuffer8, pUnkOuter);
846 WARN("pUnkOuter != 0\n");
848 return DSERR_NOAGGREGATION;
851 if (pcDSCBufferDesc == NULL) {
852 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
854 return DSERR_INVALIDPARAM;
857 if (pcDSBufferDesc == NULL) {
858 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
860 return DSERR_INVALIDPARAM;
863 if (ppDSFD == NULL) {
864 WARN("invalid parameter: ppDSFD == NULL\n");
865 return DSERR_INVALIDPARAM;
868 if (ppDSCBuffer8 == NULL) {
869 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
871 return DSERR_INVALIDPARAM;
874 if (ppDSBuffer8 == NULL) {
875 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
877 return DSERR_INVALIDPARAM;
880 /* Get dsound configuration */
881 setup_dsound_options();
883 This = HeapAlloc(GetProcessHeap(),
884 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
887 WARN("out of memory\n");
889 return DSERR_OUTOFMEMORY;
892 This->lpVtbl = &dsfdvt;
894 This->capture_device = NULL;
895 This->renderer_device = NULL;
897 hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
902 hWnd, dwLevel, ppDSCBuffer8,
905 HeapFree(GetProcessHeap(), 0, This);
906 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
909 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;