Added YUV routines needed for v4l driver, and in the future possibly
[wine/gsoc-2012-control.git] / dlls / dsound / tests / dsound8.c
blobeff908e4a4cdc5318d8d1c4310d19b0ccff03099
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>
31 #include <stdio.h>
33 #include "wine/test.h"
34 #include "dsound.h"
35 #include "dxerr8.h"
36 #include "dsconf.h"
38 #include "dsound_test.h"
40 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
42 int align(int length, int align)
44 return (length / align) * align;
47 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
48 LPCGUID lpGuid)
50 HRESULT rc;
51 DSCAPS dscaps;
52 int ref;
53 IUnknown * unknown;
54 IDirectSound * ds;
55 IDirectSound8 * ds8;
56 DWORD speaker_config, new_speaker_config;
57 DWORD certified;
59 /* Try to Query for objects */
60 rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
61 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
62 DXGetErrorString8(rc));
63 if (rc==DS_OK)
64 IDirectSound8_Release(unknown);
66 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
67 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
68 DXGetErrorString8(rc));
69 if (rc==DS_OK)
70 IDirectSound_Release(ds);
72 rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
73 ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
74 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
75 DXGetErrorString8(rc));
76 if (rc==DS_OK)
77 IDirectSound8_Release(ds8);
79 if (initialized == FALSE) {
80 /* try unitialized object */
81 rc=IDirectSound8_GetCaps(dso,0);
82 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
83 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
84 DXGetErrorString8(rc));
86 rc=IDirectSound8_GetCaps(dso,&dscaps);
87 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
88 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
89 DXGetErrorString8(rc));
91 rc=IDirectSound8_Compact(dso);
92 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
93 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
94 DXGetErrorString8(rc));
96 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
97 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
98 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
99 DXGetErrorString8(rc));
101 rc=IDirectSound8_VerifyCertification(dso, &certified);
102 ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
103 "should have returned DSERR_UNINITIALIZED, returned: %s\n",
104 DXGetErrorString8(rc));
106 rc=IDirectSound8_Initialize(dso,lpGuid);
107 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
108 "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
109 if (rc==DSERR_NODRIVER) {
110 trace(" No Driver\n");
111 goto EXIT;
112 } else if (rc==E_FAIL) {
113 trace(" No Device\n");
114 goto EXIT;
115 } else if (rc==DSERR_ALLOCATED) {
116 trace(" Already In Use\n");
117 goto EXIT;
121 rc=IDirectSound8_Initialize(dso,lpGuid);
122 ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() "
123 "should have returned DSERR_ALREADYINITIALIZED: %s\n",
124 DXGetErrorString8(rc));
126 /* DSOUND: Error: Invalid caps buffer */
127 rc=IDirectSound8_GetCaps(dso,0);
128 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
129 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
130 DXGetErrorString8(rc));
132 ZeroMemory(&dscaps, sizeof(dscaps));
134 /* DSOUND: Error: Invalid caps buffer */
135 rc=IDirectSound8_GetCaps(dso,&dscaps);
136 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
137 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
138 DXGetErrorString8(rc));
140 dscaps.dwSize=sizeof(dscaps);
142 /* DSOUND: Running on a certified driver */
143 rc=IDirectSound8_GetCaps(dso,&dscaps);
144 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
146 rc=IDirectSound8_Compact(dso);
147 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
148 DXGetErrorString8(rc));
150 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
151 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
152 DXGetErrorString8(rc));
154 rc=IDirectSound8_Compact(dso);
155 ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
157 rc=IDirectSound8_GetSpeakerConfig(dso,0);
158 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
159 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
160 DXGetErrorString8(rc));
162 rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
163 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
164 DXGetErrorString8(rc));
166 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
167 DSSPEAKER_GEOMETRY_WIDE);
168 rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
169 ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
170 DXGetErrorString8(rc));
171 if (rc==DS_OK) {
172 rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
173 ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
174 DXGetErrorString8(rc));
175 if (rc==DS_OK && speaker_config!=new_speaker_config)
176 trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
177 "config: expected 0x%08lx, got 0x%08lx\n",
178 speaker_config,new_speaker_config);
181 rc=IDirectSound8_VerifyCertification(dso, &certified);
182 ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
183 DXGetErrorString8(rc));
185 EXIT:
186 ref=IDirectSound8_Release(dso);
187 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
190 static void IDirectSound8_tests()
192 HRESULT rc;
193 LPDIRECTSOUND8 dso=NULL;
195 trace("Testing IDirectSound8\n");
197 /* try the COM class factory method of creation with no device specified */
198 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
199 &IID_IDirectSound8, (void**)&dso);
200 ok(rc==S_OK,"CoCreateInstance() failed: %s\n",DXGetErrorString8(rc));
201 if (dso)
202 IDirectSound8_test(dso, FALSE, NULL);
204 /* try the COM class factory method of creation with default playback
205 * device specified */
206 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
207 &IID_IDirectSound8, (void**)&dso);
208 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
209 DXGetErrorString8(rc));
210 if (dso)
211 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
213 /* try the COM class factory method of creation with default voice
214 * playback device specified */
215 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
216 &IID_IDirectSound8, (void**)&dso);
217 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
218 DXGetErrorString8(rc));
219 if (dso)
220 IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
222 /* try the COM class factory method of creation with a bad
223 * IID specified */
224 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
225 &CLSID_DirectSoundPrivate, (void**)&dso);
226 ok(rc==E_NOINTERFACE,
227 "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
228 "should have failed: %s\n",DXGetErrorString8(rc));
230 /* try the COM class factory method of creation with a bad
231 * GUID and IID specified */
232 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
233 &IID_IDirectSound8, (void**)&dso);
234 ok(rc==REGDB_E_CLASSNOTREG,
235 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
236 "should have failed: %s\n",DXGetErrorString8(rc));
238 /* try with no device specified */
239 rc=pDirectSoundCreate8(NULL,&dso,NULL);
240 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
241 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
242 if (rc==DS_OK && dso)
243 IDirectSound8_test(dso, TRUE, NULL);
245 /* try with default playback device specified */
246 rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
247 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
248 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
249 if (rc==DS_OK && dso)
250 IDirectSound8_test(dso, TRUE, NULL);
252 /* try with default voice playback device specified */
253 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
254 ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
255 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
256 if (rc==DS_OK && dso)
257 IDirectSound8_test(dso, TRUE, NULL);
259 /* try with a bad device specified */
260 rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
261 ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
262 "should have failed: %s\n",DXGetErrorString8(rc));
265 static HRESULT test_dsound8(LPGUID lpGuid)
267 HRESULT rc;
268 LPDIRECTSOUND8 dso=NULL;
269 int ref;
271 /* DSOUND: Error: Invalid interface buffer */
272 rc=pDirectSoundCreate8(lpGuid,0,NULL);
273 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
274 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
276 /* Create the DirectSound8 object */
277 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
278 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
279 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
280 if (rc!=DS_OK)
281 return rc;
283 /* Try the enumerated device */
284 IDirectSound8_test(dso, TRUE, lpGuid);
286 /* Try the COM class factory method of creation with enumerated device */
287 rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
288 &IID_IDirectSound8, (void**)&dso);
289 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
290 DXGetErrorString8(rc));
291 if (dso)
292 IDirectSound8_test(dso, FALSE, lpGuid);
294 /* Create a DirectSound8 object */
295 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
296 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
297 if (rc==DS_OK) {
298 LPDIRECTSOUND8 dso1=NULL;
300 /* Create a second DirectSound8 object */
301 rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
302 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
303 if (rc==DS_OK) {
304 /* Release the second DirectSound8 object */
305 ref=IDirectSound8_Release(dso1);
306 ok(ref==0,"IDirectSound8_Release() has %d references, "
307 "should have 0\n",ref);
308 ok(dso!=dso1,"DirectSound8 objects should be unique: "
309 "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
312 /* Release the first DirectSound8 object */
313 ref=IDirectSound8_Release(dso);
314 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
315 ref);
316 if (ref!=0)
317 return DSERR_GENERIC;
318 } else
319 return rc;
321 /* Create a DirectSound8 object */
322 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
323 ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
324 if (rc==DS_OK) {
325 LPDIRECTSOUNDBUFFER secondary;
326 DSBUFFERDESC bufdesc;
327 WAVEFORMATEX wfx;
329 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
330 ZeroMemory(&bufdesc, sizeof(bufdesc));
331 bufdesc.dwSize=sizeof(bufdesc);
332 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
333 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
334 wfx.nBlockAlign);
335 bufdesc.lpwfxFormat=&wfx;
336 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
337 ok(rc==DS_OK && secondary!=NULL,
338 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
339 "buffer: %s\n",DXGetErrorString8(rc));
340 if (rc==DS_OK && secondary!=NULL) {
341 LPDIRECTSOUND3DBUFFER buffer3d;
342 LPDIRECTSOUNDBUFFER8 buffer8;
343 rc=IDirectSound8_QueryInterface(secondary,
344 &IID_IDirectSound3DBuffer,
345 (void **)&buffer3d);
346 ok(rc==DS_OK && buffer3d!=NULL,
347 "IDirectSound8_QueryInterface() failed: %s\n",
348 DXGetErrorString8(rc));
349 if (rc==DS_OK && buffer3d!=NULL) {
350 ref=IDirectSound3DBuffer_AddRef(buffer3d);
351 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
352 "should have 2\n",ref);
354 rc=IDirectSound8_QueryInterface(secondary,
355 &IID_IDirectSoundBuffer8,
356 (void **)&buffer8);
357 if (rc==DS_OK && buffer8!=NULL) {
358 ref=IDirectSoundBuffer8_AddRef(buffer8);
359 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
360 "should have 3\n",ref);
362 ref=IDirectSoundBuffer_AddRef(secondary);
363 ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
364 "should have 4\n",ref);
366 /* release with buffer */
367 ref=IDirectSound8_Release(dso);
368 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
369 ref);
370 if (ref!=0)
371 return DSERR_GENERIC;
372 } else
373 return rc;
375 return DS_OK;
378 static HRESULT test_primary8(LPGUID lpGuid)
380 HRESULT rc;
381 LPDIRECTSOUND8 dso=NULL;
382 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
383 DSBUFFERDESC bufdesc;
384 DSCAPS dscaps;
385 WAVEFORMATEX wfx;
386 int ref;
388 /* Create the DirectSound object */
389 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
390 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
391 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
392 if (rc!=DS_OK)
393 return rc;
395 /* Get the device capabilities */
396 ZeroMemory(&dscaps, sizeof(dscaps));
397 dscaps.dwSize=sizeof(dscaps);
398 rc=IDirectSound8_GetCaps(dso,&dscaps);
399 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
400 if (rc!=DS_OK)
401 goto EXIT;
403 /* DSOUND: Error: Invalid buffer description pointer */
404 rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
405 ok(rc==DSERR_INVALIDPARAM,
406 "IDirectSound8_CreateSoundBuffer should have returned "
407 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
409 /* DSOUND: Error: Invalid buffer description pointer */
410 rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
411 ok(rc==DSERR_INVALIDPARAM && primary==0,
412 "IDirectSound8_CreateSoundBuffer() should have returned "
413 "DSERR_INVALIDPARAM, returned: rc=%s,dsbo=0x%lx\n",
414 DXGetErrorString8(rc),(DWORD)primary);
416 /* DSOUND: Error: Invalid buffer description pointer */
417 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
418 ok(rc==DSERR_INVALIDPARAM && primary==0,
419 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
420 "dsbo=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
422 ZeroMemory(&bufdesc, sizeof(bufdesc));
424 /* DSOUND: Error: Invalid size */
425 /* DSOUND: Error: Invalid buffer description */
426 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
427 ok(rc==DSERR_INVALIDPARAM && primary==0,
428 "IDirectSound8_CreateSoundBuffer() should have failed: rc=%s,"
429 "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
431 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
432 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
433 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
434 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
435 DXGetErrorString8(rc));
436 if (rc!=DS_OK)
437 goto EXIT;
439 /* Testing the primary buffer */
440 primary=NULL;
441 ZeroMemory(&bufdesc, sizeof(bufdesc));
442 bufdesc.dwSize=sizeof(bufdesc);
443 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
444 bufdesc.lpwfxFormat = &wfx;
445 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
446 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
447 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
448 "returned DSERR_INVALIDPARAM, returned: %s\n", DXGetErrorString8(rc));
449 if (rc==DS_OK && primary!=NULL)
450 IDirectSoundBuffer_Release(primary);
452 primary=NULL;
453 ZeroMemory(&bufdesc, sizeof(bufdesc));
454 bufdesc.dwSize=sizeof(bufdesc);
455 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
456 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
457 ok(rc==DS_OK && primary!=NULL,
458 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
459 "%s\n",DXGetErrorString8(rc));
460 if (rc==DS_OK && primary!=NULL) {
461 LONG vol;
463 /* Try to create a second primary buffer */
464 /* DSOUND: Error: The primary buffer already exists.
465 * Any changes made to the buffer description will be ignored. */
466 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
467 ok(rc==DS_OK && second==primary,
468 "IDirectSound8_CreateSoundBuffer() should have returned original "
469 "primary buffer: %s\n",DXGetErrorString8(rc));
470 ref=IDirectSoundBuffer_Release(second);
471 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
472 "should have 1\n",ref);
474 /* Try to duplicate a primary buffer */
475 /* DSOUND: Error: Can't duplicate primary buffers */
476 rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
477 /* rc=0x88780032 */
478 ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
479 "should have failed %s\n",DXGetErrorString8(rc));
481 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
482 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
483 DXGetErrorString8(rc));
485 if (winetest_interactive) {
486 trace("Playing a 5 seconds reference tone at the current volume.\n");
487 if (rc==DS_OK)
488 trace("(the current volume is %ld according to DirectSound)\n",
489 vol);
490 trace("All subsequent tones should be identical to this one.\n");
491 trace("Listen for stutter, changes in pitch, volume, etc.\n");
493 test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
494 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
496 ref=IDirectSoundBuffer_Release(primary);
497 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
498 "should have 0\n",ref);
501 /* Set the CooperativeLevel back to normal */
502 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
503 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
504 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
505 DXGetErrorString8(rc));
507 EXIT:
508 ref=IDirectSound8_Release(dso);
509 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
510 if (ref!=0)
511 return DSERR_GENERIC;
513 return rc;
517 * Test the primary buffer at different formats while keeping the
518 * secondary buffer at a constant format.
520 static HRESULT test_primary_secondary8(LPGUID lpGuid)
522 HRESULT rc;
523 LPDIRECTSOUND8 dso=NULL;
524 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
525 DSBUFFERDESC bufdesc;
526 DSCAPS dscaps;
527 WAVEFORMATEX wfx, wfx2;
528 int f,ref;
530 /* Create the DirectSound object */
531 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
532 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
533 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
534 if (rc!=DS_OK)
535 return rc;
537 /* Get the device capabilities */
538 ZeroMemory(&dscaps, sizeof(dscaps));
539 dscaps.dwSize=sizeof(dscaps);
540 rc=IDirectSound8_GetCaps(dso,&dscaps);
541 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
542 if (rc!=DS_OK)
543 goto EXIT;
545 /* We must call SetCooperativeLevel before creating primary buffer */
546 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
547 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
548 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
549 DXGetErrorString8(rc));
550 if (rc!=DS_OK)
551 goto EXIT;
553 ZeroMemory(&bufdesc, sizeof(bufdesc));
554 bufdesc.dwSize=sizeof(bufdesc);
555 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
556 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
557 ok(rc==DS_OK && primary!=NULL,
558 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
559 "%s\n",DXGetErrorString8(rc));
561 if (rc==DS_OK && primary!=NULL) {
562 for (f=0;f<NB_FORMATS;f++) {
563 /* We must call SetCooperativeLevel to be allowed to call
564 * SetFormat */
565 /* DSOUND: Setting DirectSound cooperative level to
566 * DSSCL_PRIORITY */
567 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
568 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
569 DXGetErrorString8(rc));
570 if (rc!=DS_OK)
571 goto EXIT;
573 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
574 formats[f][2]);
575 wfx2=wfx;
576 rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
577 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
578 DXGetErrorString8(rc));
580 /* There is no garantee that SetFormat will actually change the
581 * format to what we asked for. It depends on what the soundcard
582 * supports. So we must re-query the format.
584 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
585 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
586 DXGetErrorString8(rc));
587 if (rc==DS_OK &&
588 (wfx.wFormatTag!=wfx2.wFormatTag ||
589 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
590 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
591 wfx.nChannels!=wfx2.nChannels)) {
592 trace("Requested primary format tag=0x%04x %ldx%dx%d "
593 "avg.B/s=%ld align=%d\n",
594 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
595 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
596 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
597 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
598 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
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 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
609 secondary=NULL;
610 ZeroMemory(&bufdesc, sizeof(bufdesc));
611 bufdesc.dwSize=sizeof(bufdesc);
612 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
613 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
614 wfx.nBlockAlign);
615 bufdesc.lpwfxFormat=&wfx2;
616 if (winetest_interactive) {
617 trace(" Testing a primary buffer at %ldx%dx%d with a "
618 "secondary buffer at %ldx%dx%d\n",
619 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
620 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
622 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
623 ok(rc==DS_OK && secondary!=NULL,
624 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
625 "buffer %s\n",DXGetErrorString8(rc));
627 if (rc==DS_OK && secondary!=NULL) {
628 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
629 winetest_interactive,1.0,0,NULL,0,0);
631 ref=IDirectSoundBuffer_Release(secondary);
632 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
633 "should have 0\n",ref);
637 ref=IDirectSoundBuffer_Release(primary);
638 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
639 "should have 0\n",ref);
642 /* Set the CooperativeLevel back to normal */
643 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
644 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
645 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
646 DXGetErrorString8(rc));
648 EXIT:
649 ref=IDirectSound8_Release(dso);
650 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
651 if (ref!=0)
652 return DSERR_GENERIC;
654 return rc;
657 static HRESULT test_secondary8(LPGUID lpGuid)
659 HRESULT rc;
660 LPDIRECTSOUND8 dso=NULL;
661 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
662 DSBUFFERDESC bufdesc;
663 DSCAPS dscaps;
664 WAVEFORMATEX wfx, wfx1;
665 DWORD f;
666 int ref;
668 /* Create the DirectSound object */
669 rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
670 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
671 "DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
672 if (rc!=DS_OK)
673 return rc;
675 /* Get the device capabilities */
676 ZeroMemory(&dscaps, sizeof(dscaps));
677 dscaps.dwSize=sizeof(dscaps);
678 rc=IDirectSound8_GetCaps(dso,&dscaps);
679 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
680 if (rc!=DS_OK)
681 goto EXIT;
683 /* We must call SetCooperativeLevel before creating primary buffer */
684 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
685 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
686 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
687 DXGetErrorString8(rc));
688 if (rc!=DS_OK)
689 goto EXIT;
691 ZeroMemory(&bufdesc, sizeof(bufdesc));
692 bufdesc.dwSize=sizeof(bufdesc);
693 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
694 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
695 ok(rc==DS_OK && primary!=NULL,
696 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
697 "%s\n",DXGetErrorString8(rc));
699 if (rc==DS_OK && primary!=NULL) {
700 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
701 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
702 DXGetErrorString8(rc));
703 if (rc!=DS_OK)
704 goto EXIT1;
706 for (f=0;f<NB_FORMATS;f++) {
707 init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
708 formats[f][2]);
709 secondary=NULL;
710 ZeroMemory(&bufdesc, sizeof(bufdesc));
711 bufdesc.dwSize=sizeof(bufdesc);
712 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
713 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
714 wfx.nBlockAlign);
715 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
716 ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
717 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
718 DXGetErrorString8(rc));
719 if (rc==DS_OK && secondary!=NULL)
720 IDirectSoundBuffer_Release(secondary);
722 secondary=NULL;
723 ZeroMemory(&bufdesc, sizeof(bufdesc));
724 bufdesc.dwSize=sizeof(bufdesc);
725 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
726 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
727 wfx.nBlockAlign);
728 bufdesc.lpwfxFormat=&wfx;
729 if (winetest_interactive) {
730 trace(" Testing a secondary buffer at %ldx%dx%d "
731 "with a primary buffer at %ldx%dx%d\n",
732 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
733 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
735 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
736 ok(rc==DS_OK && secondary!=NULL,
737 "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
738 "buffer: %s\n",DXGetErrorString8(rc));
740 if (rc==DS_OK && secondary!=NULL) {
741 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
742 winetest_interactive,1.0,0,NULL,0,0);
744 ref=IDirectSoundBuffer_Release(secondary);
745 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
746 "should have 0\n",ref);
749 EXIT1:
750 ref=IDirectSoundBuffer_Release(primary);
751 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
752 "should have 0\n",ref);
755 /* Set the CooperativeLevel back to normal */
756 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
757 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
758 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
759 DXGetErrorString8(rc));
761 EXIT:
762 ref=IDirectSound8_Release(dso);
763 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
764 if (ref!=0)
765 return DSERR_GENERIC;
767 return rc;
770 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
771 LPCSTR lpcstrModule, LPVOID lpContext)
773 HRESULT rc;
774 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
775 rc = test_dsound8(lpGuid);
776 if (rc == DSERR_NODRIVER)
777 trace(" No Driver\n");
778 else if (rc == DSERR_ALLOCATED)
779 trace(" Already In Use\n");
780 else if (rc == E_FAIL)
781 trace(" No Device\n");
782 else {
783 test_primary8(lpGuid);
784 test_primary_secondary8(lpGuid);
785 test_secondary8(lpGuid);
788 return 1;
791 static void dsound8_tests()
793 HRESULT rc;
794 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
795 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
798 const char * get_file_version(const char * file_name)
800 static char version[32];
801 DWORD size;
802 DWORD handle;
804 size = GetFileVersionInfoSizeA("dsound.dll", &handle);
805 if (size) {
806 char * data = HeapAlloc(GetProcessHeap(), 0, size);
807 if (data) {
808 if (GetFileVersionInfoA("dsound.dll", handle, size, data)) {
809 VS_FIXEDFILEINFO *pFixedVersionInfo;
810 UINT len;
811 if (VerQueryValueA(data, "\\", (LPVOID *)&pFixedVersionInfo, &len)) {
812 sprintf(version, "%ld.%ld.%ld.%ld",
813 pFixedVersionInfo->dwFileVersionMS >> 16,
814 pFixedVersionInfo->dwFileVersionMS & 0xffff,
815 pFixedVersionInfo->dwFileVersionLS >> 16,
816 pFixedVersionInfo->dwFileVersionLS & 0xffff);
817 } else
818 sprintf(version, "not available");
819 } else
820 sprintf(version, "failed");
822 HeapFree(GetProcessHeap(), 0, data);
823 } else
824 sprintf(version, "failed");
825 } else
826 sprintf(version, "not available");
828 return version;
831 START_TEST(dsound8)
833 HMODULE hDsound;
835 CoInitialize(NULL);
837 hDsound = LoadLibraryA("dsound.dll");
838 if (!hDsound) {
839 trace("dsound.dll not found\n");
840 return;
843 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
845 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
846 if (!pDirectSoundCreate8) {
847 trace("dsound8 test skipped\n");
848 return;
851 IDirectSound8_tests();
852 dsound8_tests();
854 CoUninitialize();