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
31 #define NONAMELESSSTRUCT
32 #define NONAMELESSUNION
40 #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 This
->dscb
->notify
=NULL
;
93 IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER
)This
->dscb
);
94 HeapFree(GetProcessHeap(),0,This
);
95 TRACE("(%p) released\n", This
);
100 static HRESULT WINAPI
IDirectSoundCaptureNotifyImpl_SetNotificationPositions(
101 LPDIRECTSOUNDNOTIFY iface
,
103 LPCDSBPOSITIONNOTIFY notify
)
105 IDirectSoundCaptureNotifyImpl
*This
= (IDirectSoundCaptureNotifyImpl
*)iface
;
106 TRACE("(%p,0x%08x,%p)\n",This
,howmuch
,notify
);
108 if (howmuch
> 0 && notify
== NULL
) {
109 WARN("invalid parameter: notify == NULL\n");
110 return DSERR_INVALIDPARAM
;
113 if (TRACE_ON(dsound
)) {
115 for (i
=0;i
<howmuch
;i
++)
116 TRACE("notify at %d to %p\n",
117 notify
[i
].dwOffset
,notify
[i
].hEventNotify
);
121 /* Make an internal copy of the caller-supplied array.
122 * Replace the existing copy if one is already present. */
123 if (This
->dscb
->notifies
)
124 This
->dscb
->notifies
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
125 This
->dscb
->notifies
, howmuch
* sizeof(DSBPOSITIONNOTIFY
));
127 This
->dscb
->notifies
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
128 howmuch
* sizeof(DSBPOSITIONNOTIFY
));
130 if (This
->dscb
->notifies
== NULL
) {
131 WARN("out of memory\n");
132 return DSERR_OUTOFMEMORY
;
134 CopyMemory(This
->dscb
->notifies
, notify
, howmuch
* sizeof(DSBPOSITIONNOTIFY
));
135 This
->dscb
->nrofnotifies
= howmuch
;
137 HeapFree(GetProcessHeap(), 0, This
->dscb
->notifies
);
138 This
->dscb
->notifies
= NULL
;
139 This
->dscb
->nrofnotifies
= 0;
145 static const IDirectSoundNotifyVtbl dscnvt
=
147 IDirectSoundCaptureNotifyImpl_QueryInterface
,
148 IDirectSoundCaptureNotifyImpl_AddRef
,
149 IDirectSoundCaptureNotifyImpl_Release
,
150 IDirectSoundCaptureNotifyImpl_SetNotificationPositions
,
153 static HRESULT
IDirectSoundCaptureNotifyImpl_Create(
154 IDirectSoundCaptureBufferImpl
*dscb
,
155 IDirectSoundCaptureNotifyImpl
**pdscn
)
157 IDirectSoundCaptureNotifyImpl
* dscn
;
158 TRACE("(%p,%p)\n",dscb
,pdscn
);
160 dscn
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*dscn
));
163 WARN("out of memory\n");
164 return DSERR_OUTOFMEMORY
;
168 dscn
->lpVtbl
= &dscnvt
;
171 IDirectSoundCaptureBuffer_AddRef((LPDIRECTSOUNDCAPTUREBUFFER
)dscb
);
178 static const char * const captureStateString
[] = {
186 /*******************************************************************************
187 * IDirectSoundCaptureBuffer
189 static HRESULT WINAPI
190 IDirectSoundCaptureBufferImpl_QueryInterface(
191 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
195 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
198 TRACE( "(%p,%s,%p)\n", This
, debugstr_guid(riid
), ppobj
);
201 WARN("invalid parameter\n");
207 if ( IsEqualGUID( &IID_IDirectSoundNotify
, riid
) ) {
209 hres
= IDirectSoundCaptureNotifyImpl_Create(This
, &This
->notify
);
214 IDirectSoundNotify_AddRef((LPDIRECTSOUNDNOTIFY
)This
->notify
);
215 *ppobj
= This
->notify
;
219 if ( IsEqualGUID( &IID_IDirectSoundCaptureBuffer
, riid
) ||
220 IsEqualGUID( &IID_IDirectSoundCaptureBuffer8
, riid
) ) {
221 IDirectSoundCaptureBuffer8_AddRef(iface
);
226 FIXME("(%p,%s,%p) unsupported GUID\n", This
, debugstr_guid(riid
), ppobj
);
227 return E_NOINTERFACE
;
231 IDirectSoundCaptureBufferImpl_AddRef( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
233 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
234 ULONG ref
= InterlockedIncrement(&(This
->ref
));
235 TRACE("(%p) ref was %d\n", This
, ref
- 1);
240 IDirectSoundCaptureBufferImpl_Release( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
242 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
243 ULONG ref
= InterlockedDecrement(&(This
->ref
));
244 TRACE("(%p) ref was %d\n", This
, ref
+ 1);
247 TRACE("deleting object\n");
248 if (This
->device
->state
== STATE_CAPTURING
)
249 This
->device
->state
= STATE_STOPPING
;
251 HeapFree(GetProcessHeap(),0, This
->pdscbd
);
253 if (This
->device
->client
) {
254 IAudioClient_Release(This
->device
->client
);
255 This
->device
->client
= NULL
;
258 if (This
->device
->capture
) {
259 IAudioCaptureClient_Release(This
->device
->capture
);
260 This
->device
->capture
= NULL
;
263 /* remove from DirectSoundCaptureDevice */
264 This
->device
->capture_buffer
= NULL
;
267 IDirectSoundNotify_Release((LPDIRECTSOUNDNOTIFY
)This
->notify
);
269 HeapFree(GetProcessHeap(), 0, This
->notifies
);
270 HeapFree( GetProcessHeap(), 0, This
);
271 TRACE("(%p) released\n", This
);
276 static HRESULT WINAPI
277 IDirectSoundCaptureBufferImpl_GetCaps(
278 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
279 LPDSCBCAPS lpDSCBCaps
)
281 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
282 TRACE( "(%p,%p)\n", This
, lpDSCBCaps
);
284 if (lpDSCBCaps
== NULL
) {
285 WARN("invalid parameter: lpDSCBCaps == NULL\n");
286 return DSERR_INVALIDPARAM
;
289 if (lpDSCBCaps
->dwSize
< sizeof(DSCBCAPS
)) {
290 WARN("invalid parameter: lpDSCBCaps->dwSize = %d\n", lpDSCBCaps
->dwSize
);
291 return DSERR_INVALIDPARAM
;
294 if (This
->device
== NULL
) {
295 WARN("invalid parameter: This->device == NULL\n");
296 return DSERR_INVALIDPARAM
;
299 lpDSCBCaps
->dwSize
= sizeof(DSCBCAPS
);
300 lpDSCBCaps
->dwFlags
= This
->flags
;
301 lpDSCBCaps
->dwBufferBytes
= This
->pdscbd
->dwBufferBytes
;
302 lpDSCBCaps
->dwReserved
= 0;
304 TRACE("returning DS_OK\n");
308 static HRESULT WINAPI
309 IDirectSoundCaptureBufferImpl_GetCurrentPosition(
310 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
311 LPDWORD lpdwCapturePosition
,
312 LPDWORD lpdwReadPosition
)
314 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
315 TRACE( "(%p,%p,%p)\n", This
, lpdwCapturePosition
, lpdwReadPosition
);
317 if (This
->device
== NULL
) {
318 WARN("invalid parameter: This->device == NULL\n");
319 return DSERR_INVALIDPARAM
;
322 EnterCriticalSection(&This
->device
->lock
);
324 if (!This
->device
->client
) {
325 LeaveCriticalSection(&This
->device
->lock
);
327 return DSERR_NODRIVER
;
330 if(lpdwCapturePosition
)
331 *lpdwCapturePosition
= This
->device
->write_pos_bytes
;
334 *lpdwReadPosition
= This
->device
->write_pos_bytes
;
336 LeaveCriticalSection(&This
->device
->lock
);
338 TRACE("cappos=%d readpos=%d\n", (lpdwCapturePosition
?*lpdwCapturePosition
:-1), (lpdwReadPosition
?*lpdwReadPosition
:-1));
339 TRACE("returning DS_OK\n");
344 static HRESULT WINAPI
345 IDirectSoundCaptureBufferImpl_GetFormat(
346 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
347 LPWAVEFORMATEX lpwfxFormat
,
348 DWORD dwSizeAllocated
,
349 LPDWORD lpdwSizeWritten
)
351 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
352 HRESULT hres
= DS_OK
;
353 TRACE( "(%p,%p,0x%08x,%p)\n", This
, lpwfxFormat
, dwSizeAllocated
,
356 if (This
->device
== NULL
) {
357 WARN("invalid parameter: This->device == NULL\n");
358 return DSERR_INVALIDPARAM
;
361 if (dwSizeAllocated
> (sizeof(WAVEFORMATEX
) + This
->device
->pwfx
->cbSize
))
362 dwSizeAllocated
= sizeof(WAVEFORMATEX
) + This
->device
->pwfx
->cbSize
;
364 if (lpwfxFormat
) { /* NULL is valid (just want size) */
365 CopyMemory(lpwfxFormat
, This
->device
->pwfx
, dwSizeAllocated
);
367 *lpdwSizeWritten
= dwSizeAllocated
;
370 *lpdwSizeWritten
= sizeof(WAVEFORMATEX
) + This
->device
->pwfx
->cbSize
;
372 TRACE("invalid parameter: lpdwSizeWritten = NULL\n");
373 hres
= DSERR_INVALIDPARAM
;
377 TRACE("returning %08x\n", hres
);
381 static HRESULT WINAPI
382 IDirectSoundCaptureBufferImpl_GetStatus(
383 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
386 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
387 TRACE( "(%p, %p), thread is %04x\n", This
, lpdwStatus
, GetCurrentThreadId() );
389 if (This
->device
== NULL
) {
390 WARN("invalid parameter: This->device == NULL\n");
391 return DSERR_INVALIDPARAM
;
394 if (lpdwStatus
== NULL
) {
395 WARN("invalid parameter: lpdwStatus == NULL\n");
396 return DSERR_INVALIDPARAM
;
400 EnterCriticalSection(&(This
->device
->lock
));
402 TRACE("old This->device->state=%s, old lpdwStatus=%08x\n",
403 captureStateString
[This
->device
->state
],*lpdwStatus
);
404 if ((This
->device
->state
== STATE_STARTING
) ||
405 (This
->device
->state
== STATE_CAPTURING
)) {
406 *lpdwStatus
|= DSCBSTATUS_CAPTURING
;
407 if (This
->flags
& DSCBSTART_LOOPING
)
408 *lpdwStatus
|= DSCBSTATUS_LOOPING
;
410 TRACE("new This->device->state=%s, new lpdwStatus=%08x\n",
411 captureStateString
[This
->device
->state
],*lpdwStatus
);
412 LeaveCriticalSection(&(This
->device
->lock
));
414 TRACE("status=%x\n", *lpdwStatus
);
415 TRACE("returning DS_OK\n");
419 static HRESULT WINAPI
420 IDirectSoundCaptureBufferImpl_Initialize(
421 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
422 LPDIRECTSOUNDCAPTURE lpDSC
,
423 LPCDSCBUFFERDESC lpcDSCBDesc
)
425 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
427 FIXME( "(%p,%p,%p): stub\n", This
, lpDSC
, lpcDSCBDesc
);
432 static HRESULT WINAPI
433 IDirectSoundCaptureBufferImpl_Lock(
434 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
437 LPVOID
* lplpvAudioPtr1
,
438 LPDWORD lpdwAudioBytes1
,
439 LPVOID
* lplpvAudioPtr2
,
440 LPDWORD lpdwAudioBytes2
,
443 HRESULT hres
= DS_OK
;
444 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
445 TRACE( "(%p,%08u,%08u,%p,%p,%p,%p,0x%08x) at %d\n", This
, dwReadCusor
,
446 dwReadBytes
, lplpvAudioPtr1
, lpdwAudioBytes1
, lplpvAudioPtr2
,
447 lpdwAudioBytes2
, dwFlags
, GetTickCount() );
449 if (This
->device
== NULL
) {
450 WARN("invalid parameter: This->device == NULL\n");
451 return DSERR_INVALIDPARAM
;
454 if (lplpvAudioPtr1
== NULL
) {
455 WARN("invalid parameter: lplpvAudioPtr1 == NULL\n");
456 return DSERR_INVALIDPARAM
;
459 if (lpdwAudioBytes1
== NULL
) {
460 WARN("invalid parameter: lpdwAudioBytes1 == NULL\n");
461 return DSERR_INVALIDPARAM
;
464 EnterCriticalSection(&(This
->device
->lock
));
466 if (This
->device
->client
) {
467 *lplpvAudioPtr1
= This
->device
->buffer
+ dwReadCusor
;
468 if ( (dwReadCusor
+ dwReadBytes
) > This
->device
->buflen
) {
469 *lpdwAudioBytes1
= This
->device
->buflen
- dwReadCusor
;
471 *lplpvAudioPtr2
= This
->device
->buffer
;
473 *lpdwAudioBytes2
= dwReadBytes
- *lpdwAudioBytes1
;
475 *lpdwAudioBytes1
= dwReadBytes
;
479 *lpdwAudioBytes2
= 0;
482 TRACE("invalid call\n");
483 hres
= DSERR_INVALIDCALL
; /* DSERR_NODRIVER ? */
486 LeaveCriticalSection(&(This
->device
->lock
));
488 TRACE("returning %08x\n", hres
);
492 static HRESULT WINAPI
493 IDirectSoundCaptureBufferImpl_Start(
494 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
498 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
500 TRACE( "(%p,0x%08x)\n", This
, dwFlags
);
502 if (This
->device
== NULL
) {
503 WARN("invalid parameter: This->device == NULL\n");
504 return DSERR_INVALIDPARAM
;
507 if ( !This
->device
->client
) {
509 return DSERR_NODRIVER
;
512 EnterCriticalSection(&(This
->device
->lock
));
514 This
->flags
= dwFlags
;
515 TRACE("old This->device->state=%s\n",captureStateString
[This
->device
->state
]);
516 if (This
->device
->state
== STATE_STOPPED
)
517 This
->device
->state
= STATE_STARTING
;
518 else if (This
->device
->state
== STATE_STOPPING
)
519 This
->device
->state
= STATE_CAPTURING
;
520 TRACE("new This->device->state=%s\n",captureStateString
[This
->device
->state
]);
522 if (This
->device
->buffer
)
523 FillMemory(This
->device
->buffer
, This
->device
->buflen
, (This
->device
->pwfx
->wBitsPerSample
== 8) ? 128 : 0);
525 hres
= IAudioClient_Start(This
->device
->client
);
527 WARN("Start failed: %08x\n", hres
);
528 LeaveCriticalSection(&This
->device
->lock
);
532 LeaveCriticalSection(&This
->device
->lock
);
534 TRACE("returning DS_OK\n");
538 static HRESULT WINAPI
539 IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
542 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
543 TRACE( "(%p)\n", This
);
545 if (This
->device
== NULL
) {
546 WARN("invalid parameter: This->device == NULL\n");
547 return DSERR_INVALIDPARAM
;
550 EnterCriticalSection(&(This
->device
->lock
));
552 TRACE("old This->device->state=%s\n",captureStateString
[This
->device
->state
]);
553 if (This
->device
->state
== STATE_CAPTURING
)
554 This
->device
->state
= STATE_STOPPING
;
555 else if (This
->device
->state
== STATE_STARTING
)
556 This
->device
->state
= STATE_STOPPED
;
557 TRACE("new This->device->state=%s\n",captureStateString
[This
->device
->state
]);
559 if(This
->device
->client
){
560 hres
= IAudioClient_Stop(This
->device
->client
);
562 LeaveCriticalSection(&This
->device
->lock
);
567 LeaveCriticalSection(&(This
->device
->lock
));
569 TRACE("returning DS_OK\n");
573 static HRESULT WINAPI
574 IDirectSoundCaptureBufferImpl_Unlock(
575 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
579 DWORD dwAudioBytes2
)
581 HRESULT hres
= DS_OK
;
582 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
583 TRACE( "(%p,%p,%08u,%p,%08u)\n", This
, lpvAudioPtr1
, dwAudioBytes1
,
584 lpvAudioPtr2
, dwAudioBytes2
);
586 if (lpvAudioPtr1
== NULL
) {
587 WARN("invalid parameter: lpvAudioPtr1 == NULL\n");
588 return DSERR_INVALIDPARAM
;
591 if (!This
->device
->client
) {
592 WARN("invalid call\n");
593 hres
= DSERR_INVALIDCALL
;
596 TRACE("returning %08x\n", hres
);
600 static HRESULT WINAPI
601 IDirectSoundCaptureBufferImpl_GetObjectInPath(
602 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
605 REFGUID rguidInterface
,
608 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
610 FIXME( "(%p,%s,%u,%s,%p): stub\n", This
, debugstr_guid(rguidObject
),
611 dwIndex
, debugstr_guid(rguidInterface
), ppObject
);
616 static HRESULT WINAPI
617 IDirectSoundCaptureBufferImpl_GetFXStatus(
618 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
620 LPDWORD pdwFXStatus
)
622 IDirectSoundCaptureBufferImpl
*This
= (IDirectSoundCaptureBufferImpl
*)iface
;
624 FIXME( "(%p,%u,%p): stub\n", This
, dwFXCount
, pdwFXStatus
);
629 static const IDirectSoundCaptureBuffer8Vtbl dscbvt
=
631 /* IUnknown methods */
632 IDirectSoundCaptureBufferImpl_QueryInterface
,
633 IDirectSoundCaptureBufferImpl_AddRef
,
634 IDirectSoundCaptureBufferImpl_Release
,
636 /* IDirectSoundCaptureBuffer methods */
637 IDirectSoundCaptureBufferImpl_GetCaps
,
638 IDirectSoundCaptureBufferImpl_GetCurrentPosition
,
639 IDirectSoundCaptureBufferImpl_GetFormat
,
640 IDirectSoundCaptureBufferImpl_GetStatus
,
641 IDirectSoundCaptureBufferImpl_Initialize
,
642 IDirectSoundCaptureBufferImpl_Lock
,
643 IDirectSoundCaptureBufferImpl_Start
,
644 IDirectSoundCaptureBufferImpl_Stop
,
645 IDirectSoundCaptureBufferImpl_Unlock
,
647 /* IDirectSoundCaptureBuffer methods */
648 IDirectSoundCaptureBufferImpl_GetObjectInPath
,
649 IDirectSoundCaptureBufferImpl_GetFXStatus
652 static void capture_CheckNotify(IDirectSoundCaptureBufferImpl
*This
, DWORD from
, DWORD len
)
655 for (i
= 0; i
< This
->nrofnotifies
; ++i
) {
656 LPDSBPOSITIONNOTIFY event
= This
->notifies
+ i
;
657 DWORD offset
= event
->dwOffset
;
658 TRACE("checking %d, position %d, event = %p\n", i
, offset
, event
->hEventNotify
);
660 if (offset
== DSBPN_OFFSETSTOP
) {
662 SetEvent(event
->hEventNotify
);
663 TRACE("signalled event %p (%d)\n", event
->hEventNotify
, i
);
669 if (offset
>= from
&& offset
< (from
+ len
))
671 TRACE("signalled event %p (%d)\n", event
->hEventNotify
, i
);
672 SetEvent(event
->hEventNotify
);
677 static HRESULT
IDirectSoundCaptureBufferImpl_Create(
678 DirectSoundCaptureDevice
*device
,
679 IDirectSoundCaptureBufferImpl
** ppobj
,
680 LPCDSCBUFFERDESC lpcDSCBufferDesc
)
683 TRACE( "(%p,%p,%p)\n", device
, ppobj
, lpcDSCBufferDesc
);
686 WARN("invalid parameter: ppobj == NULL\n");
687 return DSERR_INVALIDPARAM
;
691 WARN("not initialized\n");
693 return DSERR_UNINITIALIZED
;
696 if (lpcDSCBufferDesc
== NULL
) {
697 WARN("invalid parameter: lpcDSCBufferDesc == NULL\n");
699 return DSERR_INVALIDPARAM
;
702 if ( ((lpcDSCBufferDesc
->dwSize
!= sizeof(DSCBUFFERDESC
)) &&
703 (lpcDSCBufferDesc
->dwSize
!= sizeof(DSCBUFFERDESC1
))) ||
704 (lpcDSCBufferDesc
->dwBufferBytes
== 0) ||
705 (lpcDSCBufferDesc
->lpwfxFormat
== NULL
) ) { /* FIXME: DSERR_BADFORMAT ? */
706 WARN("invalid lpcDSCBufferDesc\n");
708 return DSERR_INVALIDPARAM
;
711 wfex
= lpcDSCBufferDesc
->lpwfxFormat
;
713 TRACE("(formattag=0x%04x,chans=%d,samplerate=%d,"
714 "bytespersec=%d,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
715 wfex
->wFormatTag
, wfex
->nChannels
, wfex
->nSamplesPerSec
,
716 wfex
->nAvgBytesPerSec
, wfex
->nBlockAlign
,
717 wfex
->wBitsPerSample
, wfex
->cbSize
);
719 device
->pwfx
= DSOUND_CopyFormat(wfex
);
720 if ( device
->pwfx
== NULL
) {
722 return DSERR_OUTOFMEMORY
;
725 *ppobj
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
726 sizeof(IDirectSoundCaptureBufferImpl
));
728 if ( *ppobj
== NULL
) {
729 WARN("out of memory\n");
731 return DSERR_OUTOFMEMORY
;
736 IDirectSoundCaptureBufferImpl
*This
= *ppobj
;
739 This
->device
= device
;
740 This
->device
->capture_buffer
= This
;
742 This
->nrofnotifies
= 0;
744 This
->pdscbd
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
745 lpcDSCBufferDesc
->dwSize
);
747 CopyMemory(This
->pdscbd
, lpcDSCBufferDesc
, lpcDSCBufferDesc
->dwSize
);
750 This
->device
->capture_buffer
= 0;
751 HeapFree( GetProcessHeap(), 0, This
);
753 return DSERR_OUTOFMEMORY
;
756 This
->lpVtbl
= &dscbvt
;
758 err
= IMMDevice_Activate(device
->mmdevice
, &IID_IAudioClient
,
759 CLSCTX_INPROC_SERVER
, NULL
, (void**)&device
->client
);
761 WARN("Activate failed: %08x\n", err
);
762 HeapFree(GetProcessHeap(), 0, This
->pdscbd
);
763 This
->device
->capture_buffer
= 0;
764 HeapFree( GetProcessHeap(), 0, This
);
769 err
= IAudioClient_Initialize(device
->client
,
770 AUDCLNT_SHAREMODE_SHARED
, AUDCLNT_STREAMFLAGS_NOPERSIST
,
771 200 * 100000, 50000, device
->pwfx
, NULL
);
773 WARN("Initialize failed: %08x\n", err
);
774 IAudioClient_Release(device
->client
);
775 device
->client
= NULL
;
776 HeapFree(GetProcessHeap(), 0, This
->pdscbd
);
777 This
->device
->capture_buffer
= 0;
778 HeapFree( GetProcessHeap(), 0, This
);
783 err
= IAudioClient_GetService(device
->client
, &IID_IAudioCaptureClient
,
784 (void**)&device
->capture
);
786 WARN("GetService failed: %08x\n", err
);
787 IAudioClient_Release(device
->client
);
788 device
->client
= NULL
;
789 HeapFree(GetProcessHeap(), 0, This
->pdscbd
);
790 This
->device
->capture_buffer
= 0;
791 HeapFree( GetProcessHeap(), 0, This
);
796 buflen
= lpcDSCBufferDesc
->dwBufferBytes
;
797 TRACE("desired buflen=%d, old buffer=%p\n", buflen
, device
->buffer
);
799 newbuf
= HeapReAlloc(GetProcessHeap(),0,device
->buffer
,buflen
);
801 newbuf
= HeapAlloc(GetProcessHeap(),0,buflen
);
802 if (newbuf
== NULL
) {
803 IAudioClient_Release(device
->client
);
804 device
->client
= NULL
;
805 IAudioCaptureClient_Release(device
->capture
);
806 device
->capture
= NULL
;
807 HeapFree(GetProcessHeap(), 0, This
->pdscbd
);
808 This
->device
->capture_buffer
= 0;
809 HeapFree( GetProcessHeap(), 0, This
);
811 return DSERR_OUTOFMEMORY
;
813 device
->buffer
= newbuf
;
814 device
->buflen
= buflen
;
817 TRACE("returning DS_OK\n");
822 /*******************************************************************************
823 * DirectSoundCaptureDevice
825 static HRESULT
DirectSoundCaptureDevice_Create(
826 DirectSoundCaptureDevice
** ppDevice
)
828 DirectSoundCaptureDevice
* device
;
829 TRACE("(%p)\n", ppDevice
);
831 /* Allocate memory */
832 device
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DirectSoundCaptureDevice
));
834 if (device
== NULL
) {
835 WARN("out of memory\n");
836 return DSERR_OUTOFMEMORY
;
840 device
->state
= STATE_STOPPED
;
842 InitializeCriticalSection( &(device
->lock
) );
843 device
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": DirectSoundCaptureDevice.lock");
850 static ULONG
DirectSoundCaptureDevice_Release(
851 DirectSoundCaptureDevice
* device
)
853 ULONG ref
= InterlockedDecrement(&(device
->ref
));
854 TRACE("(%p) ref was %d\n", device
, ref
+ 1);
857 TRACE("deleting object\n");
859 timeKillEvent(device
->timerID
);
860 timeEndPeriod(DS_TIME_RES
);
862 EnterCriticalSection(&DSOUND_capturers_lock
);
863 list_remove(&device
->entry
);
864 LeaveCriticalSection(&DSOUND_capturers_lock
);
866 if (device
->capture_buffer
)
867 IDirectSoundCaptureBufferImpl_Release(
868 (LPDIRECTSOUNDCAPTUREBUFFER8
) device
->capture_buffer
);
871 IMMDevice_Release(device
->mmdevice
);
872 HeapFree(GetProcessHeap(), 0, device
->pwfx
);
873 device
->lock
.DebugInfo
->Spare
[0] = 0;
874 DeleteCriticalSection( &(device
->lock
) );
875 HeapFree(GetProcessHeap(), 0, device
);
876 TRACE("(%p) released\n", device
);
881 static void CALLBACK
DSOUND_capture_timer(UINT timerID
, UINT msg
, DWORD_PTR user
,
882 DWORD_PTR dw1
, DWORD_PTR dw2
)
884 DirectSoundCaptureDevice
*device
= (DirectSoundCaptureDevice
*)user
;
885 UINT32 packet_frames
, packet_bytes
, avail_bytes
;
893 EnterCriticalSection(&device
->lock
);
895 if(!device
->capture_buffer
|| device
->state
== STATE_STOPPED
){
896 LeaveCriticalSection(&device
->lock
);
900 if(device
->state
== STATE_STOPPING
){
901 device
->state
= STATE_STOPPED
;
902 LeaveCriticalSection(&device
->lock
);
906 if(device
->state
== STATE_STARTING
)
907 device
->state
= STATE_CAPTURING
;
909 hr
= IAudioCaptureClient_GetBuffer(device
->capture
, &buf
, &packet_frames
,
912 LeaveCriticalSection(&device
->lock
);
913 WARN("GetBuffer failed: %08x\n", hr
);
917 packet_bytes
= packet_frames
* device
->pwfx
->nBlockAlign
;
919 avail_bytes
= device
->buflen
- device
->write_pos_bytes
;
920 if(avail_bytes
> packet_bytes
)
921 avail_bytes
= packet_bytes
;
923 memcpy(device
->buffer
+ device
->write_pos_bytes
, buf
, avail_bytes
);
924 capture_CheckNotify(device
->capture_buffer
, device
->write_pos_bytes
, avail_bytes
);
926 packet_bytes
-= avail_bytes
;
927 if(packet_bytes
> 0){
928 if(device
->capture_buffer
->flags
& DSCBSTART_LOOPING
){
929 memcpy(device
->buffer
, buf
+ avail_bytes
, packet_bytes
);
930 capture_CheckNotify(device
->capture_buffer
, 0, packet_bytes
);
932 device
->state
= STATE_STOPPED
;
933 capture_CheckNotify(device
->capture_buffer
, 0, 0);
937 device
->write_pos_bytes
+= avail_bytes
+ packet_bytes
;
938 device
->write_pos_bytes
%= device
->buflen
;
940 hr
= IAudioCaptureClient_ReleaseBuffer(device
->capture
, packet_frames
);
942 LeaveCriticalSection(&device
->lock
);
943 WARN("ReleaseBuffer failed: %08x\n", hr
);
947 LeaveCriticalSection(&device
->lock
);
950 static struct _TestFormat
{
955 } formats_to_test
[] = {
956 { WAVE_FORMAT_1M08
, 11025, 8, 1 },
957 { WAVE_FORMAT_1M16
, 11025, 16, 1 },
958 { WAVE_FORMAT_1S08
, 11025, 8, 2 },
959 { WAVE_FORMAT_1S16
, 11025, 16, 2 },
960 { WAVE_FORMAT_2M08
, 22050, 8, 1 },
961 { WAVE_FORMAT_2M16
, 22050, 16, 1 },
962 { WAVE_FORMAT_2S08
, 22050, 8, 2 },
963 { WAVE_FORMAT_2S16
, 22050, 16, 2 },
964 { WAVE_FORMAT_4M08
, 44100, 8, 1 },
965 { WAVE_FORMAT_4M16
, 44100, 16, 1 },
966 { WAVE_FORMAT_4S08
, 44100, 8, 2 },
967 { WAVE_FORMAT_4S16
, 44100, 16, 2 },
968 { WAVE_FORMAT_48M08
, 48000, 8, 1 },
969 { WAVE_FORMAT_48M16
, 48000, 16, 1 },
970 { WAVE_FORMAT_48S08
, 48000, 8, 2 },
971 { WAVE_FORMAT_48S16
, 48000, 16, 2 },
972 { WAVE_FORMAT_96M08
, 96000, 8, 1 },
973 { WAVE_FORMAT_96M16
, 96000, 16, 1 },
974 { WAVE_FORMAT_96S08
, 96000, 8, 2 },
975 { WAVE_FORMAT_96S16
, 96000, 16, 2 },
979 static HRESULT
DirectSoundCaptureDevice_Initialize(
980 DirectSoundCaptureDevice
** ppDevice
,
986 struct _TestFormat
*fmt
;
987 DirectSoundCaptureDevice
*device
;
988 IAudioClient
*client
;
990 TRACE("(%p, %s)\n", ppDevice
, debugstr_guid(lpcGUID
));
992 /* Default device? */
993 if ( !lpcGUID
|| IsEqualGUID(lpcGUID
, &GUID_NULL
) )
994 lpcGUID
= &DSDEVID_DefaultCapture
;
996 if(IsEqualGUID(lpcGUID
, &DSDEVID_DefaultPlayback
) ||
997 IsEqualGUID(lpcGUID
, &DSDEVID_DefaultVoicePlayback
))
998 return DSERR_NODRIVER
;
1000 if (GetDeviceID(lpcGUID
, &devGUID
) != DS_OK
) {
1001 WARN("invalid parameter: lpcGUID\n");
1002 return DSERR_INVALIDPARAM
;
1005 hr
= get_mmdevice(eCapture
, &devGUID
, &mmdevice
);
1009 EnterCriticalSection(&DSOUND_capturers_lock
);
1011 LIST_FOR_EACH_ENTRY(device
, &DSOUND_capturers
, DirectSoundCaptureDevice
, entry
){
1012 if(IsEqualGUID(&device
->guid
, &devGUID
)){
1013 IMMDevice_Release(mmdevice
);
1014 LeaveCriticalSection(&DSOUND_capturers_lock
);
1015 return DSERR_ALLOCATED
;
1019 hr
= DirectSoundCaptureDevice_Create(&device
);
1021 WARN("DirectSoundCaptureDevice_Create failed\n");
1022 LeaveCriticalSection(&DSOUND_capturers_lock
);
1026 device
->guid
= devGUID
;
1028 device
->mmdevice
= mmdevice
;
1030 device
->drvcaps
.dwFlags
= 0;
1032 device
->drvcaps
.dwFormats
= 0;
1033 device
->drvcaps
.dwChannels
= 0;
1034 hr
= IMMDevice_Activate(mmdevice
, &IID_IAudioClient
,
1035 CLSCTX_INPROC_SERVER
, NULL
, (void**)&client
);
1037 DeleteCriticalSection(&device
->lock
);
1038 HeapFree(GetProcessHeap(), 0, device
);
1039 LeaveCriticalSection(&DSOUND_capturers_lock
);
1040 return DSERR_NODRIVER
;
1043 for(fmt
= formats_to_test
; fmt
->flag
; ++fmt
){
1044 if(DSOUND_check_supported(client
, fmt
->rate
, fmt
->depth
, fmt
->channels
)){
1045 device
->drvcaps
.dwFormats
|= fmt
->flag
;
1046 if(fmt
->channels
> device
->drvcaps
.dwChannels
)
1047 device
->drvcaps
.dwChannels
= fmt
->channels
;
1050 IAudioClient_Release(client
);
1052 device
->timerID
= DSOUND_create_timer(DSOUND_capture_timer
, (DWORD_PTR
)device
);
1054 list_add_tail(&DSOUND_capturers
, &device
->entry
);
1058 LeaveCriticalSection(&DSOUND_capturers_lock
);
1064 /*****************************************************************************
1065 * IDirectSoundCapture implementation structure
1067 struct IDirectSoundCaptureImpl
1069 IDirectSoundCapture IDirectSoundCapture_iface
;
1071 DirectSoundCaptureDevice
*device
;
1074 static inline struct IDirectSoundCaptureImpl
*impl_from_IDirectSoundCapture(IDirectSoundCapture
*iface
)
1076 return CONTAINING_RECORD(iface
, struct IDirectSoundCaptureImpl
, IDirectSoundCapture_iface
);
1079 /***************************************************************************
1080 * IDirectSoundCaptureImpl
1082 static HRESULT WINAPI
IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture
*iface
,
1083 REFIID riid
, void **ppobj
)
1085 TRACE( "(%p,%s,%p)\n", iface
, debugstr_guid(riid
), ppobj
);
1087 if (ppobj
== NULL
) {
1088 WARN("invalid parameter\n");
1089 return E_INVALIDARG
;
1094 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDirectSoundCapture
)) {
1095 IDirectSoundCapture_AddRef(iface
);
1100 WARN("unsupported riid: %s\n", debugstr_guid(riid
));
1101 return E_NOINTERFACE
;
1104 static ULONG WINAPI
IDirectSoundCaptureImpl_AddRef(IDirectSoundCapture
*iface
)
1106 IDirectSoundCaptureImpl
*This
= impl_from_IDirectSoundCapture(iface
);
1107 ULONG ref
= InterlockedIncrement(&(This
->ref
));
1109 TRACE("(%p) ref was %d\n", This
, ref
- 1);
1113 static ULONG WINAPI
IDirectSoundCaptureImpl_Release(IDirectSoundCapture
*iface
)
1115 IDirectSoundCaptureImpl
*This
= impl_from_IDirectSoundCapture(iface
);
1116 ULONG ref
= InterlockedDecrement(&(This
->ref
));
1118 TRACE("(%p) ref was %d\n", This
, ref
+ 1);
1122 DirectSoundCaptureDevice_Release(This
->device
);
1124 HeapFree( GetProcessHeap(), 0, This
);
1125 TRACE("(%p) released\n", This
);
1130 static HRESULT WINAPI
IDirectSoundCaptureImpl_CreateCaptureBuffer(IDirectSoundCapture
*iface
,
1131 LPCDSCBUFFERDESC lpcDSCBufferDesc
, IDirectSoundCaptureBuffer
**lplpDSCaptureBuffer
,
1134 IDirectSoundCaptureImpl
*This
= impl_from_IDirectSoundCapture(iface
);
1137 TRACE( "(%p,%p,%p,%p)\n",iface
,lpcDSCBufferDesc
,lplpDSCaptureBuffer
,pUnk
);
1139 if (lpcDSCBufferDesc
== NULL
) {
1140 WARN("invalid parameter: lpcDSCBufferDesc == NULL)\n");
1141 return DSERR_INVALIDPARAM
;
1144 if (lplpDSCaptureBuffer
== NULL
) {
1145 WARN("invalid parameter: lplpDSCaptureBuffer == NULL\n");
1146 return DSERR_INVALIDPARAM
;
1150 WARN("invalid parameter: pUnk != NULL\n");
1151 return DSERR_INVALIDPARAM
;
1154 /* FIXME: We can only have one buffer so what do we do here? */
1155 if (This
->device
->capture_buffer
) {
1156 WARN("invalid parameter: already has buffer\n");
1157 return DSERR_INVALIDPARAM
; /* DSERR_GENERIC ? */
1160 hr
= IDirectSoundCaptureBufferImpl_Create(This
->device
,
1161 (IDirectSoundCaptureBufferImpl
**)lplpDSCaptureBuffer
, lpcDSCBufferDesc
);
1164 WARN("IDirectSoundCaptureBufferImpl_Create failed\n");
1169 static HRESULT WINAPI
IDirectSoundCaptureImpl_GetCaps(IDirectSoundCapture
*iface
,
1170 LPDSCCAPS lpDSCCaps
)
1172 IDirectSoundCaptureImpl
*This
= impl_from_IDirectSoundCapture(iface
);
1174 TRACE("(%p,%p)\n",This
,lpDSCCaps
);
1176 if (This
->device
== NULL
) {
1177 WARN("not initialized\n");
1178 return DSERR_UNINITIALIZED
;
1181 if (lpDSCCaps
== NULL
) {
1182 WARN("invalid parameter: lpDSCCaps== NULL\n");
1183 return DSERR_INVALIDPARAM
;
1186 if (lpDSCCaps
->dwSize
< sizeof(*lpDSCCaps
)) {
1187 WARN("invalid parameter: lpDSCCaps->dwSize = %d\n", lpDSCCaps
->dwSize
);
1188 return DSERR_INVALIDPARAM
;
1191 lpDSCCaps
->dwFlags
= This
->device
->drvcaps
.dwFlags
;
1192 lpDSCCaps
->dwFormats
= This
->device
->drvcaps
.dwFormats
;
1193 lpDSCCaps
->dwChannels
= This
->device
->drvcaps
.dwChannels
;
1195 TRACE("(flags=0x%08x,format=0x%08x,channels=%d)\n",lpDSCCaps
->dwFlags
,
1196 lpDSCCaps
->dwFormats
, lpDSCCaps
->dwChannels
);
1201 static HRESULT WINAPI
IDirectSoundCaptureImpl_Initialize(IDirectSoundCapture
*iface
,
1204 IDirectSoundCaptureImpl
*This
= impl_from_IDirectSoundCapture(iface
);
1206 TRACE("(%p,%s)\n", This
, debugstr_guid(lpcGUID
));
1208 if (This
->device
!= NULL
) {
1209 WARN("already initialized\n");
1210 return DSERR_ALREADYINITIALIZED
;
1212 return DirectSoundCaptureDevice_Initialize(&This
->device
, lpcGUID
);
1215 static const IDirectSoundCaptureVtbl dscvt
=
1217 /* IUnknown methods */
1218 IDirectSoundCaptureImpl_QueryInterface
,
1219 IDirectSoundCaptureImpl_AddRef
,
1220 IDirectSoundCaptureImpl_Release
,
1222 /* IDirectSoundCapture methods */
1223 IDirectSoundCaptureImpl_CreateCaptureBuffer
,
1224 IDirectSoundCaptureImpl_GetCaps
,
1225 IDirectSoundCaptureImpl_Initialize
1228 static HRESULT
IDirectSoundCaptureImpl_Create(
1229 LPDIRECTSOUNDCAPTURE8
* ppDSC
)
1231 IDirectSoundCaptureImpl
*pDSC
;
1232 TRACE("(%p)\n", ppDSC
);
1234 /* Allocate memory */
1235 pDSC
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectSoundCaptureImpl
));
1237 WARN("out of memory\n");
1239 return DSERR_OUTOFMEMORY
;
1242 pDSC
->IDirectSoundCapture_iface
.lpVtbl
= &dscvt
;
1244 pDSC
->device
= NULL
;
1246 *ppDSC
= (LPDIRECTSOUNDCAPTURE8
)pDSC
;
1251 HRESULT
DSOUND_CaptureCreate(REFIID riid
, IDirectSoundCapture
**ppDSC
)
1253 IDirectSoundCapture
*pDSC
;
1255 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppDSC
);
1257 if (!IsEqualIID(riid
, &IID_IUnknown
) &&
1258 !IsEqualIID(riid
, &IID_IDirectSoundCapture
)) {
1260 return E_NOINTERFACE
;
1263 /* Get dsound configuration */
1264 setup_dsound_options();
1266 hr
= IDirectSoundCaptureImpl_Create(&pDSC
);
1268 IDirectSoundCapture_AddRef(pDSC
);
1271 WARN("IDirectSoundCaptureImpl_Create failed\n");
1278 HRESULT
DSOUND_CaptureCreate8(
1280 LPDIRECTSOUNDCAPTURE8
*ppDSC8
)
1282 LPDIRECTSOUNDCAPTURE8 pDSC8
;
1284 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppDSC8
);
1286 if (!IsEqualIID(riid
, &IID_IUnknown
) &&
1287 !IsEqualIID(riid
, &IID_IDirectSoundCapture8
)) {
1289 return E_NOINTERFACE
;
1292 /* Get dsound configuration */
1293 setup_dsound_options();
1295 hr
= IDirectSoundCaptureImpl_Create(&pDSC8
);
1297 IDirectSoundCapture_AddRef(pDSC8
);
1300 WARN("IDirectSoundCaptureImpl_Create failed\n");
1307 /***************************************************************************
1308 * DirectSoundCaptureCreate [DSOUND.6]
1310 * Create and initialize a DirectSoundCapture interface.
1313 * lpcGUID [I] Address of the GUID that identifies the sound capture device.
1314 * lplpDSC [O] Address of a variable to receive the interface pointer.
1315 * pUnkOuter [I] Must be NULL.
1319 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
1323 * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
1324 * or NULL for the default device or DSDEVID_DefaultCapture or
1325 * DSDEVID_DefaultVoiceCapture.
1327 * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
1329 HRESULT WINAPI
DirectSoundCaptureCreate(LPCGUID lpcGUID
, IDirectSoundCapture
**ppDSC
,
1330 IUnknown
*pUnkOuter
)
1333 IDirectSoundCapture
*pDSC
;
1335 TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID
), ppDSC
, pUnkOuter
);
1337 if (ppDSC
== NULL
) {
1338 WARN("invalid parameter: ppDSC == NULL\n");
1339 return DSERR_INVALIDPARAM
;
1343 WARN("invalid parameter: pUnkOuter != NULL\n");
1345 return DSERR_NOAGGREGATION
;
1348 hr
= DSOUND_CaptureCreate(&IID_IDirectSoundCapture
, &pDSC
);
1350 hr
= IDirectSoundCapture_Initialize(pDSC
, lpcGUID
);
1352 IDirectSoundCapture_Release(pDSC
);
1362 /***************************************************************************
1363 * DirectSoundCaptureCreate8 [DSOUND.12]
1365 * Create and initialize a DirectSoundCapture interface.
1368 * lpcGUID [I] Address of the GUID that identifies the sound capture device.
1369 * lplpDSC [O] Address of a variable to receive the interface pointer.
1370 * pUnkOuter [I] Must be NULL.
1374 * Failure: DSERR_NOAGGREGATION, DSERR_ALLOCATED, DSERR_INVALIDPARAM,
1378 * lpcGUID must be one of the values returned from DirectSoundCaptureEnumerate
1379 * or NULL for the default device or DSDEVID_DefaultCapture or
1380 * DSDEVID_DefaultVoiceCapture.
1382 * DSERR_ALLOCATED is returned for sound devices that do not support full duplex.
1384 HRESULT WINAPI
DirectSoundCaptureCreate8(
1386 LPDIRECTSOUNDCAPTURE8
*ppDSC8
,
1387 LPUNKNOWN pUnkOuter
)
1390 LPDIRECTSOUNDCAPTURE8 pDSC8
;
1391 TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID
), ppDSC8
, pUnkOuter
);
1393 if (ppDSC8
== NULL
) {
1394 WARN("invalid parameter: ppDSC8 == NULL\n");
1395 return DSERR_INVALIDPARAM
;
1399 WARN("invalid parameter: pUnkOuter != NULL\n");
1401 return DSERR_NOAGGREGATION
;
1404 hr
= DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8
, &pDSC8
);
1406 hr
= IDirectSoundCapture_Initialize(pDSC8
, lpcGUID
);
1408 IDirectSoundCapture_Release(pDSC8
);