ReactOS 0.4.15-dev-7924-g5949c20
directsound.c
Go to the documentation of this file.
1/*
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
6 *
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8 */
9
10#include "precomp.h"
11
12typedef struct
13{
14 IDirectSound8Vtbl *lpVtbl;
22
23
25
29 LPDIRECTSOUND8 iface,
31 LPVOID * ppobj)
32{
33 LPOLESTR pStr;
35
36 if ((IsEqualIID(riid, &IID_IDirectSound) && This->bDirectSound8 == FALSE) ||
37 (IsEqualIID(riid, &IID_IDirectSound8) && This->bDirectSound8 != FALSE) ||
39 {
40 *ppobj = (LPVOID)&This->lpVtbl;
42 return S_OK;
43 }
44
45 if (SUCCEEDED(StringFromIID(riid, &pStr)))
46 {
47 DPRINT("No Interface for class %s\n", pStr);
48 CoTaskMemFree(pStr);
49 }
50 return E_NOINTERFACE;
51}
52
56 LPDIRECTSOUND8 iface)
57{
58 ULONG ref;
60
62
63 return ref;
64}
65
69 LPDIRECTSOUND8 iface)
70{
71 ULONG ref;
73
74 ref = InterlockedDecrement(&(This->ref));
75
76 if (!ref)
77 {
79 }
80
81 return ref;
82}
83
87 LPDIRECTSOUND8 iface,
88 LPCDSBUFFERDESC lpcDSBufferDesc,
89 LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer,
90 IUnknown FAR* pUnkOuter)
91{
92 HRESULT hResult;
94
95 if (!This->bInitialized)
96 {
97 /* object not yet initialized */
99 }
100
101 if (!lpcDSBufferDesc || !lplpDirectSoundBuffer || pUnkOuter != NULL)
102 {
103 DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter);
104 return DSERR_INVALIDPARAM;
105 }
106
107 /* check buffer description */
108 if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0)
109 {
110 DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved);
111 return DSERR_INVALIDPARAM;
112 }
113
114 DPRINT("This %p dwFlags %x dwBufferBytes %u lpwfxFormat %p dwSize %u\n", This, lpcDSBufferDesc->dwFlags, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat, lpcDSBufferDesc->dwSize);
115
116 if (lpcDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER)
117 {
118 if (lpcDSBufferDesc->lpwfxFormat != NULL)
119 {
120 /* format must be null for primary sound buffer */
121 return DSERR_INVALIDPARAM;
122 }
123
124 if (lpcDSBufferDesc->dwBufferBytes != 0)
125 {
126 /* buffer size must be zero for primary sound buffer */
127 return DSERR_INVALIDPARAM;
128 }
129
130 if (This->PrimaryBuffer)
131 {
132 /* primary buffer already exists */
133 IDirectSoundBuffer8_AddRef(This->PrimaryBuffer);
134 *lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)This->PrimaryBuffer;
135 return S_OK;
136 }
137
138 hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc->dwFlags);
139 if (SUCCEEDED(hResult))
140 {
141 /* store primary buffer */
142 This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer;
143 }
144 return hResult;
145 }
146 else
147 {
148 if (lpcDSBufferDesc->lpwfxFormat == NULL)
149 {
150 /* format must not be null */
151 return DSERR_INVALIDPARAM;
152 }
153
154 if (lpcDSBufferDesc->dwBufferBytes < DSBSIZE_MIN || lpcDSBufferDesc->dwBufferBytes > DSBSIZE_MAX)
155 {
156 /* buffer size must be within bounds for secondary sound buffer*/
157 return DSERR_INVALIDPARAM;
158 }
159
160 if (!This->PrimaryBuffer)
161 {
162 hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc->dwFlags);
163 if (SUCCEEDED(hResult))
164 {
165 /* store primary buffer */
166 This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer;
167 }
168 else
169 {
170 DPRINT("Failed to create primary buffer with %x\n", hResult);
171 return hResult;
172 }
173
174 }
175
176 ASSERT(This->PrimaryBuffer);
177
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);
180
181 hResult = NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc, This->PrimaryBuffer);
182 return hResult;
183 }
184}
185
187WINAPI
189 LPDIRECTSOUND8 iface,
190 LPDSCAPS lpDSCaps)
191{
193
194 if (!This->bInitialized)
195 {
196 /* object not yet initialized */
197 return DSERR_UNINITIALIZED;
198 }
199
200 if (!lpDSCaps)
201 {
202 /* object not yet initialized */
203 return DSERR_INVALIDPARAM;
204 }
205
206 if (lpDSCaps->dwSize != sizeof(DSCAPS))
207 {
208 /* object not yet initialized */
209 return DSERR_INVALIDPARAM;
210 }
211
213 return DSERR_GENERIC;
214}
215
217WINAPI
219 LPDIRECTSOUND8 iface,
220 LPDIRECTSOUNDBUFFER lpDsbOriginal,
221 LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate)
222{
224 return DSERR_OUTOFMEMORY;
225}
226
228WINAPI
230 LPDIRECTSOUND8 iface,
231 HWND hwnd,
232 DWORD dwLevel)
233{
235
236 if (!This->bInitialized)
237 {
238 /* object not yet initialized */
239 return DSERR_UNINITIALIZED;
240 }
241
242 /* store cooperation level */
243 This->dwLevel = dwLevel;
244 return DS_OK;
245}
246
248WINAPI
250 LPDIRECTSOUND8 iface)
251{
253
254 if (!This->bInitialized)
255 {
256 /* object not yet initialized */
257 return DSERR_UNINITIALIZED;
258 }
259
260 if (This->dwLevel != DSSCL_PRIORITY)
261 {
262 /* needs priority level */
264 }
265
266 /* done */
267 return DS_OK;
268}
269
271WINAPI
273 LPDIRECTSOUND8 iface,
274 LPDWORD pdwSpeakerConfig)
275{
277
278 if (!This->bInitialized)
279 {
280 /* object not yet initialized */
281 return DSERR_UNINITIALIZED;
282 }
283
284
286 return DSERR_INVALIDPARAM;
287}
288
290WINAPI
292 LPDIRECTSOUND8 iface,
293 DWORD dwSpeakerConfig)
294{
296 return DSERR_INVALIDPARAM;
297}
298
299
301WINAPI
303 LPDIRECTSOUND8 iface,
304 LPCGUID pcGuidDevice)
305{
306 GUID DeviceGuid;
307 LPOLESTR pGuidStr;
308 HRESULT hr;
310
311 if (!RootInfo)
312 {
314 }
315
316 /* sanity check */
318
319 if (This->bInitialized)
320 {
321 /* object has already been initialized */
323 }
324
325 /* fixme mutual exclusion */
326
327 if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL))
328 {
329 /* use default playback device id */
330 pcGuidDevice = &DSDEVID_DefaultPlayback;
331 }
332
333 if (IsEqualIID(pcGuidDevice, &DSDEVID_DefaultCapture) || IsEqualIID(pcGuidDevice, &DSDEVID_DefaultVoiceCapture))
334 {
335 /* this has to be a winetest */
336 return DSERR_NODRIVER;
337 }
338
339 /* now verify the guid */
340 if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK)
341 {
342 if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr)))
343 {
344 DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr);
345 CoTaskMemFree(pGuidStr);
346 }
347 return DSERR_INVALIDPARAM;
348 }
349
350 hr = FindDeviceByGuid(&DeviceGuid, &This->Filter);
351
352 if (SUCCEEDED(hr))
353 {
354 This->bInitialized = TRUE;
355 return DS_OK;
356 }
357
358 DPRINT("Failed to find device\n");
359 return DSERR_INVALIDPARAM;
360}
361
363WINAPI
365 LPDIRECTSOUND8 iface,
366 LPDWORD pdwCertified)
367{
369
370 if (!This->bInitialized)
371 {
372 /* object not yet initialized */
373 return DSERR_UNINITIALIZED;
374 }
375
377 return DS_CERTIFIED;
378}
379
380static IDirectSound8Vtbl vt_DirectSound8 =
381{
382 /* IUnknown methods */
386 /* IDirectSound methods */
395 /* IDirectSound8 methods */
397};
398
401 LPCGUID lpcGUID,
402 LPDIRECTSOUND8 *ppDS,
403 IUnknown *pUnkOuter,
404 BOOL bDirectSound8)
405{
407 HRESULT hr;
408
409 if (!ppDS || pUnkOuter != NULL)
410 {
411 /* invalid parameter passed */
412 return DSERR_INVALIDPARAM;
413 }
414
415 /* allocate CDirectSoundImpl struct */
417 if (!This)
418 {
419 /* not enough memory */
420 return DSERR_OUTOFMEMORY;
421 }
422
423 /* initialize IDirectSound object */
424 This->ref = 1;
425 This->bDirectSound8 = bDirectSound8;
426 This->lpVtbl = &vt_DirectSound8;
427
428
429 /* initialize direct sound interface */
430 hr = IDirectSound8_Initialize((LPDIRECTSOUND8)&This->lpVtbl, lpcGUID);
431
432 /* check for success */
433 if (!SUCCEEDED(hr))
434 {
435 /* failed */
436 DPRINT("Failed to initialize DirectSound object with %x\n", hr);
438 return hr;
439 }
440
441 /* store result */
442 *ppDS = (LPDIRECTSOUND8)&This->lpVtbl;
443 DPRINT("DirectSound object %p\n", *ppDS);
444 return DS_OK;
445}
446
450 IUnknown* pUnkOuter,
451 REFIID riid,
453{
454 LPOLESTR pStr;
456
457 /* check param */
458 if (!ppvObject)
459 {
460 /* invalid param */
461 return E_INVALIDARG;
462 }
463
464 /* check requested interface */
465 if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IDirectSound) && !IsEqualIID(riid, &IID_IDirectSound8))
466 {
467 *ppvObject = 0;
468 StringFromIID(riid, &pStr);
469 DPRINT("KsPropertySet does not support Interface %ws\n", pStr);
470 CoTaskMemFree(pStr);
471 return E_NOINTERFACE;
472 }
473
474 /* allocate CDirectSoundCaptureImpl struct */
476 if (!This)
477 {
478 /* not enough memory */
479 return DSERR_OUTOFMEMORY;
480 }
481
482 /* initialize object */
483 This->ref = 1;
484 This->lpVtbl = &vt_DirectSound8;
485 This->bInitialized = FALSE;
486 *ppvObject = (LPVOID)&This->lpVtbl;
487
488 return S_OK;
489}
490
491
493WINAPI
495 LPCGUID lpcGUID,
496 LPDIRECTSOUND *ppDS,
497 IUnknown *pUnkOuter)
498{
499 return InternalDirectSoundCreate(lpcGUID, (LPDIRECTSOUND8*)ppDS, pUnkOuter, FALSE);
500}
501
503WINAPI
505 LPCGUID lpcGUID,
506 LPDIRECTSOUND8 *ppDS,
507 IUnknown *pUnkOuter)
508{
509 return InternalDirectSoundCreate(lpcGUID, ppDS, pUnkOuter, TRUE);
510}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
const GUID IID_IUnknown
#define UNIMPLEMENTED
Definition: debug.h:115
#define E_INVALIDARG
Definition: ddrawi.h:101
ULONG WINAPI IDirectSound8_fnAddRef(LPDIRECTSOUND8 iface)
Definition: directsound.c:55
static IDirectSound8Vtbl vt_DirectSound8
Definition: directsound.c:380
HRESULT WINAPI DirectSoundCreate(LPCGUID lpcGUID, LPDIRECTSOUND *ppDS, IUnknown *pUnkOuter)
Definition: directsound.c:494
HRESULT WINAPI IDirectSound8_fnQueryInterface(LPDIRECTSOUND8 iface, REFIID riid, LPVOID *ppobj)
Definition: directsound.c:28
struct CDirectSoundImpl * LPCDirectSoundImpl
ULONG WINAPI IDirectSound8_fnRelease(LPDIRECTSOUND8 iface)
Definition: directsound.c:68
HRESULT InternalDirectSoundCreate(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter, BOOL bDirectSound8)
Definition: directsound.c:400
HRESULT WINAPI IDirectSound8_fnSetSpeakerConfig(LPDIRECTSOUND8 iface, DWORD dwSpeakerConfig)
Definition: directsound.c:291
HRESULT WINAPI IDirectSound8_fnCreateSoundBuffer(LPDIRECTSOUND8 iface, LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, IUnknown FAR *pUnkOuter)
Definition: directsound.c:86
HRESULT WINAPI IDirectSound8_fnGetSpeakerConfig(LPDIRECTSOUND8 iface, LPDWORD pdwSpeakerConfig)
Definition: directsound.c:272
HRESULT WINAPI IDirectSound8_fnVerifyCertification(LPDIRECTSOUND8 iface, LPDWORD pdwCertified)
Definition: directsound.c:364
HRESULT WINAPI IDirectSound8_fnDuplicateSoundBuffer(LPDIRECTSOUND8 iface, LPDIRECTSOUNDBUFFER lpDsbOriginal, LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate)
Definition: directsound.c:218
HRESULT WINAPI IDirectSound8_fnCompact(LPDIRECTSOUND8 iface)
Definition: directsound.c:249
HRESULT WINAPI IDirectSound8_fnGetCaps(LPDIRECTSOUND8 iface, LPDSCAPS lpDSCaps)
Definition: directsound.c:188
HRESULT WINAPI IDirectSound8_fnSetCooperativeLevel(LPDIRECTSOUND8 iface, HWND hwnd, DWORD dwLevel)
Definition: directsound.c:229
HRESULT WINAPI IDirectSound8_fnInitialize(LPDIRECTSOUND8 iface, LPCGUID pcGuidDevice)
Definition: directsound.c:302
HRESULT CALLBACK NewDirectSound(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppvObject)
Definition: directsound.c:449
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID, LPDIRECTSOUND8 *ppDS, IUnknown *pUnkOuter)
Definition: directsound.c:504
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT EnumAudioDeviceInterfaces(LPFILTERINFO *OutRootInfo)
Definition: devicelist.c:384
BOOL FindDeviceByGuid(LPCGUID pGuidSrc, LPFILTERINFO *Filter)
Definition: devicelist.c:470
LPFILTERINFO RootInfo
Definition: dsound.c:13
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
Definition: dsound.c:53
HRESULT NewSecondarySoundBuffer(LPDIRECTSOUNDBUFFER8 *OutBuffer, LPFILTERINFO Filter, DWORD dwLevel, LPCDSBUFFERDESC lpcDSBufferDesc, LPDIRECTSOUNDBUFFER8 PrimaryBuffer)
Definition: secondary.c:611
HRESULT NewPrimarySoundBuffer(LPDIRECTSOUNDBUFFER8 *OutBuffer, LPFILTERINFO Filter, DWORD dwLevel, DWORD dwFlags)
Definition: primary.c:768
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define FAR
Definition: zlib.h:34
#define DSERR_UNINITIALIZED
Definition: dsound.h:133
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
struct IDirectSoundBuffer ** LPLPDIRECTSOUNDBUFFER
Definition: dsound.h:76
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
struct IDirectSoundBuffer8 ** LPLPDIRECTSOUNDBUFFER8
Definition: dsound.h:79
#define DSBSIZE_MAX
Definition: dsound.h:225
#define DSSCL_PRIORITY
Definition: dsound.h:248
struct IDirectSound * LPDIRECTSOUND
Definition: dsound.h:70
#define DS_OK
Definition: dsound.h:116
#define DSBSIZE_MIN
Definition: dsound.h:224
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
struct IDirectSound8 * LPDIRECTSOUND8
Definition: dsound.h:73
#define IDirectSound8_Release(p)
Definition: dsound.h:507
#define IDirectSoundBuffer8_AddRef(p)
Definition: dsound.h:659
struct IDirectSoundBuffer8 * LPDIRECTSOUNDBUFFER8
Definition: dsound.h:79
#define DS_CERTIFIED
Definition: dsound.h:326
#define IDirectSound8_Initialize(p, a)
Definition: dsound.h:516
#define DSERR_PRIOLEVELNEEDED
Definition: dsound.h:124
#define DSERR_GENERIC
Definition: dsound.h:123
#define DSERR_NODRIVER
Definition: dsound.h:128
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define GUID_NULL
Definition: ks.h:106
#define ASSERT(a)
Definition: mode.c:44
static LPOLESTR
Definition: stg_prop.c:27
#define LPVOID
Definition: nt_native.h:45
_Check_return_ HRESULT WINAPI StringFromIID(_In_ REFIID rclsid, _Outptr_ LPOLESTR *lplpsz)
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
HRESULT hr
Definition: shlfolder.c:183
#define DPRINT
Definition: sndvol32.h:71
IDirectSound8Vtbl * lpVtbl
Definition: directsound.c:14
LPFILTERINFO Filter
Definition: directsound.c:20
LPDIRECTSOUNDBUFFER8 PrimaryBuffer
Definition: directsound.c:21
DWORD dwSize
Definition: dsound.h:288
DWORD dwFlags
Definition: dsound.h:289
DWORD dwBufferBytes
Definition: dsound.h:290
DWORD dwReserved
Definition: dsound.h:291
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
DWORD dwSize
Definition: dsound.h:162
WORD nBlockAlign
Definition: mmreg.h:82
WORD cbSize
Definition: mmreg.h:84
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83
Definition: send.c:48
uint32_t * LPDWORD
Definition: typedefs.h:59
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364