Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendirectsound.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Configuration of network devices 00004 * FILE: dll/directx/dsound_new/directsound.c 00005 * PURPOSE: Handles IDirectSound interface 00006 * 00007 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) 00008 */ 00009 00010 #include "precomp.h" 00011 00012 typedef struct 00013 { 00014 IDirectSound8Vtbl *lpVtbl; 00015 LONG ref; 00016 GUID DeviceGUID; 00017 BOOL bInitialized; 00018 BOOL bDirectSound8; 00019 DWORD dwLevel; 00020 LPFILTERINFO Filter; 00021 LPDIRECTSOUNDBUFFER8 PrimaryBuffer; 00022 00023 00024 }CDirectSoundImpl, *LPCDirectSoundImpl; 00025 00026 HRESULT 00027 WINAPI 00028 IDirectSound8_fnQueryInterface( 00029 LPDIRECTSOUND8 iface, 00030 REFIID riid, 00031 LPVOID * ppobj) 00032 { 00033 LPOLESTR pStr; 00034 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00035 00036 if ((IsEqualIID(riid, &IID_IDirectSound) && This->bDirectSound8 == FALSE) || 00037 (IsEqualIID(riid, &IID_IDirectSound8) && This->bDirectSound8 == TRUE) || 00038 (IsEqualIID(riid, &IID_IUnknown))) 00039 { 00040 *ppobj = (LPVOID)&This->lpVtbl; 00041 InterlockedIncrement(&This->ref); 00042 return S_OK; 00043 } 00044 00045 if (SUCCEEDED(StringFromIID(riid, &pStr))) 00046 { 00047 DPRINT("No Interface for class %s\n", pStr); 00048 CoTaskMemFree(pStr); 00049 } 00050 return E_NOINTERFACE; 00051 } 00052 00053 ULONG 00054 WINAPI 00055 IDirectSound8_fnAddRef( 00056 LPDIRECTSOUND8 iface) 00057 { 00058 ULONG ref; 00059 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00060 00061 ref = InterlockedIncrement(&This->ref); 00062 00063 return ref; 00064 } 00065 00066 ULONG 00067 WINAPI 00068 IDirectSound8_fnRelease( 00069 LPDIRECTSOUND8 iface) 00070 { 00071 ULONG ref; 00072 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00073 00074 ref = InterlockedDecrement(&(This->ref)); 00075 00076 if (!ref) 00077 { 00078 HeapFree(GetProcessHeap(), 0, This); 00079 } 00080 00081 return ref; 00082 } 00083 00084 HRESULT 00085 WINAPI 00086 IDirectSound8_fnCreateSoundBuffer( 00087 LPDIRECTSOUND8 iface, 00088 LPCDSBUFFERDESC lpcDSBufferDesc, 00089 LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, 00090 IUnknown FAR* pUnkOuter) 00091 { 00092 HRESULT hResult; 00093 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00094 00095 if (!This->bInitialized) 00096 { 00097 /* object not yet initialized */ 00098 return DSERR_UNINITIALIZED; 00099 } 00100 00101 if (!lpcDSBufferDesc || !lplpDirectSoundBuffer || pUnkOuter != NULL) 00102 { 00103 DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter); 00104 return DSERR_INVALIDPARAM; 00105 } 00106 00107 /* check buffer description */ 00108 if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0) 00109 { 00110 DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved); 00111 return DSERR_INVALIDPARAM; 00112 } 00113 00114 DPRINT("This %p dwFlags %x dwBufferBytes %u lpwfxFormat %p dwSize %u\n", This, lpcDSBufferDesc->dwFlags, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat, lpcDSBufferDesc->dwSize); 00115 00116 if (lpcDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER) 00117 { 00118 if (lpcDSBufferDesc->lpwfxFormat != NULL) 00119 { 00120 /* format must be null for primary sound buffer */ 00121 return DSERR_INVALIDPARAM; 00122 } 00123 00124 if (lpcDSBufferDesc->dwBufferBytes != 0) 00125 { 00126 /* buffer size must be zero for primary sound buffer */ 00127 return DSERR_INVALIDPARAM; 00128 } 00129 00130 if (This->PrimaryBuffer) 00131 { 00132 /* primary buffer already exists */ 00133 IDirectSoundBuffer8_AddRef(This->PrimaryBuffer); 00134 *lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)This->PrimaryBuffer; 00135 return S_OK; 00136 } 00137 00138 hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc->dwFlags); 00139 if (SUCCEEDED(hResult)) 00140 { 00141 /* store primary buffer */ 00142 This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer; 00143 } 00144 return hResult; 00145 } 00146 else 00147 { 00148 if (lpcDSBufferDesc->lpwfxFormat == NULL) 00149 { 00150 /* format must not be null */ 00151 return DSERR_INVALIDPARAM; 00152 } 00153 00154 if (lpcDSBufferDesc->dwBufferBytes < DSBSIZE_MIN || lpcDSBufferDesc->dwBufferBytes > DSBSIZE_MAX) 00155 { 00156 /* buffer size must be within bounds for secondary sound buffer*/ 00157 return DSERR_INVALIDPARAM; 00158 } 00159 00160 if (!This->PrimaryBuffer) 00161 { 00162 hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc->dwFlags); 00163 if (SUCCEEDED(hResult)) 00164 { 00165 /* store primary buffer */ 00166 This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer; 00167 } 00168 else 00169 { 00170 DPRINT("Failed to create primary buffer with %x\n", hResult); 00171 return hResult; 00172 } 00173 00174 } 00175 00176 ASSERT(This->PrimaryBuffer); 00177 00178 DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n", 00179 This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize); 00180 00181 hResult = NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc, This->PrimaryBuffer); 00182 return hResult; 00183 } 00184 } 00185 00186 HRESULT 00187 WINAPI 00188 IDirectSound8_fnGetCaps( 00189 LPDIRECTSOUND8 iface, 00190 LPDSCAPS lpDSCaps) 00191 { 00192 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00193 00194 if (!This->bInitialized) 00195 { 00196 /* object not yet initialized */ 00197 return DSERR_UNINITIALIZED; 00198 } 00199 00200 if (!lpDSCaps) 00201 { 00202 /* object not yet initialized */ 00203 return DSERR_INVALIDPARAM; 00204 } 00205 00206 if (lpDSCaps->dwSize != sizeof(DSCAPS)) 00207 { 00208 /* object not yet initialized */ 00209 return DSERR_INVALIDPARAM; 00210 } 00211 00212 UNIMPLEMENTED; 00213 return DSERR_GENERIC; 00214 } 00215 00216 HRESULT 00217 WINAPI 00218 IDirectSound8_fnDuplicateSoundBuffer( 00219 LPDIRECTSOUND8 iface, 00220 LPDIRECTSOUNDBUFFER lpDsbOriginal, 00221 LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate) 00222 { 00223 UNIMPLEMENTED; 00224 return DSERR_OUTOFMEMORY; 00225 } 00226 00227 HRESULT 00228 WINAPI 00229 IDirectSound8_fnSetCooperativeLevel( 00230 LPDIRECTSOUND8 iface, 00231 HWND hwnd, 00232 DWORD dwLevel) 00233 { 00234 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00235 00236 if (!This->bInitialized) 00237 { 00238 /* object not yet initialized */ 00239 return DSERR_UNINITIALIZED; 00240 } 00241 00242 /* store cooperation level */ 00243 This->dwLevel = dwLevel; 00244 return DS_OK; 00245 } 00246 00247 HRESULT 00248 WINAPI 00249 IDirectSound8_fnCompact( 00250 LPDIRECTSOUND8 iface) 00251 { 00252 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00253 00254 if (!This->bInitialized) 00255 { 00256 /* object not yet initialized */ 00257 return DSERR_UNINITIALIZED; 00258 } 00259 00260 if (This->dwLevel != DSSCL_PRIORITY) 00261 { 00262 /* needs priority level */ 00263 return DSERR_PRIOLEVELNEEDED; 00264 } 00265 00266 /* done */ 00267 return DS_OK; 00268 } 00269 00270 HRESULT 00271 WINAPI 00272 IDirectSound8_fnGetSpeakerConfig( 00273 LPDIRECTSOUND8 iface, 00274 LPDWORD pdwSpeakerConfig) 00275 { 00276 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00277 00278 if (!This->bInitialized) 00279 { 00280 /* object not yet initialized */ 00281 return DSERR_UNINITIALIZED; 00282 } 00283 00284 00285 UNIMPLEMENTED; 00286 return DSERR_INVALIDPARAM; 00287 } 00288 00289 HRESULT 00290 WINAPI 00291 IDirectSound8_fnSetSpeakerConfig( 00292 LPDIRECTSOUND8 iface, 00293 DWORD dwSpeakerConfig) 00294 { 00295 UNIMPLEMENTED; 00296 return DSERR_INVALIDPARAM; 00297 } 00298 00299 00300 HRESULT 00301 WINAPI 00302 IDirectSound8_fnInitialize( 00303 LPDIRECTSOUND8 iface, 00304 LPCGUID pcGuidDevice) 00305 { 00306 GUID DeviceGuid; 00307 LPOLESTR pGuidStr; 00308 HRESULT hr; 00309 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00310 00311 if (!RootInfo) 00312 { 00313 EnumAudioDeviceInterfaces(&RootInfo); 00314 } 00315 00316 /* sanity check */ 00317 ASSERT(RootInfo); 00318 00319 if (This->bInitialized) 00320 { 00321 /* object has already been initialized */ 00322 return DSERR_ALREADYINITIALIZED; 00323 } 00324 00325 /* fixme mutual exlucsion */ 00326 00327 if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL)) 00328 { 00329 /* use default playback device id */ 00330 pcGuidDevice = &DSDEVID_DefaultPlayback; 00331 } 00332 00333 if (IsEqualIID(pcGuidDevice, &DSDEVID_DefaultCapture) || IsEqualIID(pcGuidDevice, &DSDEVID_DefaultVoiceCapture)) 00334 { 00335 /* this has to be a winetest */ 00336 return DSERR_NODRIVER; 00337 } 00338 00339 /* now verify the guid */ 00340 if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK) 00341 { 00342 if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr))) 00343 { 00344 DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr); 00345 CoTaskMemFree(pGuidStr); 00346 } 00347 return DSERR_INVALIDPARAM; 00348 } 00349 00350 hr = FindDeviceByGuid(&DeviceGuid, &This->Filter); 00351 00352 if (SUCCEEDED(hr)) 00353 { 00354 This->bInitialized = TRUE; 00355 return DS_OK; 00356 } 00357 00358 DPRINT("Failed to find device\n"); 00359 return DSERR_INVALIDPARAM; 00360 } 00361 00362 HRESULT 00363 WINAPI 00364 IDirectSound8_fnVerifyCertification( 00365 LPDIRECTSOUND8 iface, 00366 LPDWORD pdwCertified) 00367 { 00368 LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl); 00369 00370 if (!This->bInitialized) 00371 { 00372 /* object not yet initialized */ 00373 return DSERR_UNINITIALIZED; 00374 } 00375 00376 UNIMPLEMENTED; 00377 return DS_CERTIFIED; 00378 } 00379 00380 static IDirectSound8Vtbl vt_DirectSound8 = 00381 { 00382 /* IUnknown methods */ 00383 IDirectSound8_fnQueryInterface, 00384 IDirectSound8_fnAddRef, 00385 IDirectSound8_fnRelease, 00386 /* IDirectSound methods */ 00387 IDirectSound8_fnCreateSoundBuffer, 00388 IDirectSound8_fnGetCaps, 00389 IDirectSound8_fnDuplicateSoundBuffer, 00390 IDirectSound8_fnSetCooperativeLevel, 00391 IDirectSound8_fnCompact, 00392 IDirectSound8_fnGetSpeakerConfig, 00393 IDirectSound8_fnSetSpeakerConfig, 00394 IDirectSound8_fnInitialize, 00395 /* IDirectSound8 methods */ 00396 IDirectSound8_fnVerifyCertification 00397 }; 00398 00399 HRESULT 00400 InternalDirectSoundCreate( 00401 LPCGUID lpcGUID, 00402 LPDIRECTSOUND8 *ppDS, 00403 IUnknown *pUnkOuter, 00404 BOOL bDirectSound8) 00405 { 00406 LPCDirectSoundImpl This; 00407 HRESULT hr; 00408 00409 if (!ppDS || pUnkOuter != NULL) 00410 { 00411 /* invalid parameter passed */ 00412 return DSERR_INVALIDPARAM; 00413 } 00414 00415 /* allocate CDirectSoundImpl struct */ 00416 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundImpl)); 00417 if (!This) 00418 { 00419 /* not enough memory */ 00420 return DSERR_OUTOFMEMORY; 00421 } 00422 00423 /* initialize IDirectSound object */ 00424 This->ref = 1; 00425 This->bDirectSound8 = bDirectSound8; 00426 This->lpVtbl = &vt_DirectSound8; 00427 00428 00429 /* initialize direct sound interface */ 00430 hr = IDirectSound8_Initialize((LPDIRECTSOUND8)&This->lpVtbl, lpcGUID); 00431 00432 /* check for success */ 00433 if (!SUCCEEDED(hr)) 00434 { 00435 /* failed */ 00436 DPRINT("Failed to initialize DirectSound object with %x\n", hr); 00437 IDirectSound8_Release((LPDIRECTSOUND8)&This->lpVtbl); 00438 return hr; 00439 } 00440 00441 /* store result */ 00442 *ppDS = (LPDIRECTSOUND8)&This->lpVtbl; 00443 DPRINT("DirectSound object %p\n", *ppDS); 00444 return DS_OK; 00445 } 00446 00447 HRESULT 00448 CALLBACK 00449 NewDirectSound( 00450 IUnknown* pUnkOuter, 00451 REFIID riid, 00452 LPVOID* ppvObject) 00453 { 00454 LPOLESTR pStr; 00455 LPCDirectSoundImpl This; 00456 00457 /* check param */ 00458 if (!ppvObject) 00459 { 00460 /* invalid param */ 00461 return E_INVALIDARG; 00462 } 00463 00464 /* check requested interface */ 00465 if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IDirectSound) && !IsEqualIID(riid, &IID_IDirectSound8)) 00466 { 00467 *ppvObject = 0; 00468 StringFromIID(riid, &pStr); 00469 DPRINT("KsPropertySet does not support Interface %ws\n", pStr); 00470 CoTaskMemFree(pStr); 00471 return E_NOINTERFACE; 00472 } 00473 00474 /* allocate CDirectSoundCaptureImpl struct */ 00475 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundImpl)); 00476 if (!This) 00477 { 00478 /* not enough memory */ 00479 return DSERR_OUTOFMEMORY; 00480 } 00481 00482 /* initialize object */ 00483 This->ref = 1; 00484 This->lpVtbl = &vt_DirectSound8; 00485 This->bInitialized = FALSE; 00486 *ppvObject = (LPVOID)&This->lpVtbl; 00487 00488 return S_OK; 00489 } 00490 00491 00492 HRESULT 00493 WINAPI 00494 DirectSoundCreate( 00495 LPCGUID lpcGUID, 00496 LPDIRECTSOUND *ppDS, 00497 IUnknown *pUnkOuter) 00498 { 00499 return InternalDirectSoundCreate(lpcGUID, (LPDIRECTSOUND8*)ppDS, pUnkOuter, FALSE); 00500 } 00501 00502 HRESULT 00503 WINAPI 00504 DirectSoundCreate8( 00505 LPCGUID lpcGUID, 00506 LPDIRECTSOUND8 *ppDS, 00507 IUnknown *pUnkOuter) 00508 { 00509 return InternalDirectSoundCreate(lpcGUID, ppDS, pUnkOuter, TRUE); 00510 } Generated on Sun May 27 2012 04:21:43 for ReactOS by
1.7.6.1
|