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 todo_wine
ok(primary
->lpVtbl
==secondary
->lpVtbl
,
652 "Primary and secondary buffers have different vtbls.\n");
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
);
664 ref
=IDirectSoundBuffer_Release(primary
);
665 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
666 "should have 0\n",ref
);
669 /* Set the CooperativeLevel back to normal */
670 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
671 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
672 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", 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: %08x\n",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: %08x\n",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: %08x\n", rc
);
716 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
717 bufdesc
.dwSize
=sizeof(bufdesc
);
718 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
719 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
720 ok(rc
==DS_OK
&& primary
!=NULL
,
721 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
724 if (rc
==DS_OK
&& primary
!=NULL
) {
725 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
726 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
730 for (f
=0;f
<NB_FORMATS
;f
++) {
731 for (tag
=0;tag
<NB_TAGS
;tag
++) {
732 WAVEFORMATEXTENSIBLE wfxe
;
734 /* if float, we only want to test 32-bit */
735 if ((format_tags
[tag
] == WAVE_FORMAT_IEEE_FLOAT
) && (formats
[f
][1] != 32))
738 init_format(&wfx
,format_tags
[tag
],formats
[f
][0],formats
[f
][1],
741 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
742 bufdesc
.dwSize
=sizeof(bufdesc
);
743 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
744 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
746 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
747 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() "
748 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
749 if (rc
==DS_OK
&& secondary
!=NULL
)
750 IDirectSoundBuffer_Release(secondary
);
753 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
754 bufdesc
.dwSize
=sizeof(bufdesc
);
755 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
756 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
758 bufdesc
.lpwfxFormat
=&wfx
;
759 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
760 if (wfx
.wBitsPerSample
!= 8 && wfx
.wBitsPerSample
!= 16)
761 ok(((rc
== DSERR_CONTROLUNAVAIL
|| rc
== DSERR_INVALIDCALL
|| rc
== DSERR_INVALIDPARAM
/* 2003 */) && !secondary
)
762 || rc
== DS_OK
, /* driver dependent? */
763 "IDirectSound_CreateSoundBuffer() "
764 "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
765 "and NULL, returned: %08x %p\n", rc
, secondary
);
767 ok(rc
==DS_OK
&& secondary
!=NULL
,
768 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
771 IDirectSoundBuffer_Release(secondary
);
774 bufdesc
.lpwfxFormat
=(WAVEFORMATEX
*)&wfxe
;
776 wfxe
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
777 wfxe
.SubFormat
= (format_tags
[tag
] == WAVE_FORMAT_PCM
? KSDATAFORMAT_SUBTYPE_PCM
: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
778 wfxe
.Format
.cbSize
= 1;
779 wfxe
.Samples
.wValidBitsPerSample
= wfx
.wBitsPerSample
;
780 wfxe
.dwChannelMask
= (wfx
.nChannels
== 1 ? KSAUDIO_SPEAKER_MONO
: KSAUDIO_SPEAKER_STEREO
);
782 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
783 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
784 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
788 IDirectSoundBuffer_Release(secondary
);
792 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
) + 1;
794 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
795 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
)
796 || rc
==DS_OK
/* driver dependent? */,
797 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
801 IDirectSoundBuffer_Release(secondary
);
805 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
806 wfxe
.SubFormat
= GUID_NULL
;
807 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
808 ok((rc
==DSERR_INVALIDPARAM
|| rc
==DSERR_INVALIDCALL
) && !secondary
,
809 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
813 IDirectSoundBuffer_Release(secondary
);
817 wfxe
.Format
.cbSize
= sizeof(wfxe
);
818 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
819 ok((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
|| rc
==E_INVALIDARG
) && !secondary
,
820 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
824 IDirectSoundBuffer_Release(secondary
);
828 wfxe
.SubFormat
= (format_tags
[tag
] == WAVE_FORMAT_PCM
? KSDATAFORMAT_SUBTYPE_PCM
: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
829 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
830 ok(rc
==DS_OK
&& secondary
,
831 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
835 IDirectSoundBuffer_Release(secondary
);
839 wfxe
.Format
.cbSize
= sizeof(wfxe
) + 1;
840 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
841 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
)
842 || rc
==DS_OK
/* driver dependent? */,
843 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
847 IDirectSoundBuffer_Release(secondary
);
851 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
852 ++wfxe
.Samples
.wValidBitsPerSample
;
853 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
854 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
855 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
859 IDirectSoundBuffer_Release(secondary
);
862 --wfxe
.Samples
.wValidBitsPerSample
;
864 wfxe
.Samples
.wValidBitsPerSample
= 0;
865 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
866 ok(rc
==DS_OK
&& secondary
,
867 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
871 IDirectSoundBuffer_Release(secondary
);
874 wfxe
.Samples
.wValidBitsPerSample
= wfxe
.Format
.wBitsPerSample
;
876 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
877 ok(rc
==DS_OK
&& secondary
!=NULL
,
878 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
881 if (rc
==DS_OK
&& secondary
!=NULL
) {
882 if (winetest_interactive
) {
883 trace(" Testing a secondary buffer at %dx%dx%d (fmt=%d) "
884 "with a primary buffer at %dx%dx%d\n",
885 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,format_tags
[tag
],
886 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
888 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
889 winetest_interactive
,1.0,0,NULL
,0,0);
891 ref
=IDirectSoundBuffer_Release(secondary
);
892 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
893 "should have 0\n",ref
);
898 ref
=IDirectSoundBuffer_Release(primary
);
899 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
900 "should have 0\n",ref
);
903 /* Set the CooperativeLevel back to normal */
904 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
905 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
906 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
909 ref
=IDirectSound8_Release(dso
);
910 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
912 return DSERR_GENERIC
;
917 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
918 LPCSTR lpcstrModule
, LPVOID lpContext
)
921 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
922 rc
= test_dsound8(lpGuid
);
923 if (rc
== DSERR_NODRIVER
)
924 trace(" No Driver\n");
925 else if (rc
== DSERR_ALLOCATED
)
926 trace(" Already In Use\n");
927 else if (rc
== E_FAIL
)
928 trace(" No Device\n");
930 test_primary8(lpGuid
);
931 test_primary_secondary8(lpGuid
);
932 test_secondary8(lpGuid
);
938 static void dsound8_tests(void)
941 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
942 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %08x\n",rc
);
945 static void test_hw_buffers(void)
948 IDirectSoundBuffer
*primary
, *primary2
, **secondaries
, *secondary
;
949 IDirectSoundBuffer8
*buf8
;
952 DSBUFFERDESC bufdesc
;
957 hr
= pDirectSoundCreate8(NULL
, &ds
, NULL
);
958 ok(hr
== S_OK
|| hr
== DSERR_NODRIVER
|| hr
== DSERR_ALLOCATED
|| hr
== E_FAIL
,
959 "DirectSoundCreate8 failed: %08x\n", hr
);
963 caps
.dwSize
= sizeof(caps
);
965 hr
= IDirectSound8_GetCaps(ds
, &caps
);
966 ok(hr
== S_OK
, "GetCaps failed: %08x\n", hr
);
968 ok(caps
.dwPrimaryBuffers
== 1, "Got wrong number of primary buffers: %u\n",
969 caps
.dwPrimaryBuffers
);
971 /* DSBCAPS_LOC* is ignored for primary buffers */
972 bufdesc
.dwSize
= sizeof(bufdesc
);
973 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCHARDWARE
|
974 DSBCAPS_PRIMARYBUFFER
;
975 bufdesc
.dwBufferBytes
= 0;
976 bufdesc
.dwReserved
= 0;
977 bufdesc
.lpwfxFormat
= NULL
;
978 bufdesc
.guid3DAlgorithm
= GUID_NULL
;
980 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &primary
, NULL
);
981 ok(hr
== S_OK
, "CreateSoundBuffer failed: %08x\n", hr
);
983 IDirectSound8_Release(ds
);
987 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCSOFTWARE
|
988 DSBCAPS_PRIMARYBUFFER
;
990 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &primary2
, NULL
);
991 ok(hr
== S_OK
, "CreateSoundBuffer failed: %08x\n", hr
);
992 ok(primary
== primary2
, "Got different primary buffers: %p, %p\n", primary
, primary2
);
994 IDirectSoundBuffer_Release(primary2
);
996 buf8
= (IDirectSoundBuffer8
*)0xDEADBEEF;
997 hr
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
,
999 ok(hr
== E_NOINTERFACE
, "QueryInterface gave wrong failure: %08x\n", hr
);
1000 ok(buf8
== NULL
, "Pointer didn't get set to NULL\n");
1002 fmt
.wFormatTag
= WAVE_FORMAT_PCM
;
1004 fmt
.nSamplesPerSec
= 48000;
1005 fmt
.wBitsPerSample
= 16;
1006 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
1007 fmt
.nAvgBytesPerSec
= fmt
.nBlockAlign
* fmt
.nSamplesPerSec
;
1010 bufdesc
.lpwfxFormat
= &fmt
;
1011 bufdesc
.dwBufferBytes
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
/ 10;
1012 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCHARDWARE
|
1015 secondaries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1016 sizeof(IDirectSoundBuffer
*) * caps
.dwMaxHwMixingAllBuffers
);
1018 /* try to fill all of the hw buffers */
1019 trace("dwMaxHwMixingAllBuffers: %u\n", caps
.dwMaxHwMixingAllBuffers
);
1020 trace("dwMaxHwMixingStaticBuffers: %u\n", caps
.dwMaxHwMixingStaticBuffers
);
1021 trace("dwMaxHwMixingStreamingBuffers: %u\n", caps
.dwMaxHwMixingStreamingBuffers
);
1022 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
){
1023 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &secondaries
[i
], NULL
);
1024 ok(hr
== S_OK
|| hr
== E_NOTIMPL
|| broken(hr
== DSERR_CONTROLUNAVAIL
),
1025 "CreateSoundBuffer(%u) failed: %08x\n", i
, hr
);
1029 bufcaps
.dwSize
= sizeof(bufcaps
);
1030 hr
= IDirectSoundBuffer_GetCaps(secondaries
[i
], &bufcaps
);
1031 ok(hr
== S_OK
, "GetCaps failed: %08x\n", hr
);
1032 ok((bufcaps
.dwFlags
& DSBCAPS_LOCHARDWARE
) != 0,
1033 "Buffer wasn't allocated in hardware, dwFlags: %x\n", bufcaps
.dwFlags
);
1036 /* see if we can create one more */
1037 hr
= IDirectSound8_CreateSoundBuffer(ds
, &bufdesc
, &secondary
, NULL
);
1038 ok((i
== caps
.dwMaxHwMixingAllBuffers
&& hr
== DSERR_ALLOCATED
) || /* out of hw buffers */
1039 (caps
.dwMaxHwMixingAllBuffers
== 0 && hr
== DSERR_INVALIDCALL
) || /* no hw buffers at all */
1040 hr
== E_NOTIMPL
|| /* don't support hw buffers */
1041 broken(hr
== DSERR_CONTROLUNAVAIL
) || /* vmware winxp, others? */
1042 broken(hr
== S_OK
) /* broken driver allows more hw bufs than dscaps claims */,
1043 "CreateSoundBuffer gave wrong error: %08x\n", hr
);
1045 IDirectSoundBuffer_Release(secondary
);
1047 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
)
1049 IDirectSoundBuffer_Release(secondaries
[i
]);
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 ok(hr
== S_OK
, "GetDefaultAudioEndpoint failed: %08x\n", hr
);
1100 hr
= IMMDevice_OpenPropertyStore(defdev
, STGM_READ
, &ps
);
1101 ok(hr
== S_OK
, "OpenPropertyStore failed: %08x\n", hr
);
1103 PropVariantInit(&pv
);
1105 hr
= IPropertyStore_GetValue(ps
, &PKEY_AudioEndpoint_GUID
, &pv
);
1106 ok(hr
== S_OK
, "GetValue failed: %08x\n", hr
);
1108 CLSIDFromString(pv
.u
.pwszVal
, &default_info
.guid
);
1110 PropVariantClear(&pv
);
1111 IPropertyStore_Release(ps
);
1112 IMMDevice_Release(defdev
);
1113 IMMDeviceEnumerator_Release(devenum
);
1115 hr
= pDirectSoundEnumerateA(&default_device_cb
, NULL
);
1116 ok(hr
== S_OK
, "DirectSoundEnumerateA failed: %08x\n", hr
);
1119 static void test_COM(void)
1122 IDirectSound8
*ds8
= (IDirectSound8
*)0xdeadbeef;
1123 IUnknown
*unk
, *unk8
;
1127 /* COM aggregation */
1128 hr
= CoCreateInstance(&CLSID_DirectSound8
, (IUnknown
*)&ds
, CLSCTX_INPROC_SERVER
,
1129 &IID_IUnknown
, (void**)&ds8
);
1130 ok(hr
== CLASS_E_NOAGGREGATION
,
1131 "DirectSound create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
1132 ok(!ds8
, "ds8 = %p\n", ds8
);
1135 hr
= CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
1136 &IID_IDirectSound3DBuffer
, (void**)&ds8
);
1137 ok(hr
== E_NOINTERFACE
,
1138 "DirectSound create failed: %08x, expected E_NOINTERFACE\n", hr
);
1140 /* Same refcount for IDirectSound and IDirectSound8 */
1141 hr
= CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectSound8
,
1143 ok(hr
== S_OK
, "DirectSound create failed: %08x, expected S_OK\n", hr
);
1144 refcount
= IDirectSound8_AddRef(ds8
);
1145 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1146 hr
= IDirectSound8_QueryInterface(ds8
, &IID_IDirectSound
, (void**)&ds
);
1147 ok(hr
== S_OK
, "QueryInterface for IID_IDirectSound failed: %08x\n", hr
);
1148 refcount
= IDirectSound8_AddRef(ds8
);
1149 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1150 refcount
= IDirectSound_AddRef(ds
);
1151 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
1153 /* Separate refcount for IUnknown */
1154 hr
= IDirectSound_QueryInterface(ds
, &IID_IUnknown
, (void**)&unk
);
1155 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1156 refcount
= IUnknown_AddRef(unk
);
1157 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1158 hr
= IDirectSound_QueryInterface(ds8
, &IID_IUnknown
, (void**)&unk8
);
1159 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1160 refcount
= IUnknown_AddRef(unk8
);
1161 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1162 refcount
= IDirectSound_AddRef(ds
);
1163 ok(refcount
== 6, "refcount == %u, expected 6\n", refcount
);
1165 while (IDirectSound_Release(ds
));
1166 while (IUnknown_Release(unk
));
1175 hDsound
= LoadLibrary("dsound.dll");
1179 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1180 "DirectSoundEnumerateA");
1181 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
,
1182 "DirectSoundCreate8");
1183 if (pDirectSoundCreate8
)
1186 IDirectSound8_tests();
1189 test_first_device();
1192 skip("DirectSoundCreate8 missing - skipping all tests\n");
1194 FreeLibrary(hDsound
);
1197 skip("dsound.dll not found - skipping all tests\n");