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
));
81 /* close pin handle */
82 CloseHandle(This
->hPin
);
84 /* free primary buffer */
85 HeapFree(GetProcessHeap(), 0, This
);
93 PrimaryDirectSoundBuffer8Impl_fnGetCaps(
94 LPDIRECTSOUNDBUFFER8 iface
,
95 LPDSBCAPS pDSBufferCaps
)
98 return DSERR_INVALIDPARAM
;
103 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
104 LPDIRECTSOUNDBUFFER8 iface
,
105 LPDWORD pdwCurrentPlayCursor
,
106 LPDWORD pdwCurrentWriteCursor
)
109 return DSERR_INVALIDPARAM
;
114 PrimaryDirectSoundBuffer8Impl_fnGetFormat(
115 LPDIRECTSOUNDBUFFER8 iface
,
116 LPWAVEFORMATEX pwfxFormat
,
117 DWORD dwSizeAllocated
,
118 LPDWORD pdwSizeWritten
)
121 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
123 FormatSize
= sizeof(WAVEFORMATEX
) + This
->Format
.cbSize
;
125 if (!pwfxFormat
&& !pdwSizeWritten
)
127 /* invalid parameter */
128 return DSERR_INVALIDPARAM
;
133 /* return required format size */
134 *pdwSizeWritten
= FormatSize
;
139 if (dwSizeAllocated
>= FormatSize
)
142 CopyMemory(pwfxFormat
, &This
->Format
, FormatSize
);
145 *pdwSizeWritten
= FormatSize
;
149 /* buffer too small */
153 return DSERR_INVALIDPARAM
;
159 PrimaryDirectSoundBuffer8Impl_fnGetVolume(
160 LPDIRECTSOUNDBUFFER8 iface
,
164 return DSERR_INVALIDPARAM
;
169 PrimaryDirectSoundBuffer8Impl_fnGetPan(
170 LPDIRECTSOUNDBUFFER8 iface
,
174 return DSERR_INVALIDPARAM
;
179 PrimaryDirectSoundBuffer8Impl_fnGetFrequency(
180 LPDIRECTSOUNDBUFFER8 iface
,
181 LPDWORD pdwFrequency
)
184 return DSERR_INVALIDPARAM
;
189 PrimaryDirectSoundBuffer8Impl_fnGetStatus(
190 LPDIRECTSOUNDBUFFER8 iface
,
194 return DSERR_INVALIDPARAM
;
199 PrimaryDirectSoundBuffer8Impl_fnInitialize(
200 LPDIRECTSOUNDBUFFER8 iface
,
201 LPDIRECTSOUND pDirectSound
,
202 LPCDSBUFFERDESC pcDSBufferDesc
)
205 return DSERR_INVALIDPARAM
;
210 PrimaryDirectSoundBuffer8Impl_fnLock(
211 LPDIRECTSOUNDBUFFER8 iface
,
214 LPVOID
*ppvAudioPtr1
,
215 LPDWORD pdwAudioBytes1
,
216 LPVOID
*ppvAudioPtr2
,
217 LPDWORD pdwAudioBytes2
,
221 return DSERR_INVALIDPARAM
;
226 PrimaryDirectSoundBuffer8Impl_fnPlay(
227 LPDIRECTSOUNDBUFFER8 iface
,
233 return DSERR_INVALIDPARAM
;
238 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
239 LPDIRECTSOUNDBUFFER8 iface
,
243 return DSERR_INVALIDPARAM
;
248 PrimaryDirectSoundBuffer8Impl_fnSetFormat(
249 LPDIRECTSOUNDBUFFER8 iface
,
250 LPCWAVEFORMATEX pcfxFormat
)
252 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
254 if (This
->dwLevel
== DSSCL_NORMAL
)
256 /* can't change format with this level */
257 return DSERR_PRIOLEVELNEEDED
;
260 ASSERT(pcfxFormat
->cbSize
== 0);
263 DPRINT("This %p Format: Tag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u nBlockAlign %u wBitsPerSample %u cbSize %u\n", This
,
264 pcfxFormat
->wFormatTag
, pcfxFormat
->nChannels
, pcfxFormat
->nSamplesPerSec
, pcfxFormat
->nAvgBytesPerSec
, pcfxFormat
->nBlockAlign
, pcfxFormat
->wBitsPerSample
, pcfxFormat
->cbSize
);
266 CopyMemory(&This
->Format
, pcfxFormat
, sizeof(WAVEFORMATEX
));
273 PrimaryDirectSoundBuffer8Impl_fnSetVolume(
274 LPDIRECTSOUNDBUFFER8 iface
,
278 return DSERR_INVALIDPARAM
;
283 PrimaryDirectSoundBuffer8Impl_fnSetPan(
284 LPDIRECTSOUNDBUFFER8 iface
,
288 return DSERR_INVALIDPARAM
;
293 PrimaryDirectSoundBuffer8Impl_fnSetFrequency(
294 LPDIRECTSOUNDBUFFER8 iface
,
298 return DSERR_INVALIDPARAM
;
303 PrimaryDirectSoundBuffer8Impl_fnStop(
304 LPDIRECTSOUNDBUFFER8 iface
)
307 return DSERR_INVALIDPARAM
;
313 PrimaryDirectSoundBuffer8Impl_fnUnlock(
314 LPDIRECTSOUNDBUFFER8 iface
,
321 return DSERR_INVALIDPARAM
;
329 PrimaryDirectSoundBuffer8Impl_fnRestore(
330 LPDIRECTSOUNDBUFFER8 iface
)
333 return DSERR_INVALIDPARAM
;
339 PrimaryDirectSoundBuffer8Impl_fnSetFX(
340 LPDIRECTSOUNDBUFFER8 iface
,
341 DWORD dwEffectsCount
,
342 LPDSEFFECTDESC pDSFXDesc
,
343 LPDWORD pdwResultCodes
)
346 return DSERR_INVALIDPARAM
;
351 PrimaryDirectSoundBuffer8Impl_fnAcquireResources(
352 LPDIRECTSOUNDBUFFER8 iface
,
354 DWORD dwEffectsCount
,
355 LPDWORD pdwResultCodes
)
358 return DSERR_INVALIDPARAM
;
363 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath(
364 LPDIRECTSOUNDBUFFER8 iface
,
367 REFGUID rguidInterface
,
371 return DSERR_INVALIDPARAM
;
374 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8
=
376 /* IUnknown methods */
377 PrimaryDirectSoundBuffer8Impl_fnQueryInterface
,
378 PrimaryDirectSoundBuffer8Impl_fnAddRef
,
379 PrimaryDirectSoundBuffer8Impl_fnRelease
,
380 /* IDirectSoundBuffer methods */
381 PrimaryDirectSoundBuffer8Impl_fnGetCaps
,
382 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition
,
383 PrimaryDirectSoundBuffer8Impl_fnGetFormat
,
384 PrimaryDirectSoundBuffer8Impl_fnGetVolume
,
385 PrimaryDirectSoundBuffer8Impl_fnGetPan
,
386 PrimaryDirectSoundBuffer8Impl_fnGetFrequency
,
387 PrimaryDirectSoundBuffer8Impl_fnGetStatus
,
388 PrimaryDirectSoundBuffer8Impl_fnInitialize
,
389 PrimaryDirectSoundBuffer8Impl_fnLock
,
390 PrimaryDirectSoundBuffer8Impl_fnPlay
,
391 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition
,
392 PrimaryDirectSoundBuffer8Impl_fnSetFormat
,
393 PrimaryDirectSoundBuffer8Impl_fnSetVolume
,
394 PrimaryDirectSoundBuffer8Impl_fnSetPan
,
395 PrimaryDirectSoundBuffer8Impl_fnSetFrequency
,
396 PrimaryDirectSoundBuffer8Impl_fnStop
,
397 PrimaryDirectSoundBuffer8Impl_fnUnlock
,
398 PrimaryDirectSoundBuffer8Impl_fnRestore
,
399 /* IDirectSoundBuffer8 methods */
400 PrimaryDirectSoundBuffer8Impl_fnSetFX
,
401 PrimaryDirectSoundBuffer8Impl_fnAcquireResources
,
402 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath
406 PrimaryDirectSoundBuffer_Write(
407 LPDIRECTSOUNDBUFFER8 iface
,
411 KSSTREAM_HEADER Header
;
412 DWORD Result
, BytesTransferred
;
413 OVERLAPPED Overlapped
;
415 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
417 ZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
418 Overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
422 ZeroMemory(&Header
, sizeof(KSSTREAM_HEADER
));
424 Header
.FrameExtent
= BufferSize
;
425 Header
.DataUsed
= BufferSize
;
426 Header
.Data
= Buffer
;
427 Header
.Size
= sizeof(KSSTREAM_HEADER
);
428 Header
.PresentationTime
.Numerator
= 1;
429 Header
.PresentationTime
.Denominator
= 1;
431 Result
= DeviceIoControl(This
->hPin
, IOCTL_KS_WRITE_STREAM
, NULL
, 0, &Header
, sizeof(KSSTREAM_HEADER
), &BytesTransferred
, &Overlapped
);
433 if (Result
!= ERROR_SUCCESS
)
436 return BytesTransferred
;
440 PrimaryDirectSoundBuffer_SetState(
441 LPDIRECTSOUNDBUFFER8 iface
,
445 DWORD Result
, BytesTransferred
;
446 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
448 if (This
->State
== State
)
451 Property
.Set
= KSPROPSETID_Connection
;
452 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
453 Property
.Flags
= KSPROPERTY_TYPE_SET
;
455 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesTransferred
);
456 if (Result
== ERROR_SUCCESS
)
463 PrimaryDirectSoundBuffer_GetPosition(
464 LPDIRECTSOUNDBUFFER8 iface
,
465 LPDWORD pdwCurrentPlayCursor
,
466 LPDWORD pdwCurrentWriteCursor
)
468 KSAUDIO_POSITION Position
;
472 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
476 if (pdwCurrentPlayCursor
)
477 *pdwCurrentPlayCursor
= 0;
479 if (pdwCurrentWriteCursor
)
480 *pdwCurrentWriteCursor
= 0;
482 DPRINT("No Audio Pin\n");
486 /* setup audio position property request */
487 Request
.Id
= KSPROPERTY_AUDIO_POSITION
;
488 Request
.Set
= KSPROPSETID_Audio
;
489 Request
.Flags
= KSPROPERTY_TYPE_GET
;
492 Result
= SyncOverlappedDeviceIoControl(This
->hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Request
, sizeof(KSPROPERTY
), (PVOID
)&Position
, sizeof(KSAUDIO_POSITION
), NULL
);
494 if (Result
!= ERROR_SUCCESS
)
496 DPRINT("GetPosition failed with %x\n", Result
);
497 return DSERR_UNSUPPORTED
;
500 //DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset);
502 if (pdwCurrentPlayCursor
)
503 *pdwCurrentPlayCursor
= (DWORD
)Position
.PlayOffset
;
505 if (pdwCurrentWriteCursor
)
506 *pdwCurrentWriteCursor
= (DWORD
)Position
.WriteOffset
;
512 PrimaryDirectSoundBuffer_SetFormat(
513 LPDIRECTSOUNDBUFFER8 iface
,
514 LPWAVEFORMATEX pcfxFormat
,
517 ULONG PinId
, DeviceId
= 0, Result
;
518 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
522 /* fixme change format */
528 /* try all available recording pins on that filter */
529 PinId
= GetPinIdFromFilter(This
->Filter
, FALSE
, DeviceId
);
530 DPRINT("PinId %u DeviceId %u\n", PinId
, DeviceId
);
532 if (PinId
== ULONG_MAX
)
535 Result
= OpenPin(This
->Filter
->hFilter
, PinId
, (LPWAVEFORMATEX
)pcfxFormat
, &This
->hPin
, bLooped
);
536 DPRINT("PinId %u Result %u\n", PinId
, Result
);
537 if (Result
== ERROR_SUCCESS
)
546 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat failed\n");
547 return DSERR_INVALIDPARAM
;
550 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat success\n");
555 PrimaryDirectSoundBuffer_AcquireLock(
556 LPDIRECTSOUNDBUFFER8 iface
)
558 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
560 EnterCriticalSection(&This
->Lock
);
566 PrimaryDirectSoundBuffer_ReleaseLock(
567 LPDIRECTSOUNDBUFFER8 iface
)
569 LPCDirectSoundBuffer This
= (LPCDirectSoundBuffer
)CONTAINING_RECORD(iface
, CDirectSoundBuffer
, lpVtbl
);
571 LeaveCriticalSection(&This
->Lock
);
577 NewPrimarySoundBuffer(
578 LPDIRECTSOUNDBUFFER8
*OutBuffer
,
582 LPCDirectSoundBuffer This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundBuffer
));
586 /* not enough memory */
587 return DSERR_OUTOFMEMORY
;
591 This
->lpVtbl
= &vt_DirectSoundBuffer8
;
592 This
->Filter
= Filter
;
593 This
->dwLevel
= dwLevel
;
596 InitializeCriticalSection(&This
->Lock
);
598 *OutBuffer
= (LPDIRECTSOUNDBUFFER8
)&This
->lpVtbl
;