Create a branch for network fixes.
[reactos.git] / dll / directx / dsound / tests / capture.c
1 /*
2 * Unit tests for capture functions
3 *
4 * Copyright (c) 2002 Francois Gouget
5 * Copyright (c) 2003 Robert Reif
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #define NONAMELESSSTRUCT
23 #define NONAMELESSUNION
24 #include <windows.h>
25
26 #include <stdio.h>
27
28 #include "wine/test.h"
29 #include "dsound.h"
30 #include "mmreg.h"
31 #include "dxerr8.h"
32 #include "dsconf.h"
33
34 #include "dsound_test.h"
35
36 #define NOTIFICATIONS 5
37
38 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
39 static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
40
41 static const char * get_format_str(WORD format)
42 {
43 static char msg[32];
44 #define WAVE_FORMAT(f) case f: return #f
45 switch (format) {
46 WAVE_FORMAT(WAVE_FORMAT_PCM);
47 WAVE_FORMAT(WAVE_FORMAT_ADPCM);
48 WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
49 WAVE_FORMAT(WAVE_FORMAT_ALAW);
50 WAVE_FORMAT(WAVE_FORMAT_MULAW);
51 WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
52 WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
53 WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
54 WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
55 WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
56 WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
57 WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
58 WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
59 WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
60 WAVE_FORMAT(WAVE_FORMAT_SONARC);
61 WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
62 WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
63 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
64 WAVE_FORMAT(WAVE_FORMAT_APTX);
65 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
66 WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
67 WAVE_FORMAT(WAVE_FORMAT_GSM610);
68 WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
69 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
70 WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
71 WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
72 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
73 WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
74 WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
75 WAVE_FORMAT(WAVE_FORMAT_MPEG);
76 WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
77 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
78 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
79 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
80 WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
81 WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
82 WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
83 WAVE_FORMAT(WAVE_FORMAT_OLICELP);
84 WAVE_FORMAT(WAVE_FORMAT_OLISBC);
85 WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
86 WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
87 WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
88 }
89 #undef WAVE_FORMAT
90 sprintf(msg, "Unknown(0x%04x)", format);
91 return msg;
92 }
93
94 static char * format_string(WAVEFORMATEX* wfx)
95 {
96 static char str[64];
97
98 sprintf(str, "%5ldx%2dx%d %s",
99 wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
100 get_format_str(wfx->wFormatTag));
101
102 return str;
103 }
104
105 static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco,
106 BOOL initialized, LPCGUID lpGuid)
107 {
108 HRESULT rc;
109 DSCCAPS dsccaps;
110 int ref;
111 IUnknown * unknown;
112 IDirectSoundCapture * dsc;
113
114 /* Try to Query for objects */
115 rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IUnknown,
116 (LPVOID*)&unknown);
117 ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) "
118 "failed: %s\n", DXGetErrorString8(rc));
119 if (rc==DS_OK)
120 IDirectSoundCapture_Release(unknown);
121
122 rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture,
123 (LPVOID*)&dsc);
124 ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) "
125 "failed: %s\n", DXGetErrorString8(rc));
126 if (rc==DS_OK)
127 IDirectSoundCapture_Release(dsc);
128
129 if (initialized == FALSE) {
130 /* try unitialized object */
131 rc=IDirectSoundCapture_GetCaps(dsco,0);
132 ok(rc==DSERR_UNINITIALIZED, "IDirectSoundCapture_GetCaps(NULL) "
133 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
134 DXGetErrorString8(rc));
135
136 rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
137 ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() "
138 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
139 DXGetErrorString8(rc));
140
141 rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
142 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
143 "IDirectSoundCapture_Initialize() failed: %s\n",
144 DXGetErrorString8(rc));
145 if (rc==DSERR_NODRIVER) {
146 trace(" No Driver\n");
147 goto EXIT;
148 } else if (rc==E_FAIL) {
149 trace(" No Device\n");
150 goto EXIT;
151 } else if (rc==DSERR_ALLOCATED) {
152 trace(" Already In Use\n");
153 goto EXIT;
154 }
155 }
156
157 rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
158 ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() "
159 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
160 DXGetErrorString8(rc));
161
162 /* DSOUND: Error: Invalid caps buffer */
163 rc=IDirectSoundCapture_GetCaps(dsco, 0);
164 ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) "
165 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
166 DXGetErrorString8(rc));
167
168 ZeroMemory(&dsccaps, sizeof(dsccaps));
169
170 /* DSOUND: Error: Invalid caps buffer */
171 rc=IDirectSound_GetCaps(dsco, &dsccaps);
172 ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() "
173 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
174 DXGetErrorString8(rc));
175
176 dsccaps.dwSize=sizeof(dsccaps);
177
178 /* DSOUND: Running on a certified driver */
179 rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
180 ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %s\n",
181 DXGetErrorString8(rc));
182
183 EXIT:
184 ref=IDirectSoundCapture_Release(dsco);
185 ok(ref==0, "IDirectSoundCapture_Release() has %d references, "
186 "should have 0\n", ref);
187 }
188
189 static void IDirectSoundCapture_tests(void)
190 {
191 HRESULT rc;
192 LPDIRECTSOUNDCAPTURE dsco=NULL;
193
194 trace("Testing IDirectSoundCapture\n");
195
196 /* try the COM class factory method of creation with no device specified */
197 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
198 &IID_IDirectSoundCapture, (void**)&dsco);
199 ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
200 DXGetErrorString8(rc));
201 if (rc==REGDB_E_CLASSNOTREG) {
202 trace(" Class Not Registered\n");
203 return;
204 }
205 if (dsco)
206 IDirectSoundCapture_test(dsco, FALSE, NULL);
207
208 /* try the COM class factory method of creation with default capture
209 * device specified */
210 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
211 &IID_IDirectSoundCapture, (void**)&dsco);
212 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
213 DXGetErrorString8(rc));
214 if (dsco)
215 IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultCapture);
216
217 /* try the COM class factory method of creation with default voice
218 * capture device specified */
219 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
220 &IID_IDirectSoundCapture, (void**)&dsco);
221 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
222 DXGetErrorString8(rc));
223 if (dsco)
224 IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultVoiceCapture);
225
226 /* try the COM class factory method of creation with a bad
227 * IID specified */
228 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
229 &CLSID_DirectSoundPrivate, (void**)&dsco);
230 ok(rc==E_NOINTERFACE,
231 "CoCreateInstance(CLSID_DirectSoundCapture,CLSID_DirectSoundPrivate) "
232 "should have failed: %s\n",DXGetErrorString8(rc));
233
234 /* try with no device specified */
235 rc=pDirectSoundCaptureCreate(NULL,&dsco,NULL);
236 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
237 "DirectSoundCaptureCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
238 if (rc==S_OK && dsco)
239 IDirectSoundCapture_test(dsco, TRUE, NULL);
240
241 /* try with default capture device specified */
242 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultCapture,&dsco,NULL);
243 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
244 "DirectSoundCaptureCreate(DSDEVID_DefaultCapture) failed: %s\n",
245 DXGetErrorString8(rc));
246 if (rc==DS_OK && dsco)
247 IDirectSoundCapture_test(dsco, TRUE, NULL);
248
249 /* try with default voice capture device specified */
250 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture,&dsco,NULL);
251 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
252 "DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %s\n",
253 DXGetErrorString8(rc));
254 if (rc==DS_OK && dsco)
255 IDirectSoundCapture_test(dsco, TRUE, NULL);
256
257 /* try with a bad device specified */
258 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback,&dsco,NULL);
259 ok(rc==DSERR_NODRIVER,
260 "DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
261 "should have failed: %s\n",DXGetErrorString8(rc));
262 if (rc==DS_OK && dsco)
263 IDirectSoundCapture_Release(dsco);
264 }
265
266 typedef struct {
267 char* wave;
268 DWORD wave_len;
269
270 LPDIRECTSOUNDCAPTUREBUFFER dscbo;
271 LPWAVEFORMATEX wfx;
272 DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
273 HANDLE event[NOTIFICATIONS];
274 LPDIRECTSOUNDNOTIFY notify;
275
276 DWORD buffer_size;
277 DWORD read;
278 DWORD offset;
279 DWORD size;
280
281 DWORD last_pos;
282 } capture_state_t;
283
284 static int capture_buffer_service(capture_state_t* state)
285 {
286 HRESULT rc;
287 LPVOID ptr1,ptr2;
288 DWORD len1,len2;
289 DWORD capture_pos,read_pos;
290
291 rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
292 &read_pos);
293 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %s\n",
294 DXGetErrorString8(rc));
295 if (rc!=DS_OK)
296 return 0;
297
298 rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
299 &ptr1,&len1,&ptr2,&len2,0);
300 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %s\n",
301 DXGetErrorString8(rc));
302 if (rc!=DS_OK)
303 return 0;
304
305 rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
306 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %s\n",
307 DXGetErrorString8(rc));
308 if (rc!=DS_OK)
309 return 0;
310
311 state->offset = (state->offset + state->size) % state->buffer_size;
312
313 return 1;
314 }
315
316 static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
317 LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
318 {
319 HRESULT rc;
320 DSCBCAPS dscbcaps;
321 WAVEFORMATEX wfx;
322 DWORD size,status;
323 capture_state_t state;
324 int i, ref;
325
326 /* Private dsound.dll: Error: Invalid caps pointer */
327 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
328 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
329 "have returned DSERR_INVALIDPARAM, returned: %s\n",
330 DXGetErrorString8(rc));
331
332 /* Private dsound.dll: Error: Invalid caps pointer */
333 dscbcaps.dwSize=0;
334 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
335 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
336 "have returned DSERR_INVALIDPARAM, returned: %s\n",
337 DXGetErrorString8(rc));
338
339 dscbcaps.dwSize=sizeof(dscbcaps);
340 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
341 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %s\n",
342 DXGetErrorString8(rc));
343 if (rc==DS_OK && winetest_debug > 1) {
344 trace(" Caps: size = %ld flags=0x%08lx buffer size=%ld\n",
345 dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
346 }
347
348 /* Query the format size. Note that it may not match sizeof(wfx) */
349 /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
350 * be non-NULL */
351 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
352 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
353 "have returned DSERR_INVALIDPARAM, returned: %s\n",
354 DXGetErrorString8(rc));
355
356 size=0;
357 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
358 ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
359 "have returned the needed size: rc=%s, size=%ld\n",
360 DXGetErrorString8(rc),size);
361
362 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
363 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetFormat() failed: %s\n",
364 DXGetErrorString8(rc));
365 if (rc==DS_OK && winetest_debug > 1) {
366 trace(" Format: tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
367 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
368 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
369 }
370
371 /* Private dsound.dll: Error: Invalid status pointer */
372 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0);
373 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetStatus() should "
374 "have returned DSERR_INVALIDPARAM, returned: %s\n",
375 DXGetErrorString8(rc));
376
377 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
378 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
379 DXGetErrorString8(rc));
380 if (rc==DS_OK && winetest_debug > 1) {
381 trace(" Status=0x%04lx\n",status);
382 }
383
384 ZeroMemory(&state, sizeof(state));
385 state.dscbo=dscbo;
386 state.wfx=&wfx;
387 state.buffer_size = dscbcaps.dwBufferBytes;
388 for (i = 0; i < NOTIFICATIONS; i++)
389 state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
390 state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
391
392 rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
393 (void **)&(state.notify));
394 ok((rc==DS_OK)&&(state.notify!=NULL),
395 "IDirectSoundCaptureBuffer_QueryInterface() failed: %s\n",
396 DXGetErrorString8(rc));
397 if (rc!=DS_OK)
398 return;
399
400 for (i = 0; i < NOTIFICATIONS; i++) {
401 state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
402 state.posnotify[i].hEventNotify = state.event[i];
403 }
404
405 rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,
406 state.posnotify);
407 ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions() failed: %s\n",
408 DXGetErrorString8(rc));
409 if (rc!=DS_OK)
410 return;
411
412 ref=IDirectSoundNotify_Release(state.notify);
413 ok(ref==0,"IDirectSoundNotify_Release(): has %d references, should have "
414 "0\n",ref);
415 if (ref!=0)
416 return;
417
418 if (record) {
419 rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
420 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Start() failed: %s\n",
421 DXGetErrorString8(rc));
422 if (rc!=DS_OK)
423 return;
424
425 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
426 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
427 DXGetErrorString8(rc));
428 ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING),
429 "GetStatus: bad status: %lx\n",status);
430 if (rc!=DS_OK)
431 return;
432
433 /* wait for the notifications */
434 for (i = 0; i < (NOTIFICATIONS * 2); i++) {
435 rc=WaitForMultipleObjects(NOTIFICATIONS,state.event,FALSE,3000);
436 ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),
437 "WaitForMultipleObjects failed: 0x%lx\n",rc);
438 if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) {
439 ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),
440 "Wrong notification: should be %d, got %ld\n",
441 i%NOTIFICATIONS,rc-WAIT_OBJECT_0);
442 }
443 if (!capture_buffer_service(&state))
444 break;
445 }
446
447 rc=IDirectSoundCaptureBuffer_Stop(dscbo);
448 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Stop() failed: %s\n",
449 DXGetErrorString8(rc));
450 if (rc!=DS_OK)
451 return;
452 }
453 }
454
455 static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
456 LPCSTR lpcstrModule, LPVOID lpContext)
457 {
458 HRESULT rc;
459 LPDIRECTSOUNDCAPTURE dsco=NULL;
460 LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
461 DSCBUFFERDESC bufdesc;
462 WAVEFORMATEX wfx;
463 DSCCAPS dsccaps;
464 DWORD f;
465 int ref;
466
467 /* Private dsound.dll: Error: Invalid interface buffer */
468 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
469 rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
470 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
471 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
472 if (rc==DS_OK) {
473 ref=IDirectSoundCapture_Release(dsco);
474 ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
475 "have 0\n",ref);
476 }
477
478 rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
479 ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
480 "DirectSoundCaptureCreate() failed: %s\n",DXGetErrorString8(rc));
481 if (rc!=DS_OK) {
482 if (rc==DSERR_NODRIVER)
483 trace(" No Driver\n");
484 else if (rc==E_FAIL)
485 trace(" No Device\n");
486 else if (rc==DSERR_ALLOCATED)
487 trace(" Already In Use\n");
488 goto EXIT;
489 }
490
491 /* Private dsound.dll: Error: Invalid caps buffer */
492 rc=IDirectSoundCapture_GetCaps(dsco,NULL);
493 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
494 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
495
496 /* Private dsound.dll: Error: Invalid caps buffer */
497 dsccaps.dwSize=0;
498 rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
499 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
500 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
501
502 dsccaps.dwSize=sizeof(dsccaps);
503 rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
504 ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %s\n",
505 DXGetErrorString8(rc));
506 if (rc==DS_OK && winetest_debug > 1) {
507 trace(" Caps: size=%ld flags=0x%08lx formats=%05lx channels=%ld\n",
508 dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
509 dsccaps.dwChannels);
510 }
511
512 /* Private dsound.dll: Error: Invalid size */
513 /* Private dsound.dll: Error: Invalid capture buffer description */
514 ZeroMemory(&bufdesc, sizeof(bufdesc));
515 bufdesc.dwSize=0;
516 bufdesc.dwFlags=0;
517 bufdesc.dwBufferBytes=0;
518 bufdesc.dwReserved=0;
519 bufdesc.lpwfxFormat=NULL;
520 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
521 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
522 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
523 DXGetErrorString8(rc));
524 if (rc==DS_OK) {
525 ref=IDirectSoundCaptureBuffer_Release(dscbo);
526 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
527 "should have 0\n",ref);
528 }
529
530 /* Private dsound.dll: Error: Invalid buffer size */
531 /* Private dsound.dll: Error: Invalid capture buffer description */
532 ZeroMemory(&bufdesc, sizeof(bufdesc));
533 bufdesc.dwSize=sizeof(bufdesc);
534 bufdesc.dwFlags=0;
535 bufdesc.dwBufferBytes=0;
536 bufdesc.dwReserved=0;
537 bufdesc.lpwfxFormat=NULL;
538 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
539 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
540 "should have returned DSERR_INVALIDPARAM, returned %s\n",
541 DXGetErrorString8(rc));
542 if (rc==DS_OK) {
543 ref=IDirectSoundCaptureBuffer_Release(dscbo);
544 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
545 "should have 0\n",ref);
546 }
547
548 /* Private dsound.dll: Error: Invalid buffer size */
549 /* Private dsound.dll: Error: Invalid capture buffer description */
550 ZeroMemory(&bufdesc, sizeof(bufdesc));
551 ZeroMemory(&wfx, sizeof(wfx));
552 bufdesc.dwSize=sizeof(bufdesc);
553 bufdesc.dwFlags=0;
554 bufdesc.dwBufferBytes=0;
555 bufdesc.dwReserved=0;
556 bufdesc.lpwfxFormat=&wfx;
557 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
558 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
559 "should have returned DSERR_INVALIDPARAM, returned :%s\n",
560 DXGetErrorString8(rc));
561 if (rc==DS_OK) {
562 ref=IDirectSoundCaptureBuffer_Release(dscbo);
563 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
564 "should have 0\n",ref);
565 }
566
567 /* Private dsound.dll: Error: Invalid buffer size */
568 /* Private dsound.dll: Error: Invalid capture buffer description */
569 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
570 ZeroMemory(&bufdesc, sizeof(bufdesc));
571 bufdesc.dwSize=sizeof(bufdesc);
572 bufdesc.dwFlags=0;
573 bufdesc.dwBufferBytes=0;
574 bufdesc.dwReserved=0;
575 bufdesc.lpwfxFormat=&wfx;
576 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
577 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
578 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
579 DXGetErrorString8(rc));
580 if (rc==DS_OK) {
581 ref=IDirectSoundCaptureBuffer_Release(dscbo);
582 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
583 "should have 0\n",ref);
584 }
585
586 for (f=0;f<NB_FORMATS;f++) {
587 dscbo=NULL;
588 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
589 formats[f][2]);
590 ZeroMemory(&bufdesc, sizeof(bufdesc));
591 bufdesc.dwSize=sizeof(bufdesc);
592 bufdesc.dwFlags=0;
593 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
594 bufdesc.dwReserved=0;
595 bufdesc.lpwfxFormat=&wfx;
596 if (winetest_interactive)
597 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
598 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
599 ok(((rc==DS_OK)&&(dscbo!=NULL))||(rc==DSERR_BADFORMAT)||
600 ((rc==DSERR_NODRIVER))||(rc==DSERR_ALLOCATED)||(rc==E_INVALIDARG),
601 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
602 "%s capture buffer: %s\n",format_string(&wfx),DXGetErrorString8(rc));
603 if (rc==DS_OK) {
604 test_capture_buffer(dsco, dscbo, winetest_interactive);
605 ref=IDirectSoundCaptureBuffer_Release(dscbo);
606 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
607 "should have 0\n",ref);
608 } else if (rc==DSERR_BADFORMAT) {
609 ok(!(dsccaps.dwFormats & formats[f][3]),
610 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
611 "capture buffer: format listed as supported but using it failed\n");
612 if (!(dsccaps.dwFormats & formats[f][3]))
613 trace(" Format not supported: %s\n", format_string(&wfx));
614 } else if (rc==DSERR_NODRIVER) {
615 trace(" No Driver\n");
616 } else if (rc==DSERR_ALLOCATED) {
617 trace(" Already In Use\n");
618 } else if (rc==E_INVALIDARG) { /* try the old version struct */
619 DSCBUFFERDESC1 bufdesc1;
620 ZeroMemory(&bufdesc1, sizeof(bufdesc1));
621 bufdesc1.dwSize=sizeof(bufdesc1);
622 bufdesc1.dwFlags=0;
623 bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
624 bufdesc1.dwReserved=0;
625 bufdesc1.lpwfxFormat=&wfx;
626 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
627 (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
628 ok(rc==DS_OK,
629 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
630 "%s capture buffer: %s\n",format_string(&wfx),
631 DXGetErrorString8(rc));
632 if (rc==DS_OK) {
633 test_capture_buffer(dsco, dscbo, winetest_interactive);
634 ref=IDirectSoundCaptureBuffer_Release(dscbo);
635 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
636 "references, should have 0\n",ref);
637 }
638 }
639 }
640
641 /* try a non PCM format */
642 #if 0
643 init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
644 ZeroMemory(&bufdesc, sizeof(bufdesc));
645 bufdesc.dwSize=sizeof(bufdesc);
646 bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
647 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
648 bufdesc.dwReserved=0;
649 bufdesc.lpwfxFormat=&wfx;
650 if (winetest_interactive)
651 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
652 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
653 ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
654 "failed to create a capture buffer: %s\n",DXGetErrorString8(rc));
655 if ((rc==DS_OK)&&(dscbo!=NULL)) {
656 test_capture_buffer(dsco, dscbo, winetest_interactive);
657 ref=IDirectSoundCaptureBuffer_Release(dscbo);
658 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
659 "should have 0\n",ref);
660 }
661 #endif
662
663 /* Try an invalid format to test error handling */
664 #if 0
665 init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
666 ZeroMemory(&bufdesc, sizeof(bufdesc));
667 bufdesc.dwSize=sizeof(bufdesc);
668 bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
669 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
670 bufdesc.dwReserved=0;
671 bufdesc.lpwfxFormat=&wfx;
672 if (winetest_interactive)
673 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
674 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
675 ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
676 "at 2 MHz %s\n",DXGetErrorString8(rc));
677 #endif
678
679 EXIT:
680 if (dsco!=NULL) {
681 ref=IDirectSoundCapture_Release(dsco);
682 ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
683 "have 0\n",ref);
684 }
685
686 return TRUE;
687 }
688
689 static void capture_tests(void)
690 {
691 HRESULT rc;
692 rc=pDirectSoundCaptureEnumerateA(&dscenum_callback,NULL);
693 ok(rc==DS_OK,"DirectSoundCaptureEnumerateA() failed: %s\n",
694 DXGetErrorString8(rc));
695 }
696
697 START_TEST(capture)
698 {
699 HMODULE hDsound;
700
701 CoInitialize(NULL);
702
703 hDsound = LoadLibraryA("dsound.dll");
704 if (!hDsound) {
705 trace("dsound.dll not found\n");
706 return;
707 }
708
709 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
710
711 pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate");
712 pDirectSoundCaptureEnumerateA=(void*)GetProcAddress(hDsound,"DirectSoundCaptureEnumerateA");
713 if (!pDirectSoundCaptureCreate || !pDirectSoundCaptureEnumerateA)
714 {
715 trace("capture test skipped\n");
716 return;
717 }
718
719 IDirectSoundCapture_tests();
720 capture_tests();
721
722 CoUninitialize();
723 }