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
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
15 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
25 LPWAVEFORMATEX Format
;
33 LPDIRECTSOUNDBUFFER8 PrimaryBuffer
;
36 }CDirectSoundBuffer
, *LPCDirectSoundBuffer
;
40 SecondaryDirectSoundBuffer8Impl_fnQueryInterface(
41 LPDIRECTSOUNDBUFFER8 iface
,
46 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
48 if (IsEqualIID(riid
, &IID_IUnknown
) ||
49 IsEqualIID(riid
, &IID_IDirectSoundBuffer
) ||
50 IsEqualIID(riid
, &IID_IDirectSoundBuffer8
))
52 *ppobj
= (LPVOID
)&This
->lpVtbl
;
53 InterlockedIncrement(&This
->ref
);
57 if (SUCCEEDED(StringFromIID(riid
, &pStr
)))
59 DPRINT("No Interface for class %s\n", pStr
);
67 SecondaryDirectSoundBuffer8Impl_fnAddRef(
68 LPDIRECTSOUNDBUFFER8 iface
)
71 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
73 ref
= InterlockedIncrement(&This
->ref
);
81 SecondaryDirectSoundBuffer8Impl_fnRelease(
82 LPDIRECTSOUNDBUFFER8 iface
)
85 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
87 ref
= InterlockedDecrement(&(This
->ref
));
91 HeapFree(GetProcessHeap(), 0, This
->Buffer
);
92 HeapFree(GetProcessHeap(), 0, This
->Format
);
93 HeapFree(GetProcessHeap(), 0, This
);
101 SecondaryDirectSoundBuffer8Impl_fnGetCaps(
102 LPDIRECTSOUNDBUFFER8 iface
,
103 LPDSBCAPS pDSBufferCaps
)
105 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
109 /* invalid parameter */
110 return DSERR_INVALIDPARAM
;
113 if (pDSBufferCaps
->dwSize
< sizeof(DSBCAPS
))
115 /* invalid buffer size */
116 return DSERR_INVALIDPARAM
;
119 /* get buffer details */
120 pDSBufferCaps
->dwUnlockTransferRate
= 0;
121 pDSBufferCaps
->dwPlayCpuOverhead
= 0;
122 pDSBufferCaps
->dwSize
= This
->BufferSize
;
123 pDSBufferCaps
->dwFlags
= This
->dwFlags
;
130 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
131 LPDIRECTSOUNDBUFFER8 iface
,
132 LPDWORD pdwCurrentPlayCursor
,
133 LPDWORD pdwCurrentWriteCursor
)
135 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
137 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
139 if (pdwCurrentWriteCursor
)
141 *pdwCurrentWriteCursor
= This
->BufferPosition
;
144 return PrimaryDirectSoundBuffer_GetPosition(This
->PrimaryBuffer
, pdwCurrentPlayCursor
, NULL
);
149 SecondaryDirectSoundBuffer8Impl_fnGetFormat(
150 LPDIRECTSOUNDBUFFER8 iface
,
151 LPWAVEFORMATEX pwfxFormat
,
152 DWORD dwSizeAllocated
,
153 LPDWORD pdwSizeWritten
)
156 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
158 FormatSize
= sizeof(WAVEFORMATEX
) + This
->Format
->cbSize
;
160 if (!pwfxFormat
&& !pdwSizeWritten
)
162 /* invalid parameter */
163 return DSERR_INVALIDPARAM
;
168 /* return required format size */
169 *pdwSizeWritten
= FormatSize
;
174 if (dwSizeAllocated
>= FormatSize
)
177 CopyMemory(pwfxFormat
, This
->Format
, FormatSize
);
180 *pdwSizeWritten
= FormatSize
;
184 /* buffer too small */
188 return DSERR_INVALIDPARAM
;
194 SecondaryDirectSoundBuffer8Impl_fnGetVolume(
195 LPDIRECTSOUNDBUFFER8 iface
,
198 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
202 /* invalid parameter */
203 return DSERR_INVALIDPARAM
;
207 *plVolume
= This
->Volume
;
214 SecondaryDirectSoundBuffer8Impl_fnGetPan(
215 LPDIRECTSOUNDBUFFER8 iface
,
218 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
222 /* invalid parameter */
223 return DSERR_INVALIDPARAM
;
227 *plPan
= This
->VolumePan
;
234 SecondaryDirectSoundBuffer8Impl_fnGetFrequency(
235 LPDIRECTSOUNDBUFFER8 iface
,
236 LPDWORD pdwFrequency
)
238 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
242 /* invalid parameter */
243 return DSERR_INVALIDPARAM
;
247 *pdwFrequency
= This
->dwFrequency
;
254 SecondaryDirectSoundBuffer8Impl_fnGetStatus(
255 LPDIRECTSOUNDBUFFER8 iface
,
258 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
262 /* invalid parameter */
263 return DSERR_INVALIDPARAM
;
267 if (This
->State
== KSSTATE_RUN
|| This
->State
== KSSTATE_ACQUIRE
)
269 /* buffer is playing */
270 *pdwStatus
|= DSBSTATUS_PLAYING
;
271 if (This
->Flags
& DSBPLAY_LOOPING
)
272 *pdwStatus
|= DSBSTATUS_LOOPING
;
280 SecondaryDirectSoundBuffer8Impl_fnInitialize(
281 LPDIRECTSOUNDBUFFER8 iface
,
282 LPDIRECTSOUND pDirectSound
,
283 LPCDSBUFFERDESC pcDSBufferDesc
)
286 return DSERR_ALREADYINITIALIZED
;
291 SecondaryDirectSoundBuffer8Impl_fnLock(
292 LPDIRECTSOUNDBUFFER8 iface
,
295 LPVOID
*ppvAudioPtr1
,
296 LPDWORD pdwAudioBytes1
,
297 LPVOID
*ppvAudioPtr2
,
298 LPDWORD pdwAudioBytes2
,
301 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
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
);
306 if (dwFlags
== DSBLOCK_ENTIREBUFFER
)
308 *ppvAudioPtr1
= (LPVOID
)This
->Buffer
;
309 *pdwAudioBytes1
= This
->BufferSize
;
311 *ppvAudioPtr2
= NULL
;
317 else if (dwFlags
== DSBLOCK_FROMWRITECURSOR
)
320 return DSERR_UNSUPPORTED
;
324 ASSERT(dwOffset
< This
->BufferSize
);
325 ASSERT(dwBytes
<= This
->BufferSize
);
327 dwBytes
= min(This
->BufferSize
- dwOffset
, dwBytes
);
329 *ppvAudioPtr1
= This
->Buffer
+ dwOffset
;
330 *pdwAudioBytes1
= dwBytes
;
332 This
->BufferPosition
= dwOffset
+ dwBytes
;
334 if (This
->BufferPosition
== This
->BufferSize
)
335 This
->BufferPosition
= 0;
338 *ppvAudioPtr2
= NULL
;
348 SecondaryDirectSoundBuffer8Impl_fnPlay(
349 LPDIRECTSOUNDBUFFER8 iface
,
355 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
357 if (dwReserved1
!= 0)
360 return DSERR_INVALIDPARAM
;
364 ASSERT(dwFlags
& DSBPLAY_LOOPING
);
367 if (This
->State
== KSSTATE_RUN
)
369 /* sound buffer is already playing */
374 hResult
= PrimaryDirectSoundBuffer_SetFormat(This
->PrimaryBuffer
, This
->Format
, TRUE
);
376 if (!SUCCEEDED(hResult
))
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
);
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
);
392 DPRINT("SetFormatSuccess PrimaryBuffer %p\n", This
->PrimaryBuffer
);
393 This
->State
= KSSTATE_RUN
;
400 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
401 LPDIRECTSOUNDBUFFER8 iface
,
404 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
406 DPRINT("Setting position %u\n", dwNewPosition
);
407 This
->Position
= dwNewPosition
;
414 SecondaryDirectSoundBuffer8Impl_fnSetFormat(
415 LPDIRECTSOUNDBUFFER8 iface
,
416 LPCWAVEFORMATEX pcfxFormat
)
419 return DSERR_INVALIDCALL
;
424 SecondaryDirectSoundBuffer8Impl_fnSetVolume(
425 LPDIRECTSOUNDBUFFER8 iface
,
428 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
430 if (lVolume
< DSBVOLUME_MIN
|| lVolume
> DSBVOLUME_MAX
)
432 /* invalid parameter */
433 return DSERR_INVALIDPARAM
;
438 This
->Volume
= lVolume
;
445 SecondaryDirectSoundBuffer8Impl_fnSetPan(
446 LPDIRECTSOUNDBUFFER8 iface
,
449 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
451 if (lPan
< DSBPAN_LEFT
|| lPan
> DSBPAN_RIGHT
)
453 /* invalid parameter */
454 return DSERR_INVALIDPARAM
;
457 /* Store volume pan */
458 This
->VolumePan
= lPan
;
465 SecondaryDirectSoundBuffer8Impl_fnSetFrequency(
466 LPDIRECTSOUNDBUFFER8 iface
,
469 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
471 if (dwFrequency
== DSBFREQUENCY_ORIGINAL
)
473 /* restore original frequency */
474 dwFrequency
= This
->Format
->nSamplesPerSec
;
477 if (dwFrequency
< DSBFREQUENCY_MIN
|| dwFrequency
> DSBFREQUENCY_MAX
)
479 /* invalid frequency */
480 return DSERR_INVALIDPARAM
;
483 if (dwFrequency
!= This
->dwFrequency
)
485 /* FIXME handle frequency change */
488 /* store frequency */
489 This
->dwFrequency
= dwFrequency
;
496 SecondaryDirectSoundBuffer8Impl_fnStop(
497 LPDIRECTSOUNDBUFFER8 iface
)
499 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
501 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_PAUSE
);
502 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_ACQUIRE
);
503 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_STOP
);
505 DPRINT("SecondaryDirectSoundBuffer8Impl_fnStop\n");
508 /* set state to stop */
509 This
->State
= KSSTATE_STOP
;
510 This
->BufferPosition
= 0;
518 SecondaryDirectSoundBuffer8Impl_fnUnlock(
519 LPDIRECTSOUNDBUFFER8 iface
,
525 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n");
534 SecondaryDirectSoundBuffer8Impl_fnRestore(
535 LPDIRECTSOUNDBUFFER8 iface
)
538 return DSERR_INVALIDPARAM
;
544 SecondaryDirectSoundBuffer8Impl_fnSetFX(
545 LPDIRECTSOUNDBUFFER8 iface
,
546 DWORD dwEffectsCount
,
547 LPDSEFFECTDESC pDSFXDesc
,
548 LPDWORD pdwResultCodes
)
551 return DSERR_INVALIDPARAM
;
556 SecondaryDirectSoundBuffer8Impl_fnAcquireResources(
557 LPDIRECTSOUNDBUFFER8 iface
,
559 DWORD dwEffectsCount
,
560 LPDWORD pdwResultCodes
)
563 return DSERR_INVALIDPARAM
;
568 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(
569 LPDIRECTSOUNDBUFFER8 iface
,
572 REFGUID rguidInterface
,
576 return DSERR_INVALIDPARAM
;
579 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8
=
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
611 NewSecondarySoundBuffer(
612 LPDIRECTSOUNDBUFFER8
*OutBuffer
,
615 LPCDSBUFFERDESC lpcDSBufferDesc
,
616 LPDIRECTSOUNDBUFFER8 PrimaryBuffer
)
619 LPCDirectSoundBuffer This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundBuffer
));
623 /* not enough memory */
624 return DSERR_OUTOFMEMORY
;
627 FormatSize
= sizeof(WAVEFORMATEX
) + lpcDSBufferDesc
->lpwfxFormat
->cbSize
;
629 This
->Format
= HeapAlloc(GetProcessHeap(), 0, FormatSize
);
632 /* not enough memory */
633 HeapFree(GetProcessHeap(), 0, This
);
634 return DSERR_OUTOFMEMORY
;
638 ASSERT(lpcDSBufferDesc
->dwBufferBytes
);
640 /* allocate sound buffer */
641 This
->Buffer
= HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc
->dwBufferBytes
);
644 /* not enough memory */
645 HeapFree(GetProcessHeap(), 0, This
->Format
);
646 HeapFree(GetProcessHeap(), 0, This
);
647 return DSERR_OUTOFMEMORY
;
650 /* fill buffer with silence */
651 FillMemory(This
->Buffer
, lpcDSBufferDesc
->dwBufferBytes
, lpcDSBufferDesc
->lpwfxFormat
->wBitsPerSample
== 8 ? 0x80 : 0);
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
;
664 This
->BufferSize
= lpcDSBufferDesc
->dwBufferBytes
;
665 This
->PrimaryBuffer
= PrimaryBuffer
;
667 CopyMemory(This
->Format
, lpcDSBufferDesc
->lpwfxFormat
, FormatSize
);
669 *OutBuffer
= (LPDIRECTSOUNDBUFFER8
)&This
->lpVtbl
;