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||rc==E_FAIL,
108 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
109 if (rc==DSERR_NODRIVER) {
110 trace(" No Driver\n");
112 } else if (rc==E_FAIL) {
113 trace(" No Device\n");
115 } else if (rc==DSERR_ALLOCATED) {
116 trace(" Already In Use\n");
121 rc=IDirectSound8_Initialize(dso,lpGuid);
122 ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() "
123 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
124 DXGetErrorString8(rc));
126 /* DSOUND: Error: Invalid caps buffer */
127 rc=IDirectSound8_GetCaps(dso,0);
128 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
129 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
130 DXGetErrorString8(rc));
132 ZeroMemory(&dscaps, sizeof(dscaps));
134 /* DSOUND: Error: Invalid caps buffer */
135 rc=IDirectSound8_GetCaps(dso,&dscaps);
136 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
137 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
138 DXGetErrorString8(rc));
140 dscaps.dwSize=sizeof(dscaps);
142 /* DSOUND: Running on a certified driver */
143 rc=IDirectSound8_GetCaps(dso,&dscaps);
144 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
146 rc=IDirectSound8_Compact(dso);
147 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
148 DXGetErrorString8(rc));
150 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
151 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
152 DXGetErrorString8(rc));
154 rc=IDirectSound8_Compact(dso);
155 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
157 rc=IDirectSound8_GetSpeakerConfig(dso,0);
158 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
159 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
160 DXGetErrorString8(rc));
162 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
163 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
164 DXGetErrorString8(rc));
166 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
167 DSSPEAKER_GEOMETRY_WIDE);
168 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
169 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
170 DXGetErrorString8(rc));
172 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
173 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
174 DXGetErrorString8(rc));
175 if (rc==DS_OK && speaker_config!=new_speaker_config)
176 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
177 "config: expected 0x%08lx, got 0x%08lx\n",
178 speaker_config,new_speaker_config);
181 rc=IDirectSound8_VerifyCertification(dso, &certified);
182 ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
183 DXGetErrorString8(rc));
186 ref=IDirectSound8_Release(dso);
187 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
190 static void IDirectSound8_tests(void)
193 LPDIRECTSOUND8 dso=NULL;
195 trace("Testing IDirectSound8\n");
197 /* try the COM class factory method of creation with no device specified */
198 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
199 &IID_IDirectSound8, (void**)&dso);
200 ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance() failed: %s\n",
201 DXGetErrorString8(rc));
202 if (rc==REGDB_E_CLASSNOTREG) {
203 trace(" Class Not Registered\n");
207 IDirectSound8_test(dso, FALSE, NULL);
209 /* try the COM class factory method of creation with default playback
210 * 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_DefaultPlayback);
218 /* try the COM class factory method of creation with default voice
219 * playback device specified */
220 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
221 &IID_IDirectSound8, (void**)&dso);
222 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
223 DXGetErrorString8(rc));
225 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
227 /* try the COM class factory method of creation with a bad
229 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
230 &CLSID_DirectSoundPrivate, (void**)&dso);
231 ok(rc==E_NOINTERFACE,
232 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
233 "should have failed: %s\n",DXGetErrorString8(rc));
235 /* try the COM class factory method of creation with a bad
236 * GUID and IID specified */
237 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
238 &IID_IDirectSound8, (void**)&dso);
239 ok(rc==REGDB_E_CLASSNOTREG,
240 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
241 "should have failed: %s\n",DXGetErrorString8(rc));
243 /* try with no device specified */
244 rc=pDirectSoundCreate8(NULL,&dso,NULL);
245 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
246 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
247 if (rc==DS_OK && dso)
248 IDirectSound8_test(dso, TRUE, NULL);
250 /* try with default playback device specified */
251 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
252 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
253 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
254 if (rc==DS_OK && dso)
255 IDirectSound8_test(dso, TRUE, NULL);
257 /* try with default voice playback device specified */
258 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
259 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
260 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
261 if (rc==DS_OK && dso)
262 IDirectSound8_test(dso, TRUE, NULL);
264 /* try with a bad device specified */
265 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
266 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
267 "should have failed: %s\n",DXGetErrorString8(rc));
270 static HRESULT test_dsound8(LPGUID lpGuid)
273 LPDIRECTSOUND8 dso=NULL;
276 /* DSOUND: Error: Invalid interface buffer */
277 rc=pDirectSoundCreate8(lpGuid,0,NULL);
278 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
279 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
281 /* Create the DirectSound8 object */
282 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
283 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
284 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
288 /* Try the enumerated device */
289 IDirectSound8_test(dso, TRUE, lpGuid);
291 /* Try the COM class factory method of creation with enumerated device */
292 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
293 &IID_IDirectSound8, (void**)&dso);
294 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
295 DXGetErrorString8(rc));
297 IDirectSound8_test(dso, FALSE, lpGuid);
299 /* Create a DirectSound8 object */
300 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
301 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
303 LPDIRECTSOUND8 dso1=NULL;
305 /* Create a second DirectSound8 object */
306 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
307 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
309 /* Release the second DirectSound8 object */
310 ref=IDirectSound8_Release(dso1);
311 ok(ref==0,"IDirectSound8_Release() has %d references, "
312 "should have 0\n",ref);
313 ok(dso!=dso1,"DirectSound8 objects should be unique: "
314 "dso=%p,dso1=%p\n",dso,dso1);
317 /* Release the first DirectSound8 object */
318 ref=IDirectSound8_Release(dso);
319 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
322 return DSERR_GENERIC;
326 /* Create a DirectSound8 object */
327 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
328 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
330 LPDIRECTSOUNDBUFFER secondary;
331 DSBUFFERDESC bufdesc;
334 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
335 ZeroMemory(&bufdesc, sizeof(bufdesc));
336 bufdesc.dwSize=sizeof(bufdesc);
337 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
338 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
340 bufdesc.lpwfxFormat=&wfx;
341 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
342 ok(rc==DS_OK && secondary!=NULL,
343 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
344 "buffer: %s\n",DXGetErrorString8(rc));
345 if (rc==DS_OK && secondary!=NULL) {
346 LPDIRECTSOUND3DBUFFER buffer3d;
347 LPDIRECTSOUNDBUFFER8 buffer8;
348 rc=IDirectSound8_QueryInterface(secondary,
349 &IID_IDirectSound3DBuffer,
351 ok(rc==DS_OK && buffer3d!=NULL,
352 "IDirectSound8_QueryInterface() failed: %s\n",
353 DXGetErrorString8(rc));
354 if (rc==DS_OK && buffer3d!=NULL) {
355 ref=IDirectSound3DBuffer_AddRef(buffer3d);
356 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
357 "should have 2\n",ref);
359 rc=IDirectSound8_QueryInterface(secondary,
360 &IID_IDirectSoundBuffer8,
362 if (rc==DS_OK && buffer8!=NULL) {
363 ref=IDirectSoundBuffer8_AddRef(buffer8);
364 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
365 "should have 3\n",ref);
367 ref=IDirectSoundBuffer_AddRef(secondary);
368 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
369 "should have 4\n",ref);
371 /* release with buffer */
372 ref=IDirectSound8_Release(dso);
373 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
376 return DSERR_GENERIC;
383 static HRESULT test_primary8(LPGUID lpGuid)
386 LPDIRECTSOUND8 dso=NULL;
387 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
388 DSBUFFERDESC bufdesc;
393 /* Create the DirectSound object */
394 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
395 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
396 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
400 /* Get the device capabilities */
401 ZeroMemory(&dscaps, sizeof(dscaps));
402 dscaps.dwSize=sizeof(dscaps);
403 rc=IDirectSound8_GetCaps(dso,&dscaps);
404 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
408 /* DSOUND: Error: Invalid buffer description pointer */
409 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
410 ok(rc==DSERR_INVALIDPARAM,
411 "IDirectSound8_CreateSoundBuffer should have returned "
412 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
414 /* DSOUND: Error: Invalid buffer description pointer */
415 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
416 ok(rc==DSERR_INVALIDPARAM && primary==0,
417 "IDirectSound8_CreateSoundBuffer() should have returned "
418 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=%p\n",
419 DXGetErrorString8(rc),primary);
421 /* DSOUND: Error: Invalid buffer description pointer */
422 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
423 ok(rc==DSERR_INVALIDPARAM && primary==0,
424 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
425 "dsbo=%p\n",DXGetErrorString8(rc),primary);
427 ZeroMemory(&bufdesc, sizeof(bufdesc));
429 /* DSOUND: Error: Invalid size */
430 /* DSOUND: Error: Invalid buffer description */
431 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
432 ok(rc==DSERR_INVALIDPARAM && primary==0,
433 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
434 "primary=%p\n",DXGetErrorString8(rc),primary);
436 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
437 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
438 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
439 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
440 DXGetErrorString8(rc));
444 /* Testing the primary buffer */
446 ZeroMemory(&bufdesc, sizeof(bufdesc));
447 bufdesc.dwSize=sizeof(bufdesc);
448 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
449 bufdesc.lpwfxFormat = &wfx;
450 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
451 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
452 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
453 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
454 if (rc==DS_OK && primary!=NULL)
455 IDirectSoundBuffer_Release(primary);
458 ZeroMemory(&bufdesc, sizeof(bufdesc));
459 bufdesc.dwSize=sizeof(bufdesc);
460 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
461 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
462 ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
463 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
464 "%s\n",DXGetErrorString8(rc));
465 if (rc==DSERR_CONTROLUNAVAIL)
466 trace(" No Primary\n");
467 else if (rc==DS_OK && primary!=NULL) {
470 /* Try to create a second primary buffer */
471 /* DSOUND: Error: The primary buffer already exists.
472 * Any changes made to the buffer description will be ignored. */
473 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
474 ok(rc==DS_OK && second==primary,
475 "IDirectSound8_CreateSoundBuffer() should have returned original "
476 "primary buffer: %s\n",DXGetErrorString8(rc));
477 ref=IDirectSoundBuffer_Release(second);
478 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
479 "should have 1\n",ref);
481 /* Try to duplicate a primary buffer */
482 /* DSOUND: Error: Can't duplicate primary buffers */
483 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
485 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
486 "should have failed %s\n",DXGetErrorString8(rc));
488 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
489 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
490 DXGetErrorString8(rc));
492 if (winetest_interactive) {
493 trace("Playing a 5 seconds reference tone at the current volume.\n");
495 trace("(the current volume is %ld according to DirectSound)\n",
497 trace("All subsequent tones should be identical to this one.\n");
498 trace("Listen for stutter, changes in pitch, volume, etc.\n");
500 test_buffer8(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive &&
501 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
503 ref=IDirectSoundBuffer_Release(primary);
504 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
505 "should have 0\n",ref);
508 /* Set the CooperativeLevel back to normal */
509 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
510 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
511 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
512 DXGetErrorString8(rc));
515 ref=IDirectSound8_Release(dso);
516 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
518 return DSERR_GENERIC;
524 * Test the primary buffer at different formats while keeping the
525 * secondary buffer at a constant format.
527 static HRESULT test_primary_secondary8(LPGUID lpGuid)
530 LPDIRECTSOUND8 dso=NULL;
531 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
532 DSBUFFERDESC bufdesc;
534 WAVEFORMATEX wfx, wfx2;
538 /* Create the DirectSound object */
539 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
540 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
541 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
545 /* Get the device capabilities */
546 ZeroMemory(&dscaps, sizeof(dscaps));
547 dscaps.dwSize=sizeof(dscaps);
548 rc=IDirectSound8_GetCaps(dso,&dscaps);
549 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
553 /* We must call SetCooperativeLevel before creating primary buffer */
554 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
555 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
556 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
557 DXGetErrorString8(rc));
561 ZeroMemory(&bufdesc, sizeof(bufdesc));
562 bufdesc.dwSize=sizeof(bufdesc);
563 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
564 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
565 ok(rc==DS_OK && primary!=NULL,
566 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
567 "%s\n",DXGetErrorString8(rc));
569 if (rc==DS_OK && primary!=NULL) {
570 for (f=0;f<NB_FORMATS;f++) {
571 /* We must call SetCooperativeLevel to be allowed to call
573 /* DSOUND: Setting DirectSound cooperative level to
575 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
576 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
577 DXGetErrorString8(rc));
581 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
584 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
585 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
586 DXGetErrorString8(rc));
588 /* There is no garantee that SetFormat will actually change the
589 * format to what we asked for. It depends on what the soundcard
590 * supports. So we must re-query the format.
592 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
593 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
594 DXGetErrorString8(rc));
596 (wfx.wFormatTag!=wfx2.wFormatTag ||
597 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
598 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
599 wfx.nChannels!=wfx2.nChannels)) {
600 trace("Requested primary format tag=0x%04x %ldx%dx%d "
601 "avg.B/s=%ld align=%d\n",
602 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
603 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
604 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
605 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
606 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
609 /* Set the CooperativeLevel back to normal */
610 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
611 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
612 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
613 DXGetErrorString8(rc));
615 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
618 ZeroMemory(&bufdesc, sizeof(bufdesc));
619 bufdesc.dwSize=sizeof(bufdesc);
620 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
621 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
623 bufdesc.lpwfxFormat=&wfx2;
624 if (winetest_interactive) {
625 trace(" Testing a primary buffer at %ldx%dx%d with a "
626 "secondary buffer at %ldx%dx%d\n",
627 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
628 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
630 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
631 ok(rc==DS_OK && secondary!=NULL,
632 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
633 "buffer %s\n",DXGetErrorString8(rc));
635 if (rc==DS_OK && secondary!=NULL) {
636 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
637 winetest_interactive,1.0,0,NULL,0,0);
639 ref=IDirectSoundBuffer_Release(secondary);
640 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
641 "should have 0\n",ref);
645 ref=IDirectSoundBuffer_Release(primary);
646 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
647 "should have 0\n",ref);
650 /* Set the CooperativeLevel back to normal */
651 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
652 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
653 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
654 DXGetErrorString8(rc));
657 ref=IDirectSound8_Release(dso);
658 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
660 return DSERR_GENERIC;
665 static HRESULT test_secondary8(LPGUID lpGuid)
668 LPDIRECTSOUND8 dso=NULL;
669 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
670 DSBUFFERDESC bufdesc;
672 WAVEFORMATEX wfx, wfx1;
676 /* Create the DirectSound object */
677 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
678 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
679 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
683 /* Get the device capabilities */
684 ZeroMemory(&dscaps, sizeof(dscaps));
685 dscaps.dwSize=sizeof(dscaps);
686 rc=IDirectSound8_GetCaps(dso,&dscaps);
687 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
691 /* We must call SetCooperativeLevel before creating primary buffer */
692 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
693 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
694 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
695 DXGetErrorString8(rc));
699 ZeroMemory(&bufdesc, sizeof(bufdesc));
700 bufdesc.dwSize=sizeof(bufdesc);
701 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
702 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
703 ok(rc==DS_OK && primary!=NULL,
704 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
705 "%s\n",DXGetErrorString8(rc));
707 if (rc==DS_OK && primary!=NULL) {
708 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
709 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
710 DXGetErrorString8(rc));
714 for (f=0;f<NB_FORMATS;f++) {
715 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
718 ZeroMemory(&bufdesc, sizeof(bufdesc));
719 bufdesc.dwSize=sizeof(bufdesc);
720 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
721 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
723 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
724 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
725 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
726 DXGetErrorString8(rc));
727 if (rc==DS_OK && secondary!=NULL)
728 IDirectSoundBuffer_Release(secondary);
731 ZeroMemory(&bufdesc, sizeof(bufdesc));
732 bufdesc.dwSize=sizeof(bufdesc);
733 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
734 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
736 bufdesc.lpwfxFormat=&wfx;
737 if (winetest_interactive) {
738 trace(" Testing a secondary buffer at %ldx%dx%d "
739 "with a primary buffer at %ldx%dx%d\n",
740 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
741 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
743 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
744 ok(rc==DS_OK && secondary!=NULL,
745 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
746 "buffer: %s\n",DXGetErrorString8(rc));
748 if (rc==DS_OK && secondary!=NULL) {
749 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
750 winetest_interactive,1.0,0,NULL,0,0);
752 ref=IDirectSoundBuffer_Release(secondary);
753 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
754 "should have 0\n",ref);
758 ref=IDirectSoundBuffer_Release(primary);
759 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
760 "should have 0\n",ref);
763 /* Set the CooperativeLevel back to normal */
764 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
765 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
766 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
767 DXGetErrorString8(rc));
770 ref=IDirectSound8_Release(dso);
771 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
773 return DSERR_GENERIC;
778 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
779 LPCSTR lpcstrModule, LPVOID lpContext)
782 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
783 rc = test_dsound8(lpGuid);
784 if (rc == DSERR_NODRIVER)
785 trace(" No Driver\n");
786 else if (rc == DSERR_ALLOCATED)
787 trace(" Already In Use\n");
788 else if (rc == E_FAIL)
789 trace(" No Device\n");
791 test_primary8(lpGuid);
792 test_primary_secondary8(lpGuid);
793 test_secondary8(lpGuid);
799 static void dsound8_tests(void)
802 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
803 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
806 const char * get_file_version(const char * file_name)
808 static char version[32];
812 size = GetFileVersionInfoSizeA("dsound.dll", &handle);
814 char * data = HeapAlloc(GetProcessHeap(), 0, size);
816 if (GetFileVersionInfoA("dsound.dll", handle, size, data)) {
817 VS_FIXEDFILEINFO *pFixedVersionInfo;
819 if (VerQueryValueA(data, "\\", (LPVOID *)&pFixedVersionInfo, &len)) {
820 sprintf(version, "%ld.%ld.%ld.%ld",
821 pFixedVersionInfo->dwFileVersionMS >> 16,
822 pFixedVersionInfo->dwFileVersionMS & 0xffff,
823 pFixedVersionInfo->dwFileVersionLS >> 16,
824 pFixedVersionInfo->dwFileVersionLS & 0xffff);
826 sprintf(version, "not available");
828 sprintf(version, "failed");
830 HeapFree(GetProcessHeap(), 0, data);
832 sprintf(version, "failed");
834 sprintf(version, "not available");
845 hDsound = LoadLibraryA("dsound.dll");
847 trace("dsound.dll not found\n");
851 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
853 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
854 if (!pDirectSoundCreate8) {
855 trace("dsound8 test skipped\n");
859 IDirectSound8_tests();