4a86ef1b32ca9efda6bdbdb3c4ee2e06dc70ca37
[reactos.git] / reactos / dll / directx / dsound_new / capture.c
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 (janderwald@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 exlucsion */
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 }