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
32 #include "wine/test.h"
37 #include "dsound_test.h"
39 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
41 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
50 DWORD speaker_config, new_speaker_config;
53 /* Try to Query for objects */
54 rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
55 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
56 DXGetErrorString8(rc));
58 IDirectSound8_Release(unknown);
60 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
61 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
62 DXGetErrorString8(rc));
64 IDirectSound_Release(ds);
66 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
67 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
68 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
69 DXGetErrorString8(rc));
71 IDirectSound8_Release(ds8);
73 if (initialized == FALSE) {
74 /* try unitialized object */
75 rc=IDirectSound8_GetCaps(dso,0);
76 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
77 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
78 DXGetErrorString8(rc));
80 rc=IDirectSound8_GetCaps(dso,&dscaps);
81 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
82 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
83 DXGetErrorString8(rc));
85 rc=IDirectSound8_Compact(dso);
86 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
87 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
88 DXGetErrorString8(rc));
90 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
91 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
92 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
93 DXGetErrorString8(rc));
95 rc=IDirectSound8_VerifyCertification(dso, &certified);
96 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
97 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
98 DXGetErrorString8(rc));
100 rc=IDirectSound8_Initialize(dso,lpGuid);
101 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
102 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
103 if (rc==DSERR_NODRIVER) {
104 trace(" No Driver\n");
106 } else if (rc==DSERR_ALLOCATED) {
107 trace(" Already In Use\n");
112 /* DSOUND: Error: Invalid caps buffer */
113 rc=IDirectSound8_GetCaps(dso,0);
114 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
115 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
116 DXGetErrorString8(rc));
118 ZeroMemory(&dscaps, sizeof(dscaps));
120 /* DSOUND: Error: Invalid caps buffer */
121 rc=IDirectSound8_GetCaps(dso,&dscaps);
122 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
123 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
124 DXGetErrorString8(rc));
126 dscaps.dwSize=sizeof(dscaps);
128 /* DSOUND: Running on a certified driver */
129 rc=IDirectSound8_GetCaps(dso,&dscaps);
130 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
132 rc=IDirectSound8_Compact(dso);
133 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
134 DXGetErrorString8(rc));
136 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
137 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
138 DXGetErrorString8(rc));
140 rc=IDirectSound8_Compact(dso);
141 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
143 rc=IDirectSound8_GetSpeakerConfig(dso,0);
144 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
145 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
146 DXGetErrorString8(rc));
148 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
149 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
150 DXGetErrorString8(rc));
152 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
153 DSSPEAKER_GEOMETRY_WIDE);
154 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
155 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
156 DXGetErrorString8(rc));
158 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
159 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
160 DXGetErrorString8(rc));
161 if (rc==DS_OK && speaker_config!=new_speaker_config)
162 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
163 "config: expected 0x%08lx, got 0x%08lx\n",
164 speaker_config,new_speaker_config);
167 rc=IDirectSound8_VerifyCertification(dso, &certified);
168 ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
169 DXGetErrorString8(rc));
171 ref=IDirectSound8_Release(dso);
172 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
175 static void IDirectSound8_tests()
178 LPDIRECTSOUND8 dso=NULL;
180 trace("Testing IDirectSound8\n");
182 /* try the COM class factory method of creation with no device specified */
183 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
184 &IID_IDirectSound8, (void**)&dso);
185 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
187 IDirectSound8_test(dso, FALSE, NULL);
189 /* try the COM class factory method of creation with default playback
190 * device specified */
191 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
192 &IID_IDirectSound8, (void**)&dso);
193 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
194 DXGetErrorString8(rc));
196 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
198 /* try the COM class factory method of creation with default voice
199 * playback device specified */
200 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
201 &IID_IDirectSound8, (void**)&dso);
202 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
203 DXGetErrorString8(rc));
205 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
207 /* try the COM class factory method of creation with a bad
209 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
210 &CLSID_DirectSoundPrivate, (void**)&dso);
211 ok(rc==E_NOINTERFACE,
212 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
213 "should have failed: %s\n",DXGetErrorString8(rc));
215 /* try the COM class factory method of creation with a bad
216 * GUID and IID specified */
217 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
218 &IID_IDirectSound8, (void**)&dso);
219 ok(rc==REGDB_E_CLASSNOTREG,
220 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
221 "should have failed: %s\n",DXGetErrorString8(rc));
223 /* try with no device specified */
224 rc=pDirectSoundCreate8(NULL,&dso,NULL);
225 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
226 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
227 if (rc==DS_OK && dso)
228 IDirectSound8_test(dso, TRUE, NULL);
230 /* try with default playback device specified */
231 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
232 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
233 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
234 if (rc==DS_OK && dso)
235 IDirectSound8_test(dso, TRUE, NULL);
237 /* try with default voice playback device specified */
238 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
239 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
240 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
241 if (rc==DS_OK && dso)
242 IDirectSound8_test(dso, TRUE, NULL);
244 /* try with a bad device specified */
245 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
246 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
247 "should have failed: %s\n",DXGetErrorString8(rc));
250 static HRESULT test_dsound8(LPGUID lpGuid)
253 LPDIRECTSOUND8 dso=NULL;
256 /* DSOUND: Error: Invalid interface buffer */
257 rc=pDirectSoundCreate8(lpGuid,0,NULL);
258 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
259 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
261 /* Create the DirectSound8 object */
262 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
263 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
264 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
268 /* Try the enumerated device */
269 IDirectSound8_test(dso, TRUE, lpGuid);
271 /* Try the COM class factory method of creation with enumerated device */
272 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
273 &IID_IDirectSound8, (void**)&dso);
274 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
275 DXGetErrorString8(rc));
277 IDirectSound8_test(dso, FALSE, lpGuid);
279 /* Create a DirectSound8 object */
280 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
281 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
283 LPDIRECTSOUND8 dso1=NULL;
285 /* Create a second DirectSound8 object */
286 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
287 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
289 /* Release the second DirectSound8 object */
290 ref=IDirectSound8_Release(dso1);
291 ok(ref==0,"IDirectSound8_Release() has %d references, "
292 "should have 0\n",ref);
293 ok(dso!=dso1,"DirectSound8 objects should be unique: "
294 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
297 /* Release the first DirectSound8 object */
298 ref=IDirectSound8_Release(dso);
299 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
302 return DSERR_GENERIC;
306 /* Create a DirectSound8 object */
307 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
308 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
310 LPDIRECTSOUNDBUFFER secondary;
311 DSBUFFERDESC bufdesc;
314 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
315 ZeroMemory(&bufdesc, sizeof(bufdesc));
316 bufdesc.dwSize=sizeof(bufdesc);
317 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
318 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
319 bufdesc.lpwfxFormat=&wfx;
320 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
321 ok(rc==DS_OK && secondary!=NULL,
322 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
323 "buffer: %s\n",DXGetErrorString8(rc));
324 if (rc==DS_OK && secondary!=NULL) {
325 LPDIRECTSOUND3DBUFFER buffer3d;
326 LPDIRECTSOUNDBUFFER8 buffer8;
327 rc=IDirectSound8_QueryInterface(secondary,
328 &IID_IDirectSound3DBuffer,
330 ok(rc==DS_OK && buffer3d!=NULL,
331 "IDirectSound8_QueryInterface() failed: %s\n",
332 DXGetErrorString8(rc));
333 if (rc==DS_OK && buffer3d!=NULL) {
334 ref=IDirectSound3DBuffer_AddRef(buffer3d);
335 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
336 "should have 2\n",ref);
338 rc=IDirectSound8_QueryInterface(secondary,
339 &IID_IDirectSoundBuffer8,
341 if (rc==DS_OK && buffer8!=NULL) {
342 ref=IDirectSoundBuffer8_AddRef(buffer8);
343 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
344 "should have 3\n",ref);
346 ref=IDirectSoundBuffer_AddRef(secondary);
347 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
348 "should have 4\n",ref);
350 /* release with buffer */
351 ref=IDirectSound8_Release(dso);
352 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
355 return DSERR_GENERIC;
362 static HRESULT test_primary8(LPGUID lpGuid)
365 LPDIRECTSOUND8 dso=NULL;
366 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
367 DSBUFFERDESC bufdesc;
372 /* Create the DirectSound object */
373 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
374 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
375 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
379 /* Get the device capabilities */
380 ZeroMemory(&dscaps, sizeof(dscaps));
381 dscaps.dwSize=sizeof(dscaps);
382 rc=IDirectSound8_GetCaps(dso,&dscaps);
383 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
387 /* DSOUND: Error: Invalid buffer description pointer */
388 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
389 ok(rc==DSERR_INVALIDPARAM,
390 "IDirectSound8_CreateSoundBuffer should have returned "
391 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
393 /* DSOUND: Error: Invalid buffer description pointer */
394 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
395 ok(rc==DSERR_INVALIDPARAM && primary==0,
396 "IDirectSound8_CreateSoundBuffer() should have returned "
397 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
398 DXGetErrorString8(rc),(DWORD)primary);
400 /* DSOUND: Error: Invalid buffer description pointer */
401 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
402 ok(rc==DSERR_INVALIDPARAM && primary==0,
403 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
404 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
406 ZeroMemory(&bufdesc, sizeof(bufdesc));
408 /* DSOUND: Error: Invalid size */
409 /* DSOUND: Error: Invalid buffer description */
410 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
411 ok(rc==DSERR_INVALIDPARAM && primary==0,
412 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
413 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
415 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
416 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
417 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
418 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
419 DXGetErrorString8(rc));
423 /* Testing the primary buffer */
425 ZeroMemory(&bufdesc, sizeof(bufdesc));
426 bufdesc.dwSize=sizeof(bufdesc);
427 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
428 bufdesc.lpwfxFormat = &wfx;
429 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
430 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
431 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
432 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
433 if (rc==DS_OK && primary!=NULL)
434 IDirectSoundBuffer_Release(primary);
437 ZeroMemory(&bufdesc, sizeof(bufdesc));
438 bufdesc.dwSize=sizeof(bufdesc);
439 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
440 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
441 ok(rc==DS_OK && primary!=NULL,
442 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
443 "%s\n",DXGetErrorString8(rc));
444 if (rc==DS_OK && primary!=NULL) {
447 /* Try to create a second primary buffer */
448 /* DSOUND: Error: The primary buffer already exists.
449 * Any changes made to the buffer description will be ignored. */
450 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
451 ok(rc==DS_OK && second==primary,
452 "IDirectSound8_CreateSoundBuffer() should have returned original "
453 "primary buffer: %s\n",DXGetErrorString8(rc));
454 ref=IDirectSoundBuffer_Release(second);
455 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
456 "should have 1\n",ref);
458 /* Try to duplicate a primary buffer */
459 /* DSOUND: Error: Can't duplicate primary buffers */
460 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
462 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
463 "should have failed %s\n",DXGetErrorString8(rc));
465 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
466 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
467 DXGetErrorString8(rc));
469 if (winetest_interactive) {
470 trace("Playing a 5 seconds reference tone at the current volume.\n");
472 trace("(the current volume is %ld according to DirectSound)\n",
474 trace("All subsequent tones should be identical to this one.\n");
475 trace("Listen for stutter, changes in pitch, volume, etc.\n");
477 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
478 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
480 ref=IDirectSoundBuffer_Release(primary);
481 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
482 "should have 0\n",ref);
485 /* Set the CooperativeLevel back to normal */
486 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
487 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
488 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
489 DXGetErrorString8(rc));
492 ref=IDirectSound8_Release(dso);
493 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
495 return DSERR_GENERIC;
501 * Test the primary buffer at different formats while keeping the
502 * secondary buffer at a constant format.
504 static HRESULT test_primary_secondary8(LPGUID lpGuid)
507 LPDIRECTSOUND8 dso=NULL;
508 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
509 DSBUFFERDESC bufdesc;
511 WAVEFORMATEX wfx, wfx2;
514 /* Create the DirectSound object */
515 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
516 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
517 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
521 /* Get the device capabilities */
522 ZeroMemory(&dscaps, sizeof(dscaps));
523 dscaps.dwSize=sizeof(dscaps);
524 rc=IDirectSound8_GetCaps(dso,&dscaps);
525 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
529 /* We must call SetCooperativeLevel before creating primary buffer */
530 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
531 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
532 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
533 DXGetErrorString8(rc));
537 ZeroMemory(&bufdesc, sizeof(bufdesc));
538 bufdesc.dwSize=sizeof(bufdesc);
539 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
540 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
541 ok(rc==DS_OK && primary!=NULL,
542 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
543 "%s\n",DXGetErrorString8(rc));
545 if (rc==DS_OK && primary!=NULL) {
546 for (f=0;f<NB_FORMATS;f++) {
547 /* We must call SetCooperativeLevel to be allowed to call
549 /* DSOUND: Setting DirectSound cooperative level to
551 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
552 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
553 DXGetErrorString8(rc));
557 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
560 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
561 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
562 DXGetErrorString8(rc));
564 /* There is no garantee that SetFormat will actually change the
565 * format to what we asked for. It depends on what the soundcard
566 * supports. So we must re-query the format.
568 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
569 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
570 DXGetErrorString8(rc));
572 (wfx.wFormatTag!=wfx2.wFormatTag ||
573 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
574 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
575 wfx.nChannels!=wfx2.nChannels)) {
576 trace("Requested primary format tag=0x%04x %ldx%dx%d "
577 "avg.B/s=%ld align=%d\n",
578 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
579 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
580 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
581 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
582 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
585 /* Set the CooperativeLevel back to normal */
586 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
587 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
588 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
589 DXGetErrorString8(rc));
591 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
594 ZeroMemory(&bufdesc, sizeof(bufdesc));
595 bufdesc.dwSize=sizeof(bufdesc);
596 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
597 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
598 bufdesc.lpwfxFormat=&wfx2;
599 if (winetest_interactive) {
600 trace(" Testing a primary buffer at %ldx%dx%d with a "
601 "secondary buffer at %ldx%dx%d\n",
602 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
603 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
605 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
606 ok(rc==DS_OK && secondary!=NULL,
607 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
608 "buffer %s\n",DXGetErrorString8(rc));
610 if (rc==DS_OK && secondary!=NULL) {
611 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
612 winetest_interactive,1.0,0,NULL,0,0);
614 ref=IDirectSoundBuffer_Release(secondary);
615 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
616 "should have 0\n",ref);
620 ref=IDirectSoundBuffer_Release(primary);
621 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
622 "should have 0\n",ref);
625 /* Set the CooperativeLevel back to normal */
626 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
627 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
628 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
629 DXGetErrorString8(rc));
632 ref=IDirectSound8_Release(dso);
633 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
635 return DSERR_GENERIC;
640 static HRESULT test_secondary8(LPGUID lpGuid)
643 LPDIRECTSOUND8 dso=NULL;
644 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
645 DSBUFFERDESC bufdesc;
651 /* Create the DirectSound object */
652 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
653 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
654 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
658 /* Get the device capabilities */
659 ZeroMemory(&dscaps, sizeof(dscaps));
660 dscaps.dwSize=sizeof(dscaps);
661 rc=IDirectSound8_GetCaps(dso,&dscaps);
662 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
666 /* We must call SetCooperativeLevel before creating primary buffer */
667 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
668 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
669 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
670 DXGetErrorString8(rc));
674 ZeroMemory(&bufdesc, sizeof(bufdesc));
675 bufdesc.dwSize=sizeof(bufdesc);
676 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
677 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
678 ok(rc==DS_OK && primary!=NULL,
679 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
680 "%s\n",DXGetErrorString8(rc));
682 if (rc==DS_OK && primary!=NULL) {
683 for (f=0;f<NB_FORMATS;f++) {
684 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
687 ZeroMemory(&bufdesc, sizeof(bufdesc));
688 bufdesc.dwSize=sizeof(bufdesc);
689 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
690 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
691 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
692 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
693 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
694 DXGetErrorString8(rc));
695 if (rc==DS_OK && secondary!=NULL)
696 IDirectSoundBuffer_Release(secondary);
699 ZeroMemory(&bufdesc, sizeof(bufdesc));
700 bufdesc.dwSize=sizeof(bufdesc);
701 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
702 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
703 bufdesc.lpwfxFormat=&wfx;
704 if (winetest_interactive) {
705 trace(" Testing a secondary buffer at %ldx%dx%d\n",
706 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
708 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
709 ok(rc==DS_OK && secondary!=NULL,
710 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
711 "buffer: %s\n",DXGetErrorString8(rc));
713 if (rc==DS_OK && secondary!=NULL) {
714 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
715 winetest_interactive,1.0,0,NULL,0,0);
717 ref=IDirectSoundBuffer_Release(secondary);
718 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
719 "should have 0\n",ref);
723 ref=IDirectSoundBuffer_Release(primary);
724 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
725 "should have 0\n",ref);
728 /* Set the CooperativeLevel back to normal */
729 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
730 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
731 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
732 DXGetErrorString8(rc));
735 ref=IDirectSound8_Release(dso);
736 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
738 return DSERR_GENERIC;
743 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
744 LPCSTR lpcstrModule, LPVOID lpContext)
747 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
748 rc = test_dsound8(lpGuid);
749 if (rc == DSERR_NODRIVER)
750 trace(" No Driver\n");
751 else if (rc == DSERR_ALLOCATED)
752 trace(" Already In Use\n");
754 test_primary8(lpGuid);
755 test_primary_secondary8(lpGuid);
756 test_secondary8(lpGuid);
762 static void dsound8_tests()
765 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
766 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
775 hDsound = LoadLibraryA("dsound.dll");
777 trace("dsound.dll not found\n");
781 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
782 if (!pDirectSoundCreate8) {
783 trace("dsound8 test skipped\n");
787 IDirectSound8_tests();