xref: /reactos/dll/directx/dsound_new/secondary.c (revision 9393fc32)
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 (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     DWORD BufferPosition;
23     LONG Volume;
24     LONG VolumePan;
25     LPWAVEFORMATEX Format;
26     PUCHAR Buffer;
27     DWORD BufferSize;
28     KSSTATE State;
29     DWORD Flags;
30     DWORD Position;
31     DWORD PlayPosition;
32 
33     LPDIRECTSOUNDBUFFER8 PrimaryBuffer;
34 
35 
36 }CDirectSoundBuffer, *LPCDirectSoundBuffer;
37 
38 HRESULT
39 WINAPI
SecondaryDirectSoundBuffer8Impl_fnQueryInterface(LPDIRECTSOUNDBUFFER8 iface,IN REFIID riid,LPVOID * ppobj)40 SecondaryDirectSoundBuffer8Impl_fnQueryInterface(
41     LPDIRECTSOUNDBUFFER8 iface,
42     IN REFIID riid,
43     LPVOID* ppobj)
44 {
45     LPOLESTR pStr;
46     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
47 
48     if (IsEqualIID(riid, &IID_IUnknown) ||
49         IsEqualIID(riid, &IID_IDirectSoundBuffer) ||
50         IsEqualIID(riid, &IID_IDirectSoundBuffer8))
51     {
52         *ppobj = (LPVOID)&This->lpVtbl;
53         InterlockedIncrement(&This->ref);
54         return S_OK;
55     }
56 
57     if (SUCCEEDED(StringFromIID(riid, &pStr)))
58     {
59         DPRINT("No Interface for class %s\n", pStr);
60         CoTaskMemFree(pStr);
61     }
62     return E_NOINTERFACE;
63 }
64 
65 ULONG
66 WINAPI
SecondaryDirectSoundBuffer8Impl_fnAddRef(LPDIRECTSOUNDBUFFER8 iface)67 SecondaryDirectSoundBuffer8Impl_fnAddRef(
68     LPDIRECTSOUNDBUFFER8 iface)
69 {
70     ULONG ref;
71     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
72 
73     ref = InterlockedIncrement(&This->ref);
74 
75     return ref;
76 
77 }
78 
79 ULONG
80 WINAPI
SecondaryDirectSoundBuffer8Impl_fnRelease(LPDIRECTSOUNDBUFFER8 iface)81 SecondaryDirectSoundBuffer8Impl_fnRelease(
82     LPDIRECTSOUNDBUFFER8 iface)
83 {
84     ULONG ref;
85     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
86 
87     ref = InterlockedDecrement(&(This->ref));
88 
89     if (!ref)
90     {
91         HeapFree(GetProcessHeap(), 0, This->Buffer);
92         HeapFree(GetProcessHeap(), 0, This->Format);
93         HeapFree(GetProcessHeap(), 0, This);
94     }
95 
96     return ref;
97 }
98 
99 HRESULT
100 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetCaps(LPDIRECTSOUNDBUFFER8 iface,LPDSBCAPS pDSBufferCaps)101 SecondaryDirectSoundBuffer8Impl_fnGetCaps(
102     LPDIRECTSOUNDBUFFER8 iface,
103     LPDSBCAPS pDSBufferCaps)
104 {
105     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
106 
107     if (!pDSBufferCaps)
108     {
109         /* invalid parameter */
110         return DSERR_INVALIDPARAM;
111     }
112 
113     if (pDSBufferCaps->dwSize < sizeof(DSBCAPS))
114     {
115         /* invalid buffer size */
116         return DSERR_INVALIDPARAM;
117     }
118 
119     /* get buffer details */
120     pDSBufferCaps->dwUnlockTransferRate = 0;
121     pDSBufferCaps->dwPlayCpuOverhead = 0;
122     pDSBufferCaps->dwSize = This->BufferSize;
123     pDSBufferCaps->dwFlags = This->dwFlags;
124 
125     return DS_OK;
126 }
127 
128 HRESULT
129 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(LPDIRECTSOUNDBUFFER8 iface,LPDWORD pdwCurrentPlayCursor,LPDWORD pdwCurrentWriteCursor)130 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
131     LPDIRECTSOUNDBUFFER8 iface,
132     LPDWORD pdwCurrentPlayCursor,
133     LPDWORD pdwCurrentWriteCursor)
134 {
135     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
136 
137     //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
138 
139     if (pdwCurrentWriteCursor)
140     {
141         *pdwCurrentWriteCursor = This->BufferPosition;
142     }
143 
144     return PrimaryDirectSoundBuffer_GetPosition(This->PrimaryBuffer, pdwCurrentPlayCursor, NULL);
145 }
146 
147 HRESULT
148 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetFormat(LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX pwfxFormat,DWORD dwSizeAllocated,LPDWORD pdwSizeWritten)149 SecondaryDirectSoundBuffer8Impl_fnGetFormat(
150     LPDIRECTSOUNDBUFFER8 iface,
151     LPWAVEFORMATEX pwfxFormat,
152     DWORD dwSizeAllocated,
153     LPDWORD pdwSizeWritten)
154 {
155     DWORD FormatSize;
156     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
157 
158     FormatSize = sizeof(WAVEFORMATEX) + This->Format->cbSize;
159 
160     if (!pwfxFormat && !pdwSizeWritten)
161     {
162         /* invalid parameter */
163         return DSERR_INVALIDPARAM;
164     }
165 
166     if (!pwfxFormat)
167     {
168         /* return required format size */
169         *pdwSizeWritten = FormatSize;
170         return DS_OK;
171     }
172     else
173     {
174         if (dwSizeAllocated >= FormatSize)
175         {
176             /* copy format */
177             CopyMemory(pwfxFormat, This->Format, FormatSize);
178 
179             if (pdwSizeWritten)
180                 *pdwSizeWritten = FormatSize;
181 
182             return DS_OK;
183         }
184         /* buffer too small */
185         if (pdwSizeWritten)
186             *pdwSizeWritten = 0;
187 
188         return DSERR_INVALIDPARAM;
189     }
190 }
191 
192 HRESULT
193 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetVolume(LPDIRECTSOUNDBUFFER8 iface,LPLONG plVolume)194 SecondaryDirectSoundBuffer8Impl_fnGetVolume(
195     LPDIRECTSOUNDBUFFER8 iface,
196     LPLONG plVolume)
197 {
198     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
199 
200     if (!plVolume)
201     {
202         /* invalid parameter */
203         return DSERR_INVALIDPARAM;
204     }
205 
206     /* get volume */
207     *plVolume = This->Volume;
208 
209     return DS_OK;
210 }
211 
212 HRESULT
213 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetPan(LPDIRECTSOUNDBUFFER8 iface,LPLONG plPan)214 SecondaryDirectSoundBuffer8Impl_fnGetPan(
215     LPDIRECTSOUNDBUFFER8 iface,
216     LPLONG plPan)
217 {
218     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
219 
220     if (!plPan)
221     {
222         /* invalid parameter */
223         return DSERR_INVALIDPARAM;
224     }
225 
226     /* get frequency */
227     *plPan = This->VolumePan;
228 
229     return DS_OK;
230 }
231 
232 HRESULT
233 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetFrequency(LPDIRECTSOUNDBUFFER8 iface,LPDWORD pdwFrequency)234 SecondaryDirectSoundBuffer8Impl_fnGetFrequency(
235     LPDIRECTSOUNDBUFFER8 iface,
236     LPDWORD pdwFrequency)
237 {
238     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
239 
240     if (!pdwFrequency)
241     {
242         /* invalid parameter */
243         return DSERR_INVALIDPARAM;
244     }
245 
246     /* get frequency */
247     *pdwFrequency = This->dwFrequency;
248 
249     return DS_OK;
250 }
251 
252 HRESULT
253 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetStatus(LPDIRECTSOUNDBUFFER8 iface,LPDWORD pdwStatus)254 SecondaryDirectSoundBuffer8Impl_fnGetStatus(
255     LPDIRECTSOUNDBUFFER8 iface,
256     LPDWORD pdwStatus)
257 {
258     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
259 
260     if (!pdwStatus)
261     {
262         /* invalid parameter */
263         return DSERR_INVALIDPARAM;
264     }
265 
266     *pdwStatus = 0;
267     if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE)
268     {
269         /* buffer is playing */
270         *pdwStatus |= DSBSTATUS_PLAYING;
271         if (This->Flags & DSBPLAY_LOOPING)
272             *pdwStatus |= DSBSTATUS_LOOPING;
273     }
274 
275     return DS_OK;
276 }
277 
278 HRESULT
279 WINAPI
SecondaryDirectSoundBuffer8Impl_fnInitialize(LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND pDirectSound,LPCDSBUFFERDESC pcDSBufferDesc)280 SecondaryDirectSoundBuffer8Impl_fnInitialize(
281     LPDIRECTSOUNDBUFFER8 iface,
282     LPDIRECTSOUND pDirectSound,
283     LPCDSBUFFERDESC pcDSBufferDesc)
284 {
285     /* RTFM */
286     return DSERR_ALREADYINITIALIZED;
287 }
288 
289 HRESULT
290 WINAPI
SecondaryDirectSoundBuffer8Impl_fnLock(LPDIRECTSOUNDBUFFER8 iface,DWORD dwOffset,DWORD dwBytes,LPVOID * ppvAudioPtr1,LPDWORD pdwAudioBytes1,LPVOID * ppvAudioPtr2,LPDWORD pdwAudioBytes2,DWORD dwFlags)291 SecondaryDirectSoundBuffer8Impl_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     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
302 
303     DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n",
304            This, dwOffset, dwBytes, ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2, dwFlags, This->BufferSize);
305 
306     if (dwFlags == DSBLOCK_ENTIREBUFFER)
307     {
308         *ppvAudioPtr1 = (LPVOID)This->Buffer;
309         *pdwAudioBytes1 = This->BufferSize;
310         if (ppvAudioPtr2)
311             *ppvAudioPtr2 = NULL;
312         if (pdwAudioBytes2)
313             *pdwAudioBytes2 = 0;
314 
315         return DS_OK;
316     }
317     else if (dwFlags == DSBLOCK_FROMWRITECURSOR)
318     {
319         UNIMPLEMENTED;
320         return DSERR_UNSUPPORTED;
321     }
322     else
323     {
324         ASSERT(dwOffset < This->BufferSize);
325         ASSERT(dwBytes <= This->BufferSize);
326 
327         dwBytes = min(This->BufferSize - dwOffset, dwBytes);
328 
329         *ppvAudioPtr1 = This->Buffer + dwOffset;
330         *pdwAudioBytes1 = dwBytes;
331 
332         This->BufferPosition = dwOffset + dwBytes;
333 
334         if (This->BufferPosition == This->BufferSize)
335             This->BufferPosition = 0;
336 
337         if (ppvAudioPtr2)
338             *ppvAudioPtr2 = NULL;
339         if (pdwAudioBytes2)
340             *pdwAudioBytes2 = 0;
341 
342         return DS_OK;
343     }
344 }
345 
346 HRESULT
347 WINAPI
SecondaryDirectSoundBuffer8Impl_fnPlay(LPDIRECTSOUNDBUFFER8 iface,DWORD dwReserved1,DWORD dwPriority,DWORD dwFlags)348 SecondaryDirectSoundBuffer8Impl_fnPlay(
349     LPDIRECTSOUNDBUFFER8 iface,
350     DWORD dwReserved1,
351     DWORD dwPriority,
352     DWORD dwFlags)
353 {
354     HRESULT hResult;
355     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
356 
357     if (dwReserved1 != 0)
358     {
359         /* must be zero */
360         return DSERR_INVALIDPARAM;
361     }
362 
363     /* sanity check */
364     ASSERT(dwFlags & DSBPLAY_LOOPING);
365 
366 
367     if (This->State == KSSTATE_RUN)
368     {
369         /* sound buffer is already playing */
370         return DS_OK;
371     }
372 
373     /* set dataformat */
374     hResult = PrimaryDirectSoundBuffer_SetFormat(This->PrimaryBuffer, This->Format, TRUE);
375 
376     if (!SUCCEEDED(hResult))
377     {
378         /* failed */
379         DPRINT1("Failed to set format Tag %u Samples %u Bytes %u nChannels %u\n", This->Format->wFormatTag, This->Format->nSamplesPerSec, This->Format->wBitsPerSample, This->Format->nChannels);
380         return hResult;
381     }
382 
383     /* start primary buffer */
384     PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_RUN);
385     /* acquire primary buffer */
386     PrimaryDirectSoundBuffer_AcquireLock(This->PrimaryBuffer);
387     /* HACK write buffer */
388     PrimaryDirectSoundBuffer_Write(This->PrimaryBuffer, This->Buffer, This->BufferSize);
389     /* release primary buffer */
390     PrimaryDirectSoundBuffer_ReleaseLock(This->PrimaryBuffer);
391 
392     DPRINT("SetFormatSuccess PrimaryBuffer %p\n", This->PrimaryBuffer);
393     This->State = KSSTATE_RUN;
394 
395     return DS_OK;
396 }
397 
398 HRESULT
399 WINAPI
SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(LPDIRECTSOUNDBUFFER8 iface,DWORD dwNewPosition)400 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
401     LPDIRECTSOUNDBUFFER8 iface,
402     DWORD dwNewPosition)
403 {
404     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
405 
406     DPRINT("Setting position %u\n", dwNewPosition);
407     This->Position = dwNewPosition;
408 
409     return DS_OK;
410 }
411 
412 HRESULT
413 WINAPI
SecondaryDirectSoundBuffer8Impl_fnSetFormat(LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX pcfxFormat)414 SecondaryDirectSoundBuffer8Impl_fnSetFormat(
415     LPDIRECTSOUNDBUFFER8 iface,
416     LPCWAVEFORMATEX pcfxFormat)
417 {
418     /* RTFM */
419     return DSERR_INVALIDCALL;
420 }
421 
422 HRESULT
423 WINAPI
SecondaryDirectSoundBuffer8Impl_fnSetVolume(LPDIRECTSOUNDBUFFER8 iface,LONG lVolume)424 SecondaryDirectSoundBuffer8Impl_fnSetVolume(
425     LPDIRECTSOUNDBUFFER8 iface,
426     LONG lVolume)
427 {
428     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
429 
430     if (lVolume < DSBVOLUME_MIN || lVolume > DSBVOLUME_MAX)
431     {
432         /* invalid parameter */
433         return DSERR_INVALIDPARAM;
434     }
435 
436 
437     /* Store volume */
438     This->Volume = lVolume;
439 
440     return DS_OK;
441 }
442 
443 HRESULT
444 WINAPI
SecondaryDirectSoundBuffer8Impl_fnSetPan(LPDIRECTSOUNDBUFFER8 iface,LONG lPan)445 SecondaryDirectSoundBuffer8Impl_fnSetPan(
446     LPDIRECTSOUNDBUFFER8 iface,
447     LONG lPan)
448 {
449     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
450 
451     if (lPan < DSBPAN_LEFT || lPan > DSBPAN_RIGHT)
452     {
453         /* invalid parameter */
454         return DSERR_INVALIDPARAM;
455     }
456 
457     /* Store volume pan */
458     This->VolumePan = lPan;
459 
460     return DS_OK;
461 }
462 
463 HRESULT
464 WINAPI
SecondaryDirectSoundBuffer8Impl_fnSetFrequency(LPDIRECTSOUNDBUFFER8 iface,DWORD dwFrequency)465 SecondaryDirectSoundBuffer8Impl_fnSetFrequency(
466     LPDIRECTSOUNDBUFFER8 iface,
467     DWORD dwFrequency)
468 {
469     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
470 
471     if (dwFrequency == DSBFREQUENCY_ORIGINAL)
472     {
473         /* restore original frequency */
474         dwFrequency = This->Format->nSamplesPerSec;
475     }
476 
477     if (dwFrequency < DSBFREQUENCY_MIN || dwFrequency > DSBFREQUENCY_MAX)
478     {
479         /* invalid frequency */
480         return DSERR_INVALIDPARAM;
481     }
482 
483     if (dwFrequency != This->dwFrequency)
484     {
485         /* FIXME handle frequency change */
486     }
487 
488     /* store frequency */
489     This->dwFrequency = dwFrequency;
490 
491     return DS_OK;
492 }
493 
494 HRESULT
495 WINAPI
SecondaryDirectSoundBuffer8Impl_fnStop(LPDIRECTSOUNDBUFFER8 iface)496 SecondaryDirectSoundBuffer8Impl_fnStop(
497     LPDIRECTSOUNDBUFFER8 iface)
498 {
499     LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
500 
501     PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_PAUSE);
502     PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_ACQUIRE);
503     PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_STOP);
504 
505     DPRINT("SecondaryDirectSoundBuffer8Impl_fnStop\n");
506 
507 
508     /* set state to stop */
509     This->State = KSSTATE_STOP;
510     This->BufferPosition = 0;
511 
512     return DS_OK;
513 }
514 
515 
516 HRESULT
517 WINAPI
SecondaryDirectSoundBuffer8Impl_fnUnlock(LPDIRECTSOUNDBUFFER8 iface,LPVOID pvAudioPtr1,DWORD dwAudioBytes1,LPVOID pvAudioPtr2,DWORD dwAudioBytes2)518 SecondaryDirectSoundBuffer8Impl_fnUnlock(
519     LPDIRECTSOUNDBUFFER8 iface,
520     LPVOID pvAudioPtr1,
521     DWORD dwAudioBytes1,
522     LPVOID pvAudioPtr2,
523     DWORD dwAudioBytes2)
524 {
525     //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n");
526     return DS_OK;
527 }
528 
529 
530 
531 
532 HRESULT
533 WINAPI
SecondaryDirectSoundBuffer8Impl_fnRestore(LPDIRECTSOUNDBUFFER8 iface)534 SecondaryDirectSoundBuffer8Impl_fnRestore(
535     LPDIRECTSOUNDBUFFER8 iface)
536 {
537     UNIMPLEMENTED;
538     return DSERR_INVALIDPARAM;
539 }
540 
541 
542 HRESULT
543 WINAPI
SecondaryDirectSoundBuffer8Impl_fnSetFX(LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes)544 SecondaryDirectSoundBuffer8Impl_fnSetFX(
545     LPDIRECTSOUNDBUFFER8 iface,
546     DWORD dwEffectsCount,
547     LPDSEFFECTDESC pDSFXDesc,
548     LPDWORD pdwResultCodes)
549 {
550     UNIMPLEMENTED;
551     return DSERR_INVALIDPARAM;
552 }
553 
554 HRESULT
555 WINAPI
SecondaryDirectSoundBuffer8Impl_fnAcquireResources(LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes)556 SecondaryDirectSoundBuffer8Impl_fnAcquireResources(
557     LPDIRECTSOUNDBUFFER8 iface,
558     DWORD dwFlags,
559     DWORD dwEffectsCount,
560     LPDWORD pdwResultCodes)
561 {
562     UNIMPLEMENTED;
563     return DSERR_INVALIDPARAM;
564 }
565 
566 HRESULT
567 WINAPI
SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID * ppObject)568 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(
569     LPDIRECTSOUNDBUFFER8 iface,
570     REFGUID rguidObject,
571     DWORD dwIndex,
572     REFGUID rguidInterface,
573     LPVOID *ppObject)
574 {
575     UNIMPLEMENTED;
576     return DSERR_INVALIDPARAM;
577 }
578 
579 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 =
580 {
581     /* IUnknown methods */
582     SecondaryDirectSoundBuffer8Impl_fnQueryInterface,
583     SecondaryDirectSoundBuffer8Impl_fnAddRef,
584     SecondaryDirectSoundBuffer8Impl_fnRelease,
585     /* IDirectSoundBuffer methods */
586     SecondaryDirectSoundBuffer8Impl_fnGetCaps,
587     SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition,
588     SecondaryDirectSoundBuffer8Impl_fnGetFormat,
589     SecondaryDirectSoundBuffer8Impl_fnGetVolume,
590     SecondaryDirectSoundBuffer8Impl_fnGetPan,
591     SecondaryDirectSoundBuffer8Impl_fnGetFrequency,
592     SecondaryDirectSoundBuffer8Impl_fnGetStatus,
593     SecondaryDirectSoundBuffer8Impl_fnInitialize,
594     SecondaryDirectSoundBuffer8Impl_fnLock,
595     SecondaryDirectSoundBuffer8Impl_fnPlay,
596     SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition,
597     SecondaryDirectSoundBuffer8Impl_fnSetFormat,
598     SecondaryDirectSoundBuffer8Impl_fnSetVolume,
599     SecondaryDirectSoundBuffer8Impl_fnSetPan,
600     SecondaryDirectSoundBuffer8Impl_fnSetFrequency,
601     SecondaryDirectSoundBuffer8Impl_fnStop,
602     SecondaryDirectSoundBuffer8Impl_fnUnlock,
603     SecondaryDirectSoundBuffer8Impl_fnRestore,
604     /* IDirectSoundBuffer8 methods */
605     SecondaryDirectSoundBuffer8Impl_fnSetFX,
606     SecondaryDirectSoundBuffer8Impl_fnAcquireResources,
607     SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath
608 };
609 
610 HRESULT
NewSecondarySoundBuffer(LPDIRECTSOUNDBUFFER8 * OutBuffer,LPFILTERINFO Filter,DWORD dwLevel,LPCDSBUFFERDESC lpcDSBufferDesc,LPDIRECTSOUNDBUFFER8 PrimaryBuffer)611 NewSecondarySoundBuffer(
612     LPDIRECTSOUNDBUFFER8 *OutBuffer,
613     LPFILTERINFO Filter,
614     DWORD dwLevel,
615     LPCDSBUFFERDESC lpcDSBufferDesc,
616     LPDIRECTSOUNDBUFFER8 PrimaryBuffer)
617 {
618     ULONG FormatSize;
619     LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer));
620 
621     if (!This)
622     {
623         /* not enough memory */
624         return DSERR_OUTOFMEMORY;
625     }
626 
627     FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize;
628 
629     This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize);
630     if (!This->Format)
631     {
632         /* not enough memory */
633         HeapFree(GetProcessHeap(), 0, This);
634         return DSERR_OUTOFMEMORY;
635     }
636 
637     /* sanity check */
638     ASSERT(lpcDSBufferDesc->dwBufferBytes);
639 
640     /* allocate sound buffer */
641     This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes);
642     if (!This->Buffer)
643     {
644         /* not enough memory */
645         HeapFree(GetProcessHeap(), 0, This->Format);
646         HeapFree(GetProcessHeap(), 0, This);
647         return DSERR_OUTOFMEMORY;
648     }
649 
650     /* fill buffer with silence */
651     FillMemory(This->Buffer, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample == 8 ? 0x80 : 0);
652 
653     This->ref = 1;
654     This->lpVtbl = &vt_DirectSoundBuffer8;
655     This->Filter = Filter;
656     This->dwLevel = dwLevel;
657     This->dwFlags = lpcDSBufferDesc->dwFlags;
658     This->dwFrequency = lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec;
659     This->State = KSSTATE_STOP;
660     This->Volume = DSBVOLUME_MAX;
661     This->VolumePan = DSBPAN_CENTER;
662     This->Flags = 0;
663     This->Position = 0;
664     This->BufferSize = lpcDSBufferDesc->dwBufferBytes;
665     This->PrimaryBuffer = PrimaryBuffer;
666 
667     CopyMemory(This->Format, lpcDSBufferDesc->lpwfxFormat, FormatSize);
668 
669     *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl;
670     return DS_OK;
671 }
672 
673