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
31 #include "wine/test.h"
39 #include "dsound_test.h"
41 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
42 static HRESULT (WINAPI
*pDirectSoundCreate8
)(LPCGUID
,LPDIRECTSOUND8
*,LPUNKNOWN
)=NULL
;
44 int align(int length
, int align
)
46 return (length
/ align
) * align
;
49 static void IDirectSound8_test(LPDIRECTSOUND8 dso
, BOOL initialized
,
58 DWORD speaker_config
, new_speaker_config
;
61 /* Try to Query for objects */
62 rc
=IDirectSound8_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
63 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
64 DXGetErrorString8(rc
));
66 IDirectSound8_Release(unknown
);
68 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
69 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
70 DXGetErrorString8(rc
));
72 IDirectSound_Release(ds
);
74 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
75 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
76 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
77 DXGetErrorString8(rc
));
79 IDirectSound8_Release(ds8
);
81 if (initialized
== FALSE
) {
82 /* try uninitialized object */
83 rc
=IDirectSound8_GetCaps(dso
,0);
84 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps(NULL) "
85 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
86 DXGetErrorString8(rc
));
88 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
89 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps() "
90 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
91 DXGetErrorString8(rc
));
93 rc
=IDirectSound8_Compact(dso
);
94 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_Compact() "
95 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
96 DXGetErrorString8(rc
));
98 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
99 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetSpeakerConfig() "
100 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
101 DXGetErrorString8(rc
));
103 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
104 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_VerifyCertification() "
105 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
106 DXGetErrorString8(rc
));
108 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
109 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
110 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc
));
111 if (rc
==DSERR_NODRIVER
) {
112 trace(" No Driver\n");
114 } else if (rc
==E_FAIL
) {
115 trace(" No Device\n");
117 } else if (rc
==DSERR_ALLOCATED
) {
118 trace(" Already In Use\n");
123 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
124 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSound8_Initialize() "
125 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
126 DXGetErrorString8(rc
));
128 /* DSOUND: Error: Invalid caps buffer */
129 rc
=IDirectSound8_GetCaps(dso
,0);
130 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
131 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
132 DXGetErrorString8(rc
));
134 ZeroMemory(&dscaps
, sizeof(dscaps
));
136 /* DSOUND: Error: Invalid caps buffer */
137 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
138 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
139 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
140 DXGetErrorString8(rc
));
142 dscaps
.dwSize
=sizeof(dscaps
);
144 /* DSOUND: Running on a certified driver */
145 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
146 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
148 rc
=IDirectSound8_Compact(dso
);
149 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound8_Compact() failed: %s\n",
150 DXGetErrorString8(rc
));
152 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
153 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
154 DXGetErrorString8(rc
));
156 rc
=IDirectSound8_Compact(dso
);
157 ok(rc
==DS_OK
,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc
));
159 rc
=IDirectSound8_GetSpeakerConfig(dso
,0);
160 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetSpeakerConfig(NULL) "
161 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
162 DXGetErrorString8(rc
));
164 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
165 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
166 DXGetErrorString8(rc
));
168 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
169 DSSPEAKER_GEOMETRY_WIDE
);
170 rc
=IDirectSound8_SetSpeakerConfig(dso
,speaker_config
);
171 ok(rc
==DS_OK
,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
172 DXGetErrorString8(rc
));
174 rc
=IDirectSound8_GetSpeakerConfig(dso
,&new_speaker_config
);
175 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
176 DXGetErrorString8(rc
));
177 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
178 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
179 "config: expected 0x%08x, got 0x%08x\n",
180 speaker_config
,new_speaker_config
);
183 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
184 ok(rc
==DS_OK
||rc
==E_NOTIMPL
,"IDirectSound8_VerifyCertification() failed: %s\n",
185 DXGetErrorString8(rc
));
188 ref
=IDirectSound8_Release(dso
);
189 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
192 static void IDirectSound8_tests(void)
195 LPDIRECTSOUND8 dso
=NULL
;
196 LPCLASSFACTORY cf
=NULL
;
198 trace("Testing IDirectSound8\n");
200 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
201 &IID_IClassFactory
, (void**)&cf
);
202 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
203 "failed: %s\n", DXGetErrorString8(rc
));
205 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
206 &IID_IUnknown
, (void**)&cf
);
207 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) "
208 "failed: %s\n", DXGetErrorString8(rc
));
210 /* try the COM class factory method of creation with no device specified */
211 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
212 &IID_IDirectSound8
, (void**)&dso
);
213 ok(rc
==S_OK
||rc
==REGDB_E_CLASSNOTREG
,"CoCreateInstance() failed: %s\n",
214 DXGetErrorString8(rc
));
215 if (rc
==REGDB_E_CLASSNOTREG
) {
216 trace(" Class Not Registered\n");
220 IDirectSound8_test(dso
, FALSE
, NULL
);
222 /* try the COM class factory method of creation with default playback
223 * device specified */
224 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
225 &IID_IDirectSound8
, (void**)&dso
);
226 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
227 DXGetErrorString8(rc
));
229 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
231 /* try the COM class factory method of creation with default voice
232 * playback device specified */
233 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
234 &IID_IDirectSound8
, (void**)&dso
);
235 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
236 DXGetErrorString8(rc
));
238 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
240 /* try the COM class factory method of creation with a bad
242 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
243 &CLSID_DirectSoundPrivate
, (void**)&dso
);
244 ok(rc
==E_NOINTERFACE
,
245 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
246 "should have failed: %s\n",DXGetErrorString8(rc
));
248 /* try the COM class factory method of creation with a bad
249 * GUID and IID specified */
250 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
251 &IID_IDirectSound8
, (void**)&dso
);
252 ok(rc
==REGDB_E_CLASSNOTREG
,
253 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
254 "should have failed: %s\n",DXGetErrorString8(rc
));
256 /* try with no device specified */
257 rc
=pDirectSoundCreate8(NULL
,&dso
,NULL
);
258 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
259 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
260 if (rc
==DS_OK
&& dso
)
261 IDirectSound8_test(dso
, TRUE
, NULL
);
263 /* try with default playback device specified */
264 rc
=pDirectSoundCreate8(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
265 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
266 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
267 if (rc
==DS_OK
&& dso
)
268 IDirectSound8_test(dso
, TRUE
, NULL
);
270 /* try with default voice playback device specified */
271 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
272 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
273 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
274 if (rc
==DS_OK
&& dso
)
275 IDirectSound8_test(dso
, TRUE
, NULL
);
277 /* try with a bad device specified */
278 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
279 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
280 "should have failed: %s\n",DXGetErrorString8(rc
));
283 static HRESULT
test_dsound8(LPGUID lpGuid
)
286 LPDIRECTSOUND8 dso
=NULL
;
289 /* DSOUND: Error: Invalid interface buffer */
290 rc
=pDirectSoundCreate8(lpGuid
,0,NULL
);
291 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate8() should have returned "
292 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
294 /* Create the DirectSound8 object */
295 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
296 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
297 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
301 /* Try the enumerated device */
302 IDirectSound8_test(dso
, TRUE
, lpGuid
);
304 /* Try the COM class factory method of creation with enumerated device */
305 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
306 &IID_IDirectSound8
, (void**)&dso
);
307 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
308 DXGetErrorString8(rc
));
310 IDirectSound8_test(dso
, FALSE
, lpGuid
);
312 /* Create a DirectSound8 object */
313 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
314 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
316 LPDIRECTSOUND8 dso1
=NULL
;
318 /* Create a second DirectSound8 object */
319 rc
=pDirectSoundCreate8(lpGuid
,&dso1
,NULL
);
320 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
322 /* Release the second DirectSound8 object */
323 ref
=IDirectSound8_Release(dso1
);
324 ok(ref
==0,"IDirectSound8_Release() has %d references, "
325 "should have 0\n",ref
);
326 ok(dso
!=dso1
,"DirectSound8 objects should be unique: "
327 "dso=%p,dso1=%p\n",dso
,dso1
);
330 /* Release the first DirectSound8 object */
331 ref
=IDirectSound8_Release(dso
);
332 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
335 return DSERR_GENERIC
;
339 /* Create a DirectSound8 object */
340 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
341 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
343 LPDIRECTSOUNDBUFFER secondary
;
344 DSBUFFERDESC bufdesc
;
347 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
348 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
349 bufdesc
.dwSize
=sizeof(bufdesc
);
350 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
351 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
353 bufdesc
.lpwfxFormat
=&wfx
;
354 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
355 ok(rc
==DS_OK
&& secondary
!=NULL
,
356 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
357 "buffer: %s\n",DXGetErrorString8(rc
));
358 if (rc
==DS_OK
&& secondary
!=NULL
) {
359 LPDIRECTSOUND3DBUFFER buffer3d
;
360 LPDIRECTSOUNDBUFFER8 buffer8
;
361 rc
=IDirectSound8_QueryInterface(secondary
,
362 &IID_IDirectSound3DBuffer
,
364 ok(rc
==DS_OK
&& buffer3d
!=NULL
,
365 "IDirectSound8_QueryInterface() failed: %s\n",
366 DXGetErrorString8(rc
));
367 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
368 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
369 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
370 "should have 2\n",ref
);
372 rc
=IDirectSound8_QueryInterface(secondary
,
373 &IID_IDirectSoundBuffer8
,
375 if (rc
==DS_OK
&& buffer8
!=NULL
) {
376 ref
=IDirectSoundBuffer8_AddRef(buffer8
);
377 ok(ref
==3,"IDirectSoundBuffer8_AddRef() has %d references, "
378 "should have 3\n",ref
);
380 ref
=IDirectSoundBuffer_AddRef(secondary
);
381 ok(ref
==4,"IDirectSoundBuffer_AddRef() has %d references, "
382 "should have 4\n",ref
);
384 /* release with buffer */
385 ref
=IDirectSound8_Release(dso
);
386 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
389 return DSERR_GENERIC
;
396 static HRESULT
test_primary8(LPGUID lpGuid
)
399 LPDIRECTSOUND8 dso
=NULL
;
400 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
401 LPDIRECTSOUNDBUFFER8 pb8
= NULL
;
402 DSBUFFERDESC bufdesc
;
407 /* Create the DirectSound object */
408 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
409 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
410 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
414 /* Get the device capabilities */
415 ZeroMemory(&dscaps
, sizeof(dscaps
));
416 dscaps
.dwSize
=sizeof(dscaps
);
417 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
418 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
422 /* DSOUND: Error: Invalid buffer description pointer */
423 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,0,NULL
);
424 ok(rc
==DSERR_INVALIDPARAM
,
425 "IDirectSound8_CreateSoundBuffer should have returned "
426 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
428 /* DSOUND: Error: Invalid buffer description pointer */
429 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,&primary
,NULL
);
430 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
431 "IDirectSound8_CreateSoundBuffer() should have returned "
432 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=%p\n",
433 DXGetErrorString8(rc
),primary
);
435 /* DSOUND: Error: Invalid buffer description pointer */
436 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
437 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
438 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
439 "dsbo=%p\n",DXGetErrorString8(rc
),primary
);
441 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
443 /* DSOUND: Error: Invalid size */
444 /* DSOUND: Error: Invalid buffer description */
445 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
446 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
447 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
448 "primary=%p\n",DXGetErrorString8(rc
),primary
);
450 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
451 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
452 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
453 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
454 DXGetErrorString8(rc
));
458 /* Testing the primary buffer */
460 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
461 bufdesc
.dwSize
=sizeof(bufdesc
);
462 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
463 bufdesc
.lpwfxFormat
= &wfx
;
464 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
465 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
466 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() should have "
467 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc
));
468 if (rc
==DS_OK
&& primary
!=NULL
)
469 IDirectSoundBuffer_Release(primary
);
472 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
473 bufdesc
.dwSize
=sizeof(bufdesc
);
474 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
475 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
476 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
477 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
478 "%s\n",DXGetErrorString8(rc
));
479 if (rc
==DSERR_CONTROLUNAVAIL
)
480 trace(" No Primary\n");
481 else if (rc
==DS_OK
&& primary
!=NULL
) {
484 /* Try to create a second primary buffer */
485 /* DSOUND: Error: The primary buffer already exists.
486 * Any changes made to the buffer description will be ignored. */
487 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
488 ok(rc
==DS_OK
&& second
==primary
,
489 "IDirectSound8_CreateSoundBuffer() should have returned original "
490 "primary buffer: %s\n",DXGetErrorString8(rc
));
491 ref
=IDirectSoundBuffer_Release(second
);
492 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
493 "should have 1\n",ref
);
495 /* Try to duplicate a primary buffer */
496 /* DSOUND: Error: Can't duplicate primary buffers */
497 rc
=IDirectSound8_DuplicateSoundBuffer(dso
,primary
,&third
);
499 ok(rc
!=DS_OK
,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
500 "should have failed %s\n",DXGetErrorString8(rc
));
502 /* Primary buffers don't have an IDirectSoundBuffer8 */
503 rc
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
, (LPVOID
*)&pb8
);
504 ok(FAILED(rc
), "Primary buffer does have an IDirectSoundBuffer8: %s\n", DXGetErrorString8(rc
));
506 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
507 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
508 DXGetErrorString8(rc
));
510 if (winetest_interactive
) {
511 trace("Playing a 5 seconds reference tone at the current volume.\n");
513 trace("(the current volume is %d according to DirectSound)\n",
515 trace("All subsequent tones should be identical to this one.\n");
516 trace("Listen for stutter, changes in pitch, volume, etc.\n");
518 test_buffer8(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
519 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
521 ref
=IDirectSoundBuffer_Release(primary
);
522 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
523 "should have 0\n",ref
);
526 /* Set the CooperativeLevel back to normal */
527 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
528 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
529 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
530 DXGetErrorString8(rc
));
533 ref
=IDirectSound8_Release(dso
);
534 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
536 return DSERR_GENERIC
;
542 * Test the primary buffer at different formats while keeping the
543 * secondary buffer at a constant format.
545 static HRESULT
test_primary_secondary8(LPGUID lpGuid
)
548 LPDIRECTSOUND8 dso
=NULL
;
549 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
550 DSBUFFERDESC bufdesc
;
552 WAVEFORMATEX wfx
, wfx2
;
556 /* Create the DirectSound object */
557 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
558 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
559 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
563 /* Get the device capabilities */
564 ZeroMemory(&dscaps
, sizeof(dscaps
));
565 dscaps
.dwSize
=sizeof(dscaps
);
566 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
567 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
571 /* We must call SetCooperativeLevel before creating primary buffer */
572 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
573 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
574 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
575 DXGetErrorString8(rc
));
579 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
580 bufdesc
.dwSize
=sizeof(bufdesc
);
581 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
582 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
583 ok(rc
==DS_OK
&& primary
!=NULL
,
584 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
585 "%s\n",DXGetErrorString8(rc
));
587 if (rc
==DS_OK
&& primary
!=NULL
) {
588 for (f
=0;f
<NB_FORMATS
;f
++) {
589 /* We must call SetCooperativeLevel to be allowed to call
591 /* DSOUND: Setting DirectSound cooperative level to
593 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
594 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
595 DXGetErrorString8(rc
));
599 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
602 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
603 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %s\n",
604 format_string(&wfx
), DXGetErrorString8(rc
));
606 /* There is no guarantee that SetFormat will actually change the
607 * format to what we asked for. It depends on what the soundcard
608 * supports. So we must re-query the format.
610 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
611 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
612 DXGetErrorString8(rc
));
614 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
615 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
616 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
617 wfx
.nChannels
!=wfx2
.nChannels
)) {
618 trace("Requested primary format tag=0x%04x %dx%dx%d "
619 "avg.B/s=%d align=%d\n",
620 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
621 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
622 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
623 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
624 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
627 /* Set the CooperativeLevel back to normal */
628 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
629 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
630 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
631 DXGetErrorString8(rc
));
633 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
636 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
637 bufdesc
.dwSize
=sizeof(bufdesc
);
638 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
639 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
641 bufdesc
.lpwfxFormat
=&wfx2
;
642 if (winetest_interactive
) {
643 trace(" Testing a primary buffer at %dx%dx%d with a "
644 "secondary buffer at %dx%dx%d\n",
645 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
646 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
648 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
649 ok(rc
==DS_OK
&& secondary
!=NULL
,
650 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
651 "buffer %s\n",DXGetErrorString8(rc
));
653 if (rc
==DS_OK
&& secondary
!=NULL
) {
654 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
655 winetest_interactive
,1.0,0,NULL
,0,0);
657 ref
=IDirectSoundBuffer_Release(secondary
);
658 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
659 "should have 0\n",ref
);
663 ref
=IDirectSoundBuffer_Release(primary
);
664 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
665 "should have 0\n",ref
);
668 /* Set the CooperativeLevel back to normal */
669 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
670 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
671 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
672 DXGetErrorString8(rc
));
675 ref
=IDirectSound8_Release(dso
);
676 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
678 return DSERR_GENERIC
;
683 static HRESULT
test_secondary8(LPGUID lpGuid
)
686 LPDIRECTSOUND8 dso
=NULL
;
687 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
688 DSBUFFERDESC bufdesc
;
690 WAVEFORMATEX wfx
, wfx1
;
694 /* Create the DirectSound object */
695 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
696 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
697 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc
));
701 /* Get the device capabilities */
702 ZeroMemory(&dscaps
, sizeof(dscaps
));
703 dscaps
.dwSize
=sizeof(dscaps
);
704 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
705 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
709 /* We must call SetCooperativeLevel before creating primary buffer */
710 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
711 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
712 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
713 DXGetErrorString8(rc
));
717 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
718 bufdesc
.dwSize
=sizeof(bufdesc
);
719 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
720 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
721 ok(rc
==DS_OK
&& primary
!=NULL
,
722 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
723 "%s\n",DXGetErrorString8(rc
));
725 if (rc
==DS_OK
&& primary
!=NULL
) {
726 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
727 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
728 DXGetErrorString8(rc
));
732 for (f
=0;f
<NB_FORMATS
;f
++) {
733 WAVEFORMATEXTENSIBLE wfxe
;
734 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
737 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
738 bufdesc
.dwSize
=sizeof(bufdesc
);
739 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
740 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
742 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
743 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() "
744 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
745 DXGetErrorString8(rc
));
746 if (rc
==DS_OK
&& secondary
!=NULL
)
747 IDirectSoundBuffer_Release(secondary
);
750 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
751 bufdesc
.dwSize
=sizeof(bufdesc
);
752 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
753 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
755 bufdesc
.lpwfxFormat
=&wfx
;
756 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
757 if (wfx
.wBitsPerSample
!= 8 && wfx
.wBitsPerSample
!= 16)
758 ok(rc
== DSERR_CONTROLUNAVAIL
&& !secondary
, "IDirectSound_CreateSoundBuffer() "
759 "should have returned DSERR_CONTROLUNAVAIL and NULL, returned: %s %p\n",
760 DXGetErrorString8(rc
), secondary
);
762 ok(rc
==DS_OK
&& secondary
!=NULL
,
763 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
764 "buffer %s\n",DXGetErrorString8(rc
));
766 IDirectSoundBuffer_Release(secondary
);
769 bufdesc
.lpwfxFormat
=(WAVEFORMATEX
*)&wfxe
;
771 wfxe
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
772 wfxe
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
773 wfxe
.Format
.cbSize
= 1;
774 wfxe
.Samples
.wValidBitsPerSample
= wfx
.wBitsPerSample
;
775 wfxe
.dwChannelMask
= (wfx
.nChannels
== 1 ? KSAUDIO_SPEAKER_MONO
: KSAUDIO_SPEAKER_STEREO
);
777 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
778 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
779 "IDirectSound_CreateSoundBuffer() returned: %s %p\n",
780 DXGetErrorString8(rc
), secondary
);
782 IDirectSoundBuffer_Release(secondary
);
784 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
) + 1;
786 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
787 ok(DSERR_CONTROLUNAVAIL
&& !secondary
,
788 "IDirectSound_CreateSoundBuffer() returned: %s %p\n",
789 DXGetErrorString8(rc
), secondary
);
791 IDirectSoundBuffer_Release(secondary
);
793 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
794 wfxe
.SubFormat
= GUID_NULL
;
795 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
796 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
797 "IDirectSound_CreateSoundBuffer() returned: %s %p\n",
798 DXGetErrorString8(rc
), secondary
);
800 IDirectSoundBuffer_Release(secondary
);
801 wfxe
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
803 ++wfxe
.Samples
.wValidBitsPerSample
;
804 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
805 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
806 "IDirectSound_CreateSoundBuffer() returned: %s %p\n",
807 DXGetErrorString8(rc
), secondary
);
809 IDirectSoundBuffer_Release(secondary
);
810 --wfxe
.Samples
.wValidBitsPerSample
;
812 wfxe
.Samples
.wValidBitsPerSample
= 0;
813 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
814 ok(rc
==DS_OK
&& secondary
,
815 "IDirectSound_CreateSoundBuffer() returned: %s %p\n",
816 DXGetErrorString8(rc
), secondary
);
818 IDirectSoundBuffer_Release(secondary
);
819 wfxe
.Samples
.wValidBitsPerSample
= wfxe
.Format
.wBitsPerSample
;
821 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
822 ok(rc
==DS_OK
&& secondary
!=NULL
,
823 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
824 "buffer %s\n",DXGetErrorString8(rc
));
826 if (rc
==DS_OK
&& secondary
!=NULL
) {
827 if (winetest_interactive
) {
828 trace(" Testing a secondary buffer at %dx%dx%d "
829 "with a primary buffer at %dx%dx%d\n",
830 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
831 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
833 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
834 winetest_interactive
,1.0,0,NULL
,0,0);
836 ref
=IDirectSoundBuffer_Release(secondary
);
837 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
838 "should have 0\n",ref
);
842 ref
=IDirectSoundBuffer_Release(primary
);
843 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
844 "should have 0\n",ref
);
847 /* Set the CooperativeLevel back to normal */
848 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
849 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
850 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
851 DXGetErrorString8(rc
));
854 ref
=IDirectSound8_Release(dso
);
855 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
857 return DSERR_GENERIC
;
862 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
863 LPCSTR lpcstrModule
, LPVOID lpContext
)
866 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
867 rc
= test_dsound8(lpGuid
);
868 if (rc
== DSERR_NODRIVER
)
869 trace(" No Driver\n");
870 else if (rc
== DSERR_ALLOCATED
)
871 trace(" Already In Use\n");
872 else if (rc
== E_FAIL
)
873 trace(" No Device\n");
875 test_primary8(lpGuid
);
876 test_primary_secondary8(lpGuid
);
877 test_secondary8(lpGuid
);
883 static void dsound8_tests(void)
886 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
887 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
890 const char * get_file_version(const char * file_name
)
892 static char version
[32];
893 static char backslash
[] = "\\";
897 size
= GetFileVersionInfoSizeA("dsound.dll", &handle
);
899 char * data
= HeapAlloc(GetProcessHeap(), 0, size
);
901 if (GetFileVersionInfoA("dsound.dll", handle
, size
, data
)) {
902 VS_FIXEDFILEINFO
*pFixedVersionInfo
;
904 if (VerQueryValueA(data
, backslash
, (LPVOID
*)&pFixedVersionInfo
, &len
)) {
905 sprintf(version
, "%d.%d.%d.%d",
906 pFixedVersionInfo
->dwFileVersionMS
>> 16,
907 pFixedVersionInfo
->dwFileVersionMS
& 0xffff,
908 pFixedVersionInfo
->dwFileVersionLS
>> 16,
909 pFixedVersionInfo
->dwFileVersionLS
& 0xffff);
911 sprintf(version
, "not available");
913 sprintf(version
, "failed");
915 HeapFree(GetProcessHeap(), 0, data
);
917 sprintf(version
, "failed");
919 sprintf(version
, "not available");
930 hDsound
= LoadLibrary("dsound.dll");
933 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
935 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
936 "DirectSoundEnumerateA");
937 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
,
938 "DirectSoundCreate8");
939 if (pDirectSoundCreate8
)
941 IDirectSound8_tests();
945 skip("dsound8 test skipped\n");
947 FreeLibrary(hDsound
);
950 skip("dsound.dll not found!\n");