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 (janderwald@reactos.org)
15 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
24 LPWAVEFORMATEX Format
;
32 LPDIRECTSOUNDBUFFER8 PrimaryBuffer
;
35 }CDirectSoundBuffer
, *LPCDirectSoundBuffer
;
39 SecondaryDirectSoundBuffer8Impl_fnQueryInterface(
40 LPDIRECTSOUNDBUFFER8 iface
,
45 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
47 if (IsEqualIID(riid
, &IID_IUnknown
) ||
48 IsEqualIID(riid
, &IID_IDirectSoundBuffer
) ||
49 IsEqualIID(riid
, &IID_IDirectSoundBuffer8
))
51 *ppobj
= (LPVOID
)&This
->lpVtbl
;
52 InterlockedIncrement(&This
->ref
);
56 if (SUCCEEDED(StringFromIID(riid
, &pStr
)))
58 DPRINT("No Interface for class %s\n", pStr
);
66 SecondaryDirectSoundBuffer8Impl_fnAddRef(
67 LPDIRECTSOUNDBUFFER8 iface
)
70 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
72 ref
= InterlockedIncrement(&This
->ref
);
80 SecondaryDirectSoundBuffer8Impl_fnRelease(
81 LPDIRECTSOUNDBUFFER8 iface
)
84 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
86 ref
= InterlockedDecrement(&(This
->ref
));
90 HeapFree(GetProcessHeap(), 0, This
->Buffer
);
91 HeapFree(GetProcessHeap(), 0, This
->Format
);
92 HeapFree(GetProcessHeap(), 0, This
);
100 SecondaryDirectSoundBuffer8Impl_fnGetCaps(
101 LPDIRECTSOUNDBUFFER8 iface
,
102 LPDSBCAPS pDSBufferCaps
)
104 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
108 /* invalid parameter */
109 return DSERR_INVALIDPARAM
;
112 if (pDSBufferCaps
->dwSize
< sizeof(DSBCAPS
))
114 /* invalid buffer size */
115 return DSERR_INVALIDPARAM
;
118 /* get buffer details */
119 pDSBufferCaps
->dwUnlockTransferRate
= 0;
120 pDSBufferCaps
->dwPlayCpuOverhead
= 0;
121 pDSBufferCaps
->dwSize
= This
->BufferSize
;
122 pDSBufferCaps
->dwFlags
= This
->dwFlags
;
129 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
130 LPDIRECTSOUNDBUFFER8 iface
,
131 LPDWORD pdwCurrentPlayCursor
,
132 LPDWORD pdwCurrentWriteCursor
)
134 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
136 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
138 return PrimaryDirectSoundBuffer_GetPosition(This
->PrimaryBuffer
, pdwCurrentPlayCursor
, pdwCurrentWriteCursor
);
143 SecondaryDirectSoundBuffer8Impl_fnGetFormat(
144 LPDIRECTSOUNDBUFFER8 iface
,
145 LPWAVEFORMATEX pwfxFormat
,
146 DWORD dwSizeAllocated
,
147 LPDWORD pdwSizeWritten
)
150 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
152 FormatSize
= sizeof(WAVEFORMATEX
) + This
->Format
->cbSize
;
154 if (!pwfxFormat
&& !pdwSizeWritten
)
156 /* invalid parameter */
157 return DSERR_INVALIDPARAM
;
162 /* return required format size */
163 *pdwSizeWritten
= FormatSize
;
168 if (dwSizeAllocated
>= FormatSize
)
171 CopyMemory(pwfxFormat
, This
->Format
, FormatSize
);
174 *pdwSizeWritten
= FormatSize
;
178 /* buffer too small */
182 return DSERR_INVALIDPARAM
;
188 SecondaryDirectSoundBuffer8Impl_fnGetVolume(
189 LPDIRECTSOUNDBUFFER8 iface
,
192 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
196 /* invalid parameter */
197 return DSERR_INVALIDPARAM
;
201 *plVolume
= This
->Volume
;
208 SecondaryDirectSoundBuffer8Impl_fnGetPan(
209 LPDIRECTSOUNDBUFFER8 iface
,
212 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
216 /* invalid parameter */
217 return DSERR_INVALIDPARAM
;
221 *plPan
= This
->VolumePan
;
228 SecondaryDirectSoundBuffer8Impl_fnGetFrequency(
229 LPDIRECTSOUNDBUFFER8 iface
,
230 LPDWORD pdwFrequency
)
232 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
236 /* invalid parameter */
237 return DSERR_INVALIDPARAM
;
241 *pdwFrequency
= This
->dwFrequency
;
248 SecondaryDirectSoundBuffer8Impl_fnGetStatus(
249 LPDIRECTSOUNDBUFFER8 iface
,
252 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
256 /* invalid parameter */
257 return DSERR_INVALIDPARAM
;
261 if (This
->State
== KSSTATE_RUN
|| This
->State
== KSSTATE_ACQUIRE
)
263 /* buffer is playing */
264 *pdwStatus
|= DSBSTATUS_PLAYING
;
265 if (This
->Flags
& DSBPLAY_LOOPING
)
266 *pdwStatus
|= DSBSTATUS_LOOPING
;
274 SecondaryDirectSoundBuffer8Impl_fnInitialize(
275 LPDIRECTSOUNDBUFFER8 iface
,
276 LPDIRECTSOUND pDirectSound
,
277 LPCDSBUFFERDESC pcDSBufferDesc
)
280 return DSERR_ALREADYINITIALIZED
;
285 SecondaryDirectSoundBuffer8Impl_fnLock(
286 LPDIRECTSOUNDBUFFER8 iface
,
289 LPVOID
*ppvAudioPtr1
,
290 LPDWORD pdwAudioBytes1
,
291 LPVOID
*ppvAudioPtr2
,
292 LPDWORD pdwAudioBytes2
,
295 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
297 DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n",
298 This
, dwOffset
, dwBytes
, ppvAudioPtr1
, pdwAudioBytes1
, ppvAudioPtr2
, pdwAudioBytes2
, dwFlags
, This
->BufferSize
);
300 if (dwFlags
== DSBLOCK_ENTIREBUFFER
)
302 *ppvAudioPtr1
= (LPVOID
)This
->Buffer
;
303 *pdwAudioBytes1
= This
->BufferSize
;
305 *ppvAudioPtr2
= NULL
;
311 else if (dwFlags
== DSBLOCK_FROMWRITECURSOR
)
314 return DSERR_UNSUPPORTED
;
318 ASSERT(dwOffset
< This
->BufferSize
);
319 ASSERT(dwBytes
<= This
->BufferSize
);
321 dwBytes
= min(This
->BufferSize
- dwOffset
, dwBytes
);
323 *ppvAudioPtr1
= This
->Buffer
+ dwOffset
;
324 *pdwAudioBytes1
= dwBytes
;
326 *ppvAudioPtr2
= NULL
;
336 SecondaryDirectSoundBuffer8Impl_fnPlay(
337 LPDIRECTSOUNDBUFFER8 iface
,
343 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
345 if (dwReserved1
!= 0)
348 return DSERR_INVALIDPARAM
;
352 ASSERT(dwFlags
& DSBPLAY_LOOPING
);
355 hResult
= PrimaryDirectSoundBuffer_SetFormat(This
->PrimaryBuffer
, This
->Format
, TRUE
);
357 if (!SUCCEEDED(hResult
))
360 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
);
364 /* start primary buffer */
365 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_RUN
);
366 /* acquire primary buffer */
367 PrimaryDirectSoundBuffer_AcquireLock(This
->PrimaryBuffer
);
368 /* HACK write buffer */
369 PrimaryDirectSoundBuffer_Write(This
->PrimaryBuffer
, This
->Buffer
, This
->BufferSize
);
370 /* release primary buffer */
371 PrimaryDirectSoundBuffer_ReleaseLock(This
->PrimaryBuffer
);
373 DPRINT("SetFormatSuccess PrimaryBuffer %p\n", This
->PrimaryBuffer
);
379 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
380 LPDIRECTSOUNDBUFFER8 iface
,
383 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
385 DPRINT("Setting position %u\n", dwNewPosition
);
386 This
->Position
= dwNewPosition
;
393 SecondaryDirectSoundBuffer8Impl_fnSetFormat(
394 LPDIRECTSOUNDBUFFER8 iface
,
395 LPCWAVEFORMATEX pcfxFormat
)
398 return DSERR_INVALIDCALL
;
403 SecondaryDirectSoundBuffer8Impl_fnSetVolume(
404 LPDIRECTSOUNDBUFFER8 iface
,
407 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
409 if (lVolume
< DSBVOLUME_MIN
|| lVolume
> DSBVOLUME_MAX
)
411 /* invalid parameter */
412 return DSERR_INVALIDPARAM
;
417 This
->Volume
= lVolume
;
424 SecondaryDirectSoundBuffer8Impl_fnSetPan(
425 LPDIRECTSOUNDBUFFER8 iface
,
428 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
430 if (lPan
< DSBPAN_LEFT
|| lPan
> DSBPAN_RIGHT
)
432 /* invalid parameter */
433 return DSERR_INVALIDPARAM
;
436 /* Store volume pan */
437 This
->VolumePan
= lPan
;
444 SecondaryDirectSoundBuffer8Impl_fnSetFrequency(
445 LPDIRECTSOUNDBUFFER8 iface
,
448 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
450 if (dwFrequency
== DSBFREQUENCY_ORIGINAL
)
452 /* restore original frequency */
453 dwFrequency
= This
->Format
->nSamplesPerSec
;
456 if (dwFrequency
< DSBFREQUENCY_MIN
|| dwFrequency
> DSBFREQUENCY_MAX
)
458 /* invalid frequency */
459 return DSERR_INVALIDPARAM
;
462 if (dwFrequency
!= This
->dwFrequency
)
464 /* FIXME handle frequency change */
467 /* store frequency */
468 This
->dwFrequency
= dwFrequency
;
475 SecondaryDirectSoundBuffer8Impl_fnStop(
476 LPDIRECTSOUNDBUFFER8 iface
)
478 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
480 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_PAUSE
);
481 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_ACQUIRE
);
482 PrimaryDirectSoundBuffer_SetState(This
->PrimaryBuffer
, KSSTATE_STOP
);
490 SecondaryDirectSoundBuffer8Impl_fnUnlock(
491 LPDIRECTSOUNDBUFFER8 iface
,
497 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n");
506 SecondaryDirectSoundBuffer8Impl_fnRestore(
507 LPDIRECTSOUNDBUFFER8 iface
)
510 return DSERR_INVALIDPARAM
;
516 SecondaryDirectSoundBuffer8Impl_fnSetFX(
517 LPDIRECTSOUNDBUFFER8 iface
,
518 DWORD dwEffectsCount
,
519 LPDSEFFECTDESC pDSFXDesc
,
520 LPDWORD pdwResultCodes
)
523 return DSERR_INVALIDPARAM
;
528 SecondaryDirectSoundBuffer8Impl_fnAcquireResources(
529 LPDIRECTSOUNDBUFFER8 iface
,
531 DWORD dwEffectsCount
,
532 LPDWORD pdwResultCodes
)
535 return DSERR_INVALIDPARAM
;
540 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(
541 LPDIRECTSOUNDBUFFER8 iface
,
544 REFGUID rguidInterface
,
548 return DSERR_INVALIDPARAM
;
551 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8
=
553 /* IUnknown methods */
554 SecondaryDirectSoundBuffer8Impl_fnQueryInterface
,
555 SecondaryDirectSoundBuffer8Impl_fnAddRef
,
556 SecondaryDirectSoundBuffer8Impl_fnRelease
,
557 /* IDirectSoundBuffer methods */
558 SecondaryDirectSoundBuffer8Impl_fnGetCaps
,
559 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition
,
560 SecondaryDirectSoundBuffer8Impl_fnGetFormat
,
561 SecondaryDirectSoundBuffer8Impl_fnGetVolume
,
562 SecondaryDirectSoundBuffer8Impl_fnGetPan
,
563 SecondaryDirectSoundBuffer8Impl_fnGetFrequency
,
564 SecondaryDirectSoundBuffer8Impl_fnGetStatus
,
565 SecondaryDirectSoundBuffer8Impl_fnInitialize
,
566 SecondaryDirectSoundBuffer8Impl_fnLock
,
567 SecondaryDirectSoundBuffer8Impl_fnPlay
,
568 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition
,
569 SecondaryDirectSoundBuffer8Impl_fnSetFormat
,
570 SecondaryDirectSoundBuffer8Impl_fnSetVolume
,
571 SecondaryDirectSoundBuffer8Impl_fnSetPan
,
572 SecondaryDirectSoundBuffer8Impl_fnSetFrequency
,
573 SecondaryDirectSoundBuffer8Impl_fnStop
,
574 SecondaryDirectSoundBuffer8Impl_fnUnlock
,
575 SecondaryDirectSoundBuffer8Impl_fnRestore
,
576 /* IDirectSoundBuffer8 methods */
577 SecondaryDirectSoundBuffer8Impl_fnSetFX
,
578 SecondaryDirectSoundBuffer8Impl_fnAcquireResources
,
579 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath
583 NewSecondarySoundBuffer(
584 LPDIRECTSOUNDBUFFER8
*OutBuffer
,
587 LPCDSBUFFERDESC lpcDSBufferDesc
,
588 LPDIRECTSOUNDBUFFER8 PrimaryBuffer
)
591 LPCDirectSoundBuffer This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundBuffer
));
595 /* not enough memory */
596 return DSERR_OUTOFMEMORY
;
599 FormatSize
= sizeof(WAVEFORMATEX
) + lpcDSBufferDesc
->lpwfxFormat
->cbSize
;
601 This
->Format
= HeapAlloc(GetProcessHeap(), 0, FormatSize
);
604 /* not enough memory */
605 HeapFree(GetProcessHeap(), 0, This
);
606 return DSERR_OUTOFMEMORY
;
610 ASSERT(lpcDSBufferDesc
->dwBufferBytes
);
612 /* allocate sound buffer */
613 This
->Buffer
= HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc
->dwBufferBytes
);
616 /* not enough memory */
617 HeapFree(GetProcessHeap(), 0, This
->Format
);
618 HeapFree(GetProcessHeap(), 0, This
);
619 return DSERR_OUTOFMEMORY
;
624 This
->lpVtbl
= &vt_DirectSoundBuffer8
;
625 This
->Filter
= Filter
;
626 This
->dwLevel
= dwLevel
;
627 This
->dwFlags
= lpcDSBufferDesc
->dwFlags
;
628 This
->dwFrequency
= lpcDSBufferDesc
->lpwfxFormat
->nSamplesPerSec
;
629 This
->State
= KSSTATE_STOP
;
630 This
->Volume
= DSBVOLUME_MAX
;
631 This
->VolumePan
= DSBPAN_CENTER
;
634 This
->BufferSize
= lpcDSBufferDesc
->dwBufferBytes
;
635 This
->PrimaryBuffer
= PrimaryBuffer
;
637 CopyMemory(This
->Format
, lpcDSBufferDesc
->lpwfxFormat
, FormatSize
);
639 *OutBuffer
= (LPDIRECTSOUNDBUFFER8
)&This
->lpVtbl
;