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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * Implement FX support.
24 * Implement both IDirectSoundCaptureBuffer and IDirectSoundCaptureBuffer8
25 * Make DirectSoundCaptureCreate and DirectSoundCaptureCreate8 behave differently
30 #define NONAMELESSSTRUCT
31 #define NONAMELESSUNION
39 #include "wine/debug.h"
42 #include "dsound_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
47 /*****************************************************************************
48 * IDirectSoundCaptureNotify implementation structure
50 struct IDirectSoundCaptureNotifyImpl
53 const IDirectSoundNotifyVtbl *lpVtbl;
55 IDirectSoundCaptureBufferImpl* dscb;
58 /*******************************************************************************
59 * IDirectSoundCaptureNotify
61 static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_QueryInterface(
62 LPDIRECTSOUNDNOTIFY iface,
66 IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
67 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
69 if (This->dscb == NULL) {
70 WARN("invalid parameter\n");
74 return IDirectSoundCaptureBuffer_QueryInterface((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb, riid, ppobj);
77 static ULONG WINAPI IDirectSoundCaptureNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface)
79 IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
80 ULONG ref = InterlockedIncrement(&(This->ref));
81 TRACE("(%p) ref was %d\n", This, ref - 1);
85 static ULONG WINAPI IDirectSoundCaptureNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface)
87 IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
88 ULONG ref = InterlockedDecrement(&(This->ref));
89 TRACE("(%p) ref was %d\n", This, ref + 1);
92 if (This->dscb->hwnotify)
93 IDsDriverNotify_Release(This->dscb->hwnotify);
94 This->dscb->notify=NULL;
95 IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb);
96 HeapFree(GetProcessHeap(),0,This);
97 TRACE("(%p) released\n", This);
102 static HRESULT WINAPI IDirectSoundCaptureNotifyImpl_SetNotificationPositions(
103 LPDIRECTSOUNDNOTIFY iface,
105 LPCDSBPOSITIONNOTIFY notify)
107 IDirectSoundCaptureNotifyImpl *This = (IDirectSoundCaptureNotifyImpl *)iface;
108 TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
110 if (howmuch > 0 && notify == NULL) {
111 WARN("invalid parameter: notify == NULL\n");
112 return DSERR_INVALIDPARAM;
115 if (TRACE_ON(dsound)) {
117 for (i=0;i<howmuch;i++)
118 TRACE("notify at %d to %p\n",
119 notify[i].dwOffset,notify[i].hEventNotify);
122 if (This->dscb->hwnotify) {
124 hres = IDsDriverNotify_SetNotificationPositions(This->dscb->hwnotify, howmuch, notify);
126 WARN("IDsDriverNotify_SetNotificationPositions failed\n");
128 } else if (howmuch > 0) {
129 /* Make an internal copy of the caller-supplied array.
130 * Replace the existing copy if one is already present. */
131 if (This->dscb->notifies)
132 This->dscb->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
133 This->dscb->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
135 This->dscb->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
136 howmuch * sizeof(DSBPOSITIONNOTIFY));
138 if (This->dscb->notifies == NULL) {
139 WARN("out of memory\n");
140 return DSERR_OUTOFMEMORY;
142 CopyMemory(This->dscb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
143 This->dscb->nrofnotifies = howmuch;
145 HeapFree(GetProcessHeap(), 0, This->dscb->notifies);
146 This->dscb->notifies = NULL;
147 This->dscb->nrofnotifies = 0;
153 static const IDirectSoundNotifyVtbl dscnvt =
155 IDirectSoundCaptureNotifyImpl_QueryInterface,
156 IDirectSoundCaptureNotifyImpl_AddRef,
157 IDirectSoundCaptureNotifyImpl_Release,
158 IDirectSoundCaptureNotifyImpl_SetNotificationPositions,
161 static HRESULT IDirectSoundCaptureNotifyImpl_Create(
162 IDirectSoundCaptureBufferImpl *dscb,
163 IDirectSoundCaptureNotifyImpl **pdscn)
165 IDirectSoundCaptureNotifyImpl * dscn;
166 TRACE("(%p,%p)\n",dscb,pdscn);
168 dscn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dscn));
171 WARN("out of memory\n");
172 return DSERR_OUTOFMEMORY;
176 dscn->lpVtbl = &dscnvt;
179 IDirectSoundCaptureBuffer_AddRef((LPDIRECTSOUNDCAPTUREBUFFER)dscb);
186 static const char * const captureStateString[] = {
194 /*******************************************************************************
195 * IDirectSoundCaptureBuffer
197 static HRESULT WINAPI
198 IDirectSoundCaptureBufferImpl_QueryInterface(
199 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
203 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
205 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
208 WARN("invalid parameter\n");
214 if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
216 hres = IDirectSoundCaptureNotifyImpl_Create(This, &This->notify);
218 IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY)This->notify);
219 if (This->device->hwbuf && !This->hwnotify) {
220 hres = IDsCaptureDriverBuffer_QueryInterface(This->device->hwbuf,
221 &IID_IDsDriverNotify, (LPVOID*)&(This->hwnotify));
223 WARN("IDsCaptureDriverBuffer_QueryInterface failed\n");
224 IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
230 *ppobj = This->notify;
234 WARN("IID_IDirectSoundNotify\n");
238 if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer, riid ) ||
239 IsEqualGUID( &IID_IDirectSoundCaptureBuffer8, riid ) ) {
240 IDirectSoundCaptureBuffer8_AddRef(iface);
245 FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
246 return E_NOINTERFACE;
250 IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
252 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
253 ULONG ref = InterlockedIncrement(&(This->ref));
254 TRACE("(%p) ref was %d\n", This, ref - 1);
259 IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
261 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
262 ULONG ref = InterlockedDecrement(&(This->ref));
263 TRACE("(%p) ref was %d\n", This, ref + 1);
266 TRACE("deleting object\n");
267 if (This->device->state == STATE_CAPTURING)
268 This->device->state = STATE_STOPPING;
270 HeapFree(GetProcessHeap(),0, This->pdscbd);
272 if (This->device->hwi) {
273 waveInReset(This->device->hwi);
274 waveInClose(This->device->hwi);
275 HeapFree(GetProcessHeap(),0, This->device->pwave);
276 This->device->pwave = 0;
277 This->device->hwi = 0;
280 if (This->device->hwbuf)
281 IDsCaptureDriverBuffer_Release(This->device->hwbuf);
283 /* remove from DirectSoundCaptureDevice */
284 This->device->capture_buffer = NULL;
287 IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY)This->notify);
289 /* If driver manages its own buffer, IDsCaptureDriverBuffer_Release
290 should have freed the buffer. Prevent freeing it again in
291 IDirectSoundCaptureBufferImpl_Create */
292 if (!(This->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY))
293 This->device->buffer = NULL;
295 HeapFree(GetProcessHeap(), 0, This->notifies);
296 HeapFree( GetProcessHeap(), 0, This );
297 TRACE("(%p) released\n", This);
302 static HRESULT WINAPI
303 IDirectSoundCaptureBufferImpl_GetCaps(
304 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
305 LPDSCBCAPS lpDSCBCaps )
307 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
308 TRACE( "(%p,%p)\n", This, lpDSCBCaps );
310 if (lpDSCBCaps == NULL) {
311 WARN("invalid parameter: lpDSCBCaps == NULL\n");
312 return DSERR_INVALIDPARAM;
315 if (lpDSCBCaps->dwSize < sizeof(DSCBCAPS)) {
316 WARN("invalid parameter: lpDSCBCaps->dwSize = %d\n", lpDSCBCaps->dwSize);
317 return DSERR_INVALIDPARAM;
320 if (This->device == NULL) {
321 WARN("invalid parameter: This->device == NULL\n");
322 return DSERR_INVALIDPARAM;
325 lpDSCBCaps->dwSize = sizeof(DSCBCAPS);
326 lpDSCBCaps->dwFlags = This->flags;
327 lpDSCBCaps->dwBufferBytes = This->pdscbd->dwBufferBytes;
328 lpDSCBCaps->dwReserved = 0;
330 TRACE("returning DS_OK\n");
334 static HRESULT WINAPI
335 IDirectSoundCaptureBufferImpl_GetCurrentPosition(
336 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
337 LPDWORD lpdwCapturePosition,
338 LPDWORD lpdwReadPosition )
340 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
341 HRESULT hres = DS_OK;
342 TRACE( "(%p,%p,%p)\n", This, lpdwCapturePosition, lpdwReadPosition );
344 if (This->device == NULL) {
345 WARN("invalid parameter: This->device == NULL\n");
346 return DSERR_INVALIDPARAM;
349 if (This->device->driver) {
350 hres = IDsCaptureDriverBuffer_GetPosition(This->device->hwbuf, lpdwCapturePosition, lpdwReadPosition );
352 WARN("IDsCaptureDriverBuffer_GetPosition failed\n");
353 } else if (This->device->hwi) {
356 EnterCriticalSection(&This->device->lock);
357 pos = (DWORD_PTR)This->device->pwave[This->device->index].lpData - (DWORD_PTR)This->device->buffer;
358 if (lpdwCapturePosition)
359 *lpdwCapturePosition = (This->device->pwave[This->device->index].dwBufferLength + pos) % This->device->buflen;
360 if (lpdwReadPosition)
361 *lpdwReadPosition = pos;
362 LeaveCriticalSection(&This->device->lock);
366 hres = DSERR_NODRIVER;
369 TRACE("cappos=%d readpos=%d\n", (lpdwCapturePosition?*lpdwCapturePosition:-1), (lpdwReadPosition?*lpdwReadPosition:-1));
370 TRACE("returning %08x\n", hres);
374 static HRESULT WINAPI
375 IDirectSoundCaptureBufferImpl_GetFormat(
376 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
377 LPWAVEFORMATEX lpwfxFormat,
378 DWORD dwSizeAllocated,
379 LPDWORD lpdwSizeWritten )
381 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
382 HRESULT hres = DS_OK;
383 TRACE( "(%p,%p,0x%08x,%p)\n", This, lpwfxFormat, dwSizeAllocated,
386 if (This->device == NULL) {
387 WARN("invalid parameter: This->device == NULL\n");
388 return DSERR_INVALIDPARAM;
391 if (dwSizeAllocated > (sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize))
392 dwSizeAllocated = sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize;
394 if (lpwfxFormat) { /* NULL is valid (just want size) */
395 CopyMemory(lpwfxFormat, This->device->pwfx, dwSizeAllocated);
397 *lpdwSizeWritten = dwSizeAllocated;
400 *lpdwSizeWritten = sizeof(WAVEFORMATEX) + This->device->pwfx->cbSize;
402 TRACE("invalid parameter: lpdwSizeWritten = NULL\n");
403 hres = DSERR_INVALIDPARAM;
407 TRACE("returning %08x\n", hres);
411 static HRESULT WINAPI
412 IDirectSoundCaptureBufferImpl_GetStatus(
413 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
416 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
417 TRACE( "(%p, %p), thread is %04x\n", This, lpdwStatus, GetCurrentThreadId() );
419 if (This->device == NULL) {
420 WARN("invalid parameter: This->device == NULL\n");
421 return DSERR_INVALIDPARAM;
424 if (lpdwStatus == NULL) {
425 WARN("invalid parameter: lpdwStatus == NULL\n");
426 return DSERR_INVALIDPARAM;
430 EnterCriticalSection(&(This->device->lock));
432 TRACE("old This->device->state=%s, old lpdwStatus=%08x\n",
433 captureStateString[This->device->state],*lpdwStatus);
434 if ((This->device->state == STATE_STARTING) ||
435 (This->device->state == STATE_CAPTURING)) {
436 *lpdwStatus |= DSCBSTATUS_CAPTURING;
437 if (This->flags & DSCBSTART_LOOPING)
438 *lpdwStatus |= DSCBSTATUS_LOOPING;
440 TRACE("new This->device->state=%s, new lpdwStatus=%08x\n",
441 captureStateString[This->device->state],*lpdwStatus);
442 LeaveCriticalSection(&(This->device->lock));
444 TRACE("status=%x\n", *lpdwStatus);
445 TRACE("returning DS_OK\n");
449 static HRESULT WINAPI
450 IDirectSoundCaptureBufferImpl_Initialize(
451 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
452 LPDIRECTSOUNDCAPTURE lpDSC,
453 LPCDSCBUFFERDESC lpcDSCBDesc )
455 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
457 FIXME( "(%p,%p,%p): stub\n", This, lpDSC, lpcDSCBDesc );
462 static HRESULT WINAPI
463 IDirectSoundCaptureBufferImpl_Lock(
464 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
467 LPVOID* lplpvAudioPtr1,
468 LPDWORD lpdwAudioBytes1,
469 LPVOID* lplpvAudioPtr2,
470 LPDWORD lpdwAudioBytes2,
473 HRESULT hres = DS_OK;
474 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
475 TRACE( "(%p,%08u,%08u,%p,%p,%p,%p,0x%08x) at %d\n", This, dwReadCusor,
476 dwReadBytes, lplpvAudioPtr1, lpdwAudioBytes1, lplpvAudioPtr2,
477 lpdwAudioBytes2, dwFlags, GetTickCount() );
479 if (This->device == NULL) {
480 WARN("invalid parameter: This->device == NULL\n");
481 return DSERR_INVALIDPARAM;
484 if (lplpvAudioPtr1 == NULL) {
485 WARN("invalid parameter: lplpvAudioPtr1 == NULL\n");
486 return DSERR_INVALIDPARAM;
489 if (lpdwAudioBytes1 == NULL) {
490 WARN("invalid parameter: lpdwAudioBytes1 == NULL\n");
491 return DSERR_INVALIDPARAM;
494 EnterCriticalSection(&(This->device->lock));
496 if (This->device->driver) {
497 hres = IDsCaptureDriverBuffer_Lock(This->device->hwbuf, lplpvAudioPtr1,
498 lpdwAudioBytes1, lplpvAudioPtr2,
499 lpdwAudioBytes2, dwReadCusor,
500 dwReadBytes, dwFlags);
502 WARN("IDsCaptureDriverBuffer_Lock failed\n");
503 } else if (This->device->hwi) {
504 *lplpvAudioPtr1 = This->device->buffer + dwReadCusor;
505 if ( (dwReadCusor + dwReadBytes) > This->device->buflen) {
506 *lpdwAudioBytes1 = This->device->buflen - dwReadCusor;
508 *lplpvAudioPtr2 = This->device->buffer;
510 *lpdwAudioBytes2 = dwReadBytes - *lpdwAudioBytes1;
512 *lpdwAudioBytes1 = dwReadBytes;
516 *lpdwAudioBytes2 = 0;
519 TRACE("invalid call\n");
520 hres = DSERR_INVALIDCALL; /* DSERR_NODRIVER ? */
523 LeaveCriticalSection(&(This->device->lock));
525 TRACE("returning %08x\n", hres);
529 static HRESULT WINAPI
530 IDirectSoundCaptureBufferImpl_Start(
531 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
534 HRESULT hres = DS_OK;
535 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
536 TRACE( "(%p,0x%08x)\n", This, dwFlags );
538 if (This->device == NULL) {
539 WARN("invalid parameter: This->device == NULL\n");
540 return DSERR_INVALIDPARAM;
543 if ( (This->device->driver == 0) && (This->device->hwi == 0) ) {
545 return DSERR_NODRIVER;
548 EnterCriticalSection(&(This->device->lock));
550 This->flags = dwFlags;
551 TRACE("old This->state=%s\n",captureStateString[This->device->state]);
552 if (This->device->state == STATE_STOPPED)
553 This->device->state = STATE_STARTING;
554 else if (This->device->state == STATE_STOPPING)
555 This->device->state = STATE_CAPTURING;
556 TRACE("new This->device->state=%s\n",captureStateString[This->device->state]);
558 LeaveCriticalSection(&(This->device->lock));
560 if (This->device->driver) {
561 hres = IDsCaptureDriverBuffer_Start(This->device->hwbuf, dwFlags);
563 WARN("IDsCaptureDriverBuffer_Start failed\n");
564 } else if (This->device->hwi) {
565 DirectSoundCaptureDevice *device = This->device;
567 if (device->buffer) {
569 DWORD blocksize = DSOUND_fraglen(device->pwfx->nSamplesPerSec, device->pwfx->nBlockAlign);
570 device->nrofpwaves = device->buflen / blocksize + !!(device->buflen % blocksize);
571 TRACE("nrofpwaves=%d\n", device->nrofpwaves);
573 /* prepare headers */
575 device->pwave = HeapReAlloc(GetProcessHeap(), 0,device->pwave, device->nrofpwaves*sizeof(WAVEHDR));
577 device->pwave = HeapAlloc(GetProcessHeap(), 0, device->nrofpwaves*sizeof(WAVEHDR));
579 for (c = 0; c < device->nrofpwaves; ++c) {
580 device->pwave[c].lpData = (char *)device->buffer + c * blocksize;
581 if (c + 1 == device->nrofpwaves)
582 device->pwave[c].dwBufferLength = device->buflen - c * blocksize;
584 device->pwave[c].dwBufferLength = blocksize;
585 device->pwave[c].dwBytesRecorded = 0;
586 device->pwave[c].dwUser = (DWORD_PTR)device;
587 device->pwave[c].dwFlags = 0;
588 device->pwave[c].dwLoops = 0;
589 hres = mmErr(waveInPrepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR)));
591 WARN("waveInPrepareHeader failed\n");
593 waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
597 hres = mmErr(waveInAddBuffer(device->hwi, &(device->pwave[c]), sizeof(WAVEHDR)));
599 WARN("waveInAddBuffer failed\n");
601 waveInUnprepareHeader(device->hwi, &(device->pwave[c]),sizeof(WAVEHDR));
606 FillMemory(device->buffer, device->buflen, (device->pwfx->wBitsPerSample == 8) ? 128 : 0);
612 /* start filling the first buffer */
613 hres = mmErr(waveInStart(device->hwi));
615 WARN("waveInStart failed\n");
619 WARN("calling waveInClose because of error\n");
620 waveInClose(device->hwi);
625 hres = DSERR_NODRIVER;
628 TRACE("returning %08x\n", hres);
632 static HRESULT WINAPI
633 IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
635 HRESULT hres = DS_OK;
636 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
637 TRACE( "(%p)\n", This );
639 if (This->device == NULL) {
640 WARN("invalid parameter: This->device == NULL\n");
641 return DSERR_INVALIDPARAM;
644 EnterCriticalSection(&(This->device->lock));
646 TRACE("old This->device->state=%s\n",captureStateString[This->device->state]);
647 if (This->device->state == STATE_CAPTURING)
648 This->device->state = STATE_STOPPING;
649 else if (This->device->state == STATE_STARTING)
650 This->device->state = STATE_STOPPED;
651 TRACE("new This->device->state=%s\n",captureStateString[This->device->state]);
653 LeaveCriticalSection(&(This->device->lock));
655 if (This->device->driver) {
656 hres = IDsCaptureDriverBuffer_Stop(This->device->hwbuf);
658 WARN("IDsCaptureDriverBuffer_Stop() failed\n");
659 } else if (This->device->hwi) {
660 hres = mmErr(waveInReset(This->device->hwi));
662 WARN("waveInReset() failed\n");
665 hres = DSERR_NODRIVER;
668 TRACE("returning %08x\n", hres);
672 static HRESULT WINAPI
673 IDirectSoundCaptureBufferImpl_Unlock(
674 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
678 DWORD dwAudioBytes2 )
680 HRESULT hres = DS_OK;
681 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
682 TRACE( "(%p,%p,%08u,%p,%08u)\n", This, lpvAudioPtr1, dwAudioBytes1,
683 lpvAudioPtr2, dwAudioBytes2 );
685 if (lpvAudioPtr1 == NULL) {
686 WARN("invalid parameter: lpvAudioPtr1 == NULL\n");
687 return DSERR_INVALIDPARAM;
690 if (This->device->driver) {
691 hres = IDsCaptureDriverBuffer_Unlock(This->device->hwbuf, lpvAudioPtr1,
692 dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
694 WARN("IDsCaptureDriverBuffer_Unlock failed\n");
695 } else if (!This->device->hwi) {
696 WARN("invalid call\n");
697 hres = DSERR_INVALIDCALL;
700 TRACE("returning %08x\n", hres);
704 static HRESULT WINAPI
705 IDirectSoundCaptureBufferImpl_GetObjectInPath(
706 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
709 REFGUID rguidInterface,
712 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
714 FIXME( "(%p,%s,%u,%s,%p): stub\n", This, debugstr_guid(rguidObject),
715 dwIndex, debugstr_guid(rguidInterface), ppObject );
720 static HRESULT WINAPI
721 IDirectSoundCaptureBufferImpl_GetFXStatus(
722 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
724 LPDWORD pdwFXStatus )
726 IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)iface;
728 FIXME( "(%p,%u,%p): stub\n", This, dwFXCount, pdwFXStatus );
733 static const IDirectSoundCaptureBuffer8Vtbl dscbvt =
735 /* IUnknown methods */
736 IDirectSoundCaptureBufferImpl_QueryInterface,
737 IDirectSoundCaptureBufferImpl_AddRef,
738 IDirectSoundCaptureBufferImpl_Release,
740 /* IDirectSoundCaptureBuffer methods */
741 IDirectSoundCaptureBufferImpl_GetCaps,
742 IDirectSoundCaptureBufferImpl_GetCurrentPosition,
743 IDirectSoundCaptureBufferImpl_GetFormat,
744 IDirectSoundCaptureBufferImpl_GetStatus,
745 IDirectSoundCaptureBufferImpl_Initialize,
746 IDirectSoundCaptureBufferImpl_Lock,
747 IDirectSoundCaptureBufferImpl_Start,
748 IDirectSoundCaptureBufferImpl_Stop,
749 IDirectSoundCaptureBufferImpl_Unlock,
751 /* IDirectSoundCaptureBuffer methods */
752 IDirectSoundCaptureBufferImpl_GetObjectInPath,
753 IDirectSoundCaptureBufferImpl_GetFXStatus
756 static void capture_CheckNotify(IDirectSoundCaptureBufferImpl *This, DWORD from, DWORD len)
759 for (i = 0; i < This->nrofnotifies; ++i) {
760 LPDSBPOSITIONNOTIFY event = This->notifies + i;
761 DWORD offset = event->dwOffset;
762 TRACE("checking %d, position %d, event = %p\n", i, offset, event->hEventNotify);
764 if (offset == DSBPN_OFFSETSTOP) {
766 SetEvent(event->hEventNotify);
767 TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
773 if (offset >= from && offset < (from + len))
775 TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
776 SetEvent(event->hEventNotify);
782 DSOUND_capture_callback(HWAVEIN hwi, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1,
785 DirectSoundCaptureDevice * This = (DirectSoundCaptureDevice*)dwUser;
786 IDirectSoundCaptureBufferImpl * Moi = This->capture_buffer;
787 TRACE("(%p,%08x(%s),%08lx,%08lx,%08lx) entering at %d\n",hwi,msg,
788 msg == MM_WIM_OPEN ? "MM_WIM_OPEN" : msg == MM_WIM_CLOSE ? "MM_WIM_CLOSE" :
789 msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount());
791 if (msg == MM_WIM_DATA) {
792 EnterCriticalSection( &(This->lock) );
793 TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n",
794 captureStateString[This->state],This->index);
795 if (This->state != STATE_STOPPED) {
796 int index = This->index;
797 if (This->state == STATE_STARTING)
798 This->state = STATE_CAPTURING;
799 capture_CheckNotify(Moi, (DWORD_PTR)This->pwave[index].lpData - (DWORD_PTR)This->buffer, This->pwave[index].dwBufferLength);
800 This->index = (This->index + 1) % This->nrofpwaves;
801 if ( (This->index == 0) && !(This->capture_buffer->flags & DSCBSTART_LOOPING) ) {
802 TRACE("end of buffer\n");
803 This->state = STATE_STOPPED;
804 capture_CheckNotify(Moi, 0, 0);
806 if (This->state == STATE_CAPTURING) {
807 waveInUnprepareHeader(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
808 waveInPrepareHeader(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
809 waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR));
810 } else if (This->state == STATE_STOPPING) {
812 This->state = STATE_STOPPED;
816 TRACE("DirectSoundCapture new This->state=%s, new This->index=%d\n",
817 captureStateString[This->state],This->index);
818 LeaveCriticalSection( &(This->lock) );
821 TRACE("completed\n");
824 static HRESULT IDirectSoundCaptureBufferImpl_Create(
825 DirectSoundCaptureDevice *device,
826 IDirectSoundCaptureBufferImpl ** ppobj,
827 LPCDSCBUFFERDESC lpcDSCBufferDesc)
830 TRACE( "(%p,%p,%p)\n", device, ppobj, lpcDSCBufferDesc);
833 WARN("invalid parameter: ppobj == NULL\n");
834 return DSERR_INVALIDPARAM;
838 WARN("not initialized\n");
840 return DSERR_UNINITIALIZED;
843 if (lpcDSCBufferDesc == NULL) {
844 WARN("invalid parameter: lpcDSCBufferDesc == NULL\n");
846 return DSERR_INVALIDPARAM;
849 if ( ((lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC)) &&
850 (lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC1))) ||
851 (lpcDSCBufferDesc->dwBufferBytes == 0) ||
852 (lpcDSCBufferDesc->lpwfxFormat == NULL) ) { /* FIXME: DSERR_BADFORMAT ? */
853 WARN("invalid lpcDSCBufferDesc\n");
855 return DSERR_INVALIDPARAM;
858 wfex = lpcDSCBufferDesc->lpwfxFormat;
860 TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
861 "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
862 wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
863 wfex->nAvgBytesPerSec, wfex->nBlockAlign,
864 wfex->wBitsPerSample, wfex->cbSize);
866 device->pwfx = DSOUND_CopyFormat(wfex);
867 if ( device->pwfx == NULL ) {
869 return DSERR_OUTOFMEMORY;
872 *ppobj = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
873 sizeof(IDirectSoundCaptureBufferImpl));
875 if ( *ppobj == NULL ) {
876 WARN("out of memory\n");
878 return DSERR_OUTOFMEMORY;
883 IDirectSoundCaptureBufferImpl *This = *ppobj;
886 This->device = device;
887 This->device->capture_buffer = This;
889 This->nrofnotifies = 0;
890 This->hwnotify = NULL;
892 This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
893 lpcDSCBufferDesc->dwSize);
895 CopyMemory(This->pdscbd, lpcDSCBufferDesc, lpcDSCBufferDesc->dwSize);
898 This->device->capture_buffer = 0;
899 HeapFree( GetProcessHeap(), 0, This );
901 return DSERR_OUTOFMEMORY;
904 This->lpVtbl = &dscbvt;
906 if (device->driver) {
907 if (This->device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
908 FIXME("DSDDESC_DOMMSYSTEMOPEN not supported\n");
910 if (This->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
911 /* allocate buffer from system memory */
912 buflen = lpcDSCBufferDesc->dwBufferBytes;
913 TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
915 newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer,buflen);
917 newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
919 if (newbuf == NULL) {
920 WARN("failed to allocate capture buffer\n");
921 err = DSERR_OUTOFMEMORY;
922 /* but the old buffer might still exist and must be re-prepared */
924 device->buffer = newbuf;
925 device->buflen = buflen;
928 /* let driver allocate memory */
929 device->buflen = lpcDSCBufferDesc->dwBufferBytes;
931 HeapFree( GetProcessHeap(), 0, device->buffer);
932 device->buffer = NULL;
935 err = IDsCaptureDriver_CreateCaptureBuffer(device->driver,
936 device->pwfx,0,0,&(device->buflen),&(device->buffer),(LPVOID*)&(device->hwbuf));
938 WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n");
939 This->device->capture_buffer = 0;
940 HeapFree( GetProcessHeap(), 0, This );
945 DWORD flags = CALLBACK_FUNCTION;
946 err = mmErr(waveInOpen(&(device->hwi),
947 device->drvdesc.dnDevNode, device->pwfx,
948 (DWORD_PTR)DSOUND_capture_callback, (DWORD_PTR)device, flags));
950 WARN("waveInOpen failed\n");
951 This->device->capture_buffer = 0;
952 HeapFree( GetProcessHeap(), 0, This );
957 buflen = lpcDSCBufferDesc->dwBufferBytes;
958 TRACE("desired buflen=%d, old buffer=%p\n", buflen, device->buffer);
960 newbuf = HeapReAlloc(GetProcessHeap(),0,device->buffer,buflen);
962 newbuf = HeapAlloc(GetProcessHeap(),0,buflen);
963 if (newbuf == NULL) {
964 WARN("failed to allocate capture buffer\n");
965 err = DSERR_OUTOFMEMORY;
966 /* but the old buffer might still exist and must be re-prepared */
968 device->buffer = newbuf;
969 device->buflen = buflen;
974 TRACE("returning DS_OK\n");
979 /*******************************************************************************
980 * DirectSoundCaptureDevice
982 DirectSoundCaptureDevice * DSOUND_capture[MAXWAVEDRIVERS];
984 static HRESULT DirectSoundCaptureDevice_Create(
985 DirectSoundCaptureDevice ** ppDevice)
987 DirectSoundCaptureDevice * device;
988 TRACE("(%p)\n", ppDevice);
990 /* Allocate memory */
991 device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectSoundCaptureDevice));
993 if (device == NULL) {
994 WARN("out of memory\n");
995 return DSERR_OUTOFMEMORY;
999 device->state = STATE_STOPPED;
1001 InitializeCriticalSection( &(device->lock) );
1002 device->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": DirectSoundCaptureDevice.lock");
1009 static ULONG DirectSoundCaptureDevice_Release(
1010 DirectSoundCaptureDevice * device)
1012 ULONG ref = InterlockedDecrement(&(device->ref));
1013 TRACE("(%p) ref was %d\n", device, ref + 1);
1016 TRACE("deleting object\n");
1017 if (device->capture_buffer)
1018 IDirectSoundCaptureBufferImpl_Release(
1019 (LPDIRECTSOUNDCAPTUREBUFFER8) device->capture_buffer);
1021 if (device->driver) {
1022 IDsCaptureDriver_Close(device->driver);
1023 IDsCaptureDriver_Release(device->driver);
1026 HeapFree(GetProcessHeap(), 0, device->pwfx);
1027 device->lock.DebugInfo->Spare[0] = 0;
1028 DeleteCriticalSection( &(device->lock) );
1029 DSOUND_capture[device->drvdesc.dnDevNode] = NULL;
1030 HeapFree(GetProcessHeap(), 0, device);
1031 TRACE("(%p) released\n", device);
1036 static HRESULT DirectSoundCaptureDevice_Initialize(
1037 DirectSoundCaptureDevice ** ppDevice,
1040 HRESULT err = DSERR_INVALIDPARAM;
1042 BOOLEAN found = FALSE;
1044 DirectSoundCaptureDevice *device = *ppDevice;
1045 TRACE("(%p, %s)\n", ppDevice, debugstr_guid(lpcGUID));
1047 /* Default device? */
1048 if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
1049 lpcGUID = &DSDEVID_DefaultCapture;
1051 if (GetDeviceID(lpcGUID, &devGUID) != DS_OK) {
1052 WARN("invalid parameter: lpcGUID\n");
1053 return DSERR_INVALIDPARAM;
1056 widn = waveInGetNumDevs();
1058 WARN("no audio devices found\n");
1059 return DSERR_NODRIVER;
1062 wid = devGUID.Data4[7];
1063 if (!memcmp(&devGUID, &DSOUND_capture_guid, sizeof(GUID)-1)
1067 if (found == FALSE) {
1068 WARN("No device found matching given ID!\n");
1069 return DSERR_NODRIVER;
1072 if (DSOUND_capture[wid]) {
1073 WARN("already in use\n");
1074 return DSERR_ALLOCATED;
1077 err = DirectSoundCaptureDevice_Create(&(device));
1079 WARN("DirectSoundCaptureDevice_Create failed\n");
1084 device->guid = devGUID;
1086 /* Disable the direct sound driver to force emulation if requested. */
1087 device->driver = NULL;
1088 if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
1090 err = mmErr(waveInMessage(UlongToHandle(wid),DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&device->driver,0));
1091 if ( (err != DS_OK) && (err != DSERR_UNSUPPORTED) ) {
1092 WARN("waveInMessage failed; err=%x\n",err);
1098 /* Get driver description */
1099 if (device->driver) {
1100 TRACE("using DirectSound driver\n");
1101 err = IDsCaptureDriver_GetDriverDesc(device->driver, &(device->drvdesc));
1103 WARN("IDsCaptureDriver_GetDriverDesc failed\n");
1107 TRACE("using WINMM\n");
1108 /* if no DirectSound interface available, use WINMM API instead */
1109 device->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN |
1110 DSDDESC_DOMMSYSTEMSETFORMAT;
1113 device->drvdesc.dnDevNode = wid;
1115 /* open the DirectSound driver if available */
1116 if (device->driver && (err == DS_OK))
1117 err = IDsCaptureDriver_Open(device->driver);
1122 /* the driver is now open, so it's now allowed to call GetCaps */
1123 if (device->driver) {
1124 device->drvcaps.dwSize = sizeof(device->drvcaps);
1125 err = IDsCaptureDriver_GetCaps(device->driver,&(device->drvcaps));
1127 WARN("IDsCaptureDriver_GetCaps failed\n");
1130 } else /*if (device->hwi)*/ {
1132 err = mmErr(waveInGetDevCapsA((UINT)device->drvdesc.dnDevNode, &wic, sizeof(wic)));
1135 device->drvcaps.dwFlags = 0;
1136 lstrcpynA(device->drvdesc.szDrvname, wic.szPname,
1137 sizeof(device->drvdesc.szDrvname));
1139 device->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
1140 device->drvcaps.dwFormats = wic.dwFormats;
1141 device->drvcaps.dwChannels = wic.wChannels;
1150 /*****************************************************************************
1151 * IDirectSoundCapture implementation structure
1153 struct IDirectSoundCaptureImpl
1155 /* IUnknown fields */
1156 const IDirectSoundCaptureVtbl *lpVtbl;
1159 DirectSoundCaptureDevice *device;
1162 /***************************************************************************
1163 * IDirectSoundCaptureImpl
1165 static HRESULT WINAPI
1166 IDirectSoundCaptureImpl_QueryInterface(
1167 LPDIRECTSOUNDCAPTURE iface,
1171 IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
1172 TRACE( "(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj );
1174 if (ppobj == NULL) {
1175 WARN("invalid parameter\n");
1176 return E_INVALIDARG;
1181 if (IsEqualIID(riid, &IID_IUnknown)) {
1182 IDirectSoundCapture_AddRef((LPDIRECTSOUNDCAPTURE)This);
1185 } else if (IsEqualIID(riid, &IID_IDirectSoundCapture)) {
1186 IDirectSoundCapture_AddRef((LPDIRECTSOUNDCAPTURE)This);
1191 WARN("unsupported riid: %s\n", debugstr_guid(riid));
1192 return E_NOINTERFACE;
1196 IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface )
1198 IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
1199 ULONG ref = InterlockedIncrement(&(This->ref));
1200 TRACE("(%p) ref was %d\n", This, ref - 1);
1205 IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface )
1207 IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
1208 ULONG ref = InterlockedDecrement(&(This->ref));
1209 TRACE("(%p) ref was %d\n", This, ref + 1);
1213 DirectSoundCaptureDevice_Release(This->device);
1215 HeapFree( GetProcessHeap(), 0, This );
1216 TRACE("(%p) released\n", This);
1221 static HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(
1222 LPDIRECTSOUNDCAPTURE iface,
1223 LPCDSCBUFFERDESC lpcDSCBufferDesc,
1224 LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
1228 IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
1230 TRACE( "(%p,%p,%p,%p)\n",iface,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
1232 if (lpcDSCBufferDesc == NULL) {
1233 WARN("invalid parameter: lpcDSCBufferDesc == NULL)\n");
1234 return DSERR_INVALIDPARAM;
1237 if (lplpDSCaptureBuffer == NULL) {
1238 WARN("invalid parameter: lplpDSCaptureBuffer == NULL\n");
1239 return DSERR_INVALIDPARAM;
1243 WARN("invalid parameter: pUnk != NULL\n");
1244 return DSERR_INVALIDPARAM;
1247 /* FIXME: We can only have one buffer so what do we do here? */
1248 if (This->device->capture_buffer) {
1249 WARN("lnvalid parameter: already has buffer\n");
1250 return DSERR_INVALIDPARAM; /* DSERR_GENERIC ? */
1253 hr = IDirectSoundCaptureBufferImpl_Create(This->device,
1254 (IDirectSoundCaptureBufferImpl **)lplpDSCaptureBuffer, lpcDSCBufferDesc);
1257 WARN("IDirectSoundCaptureBufferImpl_Create failed\n");
1262 static HRESULT WINAPI IDirectSoundCaptureImpl_GetCaps(
1263 LPDIRECTSOUNDCAPTURE iface,
1264 LPDSCCAPS lpDSCCaps )
1266 IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
1267 TRACE("(%p,%p)\n",This,lpDSCCaps);
1269 if (This->device == NULL) {
1270 WARN("not initialized\n");
1271 return DSERR_UNINITIALIZED;
1274 if (lpDSCCaps== NULL) {
1275 WARN("invalid parameter: lpDSCCaps== NULL\n");
1276 return DSERR_INVALIDPARAM;
1279 if (lpDSCCaps->dwSize < sizeof(*lpDSCCaps)) {
1280 WARN("invalid parameter: lpDSCCaps->dwSize = %d\n", lpDSCCaps->dwSize);
1281 return DSERR_INVALIDPARAM;
1284 lpDSCCaps->dwFlags = This->device->drvcaps.dwFlags;
1285 lpDSCCaps->dwFormats = This->device->drvcaps.dwFormats;
1286 lpDSCCaps->dwChannels = This->device->drvcaps.dwChannels;
1288 TRACE("(flags=0x%08x,format=0x%08x,channels=%d)\n",lpDSCCaps->dwFlags,
1289 lpDSCCaps->dwFormats, lpDSCCaps->dwChannels);
1294 static HRESULT WINAPI IDirectSoundCaptureImpl_Initialize(
1295 LPDIRECTSOUNDCAPTURE iface,
1298 IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl *)iface;
1299 TRACE("(%p,%s)\n", This, debugstr_guid(lpcGUID));
1301 if (This->device != NULL) {
1302 WARN("already initialized\n");
1303 return DSERR_ALREADYINITIALIZED;
1305 return DirectSoundCaptureDevice_Initialize(&This->device, lpcGUID);
1308 static const IDirectSoundCaptureVtbl dscvt =
1310 /* IUnknown methods */
1311 IDirectSoundCaptureImpl_QueryInterface,
1312 IDirectSoundCaptureImpl_AddRef,
1313 IDirectSoundCaptureImpl_Release,
1315 /* IDirectSoundCapture methods */
1316 IDirectSoundCaptureImpl_CreateCaptureBuffer,
1317 IDirectSoundCaptureImpl_GetCaps,
1318 IDirectSoundCaptureImpl_Initialize
1321 static HRESULT IDirectSoundCaptureImpl_Create(
1322 LPDIRECTSOUNDCAPTURE8 * ppDSC)
1324 IDirectSoundCaptureImpl *pDSC;
1325 TRACE("(%p)\n", ppDSC);
1327 /* Allocate memory */
1328 pDSC = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundCaptureImpl));
1330 WARN("out of memory\n");
1332 return DSERR_OUTOFMEMORY;
1335 pDSC->lpVtbl = &dscvt;
1337 pDSC->device = NULL;
1339 *ppDSC = (LPDIRECTSOUNDCAPTURE8)pDSC;
1344 HRESULT DSOUND_CaptureCreate(
1346 LPDIRECTSOUNDCAPTURE *ppDSC)
1348 LPDIRECTSOUNDCAPTURE pDSC;
1350 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSC);
1352 if (!IsEqualIID(riid, &IID_IUnknown) &&
1353 !IsEqualIID(riid, &IID_IDirectSoundCapture)) {
1355 return E_NOINTERFACE;
1358 /* Get dsound configuration */
1359 setup_dsound_options();
1361 hr = IDirectSoundCaptureImpl_Create(&pDSC);
1363 IDirectSoundCapture_AddRef(pDSC);
1366 WARN("IDirectSoundCaptureImpl_Create failed\n");
1373 HRESULT DSOUND_CaptureCreate8(
1375 LPDIRECTSOUNDCAPTURE8 *ppDSC8)
1377 LPDIRECTSOUNDCAPTURE8 pDSC8;
1379 TRACE("(%s, %p)\n", debugstr_guid(riid), ppDSC8);
1381 if (!IsEqualIID(riid, &IID_IUnknown) &&
1382 !IsEqualIID(riid, &IID_IDirectSoundCapture8)) {
1384 return E_NOINTERFACE;
1387 /* Get dsound configuration */
1388 setup_dsound_options();
1390 hr = IDirectSoundCaptureImpl_Create(&pDSC8);
1392 IDirectSoundCapture_AddRef(pDSC8);
1395 WARN("IDirectSoundCaptureImpl_Create failed\n");
1402 /***************************************************************************
1403 * DirectSoundCaptureCreate [DSOUND.6]
1405 * Create and initialize a DirectSoundCapture interface.
1408 * lpcGUID [I] Address of the GUID that identifies the sound capture device.
1409 * lplpDSC [O] Address of a variable to receive the interface pointer.
1410 * pUnkOuter [I] Must be NULL.
1414 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
1418 * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
1419 * or NULL for the default device or DSDEVID_DefaultCapture or
1420 * DSDEVID_DefaultVoiceCapture.
1422 * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
1424 HRESULT WINAPI DirectSoundCaptureCreate(
1426 LPDIRECTSOUNDCAPTURE *ppDSC,
1427 LPUNKNOWN pUnkOuter)
1430 LPDIRECTSOUNDCAPTURE pDSC;
1431 TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC, pUnkOuter);
1433 if (ppDSC == NULL) {
1434 WARN("invalid parameter: ppDSC == NULL\n");
1435 return DSERR_INVALIDPARAM;
1439 WARN("invalid parameter: pUnkOuter != NULL\n");
1441 return DSERR_NOAGGREGATION;
1444 hr = DSOUND_CaptureCreate(&IID_IDirectSoundCapture, &pDSC);
1446 hr = IDirectSoundCapture_Initialize(pDSC, lpcGUID);
1448 IDirectSoundCapture_Release(pDSC);
1458 /***************************************************************************
1459 * DirectSoundCaptureCreate8 [DSOUND.12]
1461 * Create and initialize a DirectSoundCapture interface.
1464 * lpcGUID [I] Address of the GUID that identifies the sound capture device.
1465 * lplpDSC [O] Address of a variable to receive the interface pointer.
1466 * pUnkOuter [I] Must be NULL.
1470 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
1474 * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
1475 * or NULL for the default device or DSDEVID_DefaultCapture or
1476 * DSDEVID_DefaultVoiceCapture.
1478 * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
1480 HRESULT WINAPI DirectSoundCaptureCreate8(
1482 LPDIRECTSOUNDCAPTURE8 *ppDSC8,
1483 LPUNKNOWN pUnkOuter)
1486 LPDIRECTSOUNDCAPTURE8 pDSC8;
1487 TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), ppDSC8, pUnkOuter);
1489 if (ppDSC8 == NULL) {
1490 WARN("invalid parameter: ppDSC8 == NULL\n");
1491 return DSERR_INVALIDPARAM;
1495 WARN("invalid parameter: pUnkOuter != NULL\n");
1497 return DSERR_NOAGGREGATION;
1500 hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &pDSC8);
1502 hr = IDirectSoundCapture_Initialize(pDSC8, lpcGUID);
1504 IDirectSoundCapture_Release(pDSC8);