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");
113 if (rc==DSERR_ALLOCATED) {
114 trace(" Already In Use\n");
118 trace(" Could not initialize DirectSound.\n");
123 /* DSOUND: Error: Invalid caps buffer */
124 rc=IDirectSound8_GetCaps(dso,0);
125 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
126 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
127 DXGetErrorString8(rc));
129 ZeroMemory(&dscaps, sizeof(dscaps));
131 /* DSOUND: Error: Invalid caps buffer */
132 rc=IDirectSound8_GetCaps(dso,&dscaps);
133 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
134 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
135 DXGetErrorString8(rc));
137 dscaps.dwSize=sizeof(dscaps);
139 /* DSOUND: Running on a certified driver */
140 rc=IDirectSound8_GetCaps(dso,&dscaps);
141 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
143 rc=IDirectSound8_Compact(dso);
144 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
145 DXGetErrorString8(rc));
147 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
148 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
149 DXGetErrorString8(rc));
151 rc=IDirectSound8_Compact(dso);
152 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
154 rc=IDirectSound8_GetSpeakerConfig(dso,0);
155 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
156 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
157 DXGetErrorString8(rc));
159 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
160 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
161 DXGetErrorString8(rc));
163 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
164 DSSPEAKER_GEOMETRY_WIDE);
165 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
166 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
167 DXGetErrorString8(rc));
169 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
170 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
171 DXGetErrorString8(rc));
172 if (rc==DS_OK && speaker_config!=new_speaker_config)
173 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
174 "config: expected 0x%08lx, got 0x%08lx\n",
175 speaker_config,new_speaker_config);
178 rc=IDirectSound8_VerifyCertification(dso, &certified);
179 ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
180 DXGetErrorString8(rc));
182 ref=IDirectSound8_Release(dso);
183 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
186 static void IDirectSound8_tests()
189 LPDIRECTSOUND8 dso=NULL;
191 trace("Testing IDirectSound8\n");
193 /* try the COM class factory method of creation with no device specified */
194 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
195 &IID_IDirectSound8, (void**)&dso);
196 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
198 IDirectSound8_test(dso, FALSE, NULL);
200 /* try the COM class factory method of creation with default playback
201 * device specified */
202 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
203 &IID_IDirectSound8, (void**)&dso);
204 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
205 DXGetErrorString8(rc));
207 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
209 /* try the COM class factory method of creation with default voice
210 * playback device specified */
211 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
212 &IID_IDirectSound8, (void**)&dso);
213 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
214 DXGetErrorString8(rc));
216 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
218 /* try the COM class factory method of creation with a bad
220 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
221 &CLSID_DirectSoundPrivate, (void**)&dso);
222 ok(rc==E_NOINTERFACE,
223 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
224 "should have failed: %s\n",DXGetErrorString8(rc));
226 /* try the COM class factory method of creation with a bad
227 * GUID and IID specified */
228 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
229 &IID_IDirectSound8, (void**)&dso);
230 ok(rc==REGDB_E_CLASSNOTREG,
231 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
232 "should have failed: %s\n",DXGetErrorString8(rc));
234 /* try with no device specified */
235 rc=pDirectSoundCreate8(NULL,&dso,NULL);
236 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
237 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
238 if (rc==DS_OK && dso)
239 IDirectSound8_test(dso, TRUE, NULL);
241 /* try with default playback device specified */
242 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
243 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
244 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
245 if (rc==DS_OK && dso)
246 IDirectSound8_test(dso, TRUE, NULL);
248 /* try with default voice playback device specified */
249 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
250 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
251 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
252 if (rc==DS_OK && dso)
253 IDirectSound8_test(dso, TRUE, NULL);
255 /* try with a bad device specified */
256 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
257 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
258 "should have failed: %s\n",DXGetErrorString8(rc));
261 static HRESULT test_dsound8(LPGUID lpGuid)
264 LPDIRECTSOUND8 dso=NULL;
267 /* DSOUND: Error: Invalid interface buffer */
268 rc=pDirectSoundCreate8(lpGuid,0,NULL);
269 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
270 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
272 /* Create the DirectSound8 object */
273 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
274 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
275 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
279 /* Try the enumerated device */
280 IDirectSound8_test(dso, TRUE, lpGuid);
282 /* Try the COM class factory method of creation with enumerated device */
283 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
284 &IID_IDirectSound8, (void**)&dso);
285 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
286 DXGetErrorString8(rc));
288 IDirectSound8_test(dso, FALSE, lpGuid);
290 /* Create a DirectSound8 object */
291 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
292 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
294 LPDIRECTSOUND8 dso1=NULL;
296 /* Create a second DirectSound8 object */
297 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
298 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
300 /* Release the second DirectSound8 object */
301 ref=IDirectSound8_Release(dso1);
302 ok(ref==0,"IDirectSound8_Release() has %d references, "
303 "should have 0\n",ref);
304 ok(dso!=dso1,"DirectSound8 objects should be unique: "
305 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
308 /* Release the first DirectSound8 object */
309 ref=IDirectSound8_Release(dso);
310 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
313 return DSERR_GENERIC;
317 /* Create a DirectSound8 object */
318 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
319 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
321 LPDIRECTSOUNDBUFFER secondary;
322 DSBUFFERDESC bufdesc;
325 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
326 ZeroMemory(&bufdesc, sizeof(bufdesc));
327 bufdesc.dwSize=sizeof(bufdesc);
328 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
329 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
331 bufdesc.lpwfxFormat=&wfx;
332 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
333 ok(rc==DS_OK && secondary!=NULL,
334 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
335 "buffer: %s\n",DXGetErrorString8(rc));
336 if (rc==DS_OK && secondary!=NULL) {
337 LPDIRECTSOUND3DBUFFER buffer3d;
338 LPDIRECTSOUNDBUFFER8 buffer8;
339 rc=IDirectSound8_QueryInterface(secondary,
340 &IID_IDirectSound3DBuffer,
342 ok(rc==DS_OK && buffer3d!=NULL,
343 "IDirectSound8_QueryInterface() failed: %s\n",
344 DXGetErrorString8(rc));
345 if (rc==DS_OK && buffer3d!=NULL) {
346 ref=IDirectSound3DBuffer_AddRef(buffer3d);
347 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
348 "should have 2\n",ref);
350 rc=IDirectSound8_QueryInterface(secondary,
351 &IID_IDirectSoundBuffer8,
353 if (rc==DS_OK && buffer8!=NULL) {
354 ref=IDirectSoundBuffer8_AddRef(buffer8);
355 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
356 "should have 3\n",ref);
358 ref=IDirectSoundBuffer_AddRef(secondary);
359 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
360 "should have 4\n",ref);
362 /* release with buffer */
363 ref=IDirectSound8_Release(dso);
364 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
367 return DSERR_GENERIC;
374 static HRESULT test_primary8(LPGUID lpGuid)
377 LPDIRECTSOUND8 dso=NULL;
378 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
379 DSBUFFERDESC bufdesc;
384 /* Create the DirectSound object */
385 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
386 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
387 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
391 /* Get the device capabilities */
392 ZeroMemory(&dscaps, sizeof(dscaps));
393 dscaps.dwSize=sizeof(dscaps);
394 rc=IDirectSound8_GetCaps(dso,&dscaps);
395 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
399 /* DSOUND: Error: Invalid buffer description pointer */
400 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
401 ok(rc==DSERR_INVALIDPARAM,
402 "IDirectSound8_CreateSoundBuffer should have returned "
403 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
405 /* DSOUND: Error: Invalid buffer description pointer */
406 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
407 ok(rc==DSERR_INVALIDPARAM && primary==0,
408 "IDirectSound8_CreateSoundBuffer() should have returned "
409 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
410 DXGetErrorString8(rc),(DWORD)primary);
412 /* DSOUND: Error: Invalid buffer description pointer */
413 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
414 ok(rc==DSERR_INVALIDPARAM && primary==0,
415 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
416 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
418 ZeroMemory(&bufdesc, sizeof(bufdesc));
420 /* DSOUND: Error: Invalid size */
421 /* DSOUND: Error: Invalid buffer description */
422 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
423 ok(rc==DSERR_INVALIDPARAM && primary==0,
424 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
425 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
427 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
428 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
429 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
430 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
431 DXGetErrorString8(rc));
435 /* Testing the primary buffer */
437 ZeroMemory(&bufdesc, sizeof(bufdesc));
438 bufdesc.dwSize=sizeof(bufdesc);
439 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
440 bufdesc.lpwfxFormat = &wfx;
441 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
442 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
443 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
444 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
445 if (rc==DS_OK && primary!=NULL)
446 IDirectSoundBuffer_Release(primary);
449 ZeroMemory(&bufdesc, sizeof(bufdesc));
450 bufdesc.dwSize=sizeof(bufdesc);
451 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
452 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
453 ok(rc==DS_OK && primary!=NULL,
454 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
455 "%s\n",DXGetErrorString8(rc));
456 if (rc==DS_OK && primary!=NULL) {
459 /* Try to create a second primary buffer */
460 /* DSOUND: Error: The primary buffer already exists.
461 * Any changes made to the buffer description will be ignored. */
462 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
463 ok(rc==DS_OK && second==primary,
464 "IDirectSound8_CreateSoundBuffer() should have returned original "
465 "primary buffer: %s\n",DXGetErrorString8(rc));
466 ref=IDirectSoundBuffer_Release(second);
467 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
468 "should have 1\n",ref);
470 /* Try to duplicate a primary buffer */
471 /* DSOUND: Error: Can't duplicate primary buffers */
472 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
474 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
475 "should have failed %s\n",DXGetErrorString8(rc));
477 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
478 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
479 DXGetErrorString8(rc));
481 if (winetest_interactive) {
482 trace("Playing a 5 seconds reference tone at the current volume.\n");
484 trace("(the current volume is %ld according to DirectSound)\n",
486 trace("All subsequent tones should be identical to this one.\n");
487 trace("Listen for stutter, changes in pitch, volume, etc.\n");
489 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
490 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
492 ref=IDirectSoundBuffer_Release(primary);
493 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
494 "should have 0\n",ref);
497 /* Set the CooperativeLevel back to normal */
498 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
499 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
500 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
501 DXGetErrorString8(rc));
504 ref=IDirectSound8_Release(dso);
505 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
507 return DSERR_GENERIC;
513 * Test the primary buffer at different formats while keeping the
514 * secondary buffer at a constant format.
516 static HRESULT test_primary_secondary8(LPGUID lpGuid)
519 LPDIRECTSOUND8 dso=NULL;
520 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
521 DSBUFFERDESC bufdesc;
523 WAVEFORMATEX wfx, wfx2;
526 /* Create the DirectSound object */
527 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
528 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
529 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
533 /* Get the device capabilities */
534 ZeroMemory(&dscaps, sizeof(dscaps));
535 dscaps.dwSize=sizeof(dscaps);
536 rc=IDirectSound8_GetCaps(dso,&dscaps);
537 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
541 /* We must call SetCooperativeLevel before creating primary buffer */
542 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
543 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
544 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
545 DXGetErrorString8(rc));
549 ZeroMemory(&bufdesc, sizeof(bufdesc));
550 bufdesc.dwSize=sizeof(bufdesc);
551 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
552 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
553 ok(rc==DS_OK && primary!=NULL,
554 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
555 "%s\n",DXGetErrorString8(rc));
557 if (rc==DS_OK && primary!=NULL) {
558 for (f=0;f<NB_FORMATS;f++) {
559 /* We must call SetCooperativeLevel to be allowed to call
561 /* DSOUND: Setting DirectSound cooperative level to
563 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
564 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
565 DXGetErrorString8(rc));
569 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
572 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
573 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
574 DXGetErrorString8(rc));
576 /* There is no garantee that SetFormat will actually change the
577 * format to what we asked for. It depends on what the soundcard
578 * supports. So we must re-query the format.
580 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
581 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
582 DXGetErrorString8(rc));
584 (wfx.wFormatTag!=wfx2.wFormatTag ||
585 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
586 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
587 wfx.nChannels!=wfx2.nChannels)) {
588 trace("Requested primary format tag=0x%04x %ldx%dx%d "
589 "avg.B/s=%ld align=%d\n",
590 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
591 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
592 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
593 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
594 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
597 /* Set the CooperativeLevel back to normal */
598 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
599 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
600 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
601 DXGetErrorString8(rc));
603 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
606 ZeroMemory(&bufdesc, sizeof(bufdesc));
607 bufdesc.dwSize=sizeof(bufdesc);
608 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
609 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
611 bufdesc.lpwfxFormat=&wfx2;
612 if (winetest_interactive) {
613 trace(" Testing a primary buffer at %ldx%dx%d with a "
614 "secondary buffer at %ldx%dx%d\n",
615 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
616 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
618 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
619 ok(rc==DS_OK && secondary!=NULL,
620 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
621 "buffer %s\n",DXGetErrorString8(rc));
623 if (rc==DS_OK && secondary!=NULL) {
624 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
625 winetest_interactive,1.0,0,NULL,0,0);
627 ref=IDirectSoundBuffer_Release(secondary);
628 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
629 "should have 0\n",ref);
633 ref=IDirectSoundBuffer_Release(primary);
634 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
635 "should have 0\n",ref);
638 /* Set the CooperativeLevel back to normal */
639 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
640 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
641 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
642 DXGetErrorString8(rc));
645 ref=IDirectSound8_Release(dso);
646 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
648 return DSERR_GENERIC;
653 static HRESULT test_secondary8(LPGUID lpGuid)
656 LPDIRECTSOUND8 dso=NULL;
657 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
658 DSBUFFERDESC bufdesc;
660 WAVEFORMATEX wfx, wfx1;
664 /* Create the DirectSound object */
665 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
666 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
667 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
671 /* Get the device capabilities */
672 ZeroMemory(&dscaps, sizeof(dscaps));
673 dscaps.dwSize=sizeof(dscaps);
674 rc=IDirectSound8_GetCaps(dso,&dscaps);
675 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
679 /* We must call SetCooperativeLevel before creating primary buffer */
680 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
681 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
682 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
683 DXGetErrorString8(rc));
687 ZeroMemory(&bufdesc, sizeof(bufdesc));
688 bufdesc.dwSize=sizeof(bufdesc);
689 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
690 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
691 ok(rc==DS_OK && primary!=NULL,
692 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
693 "%s\n",DXGetErrorString8(rc));
695 if (rc==DS_OK && primary!=NULL) {
696 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
697 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
698 DXGetErrorString8(rc));
702 for (f=0;f<NB_FORMATS;f++) {
703 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
706 ZeroMemory(&bufdesc, sizeof(bufdesc));
707 bufdesc.dwSize=sizeof(bufdesc);
708 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
709 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
711 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
712 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
713 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
714 DXGetErrorString8(rc));
715 if (rc==DS_OK && secondary!=NULL)
716 IDirectSoundBuffer_Release(secondary);
719 ZeroMemory(&bufdesc, sizeof(bufdesc));
720 bufdesc.dwSize=sizeof(bufdesc);
721 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
722 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
724 bufdesc.lpwfxFormat=&wfx;
725 if (winetest_interactive) {
726 trace(" Testing a secondary buffer at %ldx%dx%d "
727 "with a primary buffer at %ldx%dx%d\n",
728 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
729 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
731 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
732 ok(rc==DS_OK && secondary!=NULL,
733 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
734 "buffer: %s\n",DXGetErrorString8(rc));
736 if (rc==DS_OK && secondary!=NULL) {
737 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
738 winetest_interactive,1.0,0,NULL,0,0);
740 ref=IDirectSoundBuffer_Release(secondary);
741 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
742 "should have 0\n",ref);
746 ref=IDirectSoundBuffer_Release(primary);
747 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
748 "should have 0\n",ref);
751 /* Set the CooperativeLevel back to normal */
752 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
753 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
754 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
755 DXGetErrorString8(rc));
758 ref=IDirectSound8_Release(dso);
759 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
761 return DSERR_GENERIC;
766 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
767 LPCSTR lpcstrModule, LPVOID lpContext)
770 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
771 rc = test_dsound8(lpGuid);
772 if (rc == DSERR_NODRIVER)
773 trace(" No Driver\n");
774 else if (rc == DSERR_ALLOCATED)
775 trace(" Already In Use\n");
776 else if (rc == E_FAIL)
777 trace(" No Device\n");
779 test_primary8(lpGuid);
780 test_primary_secondary8(lpGuid);
781 test_secondary8(lpGuid);
787 static void dsound8_tests()
790 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
791 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
794 const char * get_file_version(const char * file_name)
796 static char version[32];
800 size = GetFileVersionInfoSizeA("dsound.dll", &handle);
802 char * data = HeapAlloc(GetProcessHeap(), 0, size);
804 if (GetFileVersionInfoA("dsound.dll", handle, size, data)) {
805 VS_FIXEDFILEINFO *pFixedVersionInfo;
807 if (VerQueryValueA(data, "\\", (LPLPVOID)&pFixedVersionInfo, &len)) {
808 sprintf(version, "%ld.%ld.%ld.%ld",
809 pFixedVersionInfo->dwFileVersionMS >> 16,
810 pFixedVersionInfo->dwFileVersionMS & 0xffff,
811 pFixedVersionInfo->dwFileVersionLS >> 16,
812 pFixedVersionInfo->dwFileVersionLS & 0xffff);
814 sprintf(version, "not available");
816 sprintf(version, "failed");
818 HeapFree(GetProcessHeap(), 0, data);
820 sprintf(version, "failed");
822 sprintf(version, "not available");
833 hDsound = LoadLibraryA("dsound.dll");
835 trace("dsound.dll not found\n");
839 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
841 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
842 if (!pDirectSoundCreate8) {
843 trace("dsound8 test skipped\n");
847 IDirectSound8_tests();