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
26 #include "wine/test.h"
31 #include "dsound_test.h"
33 #define NOTIFICATIONS 5
35 static HRESULT (WINAPI
*pDirectSoundCaptureCreate
)(LPCGUID
,LPDIRECTSOUNDCAPTURE
*,LPUNKNOWN
)=NULL
;
36 static HRESULT (WINAPI
*pDirectSoundCaptureEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
38 static const char * get_format_str(WORD format
)
41 #define WAVE_FORMAT(f) case f: return #f
43 WAVE_FORMAT(WAVE_FORMAT_PCM
);
44 WAVE_FORMAT(WAVE_FORMAT_ADPCM
);
45 WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD
);
46 WAVE_FORMAT(WAVE_FORMAT_ALAW
);
47 WAVE_FORMAT(WAVE_FORMAT_MULAW
);
48 WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM
);
49 WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM
);
50 WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM
);
51 WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM
);
52 WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM
);
53 WAVE_FORMAT(WAVE_FORMAT_DIGISTD
);
54 WAVE_FORMAT(WAVE_FORMAT_DIGIFIX
);
55 WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM
);
56 WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM
);
57 WAVE_FORMAT(WAVE_FORMAT_SONARC
);
58 WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH
);
59 WAVE_FORMAT(WAVE_FORMAT_ECHOSC1
);
60 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36
);
61 WAVE_FORMAT(WAVE_FORMAT_APTX
);
62 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10
);
63 WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2
);
64 WAVE_FORMAT(WAVE_FORMAT_GSM610
);
65 WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME
);
66 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC
);
67 WAVE_FORMAT(WAVE_FORMAT_DIGIREAL
);
68 WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM
);
69 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10
);
70 WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM
);
71 WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM
);
72 WAVE_FORMAT(WAVE_FORMAT_MPEG
);
73 WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3
);
74 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM
);
75 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8
);
76 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10
);
77 WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND
);
78 WAVE_FORMAT(WAVE_FORMAT_OLIGSM
);
79 WAVE_FORMAT(WAVE_FORMAT_OLIADPCM
);
80 WAVE_FORMAT(WAVE_FORMAT_OLICELP
);
81 WAVE_FORMAT(WAVE_FORMAT_OLISBC
);
82 WAVE_FORMAT(WAVE_FORMAT_OLIOPR
);
83 WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT
);
84 WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE
);
87 sprintf(msg
, "Unknown(0x%04x)", format
);
91 const char * format_string(const WAVEFORMATEX
* wfx
)
95 sprintf(str
, "%5dx%2dx%d %s",
96 wfx
->nSamplesPerSec
, wfx
->wBitsPerSample
, wfx
->nChannels
,
97 get_format_str(wfx
->wFormatTag
));
102 static void IDirectSoundCapture_test(LPDIRECTSOUNDCAPTURE dsco
,
103 BOOL initialized
, LPCGUID lpGuid
)
109 IDirectSoundCapture
* dsc
;
111 /* Try to Query for objects */
112 rc
=IDirectSoundCapture_QueryInterface(dsco
, &IID_IUnknown
,
114 ok(rc
==DS_OK
, "IDirectSoundCapture_QueryInterface(IID_IUnknown) "
115 "failed: %08x\n", rc
);
117 IUnknown_Release(unknown
);
119 rc
=IDirectSoundCapture_QueryInterface(dsco
, &IID_IDirectSoundCapture
,
121 ok(rc
==DS_OK
, "IDirectSoundCapture_QueryInterface(IID_IDirectSoundCapture) "
122 "failed: %08x\n", rc
);
124 IDirectSoundCapture_Release(dsc
);
126 if (initialized
== FALSE
) {
127 /* try uninitialized object */
128 rc
=IDirectSoundCapture_GetCaps(dsco
,0);
129 ok(rc
==DSERR_UNINITIALIZED
||rc
==E_INVALIDARG
,
130 "IDirectSoundCapture_GetCaps(NULL) should have returned "
131 "DSERR_UNINITIALIZED or E_INVALIDARG, returned: %08x\n", rc
);
133 rc
=IDirectSoundCapture_GetCaps(dsco
, &dsccaps
);
134 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSoundCapture_GetCaps() "
135 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
137 rc
=IDirectSoundCapture_Initialize(dsco
, lpGuid
);
138 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||
139 rc
==E_FAIL
||rc
==E_INVALIDARG
,
140 "IDirectSoundCapture_Initialize() failed: %08x\n", rc
);
141 if (rc
==DSERR_NODRIVER
||rc
==E_INVALIDARG
) {
142 trace(" No Driver\n");
144 } else if (rc
==E_FAIL
) {
145 trace(" No Device\n");
147 } else if (rc
==DSERR_ALLOCATED
) {
148 trace(" Already In Use\n");
153 rc
=IDirectSoundCapture_Initialize(dsco
, lpGuid
);
154 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSoundCapture_Initialize() "
155 "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc
);
157 /* DSOUND: Error: Invalid caps buffer */
158 rc
=IDirectSoundCapture_GetCaps(dsco
, 0);
159 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundCapture_GetCaps(NULL) "
160 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
162 ZeroMemory(&dsccaps
, sizeof(dsccaps
));
164 /* DSOUND: Error: Invalid caps buffer */
165 rc
=IDirectSoundCapture_GetCaps(dsco
, &dsccaps
);
166 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSound_GetCaps() "
167 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
169 dsccaps
.dwSize
=sizeof(dsccaps
);
171 /* DSOUND: Running on a certified driver */
172 rc
=IDirectSoundCapture_GetCaps(dsco
, &dsccaps
);
173 ok(rc
==DS_OK
, "IDirectSoundCapture_GetCaps() failed: %08x\n", rc
);
176 ref
=IDirectSoundCapture_Release(dsco
);
177 ok(ref
==0, "IDirectSoundCapture_Release() has %d references, "
178 "should have 0\n", ref
);
181 static void test_capture(void)
184 LPDIRECTSOUNDCAPTURE dsco
=NULL
;
185 LPCLASSFACTORY cf
=NULL
;
187 trace("Testing IDirectSoundCapture\n");
189 rc
=CoGetClassObject(&CLSID_DirectSoundCapture
, CLSCTX_INPROC_SERVER
, NULL
,
190 &IID_IClassFactory
, (void**)&cf
);
191 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSoundCapture, IID_IClassFactory) "
192 "failed: %08x\n", rc
);
194 rc
=CoGetClassObject(&CLSID_DirectSoundCapture
, CLSCTX_INPROC_SERVER
, NULL
,
195 &IID_IUnknown
, (void**)&cf
);
196 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSoundCapture, IID_IUnknown) "
197 "failed: %08x\n", rc
);
199 /* try the COM class factory method of creation with no device specified */
200 rc
=CoCreateInstance(&CLSID_DirectSoundCapture
, NULL
, CLSCTX_INPROC_SERVER
,
201 &IID_IDirectSoundCapture
, (void**)&dsco
);
202 ok(rc
==S_OK
||rc
==REGDB_E_CLASSNOTREG
,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %08x\n", rc
);
203 if (rc
==REGDB_E_CLASSNOTREG
) {
204 trace(" Class Not Registered\n");
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: %08x\n", rc
);
216 IDirectSoundCapture_test(dsco
, FALSE
, &DSDEVID_DefaultCapture
);
218 /* try the COM class factory method of creation with default voice
219 * capture device specified */
220 rc
=CoCreateInstance(&CLSID_DirectSoundCapture
, NULL
, CLSCTX_INPROC_SERVER
,
221 &IID_IDirectSoundCapture
, (void**)&dsco
);
222 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSoundCapture) failed: %08x\n", rc
);
224 IDirectSoundCapture_test(dsco
, FALSE
, &DSDEVID_DefaultVoiceCapture
);
226 /* try the COM class factory method of creation with a bad
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: %08x\n",rc
);
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: %08x\n",rc
);
238 if (rc
==S_OK
&& dsco
)
239 IDirectSoundCapture_test(dsco
, TRUE
, NULL
);
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: %08x\n", rc
);
245 if (rc
==DS_OK
&& dsco
)
246 IDirectSoundCapture_test(dsco
, TRUE
, NULL
);
248 /* try with default voice capture device specified */
249 rc
=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoiceCapture
,&dsco
,NULL
);
250 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
251 "DirectSoundCaptureCreate(DSDEVID_DefaultVoiceCapture) failed: %08x\n", rc
);
252 if (rc
==DS_OK
&& dsco
)
253 IDirectSoundCapture_test(dsco
, TRUE
, NULL
);
255 /* try with a bad device specified */
256 rc
=pDirectSoundCaptureCreate(&DSDEVID_DefaultVoicePlayback
,&dsco
,NULL
);
257 ok(rc
==DSERR_NODRIVER
,
258 "DirectSoundCaptureCreate(DSDEVID_DefaultVoicePlatback) "
259 "should have failed: %08x\n",rc
);
260 if (rc
==DS_OK
&& dsco
)
261 IDirectSoundCapture_Release(dsco
);
268 LPDIRECTSOUNDCAPTUREBUFFER dscbo
;
270 DSBPOSITIONNOTIFY posnotify
[NOTIFICATIONS
];
271 HANDLE event
[NOTIFICATIONS
];
272 LPDIRECTSOUNDNOTIFY notify
;
282 static BOOL
capture_buffer_service(capture_state_t
* state
)
287 DWORD capture_pos
,read_pos
;
289 rc
=IDirectSoundCaptureBuffer_GetCurrentPosition(state
->dscbo
,&capture_pos
,
291 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %08x\n", rc
);
295 rc
=IDirectSoundCaptureBuffer_Lock(state
->dscbo
,state
->offset
,state
->size
,
296 &ptr1
,&len1
,&ptr2
,&len2
,0);
297 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_Lock() failed: %08x\n", rc
);
301 rc
=IDirectSoundCaptureBuffer_Unlock(state
->dscbo
,ptr1
,len1
,ptr2
,len2
);
302 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_Unlock() failed: %08x\n", rc
);
306 state
->offset
= (state
->offset
+ state
->size
) % state
->buffer_size
;
311 static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco
,
312 LPDIRECTSOUNDCAPTUREBUFFER dscbo
, int record
)
318 capture_state_t state
;
321 /* Private dsound.dll: Error: Invalid caps pointer */
322 rc
=IDirectSoundCaptureBuffer_GetCaps(dscbo
,0);
323 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCaptureBuffer_GetCaps() should "
324 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
326 /* Private dsound.dll: Error: Invalid caps pointer */
328 rc
=IDirectSoundCaptureBuffer_GetCaps(dscbo
,&dscbcaps
);
329 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCaptureBuffer_GetCaps() should "
330 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
332 dscbcaps
.dwSize
=sizeof(dscbcaps
);
333 rc
=IDirectSoundCaptureBuffer_GetCaps(dscbo
,&dscbcaps
);
334 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_GetCaps() failed: %08x\n", rc
);
335 if (rc
==DS_OK
&& winetest_debug
> 1) {
336 trace(" Caps: size = %d flags=0x%08x buffer size=%d\n",
337 dscbcaps
.dwSize
,dscbcaps
.dwFlags
,dscbcaps
.dwBufferBytes
);
340 /* Query the format size. Note that it may not match sizeof(wfx) */
341 /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
343 rc
=IDirectSoundCaptureBuffer_GetFormat(dscbo
,NULL
,0,NULL
);
344 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCaptureBuffer_GetFormat() should "
345 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
348 rc
=IDirectSoundCaptureBuffer_GetFormat(dscbo
,NULL
,0,&size
);
349 ok(rc
==DS_OK
&& size
!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
350 "have returned the needed size: rc=%08x, size=%d\n", rc
,size
);
352 rc
=IDirectSoundCaptureBuffer_GetFormat(dscbo
,&wfx
,sizeof(wfx
),NULL
);
353 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_GetFormat() failed: %08x\n", rc
);
354 if (rc
==DS_OK
&& winetest_debug
> 1) {
355 trace(" Format: tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
356 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
357 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
360 /* Private dsound.dll: Error: Invalid status pointer */
361 rc
=IDirectSoundCaptureBuffer_GetStatus(dscbo
,0);
362 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCaptureBuffer_GetStatus() should "
363 "have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
365 rc
=IDirectSoundCaptureBuffer_GetStatus(dscbo
,&status
);
366 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_GetStatus() failed: %08x\n", rc
);
367 if (rc
==DS_OK
&& winetest_debug
> 1) {
368 trace(" Status=0x%04x\n",status
);
371 ZeroMemory(&state
, sizeof(state
));
374 state
.buffer_size
= dscbcaps
.dwBufferBytes
;
375 for (i
= 0; i
< NOTIFICATIONS
; i
++)
376 state
.event
[i
] = CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
377 state
.size
= dscbcaps
.dwBufferBytes
/ NOTIFICATIONS
;
379 rc
=IDirectSoundCaptureBuffer_QueryInterface(dscbo
,&IID_IDirectSoundNotify
,
380 (void **)&(state
.notify
));
381 ok((rc
==DS_OK
)&&(state
.notify
!=NULL
),
382 "IDirectSoundCaptureBuffer_QueryInterface() failed: %08x\n", rc
);
384 for (i
= 0; i
< NOTIFICATIONS
; i
++) {
385 state
.posnotify
[i
].dwOffset
= (i
* state
.size
) + state
.size
- 1;
386 state
.posnotify
[i
].hEventNotify
= state
.event
[i
];
389 rc
=IDirectSoundNotify_SetNotificationPositions(state
.notify
,NOTIFICATIONS
,
391 ok(rc
==DS_OK
,"IDirectSoundNotify_SetNotificationPositions() failed: %08x\n", rc
);
393 ref
=IDirectSoundNotify_Release(state
.notify
);
394 ok(ref
==0,"IDirectSoundNotify_Release(): has %d references, should have "
397 rc
=IDirectSoundCaptureBuffer_Start(dscbo
,DSCBSTART_LOOPING
);
398 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_Start() failed: %08x\n", rc
);
400 rc
=IDirectSoundCaptureBuffer_Start(dscbo
,0);
401 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_Start() failed: %08x\n", rc
);
403 rc
=IDirectSoundCaptureBuffer_GetStatus(dscbo
,&status
);
404 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_GetStatus() failed: %08x\n", rc
);
405 ok(status
==(DSCBSTATUS_CAPTURING
|DSCBSTATUS_LOOPING
) || broken(status
==DSCBSTATUS_CAPTURING
),
406 "GetStatus: bad status: %x\n",status
);
409 /* wait for the notifications */
410 for (i
= 0; i
< (NOTIFICATIONS
* 2); i
++) {
411 rc
=WaitForMultipleObjects(NOTIFICATIONS
,state
.event
,FALSE
,3000);
412 ok(rc
==(WAIT_OBJECT_0
+(i
%NOTIFICATIONS
)),
413 "WaitForMultipleObjects failed: 0x%x\n",rc
);
414 if (rc
!=(WAIT_OBJECT_0
+(i
%NOTIFICATIONS
))) {
415 ok((rc
==WAIT_TIMEOUT
)||(rc
==WAIT_FAILED
),
416 "Wrong notification: should be %d, got %d\n",
417 i
%NOTIFICATIONS
,rc
-WAIT_OBJECT_0
);
419 if (!capture_buffer_service(&state
))
424 rc
=IDirectSoundCaptureBuffer_Stop(dscbo
);
425 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_Stop() failed: %08x\n", rc
);
427 rc
=IDirectSoundCaptureBuffer_Stop(dscbo
);
428 ok(rc
==DS_OK
,"IDirectSoundCaptureBuffer_Stop() failed: %08x\n", rc
);
431 static BOOL WINAPI
dscenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
432 LPCSTR lpcstrModule
, LPVOID lpContext
)
435 LPDIRECTSOUNDCAPTURE dsco
=NULL
;
436 LPDIRECTSOUNDCAPTUREBUFFER dscbo
=NULL
;
437 DSCBUFFERDESC bufdesc
;
443 /* Private dsound.dll: Error: Invalid interface buffer */
444 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
445 rc
=pDirectSoundCaptureCreate(lpGuid
,NULL
,NULL
);
446 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCaptureCreate() should have "
447 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
449 rc
=pDirectSoundCaptureCreate(lpGuid
,&dsco
,NULL
);
450 ok((rc
==DS_OK
)||(rc
==DSERR_NODRIVER
)||(rc
==E_FAIL
)||(rc
==DSERR_ALLOCATED
),
451 "DirectSoundCaptureCreate() failed: %08x\n",rc
);
453 if (rc
==DSERR_NODRIVER
)
454 trace(" No Driver\n");
456 trace(" No Device\n");
457 else if (rc
==DSERR_ALLOCATED
)
458 trace(" Already In Use\n");
462 /* Private dsound.dll: Error: Invalid caps buffer */
463 rc
=IDirectSoundCapture_GetCaps(dsco
,NULL
);
464 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCapture_GetCaps() should have "
465 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
467 /* Private dsound.dll: Error: Invalid caps buffer */
469 rc
=IDirectSoundCapture_GetCaps(dsco
,&dsccaps
);
470 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCapture_GetCaps() should have "
471 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
473 dsccaps
.dwSize
=sizeof(dsccaps
);
474 rc
=IDirectSoundCapture_GetCaps(dsco
,&dsccaps
);
475 ok(rc
==DS_OK
,"IDirectSoundCapture_GetCaps() failed: %08x\n", rc
);
476 if (rc
==DS_OK
&& winetest_debug
> 1) {
477 trace(" Caps: size=%d flags=0x%08x formats=%05x channels=%d\n",
478 dsccaps
.dwSize
,dsccaps
.dwFlags
,dsccaps
.dwFormats
,
482 /* Private dsound.dll: Error: Invalid size */
483 /* Private dsound.dll: Error: Invalid capture buffer description */
484 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
487 bufdesc
.dwBufferBytes
=0;
488 bufdesc
.dwReserved
=0;
489 bufdesc
.lpwfxFormat
=NULL
;
490 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
491 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCapture_CreateCaptureBuffer() "
492 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
494 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
495 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
496 "should have 0\n",ref
);
499 /* Private dsound.dll: Error: Invalid buffer size */
500 /* Private dsound.dll: Error: Invalid capture buffer description */
501 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
502 bufdesc
.dwSize
=sizeof(bufdesc
);
504 bufdesc
.dwBufferBytes
=0;
505 bufdesc
.dwReserved
=0;
506 bufdesc
.lpwfxFormat
=NULL
;
507 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
508 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCapture_CreateCaptureBuffer() "
509 "should have returned DSERR_INVALIDPARAM, returned %08x\n", rc
);
511 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
512 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
513 "should have 0\n",ref
);
516 /* Private dsound.dll: Error: Invalid buffer size */
517 /* Private dsound.dll: Error: Invalid capture buffer description */
518 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
519 ZeroMemory(&wfx
, sizeof(wfx
));
520 bufdesc
.dwSize
=sizeof(bufdesc
);
522 bufdesc
.dwBufferBytes
=0;
523 bufdesc
.dwReserved
=0;
524 bufdesc
.lpwfxFormat
=&wfx
;
525 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
526 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCapture_CreateCaptureBuffer() "
527 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
529 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
530 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
531 "should have 0\n",ref
);
534 /* Private dsound.dll: Error: Invalid buffer size */
535 /* Private dsound.dll: Error: Invalid capture buffer description */
536 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
537 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
538 bufdesc
.dwSize
=sizeof(bufdesc
);
540 bufdesc
.dwBufferBytes
=0;
541 bufdesc
.dwReserved
=0;
542 bufdesc
.lpwfxFormat
=&wfx
;
543 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
544 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundCapture_CreateCaptureBuffer() "
545 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
547 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
548 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
549 "should have 0\n",ref
);
552 for (f
= 0; f
< ARRAY_SIZE(formats
); f
++) {
554 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
556 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
557 bufdesc
.dwSize
=sizeof(bufdesc
);
559 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
;
560 bufdesc
.dwReserved
=0;
561 bufdesc
.lpwfxFormat
=&wfx
;
562 if (winetest_interactive
)
563 trace(" Testing the capture buffer at %s\n", format_string(&wfx
));
564 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
565 ok(((rc
==DS_OK
)&&(dscbo
!=NULL
))
566 || rc
==DSERR_BADFORMAT
|| rc
==DSERR_INVALIDCALL
|| rc
==DSERR_NODRIVER
567 || rc
==DSERR_ALLOCATED
|| rc
==E_INVALIDARG
|| rc
==E_FAIL
,
568 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
569 "%s capture buffer: %08x\n",format_string(&wfx
),rc
);
571 test_capture_buffer(dsco
, dscbo
, winetest_interactive
);
572 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
573 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
574 "should have 0\n",ref
);
575 } else if (rc
==DSERR_BADFORMAT
) {
576 ok(!(dsccaps
.dwFormats
& formats
[f
][3]),
577 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
578 "capture buffer: format listed as supported but using it failed\n");
579 if (!(dsccaps
.dwFormats
& formats
[f
][3]))
580 trace(" Format not supported: %s\n", format_string(&wfx
));
581 } else if (rc
==DSERR_NODRIVER
) {
582 trace(" No Driver\n");
583 } else if (rc
==DSERR_ALLOCATED
) {
584 trace(" Already In Use\n");
585 } else if (rc
==E_INVALIDARG
) { /* try the old version struct */
586 DSCBUFFERDESC1 bufdesc1
;
587 ZeroMemory(&bufdesc1
, sizeof(bufdesc1
));
588 bufdesc1
.dwSize
=sizeof(bufdesc1
);
590 bufdesc1
.dwBufferBytes
=wfx
.nAvgBytesPerSec
;
591 bufdesc1
.dwReserved
=0;
592 bufdesc1
.lpwfxFormat
=&wfx
;
593 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,
594 (DSCBUFFERDESC
*)&bufdesc1
,&dscbo
,NULL
);
595 ok(rc
==DS_OK
|| broken(rc
==DSERR_INVALIDPARAM
),
596 "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
597 "%s capture buffer: %08x\n",format_string(&wfx
), rc
);
598 if (rc
==DSERR_INVALIDPARAM
) {
599 skip("broken driver\n");
603 test_capture_buffer(dsco
, dscbo
, winetest_interactive
);
604 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
605 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d "
606 "references, should have 0\n",ref
);
608 } else if (rc
==E_FAIL
) {
609 /* WAVE_FORMAT_PCM only allows 8 and 16 bits per sample, so only
610 * report a failure if the bits per sample is 8 or 16
612 if (wfx
.wBitsPerSample
== 8 || wfx
.wBitsPerSample
== 16)
613 ok(FALSE
,"Should not fail for 8 or 16 bits per sample\n");
617 /* try a non PCM format */
620 /* FIXME: Why is this commented out? */
621 init_format(&wfx
,WAVE_FORMAT_MULAW
,8000,8,1);
622 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
623 bufdesc
.dwSize
=sizeof(bufdesc
);
624 bufdesc
.dwFlags
=DSCBCAPS_WAVEMAPPED
;
625 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
;
626 bufdesc
.dwReserved
=0;
627 bufdesc
.lpwfxFormat
=&wfx
;
628 if (winetest_interactive
)
629 trace(" Testing the capture buffer at %s\n", format_string(&wfx
));
630 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
631 ok((rc
==DS_OK
)&&(dscbo
!=NULL
),"IDirectSoundCapture_CreateCaptureBuffer() "
632 "failed to create a capture buffer: %08x\n",rc
);
633 if ((rc
==DS_OK
)&&(dscbo
!=NULL
)) {
634 test_capture_buffer(dsco
, dscbo
, winetest_interactive
);
635 ref
=IDirectSoundCaptureBuffer_Release(dscbo
);
636 ok(ref
==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
637 "should have 0\n",ref
);
641 /* Try an invalid format to test error handling */
644 /* FIXME: Remove this test altogether? */
645 init_format(&wfx
,WAVE_FORMAT_PCM
,2000000,16,2);
646 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
647 bufdesc
.dwSize
=sizeof(bufdesc
);
648 bufdesc
.dwFlags
=DSCBCAPS_WAVEMAPPED
;
649 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
;
650 bufdesc
.dwReserved
=0;
651 bufdesc
.lpwfxFormat
=&wfx
;
652 if (winetest_interactive
)
653 trace(" Testing the capture buffer at %s\n", format_string(&wfx
));
654 rc
=IDirectSoundCapture_CreateCaptureBuffer(dsco
,&bufdesc
,&dscbo
,NULL
);
655 ok(rc
!=DS_OK
,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
656 "at 2 MHz %08x\n",rc
);
661 ref
=IDirectSoundCapture_Release(dsco
);
662 ok(ref
==0,"IDirectSoundCapture_Release() has %d references, should "
669 static void test_enumerate(void)
672 rc
=pDirectSoundCaptureEnumerateA(&dscenum_callback
,NULL
);
673 ok(rc
==DS_OK
,"DirectSoundCaptureEnumerateA() failed: %08x\n", rc
);
676 static void test_COM(void)
678 IDirectSoundCapture
*dsc
= (IDirectSoundCapture
*)0xdeadbeef;
679 IDirectSoundCaptureBuffer
*buffer
= (IDirectSoundCaptureBuffer
*)0xdeadbeef;
680 IDirectSoundNotify
*notify
;
682 DSCBUFFERDESC bufdesc
;
687 hr
= pDirectSoundCaptureCreate(NULL
, &dsc
, (IUnknown
*)0xdeadbeef);
688 ok(hr
== DSERR_NOAGGREGATION
,
689 "DirectSoundCaptureCreate failed: %08x, expected DSERR_NOAGGREGATION\n", hr
);
690 ok(dsc
== (IDirectSoundCapture
*)0xdeadbeef, "dsc = %p\n", dsc
);
692 hr
= pDirectSoundCaptureCreate(NULL
, &dsc
, NULL
);
693 if (hr
== DSERR_NODRIVER
) {
697 ok(hr
== DS_OK
, "DirectSoundCaptureCreate failed: %08x, expected DS_OK\n", hr
);
699 /* Different refcount for IDirectSoundCapture and for IUnknown */
700 refcount
= IDirectSoundCapture_AddRef(dsc
);
701 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
702 hr
= IDirectSoundCapture_QueryInterface(dsc
, &IID_IUnknown
, (void**)&unk
);
703 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
704 refcount
= IUnknown_AddRef(unk
);
705 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
706 IUnknown_Release(unk
);
707 IUnknown_Release(unk
);
708 IDirectSoundCapture_Release(dsc
);
710 init_format(&wfx
, WAVE_FORMAT_PCM
, 44100, 16, 1);
711 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
712 bufdesc
.dwSize
= sizeof(bufdesc
);
713 bufdesc
.dwBufferBytes
= wfx
.nAvgBytesPerSec
;
714 bufdesc
.lpwfxFormat
= &wfx
;
716 hr
= IDirectSoundCapture_CreateCaptureBuffer(dsc
, &bufdesc
, &buffer
, (IUnknown
*)0xdeadbeef);
717 if (hr
== E_INVALIDARG
) {
718 /* Old DirectX has only the 1st version of the DSCBUFFERDESC struct */
719 bufdesc
.dwSize
= sizeof(DSCBUFFERDESC1
);
720 hr
= IDirectSoundCapture_CreateCaptureBuffer(dsc
, &bufdesc
, &buffer
, (IUnknown
*)0xdeadbeef);
722 ok(hr
== DSERR_NOAGGREGATION
,
723 "IDirectSoundCapture_CreateCaptureBuffer failed: %08x, expected DSERR_NOAGGREGATION\n", hr
);
724 ok(buffer
== (IDirectSoundCaptureBuffer
*)0xdeadbeef || !buffer
/* Win2k without DirectX9 */,
725 "buffer = %p\n", buffer
);
727 hr
= IDirectSoundCapture_CreateCaptureBuffer(dsc
, &bufdesc
, &buffer
, NULL
);
728 ok(hr
== DS_OK
, "IDirectSoundCapture_CreateCaptureBuffer failed: %08x, expected DS_OK\n", hr
);
730 /* IDirectSoundCaptureBuffer and IDirectSoundNotify have separate refcounts */
731 IDirectSoundCaptureBuffer_AddRef(buffer
);
732 refcount
= IDirectSoundCaptureBuffer_AddRef(buffer
);
733 ok(refcount
== 3, "IDirectSoundCaptureBuffer refcount is %u, expected 3\n", refcount
);
734 hr
= IDirectSoundCaptureBuffer_QueryInterface(buffer
, &IID_IDirectSoundNotify
, (void**)¬ify
);
735 ok(hr
== DS_OK
, "IDirectSoundCapture_QueryInterface failed: %08x, expected DS_OK\n", hr
);
736 refcount
= IDirectSoundNotify_AddRef(notify
);
737 ok(refcount
== 2, "IDirectSoundNotify refcount is %u, expected 2\n", refcount
);
738 IDirectSoundCaptureBuffer_AddRef(buffer
);
739 refcount
= IDirectSoundCaptureBuffer_Release(buffer
);
740 ok(refcount
== 3, "IDirectSoundCaptureBuffer refcount is %u, expected 3\n", refcount
);
742 /* Release IDirectSoundCaptureBuffer while keeping IDirectSoundNotify alive */
743 while (IDirectSoundCaptureBuffer_Release(buffer
) > 0);
744 refcount
= IDirectSoundNotify_AddRef(notify
);
745 ok(refcount
== 3, "IDirectSoundNotify refcount is %u, expected 3\n", refcount
);
746 refcount
= IDirectSoundCaptureBuffer_AddRef(buffer
);
747 ok(refcount
== 1, "IDirectSoundCaptureBuffer refcount is %u, expected 1\n", refcount
);
749 while (IDirectSoundNotify_Release(notify
) > 0);
750 refcount
= IDirectSoundCaptureBuffer_Release(buffer
);
751 ok(refcount
== 0, "IDirectSoundCaptureBuffer refcount is %u, expected 0\n", refcount
);
752 refcount
= IDirectSoundCapture_Release(dsc
);
753 ok(refcount
== 0, "IDirectSoundCapture refcount is %u, expected 0\n", refcount
);
762 hDsound
= LoadLibraryA("dsound.dll");
764 skip("dsound.dll not found - skipping all tests\n");
768 pDirectSoundCaptureCreate
= (void*)GetProcAddress(hDsound
, "DirectSoundCaptureCreate");
769 pDirectSoundCaptureEnumerateA
= (void*)GetProcAddress(hDsound
, "DirectSoundCaptureEnumerateA");
770 if (!pDirectSoundCaptureCreate
|| !pDirectSoundCaptureEnumerateA
) {
771 skip("DirectSoundCapture{Create,Enumerate} missing - skipping all tests\n");
779 FreeLibrary(hDsound
);