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
29 #define NONAMELESSUNION
33 #include "wine/test.h"
42 #include "mmdeviceapi.h"
43 #include "audioclient.h"
47 #include "dsound_test.h"
49 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
50 static HRESULT (WINAPI
*pDirectSoundCreate8
)(LPCGUID
,LPDIRECTSOUND8
*,LPUNKNOWN
)=NULL
;
52 int align(int length
, int align
)
54 return (length
/ align
) * align
;
57 static void IDirectSound8_test(LPDIRECTSOUND8 dso
, BOOL initialized
,
66 DWORD speaker_config
, new_speaker_config
, ref_speaker_config
;
69 /* Try to Query for objects */
70 rc
=IDirectSound8_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
71 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %08x\n", rc
);
73 IDirectSound8_Release(unknown
);
75 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
76 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %08x\n", rc
);
78 IDirectSound_Release(ds
);
80 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
81 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
82 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
84 IDirectSound8_Release(ds8
);
86 if (initialized
== FALSE
) {
87 /* try uninitialized object */
88 rc
=IDirectSound8_GetCaps(dso
,0);
89 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps(NULL) "
90 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
92 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
93 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps() "
94 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
96 rc
=IDirectSound8_Compact(dso
);
97 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_Compact() "
98 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
100 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
101 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetSpeakerConfig() "
102 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
104 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
105 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_VerifyCertification() "
106 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", 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: %08x\n",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: %08x\n", rc
);
127 /* DSOUND: Error: Invalid caps buffer */
128 rc
=IDirectSound8_GetCaps(dso
,0);
129 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
130 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", 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: %08x\n", rc
);
139 dscaps
.dwSize
=sizeof(dscaps
);
141 /* DSOUND: Running on a certified driver */
142 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
143 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
145 rc
=IDirectSound8_Compact(dso
);
146 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound8_Compact() failed: %08x\n", rc
);
148 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
149 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
151 rc
=IDirectSound8_Compact(dso
);
152 ok(rc
==DS_OK
,"IDirectSound8_Compact() failed: %08x\n",rc
);
154 rc
=IDirectSound8_GetSpeakerConfig(dso
,0);
155 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetSpeakerConfig(NULL) "
156 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
158 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
159 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc
);
160 ref_speaker_config
= speaker_config
;
162 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
163 DSSPEAKER_GEOMETRY_WIDE
);
164 if (speaker_config
== ref_speaker_config
)
165 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
166 DSSPEAKER_GEOMETRY_NARROW
);
168 rc
=IDirectSound8_SetSpeakerConfig(dso
,speaker_config
);
169 ok(rc
==DS_OK
,"IDirectSound8_SetSpeakerConfig() failed: %08x\n", rc
);
172 rc
=IDirectSound8_GetSpeakerConfig(dso
,&new_speaker_config
);
173 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc
);
174 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
175 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
176 "config: expected 0x%08x, got 0x%08x\n",
177 speaker_config
,new_speaker_config
);
178 IDirectSound8_SetSpeakerConfig(dso
,ref_speaker_config
);
181 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
182 ok(rc
==DS_OK
||rc
==E_NOTIMPL
,"IDirectSound8_VerifyCertification() failed: %08x\n", rc
);
185 ref
=IDirectSound8_Release(dso
);
186 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
189 static void IDirectSound8_tests(void)
192 LPDIRECTSOUND8 dso
=NULL
;
193 LPCLASSFACTORY cf
=NULL
;
195 trace("Testing IDirectSound8\n");
197 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
198 &IID_IClassFactory
, (void**)&cf
);
199 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
200 "failed: %08x\n", rc
);
202 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
203 &IID_IUnknown
, (void**)&cf
);
204 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) "
205 "failed: %08x\n", rc
);
207 /* try the COM class factory method of creation with no device specified */
208 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
209 &IID_IDirectSound8
, (void**)&dso
);
210 ok(rc
==S_OK
||rc
==REGDB_E_CLASSNOTREG
,"CoCreateInstance() failed: %08x\n", rc
);
211 if (rc
==REGDB_E_CLASSNOTREG
) {
212 trace(" Class Not Registered\n");
216 IDirectSound8_test(dso
, FALSE
, NULL
);
218 /* try the COM class factory method of creation with default playback
219 * device specified */
220 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
221 &IID_IDirectSound8
, (void**)&dso
);
222 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc
);
224 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
226 /* try the COM class factory method of creation with default voice
227 * playback device specified */
228 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
229 &IID_IDirectSound8
, (void**)&dso
);
230 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc
);
232 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
234 /* try the COM class factory method of creation with a bad
236 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
237 &CLSID_DirectSoundPrivate
, (void**)&dso
);
238 ok(rc
==E_NOINTERFACE
,
239 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
240 "should have failed: %08x\n",rc
);
242 /* try the COM class factory method of creation with a bad
243 * GUID and IID specified */
244 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
245 &IID_IDirectSound8
, (void**)&dso
);
246 ok(rc
==REGDB_E_CLASSNOTREG
,
247 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
248 "should have failed: %08x\n",rc
);
250 /* try with no device specified */
251 rc
=pDirectSoundCreate8(NULL
,&dso
,NULL
);
252 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
253 "DirectSoundCreate8() failed: %08x\n",rc
);
254 if (rc
==DS_OK
&& dso
)
255 IDirectSound8_test(dso
, TRUE
, NULL
);
257 /* try with default playback device specified */
258 rc
=pDirectSoundCreate8(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
259 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
260 "DirectSoundCreate8() failed: %08x\n",rc
);
261 if (rc
==DS_OK
&& dso
)
262 IDirectSound8_test(dso
, TRUE
, NULL
);
264 /* try with default voice playback device specified */
265 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
266 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
267 "DirectSoundCreate8() failed: %08x\n",rc
);
268 if (rc
==DS_OK
&& dso
)
269 IDirectSound8_test(dso
, TRUE
, NULL
);
271 /* try with a bad device specified */
272 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
273 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
274 "should have failed: %08x\n",rc
);
277 static HRESULT
test_dsound8(LPGUID lpGuid
)
280 LPDIRECTSOUND8 dso
=NULL
;
283 /* DSOUND: Error: Invalid interface buffer */
284 rc
=pDirectSoundCreate8(lpGuid
,0,NULL
);
285 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate8() should have returned "
286 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
288 /* Create the DirectSound8 object */
289 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
290 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
291 "DirectSoundCreate8() failed: %08x\n",rc
);
295 /* Try the enumerated device */
296 IDirectSound8_test(dso
, TRUE
, lpGuid
);
298 /* Try the COM class factory method of creation with enumerated device */
299 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
300 &IID_IDirectSound8
, (void**)&dso
);
301 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
303 IDirectSound8_test(dso
, FALSE
, lpGuid
);
305 /* Create a DirectSound8 object */
306 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
307 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
309 LPDIRECTSOUND8 dso1
=NULL
;
311 /* Create a second DirectSound8 object */
312 rc
=pDirectSoundCreate8(lpGuid
,&dso1
,NULL
);
313 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
315 /* Release the second DirectSound8 object */
316 ref
=IDirectSound8_Release(dso1
);
317 ok(ref
==0,"IDirectSound8_Release() has %d references, "
318 "should have 0\n",ref
);
319 ok(dso
!=dso1
,"DirectSound8 objects should be unique: "
320 "dso=%p,dso1=%p\n",dso
,dso1
);
323 /* Release the first DirectSound8 object */
324 ref
=IDirectSound8_Release(dso
);
325 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
328 return DSERR_GENERIC
;
332 /* Create a DirectSound8 object */
333 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
334 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
336 LPDIRECTSOUNDBUFFER secondary
;
337 DSBUFFERDESC bufdesc
;
340 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
341 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
342 bufdesc
.dwSize
=sizeof(bufdesc
);
343 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
344 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
346 bufdesc
.lpwfxFormat
=&wfx
;
347 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
348 ok(rc
==DS_OK
&& secondary
!=NULL
,
349 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
350 "buffer: %08x\n",rc
);
351 if (rc
==DS_OK
&& secondary
!=NULL
) {
352 LPDIRECTSOUND3DBUFFER buffer3d
;
353 LPDIRECTSOUNDBUFFER8 buffer8
;
354 rc
=IDirectSound8_QueryInterface(secondary
,
355 &IID_IDirectSound3DBuffer
,
357 ok(rc
==DS_OK
&& buffer3d
!=NULL
,
358 "IDirectSound8_QueryInterface() failed: %08x\n", rc
);
359 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
360 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
361 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
362 "should have 2\n",ref
);
364 rc
=IDirectSound8_QueryInterface(secondary
,
365 &IID_IDirectSoundBuffer8
,
367 if (rc
==DS_OK
&& buffer8
!=NULL
) {
368 ok(buffer8
==(IDirectSoundBuffer8
*)secondary
,
369 "IDirectSoundBuffer8 iface different from IDirectSoundBuffer.\n");
370 ref
=IDirectSoundBuffer8_AddRef(buffer8
);
371 ok(ref
==3,"IDirectSoundBuffer8_AddRef() has %d references, "
372 "should have 3\n",ref
);
374 ref
=IDirectSoundBuffer_AddRef(secondary
);
375 ok(ref
==4,"IDirectSoundBuffer_AddRef() has %d references, "
376 "should have 4\n",ref
);
378 /* release with buffer */
379 ref
=IDirectSound8_Release(dso
);
380 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
383 return DSERR_GENERIC
;
390 static HRESULT
test_primary8(LPGUID lpGuid
)
393 LPDIRECTSOUND8 dso
=NULL
;
394 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
395 LPDIRECTSOUNDBUFFER8 pb8
= NULL
;
396 DSBUFFERDESC bufdesc
;
401 /* Create the DirectSound object */
402 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
403 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
404 "DirectSoundCreate8() failed: %08x\n",rc
);
408 /* Get the device capabilities */
409 ZeroMemory(&dscaps
, sizeof(dscaps
));
410 dscaps
.dwSize
=sizeof(dscaps
);
411 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
412 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
416 /* DSOUND: Error: Invalid buffer description pointer */
417 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,0,NULL
);
418 ok(rc
==DSERR_INVALIDPARAM
,
419 "IDirectSound8_CreateSoundBuffer should have returned "
420 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
422 /* DSOUND: Error: Invalid buffer description pointer */
423 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,&primary
,NULL
);
424 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
425 "IDirectSound8_CreateSoundBuffer() should have returned "
426 "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n",
429 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
430 bufdesc
.dwSize
= sizeof(DSBUFFERDESC
);
432 /* DSOUND: Error: Invalid dsound buffer interface pointer */
433 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
434 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
435 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
436 "dsbo=%p\n",rc
,primary
);
438 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
440 /* DSOUND: Error: Invalid size */
441 /* DSOUND: Error: Invalid buffer description */
442 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
443 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
444 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
445 "primary=%p\n",rc
,primary
);
447 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
448 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
449 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
450 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
454 /* Testing the primary buffer */
456 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
457 bufdesc
.dwSize
=sizeof(bufdesc
);
458 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
459 bufdesc
.lpwfxFormat
= &wfx
;
460 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
461 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
462 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() should have "
463 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
464 if (rc
==DS_OK
&& primary
!=NULL
)
465 IDirectSoundBuffer_Release(primary
);
468 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
469 bufdesc
.dwSize
=sizeof(bufdesc
);
470 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
471 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
472 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
473 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
475 if (rc
==DSERR_CONTROLUNAVAIL
)
476 trace(" No Primary\n");
477 else if (rc
==DS_OK
&& primary
!=NULL
) {
480 /* Try to create a second primary buffer */
481 /* DSOUND: Error: The primary buffer already exists.
482 * Any changes made to the buffer description will be ignored. */
483 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
484 ok(rc
==DS_OK
&& second
==primary
,
485 "IDirectSound8_CreateSoundBuffer() should have returned original "
486 "primary buffer: %08x\n",rc
);
487 ref
=IDirectSoundBuffer_Release(second
);
488 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
489 "should have 1\n",ref
);
491 /* Try to duplicate a primary buffer */
492 /* DSOUND: Error: Can't duplicate primary buffers */
493 rc
=IDirectSound8_DuplicateSoundBuffer(dso
,primary
,&third
);
495 ok(rc
!=DS_OK
,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
496 "should have failed %08x\n",rc
);
498 /* Primary buffers don't have an IDirectSoundBuffer8 */
499 rc
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
, (LPVOID
*)&pb8
);
500 ok(FAILED(rc
), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc
);
502 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
503 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc
);
505 if (winetest_interactive
) {
506 trace("Playing a 5 seconds reference tone at the current volume.\n");
508 trace("(the current volume is %d according to DirectSound)\n",
510 trace("All subsequent tones should be identical to this one.\n");
511 trace("Listen for stutter, changes in pitch, volume, etc.\n");
513 test_buffer8(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
514 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
516 ref
=IDirectSoundBuffer_Release(primary
);
517 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
518 "should have 0\n",ref
);
521 /* Set the CooperativeLevel back to normal */
522 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
523 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
524 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
527 ref
=IDirectSound8_Release(dso
);
528 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
530 return DSERR_GENERIC
;
536 * Test the primary buffer at different formats while keeping the
537 * secondary buffer at a constant format.
539 static HRESULT
test_primary_secondary8(LPGUID lpGuid
)
542 LPDIRECTSOUND8 dso
=NULL
;
543 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
544 DSBUFFERDESC bufdesc
;
546 WAVEFORMATEX wfx
, wfx2
;
550 /* Create the DirectSound object */
551 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
552 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
553 "DirectSoundCreate8() failed: %08x\n",rc
);
557 /* Get the device capabilities */
558 ZeroMemory(&dscaps
, sizeof(dscaps
));
559 dscaps
.dwSize
=sizeof(dscaps
);
560 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
561 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
565 /* We must call SetCooperativeLevel before creating primary buffer */
566 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
567 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
568 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
572 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
573 bufdesc
.dwSize
=sizeof(bufdesc
);
574 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
575 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
576 ok(rc
==DS_OK
&& primary
!=NULL
,
577 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
580 if (rc
==DS_OK
&& primary
!=NULL
) {
581 for (f
=0;f
<NB_FORMATS
;f
++) {
582 for (tag
=0;tag
<NB_TAGS
;tag
++) {
583 /* if float, we only want to test 32-bit */
584 if ((format_tags
[tag
] == WAVE_FORMAT_IEEE_FLOAT
) && (formats
[f
][1] != 32))
587 /* We must call SetCooperativeLevel to be allowed to call
589 /* DSOUND: Setting DirectSound cooperative level to
591 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
592 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
596 init_format(&wfx
,format_tags
[tag
],formats
[f
][0],formats
[f
][1],
599 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
601 || rc
==DSERR_INVALIDPARAM
, /* 2003 */
602 "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
603 format_string(&wfx
), rc
);
605 /* There is no guarantee that SetFormat will actually change the
606 * format to what we asked for. It depends on what the soundcard
607 * supports. So we must re-query the format.
609 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
610 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
612 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
613 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
614 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
615 wfx
.nChannels
!=wfx2
.nChannels
)) {
616 trace("Requested primary format tag=0x%04x %dx%dx%d "
617 "avg.B/s=%d align=%d\n",
618 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
619 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
620 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
621 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
622 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
625 /* Set the CooperativeLevel back to normal */
626 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
627 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
628 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
630 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
633 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
634 bufdesc
.dwSize
=sizeof(bufdesc
);
635 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
636 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
638 bufdesc
.lpwfxFormat
=&wfx2
;
639 if (winetest_interactive
) {
640 trace(" Testing a primary buffer at %dx%dx%d (fmt=%d) with a "
641 "secondary buffer at %dx%dx%d\n",
642 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,format_tags
[tag
],
643 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
645 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
646 ok(rc
==DS_OK
&& secondary
!=NULL
,
647 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
650 if (rc
==DS_OK
&& secondary
!=NULL
) {
651 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
652 winetest_interactive
,1.0,0,NULL
,0,0);
654 ref
=IDirectSoundBuffer_Release(secondary
);
655 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
656 "should have 0\n",ref
);
661 ref
=IDirectSoundBuffer_Release(primary
);
662 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
663 "should have 0\n",ref
);
666 /* Set the CooperativeLevel back to normal */
667 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
668 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
669 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
672 ref
=IDirectSound8_Release(dso
);
673 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
675 return DSERR_GENERIC
;
680 static HRESULT
test_secondary8(LPGUID lpGuid
)
683 LPDIRECTSOUND8 dso
=NULL
;
684 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
685 DSBUFFERDESC bufdesc
;
687 WAVEFORMATEX wfx
, wfx1
;
691 /* Create the DirectSound object */
692 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
693 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
694 "DirectSoundCreate8() failed: %08x\n",rc
);
698 /* Get the device capabilities */
699 ZeroMemory(&dscaps
, sizeof(dscaps
));
700 dscaps
.dwSize
=sizeof(dscaps
);
701 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
702 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
706 /* We must call SetCooperativeLevel before creating primary buffer */
707 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
708 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
709 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
713 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
714 bufdesc
.dwSize
=sizeof(bufdesc
);
715 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
716 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
717 ok(rc
==DS_OK
&& primary
!=NULL
,
718 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
721 if (rc
==DS_OK
&& primary
!=NULL
) {
722 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
723 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
727 for (f
=0;f
<NB_FORMATS
;f
++) {
728 for (tag
=0;tag
<NB_TAGS
;tag
++) {
729 WAVEFORMATEXTENSIBLE wfxe
;
731 /* if float, we only want to test 32-bit */
732 if ((format_tags
[tag
] == WAVE_FORMAT_IEEE_FLOAT
) && (formats
[f
][1] != 32))
735 init_format(&wfx
,format_tags
[tag
],formats
[f
][0],formats
[f
][1],
738 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
739 bufdesc
.dwSize
=sizeof(bufdesc
);
740 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
741 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
743 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
744 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() "
745 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", 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
|| rc
== DSERR_INVALIDCALL
|| rc
== DSERR_INVALIDPARAM
/* 2003 */) && !secondary
)
759 || rc
== DS_OK
, /* driver dependent? */
760 "IDirectSound_CreateSoundBuffer() "
761 "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
762 "and NULL, returned: %08x %p\n", rc
, secondary
);
764 ok(rc
==DS_OK
&& secondary
!=NULL
,
765 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
768 IDirectSoundBuffer_Release(secondary
);
771 bufdesc
.lpwfxFormat
=(WAVEFORMATEX
*)&wfxe
;
773 wfxe
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
774 wfxe
.SubFormat
= (format_tags
[tag
] == WAVE_FORMAT_PCM
? KSDATAFORMAT_SUBTYPE_PCM
: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
775 wfxe
.Format
.cbSize
= 1;
776 wfxe
.Samples
.wValidBitsPerSample
= wfx
.wBitsPerSample
;
777 wfxe
.dwChannelMask
= (wfx
.nChannels
== 1 ? KSAUDIO_SPEAKER_MONO
: KSAUDIO_SPEAKER_STEREO
);
779 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
780 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
781 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
785 IDirectSoundBuffer_Release(secondary
);
789 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
) + 1;
791 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
792 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
)
793 || rc
==DS_OK
/* driver dependent? */,
794 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
798 IDirectSoundBuffer_Release(secondary
);
802 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
803 wfxe
.SubFormat
= GUID_NULL
;
804 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
805 ok((rc
==DSERR_INVALIDPARAM
|| rc
==DSERR_INVALIDCALL
) && !secondary
,
806 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
810 IDirectSoundBuffer_Release(secondary
);
814 wfxe
.Format
.cbSize
= sizeof(wfxe
);
815 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
816 ok((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
|| rc
==E_INVALIDARG
) && !secondary
,
817 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
821 IDirectSoundBuffer_Release(secondary
);
825 wfxe
.SubFormat
= (format_tags
[tag
] == WAVE_FORMAT_PCM
? KSDATAFORMAT_SUBTYPE_PCM
: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
826 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
827 ok(rc
==DS_OK
&& secondary
,
828 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
832 IDirectSoundBuffer_Release(secondary
);
836 wfxe
.Format
.cbSize
= sizeof(wfxe
) + 1;
837 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
838 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
)
839 || rc
==DS_OK
/* driver dependent? */,
840 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
844 IDirectSoundBuffer_Release(secondary
);
848 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
849 ++wfxe
.Samples
.wValidBitsPerSample
;
850 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
851 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
852 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
856 IDirectSoundBuffer_Release(secondary
);
859 --wfxe
.Samples
.wValidBitsPerSample
;
861 wfxe
.Samples
.wValidBitsPerSample
= 0;
862 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
863 ok(rc
==DS_OK
&& secondary
,
864 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
868 IDirectSoundBuffer_Release(secondary
);
871 wfxe
.Samples
.wValidBitsPerSample
= wfxe
.Format
.wBitsPerSample
;
873 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
874 ok(rc
==DS_OK
&& secondary
!=NULL
,
875 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
878 if (rc
==DS_OK
&& secondary
!=NULL
) {
879 if (winetest_interactive
) {
880 trace(" Testing a secondary buffer at %dx%dx%d (fmt=%d) "
881 "with a primary buffer at %dx%dx%d\n",
882 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,format_tags
[tag
],
883 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
885 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
886 winetest_interactive
,1.0,0,NULL
,0,0);
888 ref
=IDirectSoundBuffer_Release(secondary
);
889 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
890 "should have 0\n",ref
);
895 ref
=IDirectSoundBuffer_Release(primary
);
896 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
897 "should have 0\n",ref
);
900 /* Set the CooperativeLevel back to normal */
901 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
902 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
903 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
906 ref
=IDirectSound8_Release(dso
);
907 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
909 return DSERR_GENERIC
;
914 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
915 LPCSTR lpcstrModule
, LPVOID lpContext
)
918 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
919 rc
= test_dsound8(lpGuid
);
920 if (rc
== DSERR_NODRIVER
)
921 trace(" No Driver\n");
922 else if (rc
== DSERR_ALLOCATED
)
923 trace(" Already In Use\n");
924 else if (rc
== E_FAIL
)
925 trace(" No Device\n");
927 test_primary8(lpGuid
);
928 test_primary_secondary8(lpGuid
);
929 test_secondary8(lpGuid
);
935 static void dsound8_tests(void)
938 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
939 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %08x\n",rc
);
942 static void test_hw_buffers(void)
945 IDirectSoundBuffer
*primary
, *primary2
, **secondaries
, *secondary
;
946 IDirectSoundBuffer8
*buf8
;
949 DSBUFFERDESC bufdesc
;
954 hr
= pDirectSoundCreate8(NULL
, &ds
, NULL
);
955 ok(hr
== S_OK
|| hr
== DSERR_NODRIVER
|| hr
== DSERR_ALLOCATED
|| hr
== E_FAIL
,
956 "DirectSoundCreate8 failed: %08x\n", hr
);
960 caps
.dwSize
= sizeof(caps
);
962 hr
= IDirectSound8_GetCaps(ds
, &caps
);
963 ok(hr
== S_OK
, "GetCaps failed: %08x\n", hr
);
965 ok(caps
.dwPrimaryBuffers
== 1, "Got wrong number of primary buffers: %u\n",
966 caps
.dwPrimaryBuffers
);
968 /* DSBCAPS_LOC* is ignored for primary buffers */
969 bufdesc
.dwSize
= sizeof(bufdesc
);
970 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCHARDWARE
|
971 DSBCAPS_PRIMARYBUFFER
;
972 bufdesc
.dwBufferBytes
= 0;
973 bufdesc
.dwReserved
= 0;
974 bufdesc
.lpwfxFormat
= NULL
;
975 bufdesc
.guid3DAlgorithm
= GUID_NULL
;
977 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &primary
, NULL
);
978 ok(hr
== S_OK
, "CreateSoundBuffer failed: %08x\n", hr
);
980 IDirectSound8_Release(ds
);
984 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCSOFTWARE
|
985 DSBCAPS_PRIMARYBUFFER
;
987 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &primary2
, NULL
);
988 ok(hr
== S_OK
, "CreateSoundBuffer failed: %08x\n", hr
);
989 ok(primary
== primary2
, "Got different primary buffers: %p, %p\n", primary
, primary2
);
991 IDirectSoundBuffer_Release(primary2
);
993 buf8
= (IDirectSoundBuffer8
*)0xDEADBEEF;
994 hr
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
,
996 ok(hr
== E_NOINTERFACE
, "QueryInterface gave wrong failure: %08x\n", hr
);
997 ok(buf8
== NULL
, "Pointer didn't get set to NULL\n");
999 fmt
.wFormatTag
= WAVE_FORMAT_PCM
;
1001 fmt
.nSamplesPerSec
= 48000;
1002 fmt
.wBitsPerSample
= 16;
1003 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
1004 fmt
.nAvgBytesPerSec
= fmt
.nBlockAlign
* fmt
.nSamplesPerSec
;
1007 bufdesc
.lpwfxFormat
= &fmt
;
1008 bufdesc
.dwBufferBytes
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
/ 10;
1009 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCHARDWARE
|
1012 secondaries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1013 sizeof(IDirectSoundBuffer
*) * caps
.dwMaxHwMixingAllBuffers
);
1015 /* try to fill all of the hw buffers */
1016 trace("dwMaxHwMixingAllBuffers: %u\n", caps
.dwMaxHwMixingAllBuffers
);
1017 trace("dwMaxHwMixingStaticBuffers: %u\n", caps
.dwMaxHwMixingStaticBuffers
);
1018 trace("dwMaxHwMixingStreamingBuffers: %u\n", caps
.dwMaxHwMixingStreamingBuffers
);
1019 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
){
1020 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &secondaries
[i
], NULL
);
1021 ok(hr
== S_OK
|| hr
== E_NOTIMPL
|| broken(hr
== DSERR_CONTROLUNAVAIL
) || broken(hr
== E_FAIL
),
1022 "CreateSoundBuffer(%u) failed: %08x\n", i
, hr
);
1026 bufcaps
.dwSize
= sizeof(bufcaps
);
1027 hr
= IDirectSoundBuffer_GetCaps(secondaries
[i
], &bufcaps
);
1028 ok(hr
== S_OK
, "GetCaps failed: %08x\n", hr
);
1029 ok((bufcaps
.dwFlags
& DSBCAPS_LOCHARDWARE
) != 0,
1030 "Buffer wasn't allocated in hardware, dwFlags: %x\n", bufcaps
.dwFlags
);
1033 /* see if we can create one more */
1034 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &secondary
, NULL
);
1035 ok((i
== caps
.dwMaxHwMixingAllBuffers
&& hr
== DSERR_ALLOCATED
) || /* out of hw buffers */
1036 (caps
.dwMaxHwMixingAllBuffers
== 0 && hr
== DSERR_INVALIDCALL
) || /* no hw buffers at all */
1037 hr
== E_NOTIMPL
|| /* don't support hw buffers */
1038 broken(hr
== DSERR_CONTROLUNAVAIL
) || /* vmware winxp, others? */
1039 broken(hr
== E_FAIL
) || /* broken AC97 driver */
1040 broken(hr
== S_OK
) /* broken driver allows more hw bufs than dscaps claims */,
1041 "CreateSoundBuffer(%u) gave wrong error: %08x\n", i
, hr
);
1043 IDirectSoundBuffer_Release(secondary
);
1045 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
)
1047 IDirectSoundBuffer_Release(secondaries
[i
]);
1049 HeapFree(GetProcessHeap(), 0, secondaries
);
1051 IDirectSoundBuffer_Release(primary
);
1052 IDirectSound8_Release(ds
);
1058 } default_info
= { 0 };
1060 static BOOL WINAPI
default_device_cb(GUID
*guid
, const char *desc
,
1061 const char *module
, void *user
)
1063 trace("guid: %p, desc: %s\n", guid
, desc
);
1065 ok(default_info
.dev_count
== 0, "Got NULL GUID not in first position\n");
1067 if(default_info
.dev_count
== 0){
1068 ok(IsEqualGUID(guid
, &default_info
.guid
), "Expected default device GUID\n");
1070 ok(!IsEqualGUID(guid
, &default_info
.guid
), "Got default GUID at unexpected location: %u\n",
1071 default_info
.dev_count
);
1074 /* only count real devices */
1075 ++default_info
.dev_count
;
1081 static void test_first_device(void)
1083 IMMDeviceEnumerator
*devenum
;
1089 hr
= CoCreateInstance(&CLSID_MMDeviceEnumerator
, NULL
,
1090 CLSCTX_INPROC_SERVER
, &IID_IMMDeviceEnumerator
, (void**)&devenum
);
1092 win_skip("MMDevAPI is not available, skipping default device test\n");
1096 hr
= IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum
, eRender
,
1097 eMultimedia
, &defdev
);
1098 if (hr
== E_NOTFOUND
) {
1099 win_skip("No default device found\n");
1102 ok(hr
== S_OK
, "GetDefaultAudioEndpoint failed: %08x\n", hr
);
1104 hr
= IMMDevice_OpenPropertyStore(defdev
, STGM_READ
, &ps
);
1105 ok(hr
== S_OK
, "OpenPropertyStore failed: %08x\n", hr
);
1107 PropVariantInit(&pv
);
1109 hr
= IPropertyStore_GetValue(ps
, &PKEY_AudioEndpoint_GUID
, &pv
);
1110 ok(hr
== S_OK
, "GetValue failed: %08x\n", hr
);
1112 CLSIDFromString(pv
.u
.pwszVal
, &default_info
.guid
);
1114 PropVariantClear(&pv
);
1115 IPropertyStore_Release(ps
);
1116 IMMDevice_Release(defdev
);
1117 IMMDeviceEnumerator_Release(devenum
);
1119 hr
= pDirectSoundEnumerateA(&default_device_cb
, NULL
);
1120 ok(hr
== S_OK
, "DirectSoundEnumerateA failed: %08x\n", hr
);
1123 static void test_COM(void)
1126 IDirectSound8
*ds8
= (IDirectSound8
*)0xdeadbeef;
1127 IUnknown
*unk
, *unk8
;
1131 /* COM aggregation */
1132 hr
= CoCreateInstance(&CLSID_DirectSound8
, (IUnknown
*)&ds
, CLSCTX_INPROC_SERVER
,
1133 &IID_IUnknown
, (void**)&ds8
);
1134 ok(hr
== CLASS_E_NOAGGREGATION
,
1135 "DirectSound create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
1136 ok(!ds8
, "ds8 = %p\n", ds8
);
1139 hr
= CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
1140 &IID_IDirectSound3DBuffer
, (void**)&ds8
);
1141 ok(hr
== E_NOINTERFACE
,
1142 "DirectSound create failed: %08x, expected E_NOINTERFACE\n", hr
);
1144 /* Same refcount for IDirectSound and IDirectSound8 */
1145 hr
= CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectSound8
,
1147 ok(hr
== S_OK
, "DirectSound create failed: %08x, expected S_OK\n", hr
);
1148 refcount
= IDirectSound8_AddRef(ds8
);
1149 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1150 hr
= IDirectSound8_QueryInterface(ds8
, &IID_IDirectSound
, (void**)&ds
);
1151 ok(hr
== S_OK
, "QueryInterface for IID_IDirectSound failed: %08x\n", hr
);
1152 refcount
= IDirectSound8_AddRef(ds8
);
1153 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1154 refcount
= IDirectSound_AddRef(ds
);
1155 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
1157 /* Separate refcount for IUnknown */
1158 hr
= IDirectSound_QueryInterface(ds
, &IID_IUnknown
, (void**)&unk
);
1159 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1160 refcount
= IUnknown_AddRef(unk
);
1161 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1162 hr
= IDirectSound_QueryInterface(ds8
, &IID_IUnknown
, (void**)&unk8
);
1163 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1164 refcount
= IUnknown_AddRef(unk8
);
1165 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1166 refcount
= IDirectSound_AddRef(ds
);
1167 ok(refcount
== 6, "refcount == %u, expected 6\n", refcount
);
1169 while (IDirectSound_Release(ds
));
1170 while (IUnknown_Release(unk
));
1179 hDsound
= LoadLibrary("dsound.dll");
1183 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1184 "DirectSoundEnumerateA");
1185 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
,
1186 "DirectSoundCreate8");
1187 if (pDirectSoundCreate8
)
1190 IDirectSound8_tests();
1193 test_first_device();
1196 skip("DirectSoundCreate8 missing - skipping all tests\n");
1198 FreeLibrary(hDsound
);
1201 skip("dsound.dll not found - skipping all tests\n");