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()
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,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
202 IDirectSound8_test(dso, FALSE, NULL);
204 /* try the COM class factory method of creation with default playback
205 * 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_DefaultPlayback);
213 /* try the COM class factory method of creation with default voice
214 * playback device specified */
215 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
216 &IID_IDirectSound8, (void**)&dso);
217 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
218 DXGetErrorString8(rc));
220 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
222 /* try the COM class factory method of creation with a bad
224 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
225 &CLSID_DirectSoundPrivate, (void**)&dso);
226 ok(rc==E_NOINTERFACE,
227 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
228 "should have failed: %s\n",DXGetErrorString8(rc));
230 /* try the COM class factory method of creation with a bad
231 * GUID and IID specified */
232 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
233 &IID_IDirectSound8, (void**)&dso);
234 ok(rc==REGDB_E_CLASSNOTREG,
235 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
236 "should have failed: %s\n",DXGetErrorString8(rc));
238 /* try with no device specified */
239 rc=pDirectSoundCreate8(NULL,&dso,NULL);
240 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
241 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
242 if (rc==DS_OK && dso)
243 IDirectSound8_test(dso, TRUE, NULL);
245 /* try with default playback device specified */
246 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
247 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
248 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
249 if (rc==DS_OK && dso)
250 IDirectSound8_test(dso, TRUE, NULL);
252 /* try with default voice playback device specified */
253 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
254 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
255 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
256 if (rc==DS_OK && dso)
257 IDirectSound8_test(dso, TRUE, NULL);
259 /* try with a bad device specified */
260 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
261 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
262 "should have failed: %s\n",DXGetErrorString8(rc));
265 static HRESULT test_dsound8(LPGUID lpGuid)
268 LPDIRECTSOUND8 dso=NULL;
271 /* DSOUND: Error: Invalid interface buffer */
272 rc=pDirectSoundCreate8(lpGuid,0,NULL);
273 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
274 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
276 /* Create the DirectSound8 object */
277 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
278 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
279 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
283 /* Try the enumerated device */
284 IDirectSound8_test(dso, TRUE, lpGuid);
286 /* Try the COM class factory method of creation with enumerated device */
287 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
288 &IID_IDirectSound8, (void**)&dso);
289 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
290 DXGetErrorString8(rc));
292 IDirectSound8_test(dso, FALSE, lpGuid);
294 /* Create a DirectSound8 object */
295 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
296 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
298 LPDIRECTSOUND8 dso1=NULL;
300 /* Create a second DirectSound8 object */
301 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
302 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
304 /* Release the second DirectSound8 object */
305 ref=IDirectSound8_Release(dso1);
306 ok(ref==0,"IDirectSound8_Release() has %d references, "
307 "should have 0\n",ref);
308 ok(dso!=dso1,"DirectSound8 objects should be unique: "
309 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
312 /* Release the first DirectSound8 object */
313 ref=IDirectSound8_Release(dso);
314 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
317 return DSERR_GENERIC;
321 /* Create a DirectSound8 object */
322 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
323 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
325 LPDIRECTSOUNDBUFFER secondary;
326 DSBUFFERDESC bufdesc;
329 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
330 ZeroMemory(&bufdesc, sizeof(bufdesc));
331 bufdesc.dwSize=sizeof(bufdesc);
332 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
333 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
335 bufdesc.lpwfxFormat=&wfx;
336 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
337 ok(rc==DS_OK && secondary!=NULL,
338 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
339 "buffer: %s\n",DXGetErrorString8(rc));
340 if (rc==DS_OK && secondary!=NULL) {
341 LPDIRECTSOUND3DBUFFER buffer3d;
342 LPDIRECTSOUNDBUFFER8 buffer8;
343 rc=IDirectSound8_QueryInterface(secondary,
344 &IID_IDirectSound3DBuffer,
346 ok(rc==DS_OK && buffer3d!=NULL,
347 "IDirectSound8_QueryInterface() failed: %s\n",
348 DXGetErrorString8(rc));
349 if (rc==DS_OK && buffer3d!=NULL) {
350 ref=IDirectSound3DBuffer_AddRef(buffer3d);
351 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
352 "should have 2\n",ref);
354 rc=IDirectSound8_QueryInterface(secondary,
355 &IID_IDirectSoundBuffer8,
357 if (rc==DS_OK && buffer8!=NULL) {
358 ref=IDirectSoundBuffer8_AddRef(buffer8);
359 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
360 "should have 3\n",ref);
362 ref=IDirectSoundBuffer_AddRef(secondary);
363 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
364 "should have 4\n",ref);
366 /* release with buffer */
367 ref=IDirectSound8_Release(dso);
368 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
371 return DSERR_GENERIC;
378 static HRESULT test_primary8(LPGUID lpGuid)
381 LPDIRECTSOUND8 dso=NULL;
382 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
383 DSBUFFERDESC bufdesc;
388 /* Create the DirectSound object */
389 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
390 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
391 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
395 /* Get the device capabilities */
396 ZeroMemory(&dscaps, sizeof(dscaps));
397 dscaps.dwSize=sizeof(dscaps);
398 rc=IDirectSound8_GetCaps(dso,&dscaps);
399 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
403 /* DSOUND: Error: Invalid buffer description pointer */
404 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
405 ok(rc==DSERR_INVALIDPARAM,
406 "IDirectSound8_CreateSoundBuffer should have returned "
407 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
409 /* DSOUND: Error: Invalid buffer description pointer */
410 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
411 ok(rc==DSERR_INVALIDPARAM && primary==0,
412 "IDirectSound8_CreateSoundBuffer() should have returned "
413 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
414 DXGetErrorString8(rc),(DWORD)primary);
416 /* DSOUND: Error: Invalid buffer description pointer */
417 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
418 ok(rc==DSERR_INVALIDPARAM && primary==0,
419 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
420 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
422 ZeroMemory(&bufdesc, sizeof(bufdesc));
424 /* DSOUND: Error: Invalid size */
425 /* DSOUND: Error: Invalid buffer description */
426 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
427 ok(rc==DSERR_INVALIDPARAM && primary==0,
428 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
429 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
431 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
432 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
433 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
434 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
435 DXGetErrorString8(rc));
439 /* Testing the primary buffer */
441 ZeroMemory(&bufdesc, sizeof(bufdesc));
442 bufdesc.dwSize=sizeof(bufdesc);
443 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
444 bufdesc.lpwfxFormat = &wfx;
445 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
446 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
447 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
448 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
449 if (rc==DS_OK && primary!=NULL)
450 IDirectSoundBuffer_Release(primary);
453 ZeroMemory(&bufdesc, sizeof(bufdesc));
454 bufdesc.dwSize=sizeof(bufdesc);
455 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
456 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
457 ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
458 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
459 "%s\n",DXGetErrorString8(rc));
460 if (rc==DSERR_CONTROLUNAVAIL)
461 trace(" No Primary\n");
462 else if (rc==DS_OK && primary!=NULL) {
465 /* Try to create a second primary buffer */
466 /* DSOUND: Error: The primary buffer already exists.
467 * Any changes made to the buffer description will be ignored. */
468 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
469 ok(rc==DS_OK && second==primary,
470 "IDirectSound8_CreateSoundBuffer() should have returned original "
471 "primary buffer: %s\n",DXGetErrorString8(rc));
472 ref=IDirectSoundBuffer_Release(second);
473 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
474 "should have 1\n",ref);
476 /* Try to duplicate a primary buffer */
477 /* DSOUND: Error: Can't duplicate primary buffers */
478 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
480 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
481 "should have failed %s\n",DXGetErrorString8(rc));
483 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
484 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
485 DXGetErrorString8(rc));
487 if (winetest_interactive) {
488 trace("Playing a 5 seconds reference tone at the current volume.\n");
490 trace("(the current volume is %ld according to DirectSound)\n",
492 trace("All subsequent tones should be identical to this one.\n");
493 trace("Listen for stutter, changes in pitch, volume, etc.\n");
495 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
496 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
498 ref=IDirectSoundBuffer_Release(primary);
499 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
500 "should have 0\n",ref);
503 /* Set the CooperativeLevel back to normal */
504 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
505 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
506 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
507 DXGetErrorString8(rc));
510 ref=IDirectSound8_Release(dso);
511 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
513 return DSERR_GENERIC;
519 * Test the primary buffer at different formats while keeping the
520 * secondary buffer at a constant format.
522 static HRESULT test_primary_secondary8(LPGUID lpGuid)
525 LPDIRECTSOUND8 dso=NULL;
526 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
527 DSBUFFERDESC bufdesc;
529 WAVEFORMATEX wfx, wfx2;
532 /* Create the DirectSound object */
533 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
534 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
535 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
539 /* Get the device capabilities */
540 ZeroMemory(&dscaps, sizeof(dscaps));
541 dscaps.dwSize=sizeof(dscaps);
542 rc=IDirectSound8_GetCaps(dso,&dscaps);
543 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
547 /* We must call SetCooperativeLevel before creating primary buffer */
548 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
549 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
550 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
551 DXGetErrorString8(rc));
555 ZeroMemory(&bufdesc, sizeof(bufdesc));
556 bufdesc.dwSize=sizeof(bufdesc);
557 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
558 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
559 ok(rc==DS_OK && primary!=NULL,
560 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
561 "%s\n",DXGetErrorString8(rc));
563 if (rc==DS_OK && primary!=NULL) {
564 for (f=0;f<NB_FORMATS;f++) {
565 /* We must call SetCooperativeLevel to be allowed to call
567 /* DSOUND: Setting DirectSound cooperative level to
569 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
570 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
571 DXGetErrorString8(rc));
575 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
578 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
579 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
580 DXGetErrorString8(rc));
582 /* There is no garantee that SetFormat will actually change the
583 * format to what we asked for. It depends on what the soundcard
584 * supports. So we must re-query the format.
586 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
587 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
588 DXGetErrorString8(rc));
590 (wfx.wFormatTag!=wfx2.wFormatTag ||
591 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
592 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
593 wfx.nChannels!=wfx2.nChannels)) {
594 trace("Requested primary format tag=0x%04x %ldx%dx%d "
595 "avg.B/s=%ld align=%d\n",
596 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
597 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
598 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
599 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
600 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
603 /* Set the CooperativeLevel back to normal */
604 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
605 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
606 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
607 DXGetErrorString8(rc));
609 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
612 ZeroMemory(&bufdesc, sizeof(bufdesc));
613 bufdesc.dwSize=sizeof(bufdesc);
614 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
615 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
617 bufdesc.lpwfxFormat=&wfx2;
618 if (winetest_interactive) {
619 trace(" Testing a primary buffer at %ldx%dx%d with a "
620 "secondary buffer at %ldx%dx%d\n",
621 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
622 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
624 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
625 ok(rc==DS_OK && secondary!=NULL,
626 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
627 "buffer %s\n",DXGetErrorString8(rc));
629 if (rc==DS_OK && secondary!=NULL) {
630 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
631 winetest_interactive,1.0,0,NULL,0,0);
633 ref=IDirectSoundBuffer_Release(secondary);
634 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
635 "should have 0\n",ref);
639 ref=IDirectSoundBuffer_Release(primary);
640 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
641 "should have 0\n",ref);
644 /* Set the CooperativeLevel back to normal */
645 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
646 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
647 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
648 DXGetErrorString8(rc));
651 ref=IDirectSound8_Release(dso);
652 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
654 return DSERR_GENERIC;
659 static HRESULT test_secondary8(LPGUID lpGuid)
662 LPDIRECTSOUND8 dso=NULL;
663 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
664 DSBUFFERDESC bufdesc;
666 WAVEFORMATEX wfx, wfx1;
670 /* Create the DirectSound object */
671 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
672 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
673 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
677 /* Get the device capabilities */
678 ZeroMemory(&dscaps, sizeof(dscaps));
679 dscaps.dwSize=sizeof(dscaps);
680 rc=IDirectSound8_GetCaps(dso,&dscaps);
681 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
685 /* We must call SetCooperativeLevel before creating primary buffer */
686 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
687 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
688 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
689 DXGetErrorString8(rc));
693 ZeroMemory(&bufdesc, sizeof(bufdesc));
694 bufdesc.dwSize=sizeof(bufdesc);
695 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
696 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
697 ok(rc==DS_OK && primary!=NULL,
698 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
699 "%s\n",DXGetErrorString8(rc));
701 if (rc==DS_OK && primary!=NULL) {
702 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
703 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
704 DXGetErrorString8(rc));
708 for (f=0;f<NB_FORMATS;f++) {
709 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
712 ZeroMemory(&bufdesc, sizeof(bufdesc));
713 bufdesc.dwSize=sizeof(bufdesc);
714 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
715 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
717 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
718 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
719 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
720 DXGetErrorString8(rc));
721 if (rc==DS_OK && secondary!=NULL)
722 IDirectSoundBuffer_Release(secondary);
725 ZeroMemory(&bufdesc, sizeof(bufdesc));
726 bufdesc.dwSize=sizeof(bufdesc);
727 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
728 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
730 bufdesc.lpwfxFormat=&wfx;
731 if (winetest_interactive) {
732 trace(" Testing a secondary buffer at %ldx%dx%d "
733 "with a primary buffer at %ldx%dx%d\n",
734 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
735 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
737 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
738 ok(rc==DS_OK && secondary!=NULL,
739 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
740 "buffer: %s\n",DXGetErrorString8(rc));
742 if (rc==DS_OK && secondary!=NULL) {
743 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
744 winetest_interactive,1.0,0,NULL,0,0);
746 ref=IDirectSoundBuffer_Release(secondary);
747 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
748 "should have 0\n",ref);
752 ref=IDirectSoundBuffer_Release(primary);
753 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
754 "should have 0\n",ref);
757 /* Set the CooperativeLevel back to normal */
758 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
759 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
760 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
761 DXGetErrorString8(rc));
764 ref=IDirectSound8_Release(dso);
765 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
767 return DSERR_GENERIC;
772 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
773 LPCSTR lpcstrModule, LPVOID lpContext)
776 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
777 rc = test_dsound8(lpGuid);
778 if (rc == DSERR_NODRIVER)
779 trace(" No Driver\n");
780 else if (rc == DSERR_ALLOCATED)
781 trace(" Already In Use\n");
782 else if (rc == E_FAIL)
783 trace(" No Device\n");
785 test_primary8(lpGuid);
786 test_primary_secondary8(lpGuid);
787 test_secondary8(lpGuid);
793 static void dsound8_tests()
796 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
797 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
800 const char * get_file_version(const char * file_name)
802 static char version[32];
806 size = GetFileVersionInfoSizeA("dsound.dll", &handle);
808 char * data = HeapAlloc(GetProcessHeap(), 0, size);
810 if (GetFileVersionInfoA("dsound.dll", handle, size, data)) {
811 VS_FIXEDFILEINFO *pFixedVersionInfo;
813 if (VerQueryValueA(data, "\\", (LPVOID *)&pFixedVersionInfo, &len)) {
814 sprintf(version, "%ld.%ld.%ld.%ld",
815 pFixedVersionInfo->dwFileVersionMS >> 16,
816 pFixedVersionInfo->dwFileVersionMS & 0xffff,
817 pFixedVersionInfo->dwFileVersionLS >> 16,
818 pFixedVersionInfo->dwFileVersionLS & 0xffff);
820 sprintf(version, "not available");
822 sprintf(version, "failed");
824 HeapFree(GetProcessHeap(), 0, data);
826 sprintf(version, "failed");
828 sprintf(version, "not available");
839 hDsound = LoadLibraryA("dsound.dll");
841 trace("dsound.dll not found\n");
845 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
847 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
848 if (!pDirectSoundCreate8) {
849 trace("dsound8 test skipped\n");
853 IDirectSound8_tests();