3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2001 TransGaming Technologies, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Implement DirectSoundFullDuplex support.
24 * Implement FX support.
30 #include <sys/types.h>
31 #include <sys/fcntl.h>
47 #include "wine/debug.h"
50 #include "dsound_private.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(dsound
);
54 static HRESULT WINAPI
IDirectSoundCaptureImpl_Initialize(
55 LPDIRECTSOUNDCAPTURE iface
,
57 static ULONG WINAPI
IDirectSoundCaptureImpl_Release(
58 LPDIRECTSOUNDCAPTURE iface
);
59 static ULONG WINAPI
IDirectSoundCaptureBufferImpl_Release(
60 LPDIRECTSOUNDCAPTUREBUFFER8 iface
);
61 static HRESULT
DSOUND_CreateDirectSoundCaptureBuffer(
62 IDirectSoundCaptureImpl
*ipDSC
,
63 LPCDSCBUFFERDESC lpcDSCBufferDesc
,
65 static HRESULT WINAPI
IDirectSoundFullDuplexImpl_Initialize(
66 LPDIRECTSOUNDFULLDUPLEX iface
,
68 LPCGUID pRendererGuid
,
69 LPCDSCBUFFERDESC lpDscBufferDesc
,
70 LPCDSBUFFERDESC lpDsBufferDesc
,
73 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8
,
74 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8
);
76 static ICOM_VTABLE(IDirectSoundCapture
) dscvt
;
77 static ICOM_VTABLE(IDirectSoundCaptureBuffer8
) dscbvt
;
78 static ICOM_VTABLE(IDirectSoundFullDuplex
) dsfdvt
;
80 IDirectSoundCaptureImpl
* dsound_capture
= NULL
;
82 /***************************************************************************
83 * DirectSoundCaptureCreate [DSOUND.6]
85 * Create and initialize a DirectSoundCapture interface
89 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
93 DirectSoundCaptureCreate8(
95 LPDIRECTSOUNDCAPTURE
* lplpDSC
,
98 IDirectSoundCaptureImpl
** ippDSC
=(IDirectSoundCaptureImpl
**)lplpDSC
;
99 TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID
), lplpDSC
, pUnkOuter
);
102 WARN("pUnkOuter != 0\n");
103 return DSERR_NOAGGREGATION
;
107 WARN("invalid parameter: lplpDSC == NULL\n");
108 return DSERR_INVALIDPARAM
;
111 /* Default device? */
112 if ( !lpcGUID
|| IsEqualGUID(lpcGUID
, &GUID_NULL
) )
113 lpcGUID
= &DSDEVID_DefaultCapture
;
115 *ippDSC
= (IDirectSoundCaptureImpl
*)HeapAlloc(GetProcessHeap(),
116 HEAP_ZERO_MEMORY
, sizeof(IDirectSoundCaptureImpl
));
118 if (*ippDSC
== NULL
) {
119 TRACE("couldn't allocate memory\n");
120 return DSERR_OUTOFMEMORY
;
124 ICOM_THIS(IDirectSoundCaptureImpl
, *ippDSC
);
127 This
->state
= STATE_STOPPED
;
129 InitializeCriticalSection( &(This
->lock
) );
131 ICOM_VTBL(This
) = &dscvt
;
132 dsound_capture
= This
;
134 if (GetDeviceID(lpcGUID
, &This
->guid
) == DS_OK
)
135 return IDirectSoundCaptureImpl_Initialize( (LPDIRECTSOUNDCAPTURE
)This
, &This
->guid
);
137 WARN("invalid GUID\n");
138 return DSERR_INVALIDPARAM
;
141 /***************************************************************************
142 * DirectSoundCaptureEnumerateA [DSOUND.7]
144 * Enumerate all DirectSound drivers installed in the system
148 * Failure: DSERR_INVALIDPARAM
151 DirectSoundCaptureEnumerateA(
152 LPDSENUMCALLBACKA lpDSEnumCallback
,
160 TRACE("(%p,%p)\n", lpDSEnumCallback
, lpContext
);
162 if (lpDSEnumCallback
== NULL
) {
163 WARN("invalid parameter\n");
164 return DSERR_INVALIDPARAM
;
167 devs
= waveInGetNumDevs();
169 if (GetDeviceID(&DSDEVID_DefaultCapture
, &guid
) == DS_OK
) {
171 for (wid
= 0; wid
< devs
; ++wid
) {
172 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDGUID
,(DWORD
)&temp
,0));
174 if (IsEqualGUID( &guid
, &temp
) ) {
175 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDDESC
,(DWORD
)&desc
,0));
177 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
178 debugstr_guid(&DSDEVID_DefaultCapture
),"Primary Sound Capture Driver",desc
.szDrvName
,lpContext
);
179 if (lpDSEnumCallback((LPGUID
)&DSDEVID_DefaultCapture
, "Primary Sound Capture Driver", desc
.szDrvName
, lpContext
) == FALSE
)
188 for (wid
= 0; wid
< devs
; ++wid
) {
189 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDDESC
,(DWORD
)&desc
,0));
191 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDGUID
,(DWORD
)&guid
,0));
193 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
194 debugstr_guid(&guid
),desc
.szDesc
,desc
.szDrvName
,lpContext
);
195 if (lpDSEnumCallback(&guid
, desc
.szDesc
, desc
.szDrvName
, lpContext
) == FALSE
)
204 /***************************************************************************
205 * DirectSoundCaptureEnumerateW [DSOUND.8]
207 * Enumerate all DirectSound drivers installed in the system
211 * Failure: DSERR_INVALIDPARAM
214 DirectSoundCaptureEnumerateW(
215 LPDSENUMCALLBACKW lpDSEnumCallback
,
222 WCHAR wDesc
[MAXPNAMELEN
];
223 WCHAR wName
[MAXPNAMELEN
];
225 TRACE("(%p,%p)\n", lpDSEnumCallback
, lpContext
);
227 if (lpDSEnumCallback
== NULL
) {
228 WARN("invalid parameter\n");
229 return DSERR_INVALIDPARAM
;
232 devs
= waveInGetNumDevs();
234 if (GetDeviceID(&DSDEVID_DefaultCapture
, &guid
) == DS_OK
) {
236 for (wid
= 0; wid
< devs
; ++wid
) {
237 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDGUID
,(DWORD
)&temp
,0));
239 if (IsEqualGUID( &guid
, &temp
) ) {
240 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDDESC
,(DWORD
)&desc
,0));
242 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
243 debugstr_guid(&DSDEVID_DefaultCapture
),"Primary Sound Capture Driver",desc
.szDrvName
,lpContext
);
244 MultiByteToWideChar( CP_ACP
, 0, "Primary Sound Capture Driver", -1,
245 wDesc
, sizeof(wDesc
)/sizeof(WCHAR
) );
246 MultiByteToWideChar( CP_ACP
, 0, desc
.szDrvName
, -1,
247 wName
, sizeof(wName
)/sizeof(WCHAR
) );
248 if (lpDSEnumCallback((LPGUID
)&DSDEVID_DefaultCapture
, wDesc
, wName
, lpContext
) == FALSE
)
257 for (wid
= 0; wid
< devs
; ++wid
) {
258 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDDESC
,(DWORD
)&desc
,0));
260 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDGUID
,(DWORD
)&guid
,0));
262 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
263 debugstr_guid(&DSDEVID_DefaultCapture
),desc
.szDesc
,desc
.szDrvName
,lpContext
);
264 MultiByteToWideChar( CP_ACP
, 0, desc
.szDesc
, -1,
265 wDesc
, sizeof(wDesc
)/sizeof(WCHAR
) );
266 MultiByteToWideChar( CP_ACP
, 0, desc
.szDrvName
, -1,
267 wName
, sizeof(wName
)/sizeof(WCHAR
) );
268 if (lpDSEnumCallback((LPGUID
)&DSDEVID_DefaultCapture
, wDesc
, wName
, lpContext
) == FALSE
)
278 DSOUND_capture_callback(
285 IDirectSoundCaptureImpl
* This
= (IDirectSoundCaptureImpl
*)dwUser
;
286 TRACE("entering at %ld, msg=%08x\n", GetTickCount(), msg
);
288 if (msg
== MM_WIM_DATA
) {
289 EnterCriticalSection( &(This
->lock
) );
290 TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%ld, old This->index=%d\n",This
->state
,This
->index
);
291 if (This
->state
!= STATE_STOPPED
) {
292 if (This
->state
== STATE_STARTING
) {
294 mtime
.wType
= TIME_BYTES
;
295 waveInGetPosition(This
->hwi
, &mtime
, sizeof(mtime
));
296 TRACE("mtime.u.cb=%ld,This->buflen=%ld\n", mtime
.u
.cb
, This
->buflen
);
297 mtime
.u
.cb
= mtime
.u
.cb
% This
->buflen
;
298 This
->read_position
= mtime
.u
.cb
;
299 This
->state
= STATE_CAPTURING
;
301 This
->index
= (This
->index
+ 1) % This
->nrofpwaves
;
302 waveInUnprepareHeader(hwi
,&(This
->pwave
[This
->index
]),sizeof(WAVEHDR
));
303 if (This
->capture_buffer
->nrofnotifies
)
304 SetEvent(This
->capture_buffer
->notifies
[This
->index
].hEventNotify
);
305 if ( (This
->index
== 0) && !(This
->capture_buffer
->flags
& DSCBSTART_LOOPING
) ) {
306 TRACE("end of buffer\n");
307 This
->state
= STATE_STOPPED
;
309 if (This
->state
== STATE_CAPTURING
) {
310 waveInPrepareHeader(hwi
,&(This
->pwave
[This
->index
]),sizeof(WAVEHDR
));
311 waveInAddBuffer(hwi
, &(This
->pwave
[This
->index
]), sizeof(WAVEHDR
));
315 TRACE("DirectSoundCapture new This->state=%ld, new This->index=%d\n",This
->state
,This
->index
);
316 LeaveCriticalSection( &(This
->lock
) );
319 TRACE("completed\n");
322 static HRESULT WINAPI
323 IDirectSoundCaptureImpl_QueryInterface(
324 LPDIRECTSOUNDCAPTURE iface
,
328 ICOM_THIS(IDirectSoundCaptureImpl
,iface
);
329 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
332 return IDsCaptureDriver_QueryInterface(This
->driver
, riid
, ppobj
);
338 IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface
)
341 ICOM_THIS(IDirectSoundCaptureImpl
,iface
);
343 EnterCriticalSection( &(This
->lock
) );
345 TRACE( "(%p) was 0x%08lx\n", This
, This
->ref
);
346 uRef
= ++(This
->ref
);
349 IDsCaptureDriver_AddRef(This
->driver
);
351 LeaveCriticalSection( &(This
->lock
) );
357 IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface
)
360 ICOM_THIS(IDirectSoundCaptureImpl
,iface
);
362 EnterCriticalSection( &(This
->lock
) );
364 TRACE( "(%p) was 0x%08lx\n", This
, This
->ref
);
365 uRef
= --(This
->ref
);
367 LeaveCriticalSection( &(This
->lock
) );
370 TRACE("deleting object\n");
371 if (This
->capture_buffer
)
372 IDirectSoundCaptureBufferImpl_Release(
373 (LPDIRECTSOUNDCAPTUREBUFFER8
) This
->capture_buffer
);
376 IDsCaptureDriver_Close(This
->driver
);
377 IDsCaptureDriver_Release(This
->driver
);
380 DeleteCriticalSection( &(This
->lock
) );
381 HeapFree( GetProcessHeap(), 0, This
);
382 dsound_capture
= NULL
;
385 TRACE( "returning 0x%08lx\n", uRef
);
389 static HRESULT WINAPI
390 IDirectSoundCaptureImpl_CreateCaptureBuffer(
391 LPDIRECTSOUNDCAPTURE iface
,
392 LPCDSCBUFFERDESC lpcDSCBufferDesc
,
393 LPDIRECTSOUNDCAPTUREBUFFER
* lplpDSCaptureBuffer
,
397 ICOM_THIS(IDirectSoundCaptureImpl
,iface
);
399 TRACE( "(%p,%p,%p,%p)\n",This
,lpcDSCBufferDesc
,lplpDSCaptureBuffer
,pUnk
);
401 if ( (This
== NULL
) || (lpcDSCBufferDesc
== NULL
) ||
402 (lplpDSCaptureBuffer
== NULL
) || pUnk
) {
403 WARN("invalid parameters\n");
404 return DSERR_INVALIDPARAM
;
407 /* FIXME: We can only have one buffer so what do we do here? */
408 if (This
->capture_buffer
) {
409 WARN("already has buffer\n");
410 return DSERR_INVALIDPARAM
; /* DSERR_GENERIC ? */
413 hr
= DSOUND_CreateDirectSoundCaptureBuffer( This
, lpcDSCBufferDesc
,
414 (LPVOID
*)lplpDSCaptureBuffer
);
419 static HRESULT WINAPI
420 IDirectSoundCaptureImpl_GetCaps(
421 LPDIRECTSOUNDCAPTURE iface
,
422 LPDSCCAPS lpDSCCaps
)
424 ICOM_THIS(IDirectSoundCaptureImpl
,iface
);
425 TRACE("(%p,%p)\n",This
,lpDSCCaps
);
427 if ( (lpDSCCaps
== NULL
) || (lpDSCCaps
->dwSize
!= sizeof(*lpDSCCaps
)) ) {
428 WARN("invalid parameters\n");
429 return DSERR_INVALIDPARAM
;
432 if ( !(This
->initialized
) ) {
433 WARN("not initialized\n");
434 return DSERR_UNINITIALIZED
;
437 lpDSCCaps
->dwFlags
= This
->drvcaps
.dwFlags
;
438 lpDSCCaps
->dwFormats
= This
->drvcaps
.dwFormats
;
439 lpDSCCaps
->dwChannels
= This
->drvcaps
.dwChannels
;
441 TRACE("(flags=0x%08lx,format=0x%08lx,channels=%ld)\n",lpDSCCaps
->dwFlags
,
442 lpDSCCaps
->dwFormats
, lpDSCCaps
->dwChannels
);
447 static HRESULT WINAPI
448 IDirectSoundCaptureImpl_Initialize(
449 LPDIRECTSOUNDCAPTURE iface
,
452 HRESULT err
= DSERR_INVALIDPARAM
;
454 ICOM_THIS(IDirectSoundCaptureImpl
,iface
);
455 TRACE("(%p)\n", This
);
458 WARN("invalid parameter\n");
459 return DSERR_INVALIDPARAM
;
462 if (This
->initialized
) {
463 WARN("already initialized\n");
464 return DSERR_ALREADYINITIALIZED
;
467 widn
= waveInGetNumDevs();
470 WARN("no audio devices found\n");
471 return DSERR_NODRIVER
;
474 /* Get dsound configuration */
475 setup_dsound_options();
477 /* enumerate WINMM audio devices and find the one we want */
478 for (wid
=0; wid
<widn
; wid
++) {
480 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDGUID
,(DWORD
)(&guid
),0));
482 WARN("waveInMessage failed; err=%lx\n",err
);
485 if (IsEqualGUID( lpcGUID
, &guid
) ) {
492 WARN("invalid parameter\n");
493 return DSERR_INVALIDPARAM
;
496 err
= mmErr(waveInMessage((HWAVEIN
)wid
,DRV_QUERYDSOUNDIFACE
,(DWORD
)&(This
->driver
),0));
497 if ( (err
!= DS_OK
) && (err
!= DSERR_UNSUPPORTED
) ) {
498 WARN("waveInMessage failed; err=%lx\n",err
);
503 /* Disable the direct sound driver to force emulation if requested. */
504 if (ds_hw_accel
== DS_HW_ACCEL_EMULATION
)
507 /* Get driver description */
509 TRACE("using DirectSound driver\n");
510 err
= IDsCaptureDriver_GetDriverDesc(This
->driver
, &(This
->drvdesc
));
512 WARN("IDsCaptureDriver_GetDriverDesc failed\n");
516 TRACE("using WINMM\n");
517 /* if no DirectSound interface available, use WINMM API instead */
518 This
->drvdesc
.dwFlags
= DSDDESC_DOMMSYSTEMOPEN
|
519 DSDDESC_DOMMSYSTEMSETFORMAT
;
522 This
->drvdesc
.dnDevNode
= wid
;
524 /* open the DirectSound driver if available */
525 if (This
->driver
&& (err
== DS_OK
))
526 err
= IDsCaptureDriver_Open(This
->driver
);
529 This
->initialized
= TRUE
;
531 /* the driver is now open, so it's now allowed to call GetCaps */
533 This
->drvcaps
.dwSize
= sizeof(This
->drvcaps
);
534 err
= IDsCaptureDriver_GetCaps(This
->driver
,&(This
->drvcaps
));
536 WARN("IDsCaptureDriver_GetCaps failed\n");
539 } else /*if (This->hwi)*/ {
541 err
= mmErr(waveInGetDevCapsA((UINT
)This
->drvdesc
.dnDevNode
, &wic
, sizeof(wic
)));
544 This
->drvcaps
.dwFlags
= 0;
545 strncpy(This
->drvdesc
.szDrvName
, wic
.szPname
,
546 sizeof(This
->drvdesc
.szDrvName
));
548 This
->drvcaps
.dwFlags
|= DSCCAPS_EMULDRIVER
;
549 This
->drvcaps
.dwFormats
= wic
.dwFormats
;
550 This
->drvcaps
.dwChannels
= wic
.wChannels
;
558 static ICOM_VTABLE(IDirectSoundCapture
) dscvt
=
560 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
561 /* IUnknown methods */
562 IDirectSoundCaptureImpl_QueryInterface
,
563 IDirectSoundCaptureImpl_AddRef
,
564 IDirectSoundCaptureImpl_Release
,
566 /* IDirectSoundCapture methods */
567 IDirectSoundCaptureImpl_CreateCaptureBuffer
,
568 IDirectSoundCaptureImpl_GetCaps
,
569 IDirectSoundCaptureImpl_Initialize
573 DSOUND_CreateDirectSoundCaptureBuffer(
574 IDirectSoundCaptureImpl
*ipDSC
,
575 LPCDSCBUFFERDESC lpcDSCBufferDesc
,
579 TRACE( "(%p,%p)\n", lpcDSCBufferDesc
, ppobj
);
581 if ( (ipDSC
== NULL
) || (lpcDSCBufferDesc
== NULL
) || (ppobj
== NULL
) ) {
582 WARN("invalid parameters\n");
583 return DSERR_INVALIDPARAM
;
586 if ( (lpcDSCBufferDesc
->dwSize
< sizeof(DSCBUFFERDESC
)) ||
587 (lpcDSCBufferDesc
->dwBufferBytes
== 0) ||
588 (lpcDSCBufferDesc
->lpwfxFormat
== NULL
) ) {
589 WARN("invalid lpcDSCBufferDesc\n");
590 return DSERR_INVALIDPARAM
;
593 if ( !ipDSC
->initialized
) {
594 WARN("not initialized\n");
595 return DSERR_UNINITIALIZED
;
598 wfex
= lpcDSCBufferDesc
->lpwfxFormat
;
601 TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
602 "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
603 wfex
->wFormatTag
, wfex
->nChannels
, wfex
->nSamplesPerSec
,
604 wfex
->nAvgBytesPerSec
, wfex
->nBlockAlign
,
605 wfex
->wBitsPerSample
, wfex
->cbSize
);
607 if (wfex
->cbSize
== 0)
608 memcpy(&(ipDSC
->wfx
), wfex
, sizeof(*wfex
) + wfex
->cbSize
);
610 WARN("non PCM formats not supported\n");
611 return DSERR_BADFORMAT
; /* FIXME: DSERR_INVALIDPARAM ? */
614 WARN("lpcDSCBufferDesc->lpwfxFormat == 0\n");
615 return DSERR_INVALIDPARAM
; /* FIXME: DSERR_BADFORMAT ? */
618 *ppobj
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
619 sizeof(IDirectSoundCaptureBufferImpl
));
621 if ( *ppobj
== NULL
) {
622 WARN("out of memory\n");
623 return DSERR_OUTOFMEMORY
;
626 ICOM_THIS(IDirectSoundCaptureBufferImpl
,*ppobj
);
629 This
->dsound
= ipDSC
;
630 This
->dsound
->capture_buffer
= This
;
632 This
->pdscbd
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
633 lpcDSCBufferDesc
->dwSize
);
635 memcpy(This
->pdscbd
, lpcDSCBufferDesc
, lpcDSCBufferDesc
->dwSize
);
638 This
->dsound
->capture_buffer
= 0;
639 HeapFree( GetProcessHeap(), 0, This
);
641 return DSERR_OUTOFMEMORY
;
644 ICOM_VTBL(This
) = &dscbvt
;
647 err
= IDsCaptureDriver_CreateCaptureBuffer(ipDSC
->driver
,
648 &(ipDSC
->wfx
),0,0,&(ipDSC
->buflen
),&(ipDSC
->buffer
),(LPVOID
*)&(ipDSC
->hwbuf
));
650 WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n");
652 return DSERR_GENERIC
;
657 DWORD flags
= CALLBACK_FUNCTION
;
658 if (ds_hw_accel
!= DS_HW_ACCEL_EMULATION
)
659 flags
|= WAVE_DIRECTSOUND
;
660 err
= mmErr(waveInOpen(&(ipDSC
->hwi
),
661 ipDSC
->drvdesc
.dnDevNode
, &(ipDSC
->wfx
),
662 (DWORD
)DSOUND_capture_callback
, (DWORD
)ipDSC
, flags
));
664 WARN("waveInOpen failed\n");
666 return DSERR_BADFORMAT
; /* FIXME: DSERR_INVALIDPARAM ? */
669 buflen
= lpcDSCBufferDesc
->dwBufferBytes
;
670 TRACE("desired buflen=%ld, old buffer=%p\n", buflen
, ipDSC
->buffer
);
671 newbuf
= (LPBYTE
)HeapReAlloc(GetProcessHeap(),0,ipDSC
->buffer
,buflen
);
673 if (newbuf
== NULL
) {
674 WARN("failed to allocate capture buffer\n");
675 err
= DSERR_OUTOFMEMORY
;
676 /* but the old buffer might still exist and must be re-prepared */
678 ipDSC
->buffer
= newbuf
;
679 ipDSC
->buflen
= buflen
;
684 TRACE("returning DS_OK\n");
688 static HRESULT WINAPI
689 IDirectSoundCaptureBufferImpl_QueryInterface(
690 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
694 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
695 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
697 if (IsEqualGUID( &IID_IDirectSoundNotify
, riid
) ) {
698 IDirectSoundNotifyImpl
*dsn
;
700 dsn
= (IDirectSoundNotifyImpl
*)HeapAlloc(GetProcessHeap(),0,
705 /* FIXME: get this right someday */
706 IDirectSoundCaptureBuffer8_AddRef(iface
);
707 ICOM_VTBL(dsn
) = &dsnvt
;
708 *ppobj
= (LPVOID
)dsn
;
712 if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer8
, riid
) ) {
713 IDirectSoundCaptureBuffer8_AddRef(iface
);
718 FIXME("(%p,%s,%p) unsupported GUID\n", This
, debugstr_guid(riid
), ppobj
);
724 IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
727 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
728 TRACE( "(%p)\n", This
);
730 assert(This
->dsound
);
732 EnterCriticalSection( &(This
->dsound
->lock
) );
734 TRACE( "(%p) was 0x%08lx\n", This
, This
->ref
);
735 uRef
= ++(This
->ref
);
737 LeaveCriticalSection( &(This
->dsound
->lock
) );
743 IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
746 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
747 TRACE( "(%p)\n", This
);
749 assert(This
->dsound
);
751 EnterCriticalSection( &(This
->dsound
->lock
) );
753 TRACE( "(%p) was 0x%08lx\n", This
, This
->ref
);
754 uRef
= --(This
->ref
);
756 LeaveCriticalSection( &(This
->dsound
->lock
) );
759 TRACE("deleting object\n");
761 HeapFree(GetProcessHeap(),0, This
->pdscbd
);
763 if (This
->dsound
->hwi
) {
764 waveInReset(This
->dsound
->hwi
);
765 waveInClose(This
->dsound
->hwi
);
766 if (This
->dsound
->pwave
) {
767 HeapFree(GetProcessHeap(),0, This
->dsound
->pwave
);
768 This
->dsound
->pwave
= 0;
770 This
->dsound
->hwi
= 0;
773 if (This
->dsound
->hwbuf
)
774 IDsCaptureDriverBuffer_Release(This
->dsound
->hwbuf
);
776 /* remove from IDirectSoundCaptureImpl */
778 This
->dsound
->capture_buffer
= NULL
;
780 ERR("does not reference dsound\n");
783 HeapFree(GetProcessHeap(),0, This
->notifies
);
785 HeapFree( GetProcessHeap(), 0, This
);
788 TRACE( "returning 0x%08lx\n", uRef
);
792 static HRESULT WINAPI
793 IDirectSoundCaptureBufferImpl_GetCaps(
794 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
795 LPDSCBCAPS lpDSCBCaps
)
797 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
798 TRACE( "(%p,%p)\n", This
, lpDSCBCaps
);
800 if ( (This
== NULL
) || (lpDSCBCaps
== NULL
) ) {
801 WARN("invalid parameters\n");
802 return DSERR_INVALIDPARAM
;
805 if ( (lpDSCBCaps
->dwSize
< sizeof(DSCBCAPS
)) || (This
->dsound
== NULL
) ) {
806 WARN("invalid parameters\n");
807 return DSERR_INVALIDPARAM
;
810 lpDSCBCaps
->dwSize
= sizeof(DSCBCAPS
);
811 lpDSCBCaps
->dwFlags
= This
->flags
;
812 lpDSCBCaps
->dwBufferBytes
= This
->pdscbd
->dwBufferBytes
;
813 lpDSCBCaps
->dwReserved
= 0;
815 TRACE("returning DS_OK\n");
819 static HRESULT WINAPI
820 IDirectSoundCaptureBufferImpl_GetCurrentPosition(
821 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
822 LPDWORD lpdwCapturePosition
,
823 LPDWORD lpdwReadPosition
)
825 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
826 TRACE( "(%p,%p,%p)\n", This
, lpdwCapturePosition
, lpdwReadPosition
);
828 if ( (This
== NULL
) || (This
->dsound
== NULL
) ) {
829 WARN("invalid parameter\n");
830 return DSERR_INVALIDPARAM
;
833 if (This
->dsound
->driver
) {
834 return IDsCaptureDriverBuffer_GetPosition(This
->dsound
->hwbuf
, lpdwCapturePosition
, lpdwReadPosition
);
835 } else if (This
->dsound
->hwi
) {
836 EnterCriticalSection(&(This
->dsound
->lock
));
837 TRACE("old This->dsound->state=%ld\n",This
->dsound
->state
);
838 if (lpdwCapturePosition
) {
840 mtime
.wType
= TIME_BYTES
;
841 waveInGetPosition(This
->dsound
->hwi
, &mtime
, sizeof(mtime
));
842 TRACE("mtime.u.cb=%ld,This->dsound->buflen=%ld\n", mtime
.u
.cb
,
843 This
->dsound
->buflen
);
844 mtime
.u
.cb
= mtime
.u
.cb
% This
->dsound
->buflen
;
845 *lpdwCapturePosition
= mtime
.u
.cb
;
848 if (lpdwReadPosition
) {
849 if (This
->dsound
->state
== STATE_STARTING
) {
850 if (lpdwCapturePosition
)
851 This
->dsound
->read_position
= *lpdwCapturePosition
;
852 This
->dsound
->state
= STATE_CAPTURING
;
854 *lpdwReadPosition
= This
->dsound
->read_position
;
856 TRACE("new This->dsound->state=%ld\n",This
->dsound
->state
);
857 LeaveCriticalSection(&(This
->dsound
->lock
));
858 if (lpdwCapturePosition
) TRACE("*lpdwCapturePosition=%ld\n",*lpdwCapturePosition
);
859 if (lpdwReadPosition
) TRACE("*lpdwReadPosition=%ld\n",*lpdwReadPosition
);
862 return DSERR_NODRIVER
;
865 TRACE("returning DS_OK\n");
869 static HRESULT WINAPI
870 IDirectSoundCaptureBufferImpl_GetFormat(
871 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
872 LPWAVEFORMATEX lpwfxFormat
,
873 DWORD dwSizeAllocated
,
874 LPDWORD lpdwSizeWritten
)
876 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
877 TRACE( "(%p,%p,0x%08lx,%p)\n", This
, lpwfxFormat
, dwSizeAllocated
,
880 if ( (This
== NULL
) || (This
->dsound
== NULL
) ) {
881 WARN("invalid parameter\n");
882 return DSERR_INVALIDPARAM
;
885 /* FIXME: use real size for extended formats someday */
886 if (dwSizeAllocated
> sizeof(This
->dsound
->wfx
))
887 dwSizeAllocated
= sizeof(This
->dsound
->wfx
);
888 if (lpwfxFormat
) { /* NULL is valid (just want size) */
889 memcpy(lpwfxFormat
,&(This
->dsound
->wfx
),dwSizeAllocated
);
891 *lpdwSizeWritten
= dwSizeAllocated
;
894 *lpdwSizeWritten
= sizeof(This
->dsound
->wfx
);
896 TRACE("invalid parameter\n");
897 return DSERR_INVALIDPARAM
;
901 TRACE("returning DS_OK\n");
905 static HRESULT WINAPI
906 IDirectSoundCaptureBufferImpl_GetStatus(
907 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
910 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
911 TRACE( "(%p, %p), thread is %04lx\n", This
, lpdwStatus
, GetCurrentThreadId() );
913 if ( (This
== NULL
) || (This
->dsound
== NULL
) || (lpdwStatus
== NULL
) ) {
914 WARN("invalid parameter\n");
915 return DSERR_INVALIDPARAM
;
919 EnterCriticalSection(&(This
->dsound
->lock
));
921 TRACE("old This->dsound->state=%ld, old lpdwStatus=%08lx\n",This
->dsound
->state
,*lpdwStatus
);
922 if ((This
->dsound
->state
== STATE_STARTING
) ||
923 (This
->dsound
->state
== STATE_CAPTURING
)) {
924 *lpdwStatus
|= DSCBSTATUS_CAPTURING
;
925 if (This
->flags
& DSCBSTART_LOOPING
)
926 *lpdwStatus
|= DSCBSTATUS_LOOPING
;
928 TRACE("new This->dsound->state=%ld, new lpdwStatus=%08lx\n",This
->dsound
->state
,*lpdwStatus
);
929 LeaveCriticalSection(&(This
->dsound
->lock
));
931 TRACE("status=%lx\n", *lpdwStatus
);
932 TRACE("returning DS_OK\n");
936 static HRESULT WINAPI
937 IDirectSoundCaptureBufferImpl_Initialize(
938 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
939 LPDIRECTSOUNDCAPTURE lpDSC
,
940 LPCDSCBUFFERDESC lpcDSCBDesc
)
942 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
944 FIXME( "(%p,%p,%p): stub\n", This
, lpDSC
, lpcDSCBDesc
);
949 static HRESULT WINAPI
950 IDirectSoundCaptureBufferImpl_Lock(
951 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
954 LPVOID
* lplpvAudioPtr1
,
955 LPDWORD lpdwAudioBytes1
,
956 LPVOID
* lplpvAudioPtr2
,
957 LPDWORD lpdwAudioBytes2
,
961 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
962 TRACE( "(%p,%08lu,%08lu,%p,%p,%p,%p,0x%08lx) at %ld\n", This
, dwReadCusor
,
963 dwReadBytes
, lplpvAudioPtr1
, lpdwAudioBytes1
, lplpvAudioPtr2
,
964 lpdwAudioBytes2
, dwFlags
, GetTickCount() );
966 if ( (This
== NULL
) || (This
->dsound
== NULL
) || (lplpvAudioPtr1
== NULL
) ||
967 (lpdwAudioBytes1
== NULL
) ) {
968 WARN("invalid parameter\n");
969 return DSERR_INVALIDPARAM
;
972 EnterCriticalSection(&(This
->dsound
->lock
));
974 if (This
->dsound
->driver
) {
975 err
= IDsCaptureDriverBuffer_Lock(This
->dsound
->hwbuf
, lplpvAudioPtr1
,
976 lpdwAudioBytes1
, lplpvAudioPtr2
, lpdwAudioBytes2
,
977 dwReadCusor
, dwReadBytes
, dwFlags
);
978 } else if (This
->dsound
->hwi
) {
979 *lplpvAudioPtr1
= This
->dsound
->buffer
+ dwReadCusor
;
980 if ( (dwReadCusor
+ dwReadBytes
) > This
->dsound
->buflen
) {
981 *lpdwAudioBytes1
= This
->dsound
->buflen
- dwReadCusor
;
983 *lplpvAudioPtr2
= This
->dsound
->buffer
;
985 *lpdwAudioBytes2
= dwReadBytes
- *lpdwAudioBytes1
;
987 *lpdwAudioBytes1
= dwReadBytes
;
991 *lpdwAudioBytes2
= 0;
994 TRACE("invalid call\n");
995 err
= DSERR_INVALIDCALL
; /* DSERR_NODRIVER ? */
998 LeaveCriticalSection(&(This
->dsound
->lock
));
1003 static HRESULT WINAPI
1004 IDirectSoundCaptureBufferImpl_Start(
1005 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
1008 HRESULT err
= DS_OK
;
1009 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
1010 TRACE( "(%p,0x%08lx)\n", This
, dwFlags
);
1012 if ( (This
== NULL
) || (This
->dsound
== NULL
) ) {
1013 WARN("invalid parameter\n");
1014 return DSERR_INVALIDPARAM
;
1017 if ( (This
->dsound
->driver
== 0) && (This
->dsound
->hwi
== 0) ) {
1018 WARN("no driver\n");
1019 return DSERR_NODRIVER
;
1022 EnterCriticalSection(&(This
->dsound
->lock
));
1024 This
->flags
= dwFlags
;
1025 TRACE("old This->dsound->state=%ld\n",This
->dsound
->state
);
1026 if (This
->dsound
->state
== STATE_STOPPED
)
1027 This
->dsound
->state
= STATE_STARTING
;
1028 else if (This
->dsound
->state
== STATE_STOPPING
)
1029 This
->dsound
->state
= STATE_CAPTURING
;
1030 TRACE("new This->dsound->state=%ld\n",This
->dsound
->state
);
1032 LeaveCriticalSection(&(This
->dsound
->lock
));
1034 if (This
->dsound
->driver
) {
1035 err
= IDsCaptureDriverBuffer_Start(This
->dsound
->hwbuf
, dwFlags
);
1038 IDirectSoundCaptureImpl
* ipDSC
= This
->dsound
;
1040 if (ipDSC
->buffer
) {
1041 if (This
->nrofnotifies
) {
1044 ipDSC
->nrofpwaves
= This
->nrofnotifies
;
1046 /* prepare headers */
1047 ipDSC
->pwave
= HeapReAlloc(GetProcessHeap(),0,ipDSC
->pwave
,
1048 ipDSC
->nrofpwaves
*sizeof(WAVEHDR
));
1050 for (c
= 0; c
< ipDSC
->nrofpwaves
; c
++) {
1052 ipDSC
->pwave
[0].lpData
= ipDSC
->buffer
;
1053 ipDSC
->pwave
[0].dwBufferLength
=
1054 This
->notifies
[0].dwOffset
+ 1;
1056 ipDSC
->pwave
[c
].lpData
= ipDSC
->buffer
+
1057 This
->notifies
[c
-1].dwOffset
+ 1;
1058 ipDSC
->pwave
[c
].dwBufferLength
=
1059 This
->notifies
[c
].dwOffset
-
1060 This
->notifies
[c
-1].dwOffset
;
1062 ipDSC
->pwave
[c
].dwUser
= (DWORD
)ipDSC
;
1063 ipDSC
->pwave
[c
].dwFlags
= 0;
1064 ipDSC
->pwave
[c
].dwLoops
= 0;
1065 err
= mmErr(waveInPrepareHeader(ipDSC
->hwi
,
1066 &(ipDSC
->pwave
[c
]),sizeof(WAVEHDR
)));
1069 waveInUnprepareHeader(ipDSC
->hwi
,
1070 &(ipDSC
->pwave
[c
]),sizeof(WAVEHDR
));
1075 memset(ipDSC
->buffer
,
1076 (ipDSC
->wfx
.wBitsPerSample
== 16) ? 0 : 128, ipDSC
->buflen
);
1078 TRACE("no notifiers specified\n");
1079 /* no notifiers specified so just create a single default header */
1080 ipDSC
->nrofpwaves
= 1;
1081 ipDSC
->pwave
= HeapReAlloc(GetProcessHeap(),0,ipDSC
->pwave
,sizeof(WAVEHDR
));
1082 ipDSC
->pwave
[0].lpData
= ipDSC
->buffer
;
1083 ipDSC
->pwave
[0].dwBufferLength
= ipDSC
->buflen
;
1084 ipDSC
->pwave
[0].dwUser
= (DWORD
)ipDSC
;
1085 ipDSC
->pwave
[0].dwFlags
= 0;
1086 ipDSC
->pwave
[0].dwLoops
= 0;
1088 err
= mmErr(waveInPrepareHeader(ipDSC
->hwi
,
1089 &(ipDSC
->pwave
[0]),sizeof(WAVEHDR
)));
1091 waveInUnprepareHeader(ipDSC
->hwi
,
1092 &(ipDSC
->pwave
[0]),sizeof(WAVEHDR
));
1098 ipDSC
->read_position
= 0;
1101 err
= mmErr(waveInReset(ipDSC
->hwi
));
1103 /* add the first buffer to the queue */
1104 err
= mmErr(waveInAddBuffer(ipDSC
->hwi
, &(ipDSC
->pwave
[0]), sizeof(WAVEHDR
)));
1106 /* start filling the first buffer */
1107 err
= mmErr(waveInStart(ipDSC
->hwi
));
1114 WARN("calling waveInClose because of error\n");
1115 waveInClose(This
->dsound
->hwi
);
1116 This
->dsound
->hwi
= 0;
1119 TRACE("returning %ld\n", err
);
1123 static HRESULT WINAPI
1124 IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
1126 HRESULT err
= DS_OK
;
1127 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
1128 TRACE( "(%p)\n", This
);
1130 if ( (This
== NULL
) || (This
->dsound
== NULL
) ) {
1131 WARN("invalid parameter\n");
1132 return DSERR_INVALIDPARAM
;
1135 EnterCriticalSection(&(This
->dsound
->lock
));
1137 TRACE("old This->dsound->state=%ld\n",This
->dsound
->state
);
1138 if (This
->dsound
->state
== STATE_CAPTURING
)
1139 This
->dsound
->state
= STATE_STOPPING
;
1140 else if (This
->dsound
->state
== STATE_STARTING
)
1141 This
->dsound
->state
= STATE_STOPPED
;
1142 TRACE("new This->dsound->state=%ld\n",This
->dsound
->state
);
1144 LeaveCriticalSection(&(This
->dsound
->lock
));
1146 if (This
->dsound
->driver
) {
1147 err
= IDsCaptureDriverBuffer_Stop(This
->dsound
->hwbuf
);
1148 if (err
== DSERR_BUFFERLOST
) {
1149 /* Wine-only: the driver wants us to reopen the device */
1150 IDsCaptureDriverBuffer_Release(This
->dsound
->hwbuf
);
1151 err
= IDsCaptureDriver_CreateCaptureBuffer(This
->dsound
->driver
,
1152 &(This
->dsound
->wfx
),0,0,&(This
->dsound
->buflen
),&(This
->dsound
->buffer
),
1153 (LPVOID
*)&(This
->dsound
->hwbuf
));
1155 WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n");
1156 This
->dsound
->hwbuf
= 0;
1159 } else if (This
->dsound
->hwi
) {
1160 err
= waveInStop(This
->dsound
->hwi
);
1162 WARN("no driver\n");
1163 err
= DSERR_NODRIVER
;
1166 TRACE( "(%p) returning 0x%08lx\n", This
,err
);
1170 static HRESULT WINAPI
1171 IDirectSoundCaptureBufferImpl_Unlock(
1172 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
1173 LPVOID lpvAudioPtr1
,
1174 DWORD dwAudioBytes1
,
1175 LPVOID lpvAudioPtr2
,
1176 DWORD dwAudioBytes2
)
1178 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
1179 TRACE( "(%p,%p,%08lu,%p,%08lu)\n", This
, lpvAudioPtr1
, dwAudioBytes1
,
1180 lpvAudioPtr2
, dwAudioBytes2
);
1182 if ( (This
== NULL
) || (lpvAudioPtr1
== NULL
) ) {
1183 WARN("invalid parameters\n");
1184 return DSERR_INVALIDPARAM
;
1187 if (This
->dsound
->driver
) {
1188 return IDsCaptureDriverBuffer_Unlock(This
->dsound
->hwbuf
, lpvAudioPtr1
,
1189 dwAudioBytes1
, lpvAudioPtr2
, dwAudioBytes2
);
1190 } else if (This
->dsound
->hwi
) {
1191 This
->dsound
->read_position
= (This
->dsound
->read_position
+
1192 (dwAudioBytes1
+ dwAudioBytes2
)) % This
->dsound
->buflen
;
1194 WARN("invalid call\n");
1195 return DSERR_INVALIDCALL
;
1201 static HRESULT WINAPI
1202 IDirectSoundCaptureBufferImpl_GetObjectInPath(
1203 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
1204 REFGUID rguidObject
,
1206 REFGUID rguidInterface
,
1209 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
1211 FIXME( "(%p,%s,%lu,%s,%p): stub\n", This
, debugstr_guid(rguidObject
),
1212 dwIndex
, debugstr_guid(rguidInterface
), ppObject
);
1217 static HRESULT WINAPI
1218 IDirectSoundCaptureBufferImpl_GetFXStatus(
1219 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
1221 LPDWORD pdwFXStatus
)
1223 ICOM_THIS(IDirectSoundCaptureBufferImpl
,iface
);
1225 FIXME( "(%p,%lu,%p): stub\n", This
, dwFXCount
, pdwFXStatus
);
1230 static ICOM_VTABLE(IDirectSoundCaptureBuffer8
) dscbvt
=
1232 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1233 /* IUnknown methods */
1234 IDirectSoundCaptureBufferImpl_QueryInterface
,
1235 IDirectSoundCaptureBufferImpl_AddRef
,
1236 IDirectSoundCaptureBufferImpl_Release
,
1238 /* IDirectSoundCaptureBuffer methods */
1239 IDirectSoundCaptureBufferImpl_GetCaps
,
1240 IDirectSoundCaptureBufferImpl_GetCurrentPosition
,
1241 IDirectSoundCaptureBufferImpl_GetFormat
,
1242 IDirectSoundCaptureBufferImpl_GetStatus
,
1243 IDirectSoundCaptureBufferImpl_Initialize
,
1244 IDirectSoundCaptureBufferImpl_Lock
,
1245 IDirectSoundCaptureBufferImpl_Start
,
1246 IDirectSoundCaptureBufferImpl_Stop
,
1247 IDirectSoundCaptureBufferImpl_Unlock
,
1249 /* IDirectSoundCaptureBuffer methods */
1250 IDirectSoundCaptureBufferImpl_GetObjectInPath
,
1251 IDirectSoundCaptureBufferImpl_GetFXStatus
1254 /***************************************************************************
1255 * DirectSoundFullDuplexCreate8 [DSOUND.8]
1257 * Create and initialize a DirectSoundFullDuplex interface
1261 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
1262 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
1265 DirectSoundFullDuplexCreate8(
1266 LPCGUID pcGuidCaptureDevice
,
1267 LPCGUID pcGuidRenderDevice
,
1268 LPCDSCBUFFERDESC pcDSCBufferDesc
,
1269 LPCDSBUFFERDESC pcDSBufferDesc
,
1272 LPDIRECTSOUNDFULLDUPLEX
*ppDSFD
,
1273 LPDIRECTSOUNDCAPTUREBUFFER8
*ppDSCBuffer8
,
1274 LPDIRECTSOUNDBUFFER8
*ppDSBuffer8
,
1275 LPUNKNOWN pUnkOuter
)
1277 IDirectSoundFullDuplexImpl
** ippDSFD
=(IDirectSoundFullDuplexImpl
**)ppDSFD
;
1278 TRACE("(%s,%s,%p,%p,%lx,%lx,%p,%p,%p,%p)\n", debugstr_guid(pcGuidCaptureDevice
),
1279 debugstr_guid(pcGuidRenderDevice
), pcDSCBufferDesc
, pcDSBufferDesc
,
1280 (DWORD
)hWnd
, dwLevel
, ppDSFD
, ppDSCBuffer8
, ppDSBuffer8
, pUnkOuter
);
1283 WARN("pUnkOuter != 0\n");
1284 return DSERR_NOAGGREGATION
;
1287 *ippDSFD
= (IDirectSoundFullDuplexImpl
*)HeapAlloc(GetProcessHeap(),
1288 HEAP_ZERO_MEMORY
, sizeof(IDirectSoundFullDuplexImpl
));
1290 if (*ippDSFD
== NULL
) {
1291 TRACE("couldn't allocate memory\n");
1292 return DSERR_OUTOFMEMORY
;
1296 ICOM_THIS(IDirectSoundFullDuplexImpl
, *ippDSFD
);
1300 InitializeCriticalSection( &(This
->lock
) );
1302 ICOM_VTBL(This
) = &dsfdvt
;
1304 return IDirectSoundFullDuplexImpl_Initialize( (LPDIRECTSOUNDFULLDUPLEX
)This
,
1305 pcGuidCaptureDevice
, pcGuidRenderDevice
,
1306 pcDSCBufferDesc
, pcDSBufferDesc
,
1307 hWnd
, dwLevel
, ppDSCBuffer8
, ppDSBuffer8
);
1311 static HRESULT WINAPI
1312 IDirectSoundFullDuplexImpl_QueryInterface(
1313 LPDIRECTSOUNDFULLDUPLEX iface
,
1317 ICOM_THIS(IDirectSoundFullDuplexImpl
,iface
);
1318 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
1324 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface
)
1327 ICOM_THIS(IDirectSoundFullDuplexImpl
,iface
);
1329 EnterCriticalSection( &(This
->lock
) );
1331 TRACE( "(%p) was 0x%08lx\n", This
, This
->ref
);
1332 uRef
= ++(This
->ref
);
1334 LeaveCriticalSection( &(This
->lock
) );
1340 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface
)
1343 ICOM_THIS(IDirectSoundFullDuplexImpl
,iface
);
1345 EnterCriticalSection( &(This
->lock
) );
1347 TRACE( "(%p) was 0x%08lx\n", This
, This
->ref
);
1348 uRef
= --(This
->ref
);
1350 LeaveCriticalSection( &(This
->lock
) );
1353 TRACE("deleting object\n");
1354 DeleteCriticalSection( &(This
->lock
) );
1355 HeapFree( GetProcessHeap(), 0, This
);
1361 static HRESULT WINAPI
1362 IDirectSoundFullDuplexImpl_Initialize(
1363 LPDIRECTSOUNDFULLDUPLEX iface
,
1364 LPCGUID pCaptureGuid
,
1365 LPCGUID pRendererGuid
,
1366 LPCDSCBUFFERDESC lpDscBufferDesc
,
1367 LPCDSBUFFERDESC lpDsBufferDesc
,
1370 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8
,
1371 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8
)
1373 ICOM_THIS(IDirectSoundFullDuplexImpl
,iface
);
1374 IDirectSoundCaptureBufferImpl
** ippdscb
=(IDirectSoundCaptureBufferImpl
**)lplpDirectSoundCaptureBuffer8
;
1375 IDirectSoundBufferImpl
** ippdsc
=(IDirectSoundBufferImpl
**)lplpDirectSoundBuffer8
;
1377 TRACE( "(%p,%s,%s,%p,%p,%lx,%lx,%p,%p)\n", This
, debugstr_guid(pCaptureGuid
),
1378 debugstr_guid(pRendererGuid
), lpDscBufferDesc
, lpDsBufferDesc
, (DWORD
)hWnd
, dwLevel
,
1384 static ICOM_VTABLE(IDirectSoundFullDuplex
) dsfdvt
=
1386 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1387 /* IUnknown methods */
1388 IDirectSoundFullDuplexImpl_QueryInterface
,
1389 IDirectSoundFullDuplexImpl_AddRef
,
1390 IDirectSoundFullDuplexImpl_Release
,
1392 /* IDirectSoundFullDuplex methods */
1393 IDirectSoundFullDuplexImpl_Initialize