2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/capturebuffer.c
5 * PURPOSE: IDirectSoundCaptureBuffer8 implementation
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
13 const GUID KSINTERFACESETID_Standard
= {0x1A8766A0L
, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
14 const GUID KSMEDIUMSETID_Standard
= {0x4747B320L
, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
15 const GUID KSDATAFORMAT_TYPE_AUDIO
= {0x73647561L
, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
16 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
= {0x05589f81L
, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
17 const GUID KSPROPSETID_Connection
= {0x1D58C920L
, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
18 const GUID KSEVENTSETID_LoopedStreaming
= {0x4682B940L
, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D}};
24 IDirectSoundCaptureBuffer8Vtbl
*lpVtbl
;
31 LPWAVEFORMATEX Format
;
32 WAVEFORMATEX MixFormat
;
39 volatile LONG StopMixerThread
;
40 volatile LONG CurrentMixPosition
;
42 LPDIRECTSOUNDNOTIFY Notify
;
44 }CDirectSoundCaptureBufferImpl
, *LPCDirectSoundCaptureBufferImpl
;
52 KSAUDIO_POSITION Position
;
53 DWORD Result
, MixPosition
, BufferPosition
, BytesWritten
, BytesRead
, MixLength
, BufferLength
;
54 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)lpParameter
;
56 /* setup audio position property request */
57 Request
.Id
= KSPROPERTY_AUDIO_POSITION
;
58 Request
.Set
= KSPROPSETID_Audio
;
59 Request
.Flags
= KSPROPERTY_TYPE_GET
;
65 /* query current position */
66 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Request
, sizeof(KSPROPERTY
), (PVOID
)&Position
, sizeof(KSAUDIO_POSITION
), NULL
);
69 ASSERT(Result
== ERROR_SUCCESS
);
71 /* FIXME implement samplerate conversion */
72 ASSERT(This
->MixFormat
.nSamplesPerSec
== This
->Format
->nSamplesPerSec
);
74 /* FIXME implement bitrate conversion */
75 ASSERT(This
->MixFormat
.wBitsPerSample
== This
->Format
->wBitsPerSample
);
78 ASSERT(BufferPosition
<= This
->BufferSize
);
79 ASSERT(MixPosition
<= This
->MixBufferSize
);
81 if (BufferPosition
== This
->BufferSize
)
83 /* restart from front */
87 if (MixPosition
== This
->MixBufferSize
)
89 /* restart from front */
93 if (This
->MixFormat
.nChannels
!= This
->Format
->nChannels
)
95 if ((DWORD
)Position
.PlayOffset
>= MixPosition
)
97 /* calculate buffer position difference */
98 MixLength
= Position
.PlayOffset
- MixPosition
;
103 MixLength
= This
->MixBufferSize
- MixPosition
;
106 BufferLength
= This
->BufferSize
- BufferPosition
;
108 /* convert the format */
109 PerformChannelConversion(&This
->MixBuffer
[MixPosition
], MixLength
, &BytesRead
, This
->MixFormat
.nChannels
, This
->Format
->nChannels
, This
->Format
->wBitsPerSample
, &This
->Buffer
[BufferPosition
], BufferLength
, &BytesWritten
);
111 /* update buffer offsets */
112 MixPosition
+= BytesRead
;
113 BufferPosition
+= BytesWritten
;
114 DPRINT("MixPosition %u BufferPosition %u BytesRead %u BytesWritten %u MixLength %u BufferLength %u\n", MixPosition
, BufferPosition
, BytesRead
, BytesWritten
, MixLength
, BufferLength
);
120 DoNotifyPositionEvents(This
->Notify
, This
->CurrentMixPosition
, BufferPosition
);
124 InterlockedExchange(&This
->CurrentMixPosition
, (LONG
)BufferPosition
);
126 /* FIXME use timer */
129 }while(InterlockedCompareExchange(&This
->StopMixerThread
, 0, 0) == 0);
132 /* signal stop event */
133 SetEvent(This
->hStopEvent
);
143 IDirectSoundCaptureBufferImpl_QueryInterface(
144 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
149 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
151 /* check if requested interface is supported */
152 if (IsEqualIID(riid
, &IID_IUnknown
) ||
153 IsEqualIID(riid
, &IID_IDirectSoundCaptureBuffer
) ||
154 IsEqualIID(riid
, &IID_IDirectSoundCaptureBuffer8
))
156 *ppobj
= (LPVOID
)&This
->lpVtbl
;
157 InterlockedIncrement(&This
->ref
);
161 /* check if the interface is supported */
162 if (IsEqualIID(riid
, &IID_IDirectSoundNotify
))
166 HRESULT hr
= NewDirectSoundNotify(&This
->Notify
, This
->bLoop
, This
->bMix
, This
->hPin
, This
->BufferSize
);
170 *ppobj
= (LPVOID
)This
->Notify
;
174 /* increment reference count on existing notify object */
175 IDirectSoundNotify_AddRef(This
->Notify
);
176 *ppobj
= (LPVOID
)This
->Notify
;
180 /* interface not supported */
181 if (SUCCEEDED(StringFromIID(riid
, &pStr
)))
183 DPRINT("No Interface for class %s\n", pStr
);
186 return E_NOINTERFACE
;
191 IDirectSoundCaptureBufferImpl_AddRef(
192 LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
195 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
197 /* increment reference count */
198 ref
= InterlockedIncrement(&This
->ref
);
206 IDirectSoundCaptureBufferImpl_Release(
207 LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
210 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
212 /* release reference count */
213 ref
= InterlockedDecrement(&(This
->ref
));
219 /* close pin handle */
220 CloseHandle(This
->hPin
);
223 if (This
->hStopEvent
)
225 /* close stop event handle */
226 CloseHandle(This
->hStopEvent
);
231 /* free mix buffer */
232 HeapFree(GetProcessHeap(), 0, This
->MixBuffer
);
235 /* free capture buffer */
236 HeapFree(GetProcessHeap(), 0, This
->Buffer
);
237 /* free wave format */
238 HeapFree(GetProcessHeap(), 0, This
->Format
);
239 /* free capture buffer */
240 HeapFree(GetProcessHeap(), 0, This
);
249 IDirectSoundCaptureBufferImpl_GetCaps(
250 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
251 LPDSCBCAPS lpDSCBCaps
)
253 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
257 /* invalid parameter */
258 return DSERR_INVALIDPARAM
;
261 if (lpDSCBCaps
->dwSize
!= sizeof(DSCBCAPS
))
263 /* invalid parameter */
264 return DSERR_INVALIDPARAM
;
267 lpDSCBCaps
->dwBufferBytes
= This
->BufferSize
;
268 lpDSCBCaps
->dwReserved
= 0;
269 //lpDSCBCaps->dwFlags = DSCBCAPS_WAVEMAPPED;
276 IDirectSoundCaptureBufferImpl_GetCurrentPosition(
277 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
278 LPDWORD lpdwCapturePosition
,
279 LPDWORD lpdwReadPosition
)
281 KSAUDIO_POSITION Position
;
286 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
290 if (lpdwCapturePosition
)
291 *lpdwCapturePosition
= 0;
293 if (lpdwReadPosition
)
294 *lpdwReadPosition
= 0;
296 DPRINT("No Audio Pin\n");
302 /* read current position */
303 Value
= InterlockedCompareExchange(&This
->CurrentMixPosition
, 0, 0);
305 if (lpdwCapturePosition
)
306 *lpdwCapturePosition
= (DWORD
)Value
;
308 if (lpdwReadPosition
)
309 *lpdwReadPosition
= (DWORD
)Value
;
314 /* setup audio position property request */
315 Request
.Id
= KSPROPERTY_AUDIO_POSITION
;
316 Request
.Set
= KSPROPSETID_Audio
;
317 Request
.Flags
= KSPROPERTY_TYPE_GET
;
320 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Request
, sizeof(KSPROPERTY
), (PVOID
)&Position
, sizeof(KSAUDIO_POSITION
), NULL
);
322 if (Result
!= ERROR_SUCCESS
)
324 DPRINT("GetPosition failed with %x\n", Result
);
325 return DSERR_UNSUPPORTED
;
328 //DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset);
330 if (lpdwCapturePosition
)
331 *lpdwCapturePosition
= (DWORD
)Position
.PlayOffset
;
333 if (lpdwReadPosition
)
334 *lpdwReadPosition
= (DWORD
)Position
.WriteOffset
;
342 IDirectSoundCaptureBufferImpl_GetFormat(
343 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
344 LPWAVEFORMATEX lpwfxFormat
,
345 DWORD dwSizeAllocated
,
346 LPDWORD lpdwSizeWritten
)
349 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
351 FormatSize
= sizeof(WAVEFORMATEX
) + This
->Format
->cbSize
;
353 if (!lpwfxFormat
&& !lpdwSizeWritten
)
355 /* invalid parameter */
356 return DSERR_INVALIDPARAM
;
361 /* return required format size */
362 *lpdwSizeWritten
= FormatSize
;
367 if (dwSizeAllocated
>= FormatSize
)
370 CopyMemory(lpwfxFormat
, This
->Format
, FormatSize
);
373 *lpdwSizeWritten
= FormatSize
;
377 /* buffer too small */
379 *lpdwSizeWritten
= 0;
380 return DSERR_INVALIDPARAM
;
386 IDirectSoundCaptureBufferImpl_GetStatus(
387 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
390 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
394 /* invalid parameter */
395 return DSERR_INVALIDPARAM
;
401 /* check if pin is running */
402 if (This
->State
== KSSTATE_RUN
)
403 *lpdwStatus
|= DSCBSTATUS_CAPTURING
;
405 /* check if a looped buffer is used */
407 *lpdwStatus
|= DSCBSTATUS_LOOPING
;
415 IDirectSoundCaptureBufferImpl_Initialize(
416 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
417 LPDIRECTSOUNDCAPTURE lpDSC
,
418 LPCDSCBUFFERDESC lpcDSCBDesc
)
420 /* capture buffer is already initialized */
421 return DSERR_ALREADYINITIALIZED
;
426 IDirectSoundCaptureBufferImpl_Lock(
427 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
430 LPVOID
* ppvAudioPtr1
,
431 LPDWORD pdwAudioBytes1
,
432 LPVOID
* ppvAudioPtr2
,
433 LPDWORD pdwAudioBytes2
,
436 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
438 DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n",
439 This
, dwOffset
, dwBytes
, ppvAudioPtr1
, pdwAudioBytes1
, ppvAudioPtr2
, pdwAudioBytes2
, dwFlags
, This
->BufferSize
);
441 if (dwFlags
== DSBLOCK_ENTIREBUFFER
)
443 *ppvAudioPtr1
= (LPVOID
)This
->Buffer
;
444 *pdwAudioBytes1
= This
->BufferSize
;
446 *ppvAudioPtr2
= NULL
;
454 ASSERT(dwOffset
< This
->BufferSize
);
455 ASSERT(dwBytes
< This
->BufferSize
);
456 ASSERT(dwBytes
+ dwOffset
<= This
->BufferSize
);
458 *ppvAudioPtr1
= This
->Buffer
+ dwOffset
;
459 *pdwAudioBytes1
= dwBytes
;
461 *ppvAudioPtr2
= NULL
;
471 IDirectSoundCaptureBufferImpl_Start(
472 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
476 KSSTREAM_HEADER Header
;
477 DWORD Result
, BytesTransferred
;
478 OVERLAPPED Overlapped
;
482 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
484 DPRINT("IDirectSoundCaptureBufferImpl_Start Flags %x\n", dwFlags
);
485 ASSERT(dwFlags
== DSCBSTART_LOOPING
);
487 /* check if pin is already running */
488 if (This
->State
== KSSTATE_RUN
)
492 /* check if there is a pin instance */
494 return DSERR_GENERIC
;
497 Property
.Set
= KSPROPSETID_Connection
;
498 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
499 Property
.Flags
= KSPROPERTY_TYPE_SET
;
503 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesTransferred
);
505 ASSERT(Result
== ERROR_SUCCESS
);
507 if (Result
== ERROR_SUCCESS
)
513 /* initialize overlapped struct */
514 ZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
515 Overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
517 /* clear stream header */
518 ZeroMemory(&Header
, sizeof(KSSTREAM_HEADER
));
520 /* initialize stream header */
521 Header
.FrameExtent
= This
->BufferSize
;
523 Header
.Data
= (This
->bMix
? This
->MixBuffer
: This
->Buffer
);
524 Header
.Size
= sizeof(KSSTREAM_HEADER
);
525 Header
.PresentationTime
.Numerator
= 1;
526 Header
.PresentationTime
.Denominator
= 1;
528 Result
= DeviceIoControl(This
->hPin
, IOCTL_KS_WRITE_STREAM
, NULL
, 0, &Header
, sizeof(KSSTREAM_HEADER
), &BytesTransferred
, &Overlapped
);
530 if (Result
!= ERROR_SUCCESS
)
532 DPRINT("Failed submit buffer with %lx\n", Result
);
533 return DSERR_GENERIC
;
538 if (!This
->hStopEvent
)
540 /* create stop event */
541 This
->hStopEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
542 if (!This
->hStopEvent
)
544 DPRINT1("Failed to create event object with %x\n", GetLastError());
545 return DSERR_GENERIC
;
549 /* set state to stop false */
550 This
->StopMixerThread
= FALSE
;
552 hThread
= CreateThread(NULL
, 0, MixerThreadRoutine
, (PVOID
)This
, 0, NULL
);
555 DPRINT1("Failed to create thread with %x\n", GetLastError());
556 return DSERR_GENERIC
;
559 /* close thread handle */
560 CloseHandle(hThread
);
569 IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface
)
575 LPCDirectSoundCaptureBufferImpl This
= (LPCDirectSoundCaptureBufferImpl
)CONTAINING_RECORD(iface
, CDirectSoundCaptureBufferImpl
, lpVtbl
);
577 if (This
->State
== KSSTATE_STOP
)
579 /* stream has already been stopped */
584 return DSERR_GENERIC
;
587 Property
.Set
= KSPROPSETID_Connection
;
588 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
589 Property
.Flags
= KSPROPERTY_TYPE_SET
;
590 State
= KSSTATE_STOP
;
593 /* set pin to stop */
594 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), NULL
);
596 ASSERT(Result
== ERROR_SUCCESS
);
602 ASSERT(This
->hStopEvent
);
604 ResetEvent(This
->hStopEvent
);
605 /* signal event to stop */
606 This
->StopMixerThread
= TRUE
;
607 /* Wait for the event to stop */
608 WaitForSingleObject(This
->hStopEvent
, INFINITE
);
612 if (Result
== ERROR_SUCCESS
)
619 DPRINT("Failed to stop pin\n");
620 return DSERR_GENERIC
;
625 IDirectSoundCaptureBufferImpl_Unlock(
626 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
630 DWORD dwAudioBytes2
)
637 IDirectSoundCaptureBufferImpl_GetObjectInPath(
638 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
641 REFGUID rguidInterface
,
645 return DSERR_INVALIDPARAM
;
650 IDirectSoundCaptureBufferImpl_GetFXStatus(
651 LPDIRECTSOUNDCAPTUREBUFFER8 iface
,
653 LPDWORD pdwFXStatus
)
656 return DSERR_INVALIDPARAM
;
660 static IDirectSoundCaptureBuffer8Vtbl vt_DirectSoundCaptureBuffer8
=
662 /* IUnknown methods */
663 IDirectSoundCaptureBufferImpl_QueryInterface
,
664 IDirectSoundCaptureBufferImpl_AddRef
,
665 IDirectSoundCaptureBufferImpl_Release
,
667 /* IDirectSoundCaptureBuffer methods */
668 IDirectSoundCaptureBufferImpl_GetCaps
,
669 IDirectSoundCaptureBufferImpl_GetCurrentPosition
,
670 IDirectSoundCaptureBufferImpl_GetFormat
,
671 IDirectSoundCaptureBufferImpl_GetStatus
,
672 IDirectSoundCaptureBufferImpl_Initialize
,
673 IDirectSoundCaptureBufferImpl_Lock
,
674 IDirectSoundCaptureBufferImpl_Start
,
675 IDirectSoundCaptureBufferImpl_Stop
,
676 IDirectSoundCaptureBufferImpl_Unlock
,
678 /* IDirectSoundCaptureBuffer methods */
679 IDirectSoundCaptureBufferImpl_GetObjectInPath
,
680 IDirectSoundCaptureBufferImpl_GetFXStatus
687 NewDirectSoundCaptureBuffer(
688 LPDIRECTSOUNDCAPTUREBUFFER8
*OutBuffer
,
690 LPCDSCBUFFERDESC lpcDSBufferDesc
)
692 DWORD FormatSize
, MixBufferSize
;
693 ULONG DeviceId
= 0, PinId
;
694 DWORD Result
= ERROR_SUCCESS
;
695 WAVEFORMATEX MixFormat
;
697 LPCDirectSoundCaptureBufferImpl This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundCaptureBufferImpl
));
701 /* not enough memory */
702 return DSERR_OUTOFMEMORY
;
705 /* calculate format size */
706 FormatSize
= sizeof(WAVEFORMATEX
) + lpcDSBufferDesc
->lpwfxFormat
->cbSize
;
707 /* allocate format struct */
708 This
->Format
= HeapAlloc(GetProcessHeap(), 0, FormatSize
);
711 /* not enough memory */
712 HeapFree(GetProcessHeap(), 0, This
);
713 return DSERR_OUTOFMEMORY
;
717 ASSERT(lpcDSBufferDesc
->dwBufferBytes
);
719 /* allocate capture buffer */
720 This
->Buffer
= HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc
->dwBufferBytes
);
723 /* not enough memory */
724 HeapFree(GetProcessHeap(), 0, This
->Format
);
725 HeapFree(GetProcessHeap(), 0, This
);
726 return DSERR_OUTOFMEMORY
;
729 /* store buffer size */
730 This
->BufferSize
= lpcDSBufferDesc
->dwBufferBytes
;
731 ASSERT(lpcDSBufferDesc
->lpwfxFormat
->cbSize
== 0);
735 /* try all available recording pins on that filter */
736 PinId
= GetPinIdFromFilter(Filter
, TRUE
, DeviceId
);
738 if (PinId
== ULONG_MAX
)
741 Result
= OpenPin(Filter
->hFilter
, PinId
, lpcDSBufferDesc
->lpwfxFormat
, &This
->hPin
, TRUE
);
742 if (Result
== ERROR_SUCCESS
)
748 if (Result
!= ERROR_SUCCESS
)
750 /* failed to instantiate the capture pin with the native format
751 * try to compute a compatible format and use that
752 * we could use the mixer api for this purpose but... the kmixer isnt working very good atm
758 /* try all available recording pins on that filter */
759 PinId
= GetPinIdFromFilter(Filter
, TRUE
, DeviceId
);
760 DPRINT("PinId %u DeviceId %u\n", PinId
, DeviceId
);
762 if (PinId
== ULONG_MAX
)
765 if (CreateCompatiblePin(Filter
->hFilter
, PinId
, TRUE
, lpcDSBufferDesc
->lpwfxFormat
, &MixFormat
, &This
->hPin
))
768 CopyMemory(&This
->MixFormat
, &MixFormat
, sizeof(WAVEFORMATEX
));
778 /* FIXME should not happen */
779 DPRINT("failed to compute a compatible format\n");
780 HeapFree(GetProcessHeap(), 0, This
->MixBuffer
);
781 HeapFree(GetProcessHeap(), 0, This
->Buffer
);
782 HeapFree(GetProcessHeap(), 0, This
->Format
);
783 HeapFree(GetProcessHeap(), 0, This
);
784 return DSERR_GENERIC
;
787 MixBufferSize
= lpcDSBufferDesc
->dwBufferBytes
;
788 MixBufferSize
/= lpcDSBufferDesc
->lpwfxFormat
->nChannels
;
789 MixBufferSize
/= (lpcDSBufferDesc
->lpwfxFormat
->wBitsPerSample
/8);
791 MixBufferSize
*= This
->MixFormat
.nChannels
;
792 MixBufferSize
*= (This
->MixFormat
.wBitsPerSample
/8);
794 /* allocate buffer for mixing */
795 This
->MixBuffer
= HeapAlloc(GetProcessHeap(), 0, MixBufferSize
);
798 /* not enough memory */
799 CloseHandle(This
->hPin
);
800 HeapFree(GetProcessHeap(), 0, This
->Buffer
);
801 HeapFree(GetProcessHeap(), 0, This
->Format
);
802 HeapFree(GetProcessHeap(), 0, This
);
803 return DSERR_OUTOFMEMORY
;
805 This
->MixBufferSize
= MixBufferSize
;
806 DPRINT1("MixBufferSize %u BufferSize %u\n", MixBufferSize
, This
->BufferSize
);
809 /* initialize capture buffer */
811 This
->lpVtbl
= &vt_DirectSoundCaptureBuffer8
;
812 This
->Filter
= Filter
;
813 This
->State
= KSSTATE_STOP
;
816 RtlMoveMemory(This
->Format
, lpcDSBufferDesc
->lpwfxFormat
, FormatSize
);
818 *OutBuffer
= (LPDIRECTSOUNDCAPTUREBUFFER8
)&This
->lpVtbl
;