- Start rewrite of DirectSound
[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 dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), 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 || pDSCCaps->dwSize != sizeof(DSCCAPS))
145 {
146 /* invalid param */
147 return DSERR_INVALIDPARAM;
148 }
149
150 /* We are certified ;) */
151 pDSCCaps->dwFlags = DSCCAPS_CERTIFIED;
152
153 Result = waveInGetDevCapsW(This->Filter->MappedId[0], &Caps, sizeof(WAVEINCAPSW));
154 if (Result != MMSYSERR_NOERROR)
155 {
156 /* failed */
157 DPRINT("waveInGetDevCapsW for device %u failed with %x\n", This->Filter->MappedId[0], Result);
158 return DSERR_UNSUPPORTED;
159 }
160
161 pDSCCaps->dwFormats = Caps.dwFormats;
162 pDSCCaps->dwChannels = Caps.wChannels;
163
164 return DS_OK;
165 }
166
167
168 HRESULT
169 WINAPI
170 CDirectSoundCapture_fnInitialize(
171 LPDIRECTSOUNDCAPTURE8 iface,
172 LPCGUID pcGuidDevice)
173 {
174 GUID DeviceGuid;
175 LPOLESTR pGuidStr;
176 HRESULT hr;
177 LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
178
179 /* sanity check */
180 ASSERT(RootInfo);
181
182 if (This->bInitialized)
183 {
184 /* object has already been initialized */
185 return DSERR_ALREADYINITIALIZED;
186 }
187
188 /* fixme mutual exlucsion */
189
190 if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL))
191 {
192 /* use default playback device id */
193 pcGuidDevice = &DSDEVID_DefaultCapture;
194 }
195
196 /* now verify the guid */
197 if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK)
198 {
199 if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr)))
200 {
201 DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr);
202 CoTaskMemFree(pGuidStr);
203 }
204 return DSERR_INVALIDPARAM;
205 }
206
207 hr = FindDeviceByGuid(&DeviceGuid, &This->Filter);
208
209 if (SUCCEEDED(hr))
210 {
211 This->bInitialized = TRUE;
212 return DS_OK;
213 }
214
215 DPRINT("Failed to find device\n");
216 return DSERR_INVALIDPARAM;
217 }
218
219 static IDirectSoundCaptureVtbl vt_DirectSoundCapture =
220 {
221 /* IUnknown methods */
222 CDirectSoundCapture_fnQueryInterface,
223 CDirectSoundCapture_fnAddRef,
224 CDirectSoundCapture_fnRelease,
225 CDirectSoundCapture_fnCreateCaptureBuffer,
226 CDirectSoundCapture_fnGetCaps,
227 CDirectSoundCapture_fnInitialize
228 };
229
230 HRESULT
231 InternalDirectSoundCaptureCreate(
232 LPCGUID lpcGUID,
233 LPDIRECTSOUNDCAPTURE8 *ppDS,
234 IUnknown *pUnkOuter)
235 {
236 LPCDirectSoundCaptureImpl This;
237 HRESULT hr;
238
239 if (!ppDS || pUnkOuter != NULL)
240 {
241 /* invalid parameter passed */
242 return DSERR_INVALIDPARAM;
243 }
244
245 /* allocate CDirectSoundCaptureImpl struct */
246 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl));
247 if (!This)
248 {
249 /* not enough memory */
250 return DSERR_OUTOFMEMORY;
251 }
252
253 /* initialize IDirectSoundCapture object */
254 This->ref = 1;
255 This->lpVtbl = &vt_DirectSoundCapture;
256
257
258 /* initialize direct sound interface */
259 hr = IDirectSoundCapture_Initialize((LPDIRECTSOUNDCAPTURE8)&This->lpVtbl, lpcGUID);
260
261 /* check for success */
262 if (!SUCCEEDED(hr))
263 {
264 /* failed */
265 DPRINT("Failed to initialize DirectSoundCapture object with %x\n", hr);
266 IDirectSoundCapture_Release((LPDIRECTSOUND8)&This->lpVtbl);
267 return hr;
268 }
269
270 /* store result */
271 *ppDS = (LPDIRECTSOUNDCAPTURE8)&This->lpVtbl;
272 DPRINT("DirectSoundCapture object %p\n", *ppDS);
273 return DS_OK;
274 }
275
276
277
278 HRESULT
279 WINAPI
280 DirectSoundCaptureCreate(
281 LPCGUID lpcGUID,
282 LPDIRECTSOUNDCAPTURE *ppDSC,
283 LPUNKNOWN pUnkOuter)
284 {
285 return InternalDirectSoundCaptureCreate(lpcGUID, (LPDIRECTSOUNDCAPTURE8*)ppDSC, pUnkOuter);
286 }
287
288 HRESULT
289 WINAPI
290 DirectSoundCaptureCreate8(
291 LPCGUID lpcGUID,
292 LPDIRECTSOUNDCAPTURE8 *ppDSC8,
293 LPUNKNOWN pUnkOuter)
294 {
295 return InternalDirectSoundCaptureCreate(lpcGUID, ppDSC8, pUnkOuter);
296 }