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
||rc
==DSERR_ALLOCATED
,
98 "IDirectSound_Initialize() failed: %s\n",DXGetErrorString8(rc
));
99 if (rc
==DSERR_NODRIVER
) {
100 trace(" No Driver\n");
102 } else if (rc
==DSERR_ALLOCATED
) {
103 trace(" Already Allocated\n");
108 /* DSOUND: Error: Invalid caps buffer */
109 rc
=IDirectSound_GetCaps(dso
,0);
110 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps(NULL) "
111 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
112 DXGetErrorString8(rc
));
114 ZeroMemory(&dscaps
, sizeof(dscaps
));
116 /* DSOUND: Error: Invalid caps buffer */
117 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
118 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetCaps() "
119 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
120 DXGetErrorString8(rc
));
122 dscaps
.dwSize
=sizeof(dscaps
);
124 /* DSOUND: Running on a certified driver */
125 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
126 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
128 rc
=IDirectSound_Compact(dso
);
129 ok(rc
==DSERR_PRIOLEVELNEEDED
,"IDirectSound_Compact() failed: %s\n",
130 DXGetErrorString8(rc
));
132 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
133 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
134 DXGetErrorString8(rc
));
136 rc
=IDirectSound_Compact(dso
);
137 ok(rc
==DS_OK
,"IDirectSound_Compact() failed: %s\n",DXGetErrorString8(rc
));
139 rc
=IDirectSound_GetSpeakerConfig(dso
,0);
140 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_GetSpeakerConfig(NULL) "
141 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
142 DXGetErrorString8(rc
));
144 rc
=IDirectSound_GetSpeakerConfig(dso
,&speaker_config
);
145 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %s\n",
146 DXGetErrorString8(rc
));
148 speaker_config
= DSSPEAKER_COMBINED(DSSPEAKER_STEREO
,
149 DSSPEAKER_GEOMETRY_WIDE
);
150 rc
=IDirectSound_SetSpeakerConfig(dso
,speaker_config
);
151 ok(rc
==DS_OK
,"IDirectSound_SetSpeakerConfig() failed: %s\n",
152 DXGetErrorString8(rc
));
154 rc
=IDirectSound_GetSpeakerConfig(dso
,&new_speaker_config
);
155 ok(rc
==DS_OK
,"IDirectSound_GetSpeakerConfig() failed: %s\n",
156 DXGetErrorString8(rc
));
157 if (rc
==DS_OK
&& speaker_config
!=new_speaker_config
)
158 trace("IDirectSound_GetSpeakerConfig() failed to set speaker "
159 "config: expected 0x%08lx, got 0x%08lx\n",
160 speaker_config
,new_speaker_config
);
163 ref
=IDirectSound_Release(dso
);
164 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
167 static void IDirectSound_tests()
170 LPDIRECTSOUND dso
=NULL
;
172 trace("Testing IDirectSound\n");
174 /* try the COM class factory method of creation with no device specified */
175 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
176 &IID_IDirectSound
, (void**)&dso
);
177 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
178 DXGetErrorString8(rc
));
180 IDirectSound_test(dso
, FALSE
, NULL
);
182 /* try the COM class factory method of creation with default playback
183 * device specified */
184 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
185 &IID_IDirectSound
, (void**)&dso
);
186 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
187 DXGetErrorString8(rc
));
189 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultPlayback
);
191 /* try the COM class factory method of creation with default voice
192 * playback device specified */
193 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
194 &IID_IDirectSound
, (void**)&dso
);
195 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
196 DXGetErrorString8(rc
));
198 IDirectSound_test(dso
, FALSE
, &DSDEVID_DefaultVoicePlayback
);
200 /* try the COM class factory method of creation with a bad
202 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
203 &CLSID_DirectSoundPrivate
, (void**)&dso
);
204 ok(rc
==E_NOINTERFACE
,
205 "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) "
206 "should have failed: %s\n",DXGetErrorString8(rc
));
208 /* try the COM class factory method of creation with a bad
209 * GUID and IID specified */
210 rc
=CoCreateInstance(&CLSID_DirectSoundPrivate
, NULL
, CLSCTX_INPROC_SERVER
,
211 &IID_IDirectSound
, (void**)&dso
);
212 ok(rc
==REGDB_E_CLASSNOTREG
,
213 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) "
214 "should have failed: %s\n",DXGetErrorString8(rc
));
216 /* try with no device specified */
217 rc
=DirectSoundCreate(NULL
,&dso
,NULL
);
218 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
219 "DirectSoundCreate(NULL) failed: %s\n",DXGetErrorString8(rc
));
221 IDirectSound_test(dso
, TRUE
, NULL
);
223 /* try with default playback device specified */
224 rc
=DirectSoundCreate(&DSDEVID_DefaultPlayback
,&dso
,NULL
);
225 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
226 "DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %s\n",
227 DXGetErrorString8(rc
));
228 if (rc
==DS_OK
&& dso
)
229 IDirectSound_test(dso
, TRUE
, NULL
);
231 /* try with default voice playback device specified */
232 rc
=DirectSoundCreate(&DSDEVID_DefaultVoicePlayback
,&dso
,NULL
);
233 ok(rc
==S_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
234 "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %s\n",
235 DXGetErrorString8(rc
));
236 if (rc
==DS_OK
&& dso
)
237 IDirectSound_test(dso
, TRUE
, NULL
);
239 /* try with a bad device specified */
240 rc
=DirectSoundCreate(&DSDEVID_DefaultVoiceCapture
,&dso
,NULL
);
241 ok(rc
==DSERR_NODRIVER
,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) "
242 "should have failed: %s\n",DXGetErrorString8(rc
));
245 static HRESULT
test_dsound(LPGUID lpGuid
)
248 LPDIRECTSOUND dso
=NULL
;
251 /* DSOUND: Error: Invalid interface buffer */
252 rc
=DirectSoundCreate(lpGuid
,0,NULL
);
253 ok(rc
==DSERR_INVALIDPARAM
,"DirectSoundCreate() should have returned "
254 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
256 /* Create the DirectSound object */
257 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
258 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
259 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
263 /* Try the enumerated device */
264 IDirectSound_test(dso
, TRUE
, lpGuid
);
266 /* Try the COM class factory method of creation with enumerated device */
267 rc
=CoCreateInstance(&CLSID_DirectSound
, NULL
, CLSCTX_INPROC_SERVER
,
268 &IID_IDirectSound
, (void**)&dso
);
269 ok(rc
==S_OK
,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
270 DXGetErrorString8(rc
));
272 IDirectSound_test(dso
, FALSE
, lpGuid
);
274 /* Create a DirectSound object */
275 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
276 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
278 LPDIRECTSOUND dso1
=NULL
;
280 /* Create a second DirectSound object */
281 rc
=DirectSoundCreate(lpGuid
,&dso1
,NULL
);
282 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
284 /* Release the second DirectSound object */
285 ref
=IDirectSound_Release(dso1
);
286 ok(ref
==0,"IDirectSound_Release() has %d references, should have "
288 ok(dso
!=dso1
,"DirectSound objects should be unique: "
289 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD
)dso
,(DWORD
)dso1
);
292 /* Release the first DirectSound object */
293 ref
=IDirectSound_Release(dso
);
294 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
297 return DSERR_GENERIC
;
301 /* Create a DirectSound object */
302 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
303 ok(rc
==DS_OK
,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
305 LPDIRECTSOUNDBUFFER secondary
;
306 DSBUFFERDESC bufdesc
;
309 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,1);
310 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
311 bufdesc
.dwSize
=sizeof(bufdesc
);
312 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
| DSBCAPS_CTRL3D
;
313 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
314 bufdesc
.lpwfxFormat
=&wfx
;
315 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
316 ok(rc
==DS_OK
&& secondary
!=NULL
,
317 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
318 "buffer %s\n",DXGetErrorString8(rc
));
319 if (rc
==DS_OK
&& secondary
!=NULL
) {
320 LPDIRECTSOUND3DBUFFER buffer3d
;
321 rc
=IDirectSound_QueryInterface(secondary
, &IID_IDirectSound3DBuffer
,
323 ok(rc
==DS_OK
&& buffer3d
!=NULL
,"IDirectSound_QueryInterface() "
324 "failed: %s\n",DXGetErrorString8(rc
));
325 if (rc
==DS_OK
&& buffer3d
!=NULL
) {
326 ref
=IDirectSound3DBuffer_AddRef(buffer3d
);
327 ok(ref
==2,"IDirectSound3DBuffer_AddRef() has %d references, "
328 "should have 2\n",ref
);
330 ref
=IDirectSoundBuffer_AddRef(secondary
);
331 ok(ref
==2,"IDirectSoundBuffer_AddRef() has %d references, "
332 "should have 2\n",ref
);
334 /* release with buffer */
335 ref
=IDirectSound_Release(dso
);
336 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",
339 return DSERR_GENERIC
;
346 static HRESULT
test_primary(LPGUID lpGuid
)
349 LPDIRECTSOUND dso
=NULL
;
350 LPDIRECTSOUNDBUFFER primary
=NULL
,second
=NULL
,third
=NULL
;
351 DSBUFFERDESC bufdesc
;
356 /* Create the DirectSound object */
357 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
358 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
359 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
363 /* Get the device capabilities */
364 ZeroMemory(&dscaps
, sizeof(dscaps
));
365 dscaps
.dwSize
=sizeof(dscaps
);
366 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
367 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
371 /* DSOUND: Error: Invalid buffer description pointer */
372 rc
=IDirectSound_CreateSoundBuffer(dso
,0,0,NULL
);
373 ok(rc
==DSERR_INVALIDPARAM
,
374 "IDirectSound_CreateSoundBuffer() should have failed: %s\n",
375 DXGetErrorString8(rc
));
377 /* DSOUND: Error: Invalid buffer description pointer */
378 rc
=IDirectSound_CreateSoundBuffer(dso
,0,&primary
,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 /* DSOUND: Error: Invalid buffer description pointer */
384 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,0,NULL
);
385 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
386 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
387 "dsbo=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
389 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
391 /* DSOUND: Error: Invalid size */
392 /* DSOUND: Error: Invalid buffer description */
393 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
394 ok(rc
==DSERR_INVALIDPARAM
&& primary
==0,
395 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
396 "primary=0x%lx\n",DXGetErrorString8(rc
),(DWORD
)primary
);
398 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
399 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
400 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
401 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
402 DXGetErrorString8(rc
));
406 /* Testing the primary buffer */
408 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
409 bufdesc
.dwSize
=sizeof(bufdesc
);
410 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
411 bufdesc
.lpwfxFormat
= &wfx
;
412 init_format(&wfx
,WAVE_FORMAT_PCM
,11025,8,2);
413 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
414 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() should have "
415 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc
));
416 if (rc
==DS_OK
&& primary
!=NULL
)
417 IDirectSoundBuffer_Release(primary
);
420 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
421 bufdesc
.dwSize
=sizeof(bufdesc
);
422 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
;
423 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
424 ok(rc
==DS_OK
&& primary
!=NULL
,
425 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
426 "%s\n",DXGetErrorString8(rc
));
427 if (rc
==DS_OK
&& primary
!=NULL
) {
430 /* Try to create a second primary buffer */
431 /* DSOUND: Error: The primary buffer already exists.
432 * Any changes made to the buffer description will be ignored. */
433 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&second
,NULL
);
434 ok(rc
==DS_OK
&& second
==primary
,
435 "IDirectSound_CreateSoundBuffer() should have returned original "
436 "primary buffer: %s\n",DXGetErrorString8(rc
));
437 ref
=IDirectSoundBuffer_Release(second
);
438 ok(ref
==1,"IDirectSoundBuffer_Release() primary has %d references, "
439 "should have 1\n",ref
);
441 /* Try to duplicate a primary buffer */
442 /* DSOUND: Error: Can't duplicate primary buffers */
443 rc
=IDirectSound_DuplicateSoundBuffer(dso
,primary
,&third
);
445 ok(rc
!=DS_OK
,"IDirectSound_DuplicateSoundBuffer() primary buffer "
446 "should have failed %s\n",DXGetErrorString8(rc
));
448 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
449 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
450 DXGetErrorString8(rc
));
452 if (winetest_interactive
) {
453 trace("Playing a 5 seconds reference tone at the current "
456 trace("(the current volume is %ld according to DirectSound)\n",
458 trace("All subsequent tones should be identical to this one.\n");
459 trace("Listen for stutter, changes in pitch, volume, etc.\n");
461 test_buffer(dso
,primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
462 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),5.0,0,0,0,0);
464 ref
=IDirectSoundBuffer_Release(primary
);
465 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
466 "should have 0\n",ref
);
469 /* Set the CooperativeLevel back to normal */
470 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
471 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
472 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
473 DXGetErrorString8(rc
));
476 ref
=IDirectSound_Release(dso
);
477 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
479 return DSERR_GENERIC
;
485 * Test the primary buffer at different formats while keeping the
486 * secondary buffer at a constant format.
488 static HRESULT
test_primary_secondary(LPGUID lpGuid
)
491 LPDIRECTSOUND dso
=NULL
;
492 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
493 DSBUFFERDESC bufdesc
;
495 WAVEFORMATEX wfx
, wfx2
;
498 /* Create the DirectSound object */
499 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
500 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
501 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
505 /* Get the device capabilities */
506 ZeroMemory(&dscaps
, sizeof(dscaps
));
507 dscaps
.dwSize
=sizeof(dscaps
);
508 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
509 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
513 /* We must call SetCooperativeLevel before creating primary buffer */
514 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
515 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
516 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
517 DXGetErrorString8(rc
));
521 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
522 bufdesc
.dwSize
=sizeof(bufdesc
);
523 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
524 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
525 ok(rc
==DS_OK
&& primary
!=NULL
,
526 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
527 "%s\n",DXGetErrorString8(rc
));
529 if (rc
==DS_OK
&& primary
!=NULL
) {
530 for (f
=0;f
<NB_FORMATS
;f
++) {
531 /* We must call SetCooperativeLevel to be allowed to call
533 /* DSOUND: Setting DirectSound cooperative level to
535 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
536 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
537 DXGetErrorString8(rc
));
541 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
544 rc
=IDirectSoundBuffer_SetFormat(primary
,&wfx
);
545 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat() failed: %s\n",
546 DXGetErrorString8(rc
));
548 /* There is no garantee that SetFormat will actually change the
549 * format to what we asked for. It depends on what the soundcard
550 * supports. So we must re-query the format.
552 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx
,sizeof(wfx
),NULL
);
553 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
554 DXGetErrorString8(rc
));
556 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
557 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
558 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
559 wfx
.nChannels
!=wfx2
.nChannels
)) {
560 trace("Requested primary format tag=0x%04x %ldx%dx%d "
561 "avg.B/s=%ld align=%d\n",
562 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
563 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
564 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
565 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
566 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
569 /* Set the CooperativeLevel back to normal */
570 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
571 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
572 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
573 DXGetErrorString8(rc
));
575 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
578 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
579 bufdesc
.dwSize
=sizeof(bufdesc
);
580 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
581 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
582 bufdesc
.lpwfxFormat
=&wfx2
;
583 if (winetest_interactive
) {
584 trace(" Testing a primary buffer at %ldx%dx%d with a "
585 "secondary buffer at %ldx%dx%d\n",
586 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
587 wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,wfx2
.nChannels
);
589 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
590 ok(rc
==DS_OK
&& secondary
!=NULL
,
591 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
592 "buffer %s\n",DXGetErrorString8(rc
));
594 if (rc
==DS_OK
&& secondary
!=NULL
) {
595 test_buffer(dso
,secondary
,0,FALSE
,0,FALSE
,0,
596 winetest_interactive
,1.0,0,NULL
,0,0);
598 ref
=IDirectSoundBuffer_Release(secondary
);
599 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
600 "should have 0\n",ref
);
604 ref
=IDirectSoundBuffer_Release(primary
);
605 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
606 "should have 0\n",ref
);
609 /* Set the CooperativeLevel back to normal */
610 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
611 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
612 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
613 DXGetErrorString8(rc
));
616 ref
=IDirectSound_Release(dso
);
617 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
619 return DSERR_GENERIC
;
624 static HRESULT
test_secondary(LPGUID lpGuid
)
627 LPDIRECTSOUND dso
=NULL
;
628 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
629 DSBUFFERDESC bufdesc
;
635 /* Create the DirectSound object */
636 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
637 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
,
638 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
642 /* Get the device capabilities */
643 ZeroMemory(&dscaps
, sizeof(dscaps
));
644 dscaps
.dwSize
=sizeof(dscaps
);
645 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
646 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
650 /* We must call SetCooperativeLevel before creating primary buffer */
651 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
652 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
653 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
654 DXGetErrorString8(rc
));
658 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
659 bufdesc
.dwSize
=sizeof(bufdesc
);
660 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
661 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
662 ok(rc
==DS_OK
&& primary
!=NULL
,
663 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
664 "%s\n",DXGetErrorString8(rc
));
666 if (rc
==DS_OK
&& primary
!=NULL
) {
667 for (f
=0;f
<NB_FORMATS
;f
++) {
668 init_format(&wfx
,WAVE_FORMAT_PCM
,formats
[f
][0],formats
[f
][1],
671 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
672 bufdesc
.dwSize
=sizeof(bufdesc
);
673 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
674 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
675 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
676 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound_CreateSoundBuffer() "
677 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
678 DXGetErrorString8(rc
));
679 if (rc
==DS_OK
&& secondary
!=NULL
)
680 IDirectSoundBuffer_Release(secondary
);
683 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
684 bufdesc
.dwSize
=sizeof(bufdesc
);
685 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
686 bufdesc
.dwBufferBytes
=wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000;
687 bufdesc
.lpwfxFormat
=&wfx
;
688 if (winetest_interactive
) {
689 trace(" Testing a secondary buffer at %ldx%dx%d\n",
690 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
);
692 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
693 ok(rc
==DS_OK
&& secondary
!=NULL
,
694 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
695 "buffer %s\n",DXGetErrorString8(rc
));
697 if (rc
==DS_OK
&& secondary
!=NULL
) {
698 test_buffer(dso
,secondary
,0,FALSE
,0,FALSE
,0,
699 winetest_interactive
,1.0,0,NULL
,0,0);
701 ref
=IDirectSoundBuffer_Release(secondary
);
702 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
703 "should have 0\n",ref
);
707 ref
=IDirectSoundBuffer_Release(primary
);
708 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
709 "should have 0\n",ref
);
712 /* Set the CooperativeLevel back to normal */
713 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
714 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
715 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel() failed: %s\n",
716 DXGetErrorString8(rc
));
719 ref
=IDirectSound_Release(dso
);
720 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
722 return DSERR_GENERIC
;
727 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
728 LPCSTR lpcstrModule
, LPVOID lpContext
)
731 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
732 rc
= test_dsound(lpGuid
);
733 if (rc
== DSERR_NODRIVER
)
734 trace(" No Driver\n");
735 else if (rc
== DSERR_ALLOCATED
)
736 trace(" Already In Use\n");
738 test_primary(lpGuid
);
739 test_primary_secondary(lpGuid
);
740 test_secondary(lpGuid
);
746 static void dsound_tests()
749 rc
=DirectSoundEnumerateA(&dsenum_callback
,NULL
);
750 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
757 IDirectSound_tests();