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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define NONAMELESSSTRUCT
29 #define NONAMELESSUNION
33 #include "wine/test.h"
38 #include "dsound_test.h"
40 static HRESULT (WINAPI
*pDirectSoundCreate8
)(LPCGUID
,LPDIRECTSOUND8
*,LPUNKNOWN
)=NULL
;
42 int align(int length
, int align
)
44 return (length
/ align
) * align
;
47 static void IDirectSound8_test(LPDIRECTSOUND8 dso
, BOOL initialized
,
56 DWORD speaker_config
, new_speaker_config
;
59 /* Try to Query for objects */
60 rc
=IDirectSound8_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
61 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
62 DXGetErrorString8(rc
));
64 IDirectSound8_Release(unknown
);
66 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
67 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
68 DXGetErrorString8(rc
));
70 IDirectSound_Release(ds
);
72 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
73 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
74 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
75 DXGetErrorString8(rc
));
77 IDirectSound8_Release(ds8
);
79 if (initialized
== FALSE
) {
80 /* try unitialized object */
81 rc
=IDirectSound8_GetCaps(dso
,0);
82 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps(NULL) "
83 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
84 DXGetErrorString8(rc
));
86 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
87 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps() "
88 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
89 DXGetErrorString8(rc
));
91 rc
=IDirectSound8_Compact(dso
);
92 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_Compact() "
93 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
94 DXGetErrorString8(rc
));
96 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
97 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetSpeakerConfig() "
98 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
99 DXGetErrorString8(rc
));
101 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
102 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_VerifyCertification() "
103 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
104 DXGetErrorString8(rc
));
106 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
107 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
108 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc
));
109 if (rc
==DSERR_NODRIVER
) {
110 trace(" No Driver\n");
112 } else if (rc
==E_FAIL
) {
113 trace(" No Device\n");
115 } else if (rc
==DSERR_ALLOCATED
) {
116 trace(" Already In Use\n");
121 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
122 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSound8_Initialize() "
123 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
124 DXGetErrorString8(rc
));
126 /* DSOUND: Error: Invalid caps buffer */
127 rc
=IDirectSound8_GetCaps(dso
,0);
128 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
129 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
130 DXGetErrorString8(rc
));
132 ZeroMemory(&dscaps
, sizeof(dscaps
));
134 /* DSOUND: Error: Invalid caps buffer */
135 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
136 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
137 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
138 DXGetErrorString8(rc
));
140 dscaps
.dwSize
=sizeof(dscaps
);
142 /* DSOUND: Running on a certified driver */
143 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
144 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
146 rc
=IDirectSound8_Compact(dso
);
147 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound8_Compact() failed: %s\n",
148 DXGetErrorString8(rc
));
150 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
151 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
152 DXGetErrorString8(rc
));
154 rc
=IDirectSound8_Compact(dso
);
155 ok(rc
==DS_OK
,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc
));
157 rc
=IDirectSound8_GetSpeakerConfig(dso
,0);
158 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetSpeakerConfig(NULL) "
159 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
160 DXGetErrorString8(rc
));
162 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
163 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
164 DXGetErrorString8(rc
));
166 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
167 DSSPEAKER_GEOMETRY_WIDE
);
168 rc
=IDirectSound8_SetSpeakerConfig(dso
,speaker_config
);
169 ok(rc
==DS_OK
,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
170 DXGetErrorString8(rc
));
172 rc
=IDirectSound8_GetSpeakerConfig(dso
,&new_speaker_config
);
173 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
174 DXGetErrorString8(rc
));
175 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
176 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
177 "config: expected 0x%08lx, got 0x%08lx\n",
178 speaker_config
,new_speaker_config
);
181 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
182 ok(rc
==DS_OK
||rc
==E_NOTIMPL
,"IDirectSound8_VerifyCertification() failed: %s\n",
183 DXGetErrorString8(rc
));
186 ref
=IDirectSound8_Release(dso
);
187 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
190 static void IDirectSound8_tests()
193 LPDIRECTSOUND8 dso
=NULL
;
195 trace("Testing IDirectSound8\n");
197 /* try the COM class factory method of creation with no device specified */
198 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
199 &IID_IDirectSound8
, (void**)&dso
);
200 ok(rc
==S_OK
,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc
));
202 IDirectSound8_test(dso
, FALSE
, NULL
);
204 /* try the COM class factory method of creation with default playback
205 * device specified */
206 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
207 &IID_IDirectSound8
, (void**)&dso
);
208 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
209 DXGetErrorString8(rc
));
211 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
213 /* try the COM class factory method of creation with default voice
214 * playback device specified */
215 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
216 &IID_IDirectSound8
, (void**)&dso
);
217 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
218 DXGetErrorString8(rc
));
220 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
222 /* try the COM class factory method of creation with a bad
224 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
225 &CLSID_DirectSoundPrivate
, (void**)&dso
);
226 ok(rc
==E_NOINTERFACE
,
227 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
228 "should have failed: %s\n",DXGetErrorString8(rc
));
230 /* try the COM class factory method of creation with a bad
231 * GUID and IID specified */
232 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
233 &IID_IDirectSound8
, (void**)&dso
);
234 ok(rc
==REGDB_E_CLASSNOTREG
,
235 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
236 "should have failed: %s\n",DXGetErrorString8(rc
));
238 /* try with no device specified */
239 rc
=pDirectSoundCreate8(NULL
,&dso
,NULL
);
240 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
241 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
242 if (rc
==DS_OK
&& dso
)
243 IDirectSound8_test(dso
, TRUE
, NULL
);
245 /* try with default playback device specified */
246 rc
=pDirectSoundCreate8(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
247 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
248 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
249 if (rc
==DS_OK
&& dso
)
250 IDirectSound8_test(dso
, TRUE
, NULL
);
252 /* try with default voice playback device specified */
253 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
254 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
255 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
256 if (rc
==DS_OK
&& dso
)
257 IDirectSound8_test(dso
, TRUE
, NULL
);
259 /* try with a bad device specified */
260 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
261 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
262 "should have failed: %s\n",DXGetErrorString8(rc
));
265 static HRESULT
test_dsound8(LPGUID lpGuid
)
268 LPDIRECTSOUND8 dso
=NULL
;
271 /* DSOUND: Error: Invalid interface buffer */
272 rc
=pDirectSoundCreate8(lpGuid
,0,NULL
);
273 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate8() should have returned "
274 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
276 /* Create the DirectSound8 object */
277 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
278 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
279 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
283 /* Try the enumerated device */
284 IDirectSound8_test(dso
, TRUE
, lpGuid
);
286 /* Try the COM class factory method of creation with enumerated device */
287 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
288 &IID_IDirectSound8
, (void**)&dso
);
289 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
290 DXGetErrorString8(rc
));
292 IDirectSound8_test(dso
, FALSE
, lpGuid
);
294 /* Create a DirectSound8 object */
295 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
296 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
298 LPDIRECTSOUND8 dso1
=NULL
;
300 /* Create a second DirectSound8 object */
301 rc
=pDirectSoundCreate8(lpGuid
,&dso1
,NULL
);
302 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
304 /* Release the second DirectSound8 object */
305 ref
=IDirectSound8_Release(dso1
);
306 ok(ref
==0,"IDirectSound8_Release() has %d references, "
307 "should have 0\n",ref
);
308 ok(dso
!=dso1
,"DirectSound8 objects should be unique: "
309 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD
)dso
,(DWORD
)dso1
);
312 /* Release the first DirectSound8 object */
313 ref
=IDirectSound8_Release(dso
);
314 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
317 return DSERR_GENERIC
;
321 /* Create a DirectSound8 object */
322 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
323 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
325 LPDIRECTSOUNDBUFFER secondary
;
326 DSBUFFERDESC bufdesc
;
329 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
330 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
331 bufdesc
.dwSize
=sizeof(bufdesc
);
332 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
333 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
335 bufdesc
.lpwfxFormat
=&wfx
;
336 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
337 ok(rc
==DS_OK
&& secondary
!=NULL
,
338 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
339 "buffer: %s\n",DXGetErrorString8(rc
));
340 if (rc
==DS_OK
&& secondary
!=NULL
) {
341 LPDIRECTSOUND3DBUFFER buffer3d
;
342 LPDIRECTSOUNDBUFFER8 buffer8
;
343 rc
=IDirectSound8_QueryInterface(secondary
,
344 &IID_IDirectSound3DBuffer
,
346 ok(rc
==DS_OK
&& buffer3d
!=NULL
,
347 "IDirectSound8_QueryInterface() failed: %s\n",
348 DXGetErrorString8(rc
));
349 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
350 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
351 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
352 "should have 2\n",ref
);
354 rc
=IDirectSound8_QueryInterface(secondary
,
355 &IID_IDirectSoundBuffer8
,
357 if (rc
==DS_OK
&& buffer8
!=NULL
) {
358 ref
=IDirectSoundBuffer8_AddRef(buffer8
);
359 ok(ref
==3,"IDirectSoundBuffer8_AddRef() has %d references, "
360 "should have 3\n",ref
);
362 ref
=IDirectSoundBuffer_AddRef(secondary
);
363 ok(ref
==4,"IDirectSoundBuffer_AddRef() has %d references, "
364 "should have 4\n",ref
);
366 /* release with buffer */
367 ref
=IDirectSound8_Release(dso
);
368 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
371 return DSERR_GENERIC
;
378 static HRESULT
test_primary8(LPGUID lpGuid
)
381 LPDIRECTSOUND8 dso
=NULL
;
382 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
383 DSBUFFERDESC bufdesc
;
388 /* Create the DirectSound object */
389 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
390 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
391 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
395 /* Get the device capabilities */
396 ZeroMemory(&dscaps
, sizeof(dscaps
));
397 dscaps
.dwSize
=sizeof(dscaps
);
398 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
399 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
403 /* DSOUND: Error: Invalid buffer description pointer */
404 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,0,NULL
);
405 ok(rc
==DSERR_INVALIDPARAM
,
406 "IDirectSound8_CreateSoundBuffer should have returned "
407 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
409 /* DSOUND: Error: Invalid buffer description pointer */
410 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,&primary
,NULL
);
411 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
412 "IDirectSound8_CreateSoundBuffer() should have returned "
413 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
414 DXGetErrorString8(rc
),(DWORD
)primary
);
416 /* DSOUND: Error: Invalid buffer description pointer */
417 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
418 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
419 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
420 "dsbo=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
422 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
424 /* DSOUND: Error: Invalid size */
425 /* DSOUND: Error: Invalid buffer description */
426 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
427 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
428 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
429 "primary=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
431 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
432 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
433 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
434 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
435 DXGetErrorString8(rc
));
439 /* Testing the primary buffer */
441 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
442 bufdesc
.dwSize
=sizeof(bufdesc
);
443 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
444 bufdesc
.lpwfxFormat
= &wfx
;
445 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
446 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
447 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() should have "
448 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc
));
449 if (rc
==DS_OK
&& primary
!=NULL
)
450 IDirectSoundBuffer_Release(primary
);
453 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
454 bufdesc
.dwSize
=sizeof(bufdesc
);
455 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
456 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
457 ok(rc
==DS_OK
&& primary
!=NULL
,
458 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
459 "%s\n",DXGetErrorString8(rc
));
460 if (rc
==DS_OK
&& primary
!=NULL
) {
463 /* Try to create a second primary buffer */
464 /* DSOUND: Error: The primary buffer already exists.
465 * Any changes made to the buffer description will be ignored. */
466 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
467 ok(rc
==DS_OK
&& second
==primary
,
468 "IDirectSound8_CreateSoundBuffer() should have returned original "
469 "primary buffer: %s\n",DXGetErrorString8(rc
));
470 ref
=IDirectSoundBuffer_Release(second
);
471 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
472 "should have 1\n",ref
);
474 /* Try to duplicate a primary buffer */
475 /* DSOUND: Error: Can't duplicate primary buffers */
476 rc
=IDirectSound8_DuplicateSoundBuffer(dso
,primary
,&third
);
478 ok(rc
!=DS_OK
,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
479 "should have failed %s\n",DXGetErrorString8(rc
));
481 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
482 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
483 DXGetErrorString8(rc
));
485 if (winetest_interactive
) {
486 trace("Playing a 5 seconds reference tone at the current volume.\n");
488 trace("(the current volume is %ld according to DirectSound)\n",
490 trace("All subsequent tones should be identical to this one.\n");
491 trace("Listen for stutter, changes in pitch, volume, etc.\n");
493 test_buffer8(dso
,primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
494 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
496 ref
=IDirectSoundBuffer_Release(primary
);
497 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
498 "should have 0\n",ref
);
501 /* Set the CooperativeLevel back to normal */
502 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
503 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
504 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
505 DXGetErrorString8(rc
));
508 ref
=IDirectSound8_Release(dso
);
509 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
511 return DSERR_GENERIC
;
517 * Test the primary buffer at different formats while keeping the
518 * secondary buffer at a constant format.
520 static HRESULT
test_primary_secondary8(LPGUID lpGuid
)
523 LPDIRECTSOUND8 dso
=NULL
;
524 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
525 DSBUFFERDESC bufdesc
;
527 WAVEFORMATEX wfx
, wfx2
;
530 /* Create the DirectSound object */
531 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
532 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
533 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
537 /* Get the device capabilities */
538 ZeroMemory(&dscaps
, sizeof(dscaps
));
539 dscaps
.dwSize
=sizeof(dscaps
);
540 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
541 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
545 /* We must call SetCooperativeLevel before creating primary buffer */
546 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
547 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
548 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
549 DXGetErrorString8(rc
));
553 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
554 bufdesc
.dwSize
=sizeof(bufdesc
);
555 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
556 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
557 ok(rc
==DS_OK
&& primary
!=NULL
,
558 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
559 "%s\n",DXGetErrorString8(rc
));
561 if (rc
==DS_OK
&& primary
!=NULL
) {
562 for (f
=0;f
<NB_FORMATS
;f
++) {
563 /* We must call SetCooperativeLevel to be allowed to call
565 /* DSOUND: Setting DirectSound cooperative level to
567 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
568 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
569 DXGetErrorString8(rc
));
573 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
576 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
577 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat() failed: %s\n",
578 DXGetErrorString8(rc
));
580 /* There is no garantee that SetFormat will actually change the
581 * format to what we asked for. It depends on what the soundcard
582 * supports. So we must re-query the format.
584 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
585 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
586 DXGetErrorString8(rc
));
588 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
589 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
590 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
591 wfx
.nChannels
!=wfx2
.nChannels
)) {
592 trace("Requested primary format tag=0x%04x %ldx%dx%d "
593 "avg.B/s=%ld align=%d\n",
594 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
595 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
596 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
597 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
598 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
601 /* Set the CooperativeLevel back to normal */
602 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
603 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
604 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
605 DXGetErrorString8(rc
));
607 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
610 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
611 bufdesc
.dwSize
=sizeof(bufdesc
);
612 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
613 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
615 bufdesc
.lpwfxFormat
=&wfx2
;
616 if (winetest_interactive
) {
617 trace(" Testing a primary buffer at %ldx%dx%d with a "
618 "secondary buffer at %ldx%dx%d\n",
619 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
620 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
622 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
623 ok(rc
==DS_OK
&& secondary
!=NULL
,
624 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
625 "buffer %s\n",DXGetErrorString8(rc
));
627 if (rc
==DS_OK
&& secondary
!=NULL
) {
628 test_buffer8(dso
,secondary
,0,FALSE
,0,FALSE
,0,
629 winetest_interactive
,1.0,0,NULL
,0,0);
631 ref
=IDirectSoundBuffer_Release(secondary
);
632 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
633 "should have 0\n",ref
);
637 ref
=IDirectSoundBuffer_Release(primary
);
638 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
639 "should have 0\n",ref
);
642 /* Set the CooperativeLevel back to normal */
643 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
644 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
645 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
646 DXGetErrorString8(rc
));
649 ref
=IDirectSound8_Release(dso
);
650 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
652 return DSERR_GENERIC
;
657 static HRESULT
test_secondary8(LPGUID lpGuid
)
660 LPDIRECTSOUND8 dso
=NULL
;
661 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
662 DSBUFFERDESC bufdesc
;
664 WAVEFORMATEX wfx
, wfx1
;
668 /* Create the DirectSound object */
669 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
670 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
671 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
675 /* Get the device capabilities */
676 ZeroMemory(&dscaps
, sizeof(dscaps
));
677 dscaps
.dwSize
=sizeof(dscaps
);
678 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
679 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
683 /* We must call SetCooperativeLevel before creating primary buffer */
684 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
685 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
686 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
687 DXGetErrorString8(rc
));
691 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
692 bufdesc
.dwSize
=sizeof(bufdesc
);
693 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
694 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
695 ok(rc
==DS_OK
&& primary
!=NULL
,
696 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
697 "%s\n",DXGetErrorString8(rc
));
699 if (rc
==DS_OK
&& primary
!=NULL
) {
700 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
701 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
702 DXGetErrorString8(rc
));
706 for (f
=0;f
<NB_FORMATS
;f
++) {
707 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
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 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
716 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() "
717 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
718 DXGetErrorString8(rc
));
719 if (rc
==DS_OK
&& secondary
!=NULL
)
720 IDirectSoundBuffer_Release(secondary
);
723 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
724 bufdesc
.dwSize
=sizeof(bufdesc
);
725 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
726 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
728 bufdesc
.lpwfxFormat
=&wfx
;
729 if (winetest_interactive
) {
730 trace(" Testing a secondary buffer at %ldx%dx%d "
731 "with a primary buffer at %ldx%dx%d\n",
732 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
733 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
735 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
736 ok(rc
==DS_OK
&& secondary
!=NULL
,
737 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
738 "buffer: %s\n",DXGetErrorString8(rc
));
740 if (rc
==DS_OK
&& secondary
!=NULL
) {
741 test_buffer8(dso
,secondary
,0,FALSE
,0,FALSE
,0,
742 winetest_interactive
,1.0,0,NULL
,0,0);
744 ref
=IDirectSoundBuffer_Release(secondary
);
745 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
746 "should have 0\n",ref
);
750 ref
=IDirectSoundBuffer_Release(primary
);
751 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
752 "should have 0\n",ref
);
755 /* Set the CooperativeLevel back to normal */
756 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
757 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
758 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
759 DXGetErrorString8(rc
));
762 ref
=IDirectSound8_Release(dso
);
763 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
765 return DSERR_GENERIC
;
770 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
771 LPCSTR lpcstrModule
, LPVOID lpContext
)
774 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
775 rc
= test_dsound8(lpGuid
);
776 if (rc
== DSERR_NODRIVER
)
777 trace(" No Driver\n");
778 else if (rc
== DSERR_ALLOCATED
)
779 trace(" Already In Use\n");
780 else if (rc
== E_FAIL
)
781 trace(" No Device\n");
783 test_primary8(lpGuid
);
784 test_primary_secondary8(lpGuid
);
785 test_secondary8(lpGuid
);
791 static void dsound8_tests()
794 rc
=DirectSoundEnumerateA(&dsenum_callback
,NULL
);
795 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
798 const char * get_file_version(const char * file_name
)
800 static char version
[32];
804 size
= GetFileVersionInfoSizeA("dsound.dll", &handle
);
806 char * data
= HeapAlloc(GetProcessHeap(), 0, size
);
808 if (GetFileVersionInfoA("dsound.dll", handle
, size
, data
)) {
809 VS_FIXEDFILEINFO
*pFixedVersionInfo
;
811 if (VerQueryValueA(data
, "\\", (LPVOID
*)&pFixedVersionInfo
, &len
)) {
812 sprintf(version
, "%ld.%ld.%ld.%ld",
813 pFixedVersionInfo
->dwFileVersionMS
>> 16,
814 pFixedVersionInfo
->dwFileVersionMS
& 0xffff,
815 pFixedVersionInfo
->dwFileVersionLS
>> 16,
816 pFixedVersionInfo
->dwFileVersionLS
& 0xffff);
818 sprintf(version
, "not available");
820 sprintf(version
, "failed");
822 HeapFree(GetProcessHeap(), 0, data
);
824 sprintf(version
, "failed");
826 sprintf(version
, "not available");
837 hDsound
= LoadLibraryA("dsound.dll");
839 trace("dsound.dll not found\n");
843 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
845 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
, "DirectSoundCreate8");
846 if (!pDirectSoundCreate8
) {
847 trace("dsound8 test skipped\n");
851 IDirectSound8_tests();