dsound: Fix capture test.
[wine/hacks.git] / dlls / dsound / tests / capture.c
blob603f378afa38a4ef9f8ffc65bc6aea2fd3d53f79
1 /*
2 * Unit tests for capture functions
4 * Copyright (c) 2002 Francois Gouget
5 * Copyright (c) 2003 Robert Reif
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.
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.
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
22 #define NONAMELESSSTRUCT
23 #define NONAMELESSUNION
24 #include <windows.h>
26 #include <stdio.h>
28 #include "wine/test.h"
29 #include "dsound.h"
30 #include "mmreg.h"
31 #include "dxerr8.h"
32 #include "dsconf.h"
34 #include "dsound_test.h"
36 #define NOTIFICATIONS 5
38 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
39 static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
41 const char * get_format_str(WORD format)
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);
89 #undef WAVE_FORMAT
90 sprintf(msg, "Unknown(0x%04x)", format);
91 return msg;
94 const char * format_string(const WAVEFORMATEX* wfx)
96 static char str[64];
98 sprintf(str, "%5ldx%2dx%d %s",
99 wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
100 get_format_str(wfx->wFormatTag));
102 return str;
105 static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco,
106 BOOL initialized, LPCGUID lpGuid)
108 HRESULT rc;
109 DSCCAPS dsccaps;
110 int ref;
111 IUnknown * unknown;
112 IDirectSoundCapture * dsc;
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);
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);
129 if (initialized == FALSE) {
130 /* try unitialized object */
131 rc=IDirectSoundCapture_GetCaps(dsco,0);
132 ok(rc==DSERR_UNINITIALIZED||rc==E_INVALIDARG,
133 "IDirectSoundCapture_GetCaps(NULL) should have returned "
134 "DSERR_UNINITIALIZED or E_INVALIDARG, returned: %s\n",
135 DXGetErrorString8(rc));
137 rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
138 ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() "
139 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
140 DXGetErrorString8(rc));
142 rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
143 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||
144 rc==E_FAIL||rc==E_INVALIDARG,
145 "IDirectSoundCapture_Initialize() failed: %s\n",
146 DXGetErrorString8(rc));
147 if (rc==DSERR_NODRIVER||rc==E_INVALIDARG) {
148 trace(" No Driver\n");
149 goto EXIT;
150 } else if (rc==E_FAIL) {
151 trace(" No Device\n");
152 goto EXIT;
153 } else if (rc==DSERR_ALLOCATED) {
154 trace(" Already In Use\n");
155 goto EXIT;
159 rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
160 ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() "
161 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
162 DXGetErrorString8(rc));
164 /* DSOUND: Error: Invalid caps buffer */
165 rc=IDirectSoundCapture_GetCaps(dsco, 0);
166 ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) "
167 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
168 DXGetErrorString8(rc));
170 ZeroMemory(&dsccaps, sizeof(dsccaps));
172 /* DSOUND: Error: Invalid caps buffer */
173 rc=IDirectSound_GetCaps(dsco, &dsccaps);
174 ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() "
175 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
176 DXGetErrorString8(rc));
178 dsccaps.dwSize=sizeof(dsccaps);
180 /* DSOUND: Running on a certified driver */
181 rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
182 ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %s\n",
183 DXGetErrorString8(rc));
185 EXIT:
186 ref=IDirectSoundCapture_Release(dsco);
187 ok(ref==0, "IDirectSoundCapture_Release() has %d references, "
188 "should have 0\n", ref);
191 static void IDirectSoundCapture_tests(void)
193 HRESULT rc;
194 LPDIRECTSOUNDCAPTURE dsco=NULL;
196 trace("Testing IDirectSoundCapture\n");
198 /* try the COM class factory method of creation with no device specified */
199 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
200 &IID_IDirectSoundCapture, (void**)&dsco);
201 ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
202 DXGetErrorString8(rc));
203 if (rc==REGDB_E_CLASSNOTREG) {
204 trace(" Class Not Registered\n");
205 return;
207 if (dsco)
208 IDirectSoundCapture_test(dsco, FALSE, NULL);
210 /* try the COM class factory method of creation with default capture
211 * device specified */
212 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
213 &IID_IDirectSoundCapture, (void**)&dsco);
214 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
215 DXGetErrorString8(rc));
216 if (dsco)
217 IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultCapture);
219 /* try the COM class factory method of creation with default voice
220 * capture device specified */
221 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
222 &IID_IDirectSoundCapture, (void**)&dsco);
223 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %s\n",
224 DXGetErrorString8(rc));
225 if (dsco)
226 IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultVoiceCapture);
228 /* try the COM class factory method of creation with a bad
229 * IID specified */
230 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
231 &CLSID_DirectSoundPrivate, (void**)&dsco);
232 ok(rc==E_NOINTERFACE,
233 "CoCreateInstance(CLSID_DirectSoundCapture,CLSID_DirectSoundPrivate) "
234 "should have failed: %s\n",DXGetErrorString8(rc));
236 /* try with no device specified */
237 rc=pDirectSoundCaptureCreate(NULL,&dsco,NULL);
238 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
239 "DirectSoundCaptureCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
240 if (rc==S_OK && dsco)
241 IDirectSoundCapture_test(dsco, TRUE, NULL);
243 /* try with default capture device specified */
244 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultCapture,&dsco,NULL);
245 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
246 "DirectSoundCaptureCreate(DSDEVID_DefaultCapture) failed: %s\n",
247 DXGetErrorString8(rc));
248 if (rc==DS_OK && dsco)
249 IDirectSoundCapture_test(dsco, TRUE, NULL);
251 /* try with default voice capture device specified */
252 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture,&dsco,NULL);
253 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
254 "DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %s\n",
255 DXGetErrorString8(rc));
256 if (rc==DS_OK && dsco)
257 IDirectSoundCapture_test(dsco, TRUE, NULL);
259 /* try with a bad device specified */
260 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback,&dsco,NULL);
261 ok(rc==DSERR_NODRIVER,
262 "DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
263 "should have failed: %s\n",DXGetErrorString8(rc));
264 if (rc==DS_OK && dsco)
265 IDirectSoundCapture_Release(dsco);
268 typedef struct {
269 char* wave;
270 DWORD wave_len;
272 LPDIRECTSOUNDCAPTUREBUFFER dscbo;
273 LPWAVEFORMATEX wfx;
274 DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
275 HANDLE event[NOTIFICATIONS];
276 LPDIRECTSOUNDNOTIFY notify;
278 DWORD buffer_size;
279 DWORD read;
280 DWORD offset;
281 DWORD size;
283 DWORD last_pos;
284 } capture_state_t;
286 static int capture_buffer_service(capture_state_t* state)
288 HRESULT rc;
289 LPVOID ptr1,ptr2;
290 DWORD len1,len2;
291 DWORD capture_pos,read_pos;
293 rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
294 &read_pos);
295 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %s\n",
296 DXGetErrorString8(rc));
297 if (rc!=DS_OK)
298 return 0;
300 rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
301 &ptr1,&len1,&ptr2,&len2,0);
302 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %s\n",
303 DXGetErrorString8(rc));
304 if (rc!=DS_OK)
305 return 0;
307 rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
308 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %s\n",
309 DXGetErrorString8(rc));
310 if (rc!=DS_OK)
311 return 0;
313 state->offset = (state->offset + state->size) % state->buffer_size;
315 return 1;
318 static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
319 LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
321 HRESULT rc;
322 DSCBCAPS dscbcaps;
323 WAVEFORMATEX wfx;
324 DWORD size,status;
325 capture_state_t state;
326 int i, ref;
328 /* Private dsound.dll: Error: Invalid caps pointer */
329 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
330 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
331 "have returned DSERR_INVALIDPARAM, returned: %s\n",
332 DXGetErrorString8(rc));
334 /* Private dsound.dll: Error: Invalid caps pointer */
335 dscbcaps.dwSize=0;
336 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
337 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
338 "have returned DSERR_INVALIDPARAM, returned: %s\n",
339 DXGetErrorString8(rc));
341 dscbcaps.dwSize=sizeof(dscbcaps);
342 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
343 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %s\n",
344 DXGetErrorString8(rc));
345 if (rc==DS_OK && winetest_debug > 1) {
346 trace(" Caps: size = %ld flags=0x%08lx buffer size=%ld\n",
347 dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
350 /* Query the format size. Note that it may not match sizeof(wfx) */
351 /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
352 * be non-NULL */
353 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
354 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
355 "have returned DSERR_INVALIDPARAM, returned: %s\n",
356 DXGetErrorString8(rc));
358 size=0;
359 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
360 ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
361 "have returned the needed size: rc=%s, size=%ld\n",
362 DXGetErrorString8(rc),size);
364 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
365 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetFormat() failed: %s\n",
366 DXGetErrorString8(rc));
367 if (rc==DS_OK && winetest_debug > 1) {
368 trace(" Format: tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
369 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
370 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
373 /* Private dsound.dll: Error: Invalid status pointer */
374 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0);
375 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetStatus() should "
376 "have returned DSERR_INVALIDPARAM, returned: %s\n",
377 DXGetErrorString8(rc));
379 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
380 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
381 DXGetErrorString8(rc));
382 if (rc==DS_OK && winetest_debug > 1) {
383 trace(" Status=0x%04lx\n",status);
386 ZeroMemory(&state, sizeof(state));
387 state.dscbo=dscbo;
388 state.wfx=&wfx;
389 state.buffer_size = dscbcaps.dwBufferBytes;
390 for (i = 0; i < NOTIFICATIONS; i++)
391 state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
392 state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
394 rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
395 (void **)&(state.notify));
396 ok((rc==DS_OK)&&(state.notify!=NULL),
397 "IDirectSoundCaptureBuffer_QueryInterface() failed: %s\n",
398 DXGetErrorString8(rc));
399 if (rc!=DS_OK)
400 return;
402 for (i = 0; i < NOTIFICATIONS; i++) {
403 state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
404 state.posnotify[i].hEventNotify = state.event[i];
407 rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,
408 state.posnotify);
409 ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions() failed: %s\n",
410 DXGetErrorString8(rc));
411 if (rc!=DS_OK)
412 return;
414 ref=IDirectSoundNotify_Release(state.notify);
415 ok(ref==0,"IDirectSoundNotify_Release(): has %d references, should have "
416 "0\n",ref);
417 if (ref!=0)
418 return;
420 if (record) {
421 rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
422 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Start() failed: %s\n",
423 DXGetErrorString8(rc));
424 if (rc!=DS_OK)
425 return;
427 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
428 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
429 DXGetErrorString8(rc));
430 ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING),
431 "GetStatus: bad status: %lx\n",status);
432 if (rc!=DS_OK)
433 return;
435 /* wait for the notifications */
436 for (i = 0; i < (NOTIFICATIONS * 2); i++) {
437 rc=WaitForMultipleObjects(NOTIFICATIONS,state.event,FALSE,3000);
438 ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),
439 "WaitForMultipleObjects failed: 0x%lx\n",rc);
440 if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) {
441 ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),
442 "Wrong notification: should be %d, got %ld\n",
443 i%NOTIFICATIONS,rc-WAIT_OBJECT_0);
445 if (!capture_buffer_service(&state))
446 break;
449 rc=IDirectSoundCaptureBuffer_Stop(dscbo);
450 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Stop() failed: %s\n",
451 DXGetErrorString8(rc));
452 if (rc!=DS_OK)
453 return;
457 static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
458 LPCSTR lpcstrModule, LPVOID lpContext)
460 HRESULT rc;
461 LPDIRECTSOUNDCAPTURE dsco=NULL;
462 LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
463 DSCBUFFERDESC bufdesc;
464 WAVEFORMATEX wfx;
465 DSCCAPS dsccaps;
466 DWORD f;
467 int ref;
469 /* Private dsound.dll: Error: Invalid interface buffer */
470 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
471 rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
472 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
473 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
475 rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
476 ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
477 "DirectSoundCaptureCreate() failed: %s\n",DXGetErrorString8(rc));
478 if (rc!=DS_OK) {
479 if (rc==DSERR_NODRIVER)
480 trace(" No Driver\n");
481 else if (rc==E_FAIL)
482 trace(" No Device\n");
483 else if (rc==DSERR_ALLOCATED)
484 trace(" Already In Use\n");
485 goto EXIT;
488 /* Private dsound.dll: Error: Invalid caps buffer */
489 rc=IDirectSoundCapture_GetCaps(dsco,NULL);
490 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
491 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
493 /* Private dsound.dll: Error: Invalid caps buffer */
494 dsccaps.dwSize=0;
495 rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
496 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
497 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
499 dsccaps.dwSize=sizeof(dsccaps);
500 rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
501 ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %s\n",
502 DXGetErrorString8(rc));
503 if (rc==DS_OK && winetest_debug > 1) {
504 trace(" Caps: size=%ld flags=0x%08lx formats=%05lx channels=%ld\n",
505 dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
506 dsccaps.dwChannels);
509 /* Private dsound.dll: Error: Invalid size */
510 /* Private dsound.dll: Error: Invalid capture buffer description */
511 ZeroMemory(&bufdesc, sizeof(bufdesc));
512 bufdesc.dwSize=0;
513 bufdesc.dwFlags=0;
514 bufdesc.dwBufferBytes=0;
515 bufdesc.dwReserved=0;
516 bufdesc.lpwfxFormat=NULL;
517 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
518 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
519 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
520 DXGetErrorString8(rc));
521 if (rc==DS_OK) {
522 ref=IDirectSoundCaptureBuffer_Release(dscbo);
523 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
524 "should have 0\n",ref);
527 /* Private dsound.dll: Error: Invalid buffer size */
528 /* Private dsound.dll: Error: Invalid capture buffer description */
529 ZeroMemory(&bufdesc, sizeof(bufdesc));
530 bufdesc.dwSize=sizeof(bufdesc);
531 bufdesc.dwFlags=0;
532 bufdesc.dwBufferBytes=0;
533 bufdesc.dwReserved=0;
534 bufdesc.lpwfxFormat=NULL;
535 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
536 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
537 "should have returned DSERR_INVALIDPARAM, returned %s\n",
538 DXGetErrorString8(rc));
539 if (rc==DS_OK) {
540 ref=IDirectSoundCaptureBuffer_Release(dscbo);
541 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
542 "should have 0\n",ref);
545 /* Private dsound.dll: Error: Invalid buffer size */
546 /* Private dsound.dll: Error: Invalid capture buffer description */
547 ZeroMemory(&bufdesc, sizeof(bufdesc));
548 ZeroMemory(&wfx, sizeof(wfx));
549 bufdesc.dwSize=sizeof(bufdesc);
550 bufdesc.dwFlags=0;
551 bufdesc.dwBufferBytes=0;
552 bufdesc.dwReserved=0;
553 bufdesc.lpwfxFormat=&wfx;
554 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
555 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
556 "should have returned DSERR_INVALIDPARAM, returned :%s\n",
557 DXGetErrorString8(rc));
558 if (rc==DS_OK) {
559 ref=IDirectSoundCaptureBuffer_Release(dscbo);
560 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
561 "should have 0\n",ref);
564 /* Private dsound.dll: Error: Invalid buffer size */
565 /* Private dsound.dll: Error: Invalid capture buffer description */
566 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
567 ZeroMemory(&bufdesc, sizeof(bufdesc));
568 bufdesc.dwSize=sizeof(bufdesc);
569 bufdesc.dwFlags=0;
570 bufdesc.dwBufferBytes=0;
571 bufdesc.dwReserved=0;
572 bufdesc.lpwfxFormat=&wfx;
573 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
574 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
575 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
576 DXGetErrorString8(rc));
577 if (rc==DS_OK) {
578 ref=IDirectSoundCaptureBuffer_Release(dscbo);
579 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
580 "should have 0\n",ref);
583 for (f=0;f<NB_FORMATS;f++) {
584 dscbo=NULL;
585 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
586 formats[f][2]);
587 ZeroMemory(&bufdesc, sizeof(bufdesc));
588 bufdesc.dwSize=sizeof(bufdesc);
589 bufdesc.dwFlags=0;
590 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
591 bufdesc.dwReserved=0;
592 bufdesc.lpwfxFormat=&wfx;
593 if (winetest_interactive)
594 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
595 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
596 ok(((rc==DS_OK)&&(dscbo!=NULL))||(rc==DSERR_BADFORMAT)||
597 ((rc==DSERR_NODRIVER))||(rc==DSERR_ALLOCATED)||(rc==E_INVALIDARG),
598 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
599 "%s capture buffer: %s\n",format_string(&wfx),DXGetErrorString8(rc));
600 if (rc==DS_OK) {
601 test_capture_buffer(dsco, dscbo, winetest_interactive);
602 ref=IDirectSoundCaptureBuffer_Release(dscbo);
603 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
604 "should have 0\n",ref);
605 } else if (rc==DSERR_BADFORMAT) {
606 ok(!(dsccaps.dwFormats & formats[f][3]),
607 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
608 "capture buffer: format listed as supported but using it failed\n");
609 if (!(dsccaps.dwFormats & formats[f][3]))
610 trace(" Format not supported: %s\n", format_string(&wfx));
611 } else if (rc==DSERR_NODRIVER) {
612 trace(" No Driver\n");
613 } else if (rc==DSERR_ALLOCATED) {
614 trace(" Already In Use\n");
615 } else if (rc==E_INVALIDARG) { /* try the old version struct */
616 DSCBUFFERDESC1 bufdesc1;
617 ZeroMemory(&bufdesc1, sizeof(bufdesc1));
618 bufdesc1.dwSize=sizeof(bufdesc1);
619 bufdesc1.dwFlags=0;
620 bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
621 bufdesc1.dwReserved=0;
622 bufdesc1.lpwfxFormat=&wfx;
623 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
624 (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
625 ok(rc==DS_OK,
626 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
627 "%s capture buffer: %s\n",format_string(&wfx),
628 DXGetErrorString8(rc));
629 if (rc==DS_OK) {
630 test_capture_buffer(dsco, dscbo, winetest_interactive);
631 ref=IDirectSoundCaptureBuffer_Release(dscbo);
632 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
633 "references, should have 0\n",ref);
638 /* try a non PCM format */
639 #if 0
640 init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
641 ZeroMemory(&bufdesc, sizeof(bufdesc));
642 bufdesc.dwSize=sizeof(bufdesc);
643 bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
644 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
645 bufdesc.dwReserved=0;
646 bufdesc.lpwfxFormat=&wfx;
647 if (winetest_interactive)
648 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
649 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
650 ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
651 "failed to create a capture buffer: %s\n",DXGetErrorString8(rc));
652 if ((rc==DS_OK)&&(dscbo!=NULL)) {
653 test_capture_buffer(dsco, dscbo, winetest_interactive);
654 ref=IDirectSoundCaptureBuffer_Release(dscbo);
655 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
656 "should have 0\n",ref);
658 #endif
660 /* Try an invalid format to test error handling */
661 #if 0
662 init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
663 ZeroMemory(&bufdesc, sizeof(bufdesc));
664 bufdesc.dwSize=sizeof(bufdesc);
665 bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
666 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
667 bufdesc.dwReserved=0;
668 bufdesc.lpwfxFormat=&wfx;
669 if (winetest_interactive)
670 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
671 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
672 ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
673 "at 2 MHz %s\n",DXGetErrorString8(rc));
674 #endif
676 EXIT:
677 if (dsco!=NULL) {
678 ref=IDirectSoundCapture_Release(dsco);
679 ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
680 "have 0\n",ref);
683 return TRUE;
686 static void capture_tests(void)
688 HRESULT rc;
689 rc=pDirectSoundCaptureEnumerateA(&dscenum_callback,NULL);
690 ok(rc==DS_OK,"DirectSoundCaptureEnumerateA() failed: %s\n",
691 DXGetErrorString8(rc));
694 START_TEST(capture)
696 HMODULE hDsound;
698 CoInitialize(NULL);
700 hDsound = LoadLibraryA("dsound.dll");
701 if (!hDsound) {
702 trace("dsound.dll not found\n");
703 return;
706 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
708 pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate");
709 pDirectSoundCaptureEnumerateA=(void*)GetProcAddress(hDsound,"DirectSoundCaptureEnumerateA");
710 if (!pDirectSoundCaptureCreate || !pDirectSoundCaptureEnumerateA)
712 trace("capture test skipped\n");
713 return;
716 IDirectSoundCapture_tests();
717 capture_tests();
719 CoUninitialize();