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