[QUARTZ]
[reactos.git] / reactos / dll / directx / dsound_new / secondary.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/secondary.c
5 * PURPOSE: Secondary IDirectSoundBuffer8 implementation
6 *
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9
10
11 #include "precomp.h"
12
13 typedef struct
14 {
15 const IDirectSoundBuffer8Vtbl *lpVtbl;
16 LONG ref;
17
18 LPFILTERINFO Filter;
19 DWORD dwLevel;
20 DWORD dwFlags;
21 DWORD dwFrequency;
22 DWORD BufferPosition;
23 LONG Volume;
24 LONG VolumePan;
25 LPWAVEFORMATEX Format;
26 PUCHAR Buffer;
27 DWORD BufferSize;
28 KSSTATE State;
29 DWORD Flags;
30 DWORD Position;
31 DWORD PlayPosition;
32
33 LPDIRECTSOUNDBUFFER8 PrimaryBuffer;
34
35
36 }CDirectSoundBuffer, *LPCDirectSoundBuffer;
37
38 HRESULT
39 WINAPI
40 SecondaryDirectSoundBuffer8Impl_fnQueryInterface(
41 LPDIRECTSOUNDBUFFER8 iface,
42 IN REFIID riid,
43 LPVOID* ppobj)
44 {
45 LPOLESTR pStr;
46 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
47
48 if (IsEqualIID(riid, &IID_IUnknown) ||
49 IsEqualIID(riid, &IID_IDirectSoundBuffer) ||
50 IsEqualIID(riid, &IID_IDirectSoundBuffer8))
51 {
52 *ppobj = (LPVOID)&This->lpVtbl;
53 InterlockedIncrement(&This->ref);
54 return S_OK;
55 }
56
57 if (SUCCEEDED(StringFromIID(riid, &pStr)))
58 {
59 DPRINT("No Interface for class %s\n", pStr);
60 CoTaskMemFree(pStr);
61 }
62 return E_NOINTERFACE;
63 }
64
65 ULONG
66 WINAPI
67 SecondaryDirectSoundBuffer8Impl_fnAddRef(
68 LPDIRECTSOUNDBUFFER8 iface)
69 {
70 ULONG ref;
71 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
72
73 ref = InterlockedIncrement(&This->ref);
74
75 return ref;
76
77 }
78
79 ULONG
80 WINAPI
81 SecondaryDirectSoundBuffer8Impl_fnRelease(
82 LPDIRECTSOUNDBUFFER8 iface)
83 {
84 ULONG ref;
85 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
86
87 ref = InterlockedDecrement(&(This->ref));
88
89 if (!ref)
90 {
91 HeapFree(GetProcessHeap(), 0, This->Buffer);
92 HeapFree(GetProcessHeap(), 0, This->Format);
93 HeapFree(GetProcessHeap(), 0, This);
94 }
95
96 return ref;
97 }
98
99 HRESULT
100 WINAPI
101 SecondaryDirectSoundBuffer8Impl_fnGetCaps(
102 LPDIRECTSOUNDBUFFER8 iface,
103 LPDSBCAPS pDSBufferCaps)
104 {
105 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
106
107 if (!pDSBufferCaps)
108 {
109 /* invalid parameter */
110 return DSERR_INVALIDPARAM;
111 }
112
113 if (pDSBufferCaps->dwSize < sizeof(DSBCAPS))
114 {
115 /* invalid buffer size */
116 return DSERR_INVALIDPARAM;
117 }
118
119 /* get buffer details */
120 pDSBufferCaps->dwUnlockTransferRate = 0;
121 pDSBufferCaps->dwPlayCpuOverhead = 0;
122 pDSBufferCaps->dwSize = This->BufferSize;
123 pDSBufferCaps->dwFlags = This->dwFlags;
124
125 return DS_OK;
126 }
127
128 HRESULT
129 WINAPI
130 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
131 LPDIRECTSOUNDBUFFER8 iface,
132 LPDWORD pdwCurrentPlayCursor,
133 LPDWORD pdwCurrentWriteCursor)
134 {
135 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
136
137 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
138
139 if (pdwCurrentWriteCursor)
140 {
141 *pdwCurrentWriteCursor = This->BufferPosition;
142 }
143
144 return PrimaryDirectSoundBuffer_GetPosition(This->PrimaryBuffer, pdwCurrentPlayCursor, NULL);
145 }
146
147 HRESULT
148 WINAPI
149 SecondaryDirectSoundBuffer8Impl_fnGetFormat(
150 LPDIRECTSOUNDBUFFER8 iface,
151 LPWAVEFORMATEX pwfxFormat,
152 DWORD dwSizeAllocated,
153 LPDWORD pdwSizeWritten)
154 {
155 DWORD FormatSize;
156 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
157
158 FormatSize = sizeof(WAVEFORMATEX) + This->Format->cbSize;
159
160 if (!pwfxFormat && !pdwSizeWritten)
161 {
162 /* invalid parameter */
163 return DSERR_INVALIDPARAM;
164 }
165
166 if (!pwfxFormat)
167 {
168 /* return required format size */
169 *pdwSizeWritten = FormatSize;
170 return DS_OK;
171 }
172 else
173 {
174 if (dwSizeAllocated >= FormatSize)
175 {
176 /* copy format */
177 CopyMemory(pwfxFormat, This->Format, FormatSize);
178
179 if (pdwSizeWritten)
180 *pdwSizeWritten = FormatSize;
181
182 return DS_OK;
183 }
184 /* buffer too small */
185 if (pdwSizeWritten)
186 *pdwSizeWritten = 0;
187
188 return DSERR_INVALIDPARAM;
189 }
190 }
191
192 HRESULT
193 WINAPI
194 SecondaryDirectSoundBuffer8Impl_fnGetVolume(
195 LPDIRECTSOUNDBUFFER8 iface,
196 LPLONG plVolume)
197 {
198 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
199
200 if (!plVolume)
201 {
202 /* invalid parameter */
203 return DSERR_INVALIDPARAM;
204 }
205
206 /* get volume */
207 *plVolume = This->Volume;
208
209 return DS_OK;
210 }
211
212 HRESULT
213 WINAPI
214 SecondaryDirectSoundBuffer8Impl_fnGetPan(
215 LPDIRECTSOUNDBUFFER8 iface,
216 LPLONG plPan)
217 {
218 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
219
220 if (!plPan)
221 {
222 /* invalid parameter */
223 return DSERR_INVALIDPARAM;
224 }
225
226 /* get frequency */
227 *plPan = This->VolumePan;
228
229 return DS_OK;
230 }
231
232 HRESULT
233 WINAPI
234 SecondaryDirectSoundBuffer8Impl_fnGetFrequency(
235 LPDIRECTSOUNDBUFFER8 iface,
236 LPDWORD pdwFrequency)
237 {
238 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
239
240 if (!pdwFrequency)
241 {
242 /* invalid parameter */
243 return DSERR_INVALIDPARAM;
244 }
245
246 /* get frequency */
247 *pdwFrequency = This->dwFrequency;
248
249 return DS_OK;
250 }
251
252 HRESULT
253 WINAPI
254 SecondaryDirectSoundBuffer8Impl_fnGetStatus(
255 LPDIRECTSOUNDBUFFER8 iface,
256 LPDWORD pdwStatus)
257 {
258 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
259
260 if (!pdwStatus)
261 {
262 /* invalid parameter */
263 return DSERR_INVALIDPARAM;
264 }
265
266 *pdwStatus = 0;
267 if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE)
268 {
269 /* buffer is playing */
270 *pdwStatus |= DSBSTATUS_PLAYING;
271 if (This->Flags & DSBPLAY_LOOPING)
272 *pdwStatus |= DSBSTATUS_LOOPING;
273 }
274
275 return DS_OK;
276 }
277
278 HRESULT
279 WINAPI
280 SecondaryDirectSoundBuffer8Impl_fnInitialize(
281 LPDIRECTSOUNDBUFFER8 iface,
282 LPDIRECTSOUND pDirectSound,
283 LPCDSBUFFERDESC pcDSBufferDesc)
284 {
285 /* RTFM */
286 return DSERR_ALREADYINITIALIZED;
287 }
288
289 HRESULT
290 WINAPI
291 SecondaryDirectSoundBuffer8Impl_fnLock(
292 LPDIRECTSOUNDBUFFER8 iface,
293 DWORD dwOffset,
294 DWORD dwBytes,
295 LPVOID *ppvAudioPtr1,
296 LPDWORD pdwAudioBytes1,
297 LPVOID *ppvAudioPtr2,
298 LPDWORD pdwAudioBytes2,
299 DWORD dwFlags)
300 {
301 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
302
303 DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n",
304 This, dwOffset, dwBytes, ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2, dwFlags, This->BufferSize);
305
306 if (dwFlags == DSBLOCK_ENTIREBUFFER)
307 {
308 *ppvAudioPtr1 = (LPVOID)This->Buffer;
309 *pdwAudioBytes1 = This->BufferSize;
310 if (ppvAudioPtr2)
311 *ppvAudioPtr2 = NULL;
312 if (pdwAudioBytes2)
313 *pdwAudioBytes2 = 0;
314
315 return DS_OK;
316 }
317 else if (dwFlags == DSBLOCK_FROMWRITECURSOR)
318 {
319 UNIMPLEMENTED
320 return DSERR_UNSUPPORTED;
321 }
322 else
323 {
324 ASSERT(dwOffset < This->BufferSize);
325 ASSERT(dwBytes <= This->BufferSize);
326
327 dwBytes = min(This->BufferSize - dwOffset, dwBytes);
328
329 *ppvAudioPtr1 = This->Buffer + dwOffset;
330 *pdwAudioBytes1 = dwBytes;
331
332 This->BufferPosition = dwOffset + dwBytes;
333
334 if (This->BufferPosition == This->BufferSize)
335 This->BufferPosition = 0;
336
337 if (ppvAudioPtr2)
338 *ppvAudioPtr2 = NULL;
339 if (pdwAudioBytes2)
340 *pdwAudioBytes2 = 0;
341
342 return DS_OK;
343 }
344 }
345
346 HRESULT
347 WINAPI
348 SecondaryDirectSoundBuffer8Impl_fnPlay(
349 LPDIRECTSOUNDBUFFER8 iface,
350 DWORD dwReserved1,
351 DWORD dwPriority,
352 DWORD dwFlags)
353 {
354 HRESULT hResult;
355 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
356
357 if (dwReserved1 != 0)
358 {
359 /* must be zero */
360 return DSERR_INVALIDPARAM;
361 }
362
363 /* sanity check */
364 ASSERT(dwFlags & DSBPLAY_LOOPING);
365
366
367 if (This->State == KSSTATE_RUN)
368 {
369 /* sound buffer is already playing */
370 return DS_OK;
371 }
372
373 /* set dataformat */
374 hResult = PrimaryDirectSoundBuffer_SetFormat(This->PrimaryBuffer, This->Format, TRUE);
375
376 if (!SUCCEEDED(hResult))
377 {
378 /* failed */
379 DPRINT1("Failed to set format Tag %u Samples %u Bytes %u nChannels %u\n", This->Format->wFormatTag, This->Format->nSamplesPerSec, This->Format->wBitsPerSample, This->Format->nChannels);
380 return hResult;
381 }
382
383 /* start primary buffer */
384 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_RUN);
385 /* acquire primary buffer */
386 PrimaryDirectSoundBuffer_AcquireLock(This->PrimaryBuffer);
387 /* HACK write buffer */
388 PrimaryDirectSoundBuffer_Write(This->PrimaryBuffer, This->Buffer, This->BufferSize);
389 /* release primary buffer */
390 PrimaryDirectSoundBuffer_ReleaseLock(This->PrimaryBuffer);
391
392 DPRINT("SetFormatSuccess PrimaryBuffer %p\n", This->PrimaryBuffer);
393 This->State = KSSTATE_RUN;
394
395 return DS_OK;
396 }
397
398 HRESULT
399 WINAPI
400 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
401 LPDIRECTSOUNDBUFFER8 iface,
402 DWORD dwNewPosition)
403 {
404 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
405
406 DPRINT("Setting position %u\n", dwNewPosition);
407 This->Position = dwNewPosition;
408
409 return DS_OK;
410 }
411
412 HRESULT
413 WINAPI
414 SecondaryDirectSoundBuffer8Impl_fnSetFormat(
415 LPDIRECTSOUNDBUFFER8 iface,
416 LPCWAVEFORMATEX pcfxFormat)
417 {
418 /* RTFM */
419 return DSERR_INVALIDCALL;
420 }
421
422 HRESULT
423 WINAPI
424 SecondaryDirectSoundBuffer8Impl_fnSetVolume(
425 LPDIRECTSOUNDBUFFER8 iface,
426 LONG lVolume)
427 {
428 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
429
430 if (lVolume < DSBVOLUME_MIN || lVolume > DSBVOLUME_MAX)
431 {
432 /* invalid parameter */
433 return DSERR_INVALIDPARAM;
434 }
435
436
437 /* Store volume */
438 This->Volume = lVolume;
439
440 return DS_OK;
441 }
442
443 HRESULT
444 WINAPI
445 SecondaryDirectSoundBuffer8Impl_fnSetPan(
446 LPDIRECTSOUNDBUFFER8 iface,
447 LONG lPan)
448 {
449 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
450
451 if (lPan < DSBPAN_LEFT || lPan > DSBPAN_RIGHT)
452 {
453 /* invalid parameter */
454 return DSERR_INVALIDPARAM;
455 }
456
457 /* Store volume pan */
458 This->VolumePan = lPan;
459
460 return DS_OK;
461 }
462
463 HRESULT
464 WINAPI
465 SecondaryDirectSoundBuffer8Impl_fnSetFrequency(
466 LPDIRECTSOUNDBUFFER8 iface,
467 DWORD dwFrequency)
468 {
469 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
470
471 if (dwFrequency == DSBFREQUENCY_ORIGINAL)
472 {
473 /* restore original frequency */
474 dwFrequency = This->Format->nSamplesPerSec;
475 }
476
477 if (dwFrequency < DSBFREQUENCY_MIN || dwFrequency > DSBFREQUENCY_MAX)
478 {
479 /* invalid frequency */
480 return DSERR_INVALIDPARAM;
481 }
482
483 if (dwFrequency != This->dwFrequency)
484 {
485 /* FIXME handle frequency change */
486 }
487
488 /* store frequency */
489 This->dwFrequency = dwFrequency;
490
491 return DS_OK;
492 }
493
494 HRESULT
495 WINAPI
496 SecondaryDirectSoundBuffer8Impl_fnStop(
497 LPDIRECTSOUNDBUFFER8 iface)
498 {
499 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
500
501 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_PAUSE);
502 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_ACQUIRE);
503 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_STOP);
504
505 DPRINT("SecondaryDirectSoundBuffer8Impl_fnStop\n");
506
507
508 /* set state to stop */
509 This->State = KSSTATE_STOP;
510 This->BufferPosition = 0;
511
512 return DS_OK;
513 }
514
515
516 HRESULT
517 WINAPI
518 SecondaryDirectSoundBuffer8Impl_fnUnlock(
519 LPDIRECTSOUNDBUFFER8 iface,
520 LPVOID pvAudioPtr1,
521 DWORD dwAudioBytes1,
522 LPVOID pvAudioPtr2,
523 DWORD dwAudioBytes2)
524 {
525 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n");
526 return DS_OK;
527 }
528
529
530
531
532 HRESULT
533 WINAPI
534 SecondaryDirectSoundBuffer8Impl_fnRestore(
535 LPDIRECTSOUNDBUFFER8 iface)
536 {
537 UNIMPLEMENTED
538 return DSERR_INVALIDPARAM;
539 }
540
541
542 HRESULT
543 WINAPI
544 SecondaryDirectSoundBuffer8Impl_fnSetFX(
545 LPDIRECTSOUNDBUFFER8 iface,
546 DWORD dwEffectsCount,
547 LPDSEFFECTDESC pDSFXDesc,
548 LPDWORD pdwResultCodes)
549 {
550 UNIMPLEMENTED
551 return DSERR_INVALIDPARAM;
552 }
553
554 HRESULT
555 WINAPI
556 SecondaryDirectSoundBuffer8Impl_fnAcquireResources(
557 LPDIRECTSOUNDBUFFER8 iface,
558 DWORD dwFlags,
559 DWORD dwEffectsCount,
560 LPDWORD pdwResultCodes)
561 {
562 UNIMPLEMENTED
563 return DSERR_INVALIDPARAM;
564 }
565
566 HRESULT
567 WINAPI
568 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(
569 LPDIRECTSOUNDBUFFER8 iface,
570 REFGUID rguidObject,
571 DWORD dwIndex,
572 REFGUID rguidInterface,
573 LPVOID *ppObject)
574 {
575 UNIMPLEMENTED
576 return DSERR_INVALIDPARAM;
577 }
578
579 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 =
580 {
581 /* IUnknown methods */
582 SecondaryDirectSoundBuffer8Impl_fnQueryInterface,
583 SecondaryDirectSoundBuffer8Impl_fnAddRef,
584 SecondaryDirectSoundBuffer8Impl_fnRelease,
585 /* IDirectSoundBuffer methods */
586 SecondaryDirectSoundBuffer8Impl_fnGetCaps,
587 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition,
588 SecondaryDirectSoundBuffer8Impl_fnGetFormat,
589 SecondaryDirectSoundBuffer8Impl_fnGetVolume,
590 SecondaryDirectSoundBuffer8Impl_fnGetPan,
591 SecondaryDirectSoundBuffer8Impl_fnGetFrequency,
592 SecondaryDirectSoundBuffer8Impl_fnGetStatus,
593 SecondaryDirectSoundBuffer8Impl_fnInitialize,
594 SecondaryDirectSoundBuffer8Impl_fnLock,
595 SecondaryDirectSoundBuffer8Impl_fnPlay,
596 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition,
597 SecondaryDirectSoundBuffer8Impl_fnSetFormat,
598 SecondaryDirectSoundBuffer8Impl_fnSetVolume,
599 SecondaryDirectSoundBuffer8Impl_fnSetPan,
600 SecondaryDirectSoundBuffer8Impl_fnSetFrequency,
601 SecondaryDirectSoundBuffer8Impl_fnStop,
602 SecondaryDirectSoundBuffer8Impl_fnUnlock,
603 SecondaryDirectSoundBuffer8Impl_fnRestore,
604 /* IDirectSoundBuffer8 methods */
605 SecondaryDirectSoundBuffer8Impl_fnSetFX,
606 SecondaryDirectSoundBuffer8Impl_fnAcquireResources,
607 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath
608 };
609
610 HRESULT
611 NewSecondarySoundBuffer(
612 LPDIRECTSOUNDBUFFER8 *OutBuffer,
613 LPFILTERINFO Filter,
614 DWORD dwLevel,
615 LPCDSBUFFERDESC lpcDSBufferDesc,
616 LPDIRECTSOUNDBUFFER8 PrimaryBuffer)
617 {
618 ULONG FormatSize;
619 LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer));
620
621 if (!This)
622 {
623 /* not enough memory */
624 return DSERR_OUTOFMEMORY;
625 }
626
627 FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize;
628
629 This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize);
630 if (!This->Format)
631 {
632 /* not enough memory */
633 HeapFree(GetProcessHeap(), 0, This);
634 return DSERR_OUTOFMEMORY;
635 }
636
637 /* sanity check */
638 ASSERT(lpcDSBufferDesc->dwBufferBytes);
639
640 /* allocate sound buffer */
641 This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes);
642 if (!This->Buffer)
643 {
644 /* not enough memory */
645 HeapFree(GetProcessHeap(), 0, This->Format);
646 HeapFree(GetProcessHeap(), 0, This);
647 return DSERR_OUTOFMEMORY;
648 }
649
650 /* fill buffer with silence */
651 FillMemory(This->Buffer, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample == 8 ? 0x80 : 0);
652
653 This->ref = 1;
654 This->lpVtbl = &vt_DirectSoundBuffer8;
655 This->Filter = Filter;
656 This->dwLevel = dwLevel;
657 This->dwFlags = lpcDSBufferDesc->dwFlags;
658 This->dwFrequency = lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec;
659 This->State = KSSTATE_STOP;
660 This->Volume = DSBVOLUME_MAX;
661 This->VolumePan = DSBPAN_CENTER;
662 This->Flags = 0;
663 This->Position = 0;
664 This->BufferSize = lpcDSBufferDesc->dwBufferBytes;
665 This->PrimaryBuffer = PrimaryBuffer;
666
667 CopyMemory(This->Format, lpcDSBufferDesc->lpwfxFormat, FormatSize);
668
669 *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl;
670 return DS_OK;
671 }
672