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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define NONAMELESSSTRUCT
29 #define NONAMELESSUNION
35 #include "wine/test.h"
42 #include "dsound_test.h"
44 static void IDirectSound_test(LPDIRECTSOUND dso
, BOOL initialized
,
53 DWORD speaker_config
, new_speaker_config
;
55 /* Try to Query for objects */
56 rc
=IDirectSound_QueryInterface(dso
,&IID_IUnknown
,(LPVOID
*)&unknown
);
57 ok(rc
==DS_OK
,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",
58 DXGetErrorString8(rc
));
60 IDirectSound_Release(unknown
);
62 rc
=IDirectSound_QueryInterface(dso
,&IID_IDirectSound
,(LPVOID
*)&ds
);
63 ok(rc
==DS_OK
,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",
64 DXGetErrorString8(rc
));
66 IDirectSound_Release(ds
);
68 rc
=IDirectSound_QueryInterface(dso
,&IID_IDirectSound8
,(LPVOID
*)&ds8
);
69 ok(rc
==E_NOINTERFACE
,"IDirectSound_QueryInterface(IID_IDirectSound8) "
70 "should have failed: %s\n",DXGetErrorString8(rc
));
72 IDirectSound8_Release(ds8
);
74 if (initialized
== FALSE
) {
75 /* try unitialized object */
76 rc
=IDirectSound_GetCaps(dso
,0);
77 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetCaps(NULL) "
78 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
79 DXGetErrorString8(rc
));
81 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
82 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetCaps() "
83 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
84 DXGetErrorString8(rc
));
86 rc
=IDirectSound_Compact(dso
);
87 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_Compact() "
88 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
89 DXGetErrorString8(rc
));
91 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
92 ok(rc
==DSERR_UNINITIALIZED
,"IDirectSound_GetSpeakerConfig() "
93 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
94 DXGetErrorString8(rc
));
96 rc
=IDirectSound_Initialize(dso
,lpGuid
);
97 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"IDirectSound_Initialize() failed: %s\n",
98 DXGetErrorString8(rc
));
99 if (rc
==DSERR_NODRIVER
)
103 /* DSOUND: Error: Invalid caps buffer */
104 rc
=IDirectSound_GetCaps(dso
,0);
105 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps(NULL) "
106 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
107 DXGetErrorString8(rc
));
109 ZeroMemory(&dscaps
, sizeof(dscaps
));
111 /* DSOUND: Error: Invalid caps buffer */
112 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
113 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps() "
114 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
115 DXGetErrorString8(rc
));
117 dscaps
.dwSize
=sizeof(dscaps
);
119 /* DSOUND: Running on a certified driver */
120 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
121 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
123 rc
=IDirectSound_Compact(dso
);
124 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound_Compact() failed: %s\n",
125 DXGetErrorString8(rc
));
127 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
128 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
129 DXGetErrorString8(rc
));
131 rc
=IDirectSound_Compact(dso
);
132 ok(rc
==DS_OK
,"IDirectSound_Compact() failed: %s\n",DXGetErrorString8(rc
));
134 rc
=IDirectSound_GetSpeakerConfig(dso
,0);
135 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetSpeakerConfig(NULL) "
136 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
137 DXGetErrorString8(rc
));
139 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
140 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %s\n",
141 DXGetErrorString8(rc
));
143 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
144 DSSPEAKER_GEOMETRY_WIDE
);
145 rc
=IDirectSound_SetSpeakerConfig(dso
,speaker_config
);
146 ok(rc
==DS_OK
,"IDirectSound_SetSpeakerConfig() failed: %s\n",
147 DXGetErrorString8(rc
));
149 rc
=IDirectSound_GetSpeakerConfig(dso
,&new_speaker_config
);
150 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %s\n",
151 DXGetErrorString8(rc
));
152 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
153 trace("IDirectSound_GetSpeakerConfig() failed to set speaker "
154 "config: expected 0x%08lx, got 0x%08lx\n",
155 speaker_config
,new_speaker_config
);
158 ref
=IDirectSound_Release(dso
);
159 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
162 static void IDirectSound_tests()
165 LPDIRECTSOUND dso
=NULL
;
167 trace("Testing IDirectSound\n");
169 /* try the COM class factory method of creation with no device specified */
170 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
171 &IID_IDirectSound
, (void**)&dso
);
172 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
173 DXGetErrorString8(rc
));
175 IDirectSound_test(dso
, FALSE
, NULL
);
177 /* try the COM class factory method of creation with default playback
178 * device specified */
179 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
180 &IID_IDirectSound
, (void**)&dso
);
181 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
182 DXGetErrorString8(rc
));
184 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
186 /* try the COM class factory method of creation with default voice
187 * playback device specified */
188 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
189 &IID_IDirectSound
, (void**)&dso
);
190 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
191 DXGetErrorString8(rc
));
193 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
195 /* try the COM class factory method of creation with a bad
197 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
198 &CLSID_DirectSoundPrivate
, (void**)&dso
);
199 ok(rc
==E_NOINTERFACE
,
200 "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) "
201 "should have failed: %s\n",DXGetErrorString8(rc
));
203 /* try the COM class factory method of creation with a bad
204 * GUID and IID specified */
205 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
206 &IID_IDirectSound
, (void**)&dso
);
207 ok(rc
==REGDB_E_CLASSNOTREG
,
208 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) "
209 "should have failed: %s\n",DXGetErrorString8(rc
));
211 /* try with no device specified */
212 rc
=DirectSoundCreate(NULL
,&dso
,NULL
);
213 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate(NULL) failed: %s\n",
214 DXGetErrorString8(rc
));
216 IDirectSound_test(dso
, TRUE
, NULL
);
218 /* try with default playback device specified */
219 rc
=DirectSoundCreate(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
220 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate(DSDEVID_DefaultPlayback)"
221 " failed: %s\n", DXGetErrorString8(rc
));
222 if (rc
==DS_OK
&& dso
)
223 IDirectSound_test(dso
, TRUE
, NULL
);
225 /* try with default voice playback device specified */
226 rc
=DirectSoundCreate(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
227 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
,
228 "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %s\n",
229 DXGetErrorString8(rc
));
230 if (rc
==DS_OK
&& dso
)
231 IDirectSound_test(dso
, TRUE
, NULL
);
233 /* try with a bad device specified */
234 rc
=DirectSoundCreate(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
235 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) "
236 "should have failed: %s\n",DXGetErrorString8(rc
));
239 static HRESULT
test_dsound(LPGUID lpGuid
)
242 LPDIRECTSOUND dso
=NULL
;
245 /* DSOUND: Error: Invalid interface buffer */
246 rc
=DirectSoundCreate(lpGuid
,0,NULL
);
247 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate() should have returned "
248 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
250 /* Create the DirectSound object */
251 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
252 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
253 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
257 /* Try the enumerated device */
258 IDirectSound_test(dso
, TRUE
, lpGuid
);
260 /* Try the COM class factory method of creation with enumerated device */
261 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
262 &IID_IDirectSound
, (void**)&dso
);
263 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
264 DXGetErrorString8(rc
));
266 IDirectSound_test(dso
, FALSE
, lpGuid
);
268 /* Create a DirectSound object */
269 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
270 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
272 LPDIRECTSOUND dso1
=NULL
;
274 /* Create a second DirectSound object */
275 rc
=DirectSoundCreate(lpGuid
,&dso1
,NULL
);
276 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
278 /* Release the second DirectSound object */
279 ref
=IDirectSound_Release(dso1
);
280 ok(ref
==0,"IDirectSound_Release() has %d references, should have "
282 ok(dso
!=dso1
,"DirectSound objects should be unique: "
283 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD
)dso
,(DWORD
)dso1
);
286 /* Release the first DirectSound object */
287 ref
=IDirectSound_Release(dso
);
288 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
291 return DSERR_GENERIC
;
295 /* Create a DirectSound object */
296 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
297 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
299 LPDIRECTSOUNDBUFFER secondary
;
300 DSBUFFERDESC bufdesc
;
303 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
304 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
305 bufdesc
.dwSize
=sizeof(bufdesc
);
306 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
307 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
308 bufdesc
.lpwfxFormat
=&wfx
;
309 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
310 ok(rc
==DS_OK
&& secondary
!=NULL
,
311 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
312 "buffer %s\n",DXGetErrorString8(rc
));
313 if (rc
==DS_OK
&& secondary
!=NULL
) {
314 LPDIRECTSOUND3DBUFFER buffer3d
;
315 rc
=IDirectSound_QueryInterface(secondary
, &IID_IDirectSound3DBuffer
,
317 ok(rc
==DS_OK
&& buffer3d
!=NULL
,"IDirectSound_QueryInterface() "
318 "failed: %s\n",DXGetErrorString8(rc
));
319 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
320 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
321 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
322 "should have 2\n",ref
);
324 ref
=IDirectSoundBuffer_AddRef(secondary
);
325 ok(ref
==2,"IDirectSoundBuffer_AddRef() has %d references, "
326 "should have 2\n",ref
);
328 /* release with buffer */
329 ref
=IDirectSound_Release(dso
);
330 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
333 return DSERR_GENERIC
;
340 static HRESULT
test_primary(LPGUID lpGuid
)
343 LPDIRECTSOUND dso
=NULL
;
344 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
345 DSBUFFERDESC bufdesc
;
350 /* Create the DirectSound object */
351 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
352 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
353 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
357 /* Get the device capabilities */
358 ZeroMemory(&dscaps
, sizeof(dscaps
));
359 dscaps
.dwSize
=sizeof(dscaps
);
360 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
361 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
365 /* DSOUND: Error: Invalid buffer description pointer */
366 rc
=IDirectSound_CreateSoundBuffer(dso
,0,0,NULL
);
367 ok(rc
==DSERR_INVALIDPARAM
,
368 "IDirectSound_CreateSoundBuffer() should have failed: %s\n",
369 DXGetErrorString8(rc
));
371 /* DSOUND: Error: Invalid buffer description pointer */
372 rc
=IDirectSound_CreateSoundBuffer(dso
,0,&primary
,NULL
);
373 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
374 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
375 "dsbo=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
377 /* DSOUND: Error: Invalid buffer description pointer */
378 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
379 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
380 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
381 "dsbo=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
383 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
385 /* DSOUND: Error: Invalid size */
386 /* DSOUND: Error: Invalid buffer description */
387 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
388 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
389 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
390 "primary=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
392 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
393 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
394 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
395 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
396 DXGetErrorString8(rc
));
400 /* Testing the primary buffer */
402 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
403 bufdesc
.dwSize
=sizeof(bufdesc
);
404 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
405 bufdesc
.lpwfxFormat
= &wfx
;
406 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
407 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
408 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() should have "
409 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc
));
410 if (rc
==DS_OK
&& primary
!=NULL
)
411 IDirectSoundBuffer_Release(primary
);
414 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
415 bufdesc
.dwSize
=sizeof(bufdesc
);
416 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
417 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
418 ok(rc
==DS_OK
&& primary
!=NULL
,
419 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
420 "%s\n",DXGetErrorString8(rc
));
421 if (rc
==DS_OK
&& primary
!=NULL
) {
424 /* Try to create a second primary buffer */
425 /* DSOUND: Error: The primary buffer already exists.
426 * Any changes made to the buffer description will be ignored. */
427 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
428 ok(rc
==DS_OK
&& second
==primary
,
429 "IDirectSound_CreateSoundBuffer() should have returned original "
430 "primary buffer: %s\n",DXGetErrorString8(rc
));
431 ref
=IDirectSoundBuffer_Release(second
);
432 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
433 "should have 1\n",ref
);
435 /* Try to duplicate a primary buffer */
436 /* DSOUND: Error: Can't duplicate primary buffers */
437 rc
=IDirectSound_DuplicateSoundBuffer(dso
,primary
,&third
);
439 ok(rc
!=DS_OK
,"IDirectSound_DuplicateSoundBuffer() primary buffer "
440 "should have failed %s\n",DXGetErrorString8(rc
));
442 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
443 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
444 DXGetErrorString8(rc
));
446 if (winetest_interactive
) {
447 trace("Playing a 5 seconds reference tone at the current "
450 trace("(the current volume is %ld according to DirectSound)\n",
452 trace("All subsequent tones should be identical to this one.\n");
453 trace("Listen for stutter, changes in pitch, volume, etc.\n");
455 test_buffer(dso
,primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
456 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
458 ref
=IDirectSoundBuffer_Release(primary
);
459 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
460 "should have 0\n",ref
);
463 /* Set the CooperativeLevel back to normal */
464 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
465 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
466 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
467 DXGetErrorString8(rc
));
470 ref
=IDirectSound_Release(dso
);
471 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
473 return DSERR_GENERIC
;
479 * Test the primary buffer at different formats while keeping the
480 * secondary buffer at a constant format.
482 static HRESULT
test_primary_secondary(LPGUID lpGuid
)
485 LPDIRECTSOUND dso
=NULL
;
486 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
487 DSBUFFERDESC bufdesc
;
489 WAVEFORMATEX wfx
, wfx2
;
492 /* Create the DirectSound object */
493 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
494 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
495 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
499 /* Get the device capabilities */
500 ZeroMemory(&dscaps
, sizeof(dscaps
));
501 dscaps
.dwSize
=sizeof(dscaps
);
502 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
503 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
507 /* We must call SetCooperativeLevel before creating primary buffer */
508 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
509 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
510 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
511 DXGetErrorString8(rc
));
515 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
516 bufdesc
.dwSize
=sizeof(bufdesc
);
517 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
518 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
519 ok(rc
==DS_OK
&& primary
!=NULL
,
520 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
521 "%s\n",DXGetErrorString8(rc
));
523 if (rc
==DS_OK
&& primary
!=NULL
) {
524 for (f
=0;f
<NB_FORMATS
;f
++) {
525 /* We must call SetCooperativeLevel to be allowed to call
527 /* DSOUND: Setting DirectSound cooperative level to
529 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
530 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
531 DXGetErrorString8(rc
));
535 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
538 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
539 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat() failed: %s\n",
540 DXGetErrorString8(rc
));
542 /* There is no garantee that SetFormat will actually change the
543 * format to what we asked for. It depends on what the soundcard
544 * supports. So we must re-query the format.
546 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
547 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
548 DXGetErrorString8(rc
));
550 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
551 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
552 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
553 wfx
.nChannels
!=wfx2
.nChannels
)) {
554 trace("Requested primary format tag=0x%04x %ldx%dx%d "
555 "avg.B/s=%ld align=%d\n",
556 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
557 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
558 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
559 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
560 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
563 /* Set the CooperativeLevel back to normal */
564 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
565 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
566 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
567 DXGetErrorString8(rc
));
569 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
572 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
573 bufdesc
.dwSize
=sizeof(bufdesc
);
574 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
575 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
576 bufdesc
.lpwfxFormat
=&wfx2
;
577 if (winetest_interactive
) {
578 trace(" Testing a primary buffer at %ldx%dx%d with a "
579 "secondary buffer at %ldx%dx%d\n",
580 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
581 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
583 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
584 ok(rc
==DS_OK
&& secondary
!=NULL
,
585 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
586 "buffer %s\n",DXGetErrorString8(rc
));
588 if (rc
==DS_OK
&& secondary
!=NULL
) {
589 test_buffer(dso
,secondary
,0,FALSE
,0,FALSE
,0,
590 winetest_interactive
,1.0,0,NULL
,0,0);
592 ref
=IDirectSoundBuffer_Release(secondary
);
593 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
594 "should have 0\n",ref
);
598 ref
=IDirectSoundBuffer_Release(primary
);
599 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
600 "should have 0\n",ref
);
603 /* Set the CooperativeLevel back to normal */
604 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
605 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
606 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
607 DXGetErrorString8(rc
));
610 ref
=IDirectSound_Release(dso
);
611 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
613 return DSERR_GENERIC
;
618 static HRESULT
test_secondary(LPGUID lpGuid
)
621 LPDIRECTSOUND dso
=NULL
;
622 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
623 DSBUFFERDESC bufdesc
;
629 /* Create the DirectSound object */
630 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
631 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
632 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
636 /* Get the device capabilities */
637 ZeroMemory(&dscaps
, sizeof(dscaps
));
638 dscaps
.dwSize
=sizeof(dscaps
);
639 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
640 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
644 /* We must call SetCooperativeLevel before creating primary buffer */
645 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
646 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
647 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
648 DXGetErrorString8(rc
));
652 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
653 bufdesc
.dwSize
=sizeof(bufdesc
);
654 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
655 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
656 ok(rc
==DS_OK
&& primary
!=NULL
,
657 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
658 "%s\n",DXGetErrorString8(rc
));
660 if (rc
==DS_OK
&& primary
!=NULL
) {
661 for (f
=0;f
<NB_FORMATS
;f
++) {
662 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
665 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
666 bufdesc
.dwSize
=sizeof(bufdesc
);
667 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
668 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
669 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
670 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() "
671 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
672 DXGetErrorString8(rc
));
673 if (rc
==DS_OK
&& secondary
!=NULL
)
674 IDirectSoundBuffer_Release(secondary
);
677 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
678 bufdesc
.dwSize
=sizeof(bufdesc
);
679 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
680 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
681 bufdesc
.lpwfxFormat
=&wfx
;
682 if (winetest_interactive
) {
683 trace(" Testing a secondary buffer at %ldx%dx%d\n",
684 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
);
686 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
687 ok(rc
==DS_OK
&& secondary
!=NULL
,
688 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
689 "buffer %s\n",DXGetErrorString8(rc
));
691 if (rc
==DS_OK
&& secondary
!=NULL
) {
692 test_buffer(dso
,secondary
,0,FALSE
,0,FALSE
,0,
693 winetest_interactive
,1.0,0,NULL
,0,0);
695 ref
=IDirectSoundBuffer_Release(secondary
);
696 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
697 "should have 0\n",ref
);
701 ref
=IDirectSoundBuffer_Release(primary
);
702 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
703 "should have 0\n",ref
);
706 /* Set the CooperativeLevel back to normal */
707 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
708 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
709 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
710 DXGetErrorString8(rc
));
713 ref
=IDirectSound_Release(dso
);
714 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
716 return DSERR_GENERIC
;
721 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
722 LPCSTR lpcstrModule
, LPVOID lpContext
)
725 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
726 rc
= test_dsound(lpGuid
);
727 if (rc
== DSERR_NODRIVER
)
728 trace(" No Driver\n");
729 else if (rc
== DSERR_ALLOCATED
)
730 trace(" Already In Use\n");
732 test_primary(lpGuid
);
733 test_primary_secondary(lpGuid
);
734 test_secondary(lpGuid
);
740 static void dsound_tests()
743 rc
=DirectSoundEnumerateA(&dsenum_callback
,NULL
);
744 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
751 IDirectSound_tests();