1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Configuration of network devices 4 * FILE: dll/directx/dsound_new/capture.c 5 * PURPOSE: Implement IDirectSoundCapture 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 10 #include "precomp.h" 11 12 typedef struct 13 { 14 IDirectSoundCaptureVtbl *lpVtbl; 15 LONG ref; 16 GUID DeviceGUID; 17 BOOL bInitialized; 18 LPFILTERINFO Filter; 19 }CDirectSoundCaptureImpl, *LPCDirectSoundCaptureImpl; 20 21 HRESULT 22 WINAPI 23 CDirectSoundCapture_fnQueryInterface( 24 LPDIRECTSOUNDCAPTURE8 iface, 25 REFIID riid, 26 LPVOID * ppobj) 27 { 28 LPOLESTR pStr; 29 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); 30 31 /* check if the interface is supported */ 32 if (IsEqualIID(riid, &IID_IUnknown) || 33 IsEqualIID(riid, &IID_IDirectSoundCapture)) 34 { 35 *ppobj = (LPVOID)&This->lpVtbl; 36 InterlockedIncrement(&This->ref); 37 return S_OK; 38 } 39 40 /* unsupported interface */ 41 if (SUCCEEDED(StringFromIID(riid, &pStr))) 42 { 43 DPRINT("No Interface for class %s\n", pStr); 44 CoTaskMemFree(pStr); 45 } 46 return E_NOINTERFACE; 47 } 48 49 ULONG 50 WINAPI 51 CDirectSoundCapture_fnAddRef( 52 LPDIRECTSOUNDCAPTURE8 iface) 53 { 54 ULONG ref; 55 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); 56 57 /* increment reference count */ 58 ref = InterlockedIncrement(&This->ref); 59 60 return ref; 61 } 62 63 ULONG 64 WINAPI 65 CDirectSoundCapture_fnRelease( 66 LPDIRECTSOUNDCAPTURE8 iface) 67 { 68 ULONG ref; 69 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); 70 71 /* release reference count */ 72 ref = InterlockedDecrement(&(This->ref)); 73 74 if (!ref) 75 { 76 HeapFree(GetProcessHeap(), 0, This); 77 } 78 79 return ref; 80 } 81 82 83 HRESULT 84 WINAPI 85 CDirectSoundCapture_fnCreateCaptureBuffer( 86 LPDIRECTSOUNDCAPTURE8 iface, 87 LPCDSCBUFFERDESC lpcDSBufferDesc, 88 LPDIRECTSOUNDCAPTUREBUFFER *ppDSCBuffer, 89 LPUNKNOWN pUnkOuter) 90 { 91 HRESULT hResult; 92 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); 93 94 if (!This->bInitialized) 95 { 96 /* object not yet initialized */ 97 return DSERR_UNINITIALIZED; 98 } 99 100 if (!lpcDSBufferDesc || !ppDSCBuffer || pUnkOuter != NULL) 101 { 102 /* invalid param */ 103 return DSERR_INVALIDPARAM; 104 } 105 106 /* check buffer description */ 107 if ((lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC1)) || 108 lpcDSBufferDesc->dwReserved != 0 || lpcDSBufferDesc->dwBufferBytes == 0 || lpcDSBufferDesc->lpwfxFormat == NULL) 109 { 110 /* invalid buffer description */ 111 return DSERR_INVALIDPARAM; 112 } 113 114 DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n", 115 This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize); 116 117 hResult = NewDirectSoundCaptureBuffer((LPDIRECTSOUNDCAPTUREBUFFER8*)ppDSCBuffer, This->Filter, lpcDSBufferDesc); 118 return hResult; 119 } 120 121 122 HRESULT 123 WINAPI 124 CDirectSoundCapture_fnGetCaps( 125 LPDIRECTSOUNDCAPTURE8 iface, 126 LPDSCCAPS pDSCCaps) 127 { 128 WAVEINCAPSW Caps; 129 MMRESULT Result; 130 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); 131 132 if (!This->bInitialized) 133 { 134 /* object not yet initialized */ 135 return DSERR_UNINITIALIZED; 136 } 137 138 if (!pDSCCaps) 139 { 140 /* invalid param */ 141 return DSERR_INVALIDPARAM; 142 } 143 144 if (pDSCCaps->dwSize != sizeof(DSCCAPS)) 145 { 146 /* invalid param */ 147 return DSERR_INVALIDPARAM; 148 } 149 150 151 /* We are certified ;) */ 152 pDSCCaps->dwFlags = DSCCAPS_CERTIFIED; 153 154 ASSERT(This->Filter); 155 156 Result = waveInGetDevCapsW(This->Filter->MappedId[0], &Caps, sizeof(WAVEINCAPSW)); 157 if (Result != MMSYSERR_NOERROR) 158 { 159 /* failed */ 160 DPRINT("waveInGetDevCapsW for device %u failed with %x\n", This->Filter->MappedId[0], Result); 161 return DSERR_UNSUPPORTED; 162 } 163 164 pDSCCaps->dwFormats = Caps.dwFormats; 165 pDSCCaps->dwChannels = Caps.wChannels; 166 167 return DS_OK; 168 } 169 170 171 HRESULT 172 WINAPI 173 CDirectSoundCapture_fnInitialize( 174 LPDIRECTSOUNDCAPTURE8 iface, 175 LPCGUID pcGuidDevice) 176 { 177 GUID DeviceGuid; 178 LPOLESTR pGuidStr; 179 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl); 180 181 /* sanity check */ 182 ASSERT(RootInfo); 183 184 if (This->bInitialized) 185 { 186 /* object has already been initialized */ 187 return DSERR_ALREADYINITIALIZED; 188 } 189 190 /* fixme mutual exclusion */ 191 192 if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL)) 193 { 194 /* use default playback device id */ 195 pcGuidDevice = &DSDEVID_DefaultCapture; 196 } 197 198 if (IsEqualIID(pcGuidDevice, &DSDEVID_DefaultVoicePlayback) || IsEqualIID(pcGuidDevice, &DSDEVID_DefaultPlayback)) 199 { 200 /* this has to be a winetest */ 201 return DSERR_NODRIVER; 202 } 203 204 /* now verify the guid */ 205 if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK) 206 { 207 if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr))) 208 { 209 DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr); 210 CoTaskMemFree(pGuidStr); 211 } 212 return DSERR_INVALIDPARAM; 213 } 214 215 if (FindDeviceByGuid(&DeviceGuid, &This->Filter)) 216 { 217 This->bInitialized = TRUE; 218 return DS_OK; 219 } 220 221 DPRINT("Failed to find device\n"); 222 return DSERR_INVALIDPARAM; 223 } 224 225 static IDirectSoundCaptureVtbl vt_DirectSoundCapture = 226 { 227 /* IUnknown methods */ 228 CDirectSoundCapture_fnQueryInterface, 229 CDirectSoundCapture_fnAddRef, 230 CDirectSoundCapture_fnRelease, 231 CDirectSoundCapture_fnCreateCaptureBuffer, 232 CDirectSoundCapture_fnGetCaps, 233 CDirectSoundCapture_fnInitialize 234 }; 235 236 HRESULT 237 InternalDirectSoundCaptureCreate( 238 LPCGUID lpcGUID, 239 LPDIRECTSOUNDCAPTURE8 *ppDS, 240 IUnknown *pUnkOuter) 241 { 242 LPCDirectSoundCaptureImpl This; 243 HRESULT hr; 244 245 if (!ppDS || pUnkOuter != NULL) 246 { 247 /* invalid parameter passed */ 248 return DSERR_INVALIDPARAM; 249 } 250 251 /* allocate CDirectSoundCaptureImpl struct */ 252 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl)); 253 if (!This) 254 { 255 /* not enough memory */ 256 return DSERR_OUTOFMEMORY; 257 } 258 259 /* initialize IDirectSoundCapture object */ 260 This->ref = 1; 261 This->lpVtbl = &vt_DirectSoundCapture; 262 263 264 /* initialize direct sound interface */ 265 hr = IDirectSoundCapture_Initialize((LPDIRECTSOUNDCAPTURE8)&This->lpVtbl, lpcGUID); 266 267 /* check for success */ 268 if (!SUCCEEDED(hr)) 269 { 270 /* failed */ 271 DPRINT("Failed to initialize DirectSoundCapture object with %x\n", hr); 272 IDirectSoundCapture_Release((LPDIRECTSOUND8)&This->lpVtbl); 273 return hr; 274 } 275 276 /* store result */ 277 *ppDS = (LPDIRECTSOUNDCAPTURE8)&This->lpVtbl; 278 DPRINT("DirectSoundCapture object %p\n", *ppDS); 279 return DS_OK; 280 } 281 282 HRESULT 283 CALLBACK 284 NewDirectSoundCapture( 285 IUnknown* pUnkOuter, 286 REFIID riid, 287 LPVOID* ppvObject) 288 { 289 LPOLESTR pStr; 290 LPCDirectSoundCaptureImpl This; 291 292 /* check requested interface */ 293 if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IDirectSoundCapture) && !IsEqualIID(riid, &IID_IDirectSoundCapture8)) 294 { 295 *ppvObject = 0; 296 StringFromIID(riid, &pStr); 297 DPRINT("NewDirectSoundCapture does not support Interface %ws\n", pStr); 298 CoTaskMemFree(pStr); 299 return E_NOINTERFACE; 300 } 301 302 /* allocate CDirectSoundCaptureImpl struct */ 303 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl)); 304 if (!This) 305 { 306 /* not enough memory */ 307 return DSERR_OUTOFMEMORY; 308 } 309 310 /* initialize object */ 311 This->ref = 1; 312 This->lpVtbl = &vt_DirectSoundCapture; 313 This->bInitialized = FALSE; 314 *ppvObject = (LPVOID)&This->lpVtbl; 315 316 return S_OK; 317 } 318 319 320 HRESULT 321 WINAPI 322 DirectSoundCaptureCreate( 323 LPCGUID lpcGUID, 324 LPDIRECTSOUNDCAPTURE *ppDSC, 325 LPUNKNOWN pUnkOuter) 326 { 327 return InternalDirectSoundCaptureCreate(lpcGUID, (LPDIRECTSOUNDCAPTURE8*)ppDSC, pUnkOuter); 328 } 329 330 HRESULT 331 WINAPI 332 DirectSoundCaptureCreate8( 333 LPCGUID lpcGUID, 334 LPDIRECTSOUNDCAPTURE8 *ppDSC8, 335 LPUNKNOWN pUnkOuter) 336 { 337 return InternalDirectSoundCaptureCreate(lpcGUID, ppDSC8, pUnkOuter); 338 } 339