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