Make the dsound tests run with DirectX < 8.
[wine.git] / dlls / dsound / tests / dsound8.c
blobd0b5c5e76b31382edc3e6a689362483930c582f5
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,"IDirectSound8_Initialize() failed: %s\n",
107 DXGetErrorString8(rc));
110 /* DSOUND: Error: Invalid caps buffer */
111 rc=IDirectSound8_GetCaps(dso,0);
112 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
113 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
114 DXGetErrorString8(rc));
116 ZeroMemory(&dscaps, sizeof(dscaps));
118 /* DSOUND: Error: Invalid caps buffer */
119 rc=IDirectSound8_GetCaps(dso,&dscaps);
120 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
121 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
122 DXGetErrorString8(rc));
124 dscaps.dwSize=sizeof(dscaps);
126 /* DSOUND: Running on a certified driver */
127 rc=IDirectSound8_GetCaps(dso,&dscaps);
128 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
130 rc=IDirectSound8_Compact(dso);
131 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
132 DXGetErrorString8(rc));
134 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
135 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
136 DXGetErrorString8(rc));
138 rc=IDirectSound8_Compact(dso);
139 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
141 rc=IDirectSound8_GetSpeakerConfig(dso,0);
142 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
143 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
144 DXGetErrorString8(rc));
146 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
147 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
148 DXGetErrorString8(rc));
150 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
151 DSSPEAKER_GEOMETRY_WIDE);
152 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
153 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
154 DXGetErrorString8(rc));
155 if (rc==DS_OK) {
156 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
157 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
158 DXGetErrorString8(rc));
159 if (rc==DS_OK && speaker_config!=new_speaker_config)
160 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
161 "config: expected 0x%08lx, got 0x%08lx\n",
162 speaker_config,new_speaker_config);
165 rc=IDirectSound8_VerifyCertification(dso, &certified);
166 ok(rc==DS_OK,"IDirectSound8_VerifyCertification() failed: %s\n",
167 DXGetErrorString8(rc));
169 ref=IDirectSound8_Release(dso);
170 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
173 static void IDirectSound8_tests()
175 HRESULT rc;
176 LPDIRECTSOUND8 dso=NULL;
178 trace("Testing IDirectSound8\n");
180 /* try the COM class factory method of creation with no device specified */
181 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
182 &IID_IDirectSound8, (void**)&dso);
183 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
184 if (dso)
185 IDirectSound8_test(dso, FALSE, NULL);
187 /* try the COM class factory method of creation with default playback
188 * device specified */
189 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
190 &IID_IDirectSound8, (void**)&dso);
191 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
192 DXGetErrorString8(rc));
193 if (dso)
194 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
196 /* try the COM class factory method of creation with default voice
197 * playback device specified */
198 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
199 &IID_IDirectSound8, (void**)&dso);
200 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
201 DXGetErrorString8(rc));
202 if (dso)
203 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
205 /* try the COM class factory method of creation with a bad
206 * IID specified */
207 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
208 &CLSID_DirectSoundPrivate, (void**)&dso);
209 ok(rc==E_NOINTERFACE,
210 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
211 "should have failed: %s\n",DXGetErrorString8(rc));
213 /* try the COM class factory method of creation with a bad
214 * GUID and IID specified */
215 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
216 &IID_IDirectSound8, (void**)&dso);
217 ok(rc==REGDB_E_CLASSNOTREG,
218 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
219 "should have failed: %s\n",DXGetErrorString8(rc));
221 /* try with no device specified */
222 rc=pDirectSoundCreate8(NULL,&dso,NULL);
223 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
224 if (dso)
225 IDirectSound8_test(dso, TRUE, NULL);
227 /* try with default playback device specified */
228 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
229 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
230 if (dso)
231 IDirectSound8_test(dso, TRUE, NULL);
233 /* try with default voice playback device specified */
234 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
235 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
236 if (dso)
237 IDirectSound8_test(dso, TRUE, NULL);
239 /* try with a bad device specified */
240 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
241 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
242 "should have failed: %s\n",DXGetErrorString8(rc));
245 static HRESULT test_dsound8(LPGUID lpGuid)
247 HRESULT rc;
248 LPDIRECTSOUND8 dso=NULL;
249 int ref;
251 /* DSOUND: Error: Invalid interface buffer */
252 rc=pDirectSoundCreate8(lpGuid,0,NULL);
253 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
254 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
256 /* Create the DirectSound8 object */
257 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
258 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
259 if (rc!=DS_OK)
260 return rc;
262 /* Try the enumerated device */
263 IDirectSound8_test(dso, TRUE, lpGuid);
265 /* Try the COM class factory method of creation with enumerated device */
266 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
267 &IID_IDirectSound8, (void**)&dso);
268 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
269 DXGetErrorString8(rc));
270 if (dso)
271 IDirectSound8_test(dso, FALSE, lpGuid);
273 /* Create a DirectSound8 object */
274 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
275 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
276 if (rc==DS_OK) {
277 LPDIRECTSOUND8 dso1=NULL;
279 /* Create a second DirectSound8 object */
280 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
281 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
282 if (rc==DS_OK) {
283 /* Release the second DirectSound8 object */
284 ref=IDirectSound8_Release(dso1);
285 ok(ref==0,"IDirectSound8_Release() has %d references, "
286 "should have 0\n",ref);
287 ok(dso!=dso1,"DirectSound8 objects should be unique: "
288 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
291 /* Release the first DirectSound8 object */
292 ref=IDirectSound8_Release(dso);
293 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
294 ref);
295 if (ref!=0)
296 return DSERR_GENERIC;
297 } else
298 return rc;
300 /* Create a DirectSound8 object */
301 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
302 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
303 if (rc==DS_OK) {
304 LPDIRECTSOUNDBUFFER secondary;
305 DSBUFFERDESC bufdesc;
306 WAVEFORMATEX wfx;
308 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
309 ZeroMemory(&bufdesc, sizeof(bufdesc));
310 bufdesc.dwSize=sizeof(bufdesc);
311 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
312 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
313 bufdesc.lpwfxFormat=&wfx;
314 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
315 ok(rc==DS_OK && secondary!=NULL,
316 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
317 "buffer: %s\n",DXGetErrorString8(rc));
318 if (rc==DS_OK && secondary!=NULL) {
319 LPDIRECTSOUND3DBUFFER buffer3d;
320 LPDIRECTSOUNDBUFFER8 buffer8;
321 rc=IDirectSound8_QueryInterface(secondary,
322 &IID_IDirectSound3DBuffer,
323 (void **)&buffer3d);
324 ok(rc==DS_OK && buffer3d!=NULL,
325 "IDirectSound8_QueryInterface() failed: %s\n",
326 DXGetErrorString8(rc));
327 if (rc==DS_OK && buffer3d!=NULL) {
328 ref=IDirectSound3DBuffer_AddRef(buffer3d);
329 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
330 "should have 2\n",ref);
332 rc=IDirectSound8_QueryInterface(secondary,
333 &IID_IDirectSoundBuffer8,
334 (void **)&buffer8);
335 if (rc==DS_OK && buffer8!=NULL) {
336 ref=IDirectSoundBuffer8_AddRef(buffer8);
337 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
338 "should have 3\n",ref);
340 ref=IDirectSoundBuffer_AddRef(secondary);
341 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
342 "should have 4\n",ref);
344 /* release with buffer */
345 ref=IDirectSound8_Release(dso);
346 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
347 ref);
348 if (ref!=0)
349 return DSERR_GENERIC;
350 } else
351 return rc;
353 return DS_OK;
356 static HRESULT test_primary8(LPGUID lpGuid)
358 HRESULT rc;
359 LPDIRECTSOUND8 dso=NULL;
360 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
361 DSBUFFERDESC bufdesc;
362 DSCAPS dscaps;
363 WAVEFORMATEX wfx;
364 int ref;
366 /* Create the DirectSound object */
367 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
368 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
369 if (rc!=DS_OK)
370 return rc;
372 /* Get the device capabilities */
373 ZeroMemory(&dscaps, sizeof(dscaps));
374 dscaps.dwSize=sizeof(dscaps);
375 rc=IDirectSound8_GetCaps(dso,&dscaps);
376 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
377 if (rc!=DS_OK)
378 goto EXIT;
380 /* DSOUND: Error: Invalid buffer description pointer */
381 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
382 ok(rc==DSERR_INVALIDPARAM,
383 "IDirectSound8_CreateSoundBuffer should have returned "
384 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
386 /* DSOUND: Error: Invalid buffer description pointer */
387 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
388 ok(rc==DSERR_INVALIDPARAM && primary==0,
389 "IDirectSound8_CreateSoundBuffer() should have returned "
390 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
391 DXGetErrorString8(rc),(DWORD)primary);
393 /* DSOUND: Error: Invalid buffer description pointer */
394 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
395 ok(rc==DSERR_INVALIDPARAM && primary==0,
396 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
397 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
399 ZeroMemory(&bufdesc, sizeof(bufdesc));
401 /* DSOUND: Error: Invalid size */
402 /* DSOUND: Error: Invalid buffer description */
403 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
404 ok(rc==DSERR_INVALIDPARAM && primary==0,
405 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
406 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
408 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
409 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
410 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
411 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
412 DXGetErrorString8(rc));
413 if (rc!=DS_OK)
414 goto EXIT;
416 /* Testing the primary buffer */
417 primary=NULL;
418 ZeroMemory(&bufdesc, sizeof(bufdesc));
419 bufdesc.dwSize=sizeof(bufdesc);
420 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
421 bufdesc.lpwfxFormat = &wfx;
422 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
423 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
424 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
425 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
426 if (rc==DS_OK && primary!=NULL)
427 IDirectSoundBuffer_Release(primary);
429 primary=NULL;
430 ZeroMemory(&bufdesc, sizeof(bufdesc));
431 bufdesc.dwSize=sizeof(bufdesc);
432 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
433 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
434 ok(rc==DS_OK && primary!=NULL,
435 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
436 "%s\n",DXGetErrorString8(rc));
437 if (rc==DS_OK && primary!=NULL) {
438 LONG vol;
440 /* Try to create a second primary buffer */
441 /* DSOUND: Error: The primary buffer already exists.
442 * Any changes made to the buffer description will be ignored. */
443 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
444 ok(rc==DS_OK && second==primary,
445 "IDirectSound8_CreateSoundBuffer() should have returned original "
446 "primary buffer: %s\n",DXGetErrorString8(rc));
447 ref=IDirectSoundBuffer_Release(second);
448 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
449 "should have 1\n",ref);
451 /* Try to duplicate a primary buffer */
452 /* DSOUND: Error: Can't duplicate primary buffers */
453 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
454 /* rc=0x88780032 */
455 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
456 "should have failed %s\n",DXGetErrorString8(rc));
458 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
459 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
460 DXGetErrorString8(rc));
462 if (winetest_interactive) {
463 trace("Playing a 5 seconds reference tone at the current volume.\n");
464 if (rc==DS_OK)
465 trace("(the current volume is %ld according to DirectSound)\n",
466 vol);
467 trace("All subsequent tones should be identical to this one.\n");
468 trace("Listen for stutter, changes in pitch, volume, etc.\n");
470 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
471 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
473 ref=IDirectSoundBuffer_Release(primary);
474 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
475 "should have 0\n",ref);
478 /* Set the CooperativeLevel back to normal */
479 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
480 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
481 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
482 DXGetErrorString8(rc));
484 EXIT:
485 ref=IDirectSound8_Release(dso);
486 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
487 if (ref!=0)
488 return DSERR_GENERIC;
490 return rc;
494 * Test the primary buffer at different formats while keeping the
495 * secondary buffer at a constant format.
497 static HRESULT test_primary_secondary8(LPGUID lpGuid)
499 HRESULT rc;
500 LPDIRECTSOUND8 dso=NULL;
501 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
502 DSBUFFERDESC bufdesc;
503 DSCAPS dscaps;
504 WAVEFORMATEX wfx, wfx2;
505 int f,ref;
507 /* Create the DirectSound object */
508 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
509 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
510 if (rc!=DS_OK)
511 return rc;
513 /* Get the device capabilities */
514 ZeroMemory(&dscaps, sizeof(dscaps));
515 dscaps.dwSize=sizeof(dscaps);
516 rc=IDirectSound8_GetCaps(dso,&dscaps);
517 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
518 if (rc!=DS_OK)
519 goto EXIT;
521 /* We must call SetCooperativeLevel before creating primary buffer */
522 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
523 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
524 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
525 DXGetErrorString8(rc));
526 if (rc!=DS_OK)
527 goto EXIT;
529 ZeroMemory(&bufdesc, sizeof(bufdesc));
530 bufdesc.dwSize=sizeof(bufdesc);
531 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
532 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
533 ok(rc==DS_OK && primary!=NULL,
534 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
535 "%s\n",DXGetErrorString8(rc));
537 if (rc==DS_OK && primary!=NULL) {
538 for (f=0;f<NB_FORMATS;f++) {
539 /* We must call SetCooperativeLevel to be allowed to call
540 * SetFormat */
541 /* DSOUND: Setting DirectSound cooperative level to
542 * DSSCL_PRIORITY */
543 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
544 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
545 DXGetErrorString8(rc));
546 if (rc!=DS_OK)
547 goto EXIT;
549 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
550 formats[f][2]);
551 wfx2=wfx;
552 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
553 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
554 DXGetErrorString8(rc));
556 /* There is no garantee that SetFormat will actually change the
557 * format to what we asked for. It depends on what the soundcard
558 * supports. So we must re-query the format.
560 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
561 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
562 DXGetErrorString8(rc));
563 if (rc==DS_OK &&
564 (wfx.wFormatTag!=wfx2.wFormatTag ||
565 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
566 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
567 wfx.nChannels!=wfx2.nChannels)) {
568 trace("Requested primary format tag=0x%04x %ldx%dx%d "
569 "avg.B/s=%ld align=%d\n",
570 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
571 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
572 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
573 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
574 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
577 /* Set the CooperativeLevel back to normal */
578 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
579 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
580 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
581 DXGetErrorString8(rc));
583 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
585 secondary=NULL;
586 ZeroMemory(&bufdesc, sizeof(bufdesc));
587 bufdesc.dwSize=sizeof(bufdesc);
588 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
589 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
590 bufdesc.lpwfxFormat=&wfx2;
591 if (winetest_interactive) {
592 trace(" Testing a primary buffer at %ldx%dx%d with a "
593 "secondary buffer at %ldx%dx%d\n",
594 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
595 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
597 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
598 ok(rc==DS_OK && secondary!=NULL,
599 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
600 "buffer %s\n",DXGetErrorString8(rc));
602 if (rc==DS_OK && secondary!=NULL) {
603 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
604 winetest_interactive,1.0,0,NULL,0,0);
606 ref=IDirectSoundBuffer_Release(secondary);
607 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
608 "should have 0\n",ref);
612 ref=IDirectSoundBuffer_Release(primary);
613 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
614 "should have 0\n",ref);
617 /* Set the CooperativeLevel back to normal */
618 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
619 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
620 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
621 DXGetErrorString8(rc));
623 EXIT:
624 ref=IDirectSound8_Release(dso);
625 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
626 if (ref!=0)
627 return DSERR_GENERIC;
629 return rc;
632 static HRESULT test_secondary8(LPGUID lpGuid)
634 HRESULT rc;
635 LPDIRECTSOUND8 dso=NULL;
636 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
637 DSBUFFERDESC bufdesc;
638 DSCAPS dscaps;
639 WAVEFORMATEX wfx;
640 DWORD f;
641 int ref;
643 /* Create the DirectSound object */
644 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
645 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
646 if (rc!=DS_OK)
647 return rc;
649 /* Get the device capabilities */
650 ZeroMemory(&dscaps, sizeof(dscaps));
651 dscaps.dwSize=sizeof(dscaps);
652 rc=IDirectSound8_GetCaps(dso,&dscaps);
653 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
654 if (rc!=DS_OK)
655 goto EXIT;
657 /* We must call SetCooperativeLevel before creating primary buffer */
658 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
659 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
660 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
661 DXGetErrorString8(rc));
662 if (rc!=DS_OK)
663 goto EXIT;
665 ZeroMemory(&bufdesc, sizeof(bufdesc));
666 bufdesc.dwSize=sizeof(bufdesc);
667 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
668 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
669 ok(rc==DS_OK && primary!=NULL,
670 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
671 "%s\n",DXGetErrorString8(rc));
673 if (rc==DS_OK && primary!=NULL) {
674 for (f=0;f<NB_FORMATS;f++) {
675 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
676 formats[f][2]);
677 secondary=NULL;
678 ZeroMemory(&bufdesc, sizeof(bufdesc));
679 bufdesc.dwSize=sizeof(bufdesc);
680 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
681 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
682 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
683 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
684 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
685 DXGetErrorString8(rc));
686 if (rc==DS_OK && secondary!=NULL)
687 IDirectSoundBuffer_Release(secondary);
689 secondary=NULL;
690 ZeroMemory(&bufdesc, sizeof(bufdesc));
691 bufdesc.dwSize=sizeof(bufdesc);
692 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
693 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
694 bufdesc.lpwfxFormat=&wfx;
695 if (winetest_interactive) {
696 trace(" Testing a secondary buffer at %ldx%dx%d\n",
697 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
699 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
700 ok(rc==DS_OK && secondary!=NULL,
701 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
702 "buffer: %s\n",DXGetErrorString8(rc));
704 if (rc==DS_OK && secondary!=NULL) {
705 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
706 winetest_interactive,1.0,0,NULL,0,0);
708 ref=IDirectSoundBuffer_Release(secondary);
709 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
710 "should have 0\n",ref);
714 ref=IDirectSoundBuffer_Release(primary);
715 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
716 "should have 0\n",ref);
719 /* Set the CooperativeLevel back to normal */
720 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
721 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
722 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
723 DXGetErrorString8(rc));
725 EXIT:
726 ref=IDirectSound8_Release(dso);
727 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
728 if (ref!=0)
729 return DSERR_GENERIC;
731 return rc;
734 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
735 LPCSTR lpcstrModule, LPVOID lpContext)
737 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
738 test_dsound8(lpGuid);
739 test_primary8(lpGuid);
740 test_primary_secondary8(lpGuid);
741 test_secondary8(lpGuid);
743 return 1;
746 static void dsound8_tests()
748 HRESULT rc;
749 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
750 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
753 START_TEST(dsound8)
755 HMODULE hDsound;
757 CoInitialize(NULL);
759 hDsound = LoadLibraryA("dsound.dll");
760 if (!hDsound) {
761 trace("dsound.dll not found\n");
762 return;
765 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
766 if (!pDirectSoundCreate8) {
767 trace("dsound8 test skipped\n");
768 return;
771 IDirectSound8_tests();
772 dsound8_tests();