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 (janderwald@reactos.org)
15 const IDirectSoundBuffer8Vtbl
*lpVtbl
;
22 CRITICAL_SECTION Lock
;
24 }CDirectSoundBuffer
, *LPCDirectSoundBuffer
;
28 PrimaryDirectSoundBuffer8Impl_fnQueryInterface(
29 LPDIRECTSOUNDBUFFER8 iface
,
34 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
36 if (IsEqualIID(riid
, &IID_IUnknown
) ||
37 IsEqualIID(riid
, &IID_IDirectSoundBuffer
) ||
38 IsEqualIID(riid
, &IID_IDirectSoundBuffer8
))
40 *ppobj
= (LPVOID
)&This
->lpVtbl
;
41 InterlockedIncrement(&This
->ref
);
45 if (SUCCEEDED(StringFromIID(riid
, &pStr
)))
47 DPRINT("No Interface for class %s\n", pStr
);
55 PrimaryDirectSoundBuffer8Impl_fnAddRef(
56 LPDIRECTSOUNDBUFFER8 iface
)
59 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
61 ref
= InterlockedIncrement(&This
->ref
);
69 PrimaryDirectSoundBuffer8Impl_fnRelease(
70 LPDIRECTSOUNDBUFFER8 iface
)
73 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
75 ref
= InterlockedDecrement(&(This
->ref
));
79 HeapFree(GetProcessHeap(), 0, This
);
87 PrimaryDirectSoundBuffer8Impl_fnGetCaps(
88 LPDIRECTSOUNDBUFFER8 iface
,
89 LPDSBCAPS pDSBufferCaps
)
92 return DSERR_INVALIDPARAM
;
97 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
98 LPDIRECTSOUNDBUFFER8 iface
,
99 LPDWORD pdwCurrentPlayCursor
,
100 LPDWORD pdwCurrentWriteCursor
)
103 return DSERR_INVALIDPARAM
;
108 PrimaryDirectSoundBuffer8Impl_fnGetFormat(
109 LPDIRECTSOUNDBUFFER8 iface
,
110 LPWAVEFORMATEX pwfxFormat
,
111 DWORD dwSizeAllocated
,
112 LPDWORD pdwSizeWritten
)
115 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
117 FormatSize
= sizeof(WAVEFORMATEX
) + This
->Format
.cbSize
;
119 if (!pwfxFormat
&& !pdwSizeWritten
)
121 /* invalid parameter */
122 return DSERR_INVALIDPARAM
;
127 /* return required format size */
128 *pdwSizeWritten
= FormatSize
;
133 if (dwSizeAllocated
>= FormatSize
)
136 CopyMemory(pwfxFormat
, &This
->Format
, FormatSize
);
139 *pdwSizeWritten
= FormatSize
;
143 /* buffer too small */
147 return DSERR_INVALIDPARAM
;
153 PrimaryDirectSoundBuffer8Impl_fnGetVolume(
154 LPDIRECTSOUNDBUFFER8 iface
,
158 return DSERR_INVALIDPARAM
;
163 PrimaryDirectSoundBuffer8Impl_fnGetPan(
164 LPDIRECTSOUNDBUFFER8 iface
,
168 return DSERR_INVALIDPARAM
;
173 PrimaryDirectSoundBuffer8Impl_fnGetFrequency(
174 LPDIRECTSOUNDBUFFER8 iface
,
175 LPDWORD pdwFrequency
)
178 return DSERR_INVALIDPARAM
;
183 PrimaryDirectSoundBuffer8Impl_fnGetStatus(
184 LPDIRECTSOUNDBUFFER8 iface
,
188 return DSERR_INVALIDPARAM
;
193 PrimaryDirectSoundBuffer8Impl_fnInitialize(
194 LPDIRECTSOUNDBUFFER8 iface
,
195 LPDIRECTSOUND pDirectSound
,
196 LPCDSBUFFERDESC pcDSBufferDesc
)
199 return DSERR_INVALIDPARAM
;
204 PrimaryDirectSoundBuffer8Impl_fnLock(
205 LPDIRECTSOUNDBUFFER8 iface
,
208 LPVOID
*ppvAudioPtr1
,
209 LPDWORD pdwAudioBytes1
,
210 LPVOID
*ppvAudioPtr2
,
211 LPDWORD pdwAudioBytes2
,
215 return DSERR_INVALIDPARAM
;
220 PrimaryDirectSoundBuffer8Impl_fnPlay(
221 LPDIRECTSOUNDBUFFER8 iface
,
227 return DSERR_INVALIDPARAM
;
232 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
233 LPDIRECTSOUNDBUFFER8 iface
,
237 return DSERR_INVALIDPARAM
;
242 PrimaryDirectSoundBuffer8Impl_fnSetFormat(
243 LPDIRECTSOUNDBUFFER8 iface
,
244 LPCWAVEFORMATEX pcfxFormat
)
246 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
248 if (This
->dwLevel
== DSSCL_NORMAL
)
250 /* can't change format with this level */
251 return DSERR_PRIOLEVELNEEDED
;
254 ASSERT(pcfxFormat
->cbSize
== 0);
257 DPRINT("This %p Format: Tag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u nBlockAlign %u wBitsPerSample %u cbSize %u\n", This
,
258 pcfxFormat
->wFormatTag
, pcfxFormat
->nChannels
, pcfxFormat
->nSamplesPerSec
, pcfxFormat
->nAvgBytesPerSec
, pcfxFormat
->nBlockAlign
, pcfxFormat
->wBitsPerSample
, pcfxFormat
->cbSize
);
260 CopyMemory(&This
->Format
, pcfxFormat
, sizeof(WAVEFORMATEX
));
267 PrimaryDirectSoundBuffer8Impl_fnSetVolume(
268 LPDIRECTSOUNDBUFFER8 iface
,
272 return DSERR_INVALIDPARAM
;
277 PrimaryDirectSoundBuffer8Impl_fnSetPan(
278 LPDIRECTSOUNDBUFFER8 iface
,
282 return DSERR_INVALIDPARAM
;
287 PrimaryDirectSoundBuffer8Impl_fnSetFrequency(
288 LPDIRECTSOUNDBUFFER8 iface
,
292 return DSERR_INVALIDPARAM
;
297 PrimaryDirectSoundBuffer8Impl_fnStop(
298 LPDIRECTSOUNDBUFFER8 iface
)
301 return DSERR_INVALIDPARAM
;
307 PrimaryDirectSoundBuffer8Impl_fnUnlock(
308 LPDIRECTSOUNDBUFFER8 iface
,
315 return DSERR_INVALIDPARAM
;
323 PrimaryDirectSoundBuffer8Impl_fnRestore(
324 LPDIRECTSOUNDBUFFER8 iface
)
327 return DSERR_INVALIDPARAM
;
333 PrimaryDirectSoundBuffer8Impl_fnSetFX(
334 LPDIRECTSOUNDBUFFER8 iface
,
335 DWORD dwEffectsCount
,
336 LPDSEFFECTDESC pDSFXDesc
,
337 LPDWORD pdwResultCodes
)
340 return DSERR_INVALIDPARAM
;
345 PrimaryDirectSoundBuffer8Impl_fnAcquireResources(
346 LPDIRECTSOUNDBUFFER8 iface
,
348 DWORD dwEffectsCount
,
349 LPDWORD pdwResultCodes
)
352 return DSERR_INVALIDPARAM
;
357 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath(
358 LPDIRECTSOUNDBUFFER8 iface
,
361 REFGUID rguidInterface
,
365 return DSERR_INVALIDPARAM
;
368 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8
=
370 /* IUnknown methods */
371 PrimaryDirectSoundBuffer8Impl_fnQueryInterface
,
372 PrimaryDirectSoundBuffer8Impl_fnAddRef
,
373 PrimaryDirectSoundBuffer8Impl_fnRelease
,
374 /* IDirectSoundBuffer methods */
375 PrimaryDirectSoundBuffer8Impl_fnGetCaps
,
376 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition
,
377 PrimaryDirectSoundBuffer8Impl_fnGetFormat
,
378 PrimaryDirectSoundBuffer8Impl_fnGetVolume
,
379 PrimaryDirectSoundBuffer8Impl_fnGetPan
,
380 PrimaryDirectSoundBuffer8Impl_fnGetFrequency
,
381 PrimaryDirectSoundBuffer8Impl_fnGetStatus
,
382 PrimaryDirectSoundBuffer8Impl_fnInitialize
,
383 PrimaryDirectSoundBuffer8Impl_fnLock
,
384 PrimaryDirectSoundBuffer8Impl_fnPlay
,
385 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition
,
386 PrimaryDirectSoundBuffer8Impl_fnSetFormat
,
387 PrimaryDirectSoundBuffer8Impl_fnSetVolume
,
388 PrimaryDirectSoundBuffer8Impl_fnSetPan
,
389 PrimaryDirectSoundBuffer8Impl_fnSetFrequency
,
390 PrimaryDirectSoundBuffer8Impl_fnStop
,
391 PrimaryDirectSoundBuffer8Impl_fnUnlock
,
392 PrimaryDirectSoundBuffer8Impl_fnRestore
,
393 /* IDirectSoundBuffer8 methods */
394 PrimaryDirectSoundBuffer8Impl_fnSetFX
,
395 PrimaryDirectSoundBuffer8Impl_fnAcquireResources
,
396 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath
400 PrimaryDirectSoundBuffer_Write(
401 LPDIRECTSOUNDBUFFER8 iface
,
405 KSSTREAM_HEADER Header
;
406 DWORD Result
, BytesTransferred
;
407 OVERLAPPED Overlapped
;
409 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
411 ZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
412 Overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
416 ZeroMemory(&Header
, sizeof(KSSTREAM_HEADER
));
418 Header
.FrameExtent
= BufferSize
;
419 Header
.DataUsed
= BufferSize
;
420 Header
.Data
= Buffer
;
421 Header
.Size
= sizeof(KSSTREAM_HEADER
);
422 Header
.PresentationTime
.Numerator
= 1;
423 Header
.PresentationTime
.Denominator
= 1;
425 Result
= DeviceIoControl(This
->hPin
, IOCTL_KS_WRITE_STREAM
, NULL
, 0, &Header
, sizeof(KSSTREAM_HEADER
), &BytesTransferred
, &Overlapped
);
427 if (Result
!= ERROR_SUCCESS
)
430 return BytesTransferred
;
434 PrimaryDirectSoundBuffer_SetState(
435 LPDIRECTSOUNDBUFFER8 iface
,
439 DWORD Result
, BytesTransferred
;
440 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
442 if (This
->State
== State
)
445 Property
.Set
= KSPROPSETID_Connection
;
446 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
447 Property
.Flags
= KSPROPERTY_TYPE_SET
;
449 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesTransferred
);
450 if (Result
== ERROR_SUCCESS
)
457 PrimaryDirectSoundBuffer_GetPosition(
458 LPDIRECTSOUNDBUFFER8 iface
,
459 LPDWORD pdwCurrentPlayCursor
,
460 LPDWORD pdwCurrentWriteCursor
)
462 KSAUDIO_POSITION Position
;
466 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
470 if (pdwCurrentPlayCursor
)
471 *pdwCurrentPlayCursor
= 0;
473 if (pdwCurrentWriteCursor
)
474 *pdwCurrentWriteCursor
= 0;
476 DPRINT("No Audio Pin\n");
480 /* setup audio position property request */
481 Request
.Id
= KSPROPERTY_AUDIO_POSITION
;
482 Request
.Set
= KSPROPSETID_Audio
;
483 Request
.Flags
= KSPROPERTY_TYPE_GET
;
486 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Request
, sizeof(KSPROPERTY
), (PVOID
)&Position
, sizeof(KSAUDIO_POSITION
), NULL
);
488 if (Result
!= ERROR_SUCCESS
)
490 DPRINT("GetPosition failed with %x\n", Result
);
491 return DSERR_UNSUPPORTED
;
494 //DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset);
496 if (pdwCurrentPlayCursor
)
497 *pdwCurrentPlayCursor
= (DWORD
)Position
.PlayOffset
;
499 if (pdwCurrentWriteCursor
)
500 *pdwCurrentWriteCursor
= (DWORD
)Position
.WriteOffset
;
506 PrimaryDirectSoundBuffer_SetFormat(
507 LPDIRECTSOUNDBUFFER8 iface
,
508 LPWAVEFORMATEX pcfxFormat
,
511 ULONG PinId
, DeviceId
= 0, Result
;
512 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
516 /* fixme change format */
522 /* try all available recording pins on that filter */
523 PinId
= GetPinIdFromFilter(This
->Filter
, FALSE
, DeviceId
);
524 DPRINT("PinId %u DeviceId %u\n", PinId
, DeviceId
);
526 if (PinId
== ULONG_MAX
)
529 Result
= OpenPin(This
->Filter
->hFilter
, PinId
, (LPWAVEFORMATEX
)pcfxFormat
, &This
->hPin
, bLooped
);
530 DPRINT("PinId %u Result %u\n", PinId
, Result
);
531 if (Result
== ERROR_SUCCESS
)
540 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat failed\n");
541 return DSERR_INVALIDPARAM
;
544 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat success\n");
549 PrimaryDirectSoundBuffer_AcquireLock(
550 LPDIRECTSOUNDBUFFER8 iface
)
552 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
554 EnterCriticalSection(&This
->Lock
);
560 PrimaryDirectSoundBuffer_ReleaseLock(
561 LPDIRECTSOUNDBUFFER8 iface
)
563 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
565 LeaveCriticalSection(&This
->Lock
);
571 NewPrimarySoundBuffer(
572 LPDIRECTSOUNDBUFFER8
*OutBuffer
,
576 LPCDirectSoundBuffer This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundBuffer
));
580 /* not enough memory */
581 return DSERR_OUTOFMEMORY
;
585 This
->lpVtbl
= &vt_DirectSoundBuffer8
;
586 This
->Filter
= Filter
;
587 This
->dwLevel
= dwLevel
;
590 InitializeCriticalSection(&This
->Lock
);
592 *OutBuffer
= (LPDIRECTSOUNDBUFFER8
)&This
->lpVtbl
;