Only print format info when in interactive mode for capture test.
[wine/multimedia.git] / dlls / dsound / tests / dsound8.c
bloba09fe0cd77d9d0306192e307feb29cd0501c88ea
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 void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
45 LPCGUID lpGuid)
47 HRESULT rc;
48 DSCAPS dscaps;
49 int ref;
50 IUnknown * unknown;
51 IDirectSound * ds;
52 IDirectSound8 * ds8;
53 DWORD speaker_config, new_speaker_config;
54 DWORD certified;
56 /* Try to Query for objects */
57 rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
58 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
59 DXGetErrorString8(rc));
60 if (rc==DS_OK)
61 IDirectSound8_Release(unknown);
63 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
64 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
65 DXGetErrorString8(rc));
66 if (rc==DS_OK)
67 IDirectSound_Release(ds);
69 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
70 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
71 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
72 DXGetErrorString8(rc));
73 if (rc==DS_OK)
74 IDirectSound8_Release(ds8);
76 if (initialized == FALSE) {
77 /* try unitialized object */
78 rc=IDirectSound8_GetCaps(dso,0);
79 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
80 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
81 DXGetErrorString8(rc));
83 rc=IDirectSound8_GetCaps(dso,&dscaps);
84 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
85 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
86 DXGetErrorString8(rc));
88 rc=IDirectSound8_Compact(dso);
89 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
90 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
91 DXGetErrorString8(rc));
93 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
94 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
95 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
96 DXGetErrorString8(rc));
98 rc=IDirectSound8_VerifyCertification(dso, &certified);
99 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
100 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
101 DXGetErrorString8(rc));
103 rc=IDirectSound8_Initialize(dso,lpGuid);
104 ok(rc==DS_OK,"IDirectSound8_Initialize() failed: %s\n",
105 DXGetErrorString8(rc));
108 /* DSOUND: Error: Invalid caps buffer */
109 rc=IDirectSound8_GetCaps(dso,0);
110 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
111 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
112 DXGetErrorString8(rc));
114 ZeroMemory(&dscaps, sizeof(dscaps));
116 /* DSOUND: Error: Invalid caps buffer */
117 rc=IDirectSound8_GetCaps(dso,&dscaps);
118 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
119 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
120 DXGetErrorString8(rc));
122 dscaps.dwSize=sizeof(dscaps);
124 /* DSOUND: Running on a certified driver */
125 rc=IDirectSound8_GetCaps(dso,&dscaps);
126 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
128 rc=IDirectSound8_Compact(dso);
129 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
130 DXGetErrorString8(rc));
132 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
133 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
134 DXGetErrorString8(rc));
136 rc=IDirectSound8_Compact(dso);
137 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
139 rc=IDirectSound8_GetSpeakerConfig(dso,0);
140 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
141 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
142 DXGetErrorString8(rc));
144 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
145 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
146 DXGetErrorString8(rc));
148 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
149 DSSPEAKER_GEOMETRY_WIDE);
150 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
151 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
152 DXGetErrorString8(rc));
153 if (rc==DS_OK) {
154 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
155 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
156 DXGetErrorString8(rc));
157 if (rc==DS_OK && speaker_config!=new_speaker_config)
158 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
159 "config: expected 0x%08lx, got 0x%08lx\n",
160 speaker_config,new_speaker_config);
163 rc=IDirectSound8_VerifyCertification(dso, &certified);
164 ok(rc==DS_OK,"IDirectSound8_VerifyCertification() failed: %s\n",
165 DXGetErrorString8(rc));
167 ref=IDirectSound8_Release(dso);
168 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
171 static void IDirectSound8_tests()
173 HRESULT rc;
174 LPDIRECTSOUND8 dso=NULL;
176 trace("Testing IDirectSound8\n");
178 /* try the COM class factory method of creation with no device specified */
179 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
180 &IID_IDirectSound8, (void**)&dso);
181 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
182 if (dso)
183 IDirectSound8_test(dso, FALSE, NULL);
185 /* try the COM class factory method of creation with default playback
186 * device specified */
187 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
188 &IID_IDirectSound8, (void**)&dso);
189 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
190 DXGetErrorString8(rc));
191 if (dso)
192 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
194 /* try the COM class factory method of creation with default voice
195 * playback 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_DefaultVoicePlayback);
203 /* try the COM class factory method of creation with a bad
204 * IID specified */
205 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
206 &CLSID_DirectSoundPrivate, (void**)&dso);
207 ok(rc==E_NOINTERFACE,
208 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
209 "should have failed: %s\n",DXGetErrorString8(rc));
211 /* try the COM class factory method of creation with a bad
212 * GUID and IID specified */
213 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
214 &IID_IDirectSound8, (void**)&dso);
215 ok(rc==REGDB_E_CLASSNOTREG,
216 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
217 "should have failed: %s\n",DXGetErrorString8(rc));
219 /* try with no device specified */
220 rc=DirectSoundCreate8(NULL,&dso,NULL);
221 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
222 if (dso)
223 IDirectSound8_test(dso, TRUE, NULL);
225 /* try with default playback device specified */
226 rc=DirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
227 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
228 if (dso)
229 IDirectSound8_test(dso, TRUE, NULL);
231 /* try with default voice playback device specified */
232 rc=DirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
233 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
234 if (dso)
235 IDirectSound8_test(dso, TRUE, NULL);
237 /* try with a bad device specified */
238 rc=DirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
239 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
240 "should have failed: %s\n",DXGetErrorString8(rc));
243 static HRESULT test_dsound8(LPGUID lpGuid)
245 HRESULT rc;
246 LPDIRECTSOUND8 dso=NULL;
247 int ref;
249 /* DSOUND: Error: Invalid interface buffer */
250 rc=DirectSoundCreate8(lpGuid,0,NULL);
251 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
252 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
254 /* Create the DirectSound8 object */
255 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
256 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
257 if (rc!=DS_OK)
258 return rc;
260 /* Try the enumerated device */
261 IDirectSound8_test(dso, TRUE, lpGuid);
263 /* Try the COM class factory method of creation with enumerated device */
264 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
265 &IID_IDirectSound8, (void**)&dso);
266 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
267 DXGetErrorString8(rc));
268 if (dso)
269 IDirectSound8_test(dso, FALSE, lpGuid);
271 /* Create a DirectSound8 object */
272 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
273 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
274 if (rc==DS_OK) {
275 LPDIRECTSOUND8 dso1=NULL;
277 /* Create a second DirectSound8 object */
278 rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
279 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
280 if (rc==DS_OK) {
281 /* Release the second DirectSound8 object */
282 ref=IDirectSound8_Release(dso1);
283 ok(ref==0,"IDirectSound8_Release() has %d references, "
284 "should have 0\n",ref);
285 ok(dso!=dso1,"DirectSound8 objects should be unique: "
286 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
289 /* Release the first DirectSound8 object */
290 ref=IDirectSound8_Release(dso);
291 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
292 ref);
293 if (ref!=0)
294 return DSERR_GENERIC;
295 } else
296 return rc;
298 /* Create a DirectSound8 object */
299 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
300 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
301 if (rc==DS_OK) {
302 LPDIRECTSOUNDBUFFER secondary;
303 DSBUFFERDESC bufdesc;
304 WAVEFORMATEX wfx;
306 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
307 ZeroMemory(&bufdesc, sizeof(bufdesc));
308 bufdesc.dwSize=sizeof(bufdesc);
309 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
310 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
311 bufdesc.lpwfxFormat=&wfx;
312 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
313 ok(rc==DS_OK && secondary!=NULL,
314 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
315 "buffer: %s\n",DXGetErrorString8(rc));
316 if (rc==DS_OK && secondary!=NULL) {
317 LPDIRECTSOUND3DBUFFER buffer3d;
318 LPDIRECTSOUNDBUFFER8 buffer8;
319 rc=IDirectSound8_QueryInterface(secondary,
320 &IID_IDirectSound3DBuffer,
321 (void **)&buffer3d);
322 ok(rc==DS_OK && buffer3d!=NULL,
323 "IDirectSound8_QueryInterface() failed: %s\n",
324 DXGetErrorString8(rc));
325 if (rc==DS_OK && buffer3d!=NULL) {
326 ref=IDirectSound3DBuffer_AddRef(buffer3d);
327 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
328 "should have 2\n",ref);
330 rc=IDirectSound8_QueryInterface(secondary,
331 &IID_IDirectSoundBuffer8,
332 (void **)&buffer8);
333 if (rc==DS_OK && buffer8!=NULL) {
334 ref=IDirectSoundBuffer8_AddRef(buffer8);
335 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
336 "should have 3\n",ref);
338 ref=IDirectSoundBuffer_AddRef(secondary);
339 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
340 "should have 4\n",ref);
342 /* release with buffer */
343 ref=IDirectSound8_Release(dso);
344 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
345 ref);
346 if (ref!=0)
347 return DSERR_GENERIC;
348 } else
349 return rc;
351 return DS_OK;
354 static HRESULT test_primary8(LPGUID lpGuid)
356 HRESULT rc;
357 LPDIRECTSOUND8 dso=NULL;
358 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
359 DSBUFFERDESC bufdesc;
360 DSCAPS dscaps;
361 int ref;
363 /* Create the DirectSound object */
364 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
365 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
366 if (rc!=DS_OK)
367 return rc;
369 /* Get the device capabilities */
370 ZeroMemory(&dscaps, sizeof(dscaps));
371 dscaps.dwSize=sizeof(dscaps);
372 rc=IDirectSound8_GetCaps(dso,&dscaps);
373 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
374 if (rc!=DS_OK)
375 goto EXIT;
377 /* DSOUND: Error: Invalid buffer description pointer */
378 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
379 ok(rc==DSERR_INVALIDPARAM,
380 "IDirectSound8_CreateSoundBuffer should have returned "
381 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
383 /* DSOUND: Error: Invalid buffer description pointer */
384 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
385 ok(rc==DSERR_INVALIDPARAM && primary==0,
386 "IDirectSound8_CreateSoundBuffer() should have returned "
387 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
388 DXGetErrorString8(rc),(DWORD)primary);
390 /* DSOUND: Error: Invalid buffer description pointer */
391 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
392 ok(rc==DSERR_INVALIDPARAM && primary==0,
393 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
394 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
396 ZeroMemory(&bufdesc, sizeof(bufdesc));
398 /* DSOUND: Error: Invalid size */
399 /* DSOUND: Error: Invalid buffer description */
400 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
401 ok(rc==DSERR_INVALIDPARAM && primary==0,
402 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
403 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
405 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
406 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
407 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
408 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
409 DXGetErrorString8(rc));
410 if (rc!=DS_OK)
411 goto EXIT;
413 /* Testing the primary buffer */
414 primary=NULL;
415 ZeroMemory(&bufdesc, sizeof(bufdesc));
416 bufdesc.dwSize=sizeof(bufdesc);
417 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
418 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
419 ok(rc==DS_OK && primary!=NULL,
420 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
421 "%s\n",DXGetErrorString8(rc));
422 if (rc==DS_OK && primary!=NULL) {
423 LONG vol;
425 /* Try to create a second primary buffer */
426 /* DSOUND: Error: The primary buffer already exists.
427 * Any changes made to the buffer description will be ignored. */
428 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
429 ok(rc==DS_OK && second==primary,
430 "IDirectSound8_CreateSoundBuffer() should have returned original "
431 "primary buffer: %s\n",DXGetErrorString8(rc));
432 ref=IDirectSoundBuffer_Release(second);
433 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
434 "should have 1\n",ref);
436 /* Try to duplicate a primary buffer */
437 /* DSOUND: Error: Can't duplicate primary buffers */
438 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
439 /* rc=0x88780032 */
440 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
441 "should have failed %s\n",DXGetErrorString8(rc));
443 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
444 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
445 DXGetErrorString8(rc));
447 if (winetest_interactive) {
448 trace("Playing a 5 seconds reference tone at the current volume.\n");
449 if (rc==DS_OK)
450 trace("(the current volume is %ld according to DirectSound)\n",
451 vol);
452 trace("All subsequent tones should be identical to this one.\n");
453 trace("Listen for stutter, changes in pitch, volume, etc.\n");
455 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
456 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
458 ref=IDirectSoundBuffer_Release(primary);
459 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
460 "should have 0\n",ref);
463 /* Set the CooperativeLevel back to normal */
464 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
465 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
466 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
467 DXGetErrorString8(rc));
469 EXIT:
470 ref=IDirectSound8_Release(dso);
471 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
472 if (ref!=0)
473 return DSERR_GENERIC;
475 return rc;
479 * Test the primary buffer at different formats while keeping the
480 * secondary buffer at a constant format.
482 static HRESULT test_primary_secondary8(LPGUID lpGuid)
484 HRESULT rc;
485 LPDIRECTSOUND8 dso=NULL;
486 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
487 DSBUFFERDESC bufdesc;
488 DSCAPS dscaps;
489 WAVEFORMATEX wfx, wfx2;
490 int f,ref;
492 /* Create the DirectSound object */
493 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
494 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
495 if (rc!=DS_OK)
496 return rc;
498 /* Get the device capabilities */
499 ZeroMemory(&dscaps, sizeof(dscaps));
500 dscaps.dwSize=sizeof(dscaps);
501 rc=IDirectSound8_GetCaps(dso,&dscaps);
502 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
503 if (rc!=DS_OK)
504 goto EXIT;
506 /* We must call SetCooperativeLevel before creating primary buffer */
507 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
508 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
509 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
510 DXGetErrorString8(rc));
511 if (rc!=DS_OK)
512 goto EXIT;
514 ZeroMemory(&bufdesc, sizeof(bufdesc));
515 bufdesc.dwSize=sizeof(bufdesc);
516 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
517 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
518 ok(rc==DS_OK && primary!=NULL,
519 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
520 "%s\n",DXGetErrorString8(rc));
522 if (rc==DS_OK && primary!=NULL) {
523 for (f=0;f<NB_FORMATS;f++) {
524 /* We must call SetCooperativeLevel to be allowed to call
525 * SetFormat */
526 /* DSOUND: Setting DirectSound cooperative level to
527 * DSSCL_PRIORITY */
528 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
529 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
530 DXGetErrorString8(rc));
531 if (rc!=DS_OK)
532 goto EXIT;
534 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
535 formats[f][2]);
536 wfx2=wfx;
537 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
538 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
539 DXGetErrorString8(rc));
541 /* There is no garantee that SetFormat will actually change the
542 * format to what we asked for. It depends on what the soundcard
543 * supports. So we must re-query the format.
545 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
546 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
547 DXGetErrorString8(rc));
548 if (rc==DS_OK &&
549 (wfx.wFormatTag!=wfx2.wFormatTag ||
550 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
551 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
552 wfx.nChannels!=wfx2.nChannels)) {
553 trace("Requested primary format tag=0x%04x %ldx%dx%d "
554 "avg.B/s=%ld align=%d\n",
555 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
556 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
557 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
558 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
559 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
562 /* Set the CooperativeLevel back to normal */
563 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
564 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
565 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
566 DXGetErrorString8(rc));
568 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
570 secondary=NULL;
571 ZeroMemory(&bufdesc, sizeof(bufdesc));
572 bufdesc.dwSize=sizeof(bufdesc);
573 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
574 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
575 bufdesc.lpwfxFormat=&wfx2;
576 if (winetest_interactive) {
577 trace(" Testing a primary buffer at %ldx%dx%d with a "
578 "secondary buffer at %ldx%dx%d\n",
579 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
580 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
582 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
583 ok(rc==DS_OK && secondary!=NULL,
584 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
585 "buffer %s\n",DXGetErrorString8(rc));
587 if (rc==DS_OK && secondary!=NULL) {
588 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
589 winetest_interactive,1.0,0,NULL,0,0);
591 ref=IDirectSoundBuffer_Release(secondary);
592 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
593 "should have 0\n",ref);
597 ref=IDirectSoundBuffer_Release(primary);
598 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
599 "should have 0\n",ref);
602 /* Set the CooperativeLevel back to normal */
603 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
604 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
605 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
606 DXGetErrorString8(rc));
608 EXIT:
609 ref=IDirectSound8_Release(dso);
610 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
611 if (ref!=0)
612 return DSERR_GENERIC;
614 return rc;
617 static HRESULT test_secondary8(LPGUID lpGuid)
619 HRESULT rc;
620 LPDIRECTSOUND8 dso=NULL;
621 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
622 DSBUFFERDESC bufdesc;
623 DSCAPS dscaps;
624 WAVEFORMATEX wfx;
625 DWORD f;
626 int ref;
628 /* Create the DirectSound object */
629 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
630 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
631 if (rc!=DS_OK)
632 return rc;
634 /* Get the device capabilities */
635 ZeroMemory(&dscaps, sizeof(dscaps));
636 dscaps.dwSize=sizeof(dscaps);
637 rc=IDirectSound8_GetCaps(dso,&dscaps);
638 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
639 if (rc!=DS_OK)
640 goto EXIT;
642 /* We must call SetCooperativeLevel before creating primary buffer */
643 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
644 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
645 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
646 DXGetErrorString8(rc));
647 if (rc!=DS_OK)
648 goto EXIT;
650 ZeroMemory(&bufdesc, sizeof(bufdesc));
651 bufdesc.dwSize=sizeof(bufdesc);
652 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
653 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
654 ok(rc==DS_OK && primary!=NULL,
655 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
656 "%s\n",DXGetErrorString8(rc));
658 if (rc==DS_OK && primary!=NULL) {
659 for (f=0;f<NB_FORMATS;f++) {
660 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
661 formats[f][2]);
662 secondary=NULL;
663 ZeroMemory(&bufdesc, sizeof(bufdesc));
664 bufdesc.dwSize=sizeof(bufdesc);
665 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
666 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
667 bufdesc.lpwfxFormat=&wfx;
668 if (winetest_interactive) {
669 trace(" Testing a secondary buffer at %ldx%dx%d\n",
670 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
672 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
673 ok(rc==DS_OK && secondary!=NULL,
674 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
675 "buffer: %s\n",DXGetErrorString8(rc));
677 if (rc==DS_OK && secondary!=NULL) {
678 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
679 winetest_interactive,1.0,0,NULL,0,0);
681 ref=IDirectSoundBuffer_Release(secondary);
682 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
683 "should have 0\n",ref);
687 ref=IDirectSoundBuffer_Release(primary);
688 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
689 "should have 0\n",ref);
692 /* Set the CooperativeLevel back to normal */
693 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
694 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
695 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
696 DXGetErrorString8(rc));
698 EXIT:
699 ref=IDirectSound8_Release(dso);
700 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
701 if (ref!=0)
702 return DSERR_GENERIC;
704 return rc;
707 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
708 LPCSTR lpcstrModule, LPVOID lpContext)
710 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
711 test_dsound8(lpGuid);
712 test_primary8(lpGuid);
713 test_primary_secondary8(lpGuid);
714 test_secondary8(lpGuid);
716 return 1;
719 static void dsound8_tests()
721 HRESULT rc;
722 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
723 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
726 START_TEST(dsound8)
728 HMODULE hDsound;
729 FARPROC pFunc;
731 CoInitialize(NULL);
733 hDsound = LoadLibraryA("dsound.dll");
734 if (!hDsound) {
735 trace("dsound.dll not found\n");
736 return;
739 pFunc = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
740 if (!pFunc) {
741 trace("dsound8 test skipped\n");
742 return;
745 IDirectSound8_tests();
746 dsound8_tests();