2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/directsound.c
5 * PURPOSE: Handles IDirectSound interface
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
14 IDirectSound8Vtbl
*lpVtbl
;
21 LPDIRECTSOUNDBUFFER8 PrimaryBuffer
;
24 }CDirectSoundImpl
, *LPCDirectSoundImpl
;
28 IDirectSound8_fnQueryInterface(
34 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
36 if ((IsEqualIID(riid
, &IID_IDirectSound
) && This
->bDirectSound8
== FALSE
) ||
37 (IsEqualIID(riid
, &IID_IDirectSound8
) && This
->bDirectSound8
!= FALSE
) ||
38 (IsEqualIID(riid
, &IID_IUnknown
)))
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 IDirectSound8_fnAddRef(
59 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
61 ref
= InterlockedIncrement(&This
->ref
);
68 IDirectSound8_fnRelease(
72 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
74 ref
= InterlockedDecrement(&(This
->ref
));
78 HeapFree(GetProcessHeap(), 0, This
);
86 IDirectSound8_fnCreateSoundBuffer(
88 LPCDSBUFFERDESC lpcDSBufferDesc
,
89 LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer
,
90 IUnknown FAR
* pUnkOuter
)
93 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
95 if (!This
->bInitialized
)
97 /* object not yet initialized */
98 return DSERR_UNINITIALIZED
;
101 if (!lpcDSBufferDesc
|| !lplpDirectSoundBuffer
|| pUnkOuter
!= NULL
)
103 DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc
, lplpDirectSoundBuffer
, pUnkOuter
);
104 return DSERR_INVALIDPARAM
;
107 /* check buffer description */
108 if ((lpcDSBufferDesc
->dwSize
!= sizeof(DSBUFFERDESC
) && lpcDSBufferDesc
->dwSize
!= sizeof(DSBUFFERDESC1
)) || lpcDSBufferDesc
->dwReserved
!= 0)
110 DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc
->dwSize
, sizeof(DSBUFFERDESC1
), lpcDSBufferDesc
->dwReserved
);
111 return DSERR_INVALIDPARAM
;
114 DPRINT("This %p dwFlags %x dwBufferBytes %u lpwfxFormat %p dwSize %u\n", This
, lpcDSBufferDesc
->dwFlags
, lpcDSBufferDesc
->dwBufferBytes
, lpcDSBufferDesc
->lpwfxFormat
, lpcDSBufferDesc
->dwSize
);
116 if (lpcDSBufferDesc
->dwFlags
& DSBCAPS_PRIMARYBUFFER
)
118 if (lpcDSBufferDesc
->lpwfxFormat
!= NULL
)
120 /* format must be null for primary sound buffer */
121 return DSERR_INVALIDPARAM
;
124 if (lpcDSBufferDesc
->dwBufferBytes
!= 0)
126 /* buffer size must be zero for primary sound buffer */
127 return DSERR_INVALIDPARAM
;
130 if (This
->PrimaryBuffer
)
132 /* primary buffer already exists */
133 IDirectSoundBuffer8_AddRef(This
->PrimaryBuffer
);
134 *lplpDirectSoundBuffer
= (LPDIRECTSOUNDBUFFER
)This
->PrimaryBuffer
;
138 hResult
= NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8
)lplpDirectSoundBuffer
, This
->Filter
, This
->dwLevel
, lpcDSBufferDesc
->dwFlags
);
139 if (SUCCEEDED(hResult
))
141 /* store primary buffer */
142 This
->PrimaryBuffer
= (LPDIRECTSOUNDBUFFER8
)*lplpDirectSoundBuffer
;
148 if (lpcDSBufferDesc
->lpwfxFormat
== NULL
)
150 /* format must not be null */
151 return DSERR_INVALIDPARAM
;
154 if (lpcDSBufferDesc
->dwBufferBytes
< DSBSIZE_MIN
|| lpcDSBufferDesc
->dwBufferBytes
> DSBSIZE_MAX
)
156 /* buffer size must be within bounds for secondary sound buffer*/
157 return DSERR_INVALIDPARAM
;
160 if (!This
->PrimaryBuffer
)
162 hResult
= NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8
)lplpDirectSoundBuffer
, This
->Filter
, This
->dwLevel
, lpcDSBufferDesc
->dwFlags
);
163 if (SUCCEEDED(hResult
))
165 /* store primary buffer */
166 This
->PrimaryBuffer
= (LPDIRECTSOUNDBUFFER8
)*lplpDirectSoundBuffer
;
170 DPRINT("Failed to create primary buffer with %x\n", hResult
);
176 ASSERT(This
->PrimaryBuffer
);
178 DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
179 This
, lpcDSBufferDesc
->lpwfxFormat
->wFormatTag
, lpcDSBufferDesc
->lpwfxFormat
->nChannels
, lpcDSBufferDesc
->lpwfxFormat
->nSamplesPerSec
, lpcDSBufferDesc
->lpwfxFormat
->nAvgBytesPerSec
, lpcDSBufferDesc
->lpwfxFormat
->nBlockAlign
, lpcDSBufferDesc
->lpwfxFormat
->wBitsPerSample
, lpcDSBufferDesc
->lpwfxFormat
->cbSize
);
181 hResult
= NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8
)lplpDirectSoundBuffer
, This
->Filter
, This
->dwLevel
, lpcDSBufferDesc
, This
->PrimaryBuffer
);
188 IDirectSound8_fnGetCaps(
189 LPDIRECTSOUND8 iface
,
192 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
194 if (!This
->bInitialized
)
196 /* object not yet initialized */
197 return DSERR_UNINITIALIZED
;
202 /* object not yet initialized */
203 return DSERR_INVALIDPARAM
;
206 if (lpDSCaps
->dwSize
!= sizeof(DSCAPS
))
208 /* object not yet initialized */
209 return DSERR_INVALIDPARAM
;
213 return DSERR_GENERIC
;
218 IDirectSound8_fnDuplicateSoundBuffer(
219 LPDIRECTSOUND8 iface
,
220 LPDIRECTSOUNDBUFFER lpDsbOriginal
,
221 LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate
)
224 return DSERR_OUTOFMEMORY
;
229 IDirectSound8_fnSetCooperativeLevel(
230 LPDIRECTSOUND8 iface
,
234 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
236 if (!This
->bInitialized
)
238 /* object not yet initialized */
239 return DSERR_UNINITIALIZED
;
242 /* store cooperation level */
243 This
->dwLevel
= dwLevel
;
249 IDirectSound8_fnCompact(
250 LPDIRECTSOUND8 iface
)
252 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
254 if (!This
->bInitialized
)
256 /* object not yet initialized */
257 return DSERR_UNINITIALIZED
;
260 if (This
->dwLevel
!= DSSCL_PRIORITY
)
262 /* needs priority level */
263 return DSERR_PRIOLEVELNEEDED
;
272 IDirectSound8_fnGetSpeakerConfig(
273 LPDIRECTSOUND8 iface
,
274 LPDWORD pdwSpeakerConfig
)
276 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
278 if (!This
->bInitialized
)
280 /* object not yet initialized */
281 return DSERR_UNINITIALIZED
;
286 return DSERR_INVALIDPARAM
;
291 IDirectSound8_fnSetSpeakerConfig(
292 LPDIRECTSOUND8 iface
,
293 DWORD dwSpeakerConfig
)
296 return DSERR_INVALIDPARAM
;
302 IDirectSound8_fnInitialize(
303 LPDIRECTSOUND8 iface
,
304 LPCGUID pcGuidDevice
)
309 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
313 EnumAudioDeviceInterfaces(&RootInfo
);
319 if (This
->bInitialized
)
321 /* object has already been initialized */
322 return DSERR_ALREADYINITIALIZED
;
325 /* fixme mutual exclusion */
327 if (pcGuidDevice
== NULL
|| IsEqualGUID(pcGuidDevice
, &GUID_NULL
))
329 /* use default playback device id */
330 pcGuidDevice
= &DSDEVID_DefaultPlayback
;
333 if (IsEqualIID(pcGuidDevice
, &DSDEVID_DefaultCapture
) || IsEqualIID(pcGuidDevice
, &DSDEVID_DefaultVoiceCapture
))
335 /* this has to be a winetest */
336 return DSERR_NODRIVER
;
339 /* now verify the guid */
340 if (GetDeviceID(pcGuidDevice
, &DeviceGuid
) != DS_OK
)
342 if (SUCCEEDED(StringFromIID(pcGuidDevice
, &pGuidStr
)))
344 DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr
);
345 CoTaskMemFree(pGuidStr
);
347 return DSERR_INVALIDPARAM
;
350 hr
= FindDeviceByGuid(&DeviceGuid
, &This
->Filter
);
354 This
->bInitialized
= TRUE
;
358 DPRINT("Failed to find device\n");
359 return DSERR_INVALIDPARAM
;
364 IDirectSound8_fnVerifyCertification(
365 LPDIRECTSOUND8 iface
,
366 LPDWORD pdwCertified
)
368 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
370 if (!This
->bInitialized
)
372 /* object not yet initialized */
373 return DSERR_UNINITIALIZED
;
380 static IDirectSound8Vtbl vt_DirectSound8
=
382 /* IUnknown methods */
383 IDirectSound8_fnQueryInterface
,
384 IDirectSound8_fnAddRef
,
385 IDirectSound8_fnRelease
,
386 /* IDirectSound methods */
387 IDirectSound8_fnCreateSoundBuffer
,
388 IDirectSound8_fnGetCaps
,
389 IDirectSound8_fnDuplicateSoundBuffer
,
390 IDirectSound8_fnSetCooperativeLevel
,
391 IDirectSound8_fnCompact
,
392 IDirectSound8_fnGetSpeakerConfig
,
393 IDirectSound8_fnSetSpeakerConfig
,
394 IDirectSound8_fnInitialize
,
395 /* IDirectSound8 methods */
396 IDirectSound8_fnVerifyCertification
400 InternalDirectSoundCreate(
402 LPDIRECTSOUND8
*ppDS
,
406 LPCDirectSoundImpl This
;
409 if (!ppDS
|| pUnkOuter
!= NULL
)
411 /* invalid parameter passed */
412 return DSERR_INVALIDPARAM
;
415 /* allocate CDirectSoundImpl struct */
416 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundImpl
));
419 /* not enough memory */
420 return DSERR_OUTOFMEMORY
;
423 /* initialize IDirectSound object */
425 This
->bDirectSound8
= bDirectSound8
;
426 This
->lpVtbl
= &vt_DirectSound8
;
429 /* initialize direct sound interface */
430 hr
= IDirectSound8_Initialize((LPDIRECTSOUND8
)&This
->lpVtbl
, lpcGUID
);
432 /* check for success */
436 DPRINT("Failed to initialize DirectSound object with %x\n", hr
);
437 IDirectSound8_Release((LPDIRECTSOUND8
)&This
->lpVtbl
);
442 *ppDS
= (LPDIRECTSOUND8
)&This
->lpVtbl
;
443 DPRINT("DirectSound object %p\n", *ppDS
);
455 LPCDirectSoundImpl This
;
464 /* check requested interface */
465 if (!IsEqualIID(riid
, &IID_IUnknown
) && !IsEqualIID(riid
, &IID_IDirectSound
) && !IsEqualIID(riid
, &IID_IDirectSound8
))
468 StringFromIID(riid
, &pStr
);
469 DPRINT("KsPropertySet does not support Interface %ws\n", pStr
);
471 return E_NOINTERFACE
;
474 /* allocate CDirectSoundCaptureImpl struct */
475 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundImpl
));
478 /* not enough memory */
479 return DSERR_OUTOFMEMORY
;
482 /* initialize object */
484 This
->lpVtbl
= &vt_DirectSound8
;
485 This
->bInitialized
= FALSE
;
486 *ppvObject
= (LPVOID
)&This
->lpVtbl
;
499 return InternalDirectSoundCreate(lpcGUID
, (LPDIRECTSOUND8
*)ppDS
, pUnkOuter
, FALSE
);
506 LPDIRECTSOUND8
*ppDS
,
509 return InternalDirectSoundCreate(lpcGUID
, ppDS
, pUnkOuter
, TRUE
);