- Fix checking of flags found by Ged
[reactos.git] / reactos / dll / directx / dsound_new / secondary.c
1 /*
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
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 LPWAVEFORMATEX Format;
21 PUCHAR Buffer;
22 DWORD BufferSize;
23 KSSTATE State;
24 DWORD Flags;
25 DWORD Position;
26 DWORD PlayPosition;
27
28 LPDIRECTSOUNDBUFFER8 PrimaryBuffer;
29
30
31 }CDirectSoundBuffer, *LPCDirectSoundBuffer;
32
33 HRESULT
34 WINAPI
35 SecondaryDirectSoundBuffer8Impl_fnQueryInterface(
36 LPDIRECTSOUNDBUFFER8 iface,
37 IN REFIID riid,
38 LPVOID* ppobj)
39 {
40 LPOLESTR pStr;
41 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
42
43 if (IsEqualIID(riid, &IID_IUnknown) ||
44 IsEqualIID(riid, &IID_IDirectSoundBuffer) ||
45 IsEqualIID(riid, &IID_IDirectSoundBuffer8))
46 {
47 *ppobj = (LPVOID)&This->lpVtbl;
48 InterlockedIncrement(&This->ref);
49 return S_OK;
50 }
51
52 if (SUCCEEDED(StringFromIID(riid, &pStr)))
53 {
54 DPRINT("No Interface for class %s\n", pStr);
55 CoTaskMemFree(pStr);
56 }
57 return E_NOINTERFACE;
58 }
59
60 ULONG
61 WINAPI
62 SecondaryDirectSoundBuffer8Impl_fnAddRef(
63 LPDIRECTSOUNDBUFFER8 iface)
64 {
65 ULONG ref;
66 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
67
68 ref = InterlockedIncrement(&This->ref);
69
70 return ref;
71
72 }
73
74 ULONG
75 WINAPI
76 SecondaryDirectSoundBuffer8Impl_fnRelease(
77 LPDIRECTSOUNDBUFFER8 iface)
78 {
79 ULONG ref;
80 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
81
82 ref = InterlockedDecrement(&(This->ref));
83
84 if (!ref)
85 {
86 HeapFree(GetProcessHeap(), 0, This->Buffer);
87 HeapFree(GetProcessHeap(), 0, This->Format);
88 HeapFree(GetProcessHeap(), 0, This);
89 }
90
91 return ref;
92 }
93
94 HRESULT
95 WINAPI
96 SecondaryDirectSoundBuffer8Impl_fnGetCaps(
97 LPDIRECTSOUNDBUFFER8 iface,
98 LPDSBCAPS pDSBufferCaps)
99 {
100 UNIMPLEMENTED
101 return DSERR_INVALIDPARAM;
102 }
103
104 HRESULT
105 WINAPI
106 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
107 LPDIRECTSOUNDBUFFER8 iface,
108 LPDWORD pdwCurrentPlayCursor,
109 LPDWORD pdwCurrentWriteCursor)
110 {
111 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
112
113 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
114
115 return PrimaryDirectSoundBuffer_GetPosition(This->PrimaryBuffer, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
116 }
117
118 HRESULT
119 WINAPI
120 SecondaryDirectSoundBuffer8Impl_fnGetFormat(
121 LPDIRECTSOUNDBUFFER8 iface,
122 LPWAVEFORMATEX pwfxFormat,
123 DWORD dwSizeAllocated,
124 LPDWORD pdwSizeWritten)
125 {
126 DWORD FormatSize;
127 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
128
129 FormatSize = sizeof(WAVEFORMATEX) + This->Format->cbSize;
130
131 if (!pwfxFormat && !pdwSizeWritten)
132 {
133 /* invalid parameter */
134 return DSERR_INVALIDPARAM;
135 }
136
137 if (!pwfxFormat)
138 {
139 /* return required format size */
140 *pdwSizeWritten = FormatSize;
141 return DS_OK;
142 }
143 else
144 {
145 if (dwSizeAllocated >= FormatSize)
146 {
147 /* copy format */
148 CopyMemory(pwfxFormat, This->Format, FormatSize);
149
150 if (pdwSizeWritten)
151 *pdwSizeWritten = FormatSize;
152
153 return DS_OK;
154 }
155 /* buffer too small */
156 if (pdwSizeWritten)
157 *pdwSizeWritten = 0;
158
159 return DSERR_INVALIDPARAM;
160 }
161 }
162
163 HRESULT
164 WINAPI
165 SecondaryDirectSoundBuffer8Impl_fnGetVolume(
166 LPDIRECTSOUNDBUFFER8 iface,
167 LPLONG plVolume)
168 {
169 UNIMPLEMENTED
170 return DSERR_INVALIDPARAM;
171 }
172
173 HRESULT
174 WINAPI
175 SecondaryDirectSoundBuffer8Impl_fnGetPan(
176 LPDIRECTSOUNDBUFFER8 iface,
177 LPLONG plPan)
178 {
179 UNIMPLEMENTED
180 return DSERR_INVALIDPARAM;
181 }
182
183 HRESULT
184 WINAPI
185 SecondaryDirectSoundBuffer8Impl_fnGetFrequency(
186 LPDIRECTSOUNDBUFFER8 iface,
187 LPDWORD pdwFrequency)
188 {
189 UNIMPLEMENTED
190 return DSERR_INVALIDPARAM;
191 }
192
193 HRESULT
194 WINAPI
195 SecondaryDirectSoundBuffer8Impl_fnGetStatus(
196 LPDIRECTSOUNDBUFFER8 iface,
197 LPDWORD pdwStatus)
198 {
199 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
200
201 if (!pdwStatus)
202 {
203 /* invalid parameter */
204 return DSERR_INVALIDPARAM;
205 }
206
207 *pdwStatus = 0;
208 if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE)
209 {
210 /* buffer is playing */
211 *pdwStatus |= DSBSTATUS_PLAYING;
212 if (This->Flags & DSBPLAY_LOOPING)
213 *pdwStatus |= DSBSTATUS_LOOPING;
214 }
215
216 return DS_OK;
217 }
218
219 HRESULT
220 WINAPI
221 SecondaryDirectSoundBuffer8Impl_fnInitialize(
222 LPDIRECTSOUNDBUFFER8 iface,
223 LPDIRECTSOUND pDirectSound,
224 LPCDSBUFFERDESC pcDSBufferDesc)
225 {
226 UNIMPLEMENTED
227 return DSERR_INVALIDPARAM;
228 }
229
230 HRESULT
231 WINAPI
232 SecondaryDirectSoundBuffer8Impl_fnLock(
233 LPDIRECTSOUNDBUFFER8 iface,
234 DWORD dwOffset,
235 DWORD dwBytes,
236 LPVOID *ppvAudioPtr1,
237 LPDWORD pdwAudioBytes1,
238 LPVOID *ppvAudioPtr2,
239 LPDWORD pdwAudioBytes2,
240 DWORD dwFlags)
241 {
242 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
243
244 DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n",
245 This, dwOffset, dwBytes, ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2, dwFlags, This->BufferSize);
246
247 if (dwFlags == DSBLOCK_ENTIREBUFFER)
248 {
249 *ppvAudioPtr1 = (LPVOID)This->Buffer;
250 *pdwAudioBytes1 = This->BufferSize;
251 if (ppvAudioPtr2)
252 *ppvAudioPtr2 = NULL;
253 if (pdwAudioBytes2)
254 *pdwAudioBytes2 = 0;
255
256 return DS_OK;
257 }
258 else if (dwFlags == DSBLOCK_FROMWRITECURSOR)
259 {
260 UNIMPLEMENTED
261 return DSERR_UNSUPPORTED;
262 }
263 else
264 {
265 ASSERT(dwOffset < This->BufferSize);
266 ASSERT(dwBytes < This->BufferSize);
267 ASSERT(dwBytes + dwOffset <= This->BufferSize);
268
269 *ppvAudioPtr1 = This->Buffer + dwOffset;
270 *pdwAudioBytes1 = dwBytes;
271 if (ppvAudioPtr2)
272 *ppvAudioPtr2 = NULL;
273 if (pdwAudioBytes2)
274 *pdwAudioBytes2 = 0;
275
276 return DS_OK;
277 }
278 }
279
280 HRESULT
281 WINAPI
282 SecondaryDirectSoundBuffer8Impl_fnPlay(
283 LPDIRECTSOUNDBUFFER8 iface,
284 DWORD dwReserved1,
285 DWORD dwPriority,
286 DWORD dwFlags)
287 {
288 HRESULT hResult;
289 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
290
291 if (dwReserved1 != 0)
292 {
293 /* must be zero */
294 return DSERR_INVALIDPARAM;
295 }
296
297 DPRINT("SecondaryDirectSoundBuffer8Impl_fnPlay dwPriority %x dwFlags %x\n", dwPriority, dwFlags);
298 hResult = PrimaryDirectSoundBuffer_SetFormat(This->PrimaryBuffer, This->Format, (dwFlags & DSBPLAY_LOOPING));
299
300 DPRINT("Result %x\n", hResult);
301 if (!SUCCEEDED(hResult))
302 {
303 /* failed */
304 return hResult;
305 }
306
307 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_RUN);
308
309
310 PrimaryDirectSoundBuffer_AcquireLock(This->PrimaryBuffer);
311
312 PrimaryDirectSoundBuffer_Write(This->PrimaryBuffer, This->Buffer, This->BufferSize);
313
314 PrimaryDirectSoundBuffer_ReleaseLock(This->PrimaryBuffer);
315
316 return DS_OK;
317 }
318
319 HRESULT
320 WINAPI
321 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
322 LPDIRECTSOUNDBUFFER8 iface,
323 DWORD dwNewPosition)
324 {
325 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
326
327 DPRINT("Setting position %u\n", dwNewPosition);
328 This->Position = dwNewPosition;
329
330 return DS_OK;
331 }
332
333 HRESULT
334 WINAPI
335 SecondaryDirectSoundBuffer8Impl_fnSetFormat(
336 LPDIRECTSOUNDBUFFER8 iface,
337 LPCWAVEFORMATEX pcfxFormat)
338 {
339 return DSERR_INVALIDCALL;
340 }
341
342 HRESULT
343 WINAPI
344 SecondaryDirectSoundBuffer8Impl_fnSetVolume(
345 LPDIRECTSOUNDBUFFER8 iface,
346 LONG lVolume)
347 {
348 UNIMPLEMENTED
349 return DSERR_INVALIDPARAM;
350 }
351
352 HRESULT
353 WINAPI
354 SecondaryDirectSoundBuffer8Impl_fnSetPan(
355 LPDIRECTSOUNDBUFFER8 iface,
356 LONG lPan)
357 {
358 UNIMPLEMENTED
359 return DSERR_INVALIDPARAM;
360 }
361
362 HRESULT
363 WINAPI
364 SecondaryDirectSoundBuffer8Impl_fnSetFrequency(
365 LPDIRECTSOUNDBUFFER8 iface,
366 DWORD dwFrequency)
367 {
368 UNIMPLEMENTED
369 return DSERR_INVALIDPARAM;
370 }
371
372 HRESULT
373 WINAPI
374 SecondaryDirectSoundBuffer8Impl_fnStop(
375 LPDIRECTSOUNDBUFFER8 iface)
376 {
377 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
378
379 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_PAUSE);
380 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_ACQUIRE);
381 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_STOP);
382
383 return DS_OK;
384 }
385
386
387 HRESULT
388 WINAPI
389 SecondaryDirectSoundBuffer8Impl_fnUnlock(
390 LPDIRECTSOUNDBUFFER8 iface,
391 LPVOID pvAudioPtr1,
392 DWORD dwAudioBytes1,
393 LPVOID pvAudioPtr2,
394 DWORD dwAudioBytes2)
395 {
396 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n");
397 return DS_OK;
398 }
399
400
401
402
403 HRESULT
404 WINAPI
405 SecondaryDirectSoundBuffer8Impl_fnRestore(
406 LPDIRECTSOUNDBUFFER8 iface)
407 {
408 UNIMPLEMENTED
409 return DSERR_INVALIDPARAM;
410 }
411
412
413 HRESULT
414 WINAPI
415 SecondaryDirectSoundBuffer8Impl_fnSetFX(
416 LPDIRECTSOUNDBUFFER8 iface,
417 DWORD dwEffectsCount,
418 LPDSEFFECTDESC pDSFXDesc,
419 LPDWORD pdwResultCodes)
420 {
421 UNIMPLEMENTED
422 return DSERR_INVALIDPARAM;
423 }
424
425 HRESULT
426 WINAPI
427 SecondaryDirectSoundBuffer8Impl_fnAcquireResources(
428 LPDIRECTSOUNDBUFFER8 iface,
429 DWORD dwFlags,
430 DWORD dwEffectsCount,
431 LPDWORD pdwResultCodes)
432 {
433 UNIMPLEMENTED
434 return DSERR_INVALIDPARAM;
435 }
436
437 HRESULT
438 WINAPI
439 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(
440 LPDIRECTSOUNDBUFFER8 iface,
441 REFGUID rguidObject,
442 DWORD dwIndex,
443 REFGUID rguidInterface,
444 LPVOID *ppObject)
445 {
446 UNIMPLEMENTED
447 return DSERR_INVALIDPARAM;
448 }
449
450 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 =
451 {
452 /* IUnknown methods */
453 SecondaryDirectSoundBuffer8Impl_fnQueryInterface,
454 SecondaryDirectSoundBuffer8Impl_fnAddRef,
455 SecondaryDirectSoundBuffer8Impl_fnRelease,
456 /* IDirectSoundBuffer methods */
457 SecondaryDirectSoundBuffer8Impl_fnGetCaps,
458 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition,
459 SecondaryDirectSoundBuffer8Impl_fnGetFormat,
460 SecondaryDirectSoundBuffer8Impl_fnGetVolume,
461 SecondaryDirectSoundBuffer8Impl_fnGetPan,
462 SecondaryDirectSoundBuffer8Impl_fnGetFrequency,
463 SecondaryDirectSoundBuffer8Impl_fnGetStatus,
464 SecondaryDirectSoundBuffer8Impl_fnInitialize,
465 SecondaryDirectSoundBuffer8Impl_fnLock,
466 SecondaryDirectSoundBuffer8Impl_fnPlay,
467 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition,
468 SecondaryDirectSoundBuffer8Impl_fnSetFormat,
469 SecondaryDirectSoundBuffer8Impl_fnSetVolume,
470 SecondaryDirectSoundBuffer8Impl_fnSetPan,
471 SecondaryDirectSoundBuffer8Impl_fnSetFrequency,
472 SecondaryDirectSoundBuffer8Impl_fnStop,
473 SecondaryDirectSoundBuffer8Impl_fnUnlock,
474 SecondaryDirectSoundBuffer8Impl_fnRestore,
475 /* IDirectSoundBuffer8 methods */
476 SecondaryDirectSoundBuffer8Impl_fnSetFX,
477 SecondaryDirectSoundBuffer8Impl_fnAcquireResources,
478 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath
479 };
480
481 HRESULT
482 NewSecondarySoundBuffer(
483 LPDIRECTSOUNDBUFFER8 *OutBuffer,
484 LPFILTERINFO Filter,
485 DWORD dwLevel,
486 LPCDSBUFFERDESC lpcDSBufferDesc,
487 LPDIRECTSOUNDBUFFER8 PrimaryBuffer)
488 {
489 ULONG FormatSize;
490 LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer));
491
492 if (!This)
493 {
494 /* not enough memory */
495 return DSERR_OUTOFMEMORY;
496 }
497
498 FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize;
499
500 This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize);
501 if (!This->Format)
502 {
503 /* not enough memory */
504 HeapFree(GetProcessHeap(), 0, This);
505 return DSERR_OUTOFMEMORY;
506 }
507
508 /* sanity check */
509 ASSERT(lpcDSBufferDesc->dwBufferBytes);
510
511 /* allocate sound buffer */
512 This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes);
513 if (!This->Buffer)
514 {
515 /* not enough memory */
516 HeapFree(GetProcessHeap(), 0, This->Format);
517 HeapFree(GetProcessHeap(), 0, This);
518 return DSERR_OUTOFMEMORY;
519 }
520
521
522 This->ref = 1;
523 This->lpVtbl = &vt_DirectSoundBuffer8;
524 This->Filter = Filter;
525 This->dwLevel = dwLevel;
526 This->State = KSSTATE_STOP;
527 This->Flags = 0;
528 This->Position = 0;
529 This->BufferSize = lpcDSBufferDesc->dwBufferBytes;
530 This->PrimaryBuffer = PrimaryBuffer;
531
532 CopyMemory(This->Format, lpcDSBufferDesc->lpwfxFormat, FormatSize);
533
534 *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl;
535 return DS_OK;
536 }
537