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"
38 #include "dsound_test.h"
40 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
41 static HRESULT (WINAPI
*pDirectSoundCreate8
)(LPCGUID
,LPDIRECTSOUND8
*,LPUNKNOWN
)=NULL
;
43 int align(int length
, int align
)
45 return (length
/ align
) * align
;
48 static void IDirectSound8_test(LPDIRECTSOUND8 dso
, BOOL initialized
,
57 DWORD speaker_config
, new_speaker_config
, ref_speaker_config
;
60 /* Try to Query for objects */
61 rc
=IDirectSound8_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
62 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %08x\n", rc
);
64 IDirectSound8_Release(unknown
);
66 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
67 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %08x\n", rc
);
69 IDirectSound_Release(ds
);
71 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
72 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
73 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
75 IDirectSound8_Release(ds8
);
77 if (initialized
== FALSE
) {
78 /* try uninitialized object */
79 rc
=IDirectSound8_GetCaps(dso
,0);
80 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps(NULL) "
81 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
83 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
84 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps() "
85 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
87 rc
=IDirectSound8_Compact(dso
);
88 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_Compact() "
89 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
91 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
92 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetSpeakerConfig() "
93 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
95 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
96 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_VerifyCertification() "
97 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
99 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
100 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
101 "IDirectSound8_Initialize() failed: %08x\n",rc
);
102 if (rc
==DSERR_NODRIVER
) {
103 trace(" No Driver\n");
105 } else if (rc
==E_FAIL
) {
106 trace(" No Device\n");
108 } else if (rc
==DSERR_ALLOCATED
) {
109 trace(" Already In Use\n");
114 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
115 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSound8_Initialize() "
116 "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc
);
118 /* DSOUND: Error: Invalid caps buffer */
119 rc
=IDirectSound8_GetCaps(dso
,0);
120 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
121 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
123 ZeroMemory(&dscaps
, sizeof(dscaps
));
125 /* DSOUND: Error: Invalid caps buffer */
126 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
127 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
128 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
130 dscaps
.dwSize
=sizeof(dscaps
);
132 /* DSOUND: Running on a certified driver */
133 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
134 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
136 rc
=IDirectSound8_Compact(dso
);
137 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound8_Compact() failed: %08x\n", rc
);
139 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
140 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
142 rc
=IDirectSound8_Compact(dso
);
143 ok(rc
==DS_OK
,"IDirectSound8_Compact() failed: %08x\n",rc
);
145 rc
=IDirectSound8_GetSpeakerConfig(dso
,0);
146 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetSpeakerConfig(NULL) "
147 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
149 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
150 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc
);
151 ref_speaker_config
= speaker_config
;
153 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
154 DSSPEAKER_GEOMETRY_WIDE
);
155 if (speaker_config
== ref_speaker_config
)
156 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
157 DSSPEAKER_GEOMETRY_NARROW
);
159 rc
=IDirectSound8_SetSpeakerConfig(dso
,speaker_config
);
160 ok(rc
==DS_OK
,"IDirectSound8_SetSpeakerConfig() failed: %08x\n", rc
);
163 rc
=IDirectSound8_GetSpeakerConfig(dso
,&new_speaker_config
);
164 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc
);
165 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
166 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
167 "config: expected 0x%08x, got 0x%08x\n",
168 speaker_config
,new_speaker_config
);
169 IDirectSound8_SetSpeakerConfig(dso
,ref_speaker_config
);
172 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
173 ok(rc
==DS_OK
||rc
==E_NOTIMPL
,"IDirectSound8_VerifyCertification() failed: %08x\n", rc
);
176 ref
=IDirectSound8_Release(dso
);
177 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
180 static void IDirectSound8_tests(void)
183 LPDIRECTSOUND8 dso
=NULL
;
184 LPCLASSFACTORY cf
=NULL
;
186 trace("Testing IDirectSound8\n");
188 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
189 &IID_IClassFactory
, (void**)&cf
);
190 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
191 "failed: %08x\n", rc
);
193 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
194 &IID_IUnknown
, (void**)&cf
);
195 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) "
196 "failed: %08x\n", rc
);
198 /* try the COM class factory method of creation with no device specified */
199 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
200 &IID_IDirectSound8
, (void**)&dso
);
201 ok(rc
==S_OK
||rc
==REGDB_E_CLASSNOTREG
,"CoCreateInstance() failed: %08x\n", rc
);
202 if (rc
==REGDB_E_CLASSNOTREG
) {
203 trace(" Class Not Registered\n");
207 IDirectSound8_test(dso
, FALSE
, NULL
);
209 /* try the COM class factory method of creation with default playback
210 * device specified */
211 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
212 &IID_IDirectSound8
, (void**)&dso
);
213 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc
);
215 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
217 /* try the COM class factory method of creation with default voice
218 * playback device specified */
219 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
220 &IID_IDirectSound8
, (void**)&dso
);
221 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc
);
223 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
225 /* try the COM class factory method of creation with a bad
227 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
228 &CLSID_DirectSoundPrivate
, (void**)&dso
);
229 ok(rc
==E_NOINTERFACE
,
230 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
231 "should have failed: %08x\n",rc
);
233 /* try the COM class factory method of creation with a bad
234 * GUID and IID specified */
235 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
236 &IID_IDirectSound8
, (void**)&dso
);
237 ok(rc
==REGDB_E_CLASSNOTREG
,
238 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
239 "should have failed: %08x\n",rc
);
241 /* try with no device specified */
242 rc
=pDirectSoundCreate8(NULL
,&dso
,NULL
);
243 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
244 "DirectSoundCreate8() failed: %08x\n",rc
);
245 if (rc
==DS_OK
&& dso
)
246 IDirectSound8_test(dso
, TRUE
, NULL
);
248 /* try with default playback device specified */
249 rc
=pDirectSoundCreate8(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
250 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
251 "DirectSoundCreate8() failed: %08x\n",rc
);
252 if (rc
==DS_OK
&& dso
)
253 IDirectSound8_test(dso
, TRUE
, NULL
);
255 /* try with default voice playback device specified */
256 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
257 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
258 "DirectSoundCreate8() failed: %08x\n",rc
);
259 if (rc
==DS_OK
&& dso
)
260 IDirectSound8_test(dso
, TRUE
, NULL
);
262 /* try with a bad device specified */
263 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
264 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
265 "should have failed: %08x\n",rc
);
268 static HRESULT
test_dsound8(LPGUID lpGuid
)
271 LPDIRECTSOUND8 dso
=NULL
;
274 /* DSOUND: Error: Invalid interface buffer */
275 rc
=pDirectSoundCreate8(lpGuid
,0,NULL
);
276 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate8() should have returned "
277 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
279 /* Create the DirectSound8 object */
280 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
281 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
282 "DirectSoundCreate8() failed: %08x\n",rc
);
286 /* Try the enumerated device */
287 IDirectSound8_test(dso
, TRUE
, lpGuid
);
289 /* Try the COM class factory method of creation with enumerated device */
290 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
291 &IID_IDirectSound8
, (void**)&dso
);
292 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
294 IDirectSound8_test(dso
, FALSE
, lpGuid
);
296 /* Create a DirectSound8 object */
297 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
298 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
300 LPDIRECTSOUND8 dso1
=NULL
;
302 /* Create a second DirectSound8 object */
303 rc
=pDirectSoundCreate8(lpGuid
,&dso1
,NULL
);
304 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
306 /* Release the second DirectSound8 object */
307 ref
=IDirectSound8_Release(dso1
);
308 ok(ref
==0,"IDirectSound8_Release() has %d references, "
309 "should have 0\n",ref
);
310 ok(dso
!=dso1
,"DirectSound8 objects should be unique: "
311 "dso=%p,dso1=%p\n",dso
,dso1
);
314 /* Release the first DirectSound8 object */
315 ref
=IDirectSound8_Release(dso
);
316 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
319 return DSERR_GENERIC
;
323 /* Create a DirectSound8 object */
324 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
325 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
327 LPDIRECTSOUNDBUFFER secondary
;
328 DSBUFFERDESC bufdesc
;
331 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
332 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
333 bufdesc
.dwSize
=sizeof(bufdesc
);
334 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
335 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
337 bufdesc
.lpwfxFormat
=&wfx
;
338 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
339 ok(rc
==DS_OK
&& secondary
!=NULL
,
340 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
341 "buffer: %08x\n",rc
);
342 if (rc
==DS_OK
&& secondary
!=NULL
) {
343 LPDIRECTSOUND3DBUFFER buffer3d
;
344 LPDIRECTSOUNDBUFFER8 buffer8
;
345 rc
=IDirectSound8_QueryInterface(secondary
,
346 &IID_IDirectSound3DBuffer
,
348 ok(rc
==DS_OK
&& buffer3d
!=NULL
,
349 "IDirectSound8_QueryInterface() failed: %08x\n", rc
);
350 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
351 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
352 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
353 "should have 2\n",ref
);
355 rc
=IDirectSound8_QueryInterface(secondary
,
356 &IID_IDirectSoundBuffer8
,
358 if (rc
==DS_OK
&& buffer8
!=NULL
) {
359 ref
=IDirectSoundBuffer8_AddRef(buffer8
);
360 ok(ref
==3,"IDirectSoundBuffer8_AddRef() has %d references, "
361 "should have 3\n",ref
);
363 ref
=IDirectSoundBuffer_AddRef(secondary
);
364 ok(ref
==4,"IDirectSoundBuffer_AddRef() has %d references, "
365 "should have 4\n",ref
);
367 /* release with buffer */
368 ref
=IDirectSound8_Release(dso
);
369 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
372 return DSERR_GENERIC
;
379 static HRESULT
test_primary8(LPGUID lpGuid
)
382 LPDIRECTSOUND8 dso
=NULL
;
383 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
384 LPDIRECTSOUNDBUFFER8 pb8
= NULL
;
385 DSBUFFERDESC bufdesc
;
390 /* Create the DirectSound object */
391 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
392 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
393 "DirectSoundCreate8() failed: %08x\n",rc
);
397 /* Get the device capabilities */
398 ZeroMemory(&dscaps
, sizeof(dscaps
));
399 dscaps
.dwSize
=sizeof(dscaps
);
400 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
401 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
405 /* DSOUND: Error: Invalid buffer description pointer */
406 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,0,NULL
);
407 ok(rc
==DSERR_INVALIDPARAM
,
408 "IDirectSound8_CreateSoundBuffer should have returned "
409 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
411 /* DSOUND: Error: Invalid buffer description pointer */
412 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,&primary
,NULL
);
413 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
414 "IDirectSound8_CreateSoundBuffer() should have returned "
415 "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n",
418 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
419 bufdesc
.dwSize
= sizeof(DSBUFFERDESC
);
421 /* DSOUND: Error: Invalid dsound buffer interface pointer */
422 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
423 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
424 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
425 "dsbo=%p\n",rc
,primary
);
427 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
429 /* DSOUND: Error: Invalid size */
430 /* DSOUND: Error: Invalid buffer description */
431 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
432 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
433 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
434 "primary=%p\n",rc
,primary
);
436 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
437 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
438 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
439 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
443 /* Testing the primary buffer */
445 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
446 bufdesc
.dwSize
=sizeof(bufdesc
);
447 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
448 bufdesc
.lpwfxFormat
= &wfx
;
449 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
450 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
451 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() should have "
452 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
453 if (rc
==DS_OK
&& primary
!=NULL
)
454 IDirectSoundBuffer_Release(primary
);
457 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
458 bufdesc
.dwSize
=sizeof(bufdesc
);
459 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
460 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
461 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
462 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
464 if (rc
==DSERR_CONTROLUNAVAIL
)
465 trace(" No Primary\n");
466 else if (rc
==DS_OK
&& primary
!=NULL
) {
469 /* Try to create a second primary buffer */
470 /* DSOUND: Error: The primary buffer already exists.
471 * Any changes made to the buffer description will be ignored. */
472 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
473 ok(rc
==DS_OK
&& second
==primary
,
474 "IDirectSound8_CreateSoundBuffer() should have returned original "
475 "primary buffer: %08x\n",rc
);
476 ref
=IDirectSoundBuffer_Release(second
);
477 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
478 "should have 1\n",ref
);
480 /* Try to duplicate a primary buffer */
481 /* DSOUND: Error: Can't duplicate primary buffers */
482 rc
=IDirectSound8_DuplicateSoundBuffer(dso
,primary
,&third
);
484 ok(rc
!=DS_OK
,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
485 "should have failed %08x\n",rc
);
487 /* Primary buffers don't have an IDirectSoundBuffer8 */
488 rc
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
, (LPVOID
*)&pb8
);
489 ok(FAILED(rc
), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc
);
491 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
492 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc
);
494 if (winetest_interactive
) {
495 trace("Playing a 5 seconds reference tone at the current volume.\n");
497 trace("(the current volume is %d according to DirectSound)\n",
499 trace("All subsequent tones should be identical to this one.\n");
500 trace("Listen for stutter, changes in pitch, volume, etc.\n");
502 test_buffer8(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
503 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
505 ref
=IDirectSoundBuffer_Release(primary
);
506 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
507 "should have 0\n",ref
);
510 /* Set the CooperativeLevel back to normal */
511 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
512 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
513 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
516 ref
=IDirectSound8_Release(dso
);
517 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
519 return DSERR_GENERIC
;
525 * Test the primary buffer at different formats while keeping the
526 * secondary buffer at a constant format.
528 static HRESULT
test_primary_secondary8(LPGUID lpGuid
)
531 LPDIRECTSOUND8 dso
=NULL
;
532 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
533 DSBUFFERDESC bufdesc
;
535 WAVEFORMATEX wfx
, wfx2
;
539 /* Create the DirectSound object */
540 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
541 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
542 "DirectSoundCreate8() failed: %08x\n",rc
);
546 /* Get the device capabilities */
547 ZeroMemory(&dscaps
, sizeof(dscaps
));
548 dscaps
.dwSize
=sizeof(dscaps
);
549 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
550 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
554 /* We must call SetCooperativeLevel before creating primary buffer */
555 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
556 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
557 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
561 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
562 bufdesc
.dwSize
=sizeof(bufdesc
);
563 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
564 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
565 ok(rc
==DS_OK
&& primary
!=NULL
,
566 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
569 if (rc
==DS_OK
&& primary
!=NULL
) {
570 for (f
=0;f
<NB_FORMATS
;f
++) {
571 /* We must call SetCooperativeLevel to be allowed to call
573 /* DSOUND: Setting DirectSound cooperative level to
575 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
576 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
580 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
583 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
585 || rc
==DSERR_INVALIDPARAM
, /* 2003 */
586 "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
587 format_string(&wfx
), rc
);
589 /* There is no guarantee that SetFormat will actually change the
590 * format to what we asked for. It depends on what the soundcard
591 * supports. So we must re-query the format.
593 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
594 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
596 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
597 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
598 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
599 wfx
.nChannels
!=wfx2
.nChannels
)) {
600 trace("Requested primary format tag=0x%04x %dx%dx%d "
601 "avg.B/s=%d align=%d\n",
602 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
603 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
604 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
605 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
606 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
609 /* Set the CooperativeLevel back to normal */
610 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
611 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
612 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
614 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
617 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
618 bufdesc
.dwSize
=sizeof(bufdesc
);
619 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
620 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
622 bufdesc
.lpwfxFormat
=&wfx2
;
623 if (winetest_interactive
) {
624 trace(" Testing a primary buffer at %dx%dx%d with a "
625 "secondary buffer at %dx%dx%d\n",
626 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
627 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
629 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
630 ok(rc
==DS_OK
&& secondary
!=NULL
,
631 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
634 if (rc
==DS_OK
&& secondary
!=NULL
) {
635 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
636 winetest_interactive
,1.0,0,NULL
,0,0);
638 ref
=IDirectSoundBuffer_Release(secondary
);
639 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
640 "should have 0\n",ref
);
644 ref
=IDirectSoundBuffer_Release(primary
);
645 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
646 "should have 0\n",ref
);
649 /* Set the CooperativeLevel back to normal */
650 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
651 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
652 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
655 ref
=IDirectSound8_Release(dso
);
656 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
658 return DSERR_GENERIC
;
663 static HRESULT
test_secondary8(LPGUID lpGuid
)
666 LPDIRECTSOUND8 dso
=NULL
;
667 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
668 DSBUFFERDESC bufdesc
;
670 WAVEFORMATEX wfx
, wfx1
;
674 /* Create the DirectSound object */
675 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
676 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
677 "DirectSoundCreate8() failed: %08x\n",rc
);
681 /* Get the device capabilities */
682 ZeroMemory(&dscaps
, sizeof(dscaps
));
683 dscaps
.dwSize
=sizeof(dscaps
);
684 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
685 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
689 /* We must call SetCooperativeLevel before creating primary buffer */
690 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
691 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
692 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
696 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
697 bufdesc
.dwSize
=sizeof(bufdesc
);
698 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
699 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
700 ok(rc
==DS_OK
&& primary
!=NULL
,
701 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
704 if (rc
==DS_OK
&& primary
!=NULL
) {
705 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
706 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
710 for (f
=0;f
<NB_FORMATS
;f
++) {
711 WAVEFORMATEXTENSIBLE wfxe
;
712 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
715 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
716 bufdesc
.dwSize
=sizeof(bufdesc
);
717 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
718 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
720 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
721 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() "
722 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
723 if (rc
==DS_OK
&& secondary
!=NULL
)
724 IDirectSoundBuffer_Release(secondary
);
727 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
728 bufdesc
.dwSize
=sizeof(bufdesc
);
729 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
730 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
732 bufdesc
.lpwfxFormat
=&wfx
;
733 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
734 if (wfx
.wBitsPerSample
!= 8 && wfx
.wBitsPerSample
!= 16)
735 ok(((rc
== DSERR_CONTROLUNAVAIL
|| rc
== DSERR_INVALIDCALL
|| rc
== DSERR_INVALIDPARAM
/* 2003 */) && !secondary
)
736 || rc
== DS_OK
, /* driver dependent? */
737 "IDirectSound_CreateSoundBuffer() "
738 "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
739 "and NULL, returned: %08x %p\n", rc
, secondary
);
741 ok(rc
==DS_OK
&& secondary
!=NULL
,
742 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
745 IDirectSoundBuffer_Release(secondary
);
748 bufdesc
.lpwfxFormat
=(WAVEFORMATEX
*)&wfxe
;
750 wfxe
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
751 wfxe
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
752 wfxe
.Format
.cbSize
= 1;
753 wfxe
.Samples
.wValidBitsPerSample
= wfx
.wBitsPerSample
;
754 wfxe
.dwChannelMask
= (wfx
.nChannels
== 1 ? KSAUDIO_SPEAKER_MONO
: KSAUDIO_SPEAKER_STEREO
);
756 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
757 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
758 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
762 IDirectSoundBuffer_Release(secondary
);
766 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
) + 1;
768 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
769 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
)
770 || rc
==DS_OK
/* driver dependent? */,
771 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
775 IDirectSoundBuffer_Release(secondary
);
779 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
780 wfxe
.SubFormat
= GUID_NULL
;
781 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
782 ok((rc
==DSERR_INVALIDPARAM
|| rc
==DSERR_INVALIDCALL
) && !secondary
,
783 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
787 IDirectSoundBuffer_Release(secondary
);
791 wfxe
.Format
.cbSize
= sizeof(wfxe
);
792 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
793 ok((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
|| rc
==E_INVALIDARG
) && !secondary
,
794 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
798 IDirectSoundBuffer_Release(secondary
);
802 wfxe
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
803 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
804 ok(rc
==DS_OK
&& secondary
,
805 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
809 IDirectSoundBuffer_Release(secondary
);
813 wfxe
.Format
.cbSize
= sizeof(wfxe
) + 1;
814 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
815 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
)
816 || rc
==DS_OK
/* driver dependent? */,
817 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
821 IDirectSoundBuffer_Release(secondary
);
825 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
826 ++wfxe
.Samples
.wValidBitsPerSample
;
827 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
828 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
829 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
833 IDirectSoundBuffer_Release(secondary
);
836 --wfxe
.Samples
.wValidBitsPerSample
;
838 wfxe
.Samples
.wValidBitsPerSample
= 0;
839 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
840 ok(rc
==DS_OK
&& secondary
,
841 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
845 IDirectSoundBuffer_Release(secondary
);
848 wfxe
.Samples
.wValidBitsPerSample
= wfxe
.Format
.wBitsPerSample
;
850 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
851 ok(rc
==DS_OK
&& secondary
!=NULL
,
852 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
855 if (rc
==DS_OK
&& secondary
!=NULL
) {
856 if (winetest_interactive
) {
857 trace(" Testing a secondary buffer at %dx%dx%d "
858 "with a primary buffer at %dx%dx%d\n",
859 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
860 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
862 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
863 winetest_interactive
,1.0,0,NULL
,0,0);
865 ref
=IDirectSoundBuffer_Release(secondary
);
866 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
867 "should have 0\n",ref
);
871 ref
=IDirectSoundBuffer_Release(primary
);
872 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
873 "should have 0\n",ref
);
876 /* Set the CooperativeLevel back to normal */
877 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
878 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
879 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
882 ref
=IDirectSound8_Release(dso
);
883 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
885 return DSERR_GENERIC
;
890 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
891 LPCSTR lpcstrModule
, LPVOID lpContext
)
894 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
895 rc
= test_dsound8(lpGuid
);
896 if (rc
== DSERR_NODRIVER
)
897 trace(" No Driver\n");
898 else if (rc
== DSERR_ALLOCATED
)
899 trace(" Already In Use\n");
900 else if (rc
== E_FAIL
)
901 trace(" No Device\n");
903 test_primary8(lpGuid
);
904 test_primary_secondary8(lpGuid
);
905 test_secondary8(lpGuid
);
911 static void dsound8_tests(void)
914 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
915 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %08x\n",rc
);
925 hDsound
= LoadLibrary("dsound.dll");
929 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
930 "DirectSoundEnumerateA");
931 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
,
932 "DirectSoundCreate8");
933 if (pDirectSoundCreate8
)
935 IDirectSound8_tests();
939 skip("dsound8 test skipped\n");
941 FreeLibrary(hDsound
);
944 skip("dsound.dll not found!\n");