strmbase: Implement BaseControlWindow.
[wine/multimedia.git] / dlls / dsound / tests / capture.c
blob96fb4172b5a4f1ef1fc89d0894ece6822a367758
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdio.h>
23 #include "initguid.h"
24 #include "windows.h"
25 #include "wine/test.h"
26 #include "dsound.h"
27 #include "mmreg.h"
28 #include "dsconf.h"
30 #include "dsound_test.h"
32 #define NOTIFICATIONS 5
34 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
35 static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
37 static const char * get_format_str(WORD format)
39 static char msg[32];
40 #define WAVE_FORMAT(f) case f: return #f
41 switch (format) {
42 WAVE_FORMAT(WAVE_FORMAT_PCM);
43 WAVE_FORMAT(WAVE_FORMAT_ADPCM);
44 WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
45 WAVE_FORMAT(WAVE_FORMAT_ALAW);
46 WAVE_FORMAT(WAVE_FORMAT_MULAW);
47 WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
48 WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
49 WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
50 WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
51 WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
52 WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
53 WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
54 WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
55 WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
56 WAVE_FORMAT(WAVE_FORMAT_SONARC);
57 WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
58 WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
59 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
60 WAVE_FORMAT(WAVE_FORMAT_APTX);
61 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
62 WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
63 WAVE_FORMAT(WAVE_FORMAT_GSM610);
64 WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
65 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
66 WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
67 WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
68 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
69 WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
70 WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
71 WAVE_FORMAT(WAVE_FORMAT_MPEG);
72 WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
73 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
74 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
75 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
76 WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
77 WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
78 WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
79 WAVE_FORMAT(WAVE_FORMAT_OLICELP);
80 WAVE_FORMAT(WAVE_FORMAT_OLISBC);
81 WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
82 WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
83 WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
85 #undef WAVE_FORMAT
86 sprintf(msg, "Unknown(0x%04x)", format);
87 return msg;
90 const char * format_string(const WAVEFORMATEX* wfx)
92 static char str[64];
94 sprintf(str, "%5dx%2dx%d %s",
95 wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
96 get_format_str(wfx->wFormatTag));
98 return str;
101 static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco,
102 BOOL initialized, LPCGUID lpGuid)
104 HRESULT rc;
105 DSCCAPS dsccaps;
106 int ref;
107 IUnknown * unknown;
108 IDirectSoundCapture * dsc;
110 /* Try to Query for objects */
111 rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IUnknown,
112 (LPVOID*)&unknown);
113 ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IUnknown) "
114 "failed: %08x\n", rc);
115 if (rc==DS_OK)
116 IDirectSoundCapture_Release(unknown);
118 rc=IDirectSoundCapture_QueryInterface(dsco, &IID_IDirectSoundCapture,
119 (LPVOID*)&dsc);
120 ok(rc==DS_OK, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) "
121 "failed: %08x\n", rc);
122 if (rc==DS_OK)
123 IDirectSoundCapture_Release(dsc);
125 if (initialized == FALSE) {
126 /* try uninitialized object */
127 rc=IDirectSoundCapture_GetCaps(dsco,0);
128 ok(rc==DSERR_UNINITIALIZED||rc==E_INVALIDARG,
129 "IDirectSoundCapture_GetCaps(NULL) should have returned "
130 "DSERR_UNINITIALIZED or E_INVALIDARG, returned: %08x\n", rc);
132 rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
133 ok(rc==DSERR_UNINITIALIZED,"IDirectSoundCapture_GetCaps() "
134 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc);
136 rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
137 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||
138 rc==E_FAIL||rc==E_INVALIDARG,
139 "IDirectSoundCapture_Initialize() failed: %08x\n", rc);
140 if (rc==DSERR_NODRIVER||rc==E_INVALIDARG) {
141 trace(" No Driver\n");
142 goto EXIT;
143 } else if (rc==E_FAIL) {
144 trace(" No Device\n");
145 goto EXIT;
146 } else if (rc==DSERR_ALLOCATED) {
147 trace(" Already In Use\n");
148 goto EXIT;
152 rc=IDirectSoundCapture_Initialize(dsco, lpGuid);
153 ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSoundCapture_Initialize() "
154 "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc);
156 /* DSOUND: Error: Invalid caps buffer */
157 rc=IDirectSoundCapture_GetCaps(dsco, 0);
158 ok(rc==DSERR_INVALIDPARAM, "IDirectSoundCapture_GetCaps(NULL) "
159 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
161 ZeroMemory(&dsccaps, sizeof(dsccaps));
163 /* DSOUND: Error: Invalid caps buffer */
164 rc=IDirectSound_GetCaps(dsco, &dsccaps);
165 ok(rc==DSERR_INVALIDPARAM, "IDirectSound_GetCaps() "
166 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
168 dsccaps.dwSize=sizeof(dsccaps);
170 /* DSOUND: Running on a certified driver */
171 rc=IDirectSoundCapture_GetCaps(dsco, &dsccaps);
172 ok(rc==DS_OK, "IDirectSoundCapture_GetCaps() failed: %08x\n", rc);
174 EXIT:
175 ref=IDirectSoundCapture_Release(dsco);
176 ok(ref==0, "IDirectSoundCapture_Release() has %d references, "
177 "should have 0\n", ref);
180 static void test_capture(void)
182 HRESULT rc;
183 LPDIRECTSOUNDCAPTURE dsco=NULL;
184 LPCLASSFACTORY cf=NULL;
186 trace("Testing IDirectSoundCapture\n");
188 rc=CoGetClassObject(&CLSID_DirectSoundCapture, CLSCTX_INPROC_SERVER, NULL,
189 &IID_IClassFactory, (void**)&cf);
190 ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSoundCapture, IID_IClassFactory) "
191 "failed: %08x\n", rc);
193 rc=CoGetClassObject(&CLSID_DirectSoundCapture, CLSCTX_INPROC_SERVER, NULL,
194 &IID_IUnknown, (void**)&cf);
195 ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSoundCapture, IID_IUnknown) "
196 "failed: %08x\n", rc);
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: %08x\n", rc);
202 if (rc==REGDB_E_CLASSNOTREG) {
203 trace(" Class Not Registered\n");
204 return;
206 if (dsco)
207 IDirectSoundCapture_test(dsco, FALSE, NULL);
209 /* try the COM class factory method of creation with default capture
210 * device specified */
211 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
212 &IID_IDirectSoundCapture, (void**)&dsco);
213 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %08x\n", rc);
214 if (dsco)
215 IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultCapture);
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: %08x\n", rc);
222 if (dsco)
223 IDirectSoundCapture_test(dsco, FALSE, &DSDEVID_DefaultVoiceCapture);
225 /* try the COM class factory method of creation with a bad
226 * IID specified */
227 rc=CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
228 &CLSID_DirectSoundPrivate, (void**)&dsco);
229 ok(rc==E_NOINTERFACE,
230 "CoCreateInstance(CLSID_DirectSoundCapture,CLSID_DirectSoundPrivate) "
231 "should have failed: %08x\n",rc);
233 /* try with no device specified */
234 rc=pDirectSoundCaptureCreate(NULL,&dsco,NULL);
235 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
236 "DirectSoundCaptureCreate(NULL) failed: %08x\n",rc);
237 if (rc==S_OK && dsco)
238 IDirectSoundCapture_test(dsco, TRUE, NULL);
240 /* try with default capture device specified */
241 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultCapture,&dsco,NULL);
242 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
243 "DirectSoundCaptureCreate(DSDEVID_DefaultCapture) failed: %08x\n", rc);
244 if (rc==DS_OK && dsco)
245 IDirectSoundCapture_test(dsco, TRUE, NULL);
247 /* try with default voice capture device specified */
248 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture,&dsco,NULL);
249 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
250 "DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %08x\n", rc);
251 if (rc==DS_OK && dsco)
252 IDirectSoundCapture_test(dsco, TRUE, NULL);
254 /* try with a bad device specified */
255 rc=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback,&dsco,NULL);
256 ok(rc==DSERR_NODRIVER,
257 "DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
258 "should have failed: %08x\n",rc);
259 if (rc==DS_OK && dsco)
260 IDirectSoundCapture_Release(dsco);
263 typedef struct {
264 char* wave;
265 DWORD wave_len;
267 LPDIRECTSOUNDCAPTUREBUFFER dscbo;
268 LPWAVEFORMATEX wfx;
269 DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
270 HANDLE event[NOTIFICATIONS];
271 LPDIRECTSOUNDNOTIFY notify;
273 DWORD buffer_size;
274 DWORD read;
275 DWORD offset;
276 DWORD size;
278 DWORD last_pos;
279 } capture_state_t;
281 static int capture_buffer_service(capture_state_t* state)
283 HRESULT rc;
284 LPVOID ptr1,ptr2;
285 DWORD len1,len2;
286 DWORD capture_pos,read_pos;
288 rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
289 &read_pos);
290 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %08x\n", rc);
291 if (rc!=DS_OK)
292 return 0;
294 rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
295 &ptr1,&len1,&ptr2,&len2,0);
296 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %08x\n", rc);
297 if (rc!=DS_OK)
298 return 0;
300 rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
301 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %08x\n", rc);
302 if (rc!=DS_OK)
303 return 0;
305 state->offset = (state->offset + state->size) % state->buffer_size;
307 return 1;
310 static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
311 LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
313 HRESULT rc;
314 DSCBCAPS dscbcaps;
315 WAVEFORMATEX wfx;
316 DWORD size,status;
317 capture_state_t state;
318 int i, ref;
320 /* Private dsound.dll: Error: Invalid caps pointer */
321 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
322 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
323 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
325 /* Private dsound.dll: Error: Invalid caps pointer */
326 dscbcaps.dwSize=0;
327 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
328 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
329 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
331 dscbcaps.dwSize=sizeof(dscbcaps);
332 rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
333 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %08x\n", rc);
334 if (rc==DS_OK && winetest_debug > 1) {
335 trace(" Caps: size = %d flags=0x%08x buffer size=%d\n",
336 dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
339 /* Query the format size. Note that it may not match sizeof(wfx) */
340 /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
341 * be non-NULL */
342 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
343 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
344 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
346 size=0;
347 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
348 ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
349 "have returned the needed size: rc=%08x, size=%d\n", rc,size);
351 rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
352 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetFormat() failed: %08x\n", rc);
353 if (rc==DS_OK && winetest_debug > 1) {
354 trace(" Format: tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
355 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
356 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
359 /* Private dsound.dll: Error: Invalid status pointer */
360 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0);
361 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetStatus() should "
362 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
364 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
365 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %08x\n", rc);
366 if (rc==DS_OK && winetest_debug > 1) {
367 trace(" Status=0x%04x\n",status);
370 ZeroMemory(&state, sizeof(state));
371 state.dscbo=dscbo;
372 state.wfx=&wfx;
373 state.buffer_size = dscbcaps.dwBufferBytes;
374 for (i = 0; i < NOTIFICATIONS; i++)
375 state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
376 state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
378 rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
379 (void **)&(state.notify));
380 ok((rc==DS_OK)&&(state.notify!=NULL),
381 "IDirectSoundCaptureBuffer_QueryInterface() failed: %08x\n", rc);
383 for (i = 0; i < NOTIFICATIONS; i++) {
384 state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
385 state.posnotify[i].hEventNotify = state.event[i];
388 rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,
389 state.posnotify);
390 ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions() failed: %08x\n", rc);
392 ref=IDirectSoundNotify_Release(state.notify);
393 ok(ref==0,"IDirectSoundNotify_Release(): has %d references, should have "
394 "0\n",ref);
396 if (record) {
397 rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
398 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Start() failed: %08x\n", rc);
400 rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
401 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %08x\n", rc);
402 ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING),
403 "GetStatus: bad status: %x\n",status);
405 /* wait for the notifications */
406 for (i = 0; i < (NOTIFICATIONS * 2); i++) {
407 rc=WaitForMultipleObjects(NOTIFICATIONS,state.event,FALSE,3000);
408 ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),
409 "WaitForMultipleObjects failed: 0x%x\n",rc);
410 if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) {
411 ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),
412 "Wrong notification: should be %d, got %d\n",
413 i%NOTIFICATIONS,rc-WAIT_OBJECT_0);
415 if (!capture_buffer_service(&state))
416 break;
419 rc=IDirectSoundCaptureBuffer_Stop(dscbo);
420 ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Stop() failed: %08x\n", rc);
424 static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
425 LPCSTR lpcstrModule, LPVOID lpContext)
427 HRESULT rc;
428 LPDIRECTSOUNDCAPTURE dsco=NULL;
429 LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
430 DSCBUFFERDESC bufdesc;
431 WAVEFORMATEX wfx;
432 DSCCAPS dsccaps;
433 DWORD f;
434 int ref;
436 /* Private dsound.dll: Error: Invalid interface buffer */
437 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
438 rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
439 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
440 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);
442 rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
443 ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
444 "DirectSoundCaptureCreate() failed: %08x\n",rc);
445 if (rc!=DS_OK) {
446 if (rc==DSERR_NODRIVER)
447 trace(" No Driver\n");
448 else if (rc==E_FAIL)
449 trace(" No Device\n");
450 else if (rc==DSERR_ALLOCATED)
451 trace(" Already In Use\n");
452 goto EXIT;
455 /* Private dsound.dll: Error: Invalid caps buffer */
456 rc=IDirectSoundCapture_GetCaps(dsco,NULL);
457 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
458 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);
460 /* Private dsound.dll: Error: Invalid caps buffer */
461 dsccaps.dwSize=0;
462 rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
463 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
464 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);
466 dsccaps.dwSize=sizeof(dsccaps);
467 rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
468 ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %08x\n", rc);
469 if (rc==DS_OK && winetest_debug > 1) {
470 trace(" Caps: size=%d flags=0x%08x formats=%05x channels=%d\n",
471 dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
472 dsccaps.dwChannels);
475 /* Private dsound.dll: Error: Invalid size */
476 /* Private dsound.dll: Error: Invalid capture buffer description */
477 ZeroMemory(&bufdesc, sizeof(bufdesc));
478 bufdesc.dwSize=0;
479 bufdesc.dwFlags=0;
480 bufdesc.dwBufferBytes=0;
481 bufdesc.dwReserved=0;
482 bufdesc.lpwfxFormat=NULL;
483 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
484 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
485 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
486 if (rc==DS_OK) {
487 ref=IDirectSoundCaptureBuffer_Release(dscbo);
488 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
489 "should have 0\n",ref);
492 /* Private dsound.dll: Error: Invalid buffer size */
493 /* Private dsound.dll: Error: Invalid capture buffer description */
494 ZeroMemory(&bufdesc, sizeof(bufdesc));
495 bufdesc.dwSize=sizeof(bufdesc);
496 bufdesc.dwFlags=0;
497 bufdesc.dwBufferBytes=0;
498 bufdesc.dwReserved=0;
499 bufdesc.lpwfxFormat=NULL;
500 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
501 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
502 "should have returned DSERR_INVALIDPARAM, returned %08x\n", rc);
503 if (rc==DS_OK) {
504 ref=IDirectSoundCaptureBuffer_Release(dscbo);
505 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
506 "should have 0\n",ref);
509 /* Private dsound.dll: Error: Invalid buffer size */
510 /* Private dsound.dll: Error: Invalid capture buffer description */
511 ZeroMemory(&bufdesc, sizeof(bufdesc));
512 ZeroMemory(&wfx, sizeof(wfx));
513 bufdesc.dwSize=sizeof(bufdesc);
514 bufdesc.dwFlags=0;
515 bufdesc.dwBufferBytes=0;
516 bufdesc.dwReserved=0;
517 bufdesc.lpwfxFormat=&wfx;
518 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
519 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
520 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", 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 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
530 ZeroMemory(&bufdesc, sizeof(bufdesc));
531 bufdesc.dwSize=sizeof(bufdesc);
532 bufdesc.dwFlags=0;
533 bufdesc.dwBufferBytes=0;
534 bufdesc.dwReserved=0;
535 bufdesc.lpwfxFormat=&wfx;
536 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
537 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
538 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", 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 for (f=0;f<NB_FORMATS;f++) {
546 dscbo=NULL;
547 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
548 formats[f][2]);
549 ZeroMemory(&bufdesc, sizeof(bufdesc));
550 bufdesc.dwSize=sizeof(bufdesc);
551 bufdesc.dwFlags=0;
552 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
553 bufdesc.dwReserved=0;
554 bufdesc.lpwfxFormat=&wfx;
555 if (winetest_interactive)
556 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
557 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
558 ok(((rc==DS_OK)&&(dscbo!=NULL))
559 || rc==DSERR_BADFORMAT || rc==DSERR_INVALIDCALL || rc==DSERR_NODRIVER
560 || rc==DSERR_ALLOCATED || rc==E_INVALIDARG || rc==E_FAIL,
561 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
562 "%s capture buffer: %08x\n",format_string(&wfx),rc);
563 if (rc==DS_OK) {
564 test_capture_buffer(dsco, dscbo, winetest_interactive);
565 ref=IDirectSoundCaptureBuffer_Release(dscbo);
566 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
567 "should have 0\n",ref);
568 } else if (rc==DSERR_BADFORMAT) {
569 ok(!(dsccaps.dwFormats & formats[f][3]),
570 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
571 "capture buffer: format listed as supported but using it failed\n");
572 if (!(dsccaps.dwFormats & formats[f][3]))
573 trace(" Format not supported: %s\n", format_string(&wfx));
574 } else if (rc==DSERR_NODRIVER) {
575 trace(" No Driver\n");
576 } else if (rc==DSERR_ALLOCATED) {
577 trace(" Already In Use\n");
578 } else if (rc==E_INVALIDARG) { /* try the old version struct */
579 DSCBUFFERDESC1 bufdesc1;
580 ZeroMemory(&bufdesc1, sizeof(bufdesc1));
581 bufdesc1.dwSize=sizeof(bufdesc1);
582 bufdesc1.dwFlags=0;
583 bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
584 bufdesc1.dwReserved=0;
585 bufdesc1.lpwfxFormat=&wfx;
586 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
587 (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
588 ok(rc==DS_OK || broken(rc==DSERR_INVALIDPARAM),
589 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
590 "%s capture buffer: %08x\n",format_string(&wfx), rc);
591 if (rc==DSERR_INVALIDPARAM) {
592 skip("broken driver\n");
593 goto EXIT;
595 if (rc==DS_OK) {
596 test_capture_buffer(dsco, dscbo, winetest_interactive);
597 ref=IDirectSoundCaptureBuffer_Release(dscbo);
598 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
599 "references, should have 0\n",ref);
601 } else if (rc==E_FAIL) {
602 /* WAVE_FORMAT_PCM only allows 8 and 16 bits per sample, so only
603 * report a failure if the bits per sample is 8 or 16
605 if (wfx.wBitsPerSample == 8 || wfx.wBitsPerSample == 16)
606 ok(FALSE,"Should not fail for 8 or 16 bits per sample\n");
610 /* try a non PCM format */
611 if (0)
613 /* FIXME: Why is this commented out? */
614 init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
615 ZeroMemory(&bufdesc, sizeof(bufdesc));
616 bufdesc.dwSize=sizeof(bufdesc);
617 bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
618 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
619 bufdesc.dwReserved=0;
620 bufdesc.lpwfxFormat=&wfx;
621 if (winetest_interactive)
622 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
623 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
624 ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
625 "failed to create a capture buffer: %08x\n",rc);
626 if ((rc==DS_OK)&&(dscbo!=NULL)) {
627 test_capture_buffer(dsco, dscbo, winetest_interactive);
628 ref=IDirectSoundCaptureBuffer_Release(dscbo);
629 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
630 "should have 0\n",ref);
634 /* Try an invalid format to test error handling */
635 if (0)
637 /* FIXME: Remove this test altogether? */
638 init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
639 ZeroMemory(&bufdesc, sizeof(bufdesc));
640 bufdesc.dwSize=sizeof(bufdesc);
641 bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
642 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
643 bufdesc.dwReserved=0;
644 bufdesc.lpwfxFormat=&wfx;
645 if (winetest_interactive)
646 trace(" Testing the capture buffer at %s\n", format_string(&wfx));
647 rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
648 ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
649 "at 2 MHz %08x\n",rc);
652 EXIT:
653 if (dsco!=NULL) {
654 ref=IDirectSoundCapture_Release(dsco);
655 ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
656 "have 0\n",ref);
659 return TRUE;
662 static void test_enumerate(void)
664 HRESULT rc;
665 rc=pDirectSoundCaptureEnumerateA(&dscenum_callback,NULL);
666 ok(rc==DS_OK,"DirectSoundCaptureEnumerateA() failed: %08x\n", rc);
669 static void test_COM(void)
671 IDirectSoundCapture *dsc = (IDirectSoundCapture*)0xdeadbeef;
672 IDirectSoundCaptureBuffer *buffer = (IDirectSoundCaptureBuffer*)0xdeadbeef;
673 IDirectSoundNotify *notify;
674 DSCBUFFERDESC bufdesc;
675 WAVEFORMATEX wfx;
676 HRESULT hr;
677 ULONG refcount;
679 hr = pDirectSoundCaptureCreate(NULL, &dsc, (IUnknown*)0xdeadbeef);
680 ok(hr == DSERR_NOAGGREGATION,
681 "DirectSoundCaptureCreate failed: %08x, expected DSERR_NOAGGREGATION\n", hr);
682 ok(dsc == (IDirectSoundCapture*)0xdeadbeef, "dsc = %p\n", dsc);
684 hr = pDirectSoundCaptureCreate(NULL, &dsc, NULL);
685 if (hr == DSERR_NODRIVER) {
686 skip("No driver\n");
687 return;
689 ok(hr == DS_OK, "DirectSoundCaptureCreate failed: %08x, expected DS_OK\n", hr);
691 init_format(&wfx, WAVE_FORMAT_PCM, 44100, 16, 1);
692 ZeroMemory(&bufdesc, sizeof(bufdesc));
693 bufdesc.dwSize = sizeof(bufdesc);
694 bufdesc.dwBufferBytes = wfx.nAvgBytesPerSec;
695 bufdesc.lpwfxFormat = &wfx;
697 hr = IDirectSoundCapture_CreateCaptureBuffer(dsc, &bufdesc, &buffer, (IUnknown*)0xdeadbeef);
698 if (hr == E_INVALIDARG) {
699 /* Old DirectX has only the 1st version of the DSCBUFFERDESC struct */
700 bufdesc.dwSize = sizeof(DSCBUFFERDESC1);
701 hr = IDirectSoundCapture_CreateCaptureBuffer(dsc, &bufdesc, &buffer, (IUnknown*)0xdeadbeef);
703 ok(hr == DSERR_NOAGGREGATION,
704 "IDirectSoundCapture_CreateCaptureBuffer failed: %08x, expected DSERR_NOAGGREGATION\n", hr);
705 ok(buffer == (IDirectSoundCaptureBuffer*)0xdeadbeef || !buffer /* Win2k without DirectX9 */,
706 "buffer = %p\n", buffer);
708 hr = IDirectSoundCapture_CreateCaptureBuffer(dsc, &bufdesc, &buffer, NULL);
709 ok(hr == DS_OK, "IDirectSoundCapture_CreateCaptureBuffer failed: %08x, expected DS_OK\n", hr);
711 /* IDirectSoundCaptureBuffer and IDirectSoundNotify have separate refcounts */
712 IDirectSoundCaptureBuffer_AddRef(buffer);
713 refcount = IDirectSoundCaptureBuffer_AddRef(buffer);
714 ok(refcount == 3, "IDirectSoundCaptureBuffer refcount is %u, expected 3\n", refcount);
715 hr = IDirectSoundCaptureBuffer_QueryInterface(buffer, &IID_IDirectSoundNotify, (void**)&notify);
716 ok(hr == DS_OK, "IDirectSoundCapture_QueryInterface failed: %08x, expected DS_OK\n", hr);
717 refcount = IDirectSoundNotify_AddRef(notify);
718 ok(refcount == 2, "IDirectSoundNotify refcount is %u, expected 2\n", refcount);
719 IDirectSoundCaptureBuffer_AddRef(buffer);
720 refcount = IDirectSoundCaptureBuffer_Release(buffer);
721 ok(refcount == 3, "IDirectSoundCaptureBuffer refcount is %u, expected 3\n", refcount);
723 /* Release IDirectSoundCaptureBuffer while keeping IDirectSoundNotify alive */
724 while (IDirectSoundCaptureBuffer_Release(buffer) > 0);
725 refcount = IDirectSoundNotify_AddRef(notify);
726 ok(refcount == 3, "IDirectSoundNotify refcount is %u, expected 3\n", refcount);
727 refcount = IDirectSoundCaptureBuffer_AddRef(buffer);
728 ok(refcount == 1, "IDirectSoundCaptureBuffer refcount is %u, expected 1\n", refcount);
730 while (IDirectSoundNotify_Release(notify) > 0);
731 refcount = IDirectSoundCaptureBuffer_Release(buffer);
732 ok(refcount == 0, "IDirectSoundCaptureBuffer refcount is %u, expected 0\n", refcount);
733 refcount = IDirectSoundCapture_Release(dsc);
734 ok(refcount == 0, "IDirectSoundCapture refcount is %u, expected 0\n", refcount);
737 START_TEST(capture)
739 HMODULE hDsound;
741 CoInitialize(NULL);
743 hDsound = LoadLibrary("dsound.dll");
744 if (!hDsound) {
745 skip("dsound.dll not found!\n");
746 return;
749 pDirectSoundCaptureCreate = (void*)GetProcAddress(hDsound, "DirectSoundCaptureCreate");
750 pDirectSoundCaptureEnumerateA = (void*)GetProcAddress(hDsound, "DirectSoundCaptureEnumerateA");
751 if (!pDirectSoundCaptureCreate || !pDirectSoundCaptureEnumerateA) {
752 skip("capture test skipped\n");
753 return;
756 test_COM();
757 test_capture();
758 test_enumerate();
760 FreeLibrary(hDsound);
761 CoUninitialize();