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 (janderwald@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
== TRUE
) ||
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 (This
->PrimaryBuffer
)
126 /* primary buffer already exists */
127 IDirectSoundBuffer8_AddRef(This
->PrimaryBuffer
);
128 *lplpDirectSoundBuffer
= (LPDIRECTSOUNDBUFFER
)This
->PrimaryBuffer
;
132 hResult
= NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8
)lplpDirectSoundBuffer
, This
->Filter
, This
->dwLevel
);
133 if (SUCCEEDED(hResult
))
135 /* store primary buffer */
136 This
->PrimaryBuffer
= (LPDIRECTSOUNDBUFFER8
)*lplpDirectSoundBuffer
;
142 if (lpcDSBufferDesc
->lpwfxFormat
== NULL
)
144 /* format must not be null */
145 return DSERR_INVALIDPARAM
;
148 if (!This
->PrimaryBuffer
)
150 hResult
= NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8
)lplpDirectSoundBuffer
, This
->Filter
, This
->dwLevel
);
151 if (SUCCEEDED(hResult
))
153 /* store primary buffer */
154 This
->PrimaryBuffer
= (LPDIRECTSOUNDBUFFER8
)*lplpDirectSoundBuffer
;
158 DPRINT("Failed to create primary buffer with %x\n", hResult
);
164 ASSERT(This
->PrimaryBuffer
);
166 DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
167 This
, lpcDSBufferDesc
->lpwfxFormat
->wFormatTag
, lpcDSBufferDesc
->lpwfxFormat
->nChannels
, lpcDSBufferDesc
->lpwfxFormat
->nSamplesPerSec
, lpcDSBufferDesc
->lpwfxFormat
->nAvgBytesPerSec
, lpcDSBufferDesc
->lpwfxFormat
->nBlockAlign
, lpcDSBufferDesc
->lpwfxFormat
->wBitsPerSample
, lpcDSBufferDesc
->lpwfxFormat
->cbSize
);
169 hResult
= NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8
)lplpDirectSoundBuffer
, This
->Filter
, This
->dwLevel
, lpcDSBufferDesc
, This
->PrimaryBuffer
);
176 IDirectSound8_fnGetCaps(
177 LPDIRECTSOUND8 iface
,
180 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
182 if (!This
->bInitialized
)
184 /* object not yet initialized */
185 return DSERR_UNINITIALIZED
;
190 /* object not yet initialized */
191 return DSERR_INVALIDPARAM
;
194 if (lpDSCaps
->dwSize
!= sizeof(DSCAPS
))
196 /* object not yet initialized */
197 return DSERR_INVALIDPARAM
;
201 return DSERR_GENERIC
;
206 IDirectSound8_fnDuplicateSoundBuffer(
207 LPDIRECTSOUND8 iface
,
208 LPDIRECTSOUNDBUFFER lpDsbOriginal
,
209 LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate
)
212 return DSERR_OUTOFMEMORY
;
217 IDirectSound8_fnSetCooperativeLevel(
218 LPDIRECTSOUND8 iface
,
222 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
224 if (!This
->bInitialized
)
226 /* object not yet initialized */
227 return DSERR_UNINITIALIZED
;
230 /* store cooperation level */
231 This
->dwLevel
= dwLevel
;
237 IDirectSound8_fnCompact(
238 LPDIRECTSOUND8 iface
)
240 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
242 if (!This
->bInitialized
)
244 /* object not yet initialized */
245 return DSERR_UNINITIALIZED
;
248 if (This
->dwLevel
!= DSSCL_PRIORITY
)
250 /* needs priority level */
251 return DSERR_PRIOLEVELNEEDED
;
260 IDirectSound8_fnGetSpeakerConfig(
261 LPDIRECTSOUND8 iface
,
262 LPDWORD pdwSpeakerConfig
)
264 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
266 if (!This
->bInitialized
)
268 /* object not yet initialized */
269 return DSERR_UNINITIALIZED
;
274 return DSERR_INVALIDPARAM
;
279 IDirectSound8_fnSetSpeakerConfig(
280 LPDIRECTSOUND8 iface
,
281 DWORD dwSpeakerConfig
)
284 return DSERR_INVALIDPARAM
;
290 IDirectSound8_fnInitialize(
291 LPDIRECTSOUND8 iface
,
292 LPCGUID pcGuidDevice
)
297 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
301 EnumAudioDeviceInterfaces(&RootInfo
);
307 if (This
->bInitialized
)
309 /* object has already been initialized */
310 return DSERR_ALREADYINITIALIZED
;
313 /* fixme mutual exlucsion */
315 if (pcGuidDevice
== NULL
|| IsEqualGUID(pcGuidDevice
, &GUID_NULL
))
317 /* use default playback device id */
318 pcGuidDevice
= &DSDEVID_DefaultPlayback
;
321 if (IsEqualIID(pcGuidDevice
, &DSDEVID_DefaultCapture
) || IsEqualIID(pcGuidDevice
, &DSDEVID_DefaultVoiceCapture
))
323 /* this has to be a winetest */
324 return DSERR_NODRIVER
;
327 /* now verify the guid */
328 if (GetDeviceID(pcGuidDevice
, &DeviceGuid
) != DS_OK
)
330 if (SUCCEEDED(StringFromIID(pcGuidDevice
, &pGuidStr
)))
332 DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr
);
333 CoTaskMemFree(pGuidStr
);
335 return DSERR_INVALIDPARAM
;
338 hr
= FindDeviceByGuid(&DeviceGuid
, &This
->Filter
);
342 This
->bInitialized
= TRUE
;
346 DPRINT("Failed to find device\n");
347 return DSERR_INVALIDPARAM
;
352 IDirectSound8_fnVerifyCertification(
353 LPDIRECTSOUND8 iface
,
354 LPDWORD pdwCertified
)
356 LPCDirectSoundImpl This
= (LPCDirectSoundImpl
)CONTAINING_RECORD(iface
, CDirectSoundImpl
, lpVtbl
);
358 if (!This
->bInitialized
)
360 /* object not yet initialized */
361 return DSERR_UNINITIALIZED
;
368 static IDirectSound8Vtbl vt_DirectSound8
=
370 /* IUnknown methods */
371 IDirectSound8_fnQueryInterface
,
372 IDirectSound8_fnAddRef
,
373 IDirectSound8_fnRelease
,
374 /* IDirectSound methods */
375 IDirectSound8_fnCreateSoundBuffer
,
376 IDirectSound8_fnGetCaps
,
377 IDirectSound8_fnDuplicateSoundBuffer
,
378 IDirectSound8_fnSetCooperativeLevel
,
379 IDirectSound8_fnCompact
,
380 IDirectSound8_fnGetSpeakerConfig
,
381 IDirectSound8_fnSetSpeakerConfig
,
382 IDirectSound8_fnInitialize
,
383 /* IDirectSound8 methods */
384 IDirectSound8_fnVerifyCertification
388 InternalDirectSoundCreate(
390 LPDIRECTSOUND8
*ppDS
,
394 LPCDirectSoundImpl This
;
397 if (!ppDS
|| pUnkOuter
!= NULL
)
399 /* invalid parameter passed */
400 return DSERR_INVALIDPARAM
;
403 /* allocate CDirectSoundImpl struct */
404 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundImpl
));
407 /* not enough memory */
408 return DSERR_OUTOFMEMORY
;
411 /* initialize IDirectSound object */
413 This
->bDirectSound8
= bDirectSound8
;
414 This
->lpVtbl
= &vt_DirectSound8
;
417 /* initialize direct sound interface */
418 hr
= IDirectSound8_Initialize((LPDIRECTSOUND8
)&This
->lpVtbl
, lpcGUID
);
420 /* check for success */
424 DPRINT("Failed to initialize DirectSound object with %x\n", hr
);
425 IDirectSound8_Release((LPDIRECTSOUND8
)&This
->lpVtbl
);
430 *ppDS
= (LPDIRECTSOUND8
)&This
->lpVtbl
;
431 DPRINT("DirectSound object %p\n", *ppDS
);
443 LPCDirectSoundImpl This
;
452 /* check requested interface */
453 if (!IsEqualIID(riid
, &IID_IUnknown
) && !IsEqualIID(riid
, &IID_IDirectSound
) && !IsEqualIID(riid
, &IID_IDirectSound8
))
456 StringFromIID(riid
, &pStr
);
457 DPRINT("KsPropertySet does not support Interface %ws\n", pStr
);
459 return E_NOINTERFACE
;
462 /* allocate CDirectSoundCaptureImpl struct */
463 This
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CDirectSoundImpl
));
466 /* not enough memory */
467 return DSERR_OUTOFMEMORY
;
470 /* initialize object */
472 This
->lpVtbl
= &vt_DirectSound8
;
473 This
->bInitialized
= FALSE
;
474 *ppvObject
= (LPVOID
)&This
->lpVtbl
;
487 return InternalDirectSoundCreate(lpcGUID
, (LPDIRECTSOUND8
*)ppDS
, pUnkOuter
, FALSE
);
494 LPDIRECTSOUND8
*ppDS
,
497 return InternalDirectSoundCreate(lpcGUID
, ppDS
, pUnkOuter
, TRUE
);