- Merge from trunk up to r45543
[reactos.git] / dll / directx / dsound_new / primary.c
1 /*
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
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@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 LONG Volume;
23 LONG VolumePan;
24 WAVEFORMATEX Format;
25 HANDLE hPin;
26 CRITICAL_SECTION Lock;
27 KSSTATE State;
28 }CDirectSoundBuffer, *LPCDirectSoundBuffer;
29
30 HRESULT
31 WINAPI
32 PrimaryDirectSoundBuffer8Impl_fnQueryInterface(
33 LPDIRECTSOUNDBUFFER8 iface,
34 IN REFIID riid,
35 LPVOID* ppobj)
36 {
37 LPOLESTR pStr;
38 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
39
40 if (IsEqualIID(riid, &IID_IUnknown) ||
41 IsEqualIID(riid, &IID_IDirectSoundBuffer) ||
42 IsEqualIID(riid, &IID_IDirectSoundBuffer8))
43 {
44 *ppobj = (LPVOID)&This->lpVtbl;
45 InterlockedIncrement(&This->ref);
46 return S_OK;
47 }
48
49 if (SUCCEEDED(StringFromIID(riid, &pStr)))
50 {
51 DPRINT("No Interface for class %s\n", pStr);
52 CoTaskMemFree(pStr);
53 }
54 return E_NOINTERFACE;
55 }
56
57 ULONG
58 WINAPI
59 PrimaryDirectSoundBuffer8Impl_fnAddRef(
60 LPDIRECTSOUNDBUFFER8 iface)
61 {
62 ULONG ref;
63 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
64
65 ref = InterlockedIncrement(&This->ref);
66
67 return ref;
68
69 }
70
71 ULONG
72 WINAPI
73 PrimaryDirectSoundBuffer8Impl_fnRelease(
74 LPDIRECTSOUNDBUFFER8 iface)
75 {
76 ULONG ref;
77 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
78
79 ref = InterlockedDecrement(&(This->ref));
80
81 if (!ref)
82 {
83 if (This->hPin)
84 {
85 /* close pin handle */
86 CloseHandle(This->hPin);
87 }
88 /* free primary buffer */
89 HeapFree(GetProcessHeap(), 0, This);
90 }
91
92 return ref;
93 }
94
95 HRESULT
96 WINAPI
97 PrimaryDirectSoundBuffer8Impl_fnGetCaps(
98 LPDIRECTSOUNDBUFFER8 iface,
99 LPDSBCAPS pDSBufferCaps)
100 {
101 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
102
103 if (!pDSBufferCaps)
104 {
105 /* invalid parameter */
106 return DSERR_INVALIDPARAM;
107 }
108
109 if (pDSBufferCaps->dwSize < sizeof(DSBCAPS))
110 {
111 /* invalid buffer size */
112 return DSERR_INVALIDPARAM;
113 }
114
115 /* get buffer details */
116 pDSBufferCaps->dwUnlockTransferRate = 0;
117 pDSBufferCaps->dwPlayCpuOverhead = 0;
118 pDSBufferCaps->dwSize = 0; //FIXME
119 pDSBufferCaps->dwFlags = This->dwFlags;
120
121 return DS_OK;
122 }
123
124 HRESULT
125 WINAPI
126 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
127 LPDIRECTSOUNDBUFFER8 iface,
128 LPDWORD pdwCurrentPlayCursor,
129 LPDWORD pdwCurrentWriteCursor)
130 {
131 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
132
133 if (This->dwLevel < DSSCL_PRIORITY)
134 {
135 /* needs priority level */
136 return DSERR_PRIOLEVELNEEDED;
137 }
138
139 if (!pdwCurrentPlayCursor && !pdwCurrentWriteCursor)
140 {
141 /* all parameters are null */
142 return DSERR_INVALIDPARAM;
143 }
144
145 UNIMPLEMENTED;
146 return DSERR_INVALIDPARAM;
147 }
148
149 HRESULT
150 WINAPI
151 PrimaryDirectSoundBuffer8Impl_fnGetFormat(
152 LPDIRECTSOUNDBUFFER8 iface,
153 LPWAVEFORMATEX pwfxFormat,
154 DWORD dwSizeAllocated,
155 LPDWORD pdwSizeWritten)
156 {
157 DWORD FormatSize;
158 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
159
160 FormatSize = sizeof(WAVEFORMATEX) + This->Format.cbSize;
161
162 if (!pwfxFormat && !pdwSizeWritten)
163 {
164 /* invalid parameter */
165 return DSERR_INVALIDPARAM;
166 }
167
168 if (!pwfxFormat)
169 {
170 /* return required format size */
171 *pdwSizeWritten = FormatSize;
172 return DS_OK;
173 }
174 else
175 {
176 if (dwSizeAllocated >= FormatSize)
177 {
178 /* copy format */
179 CopyMemory(pwfxFormat, &This->Format, FormatSize);
180
181 if (pdwSizeWritten)
182 *pdwSizeWritten = FormatSize;
183
184 return DS_OK;
185 }
186 /* buffer too small */
187 if (pdwSizeWritten)
188 *pdwSizeWritten = 0;
189
190 return DSERR_INVALIDPARAM;
191 }
192 }
193
194 HRESULT
195 WINAPI
196 PrimaryDirectSoundBuffer8Impl_fnGetVolume(
197 LPDIRECTSOUNDBUFFER8 iface,
198 LPLONG plVolume)
199 {
200 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
201
202 if (!plVolume)
203 {
204 /* invalid parameter */
205 return DSERR_INVALIDPARAM;
206 }
207
208 /* get volume */
209 *plVolume = This->Volume;
210
211 return DS_OK;
212 }
213
214 HRESULT
215 WINAPI
216 PrimaryDirectSoundBuffer8Impl_fnGetPan(
217 LPDIRECTSOUNDBUFFER8 iface,
218 LPLONG plPan)
219 {
220 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
221
222 if (!plPan)
223 {
224 /* invalid parameter */
225 return DSERR_INVALIDPARAM;
226 }
227
228 /* get frequency */
229 *plPan = This->VolumePan;
230
231 return DS_OK;
232 }
233
234 HRESULT
235 WINAPI
236 PrimaryDirectSoundBuffer8Impl_fnGetFrequency(
237 LPDIRECTSOUNDBUFFER8 iface,
238 LPDWORD pdwFrequency)
239 {
240 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
241
242 if (!pdwFrequency)
243 {
244 /* invalid parameter */
245 return DSERR_INVALIDPARAM;
246 }
247
248 /* get frequency */
249 *pdwFrequency = This->dwFrequency;
250
251 return DS_OK;
252 }
253
254 HRESULT
255 WINAPI
256 PrimaryDirectSoundBuffer8Impl_fnGetStatus(
257 LPDIRECTSOUNDBUFFER8 iface,
258 LPDWORD pdwStatus)
259 {
260 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
261
262 if (!pdwStatus)
263 {
264 /* invalid parameter */
265 return DSERR_INVALIDPARAM;
266 }
267
268 *pdwStatus = 0;
269 if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE)
270 {
271 /* buffer is playing */
272 *pdwStatus |= DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;
273 }
274
275 return DS_OK;
276 }
277
278 HRESULT
279 WINAPI
280 PrimaryDirectSoundBuffer8Impl_fnInitialize(
281 LPDIRECTSOUNDBUFFER8 iface,
282 LPDIRECTSOUND pDirectSound,
283 LPCDSBUFFERDESC pcDSBufferDesc)
284 {
285 /* RTFM */
286 return DSERR_ALREADYINITIALIZED;
287 }
288
289 HRESULT
290 WINAPI
291 PrimaryDirectSoundBuffer8Impl_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 UNIMPLEMENTED
302 return DSERR_INVALIDPARAM;
303 }
304
305 HRESULT
306 WINAPI
307 PrimaryDirectSoundBuffer8Impl_fnPlay(
308 LPDIRECTSOUNDBUFFER8 iface,
309 DWORD dwReserved1,
310 DWORD dwPriority,
311 DWORD dwFlags)
312 {
313 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
314
315 if (dwReserved1 != 0 || !(dwFlags & DSBPLAY_LOOPING))
316 {
317 /* invalid parameter */
318 return DSERR_INVALIDPARAM;
319 }
320
321 PrimaryDirectSoundBuffer_AcquireLock(iface);
322
323 if (This->State == KSSTATE_STOP)
324 {
325 PrimaryDirectSoundBuffer_SetState(iface, KSSTATE_ACQUIRE);
326 ASSERT(This->State == KSSTATE_ACQUIRE);
327 }
328
329 if (This->State == KSSTATE_ACQUIRE)
330 {
331 PrimaryDirectSoundBuffer_SetState(iface, KSSTATE_PAUSE);
332 ASSERT(This->State == KSSTATE_PAUSE);
333 }
334
335 if (This->State == KSSTATE_PAUSE)
336 {
337 PrimaryDirectSoundBuffer_SetState(iface, KSSTATE_RUN);
338 ASSERT(This->State == KSSTATE_RUN);
339 }
340
341 PrimaryDirectSoundBuffer_ReleaseLock(iface);
342
343 return DS_OK;
344 }
345
346 HRESULT
347 WINAPI
348 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
349 LPDIRECTSOUNDBUFFER8 iface,
350 DWORD dwNewPosition)
351 {
352 /* The position of a primary buffer can't be set */
353 return DSERR_INVALIDCALL;
354 }
355
356 HRESULT
357 WINAPI
358 PrimaryDirectSoundBuffer8Impl_fnSetFormat(
359 LPDIRECTSOUNDBUFFER8 iface,
360 LPCWAVEFORMATEX pcfxFormat)
361 {
362 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
363
364 if (This->dwLevel == DSSCL_NORMAL)
365 {
366 /* can't change format with this level */
367 return DSERR_PRIOLEVELNEEDED;
368 }
369
370 ASSERT(pcfxFormat->cbSize == 0);
371
372
373 DPRINT("This %p Format: Tag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u nBlockAlign %u wBitsPerSample %u cbSize %u\n", This,
374 pcfxFormat->wFormatTag, pcfxFormat->nChannels, pcfxFormat->nSamplesPerSec, pcfxFormat->nAvgBytesPerSec, pcfxFormat->nBlockAlign, pcfxFormat->wBitsPerSample, pcfxFormat->cbSize);
375
376 CopyMemory(&This->Format, pcfxFormat, sizeof(WAVEFORMATEX));
377
378 return DS_OK;
379 }
380
381 HRESULT
382 WINAPI
383 PrimaryDirectSoundBuffer8Impl_fnSetVolume(
384 LPDIRECTSOUNDBUFFER8 iface,
385 LONG lVolume)
386 {
387 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
388
389 if (lVolume < DSBVOLUME_MIN || lVolume > DSBVOLUME_MAX)
390 {
391 /* invalid parameter */
392 return DSERR_INVALIDPARAM;
393 }
394
395 /* TODO: call volume node */
396
397 /* Store volume */
398 This->Volume = lVolume;
399
400 return DS_OK;
401 }
402
403 HRESULT
404 WINAPI
405 PrimaryDirectSoundBuffer8Impl_fnSetPan(
406 LPDIRECTSOUNDBUFFER8 iface,
407 LONG lPan)
408 {
409 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
410
411 if (lPan < DSBPAN_LEFT || lPan > DSBPAN_RIGHT)
412 {
413 /* invalid parameter */
414 return DSERR_INVALIDPARAM;
415 }
416
417 /* TODO: call volume node */
418
419 /* Store volume pan */
420 This->VolumePan = lPan;
421
422 return DS_OK;
423 }
424
425 HRESULT
426 WINAPI
427 PrimaryDirectSoundBuffer8Impl_fnSetFrequency(
428 LPDIRECTSOUNDBUFFER8 iface,
429 DWORD dwFrequency)
430 {
431 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
432
433 if (This->dwLevel < DSSCL_PRIORITY)
434 {
435 /* needs priority level */
436 return DSERR_PRIOLEVELNEEDED;
437 }
438
439 /* invalid request */
440 return DSERR_CONTROLUNAVAIL;
441 }
442
443 HRESULT
444 WINAPI
445 PrimaryDirectSoundBuffer8Impl_fnStop(
446 LPDIRECTSOUNDBUFFER8 iface)
447 {
448 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
449
450 PrimaryDirectSoundBuffer_AcquireLock(iface);
451
452 if (This->State == KSSTATE_RUN)
453 {
454 PrimaryDirectSoundBuffer_SetState(iface, KSSTATE_PAUSE);
455 ASSERT(This->State == KSSTATE_PAUSE);
456 }
457
458 if (This->State == KSSTATE_PAUSE)
459 {
460 PrimaryDirectSoundBuffer_SetState(iface, KSSTATE_ACQUIRE);
461 ASSERT(This->State == KSSTATE_ACQUIRE);
462 }
463
464 if (This->State == KSSTATE_ACQUIRE)
465 {
466 PrimaryDirectSoundBuffer_SetState(iface, KSSTATE_STOP);
467 ASSERT(This->State == KSSTATE_STOP);
468 }
469
470 PrimaryDirectSoundBuffer_ReleaseLock(iface);
471
472 return DS_OK;
473 }
474
475
476 HRESULT
477 WINAPI
478 PrimaryDirectSoundBuffer8Impl_fnUnlock(
479 LPDIRECTSOUNDBUFFER8 iface,
480 LPVOID pvAudioPtr1,
481 DWORD dwAudioBytes1,
482 LPVOID pvAudioPtr2,
483 DWORD dwAudioBytes2)
484 {
485 UNIMPLEMENTED
486 return DSERR_INVALIDPARAM;
487 }
488
489
490 HRESULT
491 WINAPI
492 PrimaryDirectSoundBuffer8Impl_fnRestore(
493 LPDIRECTSOUNDBUFFER8 iface)
494 {
495 UNIMPLEMENTED
496 return DSERR_INVALIDPARAM;
497 }
498
499
500 HRESULT
501 WINAPI
502 PrimaryDirectSoundBuffer8Impl_fnSetFX(
503 LPDIRECTSOUNDBUFFER8 iface,
504 DWORD dwEffectsCount,
505 LPDSEFFECTDESC pDSFXDesc,
506 LPDWORD pdwResultCodes)
507 {
508 UNIMPLEMENTED
509 return DSERR_INVALIDPARAM;
510 }
511
512 HRESULT
513 WINAPI
514 PrimaryDirectSoundBuffer8Impl_fnAcquireResources(
515 LPDIRECTSOUNDBUFFER8 iface,
516 DWORD dwFlags,
517 DWORD dwEffectsCount,
518 LPDWORD pdwResultCodes)
519 {
520 UNIMPLEMENTED
521 return DSERR_INVALIDPARAM;
522 }
523
524 HRESULT
525 WINAPI
526 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath(
527 LPDIRECTSOUNDBUFFER8 iface,
528 REFGUID rguidObject,
529 DWORD dwIndex,
530 REFGUID rguidInterface,
531 LPVOID *ppObject)
532 {
533 UNIMPLEMENTED
534 return DSERR_INVALIDPARAM;
535 }
536
537 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 =
538 {
539 /* IUnknown methods */
540 PrimaryDirectSoundBuffer8Impl_fnQueryInterface,
541 PrimaryDirectSoundBuffer8Impl_fnAddRef,
542 PrimaryDirectSoundBuffer8Impl_fnRelease,
543 /* IDirectSoundBuffer methods */
544 PrimaryDirectSoundBuffer8Impl_fnGetCaps,
545 PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition,
546 PrimaryDirectSoundBuffer8Impl_fnGetFormat,
547 PrimaryDirectSoundBuffer8Impl_fnGetVolume,
548 PrimaryDirectSoundBuffer8Impl_fnGetPan,
549 PrimaryDirectSoundBuffer8Impl_fnGetFrequency,
550 PrimaryDirectSoundBuffer8Impl_fnGetStatus,
551 PrimaryDirectSoundBuffer8Impl_fnInitialize,
552 PrimaryDirectSoundBuffer8Impl_fnLock,
553 PrimaryDirectSoundBuffer8Impl_fnPlay,
554 PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition,
555 PrimaryDirectSoundBuffer8Impl_fnSetFormat,
556 PrimaryDirectSoundBuffer8Impl_fnSetVolume,
557 PrimaryDirectSoundBuffer8Impl_fnSetPan,
558 PrimaryDirectSoundBuffer8Impl_fnSetFrequency,
559 PrimaryDirectSoundBuffer8Impl_fnStop,
560 PrimaryDirectSoundBuffer8Impl_fnUnlock,
561 PrimaryDirectSoundBuffer8Impl_fnRestore,
562 /* IDirectSoundBuffer8 methods */
563 PrimaryDirectSoundBuffer8Impl_fnSetFX,
564 PrimaryDirectSoundBuffer8Impl_fnAcquireResources,
565 PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath
566 };
567
568 DWORD
569 PrimaryDirectSoundBuffer_Write(
570 LPDIRECTSOUNDBUFFER8 iface,
571 LPVOID Buffer,
572 DWORD BufferSize)
573 {
574 KSSTREAM_HEADER Header;
575 DWORD Result, BytesTransferred;
576 OVERLAPPED Overlapped;
577
578 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
579
580 ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
581 Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
582
583
584 ASSERT(This->hPin);
585 ZeroMemory(&Header, sizeof(KSSTREAM_HEADER));
586
587 Header.FrameExtent = BufferSize;
588 Header.DataUsed = BufferSize;
589 Header.Data = Buffer;
590 Header.Size = sizeof(KSSTREAM_HEADER);
591 Header.PresentationTime.Numerator = 1;
592 Header.PresentationTime.Denominator = 1;
593
594 Result = DeviceIoControl(This->hPin, IOCTL_KS_WRITE_STREAM, NULL, 0, &Header, sizeof(KSSTREAM_HEADER), &BytesTransferred, &Overlapped);
595
596 if (Result != ERROR_SUCCESS)
597 return 0;
598
599 return BytesTransferred;
600 }
601
602 VOID
603 PrimaryDirectSoundBuffer_SetState(
604 LPDIRECTSOUNDBUFFER8 iface,
605 KSSTATE State)
606 {
607 KSPROPERTY Property;
608 DWORD Result, BytesTransferred;
609 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
610
611 if (This->State == State)
612 return;
613
614 Property.Set = KSPROPSETID_Connection;
615 Property.Id = KSPROPERTY_CONNECTION_STATE;
616 Property.Flags = KSPROPERTY_TYPE_SET;
617
618 Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesTransferred);
619 if (Result == ERROR_SUCCESS)
620 {
621 This->State = State;
622 }
623 }
624
625 HRESULT
626 PrimaryDirectSoundBuffer_GetPosition(
627 LPDIRECTSOUNDBUFFER8 iface,
628 LPDWORD pdwCurrentPlayCursor,
629 LPDWORD pdwCurrentWriteCursor)
630 {
631 KSAUDIO_POSITION Position;
632 KSPROPERTY Request;
633 DWORD Result;
634
635 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
636
637 if (!This->hPin)
638 {
639 if (pdwCurrentPlayCursor)
640 *pdwCurrentPlayCursor = 0;
641
642 if (pdwCurrentWriteCursor)
643 *pdwCurrentWriteCursor = 0;
644
645 DPRINT("No Audio Pin\n");
646 return DS_OK;
647 }
648
649 /* setup audio position property request */
650 Request.Id = KSPROPERTY_AUDIO_POSITION;
651 Request.Set = KSPROPSETID_Audio;
652 Request.Flags = KSPROPERTY_TYPE_GET;
653
654
655 Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSPROPERTY), (PVOID)&Position, sizeof(KSAUDIO_POSITION), NULL);
656
657 if (Result != ERROR_SUCCESS)
658 {
659 DPRINT("GetPosition failed with %x\n", Result);
660 return DSERR_UNSUPPORTED;
661 }
662
663 //DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset);
664
665 if (pdwCurrentPlayCursor)
666 *pdwCurrentPlayCursor = (DWORD)Position.PlayOffset;
667
668 if (pdwCurrentWriteCursor)
669 *pdwCurrentWriteCursor = (DWORD)Position.WriteOffset;
670
671 return DS_OK;
672 }
673
674 HRESULT
675 PrimaryDirectSoundBuffer_SetFormat(
676 LPDIRECTSOUNDBUFFER8 iface,
677 LPWAVEFORMATEX pcfxFormat,
678 BOOL bLooped)
679 {
680 ULONG PinId, DeviceId = 0, Result;
681 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
682
683 if (This->hPin)
684 {
685 // FIXME
686 // check if multiple buffers are active
687 // in that case need mixing
688
689 if (SetPinFormat(This->hPin, pcfxFormat))
690 return DS_OK;
691 else
692 return DSERR_GENERIC;
693 }
694
695 do
696 {
697 /* try all available recording pins on that filter */
698 PinId = GetPinIdFromFilter(This->Filter, FALSE, DeviceId);
699 DPRINT("PinId %u DeviceId %u\n", PinId, DeviceId);
700
701 if (PinId == ULONG_MAX)
702 break;
703
704 Result = OpenPin(This->Filter->hFilter, PinId, (LPWAVEFORMATEX)pcfxFormat, &This->hPin, bLooped);
705 DPRINT("PinId %u Result %u\n", PinId, Result);
706 if (Result == ERROR_SUCCESS)
707 {
708 This->dwFrequency = pcfxFormat->nSamplesPerSec;
709 break;
710 }
711
712 This->hPin = NULL;
713 DeviceId++;
714 }while(TRUE);
715
716 if (!This->hPin)
717 {
718 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat failed\n");
719 return DSERR_INVALIDPARAM;
720 }
721
722 DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat success\n");
723 return DS_OK;
724 }
725
726 VOID
727 PrimaryDirectSoundBuffer_AcquireLock(
728 LPDIRECTSOUNDBUFFER8 iface)
729 {
730 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
731
732 EnterCriticalSection(&This->Lock);
733
734
735 }
736
737 VOID
738 PrimaryDirectSoundBuffer_ReleaseLock(
739 LPDIRECTSOUNDBUFFER8 iface)
740 {
741 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
742
743 LeaveCriticalSection(&This->Lock);
744
745 }
746
747
748 HRESULT
749 NewPrimarySoundBuffer(
750 LPDIRECTSOUNDBUFFER8 *OutBuffer,
751 LPFILTERINFO Filter,
752 DWORD dwLevel,
753 DWORD dwFlags)
754 {
755 LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer));
756
757 if (!This)
758 {
759 /* not enough memory */
760 return DSERR_OUTOFMEMORY;
761 }
762
763 This->ref = 1;
764 This->lpVtbl = &vt_DirectSoundBuffer8;
765 This->Filter = Filter;
766 This->dwLevel = dwLevel;
767 This->dwFlags = dwFlags;
768 This->dwFrequency = 0;
769 This->Volume = DSBVOLUME_MAX;
770 This->VolumePan = DSBPAN_CENTER;
771 This->hPin = NULL;
772
773 InitializeCriticalSection(&This->Lock);
774
775 *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl;
776 return DS_OK;
777 }
778