Release 0.9.14.
[wine/multimedia.git] / dlls / dsound / duplex.c
blobe97e49dbe233549e029daf29048a7bf314f69349
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 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "mmsystem.h"
31 #include "mmddk.h"
32 #include "winreg.h"
33 #include "winternl.h"
34 #include "winnls.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 * IUnknown
45 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
46 LPUNKNOWN iface,
47 REFIID riid,
48 LPVOID * ppobj)
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(
56 LPUNKNOWN iface)
58 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
59 ULONG ref = InterlockedIncrement(&(This->ref));
60 TRACE("(%p) ref was %ld\n", This, ref - 1);
61 return ref;
64 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
65 LPUNKNOWN iface)
67 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
68 ULONG ref = InterlockedDecrement(&(This->ref));
69 TRACE("(%p) ref was %ld\n", This, ref + 1);
70 if (!ref) {
71 IDirectSound_Release(This->pdsfd->pUnknown);
72 HeapFree(GetProcessHeap(), 0, This);
73 TRACE("(%p) released\n", This);
75 return ref;
78 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
80 IDirectSoundFullDuplex_IUnknown_QueryInterface,
81 IDirectSoundFullDuplex_IUnknown_AddRef,
82 IDirectSoundFullDuplex_IUnknown_Release
85 HRESULT IDirectSoundFullDuplex_IUnknown_Create(
86 LPDIRECTSOUNDFULLDUPLEX pdsfd,
87 LPUNKNOWN * ppunk)
89 IDirectSoundFullDuplex_IUnknown * pdsfdunk;
90 TRACE("(%p,%p)\n",pdsfd,ppunk);
92 if (pdsfd == NULL) {
93 ERR("invalid parameter: pdsfd == NULL\n");
94 return DSERR_INVALIDPARAM;
97 if (ppunk == NULL) {
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");
105 *ppunk = NULL;
106 return DSERR_OUTOFMEMORY;
109 pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
110 pdsfdunk->ref = 0;
111 pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
113 *ppunk = (LPUNKNOWN)pdsfdunk;
115 return DS_OK;
118 /*******************************************************************************
119 * IDirectSoundFullDuplex_IDirectSound
121 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_QueryInterface(
122 LPDIRECTSOUND iface,
123 REFIID riid,
124 LPVOID * ppobj)
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(
132 LPDIRECTSOUND iface)
134 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
135 ULONG ref = InterlockedIncrement(&(This->ref));
136 TRACE("(%p) ref was %ld\n", This, ref - 1);
137 return ref;
140 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_Release(
141 LPDIRECTSOUND iface)
143 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
144 ULONG ref = InterlockedDecrement(&(This->ref));
145 TRACE("(%p) ref was %ld\n", This, ref + 1);
146 if (!ref) {
147 IDirectSound_Release(This->pdsfd->pDS);
148 HeapFree(GetProcessHeap(), 0, This);
149 TRACE("(%p) released\n", This);
151 return ref;
154 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer(
155 LPDIRECTSOUND iface,
156 LPCDSBUFFERDESC dsbd,
157 LPLPDIRECTSOUNDBUFFER ppdsb,
158 LPUNKNOWN lpunk)
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(
166 LPDIRECTSOUND iface,
167 LPDSCAPS lpDSCaps)
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(
175 LPDIRECTSOUND iface,
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(
185 LPDIRECTSOUND iface,
186 HWND hwnd,
187 DWORD level)
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(
195 LPDIRECTSOUND iface)
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(
203 LPDIRECTSOUND iface,
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(
212 LPDIRECTSOUND iface,
213 DWORD config)
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(
221 LPDIRECTSOUND iface,
222 LPCGUID lpcGuid)
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 HRESULT IDirectSoundFullDuplex_IDirectSound_Create(
245 LPDIRECTSOUNDFULLDUPLEX pdsfd,
246 LPDIRECTSOUND * ppds)
248 IDirectSoundFullDuplex_IDirectSound * pdsfdds;
249 TRACE("(%p,%p)\n",pdsfd,ppds);
251 if (pdsfd == NULL) {
252 ERR("invalid parameter: pdsfd == NULL\n");
253 return DSERR_INVALIDPARAM;
256 if (ppds == NULL) {
257 ERR("invalid parameter: ppds == NULL\n");
258 return DSERR_INVALIDPARAM;
261 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
262 WARN("not initialized\n");
263 *ppds = NULL;
264 return DSERR_UNINITIALIZED;
267 pdsfdds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds));
268 if (pdsfdds == NULL) {
269 WARN("out of memory\n");
270 *ppds = NULL;
271 return DSERR_OUTOFMEMORY;
274 pdsfdds->lpVtbl = &DirectSoundFullDuplex_DirectSound_Vtbl;
275 pdsfdds->ref = 0;
276 pdsfdds->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
278 *ppds = (LPDIRECTSOUND)pdsfdds;
280 return DS_OK;
283 /*******************************************************************************
284 * IDirectSoundFullDuplex_IDirectSound8
286 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
287 LPDIRECTSOUND8 iface,
288 REFIID riid,
289 LPVOID * ppobj)
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);
302 return ref;
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);
311 if (!ref) {
312 IDirectSound_Release(This->pdsfd->pDS8);
313 HeapFree(GetProcessHeap(), 0, This);
314 TRACE("(%p) released\n", This);
316 return ref;
319 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
320 LPDIRECTSOUND8 iface,
321 LPCDSBUFFERDESC dsbd,
322 LPLPDIRECTSOUNDBUFFER ppdsb,
323 LPUNKNOWN lpunk)
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,
332 LPDSCAPS lpDSCaps)
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,
351 HWND hwnd,
352 DWORD level)
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,
378 DWORD config)
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,
387 LPCGUID lpcGuid)
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 HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
410 LPDIRECTSOUNDFULLDUPLEX pdsfd,
411 LPDIRECTSOUND8 * ppds8)
413 IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
414 TRACE("(%p,%p)\n",pdsfd,ppds8);
416 if (pdsfd == NULL) {
417 ERR("invalid parameter: pdsfd == NULL\n");
418 return DSERR_INVALIDPARAM;
421 if (ppds8 == NULL) {
422 ERR("invalid parameter: ppds8 == NULL\n");
423 return DSERR_INVALIDPARAM;
426 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
427 WARN("not initialized\n");
428 *ppds8 = NULL;
429 return DSERR_UNINITIALIZED;
432 pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
433 if (pdsfdds8 == NULL) {
434 WARN("out of memory\n");
435 *ppds8 = NULL;
436 return DSERR_OUTOFMEMORY;
439 pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
440 pdsfdds8->ref = 0;
441 pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
443 *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
445 return DS_OK;
448 /*******************************************************************************
449 * IDirectSoundFullDuplex_IDirectSoundCapture
451 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
452 LPDIRECTSOUNDCAPTURE iface,
453 REFIID riid,
454 LPVOID * ppobj)
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);
467 return ref;
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);
476 if (!ref) {
477 IDirectSoundCapture_Release(This->pdsfd->pDSC);
478 HeapFree(GetProcessHeap(), 0, This);
479 TRACE("(%p) released\n", This);
481 return ref;
484 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
485 LPDIRECTSOUNDCAPTURE iface,
486 LPCDSCBUFFERDESC lpcDSCBufferDesc,
487 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
488 LPUNKNOWN pUnk)
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,
497 LPDSCCAPS lpDSCCaps)
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,
506 LPCGUID lpcGUID)
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 HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
524 LPDIRECTSOUNDFULLDUPLEX pdsfd,
525 LPDIRECTSOUNDCAPTURE8 * ppdsc8)
527 IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
528 TRACE("(%p,%p)\n",pdsfd,ppdsc8);
530 if (pdsfd == NULL) {
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");
542 *ppdsc8 = NULL;
543 return DSERR_UNINITIALIZED;
546 pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
547 if (pdsfddsc == NULL) {
548 WARN("out of memory\n");
549 *ppdsc8 = NULL;
550 return DSERR_OUTOFMEMORY;
553 pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
554 pdsfddsc->ref = 0;
555 pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
557 *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
559 return DS_OK;
562 /***************************************************************************
563 * IDirectSoundFullDuplexImpl
565 static ULONG WINAPI
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);
571 return ref;
574 static HRESULT WINAPI
575 IDirectSoundFullDuplexImpl_QueryInterface(
576 LPDIRECTSOUNDFULLDUPLEX iface,
577 REFIID riid,
578 LPVOID* ppobj )
580 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
581 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
583 if (ppobj == NULL) {
584 WARN("invalid parameter\n");
585 return E_INVALIDARG;
588 *ppobj = NULL;
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");
595 *ppobj = NULL;
596 return E_NOINTERFACE;
599 IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
600 *ppobj = This->pUnknown;
601 return S_OK;
602 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
603 IDirectSoundFullDuplexImpl_AddRef(iface);
604 *ppobj = This;
605 return S_OK;
606 } else if (IsEqualIID(riid, &IID_IDirectSound)) {
607 if (!This->pDS) {
608 IDirectSoundFullDuplex_IDirectSound_Create(iface, &This->pDS);
609 if (!This->pDS) {
610 WARN("IDirectSoundFullDuplex_IDirectSound_Create() failed\n");
611 *ppobj = NULL;
612 return E_NOINTERFACE;
615 IDirectSoundFullDuplex_IDirectSound_AddRef(This->pDS);
616 *ppobj = This->pDS;
617 return S_OK;
618 } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
619 if (!This->pDS8) {
620 IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
621 if (!This->pDS8) {
622 WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
623 *ppobj = NULL;
624 return E_NOINTERFACE;
627 IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
628 *ppobj = This->pDS8;
629 return S_OK;
630 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
631 if (!This->pDSC) {
632 IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
633 if (!This->pDSC) {
634 WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
635 *ppobj = NULL;
636 return E_NOINTERFACE;
639 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
640 *ppobj = This->pDSC;
641 return S_OK;
644 return E_NOINTERFACE;
647 static ULONG WINAPI
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);
654 if (!ref) {
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);
662 return ref;
665 static HRESULT WINAPI
666 IDirectSoundFullDuplexImpl_Initialize(
667 LPDIRECTSOUNDFULLDUPLEX iface,
668 LPCGUID pCaptureGuid,
669 LPCGUID pRendererGuid,
670 LPCDSCBUFFERDESC lpDscBufferDesc,
671 LPCDSBUFFERDESC lpDsBufferDesc,
672 HWND hWnd,
673 DWORD dwLevel,
674 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
675 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
677 HRESULT hr;
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);
694 if (hr != DS_OK) {
695 WARN("DirectSoundDevice_Initialize() failed\n");
696 *lplpDirectSoundCaptureBuffer8 = NULL;
697 *lplpDirectSoundBuffer8 = NULL;
698 return hr;
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);
708 if (hr != DS_OK) {
709 WARN("DSOUND_PrimarySetFormat() failed\n");
710 *lplpDirectSoundCaptureBuffer8 = NULL;
711 *lplpDirectSoundBuffer8 = NULL;
712 return hr;
714 hr = IDirectSoundBufferImpl_Create(This->renderer_device, &dsb, lpDsBufferDesc);
715 if (hr != DS_OK) {
716 WARN("IDirectSoundBufferImpl_Create() failed\n");
717 *lplpDirectSoundCaptureBuffer8 = NULL;
718 *lplpDirectSoundBuffer8 = NULL;
719 return hr;
722 hr = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl **)lplpDirectSoundBuffer8);
723 if (hr != DS_OK) {
724 WARN("SecondaryBufferImpl_Create() failed\n");
725 *lplpDirectSoundCaptureBuffer8 = NULL;
726 *lplpDirectSoundBuffer8 = NULL;
727 return hr;
729 IDirectSoundBuffer8_AddRef(*lplpDirectSoundBuffer8);
731 hr = DirectSoundCaptureDevice_Initialize(&This->capture_device, pCaptureGuid);
732 if (hr != DS_OK) {
733 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
734 *lplpDirectSoundCaptureBuffer8 = NULL;
735 *lplpDirectSoundBuffer8 = NULL;
736 return hr;
739 hr = IDirectSoundCaptureBufferImpl_Create(This->capture_device,
740 (IDirectSoundCaptureBufferImpl **)lplpDirectSoundCaptureBuffer8,
741 lpDscBufferDesc);
742 if (hr != DS_OK) {
743 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
744 *lplpDirectSoundCaptureBuffer8 = NULL;
745 *lplpDirectSoundBuffer8 = NULL;
746 return hr;
749 return hr;
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(LPDIRECTSOUNDFULLDUPLEX* ppDSFD, IUnknown *pUnkOuter)
765 IDirectSoundFullDuplexImpl *This = NULL;
767 if (pUnkOuter) {
768 WARN("pUnkOuter != 0\n");
769 *ppDSFD = NULL;
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));
784 if (This == NULL) {
785 WARN("out of memory\n");
786 *ppDSFD = NULL;
787 return DSERR_OUTOFMEMORY;
790 This->lpVtbl = &dsfdvt;
791 This->ref = 1;
792 This->capture_device = NULL;
793 This->renderer_device = NULL;
795 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
797 return DS_OK;
800 /***************************************************************************
801 * DirectSoundFullDuplexCreate [DSOUND.10]
803 * Create and initialize a DirectSoundFullDuplex interface.
805 * PARAMS
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.
817 * RETURNS
818 * Success: DS_OK
819 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
820 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
822 HRESULT WINAPI
823 DirectSoundFullDuplexCreate(
824 LPCGUID pcGuidCaptureDevice,
825 LPCGUID pcGuidRenderDevice,
826 LPCDSCBUFFERDESC pcDSCBufferDesc,
827 LPCDSBUFFERDESC pcDSBufferDesc,
828 HWND hWnd,
829 DWORD dwLevel,
830 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
831 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
832 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
833 LPUNKNOWN pUnkOuter)
835 HRESULT hres;
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);
842 if (pUnkOuter) {
843 WARN("pUnkOuter != 0\n");
844 *ppDSFD = NULL;
845 return DSERR_NOAGGREGATION;
848 if (pcDSCBufferDesc == NULL) {
849 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
850 *ppDSFD = NULL;
851 return DSERR_INVALIDPARAM;
854 if (pcDSBufferDesc == NULL) {
855 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
856 *ppDSFD = NULL;
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");
867 *ppDSFD = NULL;
868 return DSERR_INVALIDPARAM;
871 if (ppDSBuffer8 == NULL) {
872 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
873 *ppDSFD = NULL;
874 return DSERR_INVALIDPARAM;
877 /* Get dsound configuration */
878 setup_dsound_options();
880 This = HeapAlloc(GetProcessHeap(),
881 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
883 if (This == NULL) {
884 WARN("out of memory\n");
885 *ppDSFD = NULL;
886 return DSERR_OUTOFMEMORY;
889 This->lpVtbl = &dsfdvt;
890 This->ref = 1;
891 This->capture_device = NULL;
892 This->renderer_device = NULL;
894 hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
895 pcGuidCaptureDevice,
896 pcGuidRenderDevice,
897 pcDSCBufferDesc,
898 pcDSBufferDesc,
899 hWnd, dwLevel, ppDSCBuffer8,
900 ppDSBuffer8);
901 if (hres != DS_OK) {
902 HeapFree(GetProcessHeap(), 0, This);
903 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
904 *ppDSFD = NULL;
905 } else
906 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
908 return hres;
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;
924 static ULONG WINAPI
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));
932 static ULONG WINAPI
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);
949 if (pOuter) {
950 WARN("aggregation not supported\n");
951 return CLASS_E_NOAGGREGATION;
954 if (ppobj == NULL) {
955 WARN("invalid parameter\n");
956 return E_INVALIDARG;
959 *ppobj = NULL;
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);
973 return S_OK;
976 static const IClassFactoryVtbl DSFDCF_Vtbl =
978 DSFDCF_QueryInterface,
979 DSFDCF_AddRef,
980 DSFDCF_Release,
981 DSFDCF_CreateInstance,
982 DSFDCF_LockServer
985 IClassFactoryImpl DSOUND_FULLDUPLEX_CF = { &DSFDCF_Vtbl, 1 };