d3dxof: Make is_keyword handle end of file correctly.
[wine/multimedia.git] / dlls / dsound / duplex.c
blob1fe6bbc67daf94306e2b13e603f702c6f0ebdf81
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 "winternl.h"
33 #include "wine/debug.h"
34 #include "dsound.h"
35 #include "dsdriver.h"
36 #include "dsound_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
40 /*******************************************************************************
41 * IUnknown
43 static HRESULT WINAPI IDirectSoundFullDuplex_IUnknown_QueryInterface(
44 LPUNKNOWN iface,
45 REFIID riid,
46 LPVOID * ppobj)
48 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
49 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
50 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
53 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_AddRef(
54 LPUNKNOWN iface)
56 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
57 ULONG ref = InterlockedIncrement(&(This->ref));
58 TRACE("(%p) ref was %d\n", This, ref - 1);
59 return ref;
62 static ULONG WINAPI IDirectSoundFullDuplex_IUnknown_Release(
63 LPUNKNOWN iface)
65 IDirectSoundFullDuplex_IUnknown *This = (IDirectSoundFullDuplex_IUnknown *)iface;
66 ULONG ref = InterlockedDecrement(&(This->ref));
67 TRACE("(%p) ref was %d\n", This, ref + 1);
68 if (!ref) {
69 IDirectSound_Release(This->pdsfd->pUnknown);
70 HeapFree(GetProcessHeap(), 0, This);
71 TRACE("(%p) released\n", This);
73 return ref;
76 static const IUnknownVtbl DirectSoundFullDuplex_Unknown_Vtbl =
78 IDirectSoundFullDuplex_IUnknown_QueryInterface,
79 IDirectSoundFullDuplex_IUnknown_AddRef,
80 IDirectSoundFullDuplex_IUnknown_Release
83 static HRESULT IDirectSoundFullDuplex_IUnknown_Create(
84 LPDIRECTSOUNDFULLDUPLEX pdsfd,
85 LPUNKNOWN * ppunk)
87 IDirectSoundFullDuplex_IUnknown * pdsfdunk;
88 TRACE("(%p,%p)\n",pdsfd,ppunk);
90 if (pdsfd == NULL) {
91 ERR("invalid parameter: pdsfd == NULL\n");
92 return DSERR_INVALIDPARAM;
95 if (ppunk == NULL) {
96 ERR("invalid parameter: ppunk == NULL\n");
97 return DSERR_INVALIDPARAM;
100 pdsfdunk = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdunk));
101 if (pdsfdunk == NULL) {
102 WARN("out of memory\n");
103 *ppunk = NULL;
104 return DSERR_OUTOFMEMORY;
107 pdsfdunk->lpVtbl = &DirectSoundFullDuplex_Unknown_Vtbl;
108 pdsfdunk->ref = 0;
109 pdsfdunk->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
111 *ppunk = (LPUNKNOWN)pdsfdunk;
113 return DS_OK;
116 /*******************************************************************************
117 * IDirectSoundFullDuplex_IDirectSound
119 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_QueryInterface(
120 LPDIRECTSOUND iface,
121 REFIID riid,
122 LPVOID * ppobj)
124 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
125 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
126 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
129 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_AddRef(
130 LPDIRECTSOUND iface)
132 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
133 ULONG ref = InterlockedIncrement(&(This->ref));
134 TRACE("(%p) ref was %d\n", This, ref - 1);
135 return ref;
138 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound_Release(
139 LPDIRECTSOUND iface)
141 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
142 ULONG ref = InterlockedDecrement(&(This->ref));
143 TRACE("(%p) ref was %d\n", This, ref + 1);
144 if (!ref) {
145 IDirectSound_Release(This->pdsfd->pDS);
146 HeapFree(GetProcessHeap(), 0, This);
147 TRACE("(%p) released\n", This);
149 return ref;
152 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer(
153 LPDIRECTSOUND iface,
154 LPCDSBUFFERDESC dsbd,
155 LPLPDIRECTSOUNDBUFFER ppdsb,
156 LPUNKNOWN lpunk)
158 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
159 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
160 return DirectSoundDevice_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk,FALSE);
163 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_GetCaps(
164 LPDIRECTSOUND iface,
165 LPDSCAPS lpDSCaps)
167 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
168 TRACE("(%p,%p)\n",This,lpDSCaps);
169 return DirectSoundDevice_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
172 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer(
173 LPDIRECTSOUND iface,
174 LPDIRECTSOUNDBUFFER psb,
175 LPLPDIRECTSOUNDBUFFER ppdsb)
177 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
178 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
179 return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
182 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel(
183 LPDIRECTSOUND iface,
184 HWND hwnd,
185 DWORD level)
187 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
188 TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
189 return DirectSoundDevice_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
192 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_Compact(
193 LPDIRECTSOUND iface)
195 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
196 TRACE("(%p)\n", This);
197 return DirectSoundDevice_Compact(This->pdsfd->renderer_device);
200 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig(
201 LPDIRECTSOUND iface,
202 LPDWORD lpdwSpeakerConfig)
204 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
205 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
206 return DirectSoundDevice_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
209 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig(
210 LPDIRECTSOUND iface,
211 DWORD config)
213 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
214 TRACE("(%p,0x%08x)\n",This,config);
215 return DirectSoundDevice_SetSpeakerConfig(This->pdsfd->renderer_device,config);
218 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound_Initialize(
219 LPDIRECTSOUND iface,
220 LPCGUID lpcGuid)
222 IDirectSoundFullDuplex_IDirectSound *This = (IDirectSoundFullDuplex_IDirectSound *)iface;
223 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
224 return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid);
227 static const IDirectSoundVtbl DirectSoundFullDuplex_DirectSound_Vtbl =
229 IDirectSoundFullDuplex_IDirectSound_QueryInterface,
230 IDirectSoundFullDuplex_IDirectSound_AddRef,
231 IDirectSoundFullDuplex_IDirectSound_Release,
232 IDirectSoundFullDuplex_IDirectSound_CreateSoundBuffer,
233 IDirectSoundFullDuplex_IDirectSound_GetCaps,
234 IDirectSoundFullDuplex_IDirectSound_DuplicateSoundBuffer,
235 IDirectSoundFullDuplex_IDirectSound_SetCooperativeLevel,
236 IDirectSoundFullDuplex_IDirectSound_Compact,
237 IDirectSoundFullDuplex_IDirectSound_GetSpeakerConfig,
238 IDirectSoundFullDuplex_IDirectSound_SetSpeakerConfig,
239 IDirectSoundFullDuplex_IDirectSound_Initialize
242 static HRESULT IDirectSoundFullDuplex_IDirectSound_Create(
243 LPDIRECTSOUNDFULLDUPLEX pdsfd,
244 LPDIRECTSOUND * ppds)
246 IDirectSoundFullDuplex_IDirectSound * pdsfdds;
247 TRACE("(%p,%p)\n",pdsfd,ppds);
249 if (pdsfd == NULL) {
250 ERR("invalid parameter: pdsfd == NULL\n");
251 return DSERR_INVALIDPARAM;
254 if (ppds == NULL) {
255 ERR("invalid parameter: ppds == NULL\n");
256 return DSERR_INVALIDPARAM;
259 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
260 WARN("not initialized\n");
261 *ppds = NULL;
262 return DSERR_UNINITIALIZED;
265 pdsfdds = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds));
266 if (pdsfdds == NULL) {
267 WARN("out of memory\n");
268 *ppds = NULL;
269 return DSERR_OUTOFMEMORY;
272 pdsfdds->lpVtbl = &DirectSoundFullDuplex_DirectSound_Vtbl;
273 pdsfdds->ref = 0;
274 pdsfdds->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
276 *ppds = (LPDIRECTSOUND)pdsfdds;
278 return DS_OK;
281 /*******************************************************************************
282 * IDirectSoundFullDuplex_IDirectSound8
284 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_QueryInterface(
285 LPDIRECTSOUND8 iface,
286 REFIID riid,
287 LPVOID * ppobj)
289 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
290 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
291 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
294 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_AddRef(
295 LPDIRECTSOUND8 iface)
297 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
298 ULONG ref = InterlockedIncrement(&(This->ref));
299 TRACE("(%p) ref was %d\n", This, ref - 1);
300 return ref;
303 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSound8_Release(
304 LPDIRECTSOUND8 iface)
306 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
307 ULONG ref = InterlockedDecrement(&(This->ref));
308 TRACE("(%p) ref was %d\n", This, ref + 1);
309 if (!ref) {
310 IDirectSound_Release(This->pdsfd->pDS8);
311 HeapFree(GetProcessHeap(), 0, This);
312 TRACE("(%p) released\n", This);
314 return ref;
317 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer(
318 LPDIRECTSOUND8 iface,
319 LPCDSBUFFERDESC dsbd,
320 LPLPDIRECTSOUNDBUFFER ppdsb,
321 LPUNKNOWN lpunk)
323 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
324 TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
325 return DirectSoundDevice_CreateSoundBuffer(This->pdsfd->renderer_device,dsbd,ppdsb,lpunk,TRUE);
328 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetCaps(
329 LPDIRECTSOUND8 iface,
330 LPDSCAPS lpDSCaps)
332 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
333 TRACE("(%p,%p)\n",This,lpDSCaps);
334 return DirectSoundDevice_GetCaps(This->pdsfd->renderer_device, lpDSCaps);
337 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer(
338 LPDIRECTSOUND8 iface,
339 LPDIRECTSOUNDBUFFER psb,
340 LPLPDIRECTSOUNDBUFFER ppdsb)
342 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
343 TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
344 return DirectSoundDevice_DuplicateSoundBuffer(This->pdsfd->renderer_device,psb,ppdsb);
347 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel(
348 LPDIRECTSOUND8 iface,
349 HWND hwnd,
350 DWORD level)
352 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
353 TRACE("(%p,%p,%s)\n",This,hwnd,dumpCooperativeLevel(level));
354 return DirectSoundDevice_SetCooperativeLevel(This->pdsfd->renderer_device,hwnd,level);
357 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Compact(
358 LPDIRECTSOUND8 iface)
360 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
361 TRACE("(%p)\n", This);
362 return DirectSoundDevice_Compact(This->pdsfd->renderer_device);
365 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig(
366 LPDIRECTSOUND8 iface,
367 LPDWORD lpdwSpeakerConfig)
369 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
370 TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
371 return DirectSoundDevice_GetSpeakerConfig(This->pdsfd->renderer_device,lpdwSpeakerConfig);
374 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig(
375 LPDIRECTSOUND8 iface,
376 DWORD config)
378 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
379 TRACE("(%p,0x%08x)\n",This,config);
380 return DirectSoundDevice_SetSpeakerConfig(This->pdsfd->renderer_device,config);
383 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSound8_Initialize(
384 LPDIRECTSOUND8 iface,
385 LPCGUID lpcGuid)
387 IDirectSoundFullDuplex_IDirectSound8 *This = (IDirectSoundFullDuplex_IDirectSound8 *)iface;
388 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
389 return DirectSoundDevice_Initialize(&This->pdsfd->renderer_device,lpcGuid);
392 static const IDirectSound8Vtbl DirectSoundFullDuplex_DirectSound8_Vtbl =
394 IDirectSoundFullDuplex_IDirectSound8_QueryInterface,
395 IDirectSoundFullDuplex_IDirectSound8_AddRef,
396 IDirectSoundFullDuplex_IDirectSound8_Release,
397 IDirectSoundFullDuplex_IDirectSound8_CreateSoundBuffer,
398 IDirectSoundFullDuplex_IDirectSound8_GetCaps,
399 IDirectSoundFullDuplex_IDirectSound8_DuplicateSoundBuffer,
400 IDirectSoundFullDuplex_IDirectSound8_SetCooperativeLevel,
401 IDirectSoundFullDuplex_IDirectSound8_Compact,
402 IDirectSoundFullDuplex_IDirectSound8_GetSpeakerConfig,
403 IDirectSoundFullDuplex_IDirectSound8_SetSpeakerConfig,
404 IDirectSoundFullDuplex_IDirectSound8_Initialize
407 static HRESULT IDirectSoundFullDuplex_IDirectSound8_Create(
408 LPDIRECTSOUNDFULLDUPLEX pdsfd,
409 LPDIRECTSOUND8 * ppds8)
411 IDirectSoundFullDuplex_IDirectSound8 * pdsfdds8;
412 TRACE("(%p,%p)\n",pdsfd,ppds8);
414 if (pdsfd == NULL) {
415 ERR("invalid parameter: pdsfd == NULL\n");
416 return DSERR_INVALIDPARAM;
419 if (ppds8 == NULL) {
420 ERR("invalid parameter: ppds8 == NULL\n");
421 return DSERR_INVALIDPARAM;
424 if (((IDirectSoundFullDuplexImpl*)pdsfd)->renderer_device == NULL) {
425 WARN("not initialized\n");
426 *ppds8 = NULL;
427 return DSERR_UNINITIALIZED;
430 pdsfdds8 = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfdds8));
431 if (pdsfdds8 == NULL) {
432 WARN("out of memory\n");
433 *ppds8 = NULL;
434 return DSERR_OUTOFMEMORY;
437 pdsfdds8->lpVtbl = &DirectSoundFullDuplex_DirectSound8_Vtbl;
438 pdsfdds8->ref = 0;
439 pdsfdds8->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
441 *ppds8 = (LPDIRECTSOUND8)pdsfdds8;
443 return DS_OK;
446 /*******************************************************************************
447 * IDirectSoundFullDuplex_IDirectSoundCapture
449 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface(
450 LPDIRECTSOUNDCAPTURE iface,
451 REFIID riid,
452 LPVOID * ppobj)
454 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
455 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
456 return IDirectSoundFullDuplex_QueryInterface((LPDIRECTSOUNDFULLDUPLEX)This->pdsfd, riid, ppobj);
459 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(
460 LPDIRECTSOUNDCAPTURE iface)
462 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
463 ULONG ref = InterlockedIncrement(&(This->ref));
464 TRACE("(%p) ref was %d\n", This, ref - 1);
465 return ref;
468 static ULONG WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Release(
469 LPDIRECTSOUNDCAPTURE iface)
471 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
472 ULONG ref = InterlockedDecrement(&(This->ref));
473 TRACE("(%p) ref was %d\n", This, ref + 1);
474 if (!ref) {
475 IDirectSoundCapture_Release(This->pdsfd->pDSC);
476 HeapFree(GetProcessHeap(), 0, This);
477 TRACE("(%p) released\n", This);
479 return ref;
482 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
483 LPDIRECTSOUNDCAPTURE iface,
484 LPCDSCBUFFERDESC lpcDSCBufferDesc,
485 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
486 LPUNKNOWN pUnk)
488 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
489 TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
490 return IDirectSoundCaptureImpl_CreateCaptureBuffer(This->pdsfd->pDSC,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
493 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps(
494 LPDIRECTSOUNDCAPTURE iface,
495 LPDSCCAPS lpDSCCaps)
497 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
498 TRACE("(%p,%p)\n",This,lpDSCCaps);
499 return IDirectSoundCaptureImpl_GetCaps(This->pdsfd->pDSC, lpDSCCaps);
502 static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_Initialize(
503 LPDIRECTSOUNDCAPTURE iface,
504 LPCGUID lpcGUID)
506 IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
507 TRACE("(%p, %s)\n", This, debugstr_guid(lpcGUID));
508 return IDirectSoundCaptureImpl_Initialize(This->pdsfd->pDSC,lpcGUID);
511 static const IDirectSoundCaptureVtbl DirectSoundFullDuplex_DirectSoundCapture_Vtbl =
513 IDirectSoundFullDuplex_IDirectSoundCapture_QueryInterface,
514 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef,
515 IDirectSoundFullDuplex_IDirectSoundCapture_Release,
516 IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer,
517 IDirectSoundFullDuplex_IDirectSoundCapture_GetCaps,
518 IDirectSoundFullDuplex_IDirectSoundCapture_Initialize
521 static HRESULT IDirectSoundFullDuplex_IDirectSoundCapture_Create(
522 LPDIRECTSOUNDFULLDUPLEX pdsfd,
523 LPDIRECTSOUNDCAPTURE8 * ppdsc8)
525 IDirectSoundFullDuplex_IDirectSoundCapture * pdsfddsc;
526 TRACE("(%p,%p)\n",pdsfd,ppdsc8);
528 if (pdsfd == NULL) {
529 ERR("invalid parameter: pdsfd == NULL\n");
530 return DSERR_INVALIDPARAM;
533 if (ppdsc8 == NULL) {
534 ERR("invalid parameter: ppdsc8 == NULL\n");
535 return DSERR_INVALIDPARAM;
538 if (((IDirectSoundFullDuplexImpl*)pdsfd)->capture_device == NULL) {
539 WARN("not initialized\n");
540 *ppdsc8 = NULL;
541 return DSERR_UNINITIALIZED;
544 pdsfddsc = HeapAlloc(GetProcessHeap(),0,sizeof(*pdsfddsc));
545 if (pdsfddsc == NULL) {
546 WARN("out of memory\n");
547 *ppdsc8 = NULL;
548 return DSERR_OUTOFMEMORY;
551 pdsfddsc->lpVtbl = &DirectSoundFullDuplex_DirectSoundCapture_Vtbl;
552 pdsfddsc->ref = 0;
553 pdsfddsc->pdsfd = (IDirectSoundFullDuplexImpl *)pdsfd;
555 *ppdsc8 = (LPDIRECTSOUNDCAPTURE)pdsfddsc;
557 return DS_OK;
560 /***************************************************************************
561 * IDirectSoundFullDuplexImpl
563 static ULONG WINAPI
564 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
566 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
567 ULONG ref = InterlockedIncrement(&(This->ref));
568 TRACE("(%p) ref was %d\n", This, ref - 1);
569 return ref;
572 static HRESULT WINAPI
573 IDirectSoundFullDuplexImpl_QueryInterface(
574 LPDIRECTSOUNDFULLDUPLEX iface,
575 REFIID riid,
576 LPVOID* ppobj )
578 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
579 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
581 if (ppobj == NULL) {
582 WARN("invalid parameter\n");
583 return E_INVALIDARG;
586 *ppobj = NULL;
588 if (IsEqualIID(riid, &IID_IUnknown)) {
589 if (!This->pUnknown) {
590 IDirectSoundFullDuplex_IUnknown_Create(iface, &This->pUnknown);
591 if (!This->pUnknown) {
592 WARN("IDirectSoundFullDuplex_IUnknown_Create() failed\n");
593 *ppobj = NULL;
594 return E_NOINTERFACE;
597 IDirectSoundFullDuplex_IUnknown_AddRef(This->pUnknown);
598 *ppobj = This->pUnknown;
599 return S_OK;
600 } else if (IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
601 IDirectSoundFullDuplexImpl_AddRef(iface);
602 *ppobj = This;
603 return S_OK;
604 } else if (IsEqualIID(riid, &IID_IDirectSound)) {
605 if (!This->pDS) {
606 IDirectSoundFullDuplex_IDirectSound_Create(iface, &This->pDS);
607 if (!This->pDS) {
608 WARN("IDirectSoundFullDuplex_IDirectSound_Create() failed\n");
609 *ppobj = NULL;
610 return E_NOINTERFACE;
613 IDirectSoundFullDuplex_IDirectSound_AddRef(This->pDS);
614 *ppobj = This->pDS;
615 return S_OK;
616 } else if (IsEqualIID(riid, &IID_IDirectSound8)) {
617 if (!This->pDS8) {
618 IDirectSoundFullDuplex_IDirectSound8_Create(iface, &This->pDS8);
619 if (!This->pDS8) {
620 WARN("IDirectSoundFullDuplex_IDirectSound8_Create() failed\n");
621 *ppobj = NULL;
622 return E_NOINTERFACE;
625 IDirectSoundFullDuplex_IDirectSound8_AddRef(This->pDS8);
626 *ppobj = This->pDS8;
627 return S_OK;
628 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
629 if (!This->pDSC) {
630 IDirectSoundFullDuplex_IDirectSoundCapture_Create(iface, &This->pDSC);
631 if (!This->pDSC) {
632 WARN("IDirectSoundFullDuplex_IDirectSoundCapture_Create() failed\n");
633 *ppobj = NULL;
634 return E_NOINTERFACE;
637 IDirectSoundFullDuplex_IDirectSoundCapture_AddRef(This->pDSC);
638 *ppobj = This->pDSC;
639 return S_OK;
642 return E_NOINTERFACE;
645 static ULONG WINAPI
646 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
648 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
649 ULONG ref = InterlockedDecrement(&(This->ref));
650 TRACE("(%p) ref was %d\n", This, ref - 1);
652 if (!ref) {
653 if (This->capture_device)
654 DirectSoundCaptureDevice_Release(This->capture_device);
655 if (This->renderer_device)
656 DirectSoundDevice_Release(This->renderer_device);
657 HeapFree( GetProcessHeap(), 0, This );
658 TRACE("(%p) released\n", This);
660 return ref;
663 static HRESULT WINAPI
664 IDirectSoundFullDuplexImpl_Initialize(
665 LPDIRECTSOUNDFULLDUPLEX iface,
666 LPCGUID pCaptureGuid,
667 LPCGUID pRendererGuid,
668 LPCDSCBUFFERDESC lpDscBufferDesc,
669 LPCDSBUFFERDESC lpDsBufferDesc,
670 HWND hWnd,
671 DWORD dwLevel,
672 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
673 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
675 HRESULT hr;
676 IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;
677 IDirectSoundBufferImpl * dsb;
679 TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
680 debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
681 lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
682 lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);
684 if (This->renderer_device != NULL || This->capture_device != NULL) {
685 WARN("already initialized\n");
686 *lplpDirectSoundCaptureBuffer8 = NULL;
687 *lplpDirectSoundBuffer8 = NULL;
688 return DSERR_ALREADYINITIALIZED;
691 hr = DirectSoundDevice_Initialize(&This->renderer_device, pRendererGuid);
692 if (hr != DS_OK) {
693 WARN("DirectSoundDevice_Initialize() failed\n");
694 *lplpDirectSoundCaptureBuffer8 = NULL;
695 *lplpDirectSoundBuffer8 = NULL;
696 return hr;
699 if (dwLevel==DSSCL_PRIORITY || dwLevel==DSSCL_EXCLUSIVE) {
700 WARN("level=%s not fully supported\n",
701 dwLevel==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
703 This->renderer_device->priolevel = dwLevel;
705 hr = DSOUND_PrimarySetFormat(This->renderer_device, lpDsBufferDesc->lpwfxFormat, dwLevel == DSSCL_EXCLUSIVE);
706 if (hr != DS_OK) {
707 WARN("DSOUND_PrimarySetFormat() failed\n");
708 *lplpDirectSoundCaptureBuffer8 = NULL;
709 *lplpDirectSoundBuffer8 = NULL;
710 return hr;
712 hr = IDirectSoundBufferImpl_Create(This->renderer_device, &dsb, lpDsBufferDesc);
713 if (hr != DS_OK) {
714 WARN("IDirectSoundBufferImpl_Create() failed\n");
715 *lplpDirectSoundCaptureBuffer8 = NULL;
716 *lplpDirectSoundBuffer8 = NULL;
717 return hr;
720 hr = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl **)lplpDirectSoundBuffer8);
721 if (hr != DS_OK) {
722 WARN("SecondaryBufferImpl_Create() failed\n");
723 *lplpDirectSoundCaptureBuffer8 = NULL;
724 *lplpDirectSoundBuffer8 = NULL;
725 return hr;
727 IDirectSoundBuffer8_AddRef(*lplpDirectSoundBuffer8);
729 hr = DirectSoundCaptureDevice_Initialize(&This->capture_device, pCaptureGuid);
730 if (hr != DS_OK) {
731 WARN("DirectSoundCaptureDevice_Initialize() failed\n");
732 *lplpDirectSoundCaptureBuffer8 = NULL;
733 *lplpDirectSoundBuffer8 = NULL;
734 return hr;
737 hr = IDirectSoundCaptureBufferImpl_Create(This->capture_device,
738 (IDirectSoundCaptureBufferImpl **)lplpDirectSoundCaptureBuffer8,
739 lpDscBufferDesc);
740 if (hr != DS_OK) {
741 WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
742 *lplpDirectSoundCaptureBuffer8 = NULL;
743 *lplpDirectSoundBuffer8 = NULL;
744 return hr;
747 return hr;
750 static const IDirectSoundFullDuplexVtbl dsfdvt =
752 /* IUnknown methods */
753 IDirectSoundFullDuplexImpl_QueryInterface,
754 IDirectSoundFullDuplexImpl_AddRef,
755 IDirectSoundFullDuplexImpl_Release,
757 /* IDirectSoundFullDuplex methods */
758 IDirectSoundFullDuplexImpl_Initialize
761 HRESULT DSOUND_FullDuplexCreate(
762 REFIID riid,
763 LPDIRECTSOUNDFULLDUPLEX* ppDSFD)
765 IDirectSoundFullDuplexImpl *This = NULL;
766 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSFD);
768 if (ppDSFD == NULL) {
769 WARN("invalid parameter: ppDSFD == NULL\n");
770 return DSERR_INVALIDPARAM;
773 if (!IsEqualIID(riid, &IID_IUnknown) &&
774 !IsEqualIID(riid, &IID_IDirectSoundFullDuplex)) {
775 *ppDSFD = 0;
776 return E_NOINTERFACE;
779 /* Get dsound configuration */
780 setup_dsound_options();
782 This = HeapAlloc(GetProcessHeap(),
783 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
785 if (This == NULL) {
786 WARN("out of memory\n");
787 *ppDSFD = NULL;
788 return DSERR_OUTOFMEMORY;
791 This->lpVtbl = &dsfdvt;
792 This->ref = 1;
793 This->capture_device = NULL;
794 This->renderer_device = NULL;
796 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
798 return DS_OK;
801 /***************************************************************************
802 * DirectSoundFullDuplexCreate [DSOUND.10]
804 * Create and initialize a DirectSoundFullDuplex interface.
806 * PARAMS
807 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
808 * pcGuidRenderDevice [I] Address of sound render device GUID.
809 * pcDSCBufferDesc [I] Address of capture buffer description.
810 * pcDSBufferDesc [I] Address of render buffer description.
811 * hWnd [I] Handle to application window.
812 * dwLevel [I] Cooperative level.
813 * ppDSFD [O] Address where full duplex interface returned.
814 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
815 * ppDSBuffer8 [0] Address where render buffer interface returned.
816 * pUnkOuter [I] Must be NULL.
818 * RETURNS
819 * Success: DS_OK
820 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
821 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
823 HRESULT WINAPI
824 DirectSoundFullDuplexCreate(
825 LPCGUID pcGuidCaptureDevice,
826 LPCGUID pcGuidRenderDevice,
827 LPCDSCBUFFERDESC pcDSCBufferDesc,
828 LPCDSBUFFERDESC pcDSBufferDesc,
829 HWND hWnd,
830 DWORD dwLevel,
831 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
832 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
833 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
834 LPUNKNOWN pUnkOuter)
836 HRESULT hres;
837 IDirectSoundFullDuplexImpl *This = NULL;
838 TRACE("(%s,%s,%p,%p,%p,%x,%p,%p,%p,%p)\n",
839 debugstr_guid(pcGuidCaptureDevice), debugstr_guid(pcGuidRenderDevice),
840 pcDSCBufferDesc, pcDSBufferDesc, hWnd, dwLevel, ppDSFD, ppDSCBuffer8,
841 ppDSBuffer8, pUnkOuter);
843 if (pUnkOuter) {
844 WARN("pUnkOuter != 0\n");
845 *ppDSFD = NULL;
846 return DSERR_NOAGGREGATION;
849 if (pcDSCBufferDesc == NULL) {
850 WARN("invalid parameter: pcDSCBufferDesc == NULL\n");
851 *ppDSFD = NULL;
852 return DSERR_INVALIDPARAM;
855 if (pcDSBufferDesc == NULL) {
856 WARN("invalid parameter: pcDSBufferDesc == NULL\n");
857 *ppDSFD = NULL;
858 return DSERR_INVALIDPARAM;
861 if (ppDSFD == NULL) {
862 WARN("invalid parameter: ppDSFD == NULL\n");
863 return DSERR_INVALIDPARAM;
866 if (ppDSCBuffer8 == NULL) {
867 WARN("invalid parameter: ppDSCBuffer8 == NULL\n");
868 *ppDSFD = NULL;
869 return DSERR_INVALIDPARAM;
872 if (ppDSBuffer8 == NULL) {
873 WARN("invalid parameter: ppDSBuffer8 == NULL\n");
874 *ppDSFD = NULL;
875 return DSERR_INVALIDPARAM;
878 /* Get dsound configuration */
879 setup_dsound_options();
881 This = HeapAlloc(GetProcessHeap(),
882 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
884 if (This == NULL) {
885 WARN("out of memory\n");
886 *ppDSFD = NULL;
887 return DSERR_OUTOFMEMORY;
890 This->lpVtbl = &dsfdvt;
891 This->ref = 1;
892 This->capture_device = NULL;
893 This->renderer_device = NULL;
895 hres = IDirectSoundFullDuplexImpl_Initialize((LPDIRECTSOUNDFULLDUPLEX)This,
896 pcGuidCaptureDevice,
897 pcGuidRenderDevice,
898 pcDSCBufferDesc,
899 pcDSBufferDesc,
900 hWnd, dwLevel, ppDSCBuffer8,
901 ppDSBuffer8);
902 if (hres != DS_OK) {
903 HeapFree(GetProcessHeap(), 0, This);
904 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
905 *ppDSFD = NULL;
906 } else
907 *ppDSFD = (LPDIRECTSOUNDFULLDUPLEX)This;
909 return hres;