Don't consider a device in use a failure.
[wine/wine-kai.git] / dlls / dsound / tests / dsound8.c
blob4ccb8e4151faea4382467afb47f23e9fb1d6fa88
1 /*
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
30 #include <windows.h>
32 #include <math.h>
33 #include <stdlib.h>
35 #include "wine/test.h"
36 #include "windef.h"
37 #include "wingdi.h"
38 #include "dsound.h"
39 #include "dxerr8.h"
40 #include "dsconf.h"
42 #include "dsound_test.h"
44 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
46 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
47 LPCGUID lpGuid)
49 HRESULT rc;
50 DSCAPS dscaps;
51 int ref;
52 IUnknown * unknown;
53 IDirectSound * ds;
54 IDirectSound8 * ds8;
55 DWORD speaker_config, new_speaker_config;
56 DWORD certified;
58 /* Try to Query for objects */
59 rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
60 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
61 DXGetErrorString8(rc));
62 if (rc==DS_OK)
63 IDirectSound8_Release(unknown);
65 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
66 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
67 DXGetErrorString8(rc));
68 if (rc==DS_OK)
69 IDirectSound_Release(ds);
71 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
72 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
73 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
74 DXGetErrorString8(rc));
75 if (rc==DS_OK)
76 IDirectSound8_Release(ds8);
78 if (initialized == FALSE) {
79 /* try unitialized object */
80 rc=IDirectSound8_GetCaps(dso,0);
81 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
82 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
83 DXGetErrorString8(rc));
85 rc=IDirectSound8_GetCaps(dso,&dscaps);
86 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
87 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
88 DXGetErrorString8(rc));
90 rc=IDirectSound8_Compact(dso);
91 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
92 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
93 DXGetErrorString8(rc));
95 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
96 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
97 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
98 DXGetErrorString8(rc));
100 rc=IDirectSound8_VerifyCertification(dso, &certified);
101 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
102 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
103 DXGetErrorString8(rc));
105 rc=IDirectSound8_Initialize(dso,lpGuid);
106 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
107 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
108 if (rc==DSERR_NODRIVER) {
109 trace(" No Driver\n");
110 return;
111 } else if (rc==DSERR_ALLOCATED) {
112 trace(" Already In Use\n");
113 return;
117 /* DSOUND: Error: Invalid caps buffer */
118 rc=IDirectSound8_GetCaps(dso,0);
119 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
120 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
121 DXGetErrorString8(rc));
123 ZeroMemory(&dscaps, sizeof(dscaps));
125 /* DSOUND: Error: Invalid caps buffer */
126 rc=IDirectSound8_GetCaps(dso,&dscaps);
127 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
128 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
129 DXGetErrorString8(rc));
131 dscaps.dwSize=sizeof(dscaps);
133 /* DSOUND: Running on a certified driver */
134 rc=IDirectSound8_GetCaps(dso,&dscaps);
135 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
137 rc=IDirectSound8_Compact(dso);
138 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
139 DXGetErrorString8(rc));
141 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
142 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
143 DXGetErrorString8(rc));
145 rc=IDirectSound8_Compact(dso);
146 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
148 rc=IDirectSound8_GetSpeakerConfig(dso,0);
149 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
150 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
151 DXGetErrorString8(rc));
153 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
154 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
155 DXGetErrorString8(rc));
157 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
158 DSSPEAKER_GEOMETRY_WIDE);
159 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
160 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
161 DXGetErrorString8(rc));
162 if (rc==DS_OK) {
163 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
164 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
165 DXGetErrorString8(rc));
166 if (rc==DS_OK && speaker_config!=new_speaker_config)
167 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
168 "config: expected 0x%08lx, got 0x%08lx\n",
169 speaker_config,new_speaker_config);
172 rc=IDirectSound8_VerifyCertification(dso, &certified);
173 ok(rc==DS_OK,"IDirectSound8_VerifyCertification() failed: %s\n",
174 DXGetErrorString8(rc));
176 ref=IDirectSound8_Release(dso);
177 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
180 static void IDirectSound8_tests()
182 HRESULT rc;
183 LPDIRECTSOUND8 dso=NULL;
185 trace("Testing IDirectSound8\n");
187 /* try the COM class factory method of creation with no device specified */
188 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
189 &IID_IDirectSound8, (void**)&dso);
190 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
191 if (dso)
192 IDirectSound8_test(dso, FALSE, NULL);
194 /* try the COM class factory method of creation with default playback
195 * device specified */
196 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
197 &IID_IDirectSound8, (void**)&dso);
198 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
199 DXGetErrorString8(rc));
200 if (dso)
201 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
203 /* try the COM class factory method of creation with default voice
204 * playback device specified */
205 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
206 &IID_IDirectSound8, (void**)&dso);
207 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
208 DXGetErrorString8(rc));
209 if (dso)
210 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
212 /* try the COM class factory method of creation with a bad
213 * IID specified */
214 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
215 &CLSID_DirectSoundPrivate, (void**)&dso);
216 ok(rc==E_NOINTERFACE,
217 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
218 "should have failed: %s\n",DXGetErrorString8(rc));
220 /* try the COM class factory method of creation with a bad
221 * GUID and IID specified */
222 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
223 &IID_IDirectSound8, (void**)&dso);
224 ok(rc==REGDB_E_CLASSNOTREG,
225 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
226 "should have failed: %s\n",DXGetErrorString8(rc));
228 /* try with no device specified */
229 rc=pDirectSoundCreate8(NULL,&dso,NULL);
230 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
231 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
232 if (rc==DS_OK && dso)
233 IDirectSound8_test(dso, TRUE, NULL);
235 /* try with default playback device specified */
236 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
237 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
238 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
239 if (rc==DS_OK && dso)
240 IDirectSound8_test(dso, TRUE, NULL);
242 /* try with default voice playback device specified */
243 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
244 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
245 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
246 if (rc==DS_OK && dso)
247 IDirectSound8_test(dso, TRUE, NULL);
249 /* try with a bad device specified */
250 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
251 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
252 "should have failed: %s\n",DXGetErrorString8(rc));
255 static HRESULT test_dsound8(LPGUID lpGuid)
257 HRESULT rc;
258 LPDIRECTSOUND8 dso=NULL;
259 int ref;
261 /* DSOUND: Error: Invalid interface buffer */
262 rc=pDirectSoundCreate8(lpGuid,0,NULL);
263 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
264 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
266 /* Create the DirectSound8 object */
267 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
268 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
269 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
270 if (rc!=DS_OK)
271 return rc;
273 /* Try the enumerated device */
274 IDirectSound8_test(dso, TRUE, lpGuid);
276 /* Try the COM class factory method of creation with enumerated device */
277 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
278 &IID_IDirectSound8, (void**)&dso);
279 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
280 DXGetErrorString8(rc));
281 if (dso)
282 IDirectSound8_test(dso, FALSE, lpGuid);
284 /* Create a DirectSound8 object */
285 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
286 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
287 if (rc==DS_OK) {
288 LPDIRECTSOUND8 dso1=NULL;
290 /* Create a second DirectSound8 object */
291 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
292 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
293 if (rc==DS_OK) {
294 /* Release the second DirectSound8 object */
295 ref=IDirectSound8_Release(dso1);
296 ok(ref==0,"IDirectSound8_Release() has %d references, "
297 "should have 0\n",ref);
298 ok(dso!=dso1,"DirectSound8 objects should be unique: "
299 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
302 /* Release the first DirectSound8 object */
303 ref=IDirectSound8_Release(dso);
304 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
305 ref);
306 if (ref!=0)
307 return DSERR_GENERIC;
308 } else
309 return rc;
311 /* Create a DirectSound8 object */
312 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
313 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
314 if (rc==DS_OK) {
315 LPDIRECTSOUNDBUFFER secondary;
316 DSBUFFERDESC bufdesc;
317 WAVEFORMATEX wfx;
319 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
320 ZeroMemory(&bufdesc, sizeof(bufdesc));
321 bufdesc.dwSize=sizeof(bufdesc);
322 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
323 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
324 bufdesc.lpwfxFormat=&wfx;
325 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
326 ok(rc==DS_OK && secondary!=NULL,
327 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
328 "buffer: %s\n",DXGetErrorString8(rc));
329 if (rc==DS_OK && secondary!=NULL) {
330 LPDIRECTSOUND3DBUFFER buffer3d;
331 LPDIRECTSOUNDBUFFER8 buffer8;
332 rc=IDirectSound8_QueryInterface(secondary,
333 &IID_IDirectSound3DBuffer,
334 (void **)&buffer3d);
335 ok(rc==DS_OK && buffer3d!=NULL,
336 "IDirectSound8_QueryInterface() failed: %s\n",
337 DXGetErrorString8(rc));
338 if (rc==DS_OK && buffer3d!=NULL) {
339 ref=IDirectSound3DBuffer_AddRef(buffer3d);
340 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
341 "should have 2\n",ref);
343 rc=IDirectSound8_QueryInterface(secondary,
344 &IID_IDirectSoundBuffer8,
345 (void **)&buffer8);
346 if (rc==DS_OK && buffer8!=NULL) {
347 ref=IDirectSoundBuffer8_AddRef(buffer8);
348 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
349 "should have 3\n",ref);
351 ref=IDirectSoundBuffer_AddRef(secondary);
352 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
353 "should have 4\n",ref);
355 /* release with buffer */
356 ref=IDirectSound8_Release(dso);
357 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
358 ref);
359 if (ref!=0)
360 return DSERR_GENERIC;
361 } else
362 return rc;
364 return DS_OK;
367 static HRESULT test_primary8(LPGUID lpGuid)
369 HRESULT rc;
370 LPDIRECTSOUND8 dso=NULL;
371 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
372 DSBUFFERDESC bufdesc;
373 DSCAPS dscaps;
374 WAVEFORMATEX wfx;
375 int ref;
377 /* Create the DirectSound object */
378 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
379 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
380 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
381 if (rc!=DS_OK)
382 return rc;
384 /* Get the device capabilities */
385 ZeroMemory(&dscaps, sizeof(dscaps));
386 dscaps.dwSize=sizeof(dscaps);
387 rc=IDirectSound8_GetCaps(dso,&dscaps);
388 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
389 if (rc!=DS_OK)
390 goto EXIT;
392 /* DSOUND: Error: Invalid buffer description pointer */
393 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
394 ok(rc==DSERR_INVALIDPARAM,
395 "IDirectSound8_CreateSoundBuffer should have returned "
396 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
398 /* DSOUND: Error: Invalid buffer description pointer */
399 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
400 ok(rc==DSERR_INVALIDPARAM && primary==0,
401 "IDirectSound8_CreateSoundBuffer() should have returned "
402 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
403 DXGetErrorString8(rc),(DWORD)primary);
405 /* DSOUND: Error: Invalid buffer description pointer */
406 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
407 ok(rc==DSERR_INVALIDPARAM && primary==0,
408 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
409 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
411 ZeroMemory(&bufdesc, sizeof(bufdesc));
413 /* DSOUND: Error: Invalid size */
414 /* DSOUND: Error: Invalid buffer description */
415 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
416 ok(rc==DSERR_INVALIDPARAM && primary==0,
417 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
418 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
420 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
421 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
422 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
423 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
424 DXGetErrorString8(rc));
425 if (rc!=DS_OK)
426 goto EXIT;
428 /* Testing the primary buffer */
429 primary=NULL;
430 ZeroMemory(&bufdesc, sizeof(bufdesc));
431 bufdesc.dwSize=sizeof(bufdesc);
432 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
433 bufdesc.lpwfxFormat = &wfx;
434 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
435 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
436 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
437 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
438 if (rc==DS_OK && primary!=NULL)
439 IDirectSoundBuffer_Release(primary);
441 primary=NULL;
442 ZeroMemory(&bufdesc, sizeof(bufdesc));
443 bufdesc.dwSize=sizeof(bufdesc);
444 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
445 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
446 ok(rc==DS_OK && primary!=NULL,
447 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
448 "%s\n",DXGetErrorString8(rc));
449 if (rc==DS_OK && primary!=NULL) {
450 LONG vol;
452 /* Try to create a second primary buffer */
453 /* DSOUND: Error: The primary buffer already exists.
454 * Any changes made to the buffer description will be ignored. */
455 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
456 ok(rc==DS_OK && second==primary,
457 "IDirectSound8_CreateSoundBuffer() should have returned original "
458 "primary buffer: %s\n",DXGetErrorString8(rc));
459 ref=IDirectSoundBuffer_Release(second);
460 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
461 "should have 1\n",ref);
463 /* Try to duplicate a primary buffer */
464 /* DSOUND: Error: Can't duplicate primary buffers */
465 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
466 /* rc=0x88780032 */
467 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
468 "should have failed %s\n",DXGetErrorString8(rc));
470 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
471 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
472 DXGetErrorString8(rc));
474 if (winetest_interactive) {
475 trace("Playing a 5 seconds reference tone at the current volume.\n");
476 if (rc==DS_OK)
477 trace("(the current volume is %ld according to DirectSound)\n",
478 vol);
479 trace("All subsequent tones should be identical to this one.\n");
480 trace("Listen for stutter, changes in pitch, volume, etc.\n");
482 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
483 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
485 ref=IDirectSoundBuffer_Release(primary);
486 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
487 "should have 0\n",ref);
490 /* Set the CooperativeLevel back to normal */
491 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
492 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
493 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
494 DXGetErrorString8(rc));
496 EXIT:
497 ref=IDirectSound8_Release(dso);
498 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
499 if (ref!=0)
500 return DSERR_GENERIC;
502 return rc;
506 * Test the primary buffer at different formats while keeping the
507 * secondary buffer at a constant format.
509 static HRESULT test_primary_secondary8(LPGUID lpGuid)
511 HRESULT rc;
512 LPDIRECTSOUND8 dso=NULL;
513 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
514 DSBUFFERDESC bufdesc;
515 DSCAPS dscaps;
516 WAVEFORMATEX wfx, wfx2;
517 int f,ref;
519 /* Create the DirectSound object */
520 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
521 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
522 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
523 if (rc!=DS_OK)
524 return rc;
526 /* Get the device capabilities */
527 ZeroMemory(&dscaps, sizeof(dscaps));
528 dscaps.dwSize=sizeof(dscaps);
529 rc=IDirectSound8_GetCaps(dso,&dscaps);
530 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
531 if (rc!=DS_OK)
532 goto EXIT;
534 /* We must call SetCooperativeLevel before creating primary buffer */
535 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
536 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
537 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
538 DXGetErrorString8(rc));
539 if (rc!=DS_OK)
540 goto EXIT;
542 ZeroMemory(&bufdesc, sizeof(bufdesc));
543 bufdesc.dwSize=sizeof(bufdesc);
544 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
545 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
546 ok(rc==DS_OK && primary!=NULL,
547 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
548 "%s\n",DXGetErrorString8(rc));
550 if (rc==DS_OK && primary!=NULL) {
551 for (f=0;f<NB_FORMATS;f++) {
552 /* We must call SetCooperativeLevel to be allowed to call
553 * SetFormat */
554 /* DSOUND: Setting DirectSound cooperative level to
555 * DSSCL_PRIORITY */
556 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
557 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
558 DXGetErrorString8(rc));
559 if (rc!=DS_OK)
560 goto EXIT;
562 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
563 formats[f][2]);
564 wfx2=wfx;
565 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
566 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
567 DXGetErrorString8(rc));
569 /* There is no garantee that SetFormat will actually change the
570 * format to what we asked for. It depends on what the soundcard
571 * supports. So we must re-query the format.
573 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
574 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
575 DXGetErrorString8(rc));
576 if (rc==DS_OK &&
577 (wfx.wFormatTag!=wfx2.wFormatTag ||
578 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
579 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
580 wfx.nChannels!=wfx2.nChannels)) {
581 trace("Requested primary format tag=0x%04x %ldx%dx%d "
582 "avg.B/s=%ld align=%d\n",
583 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
584 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
585 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
586 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
587 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
590 /* Set the CooperativeLevel back to normal */
591 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
592 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
593 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
594 DXGetErrorString8(rc));
596 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
598 secondary=NULL;
599 ZeroMemory(&bufdesc, sizeof(bufdesc));
600 bufdesc.dwSize=sizeof(bufdesc);
601 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
602 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
603 bufdesc.lpwfxFormat=&wfx2;
604 if (winetest_interactive) {
605 trace(" Testing a primary buffer at %ldx%dx%d with a "
606 "secondary buffer at %ldx%dx%d\n",
607 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
608 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
610 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
611 ok(rc==DS_OK && secondary!=NULL,
612 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
613 "buffer %s\n",DXGetErrorString8(rc));
615 if (rc==DS_OK && secondary!=NULL) {
616 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
617 winetest_interactive,1.0,0,NULL,0,0);
619 ref=IDirectSoundBuffer_Release(secondary);
620 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
621 "should have 0\n",ref);
625 ref=IDirectSoundBuffer_Release(primary);
626 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
627 "should have 0\n",ref);
630 /* Set the CooperativeLevel back to normal */
631 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
632 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
633 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
634 DXGetErrorString8(rc));
636 EXIT:
637 ref=IDirectSound8_Release(dso);
638 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
639 if (ref!=0)
640 return DSERR_GENERIC;
642 return rc;
645 static HRESULT test_secondary8(LPGUID lpGuid)
647 HRESULT rc;
648 LPDIRECTSOUND8 dso=NULL;
649 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
650 DSBUFFERDESC bufdesc;
651 DSCAPS dscaps;
652 WAVEFORMATEX wfx;
653 DWORD f;
654 int ref;
656 /* Create the DirectSound object */
657 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
658 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
659 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
660 if (rc!=DS_OK)
661 return rc;
663 /* Get the device capabilities */
664 ZeroMemory(&dscaps, sizeof(dscaps));
665 dscaps.dwSize=sizeof(dscaps);
666 rc=IDirectSound8_GetCaps(dso,&dscaps);
667 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
668 if (rc!=DS_OK)
669 goto EXIT;
671 /* We must call SetCooperativeLevel before creating primary buffer */
672 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
673 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
674 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
675 DXGetErrorString8(rc));
676 if (rc!=DS_OK)
677 goto EXIT;
679 ZeroMemory(&bufdesc, sizeof(bufdesc));
680 bufdesc.dwSize=sizeof(bufdesc);
681 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
682 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
683 ok(rc==DS_OK && primary!=NULL,
684 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
685 "%s\n",DXGetErrorString8(rc));
687 if (rc==DS_OK && primary!=NULL) {
688 for (f=0;f<NB_FORMATS;f++) {
689 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
690 formats[f][2]);
691 secondary=NULL;
692 ZeroMemory(&bufdesc, sizeof(bufdesc));
693 bufdesc.dwSize=sizeof(bufdesc);
694 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
695 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
696 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
697 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
698 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
699 DXGetErrorString8(rc));
700 if (rc==DS_OK && secondary!=NULL)
701 IDirectSoundBuffer_Release(secondary);
703 secondary=NULL;
704 ZeroMemory(&bufdesc, sizeof(bufdesc));
705 bufdesc.dwSize=sizeof(bufdesc);
706 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
707 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
708 bufdesc.lpwfxFormat=&wfx;
709 if (winetest_interactive) {
710 trace(" Testing a secondary buffer at %ldx%dx%d\n",
711 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
713 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
714 ok(rc==DS_OK && secondary!=NULL,
715 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
716 "buffer: %s\n",DXGetErrorString8(rc));
718 if (rc==DS_OK && secondary!=NULL) {
719 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
720 winetest_interactive,1.0,0,NULL,0,0);
722 ref=IDirectSoundBuffer_Release(secondary);
723 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
724 "should have 0\n",ref);
728 ref=IDirectSoundBuffer_Release(primary);
729 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
730 "should have 0\n",ref);
733 /* Set the CooperativeLevel back to normal */
734 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
735 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
736 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
737 DXGetErrorString8(rc));
739 EXIT:
740 ref=IDirectSound8_Release(dso);
741 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
742 if (ref!=0)
743 return DSERR_GENERIC;
745 return rc;
748 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
749 LPCSTR lpcstrModule, LPVOID lpContext)
751 HRESULT rc;
752 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
753 rc = test_dsound8(lpGuid);
754 if (rc == DSERR_NODRIVER)
755 trace(" No Driver\n");
756 else if (rc == DSERR_ALLOCATED)
757 trace(" Already In Use\n");
758 else {
759 test_primary8(lpGuid);
760 test_primary_secondary8(lpGuid);
761 test_secondary8(lpGuid);
764 return 1;
767 static void dsound8_tests()
769 HRESULT rc;
770 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
771 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
774 START_TEST(dsound8)
776 HMODULE hDsound;
778 CoInitialize(NULL);
780 hDsound = LoadLibraryA("dsound.dll");
781 if (!hDsound) {
782 trace("dsound.dll not found\n");
783 return;
786 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
787 if (!pDirectSoundCreate8) {
788 trace("dsound8 test skipped\n");
789 return;
792 IDirectSound8_tests();
793 dsound8_tests();