push 149f0a5527ac85057a8ef03858d34d91c36f97e8
[wine/hacks.git] / dlls / dsound / duplex.c
blobdbe811b2cd9529e9f28a3275da0885e3af796b68
1 /* DirectSoundFullDuplex
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2001 TransGaming Technologies, Inc.
6 * Copyright 2005 Robert Reif
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include <stdarg.h>
25 #define NONAMELESSSTRUCT
26 #define NONAMELESSUNION
27 #define CINTERFACE
28 #define COBJMACROS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "mmsystem.h"
33 #include "mmddk.h"
34 #include "winternl.h"
35 #include "wine/debug.h"
36 #include "dsound.h"
37 #include "dsdriver.h"
38 #include "dsound_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
42 /*****************************************************************************
43 * IDirectSoundFullDuplex implementation structure
45 typedef struct IDirectSoundFullDuplexImpl
47 /* IUnknown fields */
48 const IDirectSoundFullDuplexVtbl *lpVtbl;
49 LONG ref;
51 /* IDirectSoundFullDuplexImpl fields */
52 IDirectSound8 *renderer_device;
53 IDirectSoundCapture *capture_device;
55 LPUNKNOWN pUnknown;
56 LPDIRECTSOUND8 pDS8;
57 LPDIRECTSOUNDCAPTURE pDSC;
58 } IDirectSoundFullDuplexImpl;
60 typedef struct IDirectSoundFullDuplex_IUnknown {
61 const IUnknownVtbl *lpVtbl;
62 LONG ref;
63 IDirectSoundFullDuplexImpl *pdsfd;
64 } IDirectSoundFullDuplex_IUnknown;
66 typedef struct IDirectSoundFullDuplex_IDirectSound8 {
67 const IDirectSound8Vtbl *lpVtbl;
68 LONG ref;
69 IDirectSoundFullDuplexImpl *pdsfd;
70 } IDirectSoundFullDuplex_IDirectSound8;
72 typedef struct IDirectSoundFullDuplex_IDirectSoundCapture {
73 const IDirectSoundCaptureVtbl *lpVtbl;
74 LONG ref;
75 IDirectSoundFullDuplexImpl *pdsfd;
76 } IDirectSoundFullDuplex_IDirectSoundCapture;
78 /*******************************************************************************
79 * IUnknown
81 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
82 LPUNKNOWN iface,
83 REFIID riid,
84 LPVOID * ppobj)
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(
92 LPUNKNOWN iface)
94 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
95 ULONG ref = InterlockedIncrement(&(This->ref));
96 TRACE("(%p) ref was %d\n", This, ref - 1);
97 return ref;
100 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
101 LPUNKNOWN iface)
103 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
104 ULONG ref = InterlockedDecrement(&(This->ref));
105 TRACE("(%p) ref was %d\n", This, ref + 1);
106 if (!ref) {
107 This->pdsfd->pUnknown = NULL;
108 HeapFree(GetProcessHeap(), 0, This);
109 TRACE("(%p) released\n", This);
111 return ref;
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,
123 LPUNKNOWN * ppunk)
125 IDirectSoundFullDuplex_IUnknown * pdsfdunk;
126 TRACE("(%p,%p)\n",pdsfd,ppunk);
128 if (pdsfd == NULL) {
129 ERR("invalid parameter: pdsfd == NULL\n");
130 return DSERR_INVALIDPARAM;
133 if (ppunk == NULL) {
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");
141 *ppunk = NULL;
142 return DSERR_OUTOFMEMORY;
145 pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
146 pdsfdunk->ref = 0;
147 pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
149 *ppunk = (LPUNKNOWN)pdsfdunk;
151 return DS_OK;
154 /*******************************************************************************
155 * IDirectSoundFullDuplex_IDirectSound8
157 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
158 LPDIRECTSOUND8 iface,
159 REFIID riid,
160 LPVOID * ppobj)
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);
173 return ref;
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);
182 if (!ref) {
183 This->pdsfd->pDS8 = NULL;
184 HeapFree(GetProcessHeap(), 0, This);
185 TRACE("(%p) released\n", This);
187 return ref;
190 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
191 LPDIRECTSOUND8 iface,
192 LPCDSBUFFERDESC dsbd,
193 LPLPDIRECTSOUNDBUFFER ppdsb,
194 LPUNKNOWN lpunk)
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,
203 LPDSCAPS lpDSCaps)
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,
222 HWND hwnd,
223 DWORD level)
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,
249 DWORD config)
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,
258 LPCGUID lpcGuid)
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,
267 DWORD *cert)
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);
297 if (pdsfd == NULL) {
298 ERR("invalid parameter: pdsfd == NULL\n");
299 return DSERR_INVALIDPARAM;
302 if (ppds8 == NULL) {
303 ERR("invalid parameter: ppds8 == NULL\n");
304 return DSERR_INVALIDPARAM;
307 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
308 WARN("not initialized\n");
309 *ppds8 = NULL;
310 return DSERR_UNINITIALIZED;
313 pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
314 if (pdsfdds8 == NULL) {
315 WARN("out of memory\n");
316 *ppds8 = NULL;
317 return DSERR_OUTOFMEMORY;
320 pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
321 pdsfdds8->ref = 0;
322 pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
324 *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
326 return DS_OK;
329 /*******************************************************************************
330 * IDirectSoundFullDuplex_IDirectSoundCapture
332 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
333 LPDIRECTSOUNDCAPTURE iface,
334 REFIID riid,
335 LPVOID * ppobj)
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);
348 return ref;
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);
357 if (!ref) {
358 This->pdsfd->pDSC = NULL;
359 HeapFree(GetProcessHeap(), 0, This);
360 TRACE("(%p) released\n", This);
362 return ref;
365 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
366 LPDIRECTSOUNDCAPTURE iface,
367 LPCDSCBUFFERDESC lpcDSCBufferDesc,
368 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
369 LPUNKNOWN pUnk)
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,
378 LPDSCCAPS lpDSCCaps)
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,
387 LPCGUID lpcGUID)
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);
411 if (pdsfd == NULL) {
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");
423 *ppdsc8 = NULL;
424 return DSERR_UNINITIALIZED;
427 pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
428 if (pdsfddsc == NULL) {
429 WARN("out of memory\n");
430 *ppdsc8 = NULL;
431 return DSERR_OUTOFMEMORY;
434 pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
435 pdsfddsc->ref = 0;
436 pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
438 *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
440 return DS_OK;
443 /***************************************************************************
444 * IDirectSoundFullDuplexImpl
446 static ULONG WINAPI
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);
452 return ref;
455 static HRESULT WINAPI
456 IDirectSoundFullDuplexImpl_QueryInterface(
457 LPDIRECTSOUNDFULLDUPLEX iface,
458 REFIID riid,
459 LPVOID* ppobj )
461 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
462 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
464 if (ppobj == NULL) {
465 WARN("invalid parameter\n");
466 return E_INVALIDARG;
469 *ppobj = NULL;
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");
476 *ppobj = NULL;
477 return E_NOINTERFACE;
480 IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
481 *ppobj = This->pUnknown;
482 return S_OK;
483 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
484 IDirectSoundFullDuplexImpl_AddRef(iface);
485 *ppobj = This;
486 return S_OK;
487 } else if (IsEqualIID(riid, &IID_IDirectSound)
488 || IsEqualIID(riid, &IID_IDirectSound8)) {
489 if (!This->pDS8) {
490 IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
491 if (!This->pDS8) {
492 WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
493 *ppobj = NULL;
494 return E_NOINTERFACE;
497 IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
498 *ppobj = This->pDS8;
499 return S_OK;
500 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
501 if (!This->pDSC) {
502 IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
503 if (!This->pDSC) {
504 WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
505 *ppobj = NULL;
506 return E_NOINTERFACE;
509 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
510 *ppobj = This->pDSC;
511 return S_OK;
514 return E_NOINTERFACE;
517 static ULONG WINAPI
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);
524 if (!ref) {
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);
532 return ref;
535 static HRESULT WINAPI
536 IDirectSoundFullDuplexImpl_Initialize(
537 LPDIRECTSOUNDFULLDUPLEX iface,
538 LPCGUID pCaptureGuid,
539 LPCGUID pRendererGuid,
540 LPCDSCBUFFERDESC lpDscBufferDesc,
541 LPCDSBUFFERDESC lpDsBufferDesc,
542 HWND hWnd,
543 DWORD dwLevel,
544 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
545 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
547 HRESULT hr;
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);
563 if (SUCCEEDED(hr))
564 hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
565 if (hr != DS_OK) {
566 WARN("DirectSoundDevice_Initialize() failed\n");
567 *lplpDirectSoundCaptureBuffer8 = NULL;
568 *lplpDirectSoundBuffer8 = NULL;
569 return hr;
572 IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);
574 hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
575 (IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
576 if (hr != DS_OK) {
577 WARN("IDirectSoundBufferImpl_Create() failed\n");
578 *lplpDirectSoundCaptureBuffer8 = NULL;
579 *lplpDirectSoundBuffer8 = NULL;
580 return hr;
583 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &This->capture_device);
584 if (SUCCEEDED(hr))
585 hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
586 if (hr != DS_OK) {
587 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
588 *lplpDirectSoundCaptureBuffer8 = NULL;
589 *lplpDirectSoundBuffer8 = NULL;
590 return hr;
593 hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,
594 lpDscBufferDesc,
595 (IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8,
596 NULL);
597 if (hr != DS_OK) {
598 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
599 *lplpDirectSoundCaptureBuffer8 = NULL;
600 *lplpDirectSoundBuffer8 = NULL;
601 return hr;
604 return hr;
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(
619 REFIID riid,
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)) {
632 *ppDSFD = 0;
633 return E_NOINTERFACE;
636 /* Get dsound configuration */
637 setup_dsound_options();
639 This = HeapAlloc(GetProcessHeap(),
640 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
642 if (This == NULL) {
643 WARN("out of memory\n");
644 *ppDSFD = NULL;
645 return DSERR_OUTOFMEMORY;
648 This->lpVtbl = &dsfdvt;
649 This->ref = 1;
650 This->capture_device = NULL;
651 This->renderer_device = NULL;
653 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
655 return DS_OK;
658 /***************************************************************************
659 * DirectSoundFullDuplexCreate [DSOUND.10]
661 * Create and initialize a DirectSoundFullDuplex interface.
663 * PARAMS
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.
675 * RETURNS
676 * Success: DS_OK
677 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
678 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
680 HRESULT WINAPI
681 DirectSoundFullDuplexCreate(
682 LPCGUID pcGuidCaptureDevice,
683 LPCGUID pcGuidRenderDevice,
684 LPCDSCBUFFERDESC pcDSCBufferDesc,
685 LPCDSBUFFERDESC pcDSBufferDesc,
686 HWND hWnd,
687 DWORD dwLevel,
688 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
689 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
690 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
691 LPUNKNOWN pUnkOuter)
693 HRESULT hres;
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);
700 if (pUnkOuter) {
701 WARN("pUnkOuter != 0\n");
702 *ppDSFD = NULL;
703 return DSERR_NOAGGREGATION;
706 if (pcDSCBufferDesc == NULL) {
707 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
708 *ppDSFD = NULL;
709 return DSERR_INVALIDPARAM;
712 if (pcDSBufferDesc == NULL) {
713 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
714 *ppDSFD = NULL;
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");
725 *ppDSFD = NULL;
726 return DSERR_INVALIDPARAM;
729 if (ppDSBuffer8 == NULL) {
730 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
731 *ppDSFD = NULL;
732 return DSERR_INVALIDPARAM;
735 hres = DSOUND_FullDuplexCreate(&IID_IDirectSoundFullDuplex, (LPDIRECTSOUNDFULLDUPLEX*)&This);
736 if (FAILED(hres)) return hres;
738 hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
739 pcGuidCaptureDevice,
740 pcGuidRenderDevice,
741 pcDSCBufferDesc,
742 pcDSBufferDesc,
743 hWnd, dwLevel, ppDSCBuffer8,
744 ppDSBuffer8);
745 if (hres != DS_OK) {
746 IUnknown_Release((LPDIRECTSOUNDFULLDUPLEX)This);
747 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
748 *ppDSFD = NULL;
749 } else
750 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
752 return hres;