2 * Tests basic sound playback in DirectSound.
3 * In particular we test each standard Windows sound format to make sure
4 * we handle the sound card/driver quirks correctly.
6 * Part of this test involves playing test tones. But this only makes
7 * sense if someone is going to carefully listen to it, and would only
8 * bother everyone else.
9 * So this is only done if the test is being run in interactive mode.
11 * Copyright (c) 2002-2004 Francois Gouget
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #define NONAMELESSSTRUCT
29 #define NONAMELESSUNION
32 #include "wine/test.h"
37 #include "dsound_test.h"
39 static void IDirectSound_test(LPDIRECTSOUND dso
, BOOL initialized
,
48 DWORD speaker_config
, new_speaker_config
;
50 /* Try to Query for objects */
51 rc
=IDirectSound_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
52 ok(rc
==DS_OK
,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",
53 DXGetErrorString8(rc
));
55 IDirectSound_Release(unknown
);
57 rc
=IDirectSound_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
58 ok(rc
==DS_OK
,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",
59 DXGetErrorString8(rc
));
61 IDirectSound_Release(ds
);
63 rc
=IDirectSound_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
64 ok(rc
==E_NOINTERFACE
,"IDirectSound_QueryInterface(IID_IDirectSound8) "
65 "should have failed: %s\n",DXGetErrorString8(rc
));
67 IDirectSound8_Release(ds8
);
69 if (initialized
== FALSE
) {
70 /* try unitialized object */
71 rc
=IDirectSound_GetCaps(dso
,0);
72 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetCaps(NULL) "
73 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
74 DXGetErrorString8(rc
));
76 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
77 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetCaps() "
78 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
79 DXGetErrorString8(rc
));
81 rc
=IDirectSound_Compact(dso
);
82 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_Compact() "
83 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
84 DXGetErrorString8(rc
));
86 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
87 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetSpeakerConfig() "
88 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
89 DXGetErrorString8(rc
));
91 rc
=IDirectSound_Initialize(dso
,lpGuid
);
92 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
93 "IDirectSound_Initialize() failed: %s\n",DXGetErrorString8(rc
));
94 if (rc
==DSERR_NODRIVER
) {
95 trace(" No Driver\n");
97 } else if (rc
==E_FAIL
) {
98 trace(" No Device\n");
100 } else if (rc
==DSERR_ALLOCATED
) {
101 trace(" Already In Use\n");
106 rc
=IDirectSound_Initialize(dso
,lpGuid
);
107 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSound_Initialize() "
108 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
109 DXGetErrorString8(rc
));
111 /* DSOUND: Error: Invalid caps buffer */
112 rc
=IDirectSound_GetCaps(dso
,0);
113 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps(NULL) "
114 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
115 DXGetErrorString8(rc
));
117 ZeroMemory(&dscaps
, sizeof(dscaps
));
119 /* DSOUND: Error: Invalid caps buffer */
120 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
121 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps() "
122 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
123 DXGetErrorString8(rc
));
125 dscaps
.dwSize
=sizeof(dscaps
);
127 /* DSOUND: Running on a certified driver */
128 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
129 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
131 rc
=IDirectSound_Compact(dso
);
132 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound_Compact() failed: %s\n",
133 DXGetErrorString8(rc
));
135 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
136 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
137 DXGetErrorString8(rc
));
139 rc
=IDirectSound_Compact(dso
);
140 ok(rc
==DS_OK
,"IDirectSound_Compact() failed: %s\n",DXGetErrorString8(rc
));
142 rc
=IDirectSound_GetSpeakerConfig(dso
,0);
143 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetSpeakerConfig(NULL) "
144 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
145 DXGetErrorString8(rc
));
147 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
148 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %s\n",
149 DXGetErrorString8(rc
));
151 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
152 DSSPEAKER_GEOMETRY_WIDE
);
153 rc
=IDirectSound_SetSpeakerConfig(dso
,speaker_config
);
154 ok(rc
==DS_OK
,"IDirectSound_SetSpeakerConfig() failed: %s\n",
155 DXGetErrorString8(rc
));
157 rc
=IDirectSound_GetSpeakerConfig(dso
,&new_speaker_config
);
158 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %s\n",
159 DXGetErrorString8(rc
));
160 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
161 trace("IDirectSound_GetSpeakerConfig() failed to set speaker "
162 "config: expected 0x%08x, got 0x%08x\n",
163 speaker_config
,new_speaker_config
);
167 ref
=IDirectSound_Release(dso
);
168 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
171 static void IDirectSound_tests(void)
174 LPDIRECTSOUND dso
=NULL
;
175 LPCLASSFACTORY cf
=NULL
;
177 trace("Testing IDirectSound\n");
179 rc
=CoGetClassObject(&CLSID_DirectSound
, CLSCTX_INPROC_SERVER
, NULL
,
180 &IID_IClassFactory
, (void**)&cf
);
181 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound, IID_IClassFactory) "
182 "failed: %s\n", DXGetErrorString8(rc
));
184 rc
=CoGetClassObject(&CLSID_DirectSound
, CLSCTX_INPROC_SERVER
, NULL
,
185 &IID_IUnknown
, (void**)&cf
);
186 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound, IID_IUnknown) "
187 "failed: %s\n", DXGetErrorString8(rc
));
189 /* try the COM class factory method of creation with no device specified */
190 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
191 &IID_IDirectSound
, (void**)&dso
);
192 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
193 DXGetErrorString8(rc
));
195 IDirectSound_test(dso
, FALSE
, NULL
);
197 /* try the COM class factory method of creation with default playback
198 * device specified */
199 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
200 &IID_IDirectSound
, (void**)&dso
);
201 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
202 DXGetErrorString8(rc
));
204 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
206 /* try the COM class factory method of creation with default voice
207 * playback device specified */
208 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
209 &IID_IDirectSound
, (void**)&dso
);
210 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
211 DXGetErrorString8(rc
));
213 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
215 /* try the COM class factory method of creation with a bad
217 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
218 &CLSID_DirectSoundPrivate
, (void**)&dso
);
219 ok(rc
==E_NOINTERFACE
,
220 "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) "
221 "should have failed: %s\n",DXGetErrorString8(rc
));
223 /* try the COM class factory method of creation with a bad
224 * GUID and IID specified */
225 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
226 &IID_IDirectSound
, (void**)&dso
);
227 ok(rc
==REGDB_E_CLASSNOTREG
,
228 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) "
229 "should have failed: %s\n",DXGetErrorString8(rc
));
231 /* try with no device specified */
232 rc
=DirectSoundCreate(NULL
,&dso
,NULL
);
233 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
234 "DirectSoundCreate(NULL) failed: %s\n",DXGetErrorString8(rc
));
236 IDirectSound_test(dso
, TRUE
, NULL
);
238 /* try with default playback device specified */
239 rc
=DirectSoundCreate(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
240 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
241 "DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %s\n",
242 DXGetErrorString8(rc
));
243 if (rc
==DS_OK
&& dso
)
244 IDirectSound_test(dso
, TRUE
, NULL
);
246 /* try with default voice playback device specified */
247 rc
=DirectSoundCreate(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
248 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
249 "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %s\n",
250 DXGetErrorString8(rc
));
251 if (rc
==DS_OK
&& dso
)
252 IDirectSound_test(dso
, TRUE
, NULL
);
254 /* try with a bad device specified */
255 rc
=DirectSoundCreate(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
256 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) "
257 "should have failed: %s\n",DXGetErrorString8(rc
));
258 if (rc
==DS_OK
&& dso
)
259 IDirectSound_Release(dso
);
262 static HRESULT
test_dsound(LPGUID lpGuid
)
265 LPDIRECTSOUND dso
=NULL
;
268 /* DSOUND: Error: Invalid interface buffer */
269 rc
=DirectSoundCreate(lpGuid
,0,NULL
);
270 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate() should have returned "
271 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
273 /* Create the DirectSound object */
274 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
275 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
276 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
280 /* Try the enumerated device */
281 IDirectSound_test(dso
, TRUE
, lpGuid
);
283 /* Try the COM class factory method of creation with enumerated device */
284 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
285 &IID_IDirectSound
, (void**)&dso
);
286 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
287 DXGetErrorString8(rc
));
289 IDirectSound_test(dso
, FALSE
, lpGuid
);
291 /* Create a DirectSound object */
292 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
293 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
295 LPDIRECTSOUND dso1
=NULL
;
297 /* Create a second DirectSound object */
298 rc
=DirectSoundCreate(lpGuid
,&dso1
,NULL
);
299 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
301 /* Release the second DirectSound object */
302 ref
=IDirectSound_Release(dso1
);
303 ok(ref
==0,"IDirectSound_Release() has %d references, should have "
305 ok(dso
!=dso1
,"DirectSound objects should be unique: dso=%p,dso1=%p\n",dso
,dso1
);
308 /* Release the first DirectSound object */
309 ref
=IDirectSound_Release(dso
);
310 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
313 return DSERR_GENERIC
;
317 /* Create a DirectSound object */
318 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
319 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
321 LPDIRECTSOUNDBUFFER secondary
;
322 DSBUFFERDESC bufdesc
;
325 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
326 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
327 bufdesc
.dwSize
=sizeof(bufdesc
);
328 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
329 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
331 bufdesc
.lpwfxFormat
=&wfx
;
332 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
333 ok(rc
==DS_OK
&& secondary
!=NULL
,
334 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
335 "buffer %s\n",DXGetErrorString8(rc
));
336 if (rc
==DS_OK
&& secondary
!=NULL
) {
337 LPDIRECTSOUND3DBUFFER buffer3d
;
338 rc
=IDirectSound_QueryInterface(secondary
, &IID_IDirectSound3DBuffer
,
340 ok(rc
==DS_OK
&& buffer3d
!=NULL
,"IDirectSound_QueryInterface() "
341 "failed: %s\n",DXGetErrorString8(rc
));
342 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
343 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
344 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
345 "should have 2\n",ref
);
347 ref
=IDirectSoundBuffer_AddRef(secondary
);
348 ok(ref
==2,"IDirectSoundBuffer_AddRef() has %d references, "
349 "should have 2\n",ref
);
351 /* release with buffer */
352 ref
=IDirectSound_Release(dso
);
353 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
356 return DSERR_GENERIC
;
363 static HRESULT
test_primary(LPGUID lpGuid
)
366 LPDIRECTSOUND dso
=NULL
;
367 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
368 DSBUFFERDESC bufdesc
;
373 /* Create the DirectSound object */
374 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
375 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
376 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
380 /* Get the device capabilities */
381 ZeroMemory(&dscaps
, sizeof(dscaps
));
382 dscaps
.dwSize
=sizeof(dscaps
);
383 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
384 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
388 /* DSOUND: Error: Invalid buffer description pointer */
389 rc
=IDirectSound_CreateSoundBuffer(dso
,0,0,NULL
);
390 ok(rc
==DSERR_INVALIDPARAM
,
391 "IDirectSound_CreateSoundBuffer() should have failed: %s\n",
392 DXGetErrorString8(rc
));
394 /* DSOUND: Error: Invalid buffer description pointer */
395 rc
=IDirectSound_CreateSoundBuffer(dso
,0,&primary
,NULL
);
396 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
397 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
398 "dsbo=%p\n",DXGetErrorString8(rc
),primary
);
400 /* DSOUND: Error: Invalid buffer description pointer */
401 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
402 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
403 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
404 "dsbo=0x%p\n",DXGetErrorString8(rc
),primary
);
406 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
408 /* DSOUND: Error: Invalid size */
409 /* DSOUND: Error: Invalid buffer description */
410 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
411 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
412 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
413 "primary=%p\n",DXGetErrorString8(rc
),primary
);
415 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
416 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
417 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
418 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
419 DXGetErrorString8(rc
));
423 /* Testing the primary buffer */
425 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
426 bufdesc
.dwSize
=sizeof(bufdesc
);
427 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
428 bufdesc
.lpwfxFormat
= &wfx
;
429 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
430 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
431 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() should have "
432 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc
));
433 if (rc
==DS_OK
&& primary
!=NULL
)
434 IDirectSoundBuffer_Release(primary
);
437 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
438 bufdesc
.dwSize
=sizeof(bufdesc
);
439 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
440 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
441 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
442 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
443 "%s\n",DXGetErrorString8(rc
));
444 if (rc
==DSERR_CONTROLUNAVAIL
)
445 trace(" No Primary\n");
446 else if (rc
==DS_OK
&& primary
!=NULL
) {
449 /* Try to create a second primary buffer */
450 /* DSOUND: Error: The primary buffer already exists.
451 * Any changes made to the buffer description will be ignored. */
452 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
453 ok(rc
==DS_OK
&& second
==primary
,
454 "IDirectSound_CreateSoundBuffer() should have returned original "
455 "primary buffer: %s\n",DXGetErrorString8(rc
));
456 ref
=IDirectSoundBuffer_Release(second
);
457 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
458 "should have 1\n",ref
);
460 /* Try to duplicate a primary buffer */
461 /* DSOUND: Error: Can't duplicate primary buffers */
462 rc
=IDirectSound_DuplicateSoundBuffer(dso
,primary
,&third
);
464 ok(rc
!=DS_OK
,"IDirectSound_DuplicateSoundBuffer() primary buffer "
465 "should have failed %s\n",DXGetErrorString8(rc
));
467 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
468 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
469 DXGetErrorString8(rc
));
471 if (winetest_interactive
) {
472 trace("Playing a 5 seconds reference tone at the current "
475 trace("(the current volume is %d according to DirectSound)\n",
477 trace("All subsequent tones should be identical to this one.\n");
478 trace("Listen for stutter, changes in pitch, volume, etc.\n");
480 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
481 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0,FALSE
,0);
483 ref
=IDirectSoundBuffer_Release(primary
);
484 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
485 "should have 0\n",ref
);
488 /* Set the CooperativeLevel back to normal */
489 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
490 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
491 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
492 DXGetErrorString8(rc
));
495 ref
=IDirectSound_Release(dso
);
496 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
498 return DSERR_GENERIC
;
504 * Test the primary buffer at different formats while keeping the
505 * secondary buffer at a constant format.
507 static HRESULT
test_primary_secondary(LPGUID lpGuid
)
510 LPDIRECTSOUND dso
=NULL
;
511 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
512 DSBUFFERDESC bufdesc
;
514 WAVEFORMATEX wfx
, wfx2
;
517 /* Create the DirectSound object */
518 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
519 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
520 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
524 /* Get the device capabilities */
525 ZeroMemory(&dscaps
, sizeof(dscaps
));
526 dscaps
.dwSize
=sizeof(dscaps
);
527 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
528 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
532 /* We must call SetCooperativeLevel before creating primary buffer */
533 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
534 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
535 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
536 DXGetErrorString8(rc
));
540 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
541 bufdesc
.dwSize
=sizeof(bufdesc
);
542 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
543 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
544 ok(rc
==DS_OK
&& primary
!=NULL
,
545 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
546 "%s\n",DXGetErrorString8(rc
));
548 if (rc
==DS_OK
&& primary
!=NULL
) {
549 for (f
=0;f
<NB_FORMATS
;f
++) {
550 /* We must call SetCooperativeLevel to be allowed to call
552 /* DSOUND: Setting DirectSound cooperative level to
554 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
555 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
556 DXGetErrorString8(rc
));
560 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
563 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
564 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %s\n",
565 format_string(&wfx
), DXGetErrorString8(rc
));
567 /* There is no garantee that SetFormat will actually change the
568 * format to what we asked for. It depends on what the soundcard
569 * supports. So we must re-query the format.
571 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
572 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
573 DXGetErrorString8(rc
));
575 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
576 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
577 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
578 wfx
.nChannels
!=wfx2
.nChannels
)) {
579 trace("Requested primary format tag=0x%04x %dx%dx%d "
580 "avg.B/s=%d align=%d\n",
581 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
582 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
583 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
584 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
585 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
588 /* Set the CooperativeLevel back to normal */
589 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
590 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
591 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
592 DXGetErrorString8(rc
));
594 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
597 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
598 bufdesc
.dwSize
=sizeof(bufdesc
);
599 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
600 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
602 bufdesc
.lpwfxFormat
=&wfx2
;
603 if (winetest_interactive
) {
604 trace(" Testing a primary buffer at %dx%dx%d with a "
605 "secondary buffer at %dx%dx%d\n",
606 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
607 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
609 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
610 ok(rc
==DS_OK
&& secondary
!=NULL
,
611 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
612 "buffer %s\n",DXGetErrorString8(rc
));
614 if (rc
==DS_OK
&& secondary
!=NULL
) {
615 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
616 winetest_interactive
,1.0,0,NULL
,0,0,FALSE
,0);
618 ref
=IDirectSoundBuffer_Release(secondary
);
619 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
620 "should have 0\n",ref
);
624 ref
=IDirectSoundBuffer_Release(primary
);
625 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
626 "should have 0\n",ref
);
629 /* Set the CooperativeLevel back to normal */
630 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
631 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
632 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
633 DXGetErrorString8(rc
));
636 ref
=IDirectSound_Release(dso
);
637 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
639 return DSERR_GENERIC
;
644 static HRESULT
test_secondary(LPGUID lpGuid
)
647 LPDIRECTSOUND dso
=NULL
;
648 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
649 DSBUFFERDESC bufdesc
;
651 WAVEFORMATEX wfx
, wfx1
;
655 /* Create the DirectSound object */
656 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
657 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
658 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
662 /* Get the device capabilities */
663 ZeroMemory(&dscaps
, sizeof(dscaps
));
664 dscaps
.dwSize
=sizeof(dscaps
);
665 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
666 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
670 /* We must call SetCooperativeLevel before creating primary buffer */
671 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
672 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
673 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
674 DXGetErrorString8(rc
));
678 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
679 bufdesc
.dwSize
=sizeof(bufdesc
);
680 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
681 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
682 ok(rc
==DS_OK
&& primary
!=NULL
,
683 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
684 "%s\n",DXGetErrorString8(rc
));
686 if (rc
==DS_OK
&& primary
!=NULL
) {
687 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
688 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
689 DXGetErrorString8(rc
));
693 for (f
=0;f
<NB_FORMATS
;f
++) {
694 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
697 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
698 bufdesc
.dwSize
=sizeof(bufdesc
);
699 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
700 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
702 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
703 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() "
704 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
705 DXGetErrorString8(rc
));
706 if (rc
==DS_OK
&& secondary
!=NULL
)
707 IDirectSoundBuffer_Release(secondary
);
710 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
711 bufdesc
.dwSize
=sizeof(bufdesc
);
712 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
713 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
715 bufdesc
.lpwfxFormat
=&wfx
;
716 if (winetest_interactive
) {
717 trace(" Testing a secondary buffer at %dx%dx%d "
718 "with a primary buffer at %dx%dx%d\n",
719 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
720 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
722 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
723 ok(rc
==DS_OK
&& secondary
!=NULL
,
724 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
725 "buffer %s\n",DXGetErrorString8(rc
));
727 if (rc
==DS_OK
&& secondary
!=NULL
) {
728 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
729 winetest_interactive
,1.0,0,NULL
,0,0,FALSE
,0);
731 ref
=IDirectSoundBuffer_Release(secondary
);
732 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
733 "should have 0\n",ref
);
737 ref
=IDirectSoundBuffer_Release(primary
);
738 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
739 "should have 0\n",ref
);
742 /* Set the CooperativeLevel back to normal */
743 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
744 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
745 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
746 DXGetErrorString8(rc
));
749 ref
=IDirectSound_Release(dso
);
750 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
752 return DSERR_GENERIC
;
757 static HRESULT
test_block_align(LPGUID lpGuid
)
760 LPDIRECTSOUND dso
=NULL
;
761 LPDIRECTSOUNDBUFFER secondary
=NULL
;
762 DSBUFFERDESC bufdesc
;
767 /* Create the DirectSound object */
768 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
769 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
770 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
774 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,16,2);
775 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
776 bufdesc
.dwSize
=sizeof(bufdesc
);
777 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
778 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
+ 1;
779 bufdesc
.lpwfxFormat
=&wfx
;
780 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
781 ok(rc
==DS_OK
,"IDirectSound_CreateSoundBuffer() "
782 "should have returned DS_OK, returned: %s\n",
783 DXGetErrorString8(rc
));
785 if (rc
==DS_OK
&& secondary
!=NULL
) {
786 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
787 dsbcaps
.dwSize
= sizeof(dsbcaps
);
788 rc
=IDirectSoundBuffer_GetCaps(secondary
,&dsbcaps
);
789 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, "
790 "returned: %s\n", DXGetErrorString8(rc
));
792 ok(dsbcaps
.dwBufferBytes
==(wfx
.nAvgBytesPerSec
+ wfx
.nBlockAlign
),
793 "Buffer size not a multiple of nBlockAlign: requested %d, "
794 "got %d, should be %d\n", bufdesc
.dwBufferBytes
,
795 dsbcaps
.dwBufferBytes
, wfx
.nAvgBytesPerSec
+ wfx
.nBlockAlign
);
796 ref
=IDirectSoundBuffer_Release(secondary
);
797 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d references, "
798 "should have 0\n",ref
);
801 ref
=IDirectSound_Release(dso
);
802 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
804 return DSERR_GENERIC
;
812 } fmts
[] = { { 8, 1 }, { 8, 2 }, { 16, 1 }, {16, 2 } };
814 static HRESULT
test_frequency(LPGUID lpGuid
)
817 LPDIRECTSOUND dso
=NULL
;
818 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
819 DSBUFFERDESC bufdesc
;
821 WAVEFORMATEX wfx
, wfx1
;
824 int rates
[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
827 /* Create the DirectSound object */
828 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
829 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
830 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
834 /* Get the device capabilities */
835 ZeroMemory(&dscaps
, sizeof(dscaps
));
836 dscaps
.dwSize
=sizeof(dscaps
);
837 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
838 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
842 /* We must call SetCooperativeLevel before creating primary buffer */
843 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
844 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
845 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
846 DXGetErrorString8(rc
));
850 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
851 bufdesc
.dwSize
=sizeof(bufdesc
);
852 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
853 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
854 ok(rc
==DS_OK
&& primary
!=NULL
,
855 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
856 "%s\n",DXGetErrorString8(rc
));
858 if (rc
==DS_OK
&& primary
!=NULL
) {
859 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
860 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
861 DXGetErrorString8(rc
));
865 for (f
=0;f
<sizeof(fmts
)/sizeof(fmts
[0]);f
++) {
866 for (r
=0;r
<sizeof(rates
)/sizeof(rates
[0]);r
++) {
867 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,fmts
[f
].bits
,
870 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
871 bufdesc
.dwSize
=sizeof(bufdesc
);
872 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
|DSBCAPS_CTRLFREQUENCY
;
873 bufdesc
.dwBufferBytes
=align((wfx
.nAvgBytesPerSec
*rates
[r
]/11025)*
874 BUFFER_LEN
/1000,wfx
.nBlockAlign
);
875 bufdesc
.lpwfxFormat
=&wfx
;
876 if (winetest_interactive
) {
877 trace(" Testing a secondary buffer at %dx%dx%d "
878 "with a primary buffer at %dx%dx%d\n",
879 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
880 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
882 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
883 ok(rc
==DS_OK
&& secondary
!=NULL
,
884 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
885 "buffer %s\n",DXGetErrorString8(rc
));
887 if (rc
==DS_OK
&& secondary
!=NULL
) {
888 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
889 winetest_interactive
,1.0,0,NULL
,0,0,TRUE
,rates
[r
]);
891 ref
=IDirectSoundBuffer_Release(secondary
);
892 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
893 "should have 0\n",ref
);
898 ref
=IDirectSoundBuffer_Release(primary
);
899 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
900 "should have 0\n",ref
);
903 /* Set the CooperativeLevel back to normal */
904 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
905 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
906 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
907 DXGetErrorString8(rc
));
910 ref
=IDirectSound_Release(dso
);
911 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
913 return DSERR_GENERIC
;
918 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
919 LPCSTR lpcstrModule
, LPVOID lpContext
)
922 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
923 rc
= test_dsound(lpGuid
);
924 if (rc
== DSERR_NODRIVER
)
925 trace(" No Driver\n");
926 else if (rc
== DSERR_ALLOCATED
)
927 trace(" Already In Use\n");
928 else if (rc
== E_FAIL
)
929 trace(" No Device\n");
931 test_block_align(lpGuid
);
932 test_primary(lpGuid
);
933 test_primary_secondary(lpGuid
);
934 test_secondary(lpGuid
);
935 test_frequency(lpGuid
);
941 static void dsound_tests(void)
944 rc
=DirectSoundEnumerateA(&dsenum_callback
,NULL
);
945 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
952 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
954 IDirectSound_tests();