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(void)
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=%p,dso1=%p\n",dso
,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=%p\n",
414 DXGetErrorString8(rc
),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=%p\n",DXGetErrorString8(rc
),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=%p\n",DXGetErrorString8(rc
),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
) || (rc
==DSERR_CONTROLUNAVAIL
),
458 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
459 "%s\n",DXGetErrorString8(rc
));
460 if (rc
==DSERR_CONTROLUNAVAIL
)
461 trace(" No Primary\n");
462 else if (rc
==DS_OK
&& primary
!=NULL
) {
465 /* Try to create a second primary buffer */
466 /* DSOUND: Error: The primary buffer already exists.
467 * Any changes made to the buffer description will be ignored. */
468 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
469 ok(rc
==DS_OK
&& second
==primary
,
470 "IDirectSound8_CreateSoundBuffer() should have returned original "
471 "primary buffer: %s\n",DXGetErrorString8(rc
));
472 ref
=IDirectSoundBuffer_Release(second
);
473 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
474 "should have 1\n",ref
);
476 /* Try to duplicate a primary buffer */
477 /* DSOUND: Error: Can't duplicate primary buffers */
478 rc
=IDirectSound8_DuplicateSoundBuffer(dso
,primary
,&third
);
480 ok(rc
!=DS_OK
,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
481 "should have failed %s\n",DXGetErrorString8(rc
));
483 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
484 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
485 DXGetErrorString8(rc
));
487 if (winetest_interactive
) {
488 trace("Playing a 5 seconds reference tone at the current volume.\n");
490 trace("(the current volume is %ld according to DirectSound)\n",
492 trace("All subsequent tones should be identical to this one.\n");
493 trace("Listen for stutter, changes in pitch, volume, etc.\n");
495 test_buffer8(dso
,primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
496 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
498 ref
=IDirectSoundBuffer_Release(primary
);
499 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
500 "should have 0\n",ref
);
503 /* Set the CooperativeLevel back to normal */
504 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
505 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
506 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
507 DXGetErrorString8(rc
));
510 ref
=IDirectSound8_Release(dso
);
511 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
513 return DSERR_GENERIC
;
519 * Test the primary buffer at different formats while keeping the
520 * secondary buffer at a constant format.
522 static HRESULT
test_primary_secondary8(LPGUID lpGuid
)
525 LPDIRECTSOUND8 dso
=NULL
;
526 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
527 DSBUFFERDESC bufdesc
;
529 WAVEFORMATEX wfx
, wfx2
;
533 /* Create the DirectSound object */
534 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
535 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
536 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
540 /* Get the device capabilities */
541 ZeroMemory(&dscaps
, sizeof(dscaps
));
542 dscaps
.dwSize
=sizeof(dscaps
);
543 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
544 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
548 /* We must call SetCooperativeLevel before creating primary buffer */
549 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
550 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
551 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
552 DXGetErrorString8(rc
));
556 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
557 bufdesc
.dwSize
=sizeof(bufdesc
);
558 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
559 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
560 ok(rc
==DS_OK
&& primary
!=NULL
,
561 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
562 "%s\n",DXGetErrorString8(rc
));
564 if (rc
==DS_OK
&& primary
!=NULL
) {
565 for (f
=0;f
<NB_FORMATS
;f
++) {
566 /* We must call SetCooperativeLevel to be allowed to call
568 /* DSOUND: Setting DirectSound cooperative level to
570 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
571 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
572 DXGetErrorString8(rc
));
576 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
579 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
580 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat() failed: %s\n",
581 DXGetErrorString8(rc
));
583 /* There is no garantee that SetFormat will actually change the
584 * format to what we asked for. It depends on what the soundcard
585 * supports. So we must re-query the format.
587 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
588 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
589 DXGetErrorString8(rc
));
591 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
592 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
593 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
594 wfx
.nChannels
!=wfx2
.nChannels
)) {
595 trace("Requested primary format tag=0x%04x %ldx%dx%d "
596 "avg.B/s=%ld align=%d\n",
597 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
598 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
599 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
600 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
601 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
604 /* Set the CooperativeLevel back to normal */
605 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
606 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
607 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
608 DXGetErrorString8(rc
));
610 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
613 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
614 bufdesc
.dwSize
=sizeof(bufdesc
);
615 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
616 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
618 bufdesc
.lpwfxFormat
=&wfx2
;
619 if (winetest_interactive
) {
620 trace(" Testing a primary buffer at %ldx%dx%d with a "
621 "secondary buffer at %ldx%dx%d\n",
622 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
623 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
625 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
626 ok(rc
==DS_OK
&& secondary
!=NULL
,
627 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
628 "buffer %s\n",DXGetErrorString8(rc
));
630 if (rc
==DS_OK
&& secondary
!=NULL
) {
631 test_buffer8(dso
,secondary
,0,FALSE
,0,FALSE
,0,
632 winetest_interactive
,1.0,0,NULL
,0,0);
634 ref
=IDirectSoundBuffer_Release(secondary
);
635 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
636 "should have 0\n",ref
);
640 ref
=IDirectSoundBuffer_Release(primary
);
641 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
642 "should have 0\n",ref
);
645 /* Set the CooperativeLevel back to normal */
646 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
647 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
648 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
649 DXGetErrorString8(rc
));
652 ref
=IDirectSound8_Release(dso
);
653 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
655 return DSERR_GENERIC
;
660 static HRESULT
test_secondary8(LPGUID lpGuid
)
663 LPDIRECTSOUND8 dso
=NULL
;
664 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
665 DSBUFFERDESC bufdesc
;
667 WAVEFORMATEX wfx
, wfx1
;
671 /* Create the DirectSound object */
672 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
673 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
674 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
678 /* Get the device capabilities */
679 ZeroMemory(&dscaps
, sizeof(dscaps
));
680 dscaps
.dwSize
=sizeof(dscaps
);
681 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
682 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
686 /* We must call SetCooperativeLevel before creating primary buffer */
687 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
688 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
689 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
690 DXGetErrorString8(rc
));
694 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
695 bufdesc
.dwSize
=sizeof(bufdesc
);
696 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
697 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
698 ok(rc
==DS_OK
&& primary
!=NULL
,
699 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
700 "%s\n",DXGetErrorString8(rc
));
702 if (rc
==DS_OK
&& primary
!=NULL
) {
703 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
704 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
705 DXGetErrorString8(rc
));
709 for (f
=0;f
<NB_FORMATS
;f
++) {
710 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
713 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
714 bufdesc
.dwSize
=sizeof(bufdesc
);
715 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
716 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
718 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
719 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() "
720 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
721 DXGetErrorString8(rc
));
722 if (rc
==DS_OK
&& secondary
!=NULL
)
723 IDirectSoundBuffer_Release(secondary
);
726 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
727 bufdesc
.dwSize
=sizeof(bufdesc
);
728 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
729 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
731 bufdesc
.lpwfxFormat
=&wfx
;
732 if (winetest_interactive
) {
733 trace(" Testing a secondary buffer at %ldx%dx%d "
734 "with a primary buffer at %ldx%dx%d\n",
735 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
736 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
738 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
739 ok(rc
==DS_OK
&& secondary
!=NULL
,
740 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
741 "buffer: %s\n",DXGetErrorString8(rc
));
743 if (rc
==DS_OK
&& secondary
!=NULL
) {
744 test_buffer8(dso
,secondary
,0,FALSE
,0,FALSE
,0,
745 winetest_interactive
,1.0,0,NULL
,0,0);
747 ref
=IDirectSoundBuffer_Release(secondary
);
748 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
749 "should have 0\n",ref
);
753 ref
=IDirectSoundBuffer_Release(primary
);
754 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
755 "should have 0\n",ref
);
758 /* Set the CooperativeLevel back to normal */
759 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
760 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
761 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
762 DXGetErrorString8(rc
));
765 ref
=IDirectSound8_Release(dso
);
766 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
768 return DSERR_GENERIC
;
773 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
774 LPCSTR lpcstrModule
, LPVOID lpContext
)
777 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
778 rc
= test_dsound8(lpGuid
);
779 if (rc
== DSERR_NODRIVER
)
780 trace(" No Driver\n");
781 else if (rc
== DSERR_ALLOCATED
)
782 trace(" Already In Use\n");
783 else if (rc
== E_FAIL
)
784 trace(" No Device\n");
786 test_primary8(lpGuid
);
787 test_primary_secondary8(lpGuid
);
788 test_secondary8(lpGuid
);
794 static void dsound8_tests(void)
797 rc
=DirectSoundEnumerateA(&dsenum_callback
,NULL
);
798 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
801 const char * get_file_version(const char * file_name
)
803 static char version
[32];
807 size
= GetFileVersionInfoSizeA("dsound.dll", &handle
);
809 char * data
= HeapAlloc(GetProcessHeap(), 0, size
);
811 if (GetFileVersionInfoA("dsound.dll", handle
, size
, data
)) {
812 VS_FIXEDFILEINFO
*pFixedVersionInfo
;
814 if (VerQueryValueA(data
, "\\", (LPVOID
*)&pFixedVersionInfo
, &len
)) {
815 sprintf(version
, "%ld.%ld.%ld.%ld",
816 pFixedVersionInfo
->dwFileVersionMS
>> 16,
817 pFixedVersionInfo
->dwFileVersionMS
& 0xffff,
818 pFixedVersionInfo
->dwFileVersionLS
>> 16,
819 pFixedVersionInfo
->dwFileVersionLS
& 0xffff);
821 sprintf(version
, "not available");
823 sprintf(version
, "failed");
825 HeapFree(GetProcessHeap(), 0, data
);
827 sprintf(version
, "failed");
829 sprintf(version
, "not available");
840 hDsound
= LoadLibraryA("dsound.dll");
842 trace("dsound.dll not found\n");
846 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
848 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
, "DirectSoundCreate8");
849 if (!pDirectSoundCreate8
) {
850 trace("dsound8 test skipped\n");
854 IDirectSound8_tests();