shlwapi: Implement URL_APPLY_GUESSFILE in UrlApplyScheme.
[wine] / dlls / dsound / tests / dsound8.c
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.
5  *
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.
10  *
11  * Copyright (c) 2002-2004 Francois Gouget
12  *
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.
17  *
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.
22  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27
28 #include <windows.h>
29 #include <stdio.h>
30
31 #include "wine/test.h"
32 #include "dsound.h"
33 #include "dsconf.h"
34 #include "mmreg.h"
35 #include "ks.h"
36 #include "ksmedia.h"
37
38 #include "dsound_test.h"
39
40 static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
41 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL;
42
43 int align(int length, int align)
44 {
45     return (length / align) * align;
46 }
47
48 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
49                                LPCGUID lpGuid)
50 {
51     HRESULT rc;
52     DSCAPS dscaps;
53     int ref;
54     IUnknown * unknown;
55     IDirectSound * ds;
56     IDirectSound8 * ds8;
57     DWORD speaker_config, new_speaker_config, ref_speaker_config;
58     DWORD certified;
59
60     /* Try to Query for objects */
61     rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
62     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %08x\n", rc);
63     if (rc==DS_OK)
64         IDirectSound8_Release(unknown);
65
66     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
67     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %08x\n", rc);
68     if (rc==DS_OK)
69         IDirectSound_Release(ds);
70
71     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
72     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
73        "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
74     if (rc==DS_OK)
75         IDirectSound8_Release(ds8);
76
77     if (initialized == FALSE) {
78         /* try uninitialized object */
79         rc=IDirectSound8_GetCaps(dso,0);
80         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
81            "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc);
82
83         rc=IDirectSound8_GetCaps(dso,&dscaps);
84         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
85            "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc);
86
87         rc=IDirectSound8_Compact(dso);
88         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
89            "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc);
90
91         rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
92         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
93            "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc);
94
95         rc=IDirectSound8_VerifyCertification(dso, &certified);
96         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
97            "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc);
98
99         rc=IDirectSound8_Initialize(dso,lpGuid);
100         ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
101            "IDirectSound8_Initialize() failed: %08x\n",rc);
102         if (rc==DSERR_NODRIVER) {
103             trace("  No Driver\n");
104             goto EXIT;
105         } else if (rc==E_FAIL) {
106             trace("  No Device\n");
107             goto EXIT;
108         } else if (rc==DSERR_ALLOCATED) {
109             trace("  Already In Use\n");
110             goto EXIT;
111         }
112     }
113
114     rc=IDirectSound8_Initialize(dso,lpGuid);
115     ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() "
116        "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc);
117
118     /* DSOUND: Error: Invalid caps buffer */
119     rc=IDirectSound8_GetCaps(dso,0);
120     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
121        "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
122
123     ZeroMemory(&dscaps, sizeof(dscaps));
124
125     /* DSOUND: Error: Invalid caps buffer */
126     rc=IDirectSound8_GetCaps(dso,&dscaps);
127     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
128        "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
129
130     dscaps.dwSize=sizeof(dscaps);
131
132     /* DSOUND: Running on a certified driver */
133     rc=IDirectSound8_GetCaps(dso,&dscaps);
134     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
135
136     rc=IDirectSound8_Compact(dso);
137     ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %08x\n", rc);
138
139     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
140     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
141
142     rc=IDirectSound8_Compact(dso);
143     ok(rc==DS_OK,"IDirectSound8_Compact() failed: %08x\n",rc);
144
145     rc=IDirectSound8_GetSpeakerConfig(dso,0);
146     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
147        "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
148
149     rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
150     ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc);
151     ref_speaker_config = speaker_config;
152
153     speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
154                                         DSSPEAKER_GEOMETRY_WIDE);
155     if (speaker_config == ref_speaker_config)
156         speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
157                                             DSSPEAKER_GEOMETRY_NARROW);
158     if(rc==DS_OK) {
159         rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
160         ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %08x\n", rc);
161     }
162     if (rc==DS_OK) {
163         rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
164         ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc);
165         if (rc==DS_OK && speaker_config!=new_speaker_config)
166                trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
167                "config: expected 0x%08x, got 0x%08x\n",
168                speaker_config,new_speaker_config);
169         IDirectSound8_SetSpeakerConfig(dso,ref_speaker_config);
170     }
171
172     rc=IDirectSound8_VerifyCertification(dso, &certified);
173     ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %08x\n", rc);
174
175 EXIT:
176     ref=IDirectSound8_Release(dso);
177     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
178 }
179
180 static void IDirectSound8_tests(void)
181 {
182     HRESULT rc;
183     LPDIRECTSOUND8 dso=NULL;
184     LPCLASSFACTORY cf=NULL;
185
186     trace("Testing IDirectSound8\n");
187
188     rc=CoGetClassObject(&CLSID_DirectSound8, CLSCTX_INPROC_SERVER, NULL,
189                         &IID_IClassFactory, (void**)&cf);
190     ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
191        "failed: %08x\n", rc);
192
193     rc=CoGetClassObject(&CLSID_DirectSound8, CLSCTX_INPROC_SERVER, NULL,
194                         &IID_IUnknown, (void**)&cf);
195     ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) "
196        "failed: %08x\n", rc);
197
198     /* try the COM class factory method of creation with no device specified */
199     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
200                         &IID_IDirectSound8, (void**)&dso);
201     ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance() failed: %08x\n", rc);
202     if (rc==REGDB_E_CLASSNOTREG) {
203         trace("  Class Not Registered\n");
204         return;
205     }
206     if (dso)
207         IDirectSound8_test(dso, FALSE, NULL);
208
209     /* try the COM class factory method of creation with default playback
210      *  device specified */
211     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
212                         &IID_IDirectSound8, (void**)&dso);
213     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc);
214     if (dso)
215         IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
216
217     /* try the COM class factory method of creation with default voice
218      * playback device specified */
219     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
220                         &IID_IDirectSound8, (void**)&dso);
221     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc);
222     if (dso)
223         IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
224
225     /* try the COM class factory method of creation with a bad
226      * IID specified */
227     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
228                         &CLSID_DirectSoundPrivate, (void**)&dso);
229     ok(rc==E_NOINTERFACE,
230        "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
231        "should have failed: %08x\n",rc);
232
233     /* try the COM class factory method of creation with a bad
234      * GUID and IID specified */
235     rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
236                         &IID_IDirectSound8, (void**)&dso);
237     ok(rc==REGDB_E_CLASSNOTREG,
238        "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
239        "should have failed: %08x\n",rc);
240
241     /* try with no device specified */
242     rc=pDirectSoundCreate8(NULL,&dso,NULL);
243     ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
244        "DirectSoundCreate8() failed: %08x\n",rc);
245     if (rc==DS_OK && dso)
246         IDirectSound8_test(dso, TRUE, NULL);
247
248     /* try with default playback device specified */
249     rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
250     ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
251        "DirectSoundCreate8() failed: %08x\n",rc);
252     if (rc==DS_OK && dso)
253         IDirectSound8_test(dso, TRUE, NULL);
254
255     /* try with default voice playback device specified */
256     rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
257     ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
258        "DirectSoundCreate8() failed: %08x\n",rc);
259     if (rc==DS_OK && dso)
260         IDirectSound8_test(dso, TRUE, NULL);
261
262     /* try with a bad device specified */
263     rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
264     ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
265        "should have failed: %08x\n",rc);
266 }
267
268 static HRESULT test_dsound8(LPGUID lpGuid)
269 {
270     HRESULT rc;
271     LPDIRECTSOUND8 dso=NULL;
272     int ref;
273
274     /* DSOUND: Error: Invalid interface buffer */
275     rc=pDirectSoundCreate8(lpGuid,0,NULL);
276     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned "
277        "DSERR_INVALIDPARAM, returned: %08x\n",rc);
278
279     /* Create the DirectSound8 object */
280     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
281     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
282        "DirectSoundCreate8() failed: %08x\n",rc);
283     if (rc!=DS_OK)
284         return rc;
285
286     /* Try the enumerated device */
287     IDirectSound8_test(dso, TRUE, lpGuid);
288
289     /* Try the COM class factory method of creation with enumerated device */
290     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
291                         &IID_IDirectSound8, (void**)&dso);
292     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc);
293     if (dso)
294         IDirectSound8_test(dso, FALSE, lpGuid);
295
296     /* Create a DirectSound8 object */
297     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
298     ok(rc==DS_OK,"DirectSoundCreate8() failed: %08x\n",rc);
299     if (rc==DS_OK) {
300         LPDIRECTSOUND8 dso1=NULL;
301
302         /* Create a second DirectSound8 object */
303         rc=pDirectSoundCreate8(lpGuid,&dso1,NULL);
304         ok(rc==DS_OK,"DirectSoundCreate8() failed: %08x\n",rc);
305         if (rc==DS_OK) {
306             /* Release the second DirectSound8 object */
307             ref=IDirectSound8_Release(dso1);
308             ok(ref==0,"IDirectSound8_Release() has %d references, "
309                "should have 0\n",ref);
310             ok(dso!=dso1,"DirectSound8 objects should be unique: "
311                "dso=%p,dso1=%p\n",dso,dso1);
312         }
313
314         /* Release the first DirectSound8 object */
315         ref=IDirectSound8_Release(dso);
316         ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
317            ref);
318         if (ref!=0)
319             return DSERR_GENERIC;
320     } else
321         return rc;
322
323     /* Create a DirectSound8 object */
324     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
325     ok(rc==DS_OK,"DirectSoundCreate8() failed: %08x\n",rc);
326     if (rc==DS_OK) {
327         LPDIRECTSOUNDBUFFER secondary;
328         DSBUFFERDESC bufdesc;
329         WAVEFORMATEX wfx;
330
331         init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
332         ZeroMemory(&bufdesc, sizeof(bufdesc));
333         bufdesc.dwSize=sizeof(bufdesc);
334         bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
335         bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
336                                     wfx.nBlockAlign);
337         bufdesc.lpwfxFormat=&wfx;
338         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
339         ok(rc==DS_OK && secondary!=NULL,
340            "IDirectSound8_CreateSoundBuffer() failed to create a secondary "
341            "buffer: %08x\n",rc);
342         if (rc==DS_OK && secondary!=NULL) {
343             LPDIRECTSOUND3DBUFFER buffer3d;
344             LPDIRECTSOUNDBUFFER8 buffer8;
345             rc=IDirectSound8_QueryInterface(secondary,
346                                             &IID_IDirectSound3DBuffer,
347                                             (void **)&buffer3d);
348             ok(rc==DS_OK && buffer3d!=NULL,
349                "IDirectSound8_QueryInterface() failed: %08x\n", rc);
350             if (rc==DS_OK && buffer3d!=NULL) {
351                 ref=IDirectSound3DBuffer_AddRef(buffer3d);
352                 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, "
353                    "should have 2\n",ref);
354             }
355             rc=IDirectSound8_QueryInterface(secondary,
356                                             &IID_IDirectSoundBuffer8,
357                                             (void **)&buffer8);
358             if (rc==DS_OK && buffer8!=NULL) {
359                 ref=IDirectSoundBuffer8_AddRef(buffer8);
360                 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
361                    "should have 3\n",ref);
362             }
363             ref=IDirectSoundBuffer_AddRef(secondary);
364             ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
365                "should have 4\n",ref);
366         }
367         /* release with buffer */
368         ref=IDirectSound8_Release(dso);
369         ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
370            ref);
371         if (ref!=0)
372             return DSERR_GENERIC;
373     } else
374         return rc;
375
376     return DS_OK;
377 }
378
379 static HRESULT test_primary8(LPGUID lpGuid)
380 {
381     HRESULT rc;
382     LPDIRECTSOUND8 dso=NULL;
383     LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
384     LPDIRECTSOUNDBUFFER8 pb8 = NULL;
385     DSBUFFERDESC bufdesc;
386     DSCAPS dscaps;
387     WAVEFORMATEX wfx;
388     int ref;
389
390     /* Create the DirectSound object */
391     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
392     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
393        "DirectSoundCreate8() failed: %08x\n",rc);
394     if (rc!=DS_OK)
395         return rc;
396
397     /* Get the device capabilities */
398     ZeroMemory(&dscaps, sizeof(dscaps));
399     dscaps.dwSize=sizeof(dscaps);
400     rc=IDirectSound8_GetCaps(dso,&dscaps);
401     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
402     if (rc!=DS_OK)
403         goto EXIT;
404
405     /* DSOUND: Error: Invalid buffer description pointer */
406     rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
407     ok(rc==DSERR_INVALIDPARAM,
408        "IDirectSound8_CreateSoundBuffer should have returned "
409        "DSERR_INVALIDPARAM, returned: %08x\n",rc);
410
411     /* DSOUND: Error: Invalid buffer description pointer */
412     rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
413     ok(rc==DSERR_INVALIDPARAM && primary==0,
414        "IDirectSound8_CreateSoundBuffer() should have returned "
415        "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n",
416        rc,primary);
417
418     ZeroMemory(&bufdesc, sizeof(bufdesc));
419     bufdesc.dwSize = sizeof(DSBUFFERDESC);
420
421     /* DSOUND: Error: Invalid dsound buffer interface pointer */
422     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
423     ok(rc==DSERR_INVALIDPARAM && primary==0,
424        "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
425        "dsbo=%p\n",rc,primary);
426
427     ZeroMemory(&bufdesc, sizeof(bufdesc));
428
429     /* DSOUND: Error: Invalid size */
430     /* DSOUND: Error: Invalid buffer description */
431     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
432     ok(rc==DSERR_INVALIDPARAM && primary==0,
433        "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
434        "primary=%p\n",rc,primary);
435
436     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
437     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
438     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
439     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
440     if (rc!=DS_OK)
441         goto EXIT;
442
443     /* Testing the primary buffer */
444     primary=NULL;
445     ZeroMemory(&bufdesc, sizeof(bufdesc));
446     bufdesc.dwSize=sizeof(bufdesc);
447     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
448     bufdesc.lpwfxFormat = &wfx;
449     init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
450     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
451     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
452        "returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
453     if (rc==DS_OK && primary!=NULL)
454         IDirectSoundBuffer_Release(primary);
455
456     primary=NULL;
457     ZeroMemory(&bufdesc, sizeof(bufdesc));
458     bufdesc.dwSize=sizeof(bufdesc);
459     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
460     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
461     ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
462        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
463        "%08x\n",rc);
464     if (rc==DSERR_CONTROLUNAVAIL)
465         trace("  No Primary\n");
466     else if (rc==DS_OK && primary!=NULL) {
467         LONG vol;
468
469         /* Try to create a second primary buffer */
470         /* DSOUND: Error: The primary buffer already exists.
471          * Any changes made to the buffer description will be ignored. */
472         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
473         ok(rc==DS_OK && second==primary,
474            "IDirectSound8_CreateSoundBuffer() should have returned original "
475            "primary buffer: %08x\n",rc);
476         ref=IDirectSoundBuffer_Release(second);
477         ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
478            "should have 1\n",ref);
479
480         /* Try to duplicate a primary buffer */
481         /* DSOUND: Error: Can't duplicate primary buffers */
482         rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
483         /* rc=0x88780032 */
484         ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
485            "should have failed %08x\n",rc);
486
487         /* Primary buffers don't have an IDirectSoundBuffer8 */
488         rc = IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSoundBuffer8, (LPVOID*)&pb8);
489         ok(FAILED(rc), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc);
490
491         rc=IDirectSoundBuffer_GetVolume(primary,&vol);
492         ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc);
493
494         if (winetest_interactive) {
495             trace("Playing a 5 seconds reference tone at the current volume.\n");
496             if (rc==DS_OK)
497                 trace("(the current volume is %d according to DirectSound)\n",
498                       vol);
499             trace("All subsequent tones should be identical to this one.\n");
500             trace("Listen for stutter, changes in pitch, volume, etc.\n");
501         }
502         test_buffer8(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive &&
503                      !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
504
505         ref=IDirectSoundBuffer_Release(primary);
506         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
507            "should have 0\n",ref);
508     }
509
510     /* Set the CooperativeLevel back to normal */
511     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
512     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
513     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
514
515 EXIT:
516     ref=IDirectSound8_Release(dso);
517     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
518     if (ref!=0)
519         return DSERR_GENERIC;
520
521     return rc;
522 }
523
524 /*
525  * Test the primary buffer at different formats while keeping the
526  * secondary buffer at a constant format.
527  */
528 static HRESULT test_primary_secondary8(LPGUID lpGuid)
529 {
530     HRESULT rc;
531     LPDIRECTSOUND8 dso=NULL;
532     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
533     DSBUFFERDESC bufdesc;
534     DSCAPS dscaps;
535     WAVEFORMATEX wfx, wfx2;
536     int ref;
537     unsigned int f, tag;
538
539     /* Create the DirectSound object */
540     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
541     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
542        "DirectSoundCreate8() failed: %08x\n",rc);
543     if (rc!=DS_OK)
544         return rc;
545
546     /* Get the device capabilities */
547     ZeroMemory(&dscaps, sizeof(dscaps));
548     dscaps.dwSize=sizeof(dscaps);
549     rc=IDirectSound8_GetCaps(dso,&dscaps);
550     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
551     if (rc!=DS_OK)
552         goto EXIT;
553
554     /* We must call SetCooperativeLevel before creating primary buffer */
555     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
556     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
557     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
558     if (rc!=DS_OK)
559         goto EXIT;
560
561     ZeroMemory(&bufdesc, sizeof(bufdesc));
562     bufdesc.dwSize=sizeof(bufdesc);
563     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
564     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
565     ok(rc==DS_OK && primary!=NULL,
566        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
567        "%08x\n",rc);
568
569     if (rc==DS_OK && primary!=NULL) {
570         for (f=0;f<NB_FORMATS;f++) {
571           for (tag=0;tag<NB_TAGS;tag++) {
572             /* if float, we only want to test 32-bit */
573             if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
574                 continue;
575
576             /* We must call SetCooperativeLevel to be allowed to call
577              * SetFormat */
578             /* DSOUND: Setting DirectSound cooperative level to
579              * DSSCL_PRIORITY */
580             rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
581             ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
582             if (rc!=DS_OK)
583                 goto EXIT;
584
585             init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1],
586                         formats[f][2]);
587             wfx2=wfx;
588             rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
589             ok(rc==DS_OK
590                || rc==DSERR_INVALIDPARAM, /* 2003 */
591                "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
592                format_string(&wfx), rc);
593
594             /* There is no guarantee that SetFormat will actually change the
595              * format to what we asked for. It depends on what the soundcard
596              * supports. So we must re-query the format.
597              */
598             rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
599             ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc);
600             if (rc==DS_OK &&
601                 (wfx.wFormatTag!=wfx2.wFormatTag ||
602                  wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
603                  wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
604                  wfx.nChannels!=wfx2.nChannels)) {
605                 trace("Requested primary format tag=0x%04x %dx%dx%d "
606                       "avg.B/s=%d align=%d\n",
607                       wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
608                       wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
609                 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
610                       wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
611                       wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
612             }
613
614             /* Set the CooperativeLevel back to normal */
615             /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
616             rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
617             ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
618
619             init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
620
621             secondary=NULL;
622             ZeroMemory(&bufdesc, sizeof(bufdesc));
623             bufdesc.dwSize=sizeof(bufdesc);
624             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
625             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
626                                         wfx.nBlockAlign);
627             bufdesc.lpwfxFormat=&wfx2;
628             if (winetest_interactive) {
629                 trace("  Testing a primary buffer at %dx%dx%d (fmt=%d) with a "
630                       "secondary buffer at %dx%dx%d\n",
631                       wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag],
632                       wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
633             }
634             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
635             ok(rc==DS_OK && secondary!=NULL,
636                "IDirectSound_CreateSoundBuffer() failed to create a secondary "
637                "buffer %08x\n",rc);
638
639             if (rc==DS_OK && secondary!=NULL) {
640                 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
641                              winetest_interactive,1.0,0,NULL,0,0);
642
643                 ref=IDirectSoundBuffer_Release(secondary);
644                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
645                    "should have 0\n",ref);
646             }
647           }
648         }
649
650         ref=IDirectSoundBuffer_Release(primary);
651         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
652            "should have 0\n",ref);
653     }
654
655     /* Set the CooperativeLevel back to normal */
656     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
657     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
658     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
659
660 EXIT:
661     ref=IDirectSound8_Release(dso);
662     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
663     if (ref!=0)
664         return DSERR_GENERIC;
665
666     return rc;
667 }
668
669 static HRESULT test_secondary8(LPGUID lpGuid)
670 {
671     HRESULT rc;
672     LPDIRECTSOUND8 dso=NULL;
673     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
674     DSBUFFERDESC bufdesc;
675     DSCAPS dscaps;
676     WAVEFORMATEX wfx, wfx1;
677     DWORD f, tag;
678     int ref;
679
680     /* Create the DirectSound object */
681     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
682     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
683        "DirectSoundCreate8() failed: %08x\n",rc);
684     if (rc!=DS_OK)
685         return rc;
686
687     /* Get the device capabilities */
688     ZeroMemory(&dscaps, sizeof(dscaps));
689     dscaps.dwSize=sizeof(dscaps);
690     rc=IDirectSound8_GetCaps(dso,&dscaps);
691     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
692     if (rc!=DS_OK)
693         goto EXIT;
694
695     /* We must call SetCooperativeLevel before creating primary buffer */
696     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
697     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
698     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
699     if (rc!=DS_OK)
700         goto EXIT;
701
702     ZeroMemory(&bufdesc, sizeof(bufdesc));
703     bufdesc.dwSize=sizeof(bufdesc);
704     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
705     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
706     ok(rc==DS_OK && primary!=NULL,
707        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
708        "%08x\n",rc);
709
710     if (rc==DS_OK && primary!=NULL) {
711         rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
712         ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc);
713         if (rc!=DS_OK)
714             goto EXIT1;
715
716         for (f=0;f<NB_FORMATS;f++) {
717           for (tag=0;tag<NB_TAGS;tag++) {
718             WAVEFORMATEXTENSIBLE wfxe;
719
720             /* if float, we only want to test 32-bit */
721             if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
722                 continue;
723
724             init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1],
725                         formats[f][2]);
726             secondary=NULL;
727             ZeroMemory(&bufdesc, sizeof(bufdesc));
728             bufdesc.dwSize=sizeof(bufdesc);
729             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
730             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
731                                         wfx.nBlockAlign);
732             rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
733             ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
734                "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
735             if (rc==DS_OK && secondary!=NULL)
736                 IDirectSoundBuffer_Release(secondary);
737
738             secondary=NULL;
739             ZeroMemory(&bufdesc, sizeof(bufdesc));
740             bufdesc.dwSize=sizeof(bufdesc);
741             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
742             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
743                                         wfx.nBlockAlign);
744             bufdesc.lpwfxFormat=&wfx;
745             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
746             if (wfx.wBitsPerSample != 8 && wfx.wBitsPerSample != 16)
747                 ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary)
748                     || rc == DS_OK, /* driver dependent? */
749                     "IDirectSound_CreateSoundBuffer() "
750                     "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
751                     "and NULL, returned: %08x %p\n", rc, secondary);
752             else
753                 ok(rc==DS_OK && secondary!=NULL,
754                     "IDirectSound_CreateSoundBuffer() failed to create a secondary "
755                     "buffer %08x\n",rc);
756             if (secondary)
757                 IDirectSoundBuffer_Release(secondary);
758             secondary = NULL;
759
760             bufdesc.lpwfxFormat=(WAVEFORMATEX*)&wfxe;
761             wfxe.Format = wfx;
762             wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
763             wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
764             wfxe.Format.cbSize = 1;
765             wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample;
766             wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO);
767
768             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
769             ok(rc==DSERR_INVALIDPARAM && !secondary,
770                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
771                 rc, secondary);
772             if (secondary)
773             {
774                 IDirectSoundBuffer_Release(secondary);
775                 secondary=NULL;
776             }
777
778             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1;
779
780             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
781             ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary)
782                 || rc==DS_OK /* driver dependent? */,
783                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
784                 rc, secondary);
785             if (secondary)
786             {
787                 IDirectSoundBuffer_Release(secondary);
788                 secondary=NULL;
789             }
790
791             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
792             wfxe.SubFormat = GUID_NULL;
793             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
794             ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary,
795                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
796                 rc, secondary);
797             if (secondary)
798             {
799                 IDirectSoundBuffer_Release(secondary);
800                 secondary=NULL;
801             }
802
803             wfxe.Format.cbSize = sizeof(wfxe);
804             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
805             ok((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL || rc==E_INVALIDARG) && !secondary,
806                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
807                 rc, secondary);
808             if (secondary)
809             {
810                 IDirectSoundBuffer_Release(secondary);
811                 secondary=NULL;
812             }
813
814             wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
815             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
816             ok(rc==DS_OK && secondary,
817                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
818                 rc, secondary);
819             if (secondary)
820             {
821                 IDirectSoundBuffer_Release(secondary);
822                 secondary=NULL;
823             }
824
825             wfxe.Format.cbSize = sizeof(wfxe) + 1;
826             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
827             ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary)
828                 || rc==DS_OK /* driver dependent? */,
829                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
830                 rc, secondary);
831             if (secondary)
832             {
833                 IDirectSoundBuffer_Release(secondary);
834                 secondary=NULL;
835             }
836
837             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
838             ++wfxe.Samples.wValidBitsPerSample;
839             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
840             ok(rc==DSERR_INVALIDPARAM && !secondary,
841                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
842                 rc, secondary);
843             if (secondary)
844             {
845                 IDirectSoundBuffer_Release(secondary);
846                 secondary=NULL;
847             }
848             --wfxe.Samples.wValidBitsPerSample;
849
850             wfxe.Samples.wValidBitsPerSample = 0;
851             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
852             ok(rc==DS_OK && secondary,
853                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
854                 rc, secondary);
855             if (secondary)
856             {
857                 IDirectSoundBuffer_Release(secondary);
858                 secondary=NULL;
859             }
860             wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample;
861
862             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
863             ok(rc==DS_OK && secondary!=NULL,
864                 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
865                 "buffer %08x\n",rc);
866
867             if (rc==DS_OK && secondary!=NULL) {
868                 if (winetest_interactive) {
869                     trace("  Testing a secondary buffer at %dx%dx%d (fmt=%d) "
870                         "with a primary buffer at %dx%dx%d\n",
871                         wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag],
872                         wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
873                 }
874                 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
875                              winetest_interactive,1.0,0,NULL,0,0);
876
877                 ref=IDirectSoundBuffer_Release(secondary);
878                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
879                    "should have 0\n",ref);
880             }
881           }
882         }
883 EXIT1:
884         ref=IDirectSoundBuffer_Release(primary);
885         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
886            "should have 0\n",ref);
887     }
888
889     /* Set the CooperativeLevel back to normal */
890     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
891     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
892     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
893
894 EXIT:
895     ref=IDirectSound8_Release(dso);
896     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
897     if (ref!=0)
898         return DSERR_GENERIC;
899
900     return rc;
901 }
902
903 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
904                                    LPCSTR lpcstrModule, LPVOID lpContext)
905 {
906     HRESULT rc;
907     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
908     rc = test_dsound8(lpGuid);
909     if (rc == DSERR_NODRIVER)
910         trace("  No Driver\n");
911     else if (rc == DSERR_ALLOCATED)
912         trace("  Already In Use\n");
913     else if (rc == E_FAIL)
914         trace("  No Device\n");
915     else {
916         test_primary8(lpGuid);
917         test_primary_secondary8(lpGuid);
918         test_secondary8(lpGuid);
919     }
920
921     return 1;
922 }
923
924 static void dsound8_tests(void)
925 {
926     HRESULT rc;
927     rc=pDirectSoundEnumerateA(&dsenum_callback,NULL);
928     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %08x\n",rc);
929 }
930
931
932 START_TEST(dsound8)
933 {
934     HMODULE hDsound;
935
936     CoInitialize(NULL);
937
938     hDsound = LoadLibrary("dsound.dll");
939     if (hDsound)
940     {
941
942         pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound,
943             "DirectSoundEnumerateA");
944         pDirectSoundCreate8 = (void*)GetProcAddress(hDsound,
945             "DirectSoundCreate8");
946         if (pDirectSoundCreate8)
947         {
948             IDirectSound8_tests();
949             dsound8_tests();
950         }
951         else
952             skip("dsound8 test skipped\n");
953
954         FreeLibrary(hDsound);
955     }
956     else
957         skip("dsound.dll not found!\n");
958
959     CoUninitialize();
960 }