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
33 #include "wine/test.h"
38 #include "dsound_test.h"
40 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
42 int align(int length, int align)
44 return (length / align) * align;
47 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
56 DWORD speaker_config, new_speaker_config;
59 /* Try to Query for objects */
60 rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
61 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
62 DXGetErrorString8(rc));
64 IDirectSound8_Release(unknown);
66 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
67 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
68 DXGetErrorString8(rc));
70 IDirectSound_Release(ds);
72 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
73 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
74 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
75 DXGetErrorString8(rc));
77 IDirectSound8_Release(ds8);
79 if (initialized == FALSE) {
80 /* try unitialized object */
81 rc=IDirectSound8_GetCaps(dso,0);
82 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
83 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
84 DXGetErrorString8(rc));
86 rc=IDirectSound8_GetCaps(dso,&dscaps);
87 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
88 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
89 DXGetErrorString8(rc));
91 rc=IDirectSound8_Compact(dso);
92 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
93 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
94 DXGetErrorString8(rc));
96 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
97 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
98 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
99 DXGetErrorString8(rc));
101 rc=IDirectSound8_VerifyCertification(dso, &certified);
102 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
103 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
104 DXGetErrorString8(rc));
106 rc=IDirectSound8_Initialize(dso,lpGuid);
107 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
108 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
109 if (rc==DSERR_NODRIVER) {
110 trace(" No Driver\n");
112 } else if (rc==DSERR_ALLOCATED) {
113 trace(" Already In Use\n");
118 /* DSOUND: Error: Invalid caps buffer */
119 rc=IDirectSound8_GetCaps(dso,0);
120 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
121 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
122 DXGetErrorString8(rc));
124 ZeroMemory(&dscaps, sizeof(dscaps));
126 /* DSOUND: Error: Invalid caps buffer */
127 rc=IDirectSound8_GetCaps(dso,&dscaps);
128 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
129 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
130 DXGetErrorString8(rc));
132 dscaps.dwSize=sizeof(dscaps);
134 /* DSOUND: Running on a certified driver */
135 rc=IDirectSound8_GetCaps(dso,&dscaps);
136 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
138 rc=IDirectSound8_Compact(dso);
139 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
140 DXGetErrorString8(rc));
142 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
143 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
144 DXGetErrorString8(rc));
146 rc=IDirectSound8_Compact(dso);
147 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
149 rc=IDirectSound8_GetSpeakerConfig(dso,0);
150 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
151 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
152 DXGetErrorString8(rc));
154 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
155 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
156 DXGetErrorString8(rc));
158 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
159 DSSPEAKER_GEOMETRY_WIDE);
160 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
161 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
162 DXGetErrorString8(rc));
164 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
165 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
166 DXGetErrorString8(rc));
167 if (rc==DS_OK && speaker_config!=new_speaker_config)
168 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
169 "config: expected 0x%08lx, got 0x%08lx\n",
170 speaker_config,new_speaker_config);
173 rc=IDirectSound8_VerifyCertification(dso, &certified);
174 ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
175 DXGetErrorString8(rc));
177 ref=IDirectSound8_Release(dso);
178 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
181 static void IDirectSound8_tests()
184 LPDIRECTSOUND8 dso=NULL;
186 trace("Testing IDirectSound8\n");
188 /* try the COM class factory method of creation with no device specified */
189 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
190 &IID_IDirectSound8, (void**)&dso);
191 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
193 IDirectSound8_test(dso, FALSE, NULL);
195 /* try the COM class factory method of creation with default playback
196 * device specified */
197 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
198 &IID_IDirectSound8, (void**)&dso);
199 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
200 DXGetErrorString8(rc));
202 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
204 /* try the COM class factory method of creation with default voice
205 * playback device specified */
206 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
207 &IID_IDirectSound8, (void**)&dso);
208 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
209 DXGetErrorString8(rc));
211 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
213 /* try the COM class factory method of creation with a bad
215 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
216 &CLSID_DirectSoundPrivate, (void**)&dso);
217 ok(rc==E_NOINTERFACE,
218 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
219 "should have failed: %s\n",DXGetErrorString8(rc));
221 /* try the COM class factory method of creation with a bad
222 * GUID and IID specified */
223 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
224 &IID_IDirectSound8, (void**)&dso);
225 ok(rc==REGDB_E_CLASSNOTREG,
226 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
227 "should have failed: %s\n",DXGetErrorString8(rc));
229 /* try with no device specified */
230 rc=pDirectSoundCreate8(NULL,&dso,NULL);
231 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
232 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
233 if (rc==DS_OK && dso)
234 IDirectSound8_test(dso, TRUE, NULL);
236 /* try with default playback device specified */
237 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
238 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
239 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
240 if (rc==DS_OK && dso)
241 IDirectSound8_test(dso, TRUE, NULL);
243 /* try with default voice playback device specified */
244 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
245 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
246 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
247 if (rc==DS_OK && dso)
248 IDirectSound8_test(dso, TRUE, NULL);
250 /* try with a bad device specified */
251 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
252 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
253 "should have failed: %s\n",DXGetErrorString8(rc));
256 static HRESULT test_dsound8(LPGUID lpGuid)
259 LPDIRECTSOUND8 dso=NULL;
262 /* DSOUND: Error: Invalid interface buffer */
263 rc=pDirectSoundCreate8(lpGuid,0,NULL);
264 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
265 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
267 /* Create the DirectSound8 object */
268 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
269 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
270 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
274 /* Try the enumerated device */
275 IDirectSound8_test(dso, TRUE, lpGuid);
277 /* Try the COM class factory method of creation with enumerated device */
278 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
279 &IID_IDirectSound8, (void**)&dso);
280 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
281 DXGetErrorString8(rc));
283 IDirectSound8_test(dso, FALSE, lpGuid);
285 /* Create a DirectSound8 object */
286 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
287 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
289 LPDIRECTSOUND8 dso1=NULL;
291 /* Create a second DirectSound8 object */
292 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
293 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
295 /* Release the second DirectSound8 object */
296 ref=IDirectSound8_Release(dso1);
297 ok(ref==0,"IDirectSound8_Release() has %d references, "
298 "should have 0\n",ref);
299 ok(dso!=dso1,"DirectSound8 objects should be unique: "
300 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
303 /* Release the first DirectSound8 object */
304 ref=IDirectSound8_Release(dso);
305 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
308 return DSERR_GENERIC;
312 /* Create a DirectSound8 object */
313 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
314 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
316 LPDIRECTSOUNDBUFFER secondary;
317 DSBUFFERDESC bufdesc;
320 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
321 ZeroMemory(&bufdesc, sizeof(bufdesc));
322 bufdesc.dwSize=sizeof(bufdesc);
323 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
324 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
326 bufdesc.lpwfxFormat=&wfx;
327 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
328 ok(rc==DS_OK && secondary!=NULL,
329 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
330 "buffer: %s\n",DXGetErrorString8(rc));
331 if (rc==DS_OK && secondary!=NULL) {
332 LPDIRECTSOUND3DBUFFER buffer3d;
333 LPDIRECTSOUNDBUFFER8 buffer8;
334 rc=IDirectSound8_QueryInterface(secondary,
335 &IID_IDirectSound3DBuffer,
337 ok(rc==DS_OK && buffer3d!=NULL,
338 "IDirectSound8_QueryInterface() failed: %s\n",
339 DXGetErrorString8(rc));
340 if (rc==DS_OK && buffer3d!=NULL) {
341 ref=IDirectSound3DBuffer_AddRef(buffer3d);
342 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
343 "should have 2\n",ref);
345 rc=IDirectSound8_QueryInterface(secondary,
346 &IID_IDirectSoundBuffer8,
348 if (rc==DS_OK && buffer8!=NULL) {
349 ref=IDirectSoundBuffer8_AddRef(buffer8);
350 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
351 "should have 3\n",ref);
353 ref=IDirectSoundBuffer_AddRef(secondary);
354 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
355 "should have 4\n",ref);
357 /* release with buffer */
358 ref=IDirectSound8_Release(dso);
359 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
362 return DSERR_GENERIC;
369 static HRESULT test_primary8(LPGUID lpGuid)
372 LPDIRECTSOUND8 dso=NULL;
373 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
374 DSBUFFERDESC bufdesc;
379 /* Create the DirectSound object */
380 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
381 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
382 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
386 /* Get the device capabilities */
387 ZeroMemory(&dscaps, sizeof(dscaps));
388 dscaps.dwSize=sizeof(dscaps);
389 rc=IDirectSound8_GetCaps(dso,&dscaps);
390 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
394 /* DSOUND: Error: Invalid buffer description pointer */
395 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
396 ok(rc==DSERR_INVALIDPARAM,
397 "IDirectSound8_CreateSoundBuffer should have returned "
398 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
400 /* DSOUND: Error: Invalid buffer description pointer */
401 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
402 ok(rc==DSERR_INVALIDPARAM && primary==0,
403 "IDirectSound8_CreateSoundBuffer() should have returned "
404 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
405 DXGetErrorString8(rc),(DWORD)primary);
407 /* DSOUND: Error: Invalid buffer description pointer */
408 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
409 ok(rc==DSERR_INVALIDPARAM && primary==0,
410 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
411 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
413 ZeroMemory(&bufdesc, sizeof(bufdesc));
415 /* DSOUND: Error: Invalid size */
416 /* DSOUND: Error: Invalid buffer description */
417 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
418 ok(rc==DSERR_INVALIDPARAM && primary==0,
419 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
420 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
422 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
423 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
424 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
425 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
426 DXGetErrorString8(rc));
430 /* Testing the primary buffer */
432 ZeroMemory(&bufdesc, sizeof(bufdesc));
433 bufdesc.dwSize=sizeof(bufdesc);
434 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
435 bufdesc.lpwfxFormat = &wfx;
436 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
437 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
438 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
439 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
440 if (rc==DS_OK && primary!=NULL)
441 IDirectSoundBuffer_Release(primary);
444 ZeroMemory(&bufdesc, sizeof(bufdesc));
445 bufdesc.dwSize=sizeof(bufdesc);
446 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
447 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
448 ok(rc==DS_OK && primary!=NULL,
449 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
450 "%s\n",DXGetErrorString8(rc));
451 if (rc==DS_OK && primary!=NULL) {
454 /* Try to create a second primary buffer */
455 /* DSOUND: Error: The primary buffer already exists.
456 * Any changes made to the buffer description will be ignored. */
457 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
458 ok(rc==DS_OK && second==primary,
459 "IDirectSound8_CreateSoundBuffer() should have returned original "
460 "primary buffer: %s\n",DXGetErrorString8(rc));
461 ref=IDirectSoundBuffer_Release(second);
462 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
463 "should have 1\n",ref);
465 /* Try to duplicate a primary buffer */
466 /* DSOUND: Error: Can't duplicate primary buffers */
467 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
469 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
470 "should have failed %s\n",DXGetErrorString8(rc));
472 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
473 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
474 DXGetErrorString8(rc));
476 if (winetest_interactive) {
477 trace("Playing a 5 seconds reference tone at the current volume.\n");
479 trace("(the current volume is %ld according to DirectSound)\n",
481 trace("All subsequent tones should be identical to this one.\n");
482 trace("Listen for stutter, changes in pitch, volume, etc.\n");
484 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
485 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
487 ref=IDirectSoundBuffer_Release(primary);
488 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
489 "should have 0\n",ref);
492 /* Set the CooperativeLevel back to normal */
493 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
494 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
495 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
496 DXGetErrorString8(rc));
499 ref=IDirectSound8_Release(dso);
500 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
502 return DSERR_GENERIC;
508 * Test the primary buffer at different formats while keeping the
509 * secondary buffer at a constant format.
511 static HRESULT test_primary_secondary8(LPGUID lpGuid)
514 LPDIRECTSOUND8 dso=NULL;
515 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
516 DSBUFFERDESC bufdesc;
518 WAVEFORMATEX wfx, wfx2;
521 /* Create the DirectSound object */
522 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
523 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
524 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
528 /* Get the device capabilities */
529 ZeroMemory(&dscaps, sizeof(dscaps));
530 dscaps.dwSize=sizeof(dscaps);
531 rc=IDirectSound8_GetCaps(dso,&dscaps);
532 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
536 /* We must call SetCooperativeLevel before creating primary buffer */
537 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
538 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
539 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
540 DXGetErrorString8(rc));
544 ZeroMemory(&bufdesc, sizeof(bufdesc));
545 bufdesc.dwSize=sizeof(bufdesc);
546 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
547 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
548 ok(rc==DS_OK && primary!=NULL,
549 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
550 "%s\n",DXGetErrorString8(rc));
552 if (rc==DS_OK && primary!=NULL) {
553 for (f=0;f<NB_FORMATS;f++) {
554 /* We must call SetCooperativeLevel to be allowed to call
556 /* DSOUND: Setting DirectSound cooperative level to
558 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
559 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
560 DXGetErrorString8(rc));
564 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
567 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
568 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
569 DXGetErrorString8(rc));
571 /* There is no garantee that SetFormat will actually change the
572 * format to what we asked for. It depends on what the soundcard
573 * supports. So we must re-query the format.
575 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
576 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
577 DXGetErrorString8(rc));
579 (wfx.wFormatTag!=wfx2.wFormatTag ||
580 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
581 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
582 wfx.nChannels!=wfx2.nChannels)) {
583 trace("Requested primary format tag=0x%04x %ldx%dx%d "
584 "avg.B/s=%ld align=%d\n",
585 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
586 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
587 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
588 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
589 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
592 /* Set the CooperativeLevel back to normal */
593 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
594 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
595 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
596 DXGetErrorString8(rc));
598 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
601 ZeroMemory(&bufdesc, sizeof(bufdesc));
602 bufdesc.dwSize=sizeof(bufdesc);
603 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
604 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
606 bufdesc.lpwfxFormat=&wfx2;
607 if (winetest_interactive) {
608 trace(" Testing a primary buffer at %ldx%dx%d with a "
609 "secondary buffer at %ldx%dx%d\n",
610 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
611 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
613 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
614 ok(rc==DS_OK && secondary!=NULL,
615 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
616 "buffer %s\n",DXGetErrorString8(rc));
618 if (rc==DS_OK && secondary!=NULL) {
619 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
620 winetest_interactive,1.0,0,NULL,0,0);
622 ref=IDirectSoundBuffer_Release(secondary);
623 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
624 "should have 0\n",ref);
628 ref=IDirectSoundBuffer_Release(primary);
629 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
630 "should have 0\n",ref);
633 /* Set the CooperativeLevel back to normal */
634 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
635 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
636 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
637 DXGetErrorString8(rc));
640 ref=IDirectSound8_Release(dso);
641 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
643 return DSERR_GENERIC;
648 static HRESULT test_secondary8(LPGUID lpGuid)
651 LPDIRECTSOUND8 dso=NULL;
652 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
653 DSBUFFERDESC bufdesc;
655 WAVEFORMATEX wfx, wfx1;
659 /* Create the DirectSound object */
660 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
661 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
662 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
666 /* Get the device capabilities */
667 ZeroMemory(&dscaps, sizeof(dscaps));
668 dscaps.dwSize=sizeof(dscaps);
669 rc=IDirectSound8_GetCaps(dso,&dscaps);
670 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
674 /* We must call SetCooperativeLevel before creating primary buffer */
675 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
676 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
677 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
678 DXGetErrorString8(rc));
682 ZeroMemory(&bufdesc, sizeof(bufdesc));
683 bufdesc.dwSize=sizeof(bufdesc);
684 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
685 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
686 ok(rc==DS_OK && primary!=NULL,
687 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
688 "%s\n",DXGetErrorString8(rc));
690 if (rc==DS_OK && primary!=NULL) {
691 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
692 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
693 DXGetErrorString8(rc));
697 for (f=0;f<NB_FORMATS;f++) {
698 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
701 ZeroMemory(&bufdesc, sizeof(bufdesc));
702 bufdesc.dwSize=sizeof(bufdesc);
703 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
704 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
706 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
707 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
708 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
709 DXGetErrorString8(rc));
710 if (rc==DS_OK && secondary!=NULL)
711 IDirectSoundBuffer_Release(secondary);
714 ZeroMemory(&bufdesc, sizeof(bufdesc));
715 bufdesc.dwSize=sizeof(bufdesc);
716 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
717 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
719 bufdesc.lpwfxFormat=&wfx;
720 if (winetest_interactive) {
721 trace(" Testing a secondary buffer at %ldx%dx%d "
722 "with a primary buffer at %ldx%dx%d\n",
723 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
724 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
726 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
727 ok(rc==DS_OK && secondary!=NULL,
728 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
729 "buffer: %s\n",DXGetErrorString8(rc));
731 if (rc==DS_OK && secondary!=NULL) {
732 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
733 winetest_interactive,1.0,0,NULL,0,0);
735 ref=IDirectSoundBuffer_Release(secondary);
736 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
737 "should have 0\n",ref);
741 ref=IDirectSoundBuffer_Release(primary);
742 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
743 "should have 0\n",ref);
746 /* Set the CooperativeLevel back to normal */
747 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
748 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
749 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
750 DXGetErrorString8(rc));
753 ref=IDirectSound8_Release(dso);
754 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
756 return DSERR_GENERIC;
761 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
762 LPCSTR lpcstrModule, LPVOID lpContext)
765 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
766 rc = test_dsound8(lpGuid);
767 if (rc == DSERR_NODRIVER)
768 trace(" No Driver\n");
769 else if (rc == DSERR_ALLOCATED)
770 trace(" Already In Use\n");
771 else if (rc == E_FAIL)
772 trace(" No Device\n");
774 test_primary8(lpGuid);
775 test_primary_secondary8(lpGuid);
776 test_secondary8(lpGuid);
782 static void dsound8_tests()
785 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
786 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
789 const char * get_file_version(const char * file_name)
791 static char version[32];
795 size = GetFileVersionInfoSizeA("dsound.dll", &handle);
797 char * data = HeapAlloc(GetProcessHeap(), 0, size);
799 if (GetFileVersionInfoA("dsound.dll", handle, size, data)) {
800 VS_FIXEDFILEINFO *pFixedVersionInfo;
802 if (VerQueryValueA(data, "\\", (LPLPVOID)&pFixedVersionInfo, &len)) {
803 sprintf(version, "%ld.%ld.%ld.%ld",
804 pFixedVersionInfo->dwFileVersionMS >> 16,
805 pFixedVersionInfo->dwFileVersionMS & 0xffff,
806 pFixedVersionInfo->dwFileVersionLS >> 16,
807 pFixedVersionInfo->dwFileVersionLS & 0xffff);
809 sprintf(version, "not available");
811 sprintf(version, "failed");
813 HeapFree(GetProcessHeap(), 0, data);
815 sprintf(version, "failed");
817 sprintf(version, "not available");
828 hDsound = LoadLibraryA("dsound.dll");
830 trace("dsound.dll not found\n");
834 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
836 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
837 if (!pDirectSoundCreate8) {
838 trace("dsound8 test skipped\n");
842 IDirectSound8_tests();