ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

directsound.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.