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
28 #define WIN32_NO_STATUS
30 #define COM_NO_WINDOWS_H
33 #define NONAMELESSUNION
34 //#include <windows.h>
37 #include <wine/test.h>
45 #include <mmdeviceapi.h>
46 //#include "audioclient.h"
47 //#include "propkey.h"
48 //#include "devpkey.h"
50 #include "dsound_test.h"
52 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
53 static HRESULT (WINAPI
*pDirectSoundCreate8
)(LPCGUID
,LPDIRECTSOUND8
*,LPUNKNOWN
)=NULL
;
55 int align(int length
, int align
)
57 return (length
/ align
) * align
;
60 static void IDirectSound8_test(LPDIRECTSOUND8 dso
, BOOL initialized
,
69 DWORD speaker_config
, new_speaker_config
, ref_speaker_config
;
72 /* Try to Query for objects */
73 rc
=IDirectSound8_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
74 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %08x\n", rc
);
76 IDirectSound8_Release(unknown
);
78 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
79 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %08x\n", rc
);
81 IDirectSound_Release(ds
);
83 rc
=IDirectSound8_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
84 ok(rc
==DS_OK
,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
85 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
87 IDirectSound8_Release(ds8
);
89 if (initialized
== FALSE
) {
90 /* try uninitialized object */
91 rc
=IDirectSound8_GetCaps(dso
,0);
92 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps(NULL) "
93 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
95 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
96 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetCaps() "
97 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
99 rc
=IDirectSound8_Compact(dso
);
100 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_Compact() "
101 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
103 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
104 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_GetSpeakerConfig() "
105 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
107 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
108 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound8_VerifyCertification() "
109 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
111 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
112 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
113 "IDirectSound8_Initialize() failed: %08x\n",rc
);
114 if (rc
==DSERR_NODRIVER
) {
115 trace(" No Driver\n");
117 } else if (rc
==E_FAIL
) {
118 trace(" No Device\n");
120 } else if (rc
==DSERR_ALLOCATED
) {
121 trace(" Already In Use\n");
126 rc
=IDirectSound8_Initialize(dso
,lpGuid
);
127 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSound8_Initialize() "
128 "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc
);
130 /* DSOUND: Error: Invalid caps buffer */
131 rc
=IDirectSound8_GetCaps(dso
,0);
132 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
133 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
135 ZeroMemory(&dscaps
, sizeof(dscaps
));
137 /* DSOUND: Error: Invalid caps buffer */
138 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
139 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetCaps() "
140 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
142 dscaps
.dwSize
=sizeof(dscaps
);
144 /* DSOUND: Running on a certified driver */
145 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
146 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
148 rc
=IDirectSound8_Compact(dso
);
149 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound8_Compact() failed: %08x\n", rc
);
151 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
152 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
154 rc
=IDirectSound8_Compact(dso
);
155 ok(rc
==DS_OK
,"IDirectSound8_Compact() failed: %08x\n",rc
);
157 rc
=IDirectSound8_GetSpeakerConfig(dso
,0);
158 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_GetSpeakerConfig(NULL) "
159 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
161 rc
=IDirectSound8_GetSpeakerConfig(dso
,&speaker_config
);
162 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc
);
163 ref_speaker_config
= speaker_config
;
165 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
166 DSSPEAKER_GEOMETRY_WIDE
);
167 if (speaker_config
== ref_speaker_config
)
168 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
169 DSSPEAKER_GEOMETRY_NARROW
);
171 rc
=IDirectSound8_SetSpeakerConfig(dso
,speaker_config
);
172 ok(rc
==DS_OK
,"IDirectSound8_SetSpeakerConfig() failed: %08x\n", rc
);
175 rc
=IDirectSound8_GetSpeakerConfig(dso
,&new_speaker_config
);
176 ok(rc
==DS_OK
,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc
);
177 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
178 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
179 "config: expected 0x%08x, got 0x%08x\n",
180 speaker_config
,new_speaker_config
);
181 IDirectSound8_SetSpeakerConfig(dso
,ref_speaker_config
);
184 rc
=IDirectSound8_VerifyCertification(dso
, &certified
);
185 ok(rc
==DS_OK
||rc
==E_NOTIMPL
,"IDirectSound8_VerifyCertification() failed: %08x\n", rc
);
188 ref
=IDirectSound8_Release(dso
);
189 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
192 static void IDirectSound8_tests(void)
195 LPDIRECTSOUND8 dso
=NULL
;
196 LPCLASSFACTORY cf
=NULL
;
198 trace("Testing IDirectSound8\n");
200 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
201 &IID_IClassFactory
, (void**)&cf
);
202 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
203 "failed: %08x\n", rc
);
205 rc
=CoGetClassObject(&CLSID_DirectSound8
, CLSCTX_INPROC_SERVER
, NULL
,
206 &IID_IUnknown
, (void**)&cf
);
207 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) "
208 "failed: %08x\n", rc
);
210 /* try the COM class factory method of creation with no device specified */
211 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
212 &IID_IDirectSound8
, (void**)&dso
);
213 ok(rc
==S_OK
||rc
==REGDB_E_CLASSNOTREG
,"CoCreateInstance() failed: %08x\n", rc
);
214 if (rc
==REGDB_E_CLASSNOTREG
) {
215 trace(" Class Not Registered\n");
219 IDirectSound8_test(dso
, FALSE
, NULL
);
221 /* try the COM class factory method of creation with default playback
222 * device specified */
223 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
224 &IID_IDirectSound8
, (void**)&dso
);
225 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc
);
227 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
229 /* try the COM class factory method of creation with default voice
230 * playback device specified */
231 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
232 &IID_IDirectSound8
, (void**)&dso
);
233 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc
);
235 IDirectSound8_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
237 /* try the COM class factory method of creation with a bad
239 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
240 &CLSID_DirectSoundPrivate
, (void**)&dso
);
241 ok(rc
==E_NOINTERFACE
,
242 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
243 "should have failed: %08x\n",rc
);
245 /* try the COM class factory method of creation with a bad
246 * GUID and IID specified */
247 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
248 &IID_IDirectSound8
, (void**)&dso
);
249 ok(rc
==REGDB_E_CLASSNOTREG
,
250 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
251 "should have failed: %08x\n",rc
);
253 /* try with no device specified */
254 rc
=pDirectSoundCreate8(NULL
,&dso
,NULL
);
255 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
256 "DirectSoundCreate8() failed: %08x\n",rc
);
257 if (rc
==DS_OK
&& dso
)
258 IDirectSound8_test(dso
, TRUE
, NULL
);
260 /* try with default playback device specified */
261 rc
=pDirectSoundCreate8(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
262 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
263 "DirectSoundCreate8() failed: %08x\n",rc
);
264 if (rc
==DS_OK
&& dso
)
265 IDirectSound8_test(dso
, TRUE
, NULL
);
267 /* try with default voice playback device specified */
268 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
269 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
270 "DirectSoundCreate8() failed: %08x\n",rc
);
271 if (rc
==DS_OK
&& dso
)
272 IDirectSound8_test(dso
, TRUE
, NULL
);
274 /* try with a bad device specified */
275 rc
=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
276 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
277 "should have failed: %08x\n",rc
);
280 static HRESULT
test_dsound8(LPGUID lpGuid
)
283 LPDIRECTSOUND8 dso
=NULL
;
286 /* DSOUND: Error: Invalid interface buffer */
287 rc
=pDirectSoundCreate8(lpGuid
,0,NULL
);
288 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate8() should have returned "
289 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
291 /* Create the DirectSound8 object */
292 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
293 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
294 "DirectSoundCreate8() failed: %08x\n",rc
);
298 /* Try the enumerated device */
299 IDirectSound8_test(dso
, TRUE
, lpGuid
);
301 /* Try the COM class factory method of creation with enumerated device */
302 rc
=CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
303 &IID_IDirectSound8
, (void**)&dso
);
304 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
306 IDirectSound8_test(dso
, FALSE
, lpGuid
);
308 /* Create a DirectSound8 object */
309 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
310 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
312 LPDIRECTSOUND8 dso1
=NULL
;
314 /* Create a second DirectSound8 object */
315 rc
=pDirectSoundCreate8(lpGuid
,&dso1
,NULL
);
316 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
318 /* Release the second DirectSound8 object */
319 ref
=IDirectSound8_Release(dso1
);
320 ok(ref
==0,"IDirectSound8_Release() has %d references, "
321 "should have 0\n",ref
);
322 ok(dso
!=dso1
,"DirectSound8 objects should be unique: "
323 "dso=%p,dso1=%p\n",dso
,dso1
);
326 /* Release the first DirectSound8 object */
327 ref
=IDirectSound8_Release(dso
);
328 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
331 return DSERR_GENERIC
;
335 /* Create a DirectSound8 object */
336 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
337 ok(rc
==DS_OK
,"DirectSoundCreate8() failed: %08x\n",rc
);
339 LPDIRECTSOUNDBUFFER secondary
;
340 DSBUFFERDESC bufdesc
;
343 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
344 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
345 bufdesc
.dwSize
=sizeof(bufdesc
);
346 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
347 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
349 bufdesc
.lpwfxFormat
=&wfx
;
350 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
351 ok(rc
==DS_OK
&& secondary
!=NULL
,
352 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
353 "buffer: %08x\n",rc
);
354 if (rc
==DS_OK
&& secondary
!=NULL
) {
355 LPDIRECTSOUND3DBUFFER buffer3d
;
356 LPDIRECTSOUNDBUFFER8 buffer8
;
357 rc
=IDirectSound8_QueryInterface(secondary
,
358 &IID_IDirectSound3DBuffer
,
360 ok(rc
==DS_OK
&& buffer3d
!=NULL
,
361 "IDirectSound8_QueryInterface() failed: %08x\n", rc
);
362 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
363 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
364 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
365 "should have 2\n",ref
);
367 rc
=IDirectSound8_QueryInterface(secondary
,
368 &IID_IDirectSoundBuffer8
,
370 if (rc
==DS_OK
&& buffer8
!=NULL
) {
371 ok(buffer8
==(IDirectSoundBuffer8
*)secondary
,
372 "IDirectSoundBuffer8 iface different from IDirectSoundBuffer.\n");
373 ref
=IDirectSoundBuffer8_AddRef(buffer8
);
374 ok(ref
==3,"IDirectSoundBuffer8_AddRef() has %d references, "
375 "should have 3\n",ref
);
377 ref
=IDirectSoundBuffer_AddRef(secondary
);
378 ok(ref
==4,"IDirectSoundBuffer_AddRef() has %d references, "
379 "should have 4\n",ref
);
381 /* release with buffer */
382 ref
=IDirectSound8_Release(dso
);
383 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",
386 return DSERR_GENERIC
;
393 static HRESULT
test_primary8(LPGUID lpGuid
)
396 LPDIRECTSOUND8 dso
=NULL
;
397 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
398 LPDIRECTSOUNDBUFFER8 pb8
= NULL
;
399 DSBUFFERDESC bufdesc
;
404 /* Create the DirectSound object */
405 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
406 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
407 "DirectSoundCreate8() failed: %08x\n",rc
);
411 /* Get the device capabilities */
412 ZeroMemory(&dscaps
, sizeof(dscaps
));
413 dscaps
.dwSize
=sizeof(dscaps
);
414 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
415 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
419 /* DSOUND: Error: Invalid buffer description pointer */
420 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,0,NULL
);
421 ok(rc
==DSERR_INVALIDPARAM
,
422 "IDirectSound8_CreateSoundBuffer should have returned "
423 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
425 /* DSOUND: Error: Invalid buffer description pointer */
426 rc
=IDirectSound8_CreateSoundBuffer(dso
,0,&primary
,NULL
);
427 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
428 "IDirectSound8_CreateSoundBuffer() should have returned "
429 "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n",
432 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
433 bufdesc
.dwSize
= sizeof(DSBUFFERDESC
);
435 /* DSOUND: Error: Invalid dsound buffer interface pointer */
436 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
437 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
438 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
439 "dsbo=%p\n",rc
,primary
);
441 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
443 /* DSOUND: Error: Invalid size */
444 /* DSOUND: Error: Invalid buffer description */
445 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
446 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
447 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
448 "primary=%p\n",rc
,primary
);
450 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
451 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
452 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
453 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
457 /* Testing the primary buffer */
459 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
460 bufdesc
.dwSize
=sizeof(bufdesc
);
461 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
462 bufdesc
.lpwfxFormat
= &wfx
;
463 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
464 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
465 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound8_CreateSoundBuffer() should have "
466 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
467 if (rc
==DS_OK
&& primary
!=NULL
)
468 IDirectSoundBuffer_Release(primary
);
471 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
472 bufdesc
.dwSize
=sizeof(bufdesc
);
473 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
474 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
475 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
476 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
478 if (rc
==DSERR_CONTROLUNAVAIL
)
479 trace(" No Primary\n");
480 else if (rc
==DS_OK
&& primary
!=NULL
) {
483 /* Try to create a second primary buffer */
484 /* DSOUND: Error: The primary buffer already exists.
485 * Any changes made to the buffer description will be ignored. */
486 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
487 ok(rc
==DS_OK
&& second
==primary
,
488 "IDirectSound8_CreateSoundBuffer() should have returned original "
489 "primary buffer: %08x\n",rc
);
490 ref
=IDirectSoundBuffer_Release(second
);
491 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
492 "should have 1\n",ref
);
494 /* Try to duplicate a primary buffer */
495 /* DSOUND: Error: Can't duplicate primary buffers */
496 rc
=IDirectSound8_DuplicateSoundBuffer(dso
,primary
,&third
);
498 ok(rc
!=DS_OK
,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
499 "should have failed %08x\n",rc
);
501 /* Primary buffers don't have an IDirectSoundBuffer8 */
502 rc
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
, (LPVOID
*)&pb8
);
503 ok(FAILED(rc
), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc
);
505 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
506 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc
);
508 if (winetest_interactive
) {
509 trace("Playing a 5 seconds reference tone at the current volume.\n");
511 trace("(the current volume is %d according to DirectSound)\n",
513 trace("All subsequent tones should be identical to this one.\n");
514 trace("Listen for stutter, changes in pitch, volume, etc.\n");
516 test_buffer8(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
517 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
519 ref
=IDirectSoundBuffer_Release(primary
);
520 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
521 "should have 0\n",ref
);
524 /* Set the CooperativeLevel back to normal */
525 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
526 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
527 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
530 ref
=IDirectSound8_Release(dso
);
531 ok(ref
==0,"IDirectSound8_Release() has %d references, should have 0\n",ref
);
533 return DSERR_GENERIC
;
539 * Test the primary buffer at different formats while keeping the
540 * secondary buffer at a constant format.
542 static HRESULT
test_primary_secondary8(LPGUID lpGuid
)
545 LPDIRECTSOUND8 dso
=NULL
;
546 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
547 DSBUFFERDESC bufdesc
;
549 WAVEFORMATEX wfx
, wfx2
;
553 /* Create the DirectSound object */
554 rc
=pDirectSoundCreate8(lpGuid
,&dso
,NULL
);
555 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
556 "DirectSoundCreate8() failed: %08x\n",rc
);
560 /* Get the device capabilities */
561 ZeroMemory(&dscaps
, sizeof(dscaps
));
562 dscaps
.dwSize
=sizeof(dscaps
);
563 rc
=IDirectSound8_GetCaps(dso
,&dscaps
);
564 ok(rc
==DS_OK
,"IDirectSound8_GetCaps() failed: %08x\n",rc
);
568 /* We must call SetCooperativeLevel before creating primary buffer */
569 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
570 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
571 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
575 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
576 bufdesc
.dwSize
=sizeof(bufdesc
);
577 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
578 rc
=IDirectSound8_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
579 ok(rc
==DS_OK
&& primary
!=NULL
,
580 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
583 if (rc
==DS_OK
&& primary
!=NULL
) {
584 for (f
=0;f
<NB_FORMATS
;f
++) {
585 for (tag
=0;tag
<NB_TAGS
;tag
++) {
586 /* if float, we only want to test 32-bit */
587 if ((format_tags
[tag
] == WAVE_FORMAT_IEEE_FLOAT
) && (formats
[f
][1] != 32))
590 /* We must call SetCooperativeLevel to be allowed to call
592 /* DSOUND: Setting DirectSound cooperative level to
594 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
595 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
599 init_format(&wfx
,format_tags
[tag
],formats
[f
][0],formats
[f
][1],
602 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
604 || rc
==DSERR_INVALIDPARAM
, /* 2003 */
605 "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
606 format_string(&wfx
), rc
);
608 /* There is no guarantee that SetFormat will actually change the
609 * format to what we asked for. It depends on what the soundcard
610 * supports. So we must re-query the format.
612 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
613 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
615 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
616 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
617 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
618 wfx
.nChannels
!=wfx2
.nChannels
)) {
619 trace("Requested primary format tag=0x%04x %dx%dx%d "
620 "avg.B/s=%d align=%d\n",
621 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
622 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
623 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
624 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
625 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
628 /* Set the CooperativeLevel back to normal */
629 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
630 rc
=IDirectSound8_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
631 ok(rc
==DS_OK
,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc
);
633 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
636 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
637 bufdesc
.dwSize
=sizeof(bufdesc
);
638 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
639 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
641 bufdesc
.lpwfxFormat
=&wfx2
;
642 if (winetest_interactive
) {
643 trace(" Testing a primary buffer at %dx%dx%d (fmt=%d) with a "
644 "secondary buffer at %dx%dx%d\n",
645 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,format_tags
[tag
],
646 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
648 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
649 ok(rc
==DS_OK
&& secondary
!=NULL
,
650 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
653 if (rc
==DS_OK
&& secondary
!=NULL
) {
654 test_buffer8(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
655 winetest_interactive
,1.0,0,NULL
,0,0);
657 ref
=IDirectSoundBuffer_Release(secondary
);
658 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
659 "should have 0\n",ref
);
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
) || broken(hr
== E_FAIL
),
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
== E_FAIL
) || /* broken AC97 driver */
1043 broken(hr
== S_OK
) /* broken driver allows more hw bufs than dscaps claims */,
1044 "CreateSoundBuffer(%u) gave wrong error: %08x\n", i
, hr
);
1046 IDirectSoundBuffer_Release(secondary
);
1048 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
)
1050 IDirectSoundBuffer_Release(secondaries
[i
]);
1052 HeapFree(GetProcessHeap(), 0, secondaries
);
1054 IDirectSoundBuffer_Release(primary
);
1055 IDirectSound8_Release(ds
);
1061 } default_info
= { 0 };
1063 static BOOL WINAPI
default_device_cb(GUID
*guid
, const char *desc
,
1064 const char *module
, void *user
)
1066 trace("guid: %p, desc: %s\n", guid
, desc
);
1068 ok(default_info
.dev_count
== 0, "Got NULL GUID not in first position\n");
1070 if(default_info
.dev_count
== 0){
1071 ok(IsEqualGUID(guid
, &default_info
.guid
), "Expected default device GUID\n");
1073 ok(!IsEqualGUID(guid
, &default_info
.guid
), "Got default GUID at unexpected location: %u\n",
1074 default_info
.dev_count
);
1077 /* only count real devices */
1078 ++default_info
.dev_count
;
1084 static void test_first_device(void)
1086 IMMDeviceEnumerator
*devenum
;
1092 hr
= CoCreateInstance(&CLSID_MMDeviceEnumerator
, NULL
,
1093 CLSCTX_INPROC_SERVER
, &IID_IMMDeviceEnumerator
, (void**)&devenum
);
1095 win_skip("MMDevAPI is not available, skipping default device test\n");
1099 hr
= IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum
, eRender
,
1100 eMultimedia
, &defdev
);
1101 if (hr
== E_NOTFOUND
) {
1102 win_skip("No default device found\n");
1105 ok(hr
== S_OK
, "GetDefaultAudioEndpoint failed: %08x\n", hr
);
1107 hr
= IMMDevice_OpenPropertyStore(defdev
, STGM_READ
, &ps
);
1108 ok(hr
== S_OK
, "OpenPropertyStore failed: %08x\n", hr
);
1110 PropVariantInit(&pv
);
1112 hr
= IPropertyStore_GetValue(ps
, &PKEY_AudioEndpoint_GUID
, &pv
);
1113 ok(hr
== S_OK
, "GetValue failed: %08x\n", hr
);
1115 CLSIDFromString(pv
.u
.pwszVal
, &default_info
.guid
);
1117 PropVariantClear(&pv
);
1118 IPropertyStore_Release(ps
);
1119 IMMDevice_Release(defdev
);
1120 IMMDeviceEnumerator_Release(devenum
);
1122 hr
= pDirectSoundEnumerateA(&default_device_cb
, NULL
);
1123 ok(hr
== S_OK
, "DirectSoundEnumerateA failed: %08x\n", hr
);
1126 static void test_COM(void)
1129 IDirectSound8
*ds8
= (IDirectSound8
*)0xdeadbeef;
1130 IUnknown
*unk
, *unk8
;
1134 /* COM aggregation */
1135 hr
= CoCreateInstance(&CLSID_DirectSound8
, (IUnknown
*)&ds
, CLSCTX_INPROC_SERVER
,
1136 &IID_IUnknown
, (void**)&ds8
);
1137 ok(hr
== CLASS_E_NOAGGREGATION
,
1138 "DirectSound create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
1139 ok(!ds8
, "ds8 = %p\n", ds8
);
1142 hr
= CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
,
1143 &IID_IDirectSound3DBuffer
, (void**)&ds8
);
1144 ok(hr
== E_NOINTERFACE
,
1145 "DirectSound create failed: %08x, expected E_NOINTERFACE\n", hr
);
1147 /* Same refcount for IDirectSound and IDirectSound8 */
1148 hr
= CoCreateInstance(&CLSID_DirectSound8
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectSound8
,
1150 ok(hr
== S_OK
, "DirectSound create failed: %08x, expected S_OK\n", hr
);
1151 refcount
= IDirectSound8_AddRef(ds8
);
1152 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1153 hr
= IDirectSound8_QueryInterface(ds8
, &IID_IDirectSound
, (void**)&ds
);
1154 ok(hr
== S_OK
, "QueryInterface for IID_IDirectSound failed: %08x\n", hr
);
1155 refcount
= IDirectSound8_AddRef(ds8
);
1156 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1157 refcount
= IDirectSound_AddRef(ds
);
1158 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
1160 /* Separate refcount for IUnknown */
1161 hr
= IDirectSound_QueryInterface(ds
, &IID_IUnknown
, (void**)&unk
);
1162 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1163 refcount
= IUnknown_AddRef(unk
);
1164 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1165 hr
= IDirectSound_QueryInterface(ds8
, &IID_IUnknown
, (void**)&unk8
);
1166 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1167 refcount
= IUnknown_AddRef(unk8
);
1168 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1169 refcount
= IDirectSound_AddRef(ds
);
1170 ok(refcount
== 6, "refcount == %u, expected 6\n", refcount
);
1172 while (IDirectSound_Release(ds
));
1173 while (IUnknown_Release(unk
));
1182 hDsound
= LoadLibrary("dsound.dll");
1186 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1187 "DirectSoundEnumerateA");
1188 pDirectSoundCreate8
= (void*)GetProcAddress(hDsound
,
1189 "DirectSoundCreate8");
1190 if (pDirectSoundCreate8
)
1193 IDirectSound8_tests();
1196 test_first_device();
1199 skip("DirectSoundCreate8 missing - skipping all tests\n");
1201 FreeLibrary(hDsound
);
1204 skip("dsound.dll not found - skipping all tests\n");