- Start rewrite of DirectSound
[reactos.git] / reactos / dll / directx / dsound_new / capturebuffer.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/capturebuffer.c
5 * PURPOSE: IDirectSoundCaptureBuffer8 implementation
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
8 */
9
10
11 #include "precomp.h"
12
13 const GUID KSINTERFACESETID_Standard = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
14 const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
15 const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
16 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
17 const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
18
19
20 typedef struct
21 {
22 IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
23 LONG ref;
24 LPFILTERINFO Filter;
25 HANDLE hPin;
26 PUCHAR Buffer;
27 DWORD BufferSize;
28 LPWAVEFORMATEX Format;
29 KSSTATE State;
30
31
32 }CDirectSoundCaptureBufferImpl, *LPCDirectSoundCaptureBufferImpl;
33
34 HRESULT
35 WINAPI
36 IDirectSoundCaptureBufferImpl_QueryInterface(
37 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
38 IN REFIID riid,
39 LPVOID* ppobj)
40 {
41 LPOLESTR pStr;
42 LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl);
43
44 /* check if requested interface is supported */
45 if (IsEqualIID(riid, &IID_IUnknown) ||
46 IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer) ||
47 IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer8))
48 {
49 *ppobj = (LPVOID)&This->lpVtbl;
50 InterlockedIncrement(&This->ref);
51 return S_OK;
52 }
53
54 /* interface not supported */
55 if (SUCCEEDED(StringFromIID(riid, &pStr)))
56 {
57 DPRINT("No Interface for class %s\n", pStr);
58 CoTaskMemFree(pStr);
59 }
60 return E_NOINTERFACE;
61 }
62
63 ULONG
64 WINAPI
65 IDirectSoundCaptureBufferImpl_AddRef(
66 LPDIRECTSOUNDCAPTUREBUFFER8 iface)
67 {
68 ULONG ref;
69 LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl);
70
71 /* increment reference count */
72 ref = InterlockedIncrement(&This->ref);
73
74 return ref;
75
76 }
77
78 ULONG
79 WINAPI
80 IDirectSoundCaptureBufferImpl_Release(
81 LPDIRECTSOUNDCAPTUREBUFFER8 iface)
82 {
83 ULONG ref;
84 LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl);
85
86 /* release reference count */
87 ref = InterlockedDecrement(&(This->ref));
88
89 if (!ref)
90 {
91 /* free capture buffer */
92 HeapFree(GetProcessHeap(), 0, This->Buffer);
93 HeapFree(GetProcessHeap(), 0, This->Format);
94 HeapFree(GetProcessHeap(), 0, This);
95 }
96
97 return ref;
98 }
99
100
101 HRESULT
102 WINAPI
103 IDirectSoundCaptureBufferImpl_GetCaps(
104 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
105 LPDSCBCAPS lpDSCBCaps )
106 {
107 UNIMPLEMENTED
108 return DSERR_INVALIDPARAM;
109 }
110
111 HRESULT
112 WINAPI
113 IDirectSoundCaptureBufferImpl_GetCurrentPosition(
114 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
115 LPDWORD lpdwCapturePosition,
116 LPDWORD lpdwReadPosition)
117 {
118 UNIMPLEMENTED
119 return DSERR_INVALIDPARAM;
120 }
121
122
123 HRESULT
124 WINAPI
125 IDirectSoundCaptureBufferImpl_GetFormat(
126 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
127 LPWAVEFORMATEX lpwfxFormat,
128 DWORD dwSizeAllocated,
129 LPDWORD lpdwSizeWritten)
130 {
131 UNIMPLEMENTED
132 return DSERR_INVALIDPARAM;
133 }
134
135 HRESULT
136 WINAPI
137 IDirectSoundCaptureBufferImpl_GetStatus(
138 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
139 LPDWORD lpdwStatus )
140 {
141 UNIMPLEMENTED
142 return DSERR_INVALIDPARAM;
143 }
144
145 HRESULT
146 WINAPI
147 IDirectSoundCaptureBufferImpl_Initialize(
148 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
149 LPDIRECTSOUNDCAPTURE lpDSC,
150 LPCDSCBUFFERDESC lpcDSCBDesc)
151 {
152 /* capture buffer is already initialized */
153 return DSERR_ALREADYINITIALIZED;
154 }
155
156 HRESULT
157 WINAPI
158 IDirectSoundCaptureBufferImpl_Lock(
159 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
160 DWORD dwReadCusor,
161 DWORD dwReadBytes,
162 LPVOID* lplpvAudioPtr1,
163 LPDWORD lpdwAudioBytes1,
164 LPVOID* lplpvAudioPtr2,
165 LPDWORD lpdwAudioBytes2,
166 DWORD dwFlags )
167 {
168 UNIMPLEMENTED
169 return DSERR_INVALIDPARAM;
170 }
171
172 HRESULT
173 WINAPI
174 IDirectSoundCaptureBufferImpl_Start(
175 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
176 DWORD dwFlags )
177 {
178 UNIMPLEMENTED
179 return DSERR_INVALIDPARAM;
180 }
181
182 HRESULT
183 WINAPI
184 IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
185 {
186 UNIMPLEMENTED
187 return DSERR_INVALIDPARAM;
188 }
189
190 HRESULT
191 WINAPI
192 IDirectSoundCaptureBufferImpl_Unlock(
193 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
194 LPVOID lpvAudioPtr1,
195 DWORD dwAudioBytes1,
196 LPVOID lpvAudioPtr2,
197 DWORD dwAudioBytes2 )
198 {
199 UNIMPLEMENTED
200 return DSERR_INVALIDPARAM;
201 }
202
203 HRESULT
204 WINAPI
205 IDirectSoundCaptureBufferImpl_GetObjectInPath(
206 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
207 REFGUID rguidObject,
208 DWORD dwIndex,
209 REFGUID rguidInterface,
210 LPVOID* ppObject )
211 {
212 UNIMPLEMENTED
213 return DSERR_INVALIDPARAM;
214 }
215
216 HRESULT
217 WINAPI
218 IDirectSoundCaptureBufferImpl_GetFXStatus(
219 LPDIRECTSOUNDCAPTUREBUFFER8 iface,
220 DWORD dwFXCount,
221 LPDWORD pdwFXStatus )
222 {
223 UNIMPLEMENTED
224 return DSERR_INVALIDPARAM;
225 }
226
227
228 static IDirectSoundCaptureBuffer8Vtbl vt_DirectSoundCaptureBuffer8 =
229 {
230 /* IUnknown methods */
231 IDirectSoundCaptureBufferImpl_QueryInterface,
232 IDirectSoundCaptureBufferImpl_AddRef,
233 IDirectSoundCaptureBufferImpl_Release,
234
235 /* IDirectSoundCaptureBuffer methods */
236 IDirectSoundCaptureBufferImpl_GetCaps,
237 IDirectSoundCaptureBufferImpl_GetCurrentPosition,
238 IDirectSoundCaptureBufferImpl_GetFormat,
239 IDirectSoundCaptureBufferImpl_GetStatus,
240 IDirectSoundCaptureBufferImpl_Initialize,
241 IDirectSoundCaptureBufferImpl_Lock,
242 IDirectSoundCaptureBufferImpl_Start,
243 IDirectSoundCaptureBufferImpl_Stop,
244 IDirectSoundCaptureBufferImpl_Unlock,
245
246 /* IDirectSoundCaptureBuffer methods */
247 IDirectSoundCaptureBufferImpl_GetObjectInPath,
248 IDirectSoundCaptureBufferImpl_GetFXStatus
249 };
250
251
252 HRESULT
253 NewDirectSoundCaptureBuffer(
254 LPDIRECTSOUNDCAPTUREBUFFER8 *OutBuffer,
255 LPFILTERINFO Filter,
256 LPCDSCBUFFERDESC lpcDSBufferDesc)
257 {
258 DWORD FormatSize;
259 ULONG DeviceId = 0, PinId;
260 DWORD Result = ERROR_SUCCESS;
261
262 LPCDirectSoundCaptureBufferImpl This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureBufferImpl));
263
264 if (!This)
265 {
266 /* not enough memory */
267 return DSERR_OUTOFMEMORY;
268 }
269
270 /* calculate format size */
271 FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize;
272 /* allocate format struct */
273 This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize);
274 if (!This->Format)
275 {
276 /* not enough memory */
277 HeapFree(GetProcessHeap(), 0, This);
278 return DSERR_OUTOFMEMORY;
279 }
280
281 /* sanity check */
282 ASSERT(lpcDSBufferDesc->dwBufferBytes);
283
284 /* allocate capture buffer */
285 This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes);
286 if (!This->Buffer)
287 {
288 /* not enough memory */
289 HeapFree(GetProcessHeap(), 0, This->Format);
290 HeapFree(GetProcessHeap(), 0, This);
291 return DSERR_OUTOFMEMORY;
292 }
293
294 /* store buffer size */
295 This->BufferSize = lpcDSBufferDesc->dwBufferBytes;
296 ASSERT(lpcDSBufferDesc->lpwfxFormat->cbSize == 0);
297
298 do
299 {
300 /* try all available recording pins on that filter */
301 PinId = GetPinIdFromFilter(Filter, TRUE, DeviceId);
302 DPRINT("PinId %u DeviceId %u\n", PinId, DeviceId);
303
304 if (PinId == ULONG_MAX)
305 break;
306
307 Result = OpenPin(Filter->hFilter, PinId, lpcDSBufferDesc->lpwfxFormat, &This->hPin, TRUE);
308 if (Result == ERROR_SUCCESS)
309 break;
310
311 DeviceId++;
312 }while(TRUE);
313
314 if (Result != ERROR_SUCCESS)
315 {
316 /* failed to instantiate the capture pin */
317 HeapFree(GetProcessHeap(), 0, This->Buffer);
318 HeapFree(GetProcessHeap(), 0, This->Format);
319 HeapFree(GetProcessHeap(), 0, This);
320 return DSERR_OUTOFMEMORY;
321 }
322
323 /* initialize capture buffer */
324 This->ref = 1;
325 This->lpVtbl = &vt_DirectSoundCaptureBuffer8;
326 This->Filter = Filter;
327 This->State = KSSTATE_STOP;
328
329 *OutBuffer = (LPDIRECTSOUNDCAPTUREBUFFER8)&This->lpVtbl;
330 return DS_OK;
331 }