2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/primary.c
5 * PURPOSE: Primary IDirectSoundBuffer8 implementation
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
15 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
26 CRITICAL_SECTION Lock
;
28 }CDirectSoundBuffer
, *LPCDirectSoundBuffer
;
32 PrimaryDirectSoundBuffer8Impl_fnQueryInterface(
33 LPDIRECTSOUNDBUFFER8 iface
,
38 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
40 if (IsEqualIID(riid
, &IID_IUnknown
) ||
41 IsEqualIID(riid
, &IID_IDirectSoundBuffer
) ||
42 IsEqualIID(riid
, &IID_IDirectSoundBuffer8
))
44 *ppobj
= (LPVOID
)&This
->lpVtbl
;
45 InterlockedIncrement(&This
->ref
);
49 if (SUCCEEDED(StringFromIID(riid
, &pStr
)))
51 DPRINT("No Interface for class %s\n", pStr
);
59 PrimaryDirectSoundBuffer8Impl_fnAddRef(
60 LPDIRECTSOUNDBUFFER8 iface
)
63 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
65 ref
= InterlockedIncrement(&This
->ref
);
73 PrimaryDirectSoundBuffer8Impl_fnRelease(
74 LPDIRECTSOUNDBUFFER8 iface
)
77 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
79 ref
= InterlockedDecrement(&(This
->ref
));
85 /* close pin handle */
86 CloseHandle(This
->hPin
);
88 /* free primary buffer */
89 HeapFree(GetProcessHeap(), 0, This
);
97 PrimaryDirectSoundBuffer8Impl_fnGetCaps(
98 LPDIRECTSOUNDBUFFER8 iface
,
99 LPDSBCAPS pDSBufferCaps
)
101 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
103 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetCaps\n");
107 /* invalid parameter */
108 return DSERR_INVALIDPARAM
;
111 if (pDSBufferCaps
->dwSize
< sizeof(DSBCAPS
))
113 /* invalid buffer size */
114 return DSERR_INVALIDPARAM
;
117 /* get buffer details */
118 pDSBufferCaps
->dwUnlockTransferRate
= 0;
119 pDSBufferCaps
->dwPlayCpuOverhead
= 0;
120 pDSBufferCaps
->dwSize
= 0; //FIXME
121 pDSBufferCaps
->dwFlags
= This
->dwFlags
;
128 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
129 LPDIRECTSOUNDBUFFER8 iface
,
130 LPDWORD pdwCurrentPlayCursor
,
131 LPDWORD pdwCurrentWriteCursor
)
133 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
135 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition\n");
137 if (This
->dwLevel
< DSSCL_PRIORITY
)
139 /* needs priority level */
140 return DSERR_PRIOLEVELNEEDED
;
143 if (!pdwCurrentPlayCursor
&& !pdwCurrentWriteCursor
)
145 /* all parameters are null */
146 return DSERR_INVALIDPARAM
;
150 return DSERR_INVALIDPARAM
;
155 PrimaryDirectSoundBuffer8Impl_fnGetFormat(
156 LPDIRECTSOUNDBUFFER8 iface
,
157 LPWAVEFORMATEX pwfxFormat
,
158 DWORD dwSizeAllocated
,
159 LPDWORD pdwSizeWritten
)
162 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
164 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetFormat\n");
166 FormatSize
= sizeof(WAVEFORMATEX
) + This
->Format
.cbSize
;
168 if (!pwfxFormat
&& !pdwSizeWritten
)
170 /* invalid parameter */
171 return DSERR_INVALIDPARAM
;
176 /* return required format size */
177 *pdwSizeWritten
= FormatSize
;
182 if (dwSizeAllocated
>= FormatSize
)
185 CopyMemory(pwfxFormat
, &This
->Format
, FormatSize
);
188 *pdwSizeWritten
= FormatSize
;
192 /* buffer too small */
196 return DSERR_INVALIDPARAM
;
202 PrimaryDirectSoundBuffer8Impl_fnGetVolume(
203 LPDIRECTSOUNDBUFFER8 iface
,
206 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
208 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetVolume\n");
212 /* invalid parameter */
213 return DSERR_INVALIDPARAM
;
217 *plVolume
= This
->Volume
;
224 PrimaryDirectSoundBuffer8Impl_fnGetPan(
225 LPDIRECTSOUNDBUFFER8 iface
,
228 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
230 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetPan\n");
234 /* invalid parameter */
235 return DSERR_INVALIDPARAM
;
239 *plPan
= This
->VolumePan
;
246 PrimaryDirectSoundBuffer8Impl_fnGetFrequency(
247 LPDIRECTSOUNDBUFFER8 iface
,
248 LPDWORD pdwFrequency
)
250 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
252 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetFrequency\n");
256 /* invalid parameter */
257 return DSERR_INVALIDPARAM
;
261 *pdwFrequency
= This
->dwFrequency
;
268 PrimaryDirectSoundBuffer8Impl_fnGetStatus(
269 LPDIRECTSOUNDBUFFER8 iface
,
272 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
274 DPRINT("PrimaryDirectSoundBuffer8Impl_fnGetStatus\n");
278 /* invalid parameter */
279 return DSERR_INVALIDPARAM
;
283 if (This
->State
== KSSTATE_RUN
|| This
->State
== KSSTATE_ACQUIRE
)
285 /* buffer is playing */
286 *pdwStatus
|= DSBSTATUS_PLAYING
| DSBSTATUS_LOOPING
;
294 PrimaryDirectSoundBuffer8Impl_fnInitialize(
295 LPDIRECTSOUNDBUFFER8 iface
,
296 LPDIRECTSOUND pDirectSound
,
297 LPCDSBUFFERDESC pcDSBufferDesc
)
300 return DSERR_ALREADYINITIALIZED
;
305 PrimaryDirectSoundBuffer8Impl_fnLock(
306 LPDIRECTSOUNDBUFFER8 iface
,
309 LPVOID
*ppvAudioPtr1
,
310 LPDWORD pdwAudioBytes1
,
311 LPVOID
*ppvAudioPtr2
,
312 LPDWORD pdwAudioBytes2
,
316 return DSERR_INVALIDPARAM
;
321 PrimaryDirectSoundBuffer8Impl_fnPlay(
322 LPDIRECTSOUNDBUFFER8 iface
,
327 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
329 DPRINT("PrimaryDirectSoundBuffer8Impl_fnPlay dwFlags %x\n", dwFlags
);
331 if (dwReserved1
!= 0 || !(dwFlags
& DSBPLAY_LOOPING
))
333 /* invalid parameter */
334 return DSERR_INVALIDPARAM
;
337 PrimaryDirectSoundBuffer_AcquireLock(iface
);
339 if (This
->State
== KSSTATE_STOP
)
341 PrimaryDirectSoundBuffer_SetState(iface
, KSSTATE_ACQUIRE
);
342 ASSERT(This
->State
== KSSTATE_ACQUIRE
);
345 if (This
->State
== KSSTATE_ACQUIRE
)
347 PrimaryDirectSoundBuffer_SetState(iface
, KSSTATE_PAUSE
);
348 ASSERT(This
->State
== KSSTATE_PAUSE
);
351 if (This
->State
== KSSTATE_PAUSE
)
353 PrimaryDirectSoundBuffer_SetState(iface
, KSSTATE_RUN
);
354 ASSERT(This
->State
== KSSTATE_RUN
);
357 PrimaryDirectSoundBuffer_ReleaseLock(iface
);
364 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
365 LPDIRECTSOUNDBUFFER8 iface
,
368 /* The position of a primary buffer can't be set */
369 return DSERR_INVALIDCALL
;
374 PrimaryDirectSoundBuffer8Impl_fnSetFormat(
375 LPDIRECTSOUNDBUFFER8 iface
,
376 LPCWAVEFORMATEX pcfxFormat
)
378 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
380 if (This
->dwLevel
== DSSCL_NORMAL
)
382 /* can't change format with this level */
383 return DSERR_PRIOLEVELNEEDED
;
386 ASSERT(pcfxFormat
->cbSize
== 0);
389 DPRINT("This %p Format: Tag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u nBlockAlign %u wBitsPerSample %u cbSize %u\n", This
,
390 pcfxFormat
->wFormatTag
, pcfxFormat
->nChannels
, pcfxFormat
->nSamplesPerSec
, pcfxFormat
->nAvgBytesPerSec
, pcfxFormat
->nBlockAlign
, pcfxFormat
->wBitsPerSample
, pcfxFormat
->cbSize
);
392 CopyMemory(&This
->Format
, pcfxFormat
, sizeof(WAVEFORMATEX
));
399 PrimaryDirectSoundBuffer8Impl_fnSetVolume(
400 LPDIRECTSOUNDBUFFER8 iface
,
403 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
405 if (lVolume
< DSBVOLUME_MIN
|| lVolume
> DSBVOLUME_MAX
)
407 /* invalid parameter */
408 return DSERR_INVALIDPARAM
;
411 /* TODO: call volume node */
414 This
->Volume
= lVolume
;
421 PrimaryDirectSoundBuffer8Impl_fnSetPan(
422 LPDIRECTSOUNDBUFFER8 iface
,
425 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
427 if (lPan
< DSBPAN_LEFT
|| lPan
> DSBPAN_RIGHT
)
429 /* invalid parameter */
430 return DSERR_INVALIDPARAM
;
433 /* TODO: call volume node */
435 /* Store volume pan */
436 This
->VolumePan
= lPan
;
443 PrimaryDirectSoundBuffer8Impl_fnSetFrequency(
444 LPDIRECTSOUNDBUFFER8 iface
,
447 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
449 if (This
->dwLevel
< DSSCL_PRIORITY
)
451 /* needs priority level */
452 return DSERR_PRIOLEVELNEEDED
;
455 /* invalid request */
456 return DSERR_CONTROLUNAVAIL
;
461 PrimaryDirectSoundBuffer8Impl_fnStop(
462 LPDIRECTSOUNDBUFFER8 iface
)
464 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
466 DPRINT("PrimaryDirectSoundBuffer8Impl_fnStop\n");
468 PrimaryDirectSoundBuffer_AcquireLock(iface
);
470 if (This
->State
== KSSTATE_RUN
)
472 PrimaryDirectSoundBuffer_SetState(iface
, KSSTATE_PAUSE
);
473 ASSERT(This
->State
== KSSTATE_PAUSE
);
476 if (This
->State
== KSSTATE_PAUSE
)
478 PrimaryDirectSoundBuffer_SetState(iface
, KSSTATE_ACQUIRE
);
479 ASSERT(This
->State
== KSSTATE_ACQUIRE
);
482 if (This
->State
== KSSTATE_ACQUIRE
)
484 PrimaryDirectSoundBuffer_SetState(iface
, KSSTATE_STOP
);
485 ASSERT(This
->State
== KSSTATE_STOP
);
488 PrimaryDirectSoundBuffer_ReleaseLock(iface
);
496 PrimaryDirectSoundBuffer8Impl_fnUnlock(
497 LPDIRECTSOUNDBUFFER8 iface
,
504 return DSERR_INVALIDPARAM
;
510 PrimaryDirectSoundBuffer8Impl_fnRestore(
511 LPDIRECTSOUNDBUFFER8 iface
)
514 return DSERR_INVALIDPARAM
;
520 PrimaryDirectSoundBuffer8Impl_fnSetFX(
521 LPDIRECTSOUNDBUFFER8 iface
,
522 DWORD dwEffectsCount
,
523 LPDSEFFECTDESC pDSFXDesc
,
524 LPDWORD pdwResultCodes
)
527 return DSERR_INVALIDPARAM
;
532 PrimaryDirectSoundBuffer8Impl_fnAcquireResources(
533 LPDIRECTSOUNDBUFFER8 iface
,
535 DWORD dwEffectsCount
,
536 LPDWORD pdwResultCodes
)
539 return DSERR_INVALIDPARAM
;
544 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath(
545 LPDIRECTSOUNDBUFFER8 iface
,
548 REFGUID rguidInterface
,
552 return DSERR_INVALIDPARAM
;
555 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8
=
557 /* IUnknown methods */
558 PrimaryDirectSoundBuffer8Impl_fnQueryInterface
,
559 PrimaryDirectSoundBuffer8Impl_fnAddRef
,
560 PrimaryDirectSoundBuffer8Impl_fnRelease
,
561 /* IDirectSoundBuffer methods */
562 PrimaryDirectSoundBuffer8Impl_fnGetCaps
,
563 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition
,
564 PrimaryDirectSoundBuffer8Impl_fnGetFormat
,
565 PrimaryDirectSoundBuffer8Impl_fnGetVolume
,
566 PrimaryDirectSoundBuffer8Impl_fnGetPan
,
567 PrimaryDirectSoundBuffer8Impl_fnGetFrequency
,
568 PrimaryDirectSoundBuffer8Impl_fnGetStatus
,
569 PrimaryDirectSoundBuffer8Impl_fnInitialize
,
570 PrimaryDirectSoundBuffer8Impl_fnLock
,
571 PrimaryDirectSoundBuffer8Impl_fnPlay
,
572 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition
,
573 PrimaryDirectSoundBuffer8Impl_fnSetFormat
,
574 PrimaryDirectSoundBuffer8Impl_fnSetVolume
,
575 PrimaryDirectSoundBuffer8Impl_fnSetPan
,
576 PrimaryDirectSoundBuffer8Impl_fnSetFrequency
,
577 PrimaryDirectSoundBuffer8Impl_fnStop
,
578 PrimaryDirectSoundBuffer8Impl_fnUnlock
,
579 PrimaryDirectSoundBuffer8Impl_fnRestore
,
580 /* IDirectSoundBuffer8 methods */
581 PrimaryDirectSoundBuffer8Impl_fnSetFX
,
582 PrimaryDirectSoundBuffer8Impl_fnAcquireResources
,
583 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath
587 PrimaryDirectSoundBuffer_Write(
588 LPDIRECTSOUNDBUFFER8 iface
,
592 KSSTREAM_HEADER Header
;
593 DWORD Result
, BytesTransferred
;
594 OVERLAPPED Overlapped
;
596 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
598 ZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
599 Overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
603 ZeroMemory(&Header
, sizeof(KSSTREAM_HEADER
));
605 Header
.FrameExtent
= BufferSize
;
606 Header
.DataUsed
= BufferSize
;
607 Header
.Data
= Buffer
;
608 Header
.Size
= sizeof(KSSTREAM_HEADER
);
609 Header
.PresentationTime
.Numerator
= 1;
610 Header
.PresentationTime
.Denominator
= 1;
612 Result
= DeviceIoControl(This
->hPin
, IOCTL_KS_WRITE_STREAM
, NULL
, 0, &Header
, sizeof(KSSTREAM_HEADER
), &BytesTransferred
, &Overlapped
);
614 if (Result
!= ERROR_SUCCESS
)
617 return BytesTransferred
;
621 PrimaryDirectSoundBuffer_SetState(
622 LPDIRECTSOUNDBUFFER8 iface
,
626 DWORD Result
, BytesTransferred
;
627 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
629 if (This
->State
== State
)
632 Property
.Set
= KSPROPSETID_Connection
;
633 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
634 Property
.Flags
= KSPROPERTY_TYPE_SET
;
636 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesTransferred
);
637 if (Result
== ERROR_SUCCESS
)
644 PrimaryDirectSoundBuffer_GetPosition(
645 LPDIRECTSOUNDBUFFER8 iface
,
646 LPDWORD pdwCurrentPlayCursor
,
647 LPDWORD pdwCurrentWriteCursor
)
649 KSAUDIO_POSITION Position
;
652 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
654 //DPRINT("PrimaryDirectSoundBuffer_GetPosition\n");
658 if (pdwCurrentPlayCursor
)
659 *pdwCurrentPlayCursor
= 0;
661 if (pdwCurrentWriteCursor
)
662 *pdwCurrentWriteCursor
= 0;
664 DPRINT("No Audio Pin\n");
668 /* setup audio position property request */
669 Request
.Id
= KSPROPERTY_AUDIO_POSITION
;
670 Request
.Set
= KSPROPSETID_Audio
;
671 Request
.Flags
= KSPROPERTY_TYPE_GET
;
674 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Request
, sizeof(KSPROPERTY
), (PVOID
)&Position
, sizeof(KSAUDIO_POSITION
), NULL
);
676 if (Result
!= ERROR_SUCCESS
)
678 DPRINT("GetPosition failed with %x\n", Result
);
679 return DSERR_UNSUPPORTED
;
682 //DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset);
684 if (pdwCurrentPlayCursor
)
685 *pdwCurrentPlayCursor
= (DWORD
)Position
.PlayOffset
;
687 if (pdwCurrentWriteCursor
)
688 *pdwCurrentWriteCursor
= (DWORD
)Position
.WriteOffset
;
694 PrimaryDirectSoundBuffer_SetFormat(
695 LPDIRECTSOUNDBUFFER8 iface
,
696 LPWAVEFORMATEX pcfxFormat
,
699 ULONG PinId
, DeviceId
= 0, Result
;
700 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
705 // check if multiple buffers are active
706 // in that case need mixing
708 if (SetPinFormat(This
->hPin
, pcfxFormat
))
711 return DSERR_GENERIC
;
716 /* try all available recording pins on that filter */
717 PinId
= GetPinIdFromFilter(This
->Filter
, FALSE
, DeviceId
);
718 DPRINT("PinId %u DeviceId %u\n", PinId
, DeviceId
);
720 if (PinId
== ULONG_MAX
)
723 Result
= OpenPin(This
->Filter
->hFilter
, PinId
, (LPWAVEFORMATEX
)pcfxFormat
, &This
->hPin
, bLooped
);
724 DPRINT("PinId %u Result %u\n", PinId
, Result
);
725 if (Result
== ERROR_SUCCESS
)
727 This
->dwFrequency
= pcfxFormat
->nSamplesPerSec
;
737 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat failed\n");
738 return DSERR_INVALIDPARAM
;
741 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat success\n");
746 PrimaryDirectSoundBuffer_AcquireLock(
747 LPDIRECTSOUNDBUFFER8 iface
)
749 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
751 EnterCriticalSection(&This
->Lock
);
757 PrimaryDirectSoundBuffer_ReleaseLock(
758 LPDIRECTSOUNDBUFFER8 iface
)
760 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
762 LeaveCriticalSection(&This
->Lock
);
768 NewPrimarySoundBuffer(
769 LPDIRECTSOUNDBUFFER8
*OutBuffer
,
774 LPCDirectSoundBuffer This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundBuffer
));
778 /* not enough memory */
779 return DSERR_OUTOFMEMORY
;
783 This
->lpVtbl
= &vt_DirectSoundBuffer8
;
784 This
->Filter
= Filter
;
785 This
->dwLevel
= dwLevel
;
786 This
->dwFlags
= dwFlags
;
787 This
->dwFrequency
= 0;
788 This
->Volume
= DSBVOLUME_MAX
;
789 This
->VolumePan
= DSBPAN_CENTER
;
792 /* FIXME: determine default format for audio device */
793 This
->Format
.cbSize
= sizeof(WAVEFORMATEX
);
794 This
->Format
.nChannels
= 2;
795 This
->Format
.nSamplesPerSec
= 44100;
796 This
->Format
.wBitsPerSample
= 16;
797 This
->Format
.wFormatTag
= WAVE_FORMAT_PCM
;
798 This
->Format
.nBlockAlign
= (This
->Format
.nChannels
* This
->Format
.wBitsPerSample
) / 8;
799 This
->Format
.nAvgBytesPerSec
= (This
->Format
.nChannels
* This
->Format
.nSamplesPerSec
* This
->Format
.wBitsPerSample
) / 8;
801 InitializeCriticalSection(&This
->Lock
);
803 *OutBuffer
= (LPDIRECTSOUNDBUFFER8
)&This
->lpVtbl
;