DirectSound8 doesn't accept 3D stereo secondary buffers but
[wine/multimedia.git] / dlls / dsound / tests / dsound.c
blobd1632b9de4dac8be75e1ddde49056915d5953249
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 IDirectSound_test(LPDIRECTSOUND 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;
55 /* Try to Query for objects */
56 rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
57 ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",
58 DXGetErrorString8(rc));
59 if (rc==DS_OK)
60 IDirectSound_Release(unknown);
62 rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
63 ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",
64 DXGetErrorString8(rc));
65 if (rc==DS_OK)
66 IDirectSound_Release(ds);
68 rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
69 ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) "
70 "should have failed: %s\n",DXGetErrorString8(rc));
71 if (rc==DS_OK)
72 IDirectSound8_Release(ds8);
74 if (initialized == FALSE) {
75 /* try unitialized object */
76 rc=IDirectSound_GetCaps(dso,0);
77 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps(NULL) "
78 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
79 DXGetErrorString8(rc));
81 rc=IDirectSound_GetCaps(dso,&dscaps);
82 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps() "
83 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
84 DXGetErrorString8(rc));
86 rc=IDirectSound_Compact(dso);
87 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_Compact() "
88 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
89 DXGetErrorString8(rc));
91 rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config);
92 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetSpeakerConfig() "
93 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
94 DXGetErrorString8(rc));
96 rc=IDirectSound_Initialize(dso,lpGuid);
97 ok(rc==DS_OK,"IDirectSound_Initialize() failed: %s\n",
98 DXGetErrorString8(rc));
101 /* DSOUND: Error: Invalid caps buffer */
102 rc=IDirectSound_GetCaps(dso,0);
103 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps(NULL) "
104 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
105 DXGetErrorString8(rc));
107 ZeroMemory(&dscaps, sizeof(dscaps));
109 /* DSOUND: Error: Invalid caps buffer */
110 rc=IDirectSound_GetCaps(dso,&dscaps);
111 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps() "
112 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
113 DXGetErrorString8(rc));
115 dscaps.dwSize=sizeof(dscaps);
117 /* DSOUND: Running on a certified driver */
118 rc=IDirectSound_GetCaps(dso,&dscaps);
119 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
121 rc=IDirectSound_Compact(dso);
122 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound_Compact() failed: %s\n",
123 DXGetErrorString8(rc));
125 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
126 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
127 DXGetErrorString8(rc));
129 rc=IDirectSound_Compact(dso);
130 ok(rc==DS_OK,"IDirectSound_Compact() failed: %s\n",DXGetErrorString8(rc));
132 rc=IDirectSound_GetSpeakerConfig(dso,0);
133 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetSpeakerConfig(NULL) "
134 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
135 DXGetErrorString8(rc));
137 rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config);
138 ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %s\n",
139 DXGetErrorString8(rc));
141 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
142 DSSPEAKER_GEOMETRY_WIDE);
143 rc=IDirectSound_SetSpeakerConfig(dso,speaker_config);
144 ok(rc==DS_OK,"IDirectSound_SetSpeakerConfig() failed: %s\n",
145 DXGetErrorString8(rc));
146 if (rc==DS_OK) {
147 rc=IDirectSound_GetSpeakerConfig(dso,&new_speaker_config);
148 ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %s\n",
149 DXGetErrorString8(rc));
150 if (rc==DS_OK && speaker_config!=new_speaker_config)
151 trace("IDirectSound_GetSpeakerConfig() failed to set speaker "
152 "config: expected 0x%08lx, got 0x%08lx\n",
153 speaker_config,new_speaker_config);
156 ref=IDirectSound_Release(dso);
157 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
160 static void IDirectSound_tests()
162 HRESULT rc;
163 LPDIRECTSOUND dso=NULL;
165 trace("Testing IDirectSound\n");
167 /* try the COM class factory method of creation with no device specified */
168 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
169 &IID_IDirectSound, (void**)&dso);
170 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
171 DXGetErrorString8(rc));
172 if (dso)
173 IDirectSound_test(dso, FALSE, NULL);
175 /* try the COM class factory method of creation with default playback
176 * device specified */
177 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
178 &IID_IDirectSound, (void**)&dso);
179 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
180 DXGetErrorString8(rc));
181 if (dso)
182 IDirectSound_test(dso, FALSE, &DSDEVID_DefaultPlayback);
184 /* try the COM class factory method of creation with default voice
185 * playback device specified */
186 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
187 &IID_IDirectSound, (void**)&dso);
188 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
189 DXGetErrorString8(rc));
190 if (dso)
191 IDirectSound_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
193 /* try the COM class factory method of creation with a bad
194 * IID specified */
195 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
196 &CLSID_DirectSoundPrivate, (void**)&dso);
197 ok(rc==E_NOINTERFACE,
198 "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) "
199 "should have failed: %s\n",DXGetErrorString8(rc));
201 /* try the COM class factory method of creation with a bad
202 * GUID and IID specified */
203 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
204 &IID_IDirectSound, (void**)&dso);
205 ok(rc==REGDB_E_CLASSNOTREG,
206 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) "
207 "should have failed: %s\n",DXGetErrorString8(rc));
209 /* try with no device specified */
210 rc=DirectSoundCreate(NULL,&dso,NULL);
211 ok(rc==S_OK,"DirectSoundCreate(NULL) failed: %s\n",DXGetErrorString8(rc));
212 if (dso)
213 IDirectSound_test(dso, TRUE, NULL);
215 /* try with default playback device specified */
216 rc=DirectSoundCreate(&DSDEVID_DefaultPlayback,&dso,NULL);
217 ok(rc==S_OK,"DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %s\n",
218 DXGetErrorString8(rc));
219 if (dso)
220 IDirectSound_test(dso, TRUE, NULL);
222 /* try with default voice playback device specified */
223 rc=DirectSoundCreate(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
224 ok(rc==S_OK,"DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %s\n",
225 DXGetErrorString8(rc));
226 if (dso)
227 IDirectSound_test(dso, TRUE, NULL);
229 /* try with a bad device specified */
230 rc=DirectSoundCreate(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
231 ok(rc==DSERR_NODRIVER,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) "
232 "should have failed: %s\n",DXGetErrorString8(rc));
235 static HRESULT test_dsound(LPGUID lpGuid)
237 HRESULT rc;
238 LPDIRECTSOUND dso=NULL;
239 int ref;
241 /* DSOUND: Error: Invalid interface buffer */
242 rc=DirectSoundCreate(lpGuid,0,NULL);
243 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate() should have returned "
244 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
246 /* Create the DirectSound object */
247 rc=DirectSoundCreate(lpGuid,&dso,NULL);
248 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
249 if (rc!=DS_OK)
250 return rc;
252 /* Try the enumerated device */
253 IDirectSound_test(dso, TRUE, lpGuid);
255 /* Try the COM class factory method of creation with enumerated device */
256 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
257 &IID_IDirectSound, (void**)&dso);
258 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
259 DXGetErrorString8(rc));
260 if (dso)
261 IDirectSound_test(dso, FALSE, lpGuid);
263 /* Create a DirectSound object */
264 rc=DirectSoundCreate(lpGuid,&dso,NULL);
265 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
266 if (rc==DS_OK) {
267 LPDIRECTSOUND dso1=NULL;
269 /* Create a second DirectSound object */
270 rc=DirectSoundCreate(lpGuid,&dso1,NULL);
271 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
272 if (rc==DS_OK) {
273 /* Release the second DirectSound object */
274 ref=IDirectSound_Release(dso1);
275 ok(ref==0,"IDirectSound_Release() has %d references, should have "
276 "0\n",ref);
277 ok(dso!=dso1,"DirectSound objects should be unique: "
278 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
281 /* Release the first DirectSound object */
282 ref=IDirectSound_Release(dso);
283 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
284 ref);
285 if (ref!=0)
286 return DSERR_GENERIC;
287 } else
288 return rc;
290 /* Create a DirectSound object */
291 rc=DirectSoundCreate(lpGuid,&dso,NULL);
292 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
293 if (rc==DS_OK) {
294 LPDIRECTSOUNDBUFFER secondary;
295 DSBUFFERDESC bufdesc;
296 WAVEFORMATEX wfx;
298 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
299 ZeroMemory(&bufdesc, sizeof(bufdesc));
300 bufdesc.dwSize=sizeof(bufdesc);
301 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
302 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
303 bufdesc.lpwfxFormat=&wfx;
304 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
305 ok(rc==DS_OK && secondary!=NULL,
306 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
307 "buffer %s\n",DXGetErrorString8(rc));
308 if (rc==DS_OK && secondary!=NULL) {
309 LPDIRECTSOUND3DBUFFER buffer3d;
310 rc=IDirectSound_QueryInterface(secondary, &IID_IDirectSound3DBuffer,
311 (void **)&buffer3d);
312 ok(rc==DS_OK && buffer3d!=NULL,"IDirectSound_QueryInterface() "
313 "failed: %s\n",DXGetErrorString8(rc));
314 if (rc==DS_OK && buffer3d!=NULL) {
315 ref=IDirectSound3DBuffer_AddRef(buffer3d);
316 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
317 "should have 2\n",ref);
319 ref=IDirectSoundBuffer_AddRef(secondary);
320 ok(ref==2,"IDirectSoundBuffer_AddRef() has %d references, "
321 "should have 2\n",ref);
323 /* release with buffer */
324 ref=IDirectSound_Release(dso);
325 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
326 ref);
327 if (ref!=0)
328 return DSERR_GENERIC;
329 } else
330 return rc;
332 return DS_OK;
335 static HRESULT test_primary(LPGUID lpGuid)
337 HRESULT rc;
338 LPDIRECTSOUND dso=NULL;
339 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
340 DSBUFFERDESC bufdesc;
341 DSCAPS dscaps;
342 WAVEFORMATEX wfx;
343 int ref;
345 /* Create the DirectSound object */
346 rc=DirectSoundCreate(lpGuid,&dso,NULL);
347 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
348 if (rc!=DS_OK)
349 return rc;
351 /* Get the device capabilities */
352 ZeroMemory(&dscaps, sizeof(dscaps));
353 dscaps.dwSize=sizeof(dscaps);
354 rc=IDirectSound_GetCaps(dso,&dscaps);
355 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
356 if (rc!=DS_OK)
357 goto EXIT;
359 /* DSOUND: Error: Invalid buffer description pointer */
360 rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL);
361 ok(rc==DSERR_INVALIDPARAM,
362 "IDirectSound_CreateSoundBuffer() should have failed: %s\n",
363 DXGetErrorString8(rc));
365 /* DSOUND: Error: Invalid buffer description pointer */
366 rc=IDirectSound_CreateSoundBuffer(dso,0,&primary,NULL);
367 ok(rc==DSERR_INVALIDPARAM && primary==0,
368 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
369 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
371 /* DSOUND: Error: Invalid buffer description pointer */
372 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,0,NULL);
373 ok(rc==DSERR_INVALIDPARAM && primary==0,
374 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
375 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
377 ZeroMemory(&bufdesc, sizeof(bufdesc));
379 /* DSOUND: Error: Invalid size */
380 /* DSOUND: Error: Invalid buffer description */
381 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
382 ok(rc==DSERR_INVALIDPARAM && primary==0,
383 "IDirectSound_CreateSoundBuffer() should have failed: rc=%s,"
384 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
386 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
387 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
388 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
389 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
390 DXGetErrorString8(rc));
391 if (rc!=DS_OK)
392 goto EXIT;
394 /* Testing the primary buffer */
395 primary=NULL;
396 ZeroMemory(&bufdesc, sizeof(bufdesc));
397 bufdesc.dwSize=sizeof(bufdesc);
398 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
399 bufdesc.lpwfxFormat = &wfx;
400 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
401 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
402 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() should have "
403 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
404 if (rc==DS_OK && primary!=NULL)
405 IDirectSoundBuffer_Release(primary);
407 primary=NULL;
408 ZeroMemory(&bufdesc, sizeof(bufdesc));
409 bufdesc.dwSize=sizeof(bufdesc);
410 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
411 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
412 ok(rc==DS_OK && primary!=NULL,
413 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
414 "%s\n",DXGetErrorString8(rc));
415 if (rc==DS_OK && primary!=NULL) {
416 LONG vol;
418 /* Try to create a second primary buffer */
419 /* DSOUND: Error: The primary buffer already exists.
420 * Any changes made to the buffer description will be ignored. */
421 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
422 ok(rc==DS_OK && second==primary,
423 "IDirectSound_CreateSoundBuffer() should have returned original "
424 "primary buffer: %s\n",DXGetErrorString8(rc));
425 ref=IDirectSoundBuffer_Release(second);
426 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
427 "should have 1\n",ref);
429 /* Try to duplicate a primary buffer */
430 /* DSOUND: Error: Can't duplicate primary buffers */
431 rc=IDirectSound_DuplicateSoundBuffer(dso,primary,&third);
432 /* rc=0x88780032 */
433 ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer() primary buffer "
434 "should have failed %s\n",DXGetErrorString8(rc));
436 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
437 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
438 DXGetErrorString8(rc));
440 if (winetest_interactive) {
441 trace("Playing a 5 seconds reference tone at the current "
442 "volume.\n");
443 if (rc==DS_OK)
444 trace("(the current volume is %ld according to DirectSound)\n",
445 vol);
446 trace("All subsequent tones should be identical to this one.\n");
447 trace("Listen for stutter, changes in pitch, volume, etc.\n");
449 test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
450 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
452 ref=IDirectSoundBuffer_Release(primary);
453 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
454 "should have 0\n",ref);
457 /* Set the CooperativeLevel back to normal */
458 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
459 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
460 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
461 DXGetErrorString8(rc));
463 EXIT:
464 ref=IDirectSound_Release(dso);
465 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
466 if (ref!=0)
467 return DSERR_GENERIC;
469 return rc;
473 * Test the primary buffer at different formats while keeping the
474 * secondary buffer at a constant format.
476 static HRESULT test_primary_secondary(LPGUID lpGuid)
478 HRESULT rc;
479 LPDIRECTSOUND dso=NULL;
480 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
481 DSBUFFERDESC bufdesc;
482 DSCAPS dscaps;
483 WAVEFORMATEX wfx, wfx2;
484 int f,ref;
486 /* Create the DirectSound object */
487 rc=DirectSoundCreate(lpGuid,&dso,NULL);
488 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
489 if (rc!=DS_OK)
490 return rc;
492 /* Get the device capabilities */
493 ZeroMemory(&dscaps, sizeof(dscaps));
494 dscaps.dwSize=sizeof(dscaps);
495 rc=IDirectSound_GetCaps(dso,&dscaps);
496 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
497 if (rc!=DS_OK)
498 goto EXIT;
500 /* We must call SetCooperativeLevel before creating primary buffer */
501 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
502 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
503 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
504 DXGetErrorString8(rc));
505 if (rc!=DS_OK)
506 goto EXIT;
508 ZeroMemory(&bufdesc, sizeof(bufdesc));
509 bufdesc.dwSize=sizeof(bufdesc);
510 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
511 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
512 ok(rc==DS_OK && primary!=NULL,
513 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
514 "%s\n",DXGetErrorString8(rc));
516 if (rc==DS_OK && primary!=NULL) {
517 for (f=0;f<NB_FORMATS;f++) {
518 /* We must call SetCooperativeLevel to be allowed to call
519 * SetFormat */
520 /* DSOUND: Setting DirectSound cooperative level to
521 * DSSCL_PRIORITY */
522 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
523 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
524 DXGetErrorString8(rc));
525 if (rc!=DS_OK)
526 goto EXIT;
528 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
529 formats[f][2]);
530 wfx2=wfx;
531 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
532 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
533 DXGetErrorString8(rc));
535 /* There is no garantee that SetFormat will actually change the
536 * format to what we asked for. It depends on what the soundcard
537 * supports. So we must re-query the format.
539 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
540 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
541 DXGetErrorString8(rc));
542 if (rc==DS_OK &&
543 (wfx.wFormatTag!=wfx2.wFormatTag ||
544 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
545 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
546 wfx.nChannels!=wfx2.nChannels)) {
547 trace("Requested primary format tag=0x%04x %ldx%dx%d "
548 "avg.B/s=%ld align=%d\n",
549 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
550 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
551 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
552 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
553 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
556 /* Set the CooperativeLevel back to normal */
557 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
558 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
559 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
560 DXGetErrorString8(rc));
562 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
564 secondary=NULL;
565 ZeroMemory(&bufdesc, sizeof(bufdesc));
566 bufdesc.dwSize=sizeof(bufdesc);
567 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
568 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
569 bufdesc.lpwfxFormat=&wfx2;
570 if (winetest_interactive) {
571 trace(" Testing a primary buffer at %ldx%dx%d with a "
572 "secondary buffer at %ldx%dx%d\n",
573 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
574 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
576 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
577 ok(rc==DS_OK && secondary!=NULL,
578 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
579 "buffer %s\n",DXGetErrorString8(rc));
581 if (rc==DS_OK && secondary!=NULL) {
582 test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
583 winetest_interactive,1.0,0,NULL,0,0);
585 ref=IDirectSoundBuffer_Release(secondary);
586 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
587 "should have 0\n",ref);
591 ref=IDirectSoundBuffer_Release(primary);
592 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
593 "should have 0\n",ref);
596 /* Set the CooperativeLevel back to normal */
597 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
598 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
599 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
600 DXGetErrorString8(rc));
602 EXIT:
603 ref=IDirectSound_Release(dso);
604 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
605 if (ref!=0)
606 return DSERR_GENERIC;
608 return rc;
611 static HRESULT test_secondary(LPGUID lpGuid)
613 HRESULT rc;
614 LPDIRECTSOUND dso=NULL;
615 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
616 DSBUFFERDESC bufdesc;
617 DSCAPS dscaps;
618 WAVEFORMATEX wfx;
619 DWORD f;
620 int ref;
622 /* Create the DirectSound object */
623 rc=DirectSoundCreate(lpGuid,&dso,NULL);
624 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
625 if (rc!=DS_OK)
626 return rc;
628 /* Get the device capabilities */
629 ZeroMemory(&dscaps, sizeof(dscaps));
630 dscaps.dwSize=sizeof(dscaps);
631 rc=IDirectSound_GetCaps(dso,&dscaps);
632 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
633 if (rc!=DS_OK)
634 goto EXIT;
636 /* We must call SetCooperativeLevel before creating primary buffer */
637 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
638 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
639 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
640 DXGetErrorString8(rc));
641 if (rc!=DS_OK)
642 goto EXIT;
644 ZeroMemory(&bufdesc, sizeof(bufdesc));
645 bufdesc.dwSize=sizeof(bufdesc);
646 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
647 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
648 ok(rc==DS_OK && primary!=NULL,
649 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
650 "%s\n",DXGetErrorString8(rc));
652 if (rc==DS_OK && primary!=NULL) {
653 for (f=0;f<NB_FORMATS;f++) {
654 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
655 formats[f][2]);
656 secondary=NULL;
657 ZeroMemory(&bufdesc, sizeof(bufdesc));
658 bufdesc.dwSize=sizeof(bufdesc);
659 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
660 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
661 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
662 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() "
663 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
664 DXGetErrorString8(rc));
665 if (rc==DS_OK && secondary!=NULL)
666 IDirectSoundBuffer_Release(secondary);
668 secondary=NULL;
669 ZeroMemory(&bufdesc, sizeof(bufdesc));
670 bufdesc.dwSize=sizeof(bufdesc);
671 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
672 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
673 bufdesc.lpwfxFormat=&wfx;
674 if (winetest_interactive) {
675 trace(" Testing a secondary buffer at %ldx%dx%d\n",
676 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
678 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
679 ok(rc==DS_OK && secondary!=NULL,
680 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
681 "buffer %s\n",DXGetErrorString8(rc));
683 if (rc==DS_OK && secondary!=NULL) {
684 test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
685 winetest_interactive,1.0,0,NULL,0,0);
687 ref=IDirectSoundBuffer_Release(secondary);
688 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
689 "should have 0\n",ref);
693 ref=IDirectSoundBuffer_Release(primary);
694 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
695 "should have 0\n",ref);
698 /* Set the CooperativeLevel back to normal */
699 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
700 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
701 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
702 DXGetErrorString8(rc));
704 EXIT:
705 ref=IDirectSound_Release(dso);
706 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
707 if (ref!=0)
708 return DSERR_GENERIC;
710 return rc;
713 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
714 LPCSTR lpcstrModule, LPVOID lpContext)
716 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
717 test_dsound(lpGuid);
718 test_primary(lpGuid);
719 test_primary_secondary(lpGuid);
720 test_secondary(lpGuid);
722 return 1;
725 static void dsound_tests()
727 HRESULT rc;
728 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
729 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
732 START_TEST(dsound)
734 CoInitialize(NULL);
736 IDirectSound_tests();
737 dsound_tests();