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.
88 * lpcGUID [I] Address of the GUID that identifies the sound capture device.
89 * lplpDSC [O] Address of a variable to receive the interface pointer.
90 * pUnkOuter [I] Must be NULL.
94 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
98 * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
99 * or NULL for the default device or DSDEVID_DefaultCapture or
100 * DSDEVID_DefaultVoiceCapture.
102 * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
105 DirectSoundCaptureCreate8(
107 LPDIRECTSOUNDCAPTURE* lplpDSC,
108 LPUNKNOWN pUnkOuter )
110 IDirectSoundCaptureImpl** ippDSC=(IDirectSoundCaptureImpl**)lplpDSC;
111 TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), lplpDSC, pUnkOuter);
114 WARN("invalid parameter: pUnkOuter != NULL\n");
115 return DSERR_NOAGGREGATION;
119 WARN("invalid parameter: lplpDSC == NULL\n");
120 return DSERR_INVALIDPARAM;
123 /* Default device? */
124 if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
125 lpcGUID = &DSDEVID_DefaultCapture;
127 *ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
128 HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
130 if (*ippDSC == NULL) {
131 WARN("out of memory\n");
132 return DSERR_OUTOFMEMORY;
134 ICOM_THIS(IDirectSoundCaptureImpl, *ippDSC);
137 This->state = STATE_STOPPED;
139 InitializeCriticalSection( &(This->lock) );
141 This->lpVtbl = &dscvt;
142 dsound_capture = This;
144 if (GetDeviceID(lpcGUID, &This->guid) == DS_OK) {
146 hres = IDirectSoundCaptureImpl_Initialize( (LPDIRECTSOUNDCAPTURE)This, &This->guid);
148 WARN("IDirectSoundCaptureImpl_Initialize failed\n");
152 WARN("invalid GUID: %s\n", debugstr_guid(lpcGUID));
153 return DSERR_INVALIDPARAM;
156 /***************************************************************************
157 * DirectSoundCaptureEnumerateA [DSOUND.7]
159 * Enumerate all DirectSound drivers installed in the system.
162 * lpDSEnumCallback [I] Address of callback function.
163 * lpContext [I] Address of user defined context passed to callback function.
167 * Failure: DSERR_INVALIDPARAM
170 DirectSoundCaptureEnumerateA(
171 LPDSENUMCALLBACKA lpDSEnumCallback,
179 TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
181 if (lpDSEnumCallback == NULL) {
182 WARN("invalid parameter: lpDSEnumCallback == NULL\n");
183 return DSERR_INVALIDPARAM;
186 devs = waveInGetNumDevs();
188 if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
190 for (wid = 0; wid < devs; ++wid) {
191 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
193 if (IsEqualGUID( &guid, &temp ) ) {
194 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
196 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
197 debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
198 if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, "Primary Sound Capture Driver", desc.szDrvName, lpContext) == FALSE)
207 for (wid = 0; wid < devs; ++wid) {
208 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
210 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
212 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
213 debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
214 if (lpDSEnumCallback(&guid, desc.szDesc, desc.szDrvName, lpContext) == FALSE)
223 /***************************************************************************
224 * DirectSoundCaptureEnumerateW [DSOUND.8]
226 * Enumerate all DirectSound drivers installed in the system.
229 * lpDSEnumCallback [I] Address of callback function.
230 * lpContext [I] Address of user defined context passed to callback function.
234 * Failure: DSERR_INVALIDPARAM
237 DirectSoundCaptureEnumerateW(
238 LPDSENUMCALLBACKW lpDSEnumCallback,
245 WCHAR wDesc[MAXPNAMELEN];
246 WCHAR wName[MAXPNAMELEN];
248 TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
250 if (lpDSEnumCallback == NULL) {
251 WARN("invalid parameter: lpDSEnumCallback == NULL\n");
252 return DSERR_INVALIDPARAM;
255 devs = waveInGetNumDevs();
257 if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
259 for (wid = 0; wid < devs; ++wid) {
260 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
262 if (IsEqualGUID( &guid, &temp ) ) {
263 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
265 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
266 debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
267 MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
268 wDesc, sizeof(wDesc)/sizeof(WCHAR) );
269 MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
270 wName, sizeof(wName)/sizeof(WCHAR) );
271 if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
280 for (wid = 0; wid < devs; ++wid) {
281 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
283 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
285 TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
286 debugstr_guid(&DSDEVID_DefaultCapture),desc.szDesc,desc.szDrvName,lpContext);
287 MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
288 wDesc, sizeof(wDesc)/sizeof(WCHAR) );
289 MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
290 wName, sizeof(wName)/sizeof(WCHAR) );
291 if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
301 DSOUND_capture_callback(
308 IDirectSoundCaptureImpl* This = (IDirectSoundCaptureImpl*)dwUser;
309 TRACE("(%p,%08x(%s),%08lx,%08lx,%08lx) entering at %ld\n",hwi,msg,
310 msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" :
311 msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount());
313 if (msg == MM_WIM_DATA) {
314 EnterCriticalSection( &(This->lock) );
315 TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%ld, old This->index=%d\n",This->state,This->index);
316 if (This->state != STATE_STOPPED) {
317 if (This->state == STATE_STARTING) {
319 mtime.wType = TIME_BYTES;
320 waveInGetPosition(This->hwi, &mtime, sizeof(mtime));
321 TRACE("mtime.u.cb=%ld,This->buflen=%ld\n", mtime.u.cb, This->buflen);
322 mtime.u.cb = mtime.u.cb % This->buflen;
323 This->read_position = mtime.u.cb;
324 This->state = STATE_CAPTURING;
326 This->index = (This->index + 1) % This->nrofpwaves;
327 waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR));
328 if (This->capture_buffer->notify && This->capture_buffer->notify->nrofnotifies)
329 SetEvent(This->capture_buffer->notify->notifies[This->index].hEventNotify);
330 if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
331 TRACE("end of buffer\n");
332 This->state = STATE_STOPPED;
334 if (This->state == STATE_CAPTURING) {
335 waveInPrepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR));
336 waveInAddBuffer(hwi, &(This->pwave[This->index]), sizeof(WAVEHDR));
340 TRACE("DirectSoundCapture new This->state=%ld, new This->index=%d\n",This->state,This->index);
341 LeaveCriticalSection( &(This->lock) );
344 TRACE("completed\n");
347 static HRESULT WINAPI
348 IDirectSoundCaptureImpl_QueryInterface(
349 LPDIRECTSOUNDCAPTURE iface,
353 ICOM_THIS(IDirectSoundCaptureImpl,iface);
354 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
358 hres = IDsCaptureDriver_QueryInterface(This->driver, riid, ppobj);
360 WARN("IDsCaptureDriver_QueryInterface failed\n");
364 WARN("unsupported riid: %s\n", debugstr_guid(riid));
369 IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface )
372 ICOM_THIS(IDirectSoundCaptureImpl,iface);
374 EnterCriticalSection( &(This->lock) );
376 TRACE( "(%p) was 0x%08lx\n", This, This->ref );
377 uRef = ++(This->ref);
380 IDsCaptureDriver_AddRef(This->driver);
382 LeaveCriticalSection( &(This->lock) );
388 IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface )
391 ICOM_THIS(IDirectSoundCaptureImpl,iface);
393 EnterCriticalSection( &(This->lock) );
395 TRACE( "(%p) was 0x%08lx\n", This, This->ref );
396 uRef = --(This->ref);
398 LeaveCriticalSection( &(This->lock) );
401 TRACE("deleting object\n");
402 if (This->capture_buffer)
403 IDirectSoundCaptureBufferImpl_Release(
404 (LPDIRECTSOUNDCAPTUREBUFFER8) This->capture_buffer);
407 IDsCaptureDriver_Close(This->driver);
408 IDsCaptureDriver_Release(This->driver);
411 DeleteCriticalSection( &(This->lock) );
412 HeapFree( GetProcessHeap(), 0, This );
413 dsound_capture = NULL;
416 TRACE( "returning 0x%08lx\n", uRef );
420 static HRESULT WINAPI
421 IDirectSoundCaptureImpl_CreateCaptureBuffer(
422 LPDIRECTSOUNDCAPTURE iface,
423 LPCDSCBUFFERDESC lpcDSCBufferDesc,
424 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
428 ICOM_THIS(IDirectSoundCaptureImpl,iface);
430 TRACE( "(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk );
433 WARN("invalid parameter: This == NULL\n");
434 return DSERR_INVALIDPARAM;
437 if (lpcDSCBufferDesc == NULL) {
438 WARN("invalid parameter: lpcDSCBufferDesc == NULL)\n");
439 return DSERR_INVALIDPARAM;
442 if (lplpDSCaptureBuffer == NULL) {
443 WARN("invalid parameter: lplpDSCaptureBuffer == NULL\n");
444 return DSERR_INVALIDPARAM;
448 WARN("invalid parameter: pUnk != NULL\n");
449 return DSERR_INVALIDPARAM;
452 /* FIXME: We can only have one buffer so what do we do here? */
453 if (This->capture_buffer) {
454 WARN("lnvalid parameter: already has buffer\n");
455 return DSERR_INVALIDPARAM; /* DSERR_GENERIC ? */
458 hr = DSOUND_CreateDirectSoundCaptureBuffer( This, lpcDSCBufferDesc,
459 (LPVOID*)lplpDSCaptureBuffer );
462 WARN("DSOUND_CreateDirectSoundCaptureBuffer failed\n");
467 static HRESULT WINAPI
468 IDirectSoundCaptureImpl_GetCaps(
469 LPDIRECTSOUNDCAPTURE iface,
470 LPDSCCAPS lpDSCCaps )
472 ICOM_THIS(IDirectSoundCaptureImpl,iface);
473 TRACE("(%p,%p)\n",This,lpDSCCaps);
475 if (lpDSCCaps== NULL) {
476 WARN("invalid parameter: lpDSCCaps== NULL\n");
477 return DSERR_INVALIDPARAM;
480 if (lpDSCCaps->dwSize < sizeof(*lpDSCCaps)) {
481 WARN("invalid parameter: lpDSCCaps->dwSize = %ld < %d\n",
482 lpDSCCaps->dwSize, sizeof(*lpDSCCaps));
483 return DSERR_INVALIDPARAM;
486 if ( !(This->initialized) ) {
487 WARN("not initialized\n");
488 return DSERR_UNINITIALIZED;
491 lpDSCCaps->dwFlags = This->drvcaps.dwFlags;
492 lpDSCCaps->dwFormats = This->drvcaps.dwFormats;
493 lpDSCCaps->dwChannels = This->drvcaps.dwChannels;
495 TRACE("(flags=0x%08lx,format=0x%08lx,channels=%ld)\n",lpDSCCaps->dwFlags,
496 lpDSCCaps->dwFormats, lpDSCCaps->dwChannels);
501 static HRESULT WINAPI
502 IDirectSoundCaptureImpl_Initialize(
503 LPDIRECTSOUNDCAPTURE iface,
506 HRESULT err = DSERR_INVALIDPARAM;
508 ICOM_THIS(IDirectSoundCaptureImpl,iface);
509 TRACE("(%p)\n", This);
512 WARN("invalid parameter: This == NULL\n");
513 return DSERR_INVALIDPARAM;
516 if (This->initialized) {
517 WARN("already initialized\n");
518 return DSERR_ALREADYINITIALIZED;
521 widn = waveInGetNumDevs();
524 WARN("no audio devices found\n");
525 return DSERR_NODRIVER;
528 /* Get dsound configuration */
529 setup_dsound_options();
531 /* enumerate WINMM audio devices and find the one we want */
532 for (wid=0; wid<widn; wid++) {
534 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
536 WARN("waveInMessage failed; err=%lx\n",err);
539 if (IsEqualGUID( lpcGUID, &guid) ) {
546 WARN("invalid parameter\n");
547 return DSERR_INVALIDPARAM;
550 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&(This->driver),0));
551 if ( (err != DS_OK) && (err != DSERR_UNSUPPORTED) ) {
552 WARN("waveInMessage failed; err=%lx\n",err);
557 /* Disable the direct sound driver to force emulation if requested. */
558 if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
561 /* Get driver description */
563 TRACE("using DirectSound driver\n");
564 err = IDsCaptureDriver_GetDriverDesc(This->driver, &(This->drvdesc));
566 WARN("IDsCaptureDriver_GetDriverDesc failed\n");
570 TRACE("using WINMM\n");
571 /* if no DirectSound interface available, use WINMM API instead */
572 This->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN |
573 DSDDESC_DOMMSYSTEMSETFORMAT;
576 This->drvdesc.dnDevNode = wid;
578 /* open the DirectSound driver if available */
579 if (This->driver && (err == DS_OK))
580 err = IDsCaptureDriver_Open(This->driver);
583 This->initialized = TRUE;
585 /* the driver is now open, so it's now allowed to call GetCaps */
587 This->drvcaps.dwSize = sizeof(This->drvcaps);
588 err = IDsCaptureDriver_GetCaps(This->driver,&(This->drvcaps));
590 WARN("IDsCaptureDriver_GetCaps failed\n");
593 } else /*if (This->hwi)*/ {
595 err = mmErr(waveInGetDevCapsA((UINT)This->drvdesc.dnDevNode, &wic, sizeof(wic)));
598 This->drvcaps.dwFlags = 0;
599 strncpy(This->drvdesc.szDrvName, wic.szPname,
600 sizeof(This->drvdesc.szDrvName));
602 This->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
603 This->drvcaps.dwFormats = wic.dwFormats;
604 This->drvcaps.dwChannels = wic.wChannels;
612 static ICOM_VTABLE(IDirectSoundCapture) dscvt =
614 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
615 /* IUnknown methods */
616 IDirectSoundCaptureImpl_QueryInterface,
617 IDirectSoundCaptureImpl_AddRef,
618 IDirectSoundCaptureImpl_Release,
620 /* IDirectSoundCapture methods */
621 IDirectSoundCaptureImpl_CreateCaptureBuffer,
622 IDirectSoundCaptureImpl_GetCaps,
623 IDirectSoundCaptureImpl_Initialize
627 DSOUND_CreateDirectSoundCaptureBuffer(
628 IDirectSoundCaptureImpl *ipDSC,
629 LPCDSCBUFFERDESC lpcDSCBufferDesc,
633 TRACE( "(%p,%p)\n", lpcDSCBufferDesc, ppobj );
636 WARN("invalid parameter: ipDSC == NULL\n");
637 return DSERR_INVALIDPARAM;
640 if (lpcDSCBufferDesc == NULL) {
641 WARN("invalid parameter: lpcDSCBufferDesc == NULL\n");
642 return DSERR_INVALIDPARAM;
646 WARN("invalid parameter: ppobj == NULL\n");
647 return DSERR_INVALIDPARAM;
650 if ( (lpcDSCBufferDesc->dwSize < sizeof(DSCBUFFERDESC)) ||
651 (lpcDSCBufferDesc->dwBufferBytes == 0) ||
652 (lpcDSCBufferDesc->lpwfxFormat == NULL) ) {
653 WARN("invalid lpcDSCBufferDesc\n");
655 return DSERR_INVALIDPARAM;
658 if ( !ipDSC->initialized ) {
659 WARN("not initialized\n");
661 return DSERR_UNINITIALIZED;
664 wfex = lpcDSCBufferDesc->lpwfxFormat;
667 TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
668 "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
669 wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
670 wfex->nAvgBytesPerSec, wfex->nBlockAlign,
671 wfex->wBitsPerSample, wfex->cbSize);
673 if (wfex->wFormatTag == WAVE_FORMAT_PCM)
674 memcpy(&(ipDSC->wfx), wfex, sizeof(WAVEFORMATEX));
676 WARN("non PCM formats not supported\n");
678 return DSERR_BADFORMAT;
681 WARN("lpcDSCBufferDesc->lpwfxFormat == 0\n");
683 return DSERR_INVALIDPARAM; /* FIXME: DSERR_BADFORMAT ? */
686 *ppobj = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
687 sizeof(IDirectSoundCaptureBufferImpl));
689 if ( *ppobj == NULL ) {
690 WARN("out of memory\n");
692 return DSERR_OUTOFMEMORY;
695 ICOM_THIS(IDirectSoundCaptureBufferImpl,*ppobj);
698 This->dsound = ipDSC;
699 This->dsound->capture_buffer = This;
701 This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
702 lpcDSCBufferDesc->dwSize);
704 memcpy(This->pdscbd, lpcDSCBufferDesc, lpcDSCBufferDesc->dwSize);
707 This->dsound->capture_buffer = 0;
708 HeapFree( GetProcessHeap(), 0, This );
710 return DSERR_OUTOFMEMORY;
713 This->lpVtbl = &dscbvt;
716 err = IDsCaptureDriver_CreateCaptureBuffer(ipDSC->driver,
717 &(ipDSC->wfx),0,0,&(ipDSC->buflen),&(ipDSC->buffer),(LPVOID*)&(ipDSC->hwbuf));
719 WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n");
720 This->dsound->capture_buffer = 0;
721 HeapFree( GetProcessHeap(), 0, This );
728 DWORD flags = CALLBACK_FUNCTION;
729 if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
730 flags |= WAVE_DIRECTSOUND;
731 err = mmErr(waveInOpen(&(ipDSC->hwi),
732 ipDSC->drvdesc.dnDevNode, &(ipDSC->wfx),
733 (DWORD)DSOUND_capture_callback, (DWORD)ipDSC, flags));
735 WARN("waveInOpen failed\n");
736 This->dsound->capture_buffer = 0;
737 HeapFree( GetProcessHeap(), 0, This );
742 buflen = lpcDSCBufferDesc->dwBufferBytes;
743 TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->buffer);
744 newbuf = (LPBYTE)HeapReAlloc(GetProcessHeap(),0,ipDSC->buffer,buflen);
746 if (newbuf == NULL) {
747 WARN("failed to allocate capture buffer\n");
748 err = DSERR_OUTOFMEMORY;
749 /* but the old buffer might still exist and must be re-prepared */
751 ipDSC->buffer = newbuf;
752 ipDSC->buflen = buflen;
757 TRACE("returning DS_OK\n");
761 static HRESULT WINAPI
762 IDirectSoundCaptureBufferImpl_QueryInterface(
763 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
767 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
768 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
770 if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ||
771 IsEqualGUID( &IID_IDirectSoundNotify8, riid ) ) {
773 This->notify = (IDirectSoundNotifyImpl*)HeapAlloc(GetProcessHeap(),
774 HEAP_ZERO_MEMORY, sizeof(*This->notify));
776 This->notify->ref = 0; /* release when ref = -1 */
777 This->notify->lpVtbl = &dsnvt;
781 if (This->dsound->hwbuf) {
784 err = IDsCaptureDriverBuffer_QueryInterface(This->dsound->hwbuf,
785 &IID_IDsDriverNotify, (LPVOID*)&(This->notify->hwnotify));
787 WARN("IDsCaptureDriverBuffer_QueryInterface failed\n");
793 IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
794 *ppobj = (LPVOID)This->notify;
799 WARN("IID_IDirectSoundNotify\n");
803 if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer, riid ) ||
804 IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) {
805 IDirectSoundCaptureBuffer8_AddRef(iface);
810 FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
814 return E_NOINTERFACE;
818 IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
821 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
822 TRACE( "(%p)\n", This );
824 assert(This->dsound);
826 EnterCriticalSection( &(This->dsound->lock) );
828 TRACE( "(%p) was 0x%08lx\n", This, This->ref );
829 uRef = ++(This->ref);
831 LeaveCriticalSection( &(This->dsound->lock) );
837 IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
840 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
841 TRACE( "(%p)\n", This );
843 assert(This->dsound);
845 EnterCriticalSection( &(This->dsound->lock) );
847 TRACE( "(%p) was 0x%08lx\n", This, This->ref );
848 uRef = --(This->ref);
850 LeaveCriticalSection( &(This->dsound->lock) );
853 TRACE("deleting object\n");
855 HeapFree(GetProcessHeap(),0, This->pdscbd);
857 if (This->dsound->hwi) {
858 waveInReset(This->dsound->hwi);
859 waveInClose(This->dsound->hwi);
860 if (This->dsound->pwave) {
861 HeapFree(GetProcessHeap(),0, This->dsound->pwave);
862 This->dsound->pwave = 0;
864 This->dsound->hwi = 0;
867 if (This->dsound->hwbuf)
868 IDsCaptureDriverBuffer_Release(This->dsound->hwbuf);
870 /* remove from IDirectSoundCaptureImpl */
872 This->dsound->capture_buffer = NULL;
874 ERR("does not reference dsound\n");
877 IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
879 HeapFree( GetProcessHeap(), 0, This );
882 TRACE( "returning 0x%08lx\n", uRef );
886 static HRESULT WINAPI
887 IDirectSoundCaptureBufferImpl_GetCaps(
888 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
889 LPDSCBCAPS lpDSCBCaps )
891 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
892 TRACE( "(%p,%p)\n", This, lpDSCBCaps );
895 WARN("invalid parameter: This == NULL\n");
896 return DSERR_INVALIDPARAM;
899 if (lpDSCBCaps == NULL) {
900 WARN("invalid parameter: lpDSCBCaps == NULL\n");
901 return DSERR_INVALIDPARAM;
904 if (lpDSCBCaps->dwSize < sizeof(DSCBCAPS)) {
905 WARN("invalid parameter: lpDSCBCaps->dwSize = %ld < %d\n",
906 lpDSCBCaps->dwSize, sizeof(DSCBCAPS));
907 return DSERR_INVALIDPARAM;
910 if (This->dsound == NULL) {
911 WARN("invalid parameter: This->dsound == NULL\n");
912 return DSERR_INVALIDPARAM;
915 lpDSCBCaps->dwSize = sizeof(DSCBCAPS);
916 lpDSCBCaps->dwFlags = This->flags;
917 lpDSCBCaps->dwBufferBytes = This->pdscbd->dwBufferBytes;
918 lpDSCBCaps->dwReserved = 0;
920 TRACE("returning DS_OK\n");
924 static HRESULT WINAPI
925 IDirectSoundCaptureBufferImpl_GetCurrentPosition(
926 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
927 LPDWORD lpdwCapturePosition,
928 LPDWORD lpdwReadPosition )
930 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
931 TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition );
934 WARN("invalid parameter: This == NULL\n");
935 return DSERR_INVALIDPARAM;
938 if (This->dsound == NULL) {
939 WARN("invalid parameter: This->dsound == NULL\n");
940 return DSERR_INVALIDPARAM;
943 if (This->dsound->driver) {
945 hres = IDsCaptureDriverBuffer_GetPosition(This->dsound->hwbuf, lpdwCapturePosition, lpdwReadPosition );
947 WARN("IDsCaptureDriverBuffer_GetPosition failed\n");
950 } else if (This->dsound->hwi) {
951 EnterCriticalSection(&(This->dsound->lock));
952 TRACE("old This->dsound->state=%ld\n",This->dsound->state);
953 if (lpdwCapturePosition) {
955 mtime.wType = TIME_BYTES;
956 waveInGetPosition(This->dsound->hwi, &mtime, sizeof(mtime));
957 TRACE("mtime.u.cb=%ld,This->dsound->buflen=%ld\n", mtime.u.cb,
958 This->dsound->buflen);
959 mtime.u.cb = mtime.u.cb % This->dsound->buflen;
960 *lpdwCapturePosition = mtime.u.cb;
963 if (lpdwReadPosition) {
964 if (This->dsound->state == STATE_STARTING) {
965 if (lpdwCapturePosition)
966 This->dsound->read_position = *lpdwCapturePosition;
967 This->dsound->state = STATE_CAPTURING;
969 *lpdwReadPosition = This->dsound->read_position;
971 TRACE("new This->dsound->state=%ld\n",This->dsound->state);
972 LeaveCriticalSection(&(This->dsound->lock));
973 if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%ld\n",*lpdwCapturePosition);
974 if (lpdwReadPosition) TRACE("*lpdwReadPosition=%ld\n",*lpdwReadPosition);
977 return DSERR_NODRIVER;
980 TRACE("returning DS_OK\n");
984 static HRESULT WINAPI
985 IDirectSoundCaptureBufferImpl_GetFormat(
986 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
987 LPWAVEFORMATEX lpwfxFormat,
988 DWORD dwSizeAllocated,
989 LPDWORD lpdwSizeWritten )
991 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
992 TRACE( "(%p,%p,0x%08lx,%p)\n", This, lpwfxFormat, dwSizeAllocated,
996 WARN("invalid parameter: This == NULL\n");
997 return DSERR_INVALIDPARAM;
1000 if (This->dsound == NULL) {
1001 WARN("invalid parameter: This->dsound == NULL\n");
1002 return DSERR_INVALIDPARAM;
1005 /* FIXME: use real size for extended formats someday */
1006 if (dwSizeAllocated > sizeof(This->dsound->wfx))
1007 dwSizeAllocated = sizeof(This->dsound->wfx);
1008 if (lpwfxFormat) { /* NULL is valid (just want size) */
1009 memcpy(lpwfxFormat,&(This->dsound->wfx),dwSizeAllocated);
1010 if (lpdwSizeWritten)
1011 *lpdwSizeWritten = dwSizeAllocated;
1013 if (lpdwSizeWritten)
1014 *lpdwSizeWritten = sizeof(This->dsound->wfx);
1016 TRACE("invalid parameter: lpdwSizeWritten = NULL\n");
1017 return DSERR_INVALIDPARAM;
1021 TRACE("returning DS_OK\n");
1025 static HRESULT WINAPI
1026 IDirectSoundCaptureBufferImpl_GetStatus(
1027 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1028 LPDWORD lpdwStatus )
1030 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1031 TRACE( "(%p, %p), thread is %04lx\n", This, lpdwStatus, GetCurrentThreadId() );
1034 WARN("invalid parameter: This == NULL\n");
1035 return DSERR_INVALIDPARAM;
1038 if (This->dsound == NULL) {
1039 WARN("invalid parameter: This->dsound == NULL\n");
1040 return DSERR_INVALIDPARAM;
1043 if (lpdwStatus == NULL) {
1044 WARN("invalid parameter: lpdwStatus == NULL\n");
1045 return DSERR_INVALIDPARAM;
1049 EnterCriticalSection(&(This->dsound->lock));
1051 TRACE("old This->dsound->state=%ld, old lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus);
1052 if ((This->dsound->state == STATE_STARTING) ||
1053 (This->dsound->state == STATE_CAPTURING)) {
1054 *lpdwStatus |= DSCBSTATUS_CAPTURING;
1055 if (This->flags & DSCBSTART_LOOPING)
1056 *lpdwStatus |= DSCBSTATUS_LOOPING;
1058 TRACE("new This->dsound->state=%ld, new lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus);
1059 LeaveCriticalSection(&(This->dsound->lock));
1061 TRACE("status=%lx\n", *lpdwStatus);
1062 TRACE("returning DS_OK\n");
1066 static HRESULT WINAPI
1067 IDirectSoundCaptureBufferImpl_Initialize(
1068 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1069 LPDIRECTSOUNDCAPTURE lpDSC,
1070 LPCDSCBUFFERDESC lpcDSCBDesc )
1072 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1074 FIXME( "(%p,%p,%p): stub\n", This, lpDSC, lpcDSCBDesc );
1079 static HRESULT WINAPI
1080 IDirectSoundCaptureBufferImpl_Lock(
1081 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1084 LPVOID* lplpvAudioPtr1,
1085 LPDWORD lpdwAudioBytes1,
1086 LPVOID* lplpvAudioPtr2,
1087 LPDWORD lpdwAudioBytes2,
1090 HRESULT err = DS_OK;
1091 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1092 TRACE( "(%p,%08lu,%08lu,%p,%p,%p,%p,0x%08lx) at %ld\n", This, dwReadCusor,
1093 dwReadBytes, lplpvAudioPtr1, lpdwAudioBytes1, lplpvAudioPtr2,
1094 lpdwAudioBytes2, dwFlags, GetTickCount() );
1097 WARN("invalid parameter: This == NULL\n");
1098 return DSERR_INVALIDPARAM;
1101 if (This->dsound == NULL) {
1102 WARN("invalid parameter: This->dsound == NULL\n");
1103 return DSERR_INVALIDPARAM;
1106 if (lplpvAudioPtr1 == NULL) {
1107 WARN("invalid parameter: lplpvAudioPtr1 == NULL\n");
1108 return DSERR_INVALIDPARAM;
1111 if (lpdwAudioBytes1 == NULL) {
1112 WARN("invalid parameter: lpdwAudioBytes1 == NULL\n");
1113 return DSERR_INVALIDPARAM;
1116 EnterCriticalSection(&(This->dsound->lock));
1118 if (This->dsound->driver) {
1119 err = IDsCaptureDriverBuffer_Lock(This->dsound->hwbuf, lplpvAudioPtr1,
1120 lpdwAudioBytes1, lplpvAudioPtr2, lpdwAudioBytes2,
1121 dwReadCusor, dwReadBytes, dwFlags);
1123 WARN("IDsCaptureDriverBuffer_Lock failed\n");
1124 } else if (This->dsound->hwi) {
1125 *lplpvAudioPtr1 = This->dsound->buffer + dwReadCusor;
1126 if ( (dwReadCusor + dwReadBytes) > This->dsound->buflen) {
1127 *lpdwAudioBytes1 = This->dsound->buflen - dwReadCusor;
1129 *lplpvAudioPtr2 = This->dsound->buffer;
1130 if (lpdwAudioBytes2)
1131 *lpdwAudioBytes2 = dwReadBytes - *lpdwAudioBytes1;
1133 *lpdwAudioBytes1 = dwReadBytes;
1135 *lplpvAudioPtr2 = 0;
1136 if (lpdwAudioBytes2)
1137 *lpdwAudioBytes2 = 0;
1140 TRACE("invalid call\n");
1141 err = DSERR_INVALIDCALL; /* DSERR_NODRIVER ? */
1144 LeaveCriticalSection(&(This->dsound->lock));
1149 static HRESULT WINAPI
1150 IDirectSoundCaptureBufferImpl_Start(
1151 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1154 HRESULT err = DS_OK;
1155 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1156 TRACE( "(%p,0x%08lx)\n", This, dwFlags );
1159 WARN("invalid parameter: This == NULL\n");
1160 return DSERR_INVALIDPARAM;
1163 if (This->dsound == NULL) {
1164 WARN("invalid parameter: This->dsound == NULL\n");
1165 return DSERR_INVALIDPARAM;
1168 if ( (This->dsound->driver == 0) && (This->dsound->hwi == 0) ) {
1169 WARN("no driver\n");
1170 return DSERR_NODRIVER;
1173 EnterCriticalSection(&(This->dsound->lock));
1175 This->flags = dwFlags;
1176 TRACE("old This->dsound->state=%ld\n",This->dsound->state);
1177 if (This->dsound->state == STATE_STOPPED)
1178 This->dsound->state = STATE_STARTING;
1179 else if (This->dsound->state == STATE_STOPPING)
1180 This->dsound->state = STATE_CAPTURING;
1181 TRACE("new This->dsound->state=%ld\n",This->dsound->state);
1183 LeaveCriticalSection(&(This->dsound->lock));
1185 if (This->dsound->driver) {
1186 err = IDsCaptureDriverBuffer_Start(This->dsound->hwbuf, dwFlags);
1188 WARN("IDsCaptureDriverBuffer_Start failed\n");
1191 IDirectSoundCaptureImpl* ipDSC = This->dsound;
1193 if (ipDSC->buffer) {
1194 if (This->notify && This->notify->nrofnotifies) {
1197 ipDSC->nrofpwaves = This->notify->nrofnotifies;
1199 /* prepare headers */
1200 ipDSC->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->pwave,
1201 ipDSC->nrofpwaves*sizeof(WAVEHDR));
1203 for (c = 0; c < ipDSC->nrofpwaves; c++) {
1205 ipDSC->pwave[0].lpData = ipDSC->buffer;
1206 ipDSC->pwave[0].dwBufferLength =
1207 This->notify->notifies[0].dwOffset + 1;
1209 ipDSC->pwave[c].lpData = ipDSC->buffer +
1210 This->notify->notifies[c-1].dwOffset + 1;
1211 ipDSC->pwave[c].dwBufferLength =
1212 This->notify->notifies[c].dwOffset -
1213 This->notify->notifies[c-1].dwOffset;
1215 ipDSC->pwave[c].dwUser = (DWORD)ipDSC;
1216 ipDSC->pwave[c].dwFlags = 0;
1217 ipDSC->pwave[c].dwLoops = 0;
1218 err = mmErr(waveInPrepareHeader(ipDSC->hwi,
1219 &(ipDSC->pwave[c]),sizeof(WAVEHDR)));
1222 waveInUnprepareHeader(ipDSC->hwi,
1223 &(ipDSC->pwave[c]),sizeof(WAVEHDR));
1228 memset(ipDSC->buffer,
1229 (ipDSC->wfx.wBitsPerSample == 16) ? 0 : 128, ipDSC->buflen);
1231 TRACE("no notifiers specified\n");
1232 /* no notifiers specified so just create a single default header */
1233 ipDSC->nrofpwaves = 1;
1234 ipDSC->pwave = HeapReAlloc(GetProcessHeap(),0,ipDSC->pwave,sizeof(WAVEHDR));
1235 ipDSC->pwave[0].lpData = ipDSC->buffer;
1236 ipDSC->pwave[0].dwBufferLength = ipDSC->buflen;
1237 ipDSC->pwave[0].dwUser = (DWORD)ipDSC;
1238 ipDSC->pwave[0].dwFlags = 0;
1239 ipDSC->pwave[0].dwLoops = 0;
1241 err = mmErr(waveInPrepareHeader(ipDSC->hwi,
1242 &(ipDSC->pwave[0]),sizeof(WAVEHDR)));
1244 WARN("waveInPrepareHeader failed\n");
1245 waveInUnprepareHeader(ipDSC->hwi,
1246 &(ipDSC->pwave[0]),sizeof(WAVEHDR));
1252 ipDSC->read_position = 0;
1255 err = mmErr(waveInReset(ipDSC->hwi));
1257 /* add the first buffer to the queue */
1258 err = mmErr(waveInAddBuffer(ipDSC->hwi, &(ipDSC->pwave[0]), sizeof(WAVEHDR)));
1260 /* start filling the first buffer */
1261 err = mmErr(waveInStart(ipDSC->hwi));
1263 WARN("waveInAddBuffer failed\n");
1265 WARN("waveInReset failed\n");
1270 WARN("calling waveInClose because of error\n");
1271 waveInClose(This->dsound->hwi);
1272 This->dsound->hwi = 0;
1275 TRACE("returning %ld\n", err);
1279 static HRESULT WINAPI
1280 IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
1282 HRESULT err = DS_OK;
1283 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1284 TRACE( "(%p)\n", This );
1287 WARN("invalid parameter: This == NULL\n");
1288 return DSERR_INVALIDPARAM;
1291 if (This->dsound == NULL) {
1292 WARN("invalid parameter: This->dsound == NULL\n");
1293 return DSERR_INVALIDPARAM;
1296 EnterCriticalSection(&(This->dsound->lock));
1298 TRACE("old This->dsound->state=%ld\n",This->dsound->state);
1299 if (This->dsound->state == STATE_CAPTURING)
1300 This->dsound->state = STATE_STOPPING;
1301 else if (This->dsound->state == STATE_STARTING)
1302 This->dsound->state = STATE_STOPPED;
1303 TRACE("new This->dsound->state=%ld\n",This->dsound->state);
1305 LeaveCriticalSection(&(This->dsound->lock));
1307 if (This->dsound->driver) {
1308 err = IDsCaptureDriverBuffer_Stop(This->dsound->hwbuf);
1309 if (err == DSERR_BUFFERLOST) {
1310 /* Wine-only: the driver wants us to reopen the device */
1311 IDsCaptureDriverBuffer_Release(This->dsound->hwbuf);
1312 err = IDsCaptureDriver_CreateCaptureBuffer(This->dsound->driver,
1313 &(This->dsound->wfx),0,0,&(This->dsound->buflen),&(This->dsound->buffer),
1314 (LPVOID*)&(This->dsound->hwbuf));
1316 WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n");
1317 This->dsound->hwbuf = 0;
1319 } else if (err != DS_OK)
1320 WARN("IDsCaptureDriverBuffer_Stop failed\n");
1321 } else if (This->dsound->hwi) {
1322 err = waveInStop(This->dsound->hwi);
1324 WARN("no driver\n");
1325 err = DSERR_NODRIVER;
1328 TRACE( "(%p) returning 0x%08lx\n", This,err);
1332 static HRESULT WINAPI
1333 IDirectSoundCaptureBufferImpl_Unlock(
1334 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1335 LPVOID lpvAudioPtr1,
1336 DWORD dwAudioBytes1,
1337 LPVOID lpvAudioPtr2,
1338 DWORD dwAudioBytes2 )
1340 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1341 TRACE( "(%p,%p,%08lu,%p,%08lu)\n", This, lpvAudioPtr1, dwAudioBytes1,
1342 lpvAudioPtr2, dwAudioBytes2 );
1345 WARN("invalid parameter: This == NULL\n");
1346 return DSERR_INVALIDPARAM;
1349 if (lpvAudioPtr1 == NULL) {
1350 WARN("invalid parameter: lpvAudioPtr1 == NULL\n");
1351 return DSERR_INVALIDPARAM;
1354 if (This->dsound->driver) {
1356 hres = IDsCaptureDriverBuffer_Unlock(This->dsound->hwbuf, lpvAudioPtr1,
1357 dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
1359 WARN("IDsCaptureDriverBuffer_Unlock failed\n");
1361 } else if (This->dsound->hwi) {
1362 This->dsound->read_position = (This->dsound->read_position +
1363 (dwAudioBytes1 + dwAudioBytes2)) % This->dsound->buflen;
1365 WARN("invalid call\n");
1366 return DSERR_INVALIDCALL;
1372 static HRESULT WINAPI
1373 IDirectSoundCaptureBufferImpl_GetObjectInPath(
1374 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1375 REFGUID rguidObject,
1377 REFGUID rguidInterface,
1380 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1382 FIXME( "(%p,%s,%lu,%s,%p): stub\n", This, debugstr_guid(rguidObject),
1383 dwIndex, debugstr_guid(rguidInterface), ppObject );
1388 static HRESULT WINAPI
1389 IDirectSoundCaptureBufferImpl_GetFXStatus(
1390 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
1392 LPDWORD pdwFXStatus )
1394 ICOM_THIS(IDirectSoundCaptureBufferImpl,iface);
1396 FIXME( "(%p,%lu,%p): stub\n", This, dwFXCount, pdwFXStatus );
1401 static ICOM_VTABLE(IDirectSoundCaptureBuffer8) dscbvt =
1403 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1404 /* IUnknown methods */
1405 IDirectSoundCaptureBufferImpl_QueryInterface,
1406 IDirectSoundCaptureBufferImpl_AddRef,
1407 IDirectSoundCaptureBufferImpl_Release,
1409 /* IDirectSoundCaptureBuffer methods */
1410 IDirectSoundCaptureBufferImpl_GetCaps,
1411 IDirectSoundCaptureBufferImpl_GetCurrentPosition,
1412 IDirectSoundCaptureBufferImpl_GetFormat,
1413 IDirectSoundCaptureBufferImpl_GetStatus,
1414 IDirectSoundCaptureBufferImpl_Initialize,
1415 IDirectSoundCaptureBufferImpl_Lock,
1416 IDirectSoundCaptureBufferImpl_Start,
1417 IDirectSoundCaptureBufferImpl_Stop,
1418 IDirectSoundCaptureBufferImpl_Unlock,
1420 /* IDirectSoundCaptureBuffer methods */
1421 IDirectSoundCaptureBufferImpl_GetObjectInPath,
1422 IDirectSoundCaptureBufferImpl_GetFXStatus
1425 /***************************************************************************
1426 * DirectSoundFullDuplexCreate8 [DSOUND.10]
1428 * Create and initialize a DirectSoundFullDuplex interface.
1431 * pcGuidCaptureDevice [I] Address of sound capture device GUID.
1432 * pcGuidRenderDevice [I] Address of sound render device GUID.
1433 * pcDSCBufferDesc [I] Address of capture buffer description.
1434 * pcDSBufferDesc [I] Address of render buffer description.
1435 * hWnd [I] Handle to application window.
1436 * dwLevel [I] Cooperative level.
1437 * ppDSFD [O] Address where full duplex interface returned.
1438 * ppDSCBuffer8 [0] Address where capture buffer interface returned.
1439 * ppDSBuffer8 [0] Address where render buffer interface returned.
1440 * pUnkOuter [I] Must be NULL.
1444 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
1445 * DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
1448 DirectSoundFullDuplexCreate8(
1449 LPCGUID pcGuidCaptureDevice,
1450 LPCGUID pcGuidRenderDevice,
1451 LPCDSCBUFFERDESC pcDSCBufferDesc,
1452 LPCDSBUFFERDESC pcDSBufferDesc,
1455 LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
1456 LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
1457 LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
1458 LPUNKNOWN pUnkOuter)
1460 IDirectSoundFullDuplexImpl** ippDSFD=(IDirectSoundFullDuplexImpl**)ppDSFD;
1461 TRACE("(%s,%s,%p,%p,%lx,%lx,%p,%p,%p,%p)\n", debugstr_guid(pcGuidCaptureDevice),
1462 debugstr_guid(pcGuidRenderDevice), pcDSCBufferDesc, pcDSBufferDesc,
1463 (DWORD)hWnd, dwLevel, ppDSFD, ppDSCBuffer8, ppDSBuffer8, pUnkOuter);
1466 WARN("pUnkOuter != 0\n");
1467 return DSERR_NOAGGREGATION;
1470 *ippDSFD = (IDirectSoundFullDuplexImpl*)HeapAlloc(GetProcessHeap(),
1471 HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
1473 if (*ippDSFD == NULL) {
1474 WARN("out of memory\n");
1475 return DSERR_OUTOFMEMORY;
1478 ICOM_THIS(IDirectSoundFullDuplexImpl, *ippDSFD);
1481 This->lpVtbl = &dsfdvt;
1483 InitializeCriticalSection( &(This->lock) );
1485 hres = IDirectSoundFullDuplexImpl_Initialize( (LPDIRECTSOUNDFULLDUPLEX)This,
1486 pcGuidCaptureDevice, pcGuidRenderDevice,
1487 pcDSCBufferDesc, pcDSBufferDesc,
1488 hWnd, dwLevel, ppDSCBuffer8, ppDSBuffer8);
1490 WARN("IDirectSoundFullDuplexImpl_Initialize failed\n");
1494 return DSERR_GENERIC;
1497 static HRESULT WINAPI
1498 IDirectSoundFullDuplexImpl_QueryInterface(
1499 LPDIRECTSOUNDFULLDUPLEX iface,
1503 ICOM_THIS(IDirectSoundFullDuplexImpl,iface);
1504 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
1510 IDirectSoundFullDuplexImpl_AddRef( LPDIRECTSOUNDFULLDUPLEX iface )
1513 ICOM_THIS(IDirectSoundFullDuplexImpl,iface);
1515 EnterCriticalSection( &(This->lock) );
1517 TRACE( "(%p) was 0x%08lx\n", This, This->ref );
1518 uRef = ++(This->ref);
1520 LeaveCriticalSection( &(This->lock) );
1526 IDirectSoundFullDuplexImpl_Release( LPDIRECTSOUNDFULLDUPLEX iface )
1529 ICOM_THIS(IDirectSoundFullDuplexImpl,iface);
1531 EnterCriticalSection( &(This->lock) );
1533 TRACE( "(%p) was 0x%08lx\n", This, This->ref );
1534 uRef = --(This->ref);
1536 LeaveCriticalSection( &(This->lock) );
1539 TRACE("deleting object\n");
1540 DeleteCriticalSection( &(This->lock) );
1541 HeapFree( GetProcessHeap(), 0, This );
1547 static HRESULT WINAPI
1548 IDirectSoundFullDuplexImpl_Initialize(
1549 LPDIRECTSOUNDFULLDUPLEX iface,
1550 LPCGUID pCaptureGuid,
1551 LPCGUID pRendererGuid,
1552 LPCDSCBUFFERDESC lpDscBufferDesc,
1553 LPCDSBUFFERDESC lpDsBufferDesc,
1556 LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
1557 LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
1559 ICOM_THIS(IDirectSoundFullDuplexImpl,iface);
1560 IDirectSoundCaptureBufferImpl** ippdscb=(IDirectSoundCaptureBufferImpl**)lplpDirectSoundCaptureBuffer8;
1561 IDirectSoundBufferImpl** ippdsc=(IDirectSoundBufferImpl**)lplpDirectSoundBuffer8;
1563 FIXME( "(%p,%s,%s,%p,%p,%lx,%lx,%p,%p) stub!\n", This, debugstr_guid(pCaptureGuid),
1564 debugstr_guid(pRendererGuid), lpDscBufferDesc, lpDsBufferDesc, (DWORD)hWnd, dwLevel,
1570 static ICOM_VTABLE(IDirectSoundFullDuplex) dsfdvt =
1572 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1573 /* IUnknown methods */
1574 IDirectSoundFullDuplexImpl_QueryInterface,
1575 IDirectSoundFullDuplexImpl_AddRef,
1576 IDirectSoundFullDuplexImpl_Release,
1578 /* IDirectSoundFullDuplex methods */
1579 IDirectSoundFullDuplexImpl_Initialize