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
12 * Copyright (c) 2007 Maarten Lankhorst
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/test.h"
39 #include "dsound_test.h"
41 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
43 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
44 static HRESULT (WINAPI
*pDirectSoundCreate
)(LPCGUID
,LPDIRECTSOUND
*,
49 static void IDirectSound_test(LPDIRECTSOUND dso
, BOOL initialized
,
58 DWORD speaker_config
, new_speaker_config
, ref_speaker_config
;
60 /* Try to Query for objects */
61 rc
=IDirectSound_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
62 ok(rc
==DS_OK
,"IDirectSound_QueryInterface(IID_IUnknown) failed: %08x\n", rc
);
64 IDirectSound_Release(unknown
);
66 rc
=IDirectSound_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
67 ok(rc
==DS_OK
,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %08x\n", rc
);
69 IDirectSound_Release(ds
);
71 rc
=IDirectSound_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
72 ok(rc
==E_NOINTERFACE
,"IDirectSound_QueryInterface(IID_IDirectSound8) "
73 "should have failed: %08x\n",rc
);
75 IDirectSound8_Release(ds8
);
77 if (initialized
== FALSE
) {
78 /* try uninitialized object */
79 rc
=IDirectSound_GetCaps(dso
,0);
80 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetCaps(NULL) "
81 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
83 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
84 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetCaps() "
85 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
87 rc
=IDirectSound_Compact(dso
);
88 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_Compact() "
89 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
91 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
92 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetSpeakerConfig() "
93 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc
);
95 rc
=IDirectSound_Initialize(dso
,lpGuid
);
96 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
97 "IDirectSound_Initialize() failed: %08x\n",rc
);
98 if (rc
==DSERR_NODRIVER
) {
99 trace(" No Driver\n");
101 } else if (rc
==E_FAIL
) {
102 trace(" No Device\n");
104 } else if (rc
==DSERR_ALLOCATED
) {
105 trace(" Already In Use\n");
110 rc
=IDirectSound_Initialize(dso
,lpGuid
);
111 ok(rc
==DSERR_ALREADYINITIALIZED
, "IDirectSound_Initialize() "
112 "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc
);
114 /* DSOUND: Error: Invalid caps buffer */
115 rc
=IDirectSound_GetCaps(dso
,0);
116 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps(NULL) "
117 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
119 ZeroMemory(&dscaps
, sizeof(dscaps
));
121 /* DSOUND: Error: Invalid caps buffer */
122 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
123 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps() "
124 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
126 dscaps
.dwSize
=sizeof(dscaps
);
128 /* DSOUND: Running on a certified driver */
129 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
130 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
132 rc
=IDirectSound_Compact(dso
);
133 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound_Compact() failed: %08x\n", rc
);
135 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
136 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
138 rc
=IDirectSound_Compact(dso
);
139 ok(rc
==DS_OK
,"IDirectSound_Compact() failed: %08x\n",rc
);
141 rc
=IDirectSound_GetSpeakerConfig(dso
,0);
142 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetSpeakerConfig(NULL) "
143 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
145 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
146 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %08x\n", rc
);
147 ref_speaker_config
= speaker_config
;
149 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
150 DSSPEAKER_GEOMETRY_WIDE
);
151 if (speaker_config
== ref_speaker_config
)
152 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
153 DSSPEAKER_GEOMETRY_NARROW
);
155 rc
=IDirectSound_SetSpeakerConfig(dso
,speaker_config
);
156 ok(rc
==DS_OK
,"IDirectSound_SetSpeakerConfig() failed: %08x\n", rc
);
159 rc
=IDirectSound_GetSpeakerConfig(dso
,&new_speaker_config
);
160 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %08x\n", rc
);
161 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
162 trace("IDirectSound_GetSpeakerConfig() failed to set speaker "
163 "config: expected 0x%08x, got 0x%08x\n",
164 speaker_config
,new_speaker_config
);
165 IDirectSound_SetSpeakerConfig(dso
,ref_speaker_config
);
169 ref
=IDirectSound_Release(dso
);
170 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
173 static void IDirectSound_tests(void)
176 LPDIRECTSOUND dso
=NULL
;
177 LPCLASSFACTORY cf
=NULL
;
179 trace("Testing IDirectSound\n");
181 rc
=CoGetClassObject(&CLSID_DirectSound
, CLSCTX_INPROC_SERVER
, NULL
,
182 &IID_IClassFactory
, (void**)&cf
);
183 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound, IID_IClassFactory) "
184 "failed: %08x\n", rc
);
186 rc
=CoGetClassObject(&CLSID_DirectSound
, CLSCTX_INPROC_SERVER
, NULL
,
187 &IID_IUnknown
, (void**)&cf
);
188 ok(rc
==S_OK
,"CoGetClassObject(CLSID_DirectSound, IID_IUnknown) "
189 "failed: %08x\n", rc
);
191 /* try the COM class factory method of creation with no device specified */
192 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
193 &IID_IDirectSound
, (void**)&dso
);
194 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
196 IDirectSound_test(dso
, FALSE
, NULL
);
198 /* try the COM class factory method of creation with default playback
199 * device specified */
200 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
201 &IID_IDirectSound
, (void**)&dso
);
202 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
204 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
206 /* try the COM class factory method of creation with default voice
207 * playback device specified */
208 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
209 &IID_IDirectSound
, (void**)&dso
);
210 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
212 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
214 /* try the COM class factory method of creation with a bad
216 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
217 &CLSID_DirectSoundPrivate
, (void**)&dso
);
218 ok(rc
==E_NOINTERFACE
,
219 "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) "
220 "should have failed: %08x\n",rc
);
222 /* try the COM class factory method of creation with a bad
223 * GUID and IID specified */
224 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
225 &IID_IDirectSound
, (void**)&dso
);
226 ok(rc
==REGDB_E_CLASSNOTREG
,
227 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) "
228 "should have failed: %08x\n",rc
);
230 /* try with no device specified */
231 rc
=pDirectSoundCreate(NULL
,&dso
,NULL
);
232 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
233 "DirectSoundCreate(NULL) failed: %08x\n",rc
);
235 IDirectSound_test(dso
, TRUE
, NULL
);
237 /* try with default playback device specified */
238 rc
=pDirectSoundCreate(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
239 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
240 "DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %08x\n", rc
);
241 if (rc
==DS_OK
&& dso
)
242 IDirectSound_test(dso
, TRUE
, NULL
);
244 /* try with default voice playback device specified */
245 rc
=pDirectSoundCreate(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
246 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
247 "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %08x\n", rc
);
248 if (rc
==DS_OK
&& dso
)
249 IDirectSound_test(dso
, TRUE
, NULL
);
251 /* try with a bad device specified */
252 rc
=pDirectSoundCreate(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
253 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) "
254 "should have failed: %08x\n",rc
);
255 if (rc
==DS_OK
&& dso
)
256 IDirectSound_Release(dso
);
259 static HRESULT
test_dsound(LPGUID lpGuid
)
262 LPDIRECTSOUND dso
=NULL
;
265 /* DSOUND: Error: Invalid interface buffer */
266 rc
=pDirectSoundCreate(lpGuid
,0,NULL
);
267 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate() should have returned "
268 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
270 /* Create the DirectSound object */
271 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
272 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
273 "DirectSoundCreate() failed: %08x\n",rc
);
277 /* Try the enumerated device */
278 IDirectSound_test(dso
, TRUE
, lpGuid
);
280 /* Try the COM class factory method of creation with enumerated device */
281 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
282 &IID_IDirectSound
, (void**)&dso
);
283 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc
);
285 IDirectSound_test(dso
, FALSE
, lpGuid
);
287 /* Create a DirectSound object */
288 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
289 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %08x\n",rc
);
291 LPDIRECTSOUND dso1
=NULL
;
293 /* Create a second DirectSound object */
294 rc
=pDirectSoundCreate(lpGuid
,&dso1
,NULL
);
295 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %08x\n",rc
);
297 /* Release the second DirectSound object */
298 ref
=IDirectSound_Release(dso1
);
299 ok(ref
==0,"IDirectSound_Release() has %d references, should have "
301 ok(dso
!=dso1
,"DirectSound objects should be unique: dso=%p,dso1=%p\n",dso
,dso1
);
304 /* Release the first DirectSound object */
305 ref
=IDirectSound_Release(dso
);
306 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
309 return DSERR_GENERIC
;
313 /* Create a DirectSound object */
314 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
315 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %08x\n",rc
);
317 LPDIRECTSOUNDBUFFER secondary
;
318 DSBUFFERDESC bufdesc
;
321 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
322 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
323 bufdesc
.dwSize
=sizeof(bufdesc
);
324 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
325 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
327 bufdesc
.lpwfxFormat
=&wfx
;
328 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
329 ok((rc
==DS_OK
&& secondary
!=NULL
) || broken(rc
== DSERR_CONTROLUNAVAIL
), /* vmware drivers on w2k */
330 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
332 if (rc
==DS_OK
&& secondary
!=NULL
) {
333 LPDIRECTSOUND3DBUFFER buffer3d
;
334 rc
=IDirectSound_QueryInterface(secondary
, &IID_IDirectSound3DBuffer
,
336 ok(rc
==DS_OK
&& buffer3d
!=NULL
,"IDirectSound_QueryInterface() "
337 "failed: %08x\n",rc
);
338 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
339 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
340 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
341 "should have 2\n",ref
);
343 ref
=IDirectSoundBuffer_AddRef(secondary
);
344 ok(ref
==2,"IDirectSoundBuffer_AddRef() has %d references, "
345 "should have 2\n",ref
);
347 /* release with buffer */
348 ref
=IDirectSound_Release(dso
);
349 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
352 return DSERR_GENERIC
;
359 static HRESULT
test_primary(LPGUID lpGuid
)
362 LPDIRECTSOUND dso
=NULL
;
363 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
364 DSBUFFERDESC bufdesc
;
369 /* Create the DirectSound object */
370 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
371 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
372 "DirectSoundCreate() failed: %08x\n",rc
);
376 /* Get the device capabilities */
377 ZeroMemory(&dscaps
, sizeof(dscaps
));
378 dscaps
.dwSize
=sizeof(dscaps
);
379 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
380 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
384 /* DSOUND: Error: Invalid buffer description pointer */
385 rc
=IDirectSound_CreateSoundBuffer(dso
,0,0,NULL
);
386 ok(rc
==DSERR_INVALIDPARAM
,
387 "IDirectSound_CreateSoundBuffer() should have failed: %08x\n", rc
);
389 /* DSOUND: Error: NULL pointer is invalid */
390 /* DSOUND: Error: Invalid buffer description pointer */
391 rc
=IDirectSound_CreateSoundBuffer(dso
,0,&primary
,NULL
);
392 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
393 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x,"
394 "dsbo=%p\n",rc
,primary
);
396 /* DSOUND: Error: Invalid size */
397 /* DSOUND: Error: Invalid buffer description */
399 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
400 bufdesc
.dwSize
=sizeof(bufdesc
)-1;
401 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
402 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
403 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x,"
404 "primary=%p\n",rc
,primary
);
406 /* DSOUND: Error: DSBCAPS_PRIMARYBUFFER flag with non-NULL lpwfxFormat */
407 /* DSOUND: Error: Invalid buffer description pointer */
409 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
410 bufdesc
.dwSize
=sizeof(bufdesc
);
411 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
412 bufdesc
.lpwfxFormat
=&wfx
;
413 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
414 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
415 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x,"
416 "primary=%p\n",rc
,primary
);
418 /* DSOUND: Error: No DSBCAPS_PRIMARYBUFFER flag with NULL lpwfxFormat */
419 /* DSOUND: Error: Invalid buffer description pointer */
421 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
422 bufdesc
.dwSize
=sizeof(bufdesc
);
424 bufdesc
.lpwfxFormat
=NULL
;
425 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
426 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
427 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x,"
428 "primary=%p\n",rc
,primary
);
430 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
431 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
432 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
433 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
437 /* Testing the primary buffer */
439 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
440 bufdesc
.dwSize
=sizeof(bufdesc
);
441 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
442 bufdesc
.lpwfxFormat
= &wfx
;
443 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
444 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
445 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() should have "
446 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
447 if (rc
==DS_OK
&& primary
!=NULL
)
448 IDirectSoundBuffer_Release(primary
);
451 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
452 bufdesc
.dwSize
=sizeof(bufdesc
);
453 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
454 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
455 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
456 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: %08x\n",rc
);
457 if (rc
==DSERR_CONTROLUNAVAIL
)
458 trace(" No Primary\n");
459 else if (rc
==DS_OK
&& primary
!=NULL
) {
462 /* Try to create a second primary buffer */
463 /* DSOUND: Error: The primary buffer already exists.
464 * Any changes made to the buffer description will be ignored. */
465 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
466 ok(rc
==DS_OK
&& second
==primary
,
467 "IDirectSound_CreateSoundBuffer() should have returned original "
468 "primary buffer: %08x\n",rc
);
469 ref
=IDirectSoundBuffer_Release(second
);
470 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
471 "should have 1\n",ref
);
473 /* Try to duplicate a primary buffer */
474 /* DSOUND: Error: Can't duplicate primary buffers */
475 rc
=IDirectSound_DuplicateSoundBuffer(dso
,primary
,&third
);
477 ok(rc
!=DS_OK
,"IDirectSound_DuplicateSoundBuffer() primary buffer "
478 "should have failed %08x\n",rc
);
480 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
481 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc
);
483 if (winetest_interactive
) {
484 trace("Playing a 5 seconds reference tone at the current "
487 trace("(the current volume is %d according to DirectSound)\n",
489 trace("All subsequent tones should be identical to this one.\n");
490 trace("Listen for stutter, changes in pitch, volume, etc.\n");
492 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
493 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0,FALSE
,0);
495 ref
=IDirectSoundBuffer_Release(primary
);
496 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references\n",ref
);
498 ref
=IDirectSoundBuffer_AddRef(primary
);
499 ok(ref
==1,"IDirectSoundBuffer_AddRef() primary has %d references\n",ref
);
501 ref
=IDirectSoundBuffer_Release(primary
);
502 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references\n",ref
);
504 ref
=IDirectSoundBuffer_Release(primary
);
505 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
506 "should have 0\n",ref
);
509 /* Set the CooperativeLevel back to normal */
510 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
511 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
512 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
515 ref
=IDirectSound_Release(dso
);
516 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
518 return DSERR_GENERIC
;
524 * Test the primary buffer at different formats while keeping the
525 * secondary buffer at a constant format.
527 static HRESULT
test_primary_secondary(LPGUID lpGuid
)
530 LPDIRECTSOUND dso
=NULL
;
531 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
532 DSBUFFERDESC bufdesc
;
534 WAVEFORMATEX wfx
, wfx2
;
537 /* Create the DirectSound object */
538 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
539 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
540 "DirectSoundCreate() failed: %08x\n",rc
);
544 /* Get the device capabilities */
545 ZeroMemory(&dscaps
, sizeof(dscaps
));
546 dscaps
.dwSize
=sizeof(dscaps
);
547 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
548 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
552 /* We must call SetCooperativeLevel before creating primary buffer */
553 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
554 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
555 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
559 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
560 bufdesc
.dwSize
=sizeof(bufdesc
);
561 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
562 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
563 ok(rc
==DS_OK
&& primary
!=NULL
,
564 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc
);
566 if (rc
==DS_OK
&& primary
!=NULL
) {
567 for (f
=0;f
<NB_FORMATS
;f
++) {
568 for (tag
=0;tag
<NB_TAGS
;tag
++) {
569 /* if float, we only want to test 32-bit */
570 if ((format_tags
[tag
] == WAVE_FORMAT_IEEE_FLOAT
) && (formats
[f
][1] != 32))
573 /* We must call SetCooperativeLevel to be allowed to call
575 /* DSOUND: Setting DirectSound cooperative level to
577 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
578 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
582 init_format(&wfx
,format_tags
[tag
],formats
[f
][0],formats
[f
][1],
585 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
587 if (wfx
.wBitsPerSample
<= 16)
588 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
589 format_string(&wfx
), rc
);
591 ok(rc
==DS_OK
|| rc
== E_INVALIDARG
, "SetFormat (%s) failed: %08x\n",
592 format_string(&wfx
), rc
);
594 /* There is no guarantee that SetFormat will actually change the
595 * format to what we asked for. It depends on what the soundcard
596 * supports. So we must re-query the format.
598 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
599 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
601 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
602 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
603 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
604 wfx
.nChannels
!=wfx2
.nChannels
)) {
605 trace("Requested primary format tag=0x%04x %dx%dx%d "
606 "avg.B/s=%d align=%d\n",
607 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
608 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
609 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
610 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
611 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
614 /* Set the CooperativeLevel back to normal */
615 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
616 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
617 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
619 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
622 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
623 bufdesc
.dwSize
=sizeof(bufdesc
);
624 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
625 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
627 bufdesc
.lpwfxFormat
=&wfx2
;
628 if (winetest_interactive
) {
629 trace(" Testing a primary buffer at %dx%dx%d (fmt=%d) with a "
630 "secondary buffer at %dx%dx%d\n",
631 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,format_tags
[tag
],
632 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
634 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
635 ok((rc
==DS_OK
&& secondary
!=NULL
) || broken(rc
== DSERR_CONTROLUNAVAIL
), /* vmware drivers on w2k */
636 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc
);
638 if (rc
==DS_OK
&& secondary
!=NULL
) {
639 todo_wine
ok(primary
->lpVtbl
==secondary
->lpVtbl
,
640 "Primary and secondary buffers have different vtbls.\n");
642 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
643 winetest_interactive
,1.0,0,NULL
,0,0,FALSE
,0);
645 ref
=IDirectSoundBuffer_Release(secondary
);
646 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
647 "should have 0\n",ref
);
652 ref
=IDirectSoundBuffer_Release(primary
);
653 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
654 "should have 0\n",ref
);
657 /* Set the CooperativeLevel back to normal */
658 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
659 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
660 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
663 ref
=IDirectSound_Release(dso
);
664 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
666 return DSERR_GENERIC
;
671 static HRESULT
test_secondary(LPGUID lpGuid
)
674 LPDIRECTSOUND dso
=NULL
;
675 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
676 DSBUFFERDESC bufdesc
;
678 WAVEFORMATEX wfx
, wfx1
;
682 /* Create the DirectSound object */
683 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
684 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
685 "DirectSoundCreate() failed: %08x\n",rc
);
689 /* Get the device capabilities */
690 ZeroMemory(&dscaps
, sizeof(dscaps
));
691 dscaps
.dwSize
=sizeof(dscaps
);
692 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
693 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
697 /* We must call SetCooperativeLevel before creating primary buffer */
698 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
699 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
700 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
704 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
705 bufdesc
.dwSize
=sizeof(bufdesc
);
706 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
707 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
708 ok(rc
==DS_OK
&& primary
!=NULL
,
709 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc
);
711 if (rc
==DS_OK
&& primary
!=NULL
) {
712 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
713 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
717 for (f
=0;f
<NB_FORMATS
;f
++) {
718 for (tag
=0;tag
<NB_TAGS
;tag
++) {
719 WAVEFORMATEXTENSIBLE wfxe
;
721 /* if float, we only want to test 32-bit */
722 if ((format_tags
[tag
] == WAVE_FORMAT_IEEE_FLOAT
) && (formats
[f
][1] != 32))
725 init_format(&wfx
,format_tags
[tag
],formats
[f
][0],formats
[f
][1],
728 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
729 bufdesc
.dwSize
=sizeof(bufdesc
);
730 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
731 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
733 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
734 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() "
735 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
736 if (rc
==DS_OK
&& secondary
!=NULL
)
737 IDirectSoundBuffer_Release(secondary
);
740 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
741 bufdesc
.dwSize
=sizeof(bufdesc
);
742 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
743 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
745 bufdesc
.lpwfxFormat
=&wfx
;
746 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
747 if (gotdx8
|| wfx
.wBitsPerSample
<= 16 || wfx
.wFormatTag
== WAVE_FORMAT_IEEE_FLOAT
)
749 if (wfx
.wBitsPerSample
> 16)
750 ok(((rc
== DSERR_CONTROLUNAVAIL
|| rc
== DSERR_INVALIDCALL
|| rc
== DSERR_INVALIDPARAM
/* 2003 */) && !secondary
)
751 || rc
== DS_OK
, /* driver dependent? */
752 "IDirectSound_CreateSoundBuffer() "
753 "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
754 "and NULL, returned: %08x %p\n", rc
, secondary
);
756 ok((rc
==DS_OK
&& secondary
!=NULL
) || broken(rc
== DSERR_CONTROLUNAVAIL
), /* vmware drivers on w2k */
757 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc
);
760 ok(rc
==E_INVALIDARG
, "Creating %d bpp buffer on dx < 8 returned: %p %08x\n",
761 wfx
.wBitsPerSample
, secondary
, rc
);
765 win_skip("Not doing the WAVE_FORMAT_EXTENSIBLE tests\n");
766 /* Apparently they succeed with bogus values,
767 * which means that older dsound doesn't look at them
773 IDirectSoundBuffer_Release(secondary
);
776 bufdesc
.lpwfxFormat
=(WAVEFORMATEX
*)&wfxe
;
778 wfxe
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
779 wfxe
.SubFormat
= (format_tags
[tag
] == WAVE_FORMAT_PCM
? KSDATAFORMAT_SUBTYPE_PCM
: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
780 wfxe
.Format
.cbSize
= 1;
781 wfxe
.Samples
.wValidBitsPerSample
= wfx
.wBitsPerSample
;
782 wfxe
.dwChannelMask
= (wfx
.nChannels
== 1 ? KSAUDIO_SPEAKER_MONO
: KSAUDIO_SPEAKER_STEREO
);
784 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
785 ok((rc
==DSERR_INVALIDPARAM
|| rc
==DSERR_INVALIDCALL
/* 2003 */) && !secondary
,
786 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
790 IDirectSoundBuffer_Release(secondary
);
794 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
) + 1;
796 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
797 ok(((rc
==DSERR_CONTROLUNAVAIL
|| rc
==DSERR_INVALIDCALL
|| rc
==DSERR_INVALIDPARAM
)
799 || rc
==DS_OK
, /* 2003 / 2008 */
800 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
804 IDirectSoundBuffer_Release(secondary
);
808 wfxe
.Format
.cbSize
= sizeof(wfxe
) - sizeof(wfx
);
809 wfxe
.SubFormat
= GUID_NULL
;
810 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
811 ok((rc
==DSERR_INVALIDPARAM
|| rc
==DSERR_INVALIDCALL
) && !secondary
,
812 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
816 IDirectSoundBuffer_Release(secondary
);
819 wfxe
.SubFormat
= (format_tags
[tag
] == WAVE_FORMAT_PCM
? KSDATAFORMAT_SUBTYPE_PCM
: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
821 ++wfxe
.Samples
.wValidBitsPerSample
;
822 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
823 ok(rc
==DSERR_INVALIDPARAM
&& !secondary
,
824 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
828 IDirectSoundBuffer_Release(secondary
);
831 --wfxe
.Samples
.wValidBitsPerSample
;
833 wfxe
.Samples
.wValidBitsPerSample
= 0;
834 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
835 ok(rc
==DS_OK
&& secondary
,
836 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
840 IDirectSoundBuffer_Release(secondary
);
843 wfxe
.Samples
.wValidBitsPerSample
= wfxe
.Format
.wBitsPerSample
;
845 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
846 ok(rc
==DS_OK
&& secondary
!=NULL
,
847 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc
);
850 if (rc
==DS_OK
&& secondary
!=NULL
) {
851 if (winetest_interactive
) {
852 trace(" Testing a secondary buffer at %dx%dx%d (fmt=%d) "
853 "with a primary buffer at %dx%dx%d\n",
854 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,format_tags
[tag
],
855 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
857 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
858 winetest_interactive
,1.0,0,NULL
,0,0,FALSE
,0);
860 ref
=IDirectSoundBuffer_Release(secondary
);
861 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
862 "should have 0\n",ref
);
867 ref
=IDirectSoundBuffer_Release(primary
);
868 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
869 "should have 0\n",ref
);
872 /* Set the CooperativeLevel back to normal */
873 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
874 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
875 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
878 ref
=IDirectSound_Release(dso
);
879 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
881 return DSERR_GENERIC
;
886 static HRESULT
test_block_align(LPGUID lpGuid
)
889 LPDIRECTSOUND dso
=NULL
;
890 LPDIRECTSOUNDBUFFER secondary
=NULL
;
891 DSBUFFERDESC bufdesc
;
897 /* Create the DirectSound object */
898 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
899 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
900 "DirectSoundCreate() failed: %08x\n",rc
);
904 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,16,2);
905 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
906 bufdesc
.dwSize
=sizeof(bufdesc
);
907 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
908 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
+ 1;
909 bufdesc
.lpwfxFormat
=&wfx
;
910 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
911 ok(rc
== DS_OK
|| broken(rc
== DSERR_CONTROLUNAVAIL
), /* vmware drivers on w2k */
912 "IDirectSound_CreateSoundBuffer() should have returned DS_OK, returned: %08x\n", rc
);
914 if (rc
==DS_OK
&& secondary
!=NULL
) {
915 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
916 dsbcaps
.dwSize
= sizeof(dsbcaps
);
917 rc
=IDirectSoundBuffer_GetCaps(secondary
,&dsbcaps
);
918 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, "
919 "returned: %08x\n", rc
);
920 if (rc
==DS_OK
&& wfx
.nBlockAlign
> 1)
922 ok(dsbcaps
.dwBufferBytes
==(wfx
.nAvgBytesPerSec
+ wfx
.nBlockAlign
),
923 "Buffer size not a multiple of nBlockAlign: requested %d, "
924 "got %d, should be %d\n", bufdesc
.dwBufferBytes
,
925 dsbcaps
.dwBufferBytes
, wfx
.nAvgBytesPerSec
+ wfx
.nBlockAlign
);
927 rc
= IDirectSoundBuffer_SetCurrentPosition(secondary
, 0);
928 ok(rc
== DS_OK
, "Could not set position to 0: %08x\n", rc
);
929 rc
= IDirectSoundBuffer_GetCurrentPosition(secondary
, &pos
, NULL
);
930 ok(rc
== DS_OK
, "Could not get position: %08x\n", rc
);
931 rc
= IDirectSoundBuffer_SetCurrentPosition(secondary
, 1);
932 ok(rc
== DS_OK
, "Could not set position to 1: %08x\n", rc
);
933 rc
= IDirectSoundBuffer_GetCurrentPosition(secondary
, &pos2
, NULL
);
934 ok(rc
== DS_OK
, "Could not get new position: %08x\n", rc
);
935 ok(pos
== pos2
, "Positions not the same! Old position: %d, new position: %d\n", pos
, pos2
);
937 ref
=IDirectSoundBuffer_Release(secondary
);
938 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d references, "
939 "should have 0\n",ref
);
942 ref
=IDirectSound_Release(dso
);
943 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
945 return DSERR_GENERIC
;
953 } fmts
[] = { { 8, 1 }, { 8, 2 }, { 16, 1 }, {16, 2 } };
955 static HRESULT
test_frequency(LPGUID lpGuid
)
958 LPDIRECTSOUND dso
=NULL
;
959 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
960 DSBUFFERDESC bufdesc
;
962 WAVEFORMATEX wfx
, wfx1
;
965 int rates
[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
968 /* Create the DirectSound object */
969 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
970 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
971 "DirectSoundCreate() failed: %08x\n",rc
);
975 /* Get the device capabilities */
976 ZeroMemory(&dscaps
, sizeof(dscaps
));
977 dscaps
.dwSize
=sizeof(dscaps
);
978 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
979 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
983 /* We must call SetCooperativeLevel before creating primary buffer */
984 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
985 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
986 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
990 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
991 bufdesc
.dwSize
=sizeof(bufdesc
);
992 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
993 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
994 ok(rc
==DS_OK
&& primary
!=NULL
,
995 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc
);
997 if (rc
==DS_OK
&& primary
!=NULL
) {
998 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
999 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
1003 for (f
=0;f
<sizeof(fmts
)/sizeof(fmts
[0]);f
++) {
1004 for (r
=0;r
<sizeof(rates
)/sizeof(rates
[0]);r
++) {
1005 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,fmts
[f
].bits
,
1008 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1009 bufdesc
.dwSize
=sizeof(bufdesc
);
1010 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
|DSBCAPS_CTRLFREQUENCY
;
1011 bufdesc
.dwBufferBytes
=align((wfx
.nAvgBytesPerSec
*rates
[r
]/11025)*
1012 BUFFER_LEN
/1000,wfx
.nBlockAlign
);
1013 bufdesc
.lpwfxFormat
=&wfx
;
1014 if (winetest_interactive
) {
1015 trace(" Testing a secondary buffer at %dx%dx%d "
1016 "with a primary buffer at %dx%dx%d\n",
1017 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
1018 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
1020 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
1021 ok((rc
==DS_OK
&& secondary
!=NULL
) || broken(rc
== DSERR_CONTROLUNAVAIL
), /* vmware drivers on w2k */
1022 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc
);
1024 if (rc
==DS_OK
&& secondary
!=NULL
) {
1025 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
1026 winetest_interactive
,1.0,0,NULL
,0,0,TRUE
,rates
[r
]);
1028 ref
=IDirectSoundBuffer_Release(secondary
);
1029 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
1030 "should have 0\n",ref
);
1035 ref
=IDirectSoundBuffer_Release(primary
);
1036 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1037 "should have 0\n",ref
);
1040 /* Set the CooperativeLevel back to normal */
1041 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1042 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1043 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
1046 ref
=IDirectSound_Release(dso
);
1047 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1049 return DSERR_GENERIC
;
1054 static HRESULT
test_notify(LPDIRECTSOUNDBUFFER dsb
,
1055 DWORD count
, LPHANDLE event
,
1061 rc
=IDirectSoundBuffer_SetCurrentPosition(dsb
,0);
1063 "IDirectSoundBuffer_SetCurrentPosition failed %08x\n",rc
);
1067 rc
=IDirectSoundBuffer_Play(dsb
,0,0,0);
1068 ok(rc
==DS_OK
,"IDirectSoundBuffer_Play failed %08x\n",rc
);
1072 rc
=IDirectSoundBuffer_Stop(dsb
);
1073 ok(rc
==DS_OK
,"IDirectSoundBuffer_Stop failed %08x\n",rc
);
1077 ret
=WaitForMultipleObjects(count
,event
,FALSE
,0);
1078 ok(ret
==expected
,"expected %d. got %d\n",expected
,ret
);
1082 static HRESULT
test_duplicate(LPGUID lpGuid
)
1085 LPDIRECTSOUND dso
=NULL
;
1086 LPDIRECTSOUNDBUFFER primary
=NULL
;
1087 DSBUFFERDESC bufdesc
;
1090 /* Create the DirectSound object */
1091 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1092 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
1093 "DirectSoundCreate() failed: %08x\n",rc
);
1097 /* We must call SetCooperativeLevel before creating primary buffer */
1098 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1099 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1100 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
1104 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1105 bufdesc
.dwSize
=sizeof(bufdesc
);
1106 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1107 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1108 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1109 "to create a primary buffer %08x\n",rc
);
1111 if (rc
==DS_OK
&& primary
!=NULL
) {
1112 LPDIRECTSOUNDBUFFER original
=NULL
;
1115 init_format(&wfx
,WAVE_FORMAT_PCM
,22050,16,1);
1116 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1117 bufdesc
.dwSize
=sizeof(bufdesc
);
1118 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
|DSBCAPS_CTRLPOSITIONNOTIFY
;
1119 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
/100; /* very short buffer */
1120 bufdesc
.lpwfxFormat
=&wfx
;
1121 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&original
,NULL
);
1122 ok(rc
==DS_OK
&& original
!=NULL
,
1123 "IDirectSound_CreateSoundBuffer() failed to create a original "
1124 "buffer %08x\n",rc
);
1125 if (rc
==DS_OK
&& original
!=NULL
) {
1126 LPDIRECTSOUNDBUFFER duplicated
=NULL
;
1127 LPDIRECTSOUNDNOTIFY notify
=NULL
;
1133 /* Prepare notify events */
1134 for (i
=0;i
<sizeof(event
)/sizeof(event
[0]);i
++) {
1135 event
[i
] = CreateEvent(NULL
,FALSE
,FALSE
,NULL
);
1138 /* Make silent buffer */
1139 rc
=IDirectSoundBuffer_Lock(original
,0,0,&buf
,&bufsize
,
1140 NULL
,NULL
,DSBLOCK_ENTIREBUFFER
);
1141 ok(rc
==DS_OK
&& buf
!=NULL
,
1142 "IDirectSoundBuffer_Lock failed to lock the buffer %08x\n",rc
);
1143 if (rc
==DS_OK
&& buf
!=NULL
) {
1144 ZeroMemory(buf
,bufsize
);
1145 rc
=IDirectSoundBuffer_Unlock(original
,buf
,bufsize
,
1147 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock failed to unlock "
1151 rc
=IDirectSoundBuffer_QueryInterface(original
,
1152 &IID_IDirectSoundNotify
,
1154 ok(rc
==DS_OK
&& notify
!=NULL
,
1155 "IDirectSoundBuffer_QueryInterface() failed to create a "
1156 "notification %08x\n",rc
);
1157 if (rc
==DS_OK
&& notify
!=NULL
) {
1158 DSBPOSITIONNOTIFY dsbpn
;
1159 LPDIRECTSOUNDNOTIFY dup_notify
=NULL
;
1161 dsbpn
.dwOffset
=DSBPN_OFFSETSTOP
;
1162 dsbpn
.hEventNotify
=event
[0];
1163 rc
=IDirectSoundNotify_SetNotificationPositions(notify
,
1165 ok(rc
==DS_OK
,"IDirectSoundNotify_SetNotificationPositions "
1166 "failed %08x\n",rc
);
1168 rc
=IDirectSound_DuplicateSoundBuffer(dso
,original
,&duplicated
);
1169 ok(rc
==DS_OK
&& duplicated
!=NULL
,
1170 "IDirectSound_DuplicateSoundBuffer failed %08x\n",rc
);
1172 trace("testing duplicated buffer without notifications.\n");
1173 test_notify(duplicated
,sizeof(event
)/sizeof(event
[0]),
1174 event
,WAIT_TIMEOUT
);
1176 rc
=IDirectSoundBuffer_QueryInterface(duplicated
,
1177 &IID_IDirectSoundNotify
,
1178 (void**)&dup_notify
);
1179 ok(rc
==DS_OK
&&dup_notify
!=NULL
,
1180 "IDirectSoundBuffer_QueryInterface() failed to create a "
1181 "notification %08x\n",rc
);
1182 if(rc
==DS_OK
&&dup_notify
!=NULL
) {
1183 dsbpn
.dwOffset
=DSBPN_OFFSETSTOP
;
1184 dsbpn
.hEventNotify
=event
[1];
1185 rc
=IDirectSoundNotify_SetNotificationPositions(dup_notify
,
1187 ok(rc
==DS_OK
,"IDirectSoundNotify_SetNotificationPositions "
1188 "failed %08x\n",rc
);
1190 trace("testing duplicated buffer with a notification.\n");
1191 test_notify(duplicated
,sizeof(event
)/sizeof(event
[0]),
1192 event
,WAIT_OBJECT_0
+1);
1194 ref
=IDirectSoundNotify_Release(dup_notify
);
1195 ok(ref
==0,"IDirectSoundNotify_Release() has %d references, "
1196 "should have 0\n",ref
);
1198 ref
=IDirectSoundNotify_Release(notify
);
1199 ok(ref
==0,"IDirectSoundNotify_Release() has %d references, "
1200 "should have 0\n",ref
);
1202 trace("testing original buffer with a notification.\n");
1203 test_notify(original
,sizeof(event
)/sizeof(event
[0]),
1204 event
,WAIT_OBJECT_0
);
1206 ref
=IDirectSoundBuffer_Release(duplicated
);
1207 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
1208 "should have 0\n",ref
);
1210 ref
=IDirectSoundBuffer_Release(original
);
1211 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
1212 "should have 0\n",ref
);
1214 ref
=IDirectSoundBuffer_Release(primary
);
1215 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
1216 "should have 0\n",ref
);
1219 /* Set the CooperativeLevel back to normal */
1220 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1221 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1222 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
1225 ref
=IDirectSound_Release(dso
);
1226 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1228 return DSERR_GENERIC
;
1233 static HRESULT
test_invalid_fmts(LPGUID lpGuid
)
1236 LPDIRECTSOUND dso
=NULL
;
1237 LPDIRECTSOUNDBUFFER primary
=NULL
;
1238 DSBUFFERDESC bufdesc
;
1240 /* Create the DirectSound object */
1241 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1242 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
1243 "DirectSoundCreate() failed: %08x\n",rc
);
1247 /* We must call SetCooperativeLevel before creating primary buffer */
1248 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1249 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1250 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc
);
1252 IDirectSound_Release(dso
);
1256 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1257 bufdesc
.dwSize
=sizeof(bufdesc
);
1258 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1259 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1260 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1261 "to create a primary buffer %08x\n",rc
);
1263 if (rc
==DS_OK
&& primary
!=NULL
) {
1265 WAVEFORMATEXTENSIBLE fmtex
;
1267 wfx
.wFormatTag
= WAVE_FORMAT_PCM
;
1269 wfx
.nSamplesPerSec
= 44100;
1270 wfx
.wBitsPerSample
= 16;
1271 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1272 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1273 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1274 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1277 wfx
.nSamplesPerSec
= 44100;
1278 wfx
.wBitsPerSample
= 0;
1279 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1280 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1281 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1282 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1285 wfx
.nSamplesPerSec
= 44100;
1286 wfx
.wBitsPerSample
= 2;
1287 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1288 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1289 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1290 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1293 wfx
.nSamplesPerSec
= 44100;
1294 wfx
.wBitsPerSample
= 12;
1295 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1296 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1297 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1298 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1301 wfx
.nSamplesPerSec
= 0;
1302 wfx
.wBitsPerSample
= 16;
1303 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1304 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1305 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1306 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1309 wfx
.nSamplesPerSec
= 44100;
1310 wfx
.wBitsPerSample
= 16;
1311 wfx
.nBlockAlign
= 0;
1312 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1313 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1314 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1317 wfx
.nSamplesPerSec
= 44100;
1318 wfx
.wBitsPerSample
= 16;
1319 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1320 wfx
.nAvgBytesPerSec
= 0;
1321 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1322 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1325 wfx
.nSamplesPerSec
= 44100;
1326 wfx
.wBitsPerSample
= 16;
1327 wfx
.nBlockAlign
= (wfx
.nChannels
* wfx
.wBitsPerSample
/ 8) - 1;
1328 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1329 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1330 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1333 wfx
.nSamplesPerSec
= 44100;
1334 wfx
.wBitsPerSample
= 16;
1335 wfx
.nBlockAlign
= (wfx
.nChannels
* wfx
.wBitsPerSample
/ 8) + 1;
1336 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
;
1337 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1338 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1341 wfx
.nSamplesPerSec
= 44100;
1342 wfx
.wBitsPerSample
= 16;
1343 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1344 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
+ 1;
1345 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1346 ok(rc
== S_OK
, "SetFormat: %08x\n", rc
);
1349 wfx
.nSamplesPerSec
= 44100;
1350 wfx
.wBitsPerSample
= 16;
1351 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1352 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
- 1;
1353 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1354 ok(rc
== S_OK
, "SetFormat: %08x\n", rc
);
1357 wfx
.nSamplesPerSec
= 44100;
1358 wfx
.wBitsPerSample
= 16;
1359 wfx
.nBlockAlign
= wfx
.nChannels
* wfx
.wBitsPerSample
/ 8;
1360 wfx
.nAvgBytesPerSec
= wfx
.nSamplesPerSec
* wfx
.nBlockAlign
+ 1;
1361 rc
= IDirectSoundBuffer_SetFormat(primary
, &wfx
);
1362 ok(rc
== S_OK
, "SetFormat: %08x\n", rc
);
1364 fmtex
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
1365 fmtex
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
1366 fmtex
.Format
.nChannels
= 2;
1367 fmtex
.Format
.nSamplesPerSec
= 44100;
1368 fmtex
.Format
.wBitsPerSample
= 16;
1369 fmtex
.Format
.nBlockAlign
= fmtex
.Format
.nChannels
* fmtex
.Format
.wBitsPerSample
/ 8;
1370 fmtex
.Format
.nAvgBytesPerSec
= fmtex
.Format
.nSamplesPerSec
* fmtex
.Format
.nBlockAlign
;
1371 fmtex
.Samples
.wValidBitsPerSample
= 0;
1372 fmtex
.dwChannelMask
= SPEAKER_FRONT_LEFT
| SPEAKER_FRONT_RIGHT
;
1373 fmtex
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
1374 rc
= IDirectSoundBuffer_SetFormat(primary
, (WAVEFORMATEX
*)&fmtex
);
1375 ok(rc
== S_OK
, "SetFormat: %08x\n", rc
);
1377 fmtex
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
1378 fmtex
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
1379 fmtex
.Format
.nChannels
= 2;
1380 fmtex
.Format
.nSamplesPerSec
= 44100;
1381 fmtex
.Format
.wBitsPerSample
= 24;
1382 fmtex
.Format
.nBlockAlign
= fmtex
.Format
.nChannels
* fmtex
.Format
.wBitsPerSample
/ 8;
1383 fmtex
.Format
.nAvgBytesPerSec
= fmtex
.Format
.nSamplesPerSec
* fmtex
.Format
.nBlockAlign
;
1384 fmtex
.Samples
.wValidBitsPerSample
= 20;
1385 fmtex
.dwChannelMask
= SPEAKER_FRONT_LEFT
| SPEAKER_FRONT_RIGHT
;
1386 fmtex
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
1387 rc
= IDirectSoundBuffer_SetFormat(primary
, (WAVEFORMATEX
*)&fmtex
);
1388 ok(rc
== S_OK
, "SetFormat: %08x\n", rc
);
1390 fmtex
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
1391 fmtex
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
1392 fmtex
.Format
.nChannels
= 2;
1393 fmtex
.Format
.nSamplesPerSec
= 44100;
1394 fmtex
.Format
.wBitsPerSample
= 24;
1395 fmtex
.Format
.nBlockAlign
= fmtex
.Format
.nChannels
* fmtex
.Format
.wBitsPerSample
/ 8;
1396 fmtex
.Format
.nAvgBytesPerSec
= fmtex
.Format
.nSamplesPerSec
* fmtex
.Format
.nBlockAlign
;
1397 fmtex
.Samples
.wValidBitsPerSample
= 32;
1398 fmtex
.dwChannelMask
= SPEAKER_FRONT_LEFT
| SPEAKER_FRONT_RIGHT
;
1399 fmtex
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
1400 rc
= IDirectSoundBuffer_SetFormat(primary
, (WAVEFORMATEX
*)&fmtex
);
1401 ok(rc
== E_INVALIDARG
, "SetFormat: %08x\n", rc
);
1403 IDirectSoundBuffer_Release(primary
);
1406 IDirectSound_Release(dso
);
1411 static unsigned int number
;
1413 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
1414 LPCSTR lpcstrModule
, LPVOID lpContext
)
1417 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
1419 /* Don't test the primary device */
1422 ok (!lpcstrModule
[0], "lpcstrModule(%s) != NULL\n", lpcstrModule
);
1426 rc
= test_dsound(lpGuid
);
1427 if (rc
== DSERR_NODRIVER
)
1428 trace(" No Driver\n");
1429 else if (rc
== DSERR_ALLOCATED
)
1430 trace(" Already In Use\n");
1431 else if (rc
== E_FAIL
)
1432 trace(" No Device\n");
1434 test_block_align(lpGuid
);
1435 test_primary(lpGuid
);
1436 test_primary_secondary(lpGuid
);
1437 test_secondary(lpGuid
);
1438 test_frequency(lpGuid
);
1439 test_duplicate(lpGuid
);
1440 test_invalid_fmts(lpGuid
);
1446 static void dsound_tests(void)
1449 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
1450 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %08x\n",rc
);
1453 static void test_hw_buffers(void)
1456 IDirectSoundBuffer
*primary
, *primary2
, **secondaries
, *secondary
;
1457 IDirectSoundBuffer8
*buf8
;
1460 DSBUFFERDESC bufdesc
;
1465 hr
= pDirectSoundCreate(NULL
, &ds
, NULL
);
1466 ok(hr
== S_OK
|| hr
== DSERR_NODRIVER
|| hr
== DSERR_ALLOCATED
|| hr
== E_FAIL
,
1467 "DirectSoundCreate failed: %08x\n", hr
);
1471 caps
.dwSize
= sizeof(caps
);
1473 hr
= IDirectSound_GetCaps(ds
, &caps
);
1474 ok(hr
== S_OK
, "GetCaps failed: %08x\n", hr
);
1476 ok(caps
.dwPrimaryBuffers
== 1, "Got wrong number of primary buffers: %u\n",
1477 caps
.dwPrimaryBuffers
);
1479 /* DSBCAPS_LOC* is ignored for primary buffers */
1480 bufdesc
.dwSize
= sizeof(bufdesc
);
1481 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCHARDWARE
|
1482 DSBCAPS_PRIMARYBUFFER
;
1483 bufdesc
.dwBufferBytes
= 0;
1484 bufdesc
.dwReserved
= 0;
1485 bufdesc
.lpwfxFormat
= NULL
;
1486 bufdesc
.guid3DAlgorithm
= GUID_NULL
;
1488 hr
= IDirectSound_CreateSoundBuffer(ds
, &bufdesc
, &primary
, NULL
);
1489 ok(hr
== S_OK
, "CreateSoundBuffer failed: %08x\n", hr
);
1491 IDirectSound_Release(ds
);
1495 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCSOFTWARE
|
1496 DSBCAPS_PRIMARYBUFFER
;
1498 hr
= IDirectSound_CreateSoundBuffer(ds
, &bufdesc
, &primary2
, NULL
);
1499 ok(hr
== S_OK
, "CreateSoundBuffer failed: %08x\n", hr
);
1500 ok(primary
== primary2
, "Got different primary buffers: %p, %p\n", primary
, primary2
);
1502 IDirectSoundBuffer_Release(primary2
);
1504 buf8
= (IDirectSoundBuffer8
*)0xDEADBEEF;
1505 hr
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IDirectSoundBuffer8
,
1507 ok(hr
== E_NOINTERFACE
, "QueryInterface gave wrong failure: %08x\n", hr
);
1508 ok(buf8
== NULL
, "Pointer didn't get set to NULL\n");
1510 fmt
.wFormatTag
= WAVE_FORMAT_PCM
;
1512 fmt
.nSamplesPerSec
= 48000;
1513 fmt
.wBitsPerSample
= 16;
1514 fmt
.nBlockAlign
= fmt
.nChannels
* fmt
.wBitsPerSample
/ 8;
1515 fmt
.nAvgBytesPerSec
= fmt
.nBlockAlign
* fmt
.nSamplesPerSec
;
1518 bufdesc
.lpwfxFormat
= &fmt
;
1519 bufdesc
.dwBufferBytes
= fmt
.nSamplesPerSec
* fmt
.nBlockAlign
/ 10;
1520 bufdesc
.dwFlags
= DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_LOCHARDWARE
|
1523 secondaries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1524 sizeof(IDirectSoundBuffer
*) * caps
.dwMaxHwMixingAllBuffers
);
1526 /* try to fill all of the hw buffers */
1527 trace("dwMaxHwMixingAllBuffers: %u\n", caps
.dwMaxHwMixingAllBuffers
);
1528 trace("dwMaxHwMixingStaticBuffers: %u\n", caps
.dwMaxHwMixingStaticBuffers
);
1529 trace("dwMaxHwMixingStreamingBuffers: %u\n", caps
.dwMaxHwMixingStreamingBuffers
);
1530 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
){
1531 hr
= IDirectSound_CreateSoundBuffer(ds
, &bufdesc
, &secondaries
[i
], NULL
);
1532 ok(hr
== S_OK
|| hr
== E_NOTIMPL
|| broken(hr
== DSERR_CONTROLUNAVAIL
),
1533 "CreateSoundBuffer(%u) failed: %08x\n", i
, hr
);
1537 bufcaps
.dwSize
= sizeof(bufcaps
);
1538 hr
= IDirectSoundBuffer_GetCaps(secondaries
[i
], &bufcaps
);
1539 ok(hr
== S_OK
, "GetCaps failed: %08x\n", hr
);
1540 ok((bufcaps
.dwFlags
& DSBCAPS_LOCHARDWARE
) != 0,
1541 "Buffer wasn't allocated in hardware, dwFlags: %x\n", bufcaps
.dwFlags
);
1544 /* see if we can create one more */
1545 hr
= IDirectSound_CreateSoundBuffer(ds
, &bufdesc
, &secondary
, NULL
);
1546 ok((i
== caps
.dwMaxHwMixingAllBuffers
&& hr
== DSERR_ALLOCATED
) || /* out of hw buffers */
1547 (caps
.dwMaxHwMixingAllBuffers
== 0 && hr
== DSERR_INVALIDCALL
) || /* no hw buffers at all */
1548 hr
== E_NOTIMPL
|| /* don't support hw buffers */
1549 broken(hr
== DSERR_CONTROLUNAVAIL
) || /* vmware winxp, others? */
1550 broken(hr
== S_OK
) /* broken driver allows more hw bufs than dscaps claims */,
1551 "CreateSoundBuffer gave wrong error: %08x\n", hr
);
1553 IDirectSoundBuffer_Release(secondary
);
1555 for(i
= 0; i
< caps
.dwMaxHwMixingAllBuffers
; ++i
)
1557 IDirectSoundBuffer_Release(secondaries
[i
]);
1559 IDirectSoundBuffer_Release(primary
);
1560 IDirectSound_Release(ds
);
1569 hDsound
= LoadLibrary("dsound.dll");
1574 ret
= FreeLibrary(hDsound
);
1575 ok( ret
, "FreeLibrary(1) returned %d\n", GetLastError());
1576 SetLastError(0xdeadbeef);
1577 ret
= FreeLibrary(hDsound
);
1579 broken(!ret
&& GetLastError() == ERROR_MOD_NOT_FOUND
), /* NT4 */
1580 "FreeLibrary(2) returned %d\n", GetLastError());
1581 ok(!FreeLibrary(hDsound
), "DirectSound DLL still loaded\n");
1584 hDsound
= LoadLibrary("dsound.dll");
1588 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1589 "DirectSoundEnumerateA");
1590 pDirectSoundCreate
= (void*)GetProcAddress(hDsound
,
1591 "DirectSoundCreate");
1593 gotdx8
= !!GetProcAddress(hDsound
, "DirectSoundCreate8");
1595 IDirectSound_tests();
1599 FreeLibrary(hDsound
);
1602 win_skip("dsound.dll not found!\n");