More dsound tests error message cleanups.
[wine.git] / dlls / dsound / tests / dsound8.c
blob863ae14f169191e81da413928d25c24750f1438e
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)
158 ok(speaker_config==new_speaker_config,
159 "IDirectSound8_GetSpeakerConfig() failed to set speaker config: "
160 "expected 0x%08lx, got 0x%08lx\n",
161 speaker_config,new_speaker_config);
164 rc=IDirectSound8_VerifyCertification(dso, &certified);
165 ok(rc==DS_OK,"IDirectSound8_VerifyCertification() failed: %s\n",
166 DXGetErrorString8(rc));
168 ref=IDirectSound8_Release(dso);
169 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
172 static void IDirectSound8_tests()
174 HRESULT rc;
175 LPDIRECTSOUND8 dso=NULL;
177 trace("Testing IDirectSound8\n");
179 /* try the COM class factory method of creation with no device specified */
180 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
181 &IID_IDirectSound8, (void**)&dso);
182 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
183 if (dso)
184 IDirectSound8_test(dso, FALSE, NULL);
186 /* try the COM class factory method of creation with default playback
187 * device specified */
188 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
189 &IID_IDirectSound8, (void**)&dso);
190 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
191 DXGetErrorString8(rc));
192 if (dso)
193 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
195 /* try the COM class factory method of creation with default voice
196 * playback device specified */
197 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
198 &IID_IDirectSound8, (void**)&dso);
199 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
200 DXGetErrorString8(rc));
201 if (dso)
202 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
204 /* try the COM class factory method of creation with a bad
205 * IID specified */
206 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
207 &CLSID_DirectSoundPrivate, (void**)&dso);
208 ok(rc==E_NOINTERFACE,
209 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
210 "should have failed: %s\n",DXGetErrorString8(rc));
212 /* try the COM class factory method of creation with a bad
213 * GUID and IID specified */
214 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
215 &IID_IDirectSound8, (void**)&dso);
216 ok(rc==REGDB_E_CLASSNOTREG,
217 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
218 "should have failed: %s\n",DXGetErrorString8(rc));
220 /* try with no device specified */
221 rc=DirectSoundCreate8(NULL,&dso,NULL);
222 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
223 if (dso)
224 IDirectSound8_test(dso, TRUE, NULL);
226 /* try with default playback device specified */
227 rc=DirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
228 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
229 if (dso)
230 IDirectSound8_test(dso, TRUE, NULL);
232 /* try with default voice playback device specified */
233 rc=DirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
234 ok(rc==S_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
235 if (dso)
236 IDirectSound8_test(dso, TRUE, NULL);
238 /* try with a bad device specified */
239 rc=DirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
240 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
241 "should have failed: %s\n",DXGetErrorString8(rc));
244 static HRESULT test_dsound8(LPGUID lpGuid)
246 HRESULT rc;
247 LPDIRECTSOUND8 dso=NULL;
248 int ref;
250 /* DSOUND: Error: Invalid interface buffer */
251 rc=DirectSoundCreate8(lpGuid,0,NULL);
252 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
253 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
255 /* Create the DirectSound8 object */
256 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
257 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
258 if (rc!=DS_OK)
259 return rc;
261 /* Try the enumerated device */
262 IDirectSound8_test(dso, TRUE, lpGuid);
264 /* Try the COM class factory method of creation with enumerated device */
265 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
266 &IID_IDirectSound8, (void**)&dso);
267 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
268 DXGetErrorString8(rc));
269 if (dso)
270 IDirectSound8_test(dso, FALSE, lpGuid);
272 /* Create a DirectSound8 object */
273 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
274 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
275 if (rc==DS_OK) {
276 LPDIRECTSOUND8 dso1=NULL;
278 /* Create a second DirectSound8 object */
279 rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
280 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
281 if (rc==DS_OK) {
282 /* Release the second DirectSound8 object */
283 ref=IDirectSound8_Release(dso1);
284 ok(ref==0,"IDirectSound8_Release() has %d references, "
285 "should have 0\n",ref);
286 ok(dso!=dso1,"DirectSound8 objects should be unique: "
287 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
290 /* Release the first DirectSound8 object */
291 ref=IDirectSound8_Release(dso);
292 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
293 ref);
294 if (ref!=0)
295 return DSERR_GENERIC;
296 } else
297 return rc;
299 /* Create a DirectSound8 object */
300 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
301 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
302 if (rc==DS_OK) {
303 LPDIRECTSOUNDBUFFER secondary;
304 DSBUFFERDESC bufdesc;
305 WAVEFORMATEX wfx;
307 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
308 ZeroMemory(&bufdesc, sizeof(bufdesc));
309 bufdesc.dwSize=sizeof(bufdesc);
310 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
311 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
312 bufdesc.lpwfxFormat=&wfx;
313 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
314 ok(rc==DS_OK && secondary!=NULL,
315 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
316 "buffer: %s\n",DXGetErrorString8(rc));
317 if (rc==DS_OK && secondary!=NULL) {
318 LPDIRECTSOUND3DBUFFER buffer3d;
319 LPDIRECTSOUNDBUFFER8 buffer8;
320 rc=IDirectSound8_QueryInterface(secondary,
321 &IID_IDirectSound3DBuffer,
322 (void **)&buffer3d);
323 ok(rc==DS_OK && buffer3d!=NULL,
324 "IDirectSound8_QueryInterface() failed: %s\n",
325 DXGetErrorString8(rc));
326 if (rc==DS_OK && buffer3d!=NULL) {
327 ref=IDirectSound3DBuffer_AddRef(buffer3d);
328 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
329 "should have 2\n",ref);
331 rc=IDirectSound8_QueryInterface(secondary,
332 &IID_IDirectSoundBuffer8,
333 (void **)&buffer8);
334 if (rc==DS_OK && buffer8!=NULL) {
335 ref=IDirectSoundBuffer8_AddRef(buffer8);
336 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
337 "should have 3\n",ref);
339 ref=IDirectSoundBuffer_AddRef(secondary);
340 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
341 "should have 4\n",ref);
343 /* release with buffer */
344 ref=IDirectSound8_Release(dso);
345 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
346 ref);
347 if (ref!=0)
348 return DSERR_GENERIC;
349 } else
350 return rc;
352 return DS_OK;
355 static HRESULT test_primary8(LPGUID lpGuid)
357 HRESULT rc;
358 LPDIRECTSOUND8 dso=NULL;
359 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
360 DSBUFFERDESC bufdesc;
361 DSCAPS dscaps;
362 int ref;
364 /* Create the DirectSound object */
365 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
366 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
367 if (rc!=DS_OK)
368 return rc;
370 /* Get the device capabilities */
371 ZeroMemory(&dscaps, sizeof(dscaps));
372 dscaps.dwSize=sizeof(dscaps);
373 rc=IDirectSound8_GetCaps(dso,&dscaps);
374 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
375 if (rc!=DS_OK)
376 goto EXIT;
378 /* DSOUND: Error: Invalid buffer description pointer */
379 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
380 ok(rc==DSERR_INVALIDPARAM,
381 "IDirectSound8_CreateSoundBuffer should have returned "
382 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
384 /* DSOUND: Error: Invalid buffer description pointer */
385 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
386 ok(rc==DSERR_INVALIDPARAM && primary==0,
387 "IDirectSound8_CreateSoundBuffer() should have returned "
388 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
389 DXGetErrorString8(rc),(DWORD)primary);
391 /* DSOUND: Error: Invalid buffer description pointer */
392 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
393 ok(rc==DSERR_INVALIDPARAM && primary==0,
394 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
395 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
397 ZeroMemory(&bufdesc, sizeof(bufdesc));
399 /* DSOUND: Error: Invalid size */
400 /* DSOUND: Error: Invalid buffer description */
401 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
402 ok(rc==DSERR_INVALIDPARAM && primary==0,
403 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
404 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
406 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
407 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
408 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
409 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
410 DXGetErrorString8(rc));
411 if (rc!=DS_OK)
412 goto EXIT;
414 /* Testing the primary buffer */
415 primary=NULL;
416 ZeroMemory(&bufdesc, sizeof(bufdesc));
417 bufdesc.dwSize=sizeof(bufdesc);
418 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
419 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
420 ok(rc==DS_OK && primary!=NULL,
421 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
422 "%s\n",DXGetErrorString8(rc));
423 if (rc==DS_OK && primary!=NULL) {
424 LONG vol;
426 /* Try to create a second primary buffer */
427 /* DSOUND: Error: The primary buffer already exists.
428 * Any changes made to the buffer description will be ignored. */
429 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
430 ok(rc==DS_OK && second==primary,
431 "IDirectSound8_CreateSoundBuffer() should have returned original "
432 "primary buffer: %s\n",DXGetErrorString8(rc));
433 ref=IDirectSoundBuffer_Release(second);
434 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
435 "should have 1\n",ref);
437 /* Try to duplicate a primary buffer */
438 /* DSOUND: Error: Can't duplicate primary buffers */
439 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
440 /* rc=0x88780032 */
441 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
442 "should have failed %s\n",DXGetErrorString8(rc));
444 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
445 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
446 DXGetErrorString8(rc));
448 if (winetest_interactive) {
449 trace("Playing a 5 seconds reference tone at the current volume.\n");
450 if (rc==DS_OK)
451 trace("(the current volume is %ld according to DirectSound)\n",
452 vol);
453 trace("All subsequent tones should be identical to this one.\n");
454 trace("Listen for stutter, changes in pitch, volume, etc.\n");
456 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
457 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
459 ref=IDirectSoundBuffer_Release(primary);
460 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
461 "should have 0\n",ref);
464 /* Set the CooperativeLevel back to normal */
465 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
466 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
467 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
468 DXGetErrorString8(rc));
470 EXIT:
471 ref=IDirectSound8_Release(dso);
472 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
473 if (ref!=0)
474 return DSERR_GENERIC;
476 return rc;
480 * Test the primary buffer at different formats while keeping the
481 * secondary buffer at a constant format.
483 static HRESULT test_primary_secondary8(LPGUID lpGuid)
485 HRESULT rc;
486 LPDIRECTSOUND8 dso=NULL;
487 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
488 DSBUFFERDESC bufdesc;
489 DSCAPS dscaps;
490 WAVEFORMATEX wfx, wfx2;
491 int f,ref;
493 /* Create the DirectSound object */
494 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
495 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
496 if (rc!=DS_OK)
497 return rc;
499 /* Get the device capabilities */
500 ZeroMemory(&dscaps, sizeof(dscaps));
501 dscaps.dwSize=sizeof(dscaps);
502 rc=IDirectSound8_GetCaps(dso,&dscaps);
503 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
504 if (rc!=DS_OK)
505 goto EXIT;
507 /* We must call SetCooperativeLevel before creating primary buffer */
508 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
509 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
510 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
511 DXGetErrorString8(rc));
512 if (rc!=DS_OK)
513 goto EXIT;
515 ZeroMemory(&bufdesc, sizeof(bufdesc));
516 bufdesc.dwSize=sizeof(bufdesc);
517 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
518 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
519 ok(rc==DS_OK && primary!=NULL,
520 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
521 "%s\n",DXGetErrorString8(rc));
523 if (rc==DS_OK && primary!=NULL) {
524 for (f=0;f<NB_FORMATS;f++) {
525 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
526 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
527 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
528 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
529 DXGetErrorString8(rc));
530 if (rc!=DS_OK)
531 goto EXIT;
533 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
534 formats[f][2]);
535 wfx2=wfx;
536 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
537 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
538 DXGetErrorString8(rc));
540 /* There is no garantee that SetFormat will actually change the
541 * format to what we asked for. It depends on what the soundcard
542 * supports. So we must re-query the format.
544 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
545 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
546 DXGetErrorString8(rc));
547 if (rc==DS_OK &&
548 (wfx.wFormatTag!=wfx2.wFormatTag ||
549 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
550 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
551 wfx.nChannels!=wfx2.nChannels)) {
552 trace("Requested primary format tag=0x%04x %ldx%dx%d "
553 "avg.B/s=%ld align=%d\n",
554 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
555 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
556 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
557 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
558 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
561 /* Set the CooperativeLevel back to normal */
562 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
563 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
564 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
565 DXGetErrorString8(rc));
567 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
569 secondary=NULL;
570 ZeroMemory(&bufdesc, sizeof(bufdesc));
571 bufdesc.dwSize=sizeof(bufdesc);
572 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
573 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
574 bufdesc.lpwfxFormat=&wfx2;
575 if (winetest_interactive) {
576 trace(" Testing a primary buffer at %ldx%dx%d with a "
577 "secondary buffer at %ldx%dx%d\n",
578 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
579 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
581 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
582 ok(rc==DS_OK && secondary!=NULL,
583 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
584 "buffer %s\n",DXGetErrorString8(rc));
586 if (rc==DS_OK && secondary!=NULL) {
587 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
588 winetest_interactive,1.0,0,NULL,0,0);
590 ref=IDirectSoundBuffer_Release(secondary);
591 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
592 "should have 0\n",ref);
596 ref=IDirectSoundBuffer_Release(primary);
597 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
598 "should have 0\n",ref);
601 /* Set the CooperativeLevel back to normal */
602 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
603 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
604 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
605 DXGetErrorString8(rc));
607 EXIT:
608 ref=IDirectSound8_Release(dso);
609 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
610 if (ref!=0)
611 return DSERR_GENERIC;
613 return rc;
616 static HRESULT test_secondary8(LPGUID lpGuid)
618 HRESULT rc;
619 LPDIRECTSOUND8 dso=NULL;
620 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
621 DSBUFFERDESC bufdesc;
622 DSCAPS dscaps;
623 WAVEFORMATEX wfx;
624 DWORD f;
625 int ref;
627 /* Create the DirectSound object */
628 rc=DirectSoundCreate8(lpGuid,&dso,NULL);
629 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
630 if (rc!=DS_OK)
631 return rc;
633 /* Get the device capabilities */
634 ZeroMemory(&dscaps, sizeof(dscaps));
635 dscaps.dwSize=sizeof(dscaps);
636 rc=IDirectSound8_GetCaps(dso,&dscaps);
637 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
638 if (rc!=DS_OK)
639 goto EXIT;
641 /* We must call SetCooperativeLevel before creating primary buffer */
642 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
643 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
644 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
645 DXGetErrorString8(rc));
646 if (rc!=DS_OK)
647 goto EXIT;
649 ZeroMemory(&bufdesc, sizeof(bufdesc));
650 bufdesc.dwSize=sizeof(bufdesc);
651 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
652 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
653 ok(rc==DS_OK && primary!=NULL,
654 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
655 "%s\n",DXGetErrorString8(rc));
657 if (rc==DS_OK && primary!=NULL) {
658 for (f=0;f<NB_FORMATS;f++) {
659 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
660 formats[f][2]);
661 secondary=NULL;
662 ZeroMemory(&bufdesc, sizeof(bufdesc));
663 bufdesc.dwSize=sizeof(bufdesc);
664 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
665 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
666 bufdesc.lpwfxFormat=&wfx;
667 if (winetest_interactive) {
668 trace(" Testing a secondary buffer at %ldx%dx%d\n",
669 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
671 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
672 ok(rc==DS_OK && secondary!=NULL,
673 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
674 "buffer: %s\n",DXGetErrorString8(rc));
676 if (rc==DS_OK && secondary!=NULL) {
677 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
678 winetest_interactive,1.0,0,NULL,0,0);
680 ref=IDirectSoundBuffer_Release(secondary);
681 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
682 "should have 0\n",ref);
686 ref=IDirectSoundBuffer_Release(primary);
687 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
688 "should have 0\n",ref);
691 /* Set the CooperativeLevel back to normal */
692 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
693 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
694 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
695 DXGetErrorString8(rc));
697 EXIT:
698 ref=IDirectSound8_Release(dso);
699 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
700 if (ref!=0)
701 return DSERR_GENERIC;
703 return rc;
706 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
707 LPCSTR lpcstrModule, LPVOID lpContext)
709 trace("*** Testing %s - %s\n",lpcstrDescription,lpcstrModule);
710 test_dsound8(lpGuid);
711 test_primary8(lpGuid);
712 test_primary_secondary8(lpGuid);
713 test_secondary8(lpGuid);
715 return 1;
718 static void dsound8_tests()
720 HRESULT rc;
721 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
722 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
725 START_TEST(dsound8)
727 HMODULE hDsound;
728 FARPROC pFunc;
730 CoInitialize(NULL);
732 hDsound = LoadLibraryA("dsound.dll");
733 if (!hDsound) {
734 trace("dsound.dll not found\n");
735 return;
738 pFunc = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
739 if (!pFunc) {
740 trace("dsound8 test skipped\n");
741 return;
744 IDirectSound8_tests();
745 dsound8_tests();