comctl32: Fix a logical operator typo.
[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                 ok(buffer8==(IDirectSoundBuffer8*)secondary,
360                    "IDirectSoundBuffer8 iface different from IDirectSoundBuffer.\n");
361                 ref=IDirectSoundBuffer8_AddRef(buffer8);
362                 ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, "
363                    "should have 3\n",ref);
364             }
365             ref=IDirectSoundBuffer_AddRef(secondary);
366             ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, "
367                "should have 4\n",ref);
368         }
369         /* release with buffer */
370         ref=IDirectSound8_Release(dso);
371         ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",
372            ref);
373         if (ref!=0)
374             return DSERR_GENERIC;
375     } else
376         return rc;
377
378     return DS_OK;
379 }
380
381 static HRESULT test_primary8(LPGUID lpGuid)
382 {
383     HRESULT rc;
384     LPDIRECTSOUND8 dso=NULL;
385     LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
386     LPDIRECTSOUNDBUFFER8 pb8 = NULL;
387     DSBUFFERDESC bufdesc;
388     DSCAPS dscaps;
389     WAVEFORMATEX wfx;
390     int ref;
391
392     /* Create the DirectSound object */
393     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
394     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
395        "DirectSoundCreate8() failed: %08x\n",rc);
396     if (rc!=DS_OK)
397         return rc;
398
399     /* Get the device capabilities */
400     ZeroMemory(&dscaps, sizeof(dscaps));
401     dscaps.dwSize=sizeof(dscaps);
402     rc=IDirectSound8_GetCaps(dso,&dscaps);
403     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
404     if (rc!=DS_OK)
405         goto EXIT;
406
407     /* DSOUND: Error: Invalid buffer description pointer */
408     rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
409     ok(rc==DSERR_INVALIDPARAM,
410        "IDirectSound8_CreateSoundBuffer should have returned "
411        "DSERR_INVALIDPARAM, returned: %08x\n",rc);
412
413     /* DSOUND: Error: Invalid buffer description pointer */
414     rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
415     ok(rc==DSERR_INVALIDPARAM && primary==0,
416        "IDirectSound8_CreateSoundBuffer() should have returned "
417        "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n",
418        rc,primary);
419
420     ZeroMemory(&bufdesc, sizeof(bufdesc));
421     bufdesc.dwSize = sizeof(DSBUFFERDESC);
422
423     /* DSOUND: Error: Invalid dsound buffer interface pointer */
424     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
425     ok(rc==DSERR_INVALIDPARAM && primary==0,
426        "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
427        "dsbo=%p\n",rc,primary);
428
429     ZeroMemory(&bufdesc, sizeof(bufdesc));
430
431     /* DSOUND: Error: Invalid size */
432     /* DSOUND: Error: Invalid buffer description */
433     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
434     ok(rc==DSERR_INVALIDPARAM && primary==0,
435        "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
436        "primary=%p\n",rc,primary);
437
438     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
439     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
440     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
441     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
442     if (rc!=DS_OK)
443         goto EXIT;
444
445     /* Testing the primary buffer */
446     primary=NULL;
447     ZeroMemory(&bufdesc, sizeof(bufdesc));
448     bufdesc.dwSize=sizeof(bufdesc);
449     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
450     bufdesc.lpwfxFormat = &wfx;
451     init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
452     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
453     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
454        "returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
455     if (rc==DS_OK && primary!=NULL)
456         IDirectSoundBuffer_Release(primary);
457
458     primary=NULL;
459     ZeroMemory(&bufdesc, sizeof(bufdesc));
460     bufdesc.dwSize=sizeof(bufdesc);
461     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
462     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
463     ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
464        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
465        "%08x\n",rc);
466     if (rc==DSERR_CONTROLUNAVAIL)
467         trace("  No Primary\n");
468     else if (rc==DS_OK && primary!=NULL) {
469         LONG vol;
470
471         /* Try to create a second primary buffer */
472         /* DSOUND: Error: The primary buffer already exists.
473          * Any changes made to the buffer description will be ignored. */
474         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
475         ok(rc==DS_OK && second==primary,
476            "IDirectSound8_CreateSoundBuffer() should have returned original "
477            "primary buffer: %08x\n",rc);
478         ref=IDirectSoundBuffer_Release(second);
479         ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
480            "should have 1\n",ref);
481
482         /* Try to duplicate a primary buffer */
483         /* DSOUND: Error: Can't duplicate primary buffers */
484         rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
485         /* rc=0x88780032 */
486         ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
487            "should have failed %08x\n",rc);
488
489         /* Primary buffers don't have an IDirectSoundBuffer8 */
490         rc = IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSoundBuffer8, (LPVOID*)&pb8);
491         ok(FAILED(rc), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc);
492
493         rc=IDirectSoundBuffer_GetVolume(primary,&vol);
494         ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc);
495
496         if (winetest_interactive) {
497             trace("Playing a 5 seconds reference tone at the current volume.\n");
498             if (rc==DS_OK)
499                 trace("(the current volume is %d according to DirectSound)\n",
500                       vol);
501             trace("All subsequent tones should be identical to this one.\n");
502             trace("Listen for stutter, changes in pitch, volume, etc.\n");
503         }
504         test_buffer8(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive &&
505                      !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
506
507         ref=IDirectSoundBuffer_Release(primary);
508         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
509            "should have 0\n",ref);
510     }
511
512     /* Set the CooperativeLevel back to normal */
513     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
514     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
515     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
516
517 EXIT:
518     ref=IDirectSound8_Release(dso);
519     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
520     if (ref!=0)
521         return DSERR_GENERIC;
522
523     return rc;
524 }
525
526 /*
527  * Test the primary buffer at different formats while keeping the
528  * secondary buffer at a constant format.
529  */
530 static HRESULT test_primary_secondary8(LPGUID lpGuid)
531 {
532     HRESULT rc;
533     LPDIRECTSOUND8 dso=NULL;
534     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
535     DSBUFFERDESC bufdesc;
536     DSCAPS dscaps;
537     WAVEFORMATEX wfx, wfx2;
538     int ref;
539     unsigned int f, tag;
540
541     /* Create the DirectSound object */
542     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
543     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
544        "DirectSoundCreate8() failed: %08x\n",rc);
545     if (rc!=DS_OK)
546         return rc;
547
548     /* Get the device capabilities */
549     ZeroMemory(&dscaps, sizeof(dscaps));
550     dscaps.dwSize=sizeof(dscaps);
551     rc=IDirectSound8_GetCaps(dso,&dscaps);
552     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
553     if (rc!=DS_OK)
554         goto EXIT;
555
556     /* We must call SetCooperativeLevel before creating primary buffer */
557     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
558     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
559     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
560     if (rc!=DS_OK)
561         goto EXIT;
562
563     ZeroMemory(&bufdesc, sizeof(bufdesc));
564     bufdesc.dwSize=sizeof(bufdesc);
565     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
566     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
567     ok(rc==DS_OK && primary!=NULL,
568        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
569        "%08x\n",rc);
570
571     if (rc==DS_OK && primary!=NULL) {
572         for (f=0;f<NB_FORMATS;f++) {
573           for (tag=0;tag<NB_TAGS;tag++) {
574             /* if float, we only want to test 32-bit */
575             if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
576                 continue;
577
578             /* We must call SetCooperativeLevel to be allowed to call
579              * SetFormat */
580             /* DSOUND: Setting DirectSound cooperative level to
581              * DSSCL_PRIORITY */
582             rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
583             ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
584             if (rc!=DS_OK)
585                 goto EXIT;
586
587             init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1],
588                         formats[f][2]);
589             wfx2=wfx;
590             rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
591             ok(rc==DS_OK
592                || rc==DSERR_INVALIDPARAM, /* 2003 */
593                "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
594                format_string(&wfx), rc);
595
596             /* There is no guarantee that SetFormat will actually change the
597              * format to what we asked for. It depends on what the soundcard
598              * supports. So we must re-query the format.
599              */
600             rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
601             ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc);
602             if (rc==DS_OK &&
603                 (wfx.wFormatTag!=wfx2.wFormatTag ||
604                  wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
605                  wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
606                  wfx.nChannels!=wfx2.nChannels)) {
607                 trace("Requested primary format tag=0x%04x %dx%dx%d "
608                       "avg.B/s=%d align=%d\n",
609                       wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
610                       wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
611                 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
612                       wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
613                       wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
614             }
615
616             /* Set the CooperativeLevel back to normal */
617             /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
618             rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
619             ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
620
621             init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
622
623             secondary=NULL;
624             ZeroMemory(&bufdesc, sizeof(bufdesc));
625             bufdesc.dwSize=sizeof(bufdesc);
626             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
627             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
628                                         wfx.nBlockAlign);
629             bufdesc.lpwfxFormat=&wfx2;
630             if (winetest_interactive) {
631                 trace("  Testing a primary buffer at %dx%dx%d (fmt=%d) with a "
632                       "secondary buffer at %dx%dx%d\n",
633                       wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag],
634                       wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
635             }
636             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
637             ok(rc==DS_OK && secondary!=NULL,
638                "IDirectSound_CreateSoundBuffer() failed to create a secondary "
639                "buffer %08x\n",rc);
640
641             if (rc==DS_OK && secondary!=NULL) {
642                 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
643                              winetest_interactive,1.0,0,NULL,0,0);
644
645                 ref=IDirectSoundBuffer_Release(secondary);
646                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
647                    "should have 0\n",ref);
648             }
649           }
650         }
651
652         ref=IDirectSoundBuffer_Release(primary);
653         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
654            "should have 0\n",ref);
655     }
656
657     /* Set the CooperativeLevel back to normal */
658     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
659     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
660     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
661
662 EXIT:
663     ref=IDirectSound8_Release(dso);
664     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
665     if (ref!=0)
666         return DSERR_GENERIC;
667
668     return rc;
669 }
670
671 static HRESULT test_secondary8(LPGUID lpGuid)
672 {
673     HRESULT rc;
674     LPDIRECTSOUND8 dso=NULL;
675     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
676     DSBUFFERDESC bufdesc;
677     DSCAPS dscaps;
678     WAVEFORMATEX wfx, wfx1;
679     DWORD f, tag;
680     int ref;
681
682     /* Create the DirectSound object */
683     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
684     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
685        "DirectSoundCreate8() failed: %08x\n",rc);
686     if (rc!=DS_OK)
687         return rc;
688
689     /* Get the device capabilities */
690     ZeroMemory(&dscaps, sizeof(dscaps));
691     dscaps.dwSize=sizeof(dscaps);
692     rc=IDirectSound8_GetCaps(dso,&dscaps);
693     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
694     if (rc!=DS_OK)
695         goto EXIT;
696
697     /* We must call SetCooperativeLevel before creating primary buffer */
698     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
699     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
700     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
701     if (rc!=DS_OK)
702         goto EXIT;
703
704     ZeroMemory(&bufdesc, sizeof(bufdesc));
705     bufdesc.dwSize=sizeof(bufdesc);
706     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
707     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
708     ok(rc==DS_OK && primary!=NULL,
709        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
710        "%08x\n",rc);
711
712     if (rc==DS_OK && primary!=NULL) {
713         rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
714         ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc);
715         if (rc!=DS_OK)
716             goto EXIT1;
717
718         for (f=0;f<NB_FORMATS;f++) {
719           for (tag=0;tag<NB_TAGS;tag++) {
720             WAVEFORMATEXTENSIBLE wfxe;
721
722             /* if float, we only want to test 32-bit */
723             if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
724                 continue;
725
726             init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1],
727                         formats[f][2]);
728             secondary=NULL;
729             ZeroMemory(&bufdesc, sizeof(bufdesc));
730             bufdesc.dwSize=sizeof(bufdesc);
731             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
732             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
733                                         wfx.nBlockAlign);
734             rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
735             ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
736                "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
737             if (rc==DS_OK && secondary!=NULL)
738                 IDirectSoundBuffer_Release(secondary);
739
740             secondary=NULL;
741             ZeroMemory(&bufdesc, sizeof(bufdesc));
742             bufdesc.dwSize=sizeof(bufdesc);
743             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
744             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
745                                         wfx.nBlockAlign);
746             bufdesc.lpwfxFormat=&wfx;
747             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
748             if (wfx.wBitsPerSample != 8 && wfx.wBitsPerSample != 16)
749                 ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary)
750                     || rc == DS_OK, /* driver dependent? */
751                     "IDirectSound_CreateSoundBuffer() "
752                     "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
753                     "and NULL, returned: %08x %p\n", rc, secondary);
754             else
755                 ok(rc==DS_OK && secondary!=NULL,
756                     "IDirectSound_CreateSoundBuffer() failed to create a secondary "
757                     "buffer %08x\n",rc);
758             if (secondary)
759                 IDirectSoundBuffer_Release(secondary);
760             secondary = NULL;
761
762             bufdesc.lpwfxFormat=(WAVEFORMATEX*)&wfxe;
763             wfxe.Format = wfx;
764             wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
765             wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
766             wfxe.Format.cbSize = 1;
767             wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample;
768             wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO);
769
770             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
771             ok(rc==DSERR_INVALIDPARAM && !secondary,
772                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
773                 rc, secondary);
774             if (secondary)
775             {
776                 IDirectSoundBuffer_Release(secondary);
777                 secondary=NULL;
778             }
779
780             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1;
781
782             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
783             ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary)
784                 || rc==DS_OK /* driver dependent? */,
785                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
786                 rc, secondary);
787             if (secondary)
788             {
789                 IDirectSoundBuffer_Release(secondary);
790                 secondary=NULL;
791             }
792
793             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
794             wfxe.SubFormat = GUID_NULL;
795             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
796             ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary,
797                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
798                 rc, secondary);
799             if (secondary)
800             {
801                 IDirectSoundBuffer_Release(secondary);
802                 secondary=NULL;
803             }
804
805             wfxe.Format.cbSize = sizeof(wfxe);
806             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
807             ok((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL || rc==E_INVALIDARG) && !secondary,
808                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
809                 rc, secondary);
810             if (secondary)
811             {
812                 IDirectSoundBuffer_Release(secondary);
813                 secondary=NULL;
814             }
815
816             wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
817             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
818             ok(rc==DS_OK && secondary,
819                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
820                 rc, secondary);
821             if (secondary)
822             {
823                 IDirectSoundBuffer_Release(secondary);
824                 secondary=NULL;
825             }
826
827             wfxe.Format.cbSize = sizeof(wfxe) + 1;
828             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
829             ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary)
830                 || rc==DS_OK /* driver dependent? */,
831                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
832                 rc, secondary);
833             if (secondary)
834             {
835                 IDirectSoundBuffer_Release(secondary);
836                 secondary=NULL;
837             }
838
839             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
840             ++wfxe.Samples.wValidBitsPerSample;
841             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
842             ok(rc==DSERR_INVALIDPARAM && !secondary,
843                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
844                 rc, secondary);
845             if (secondary)
846             {
847                 IDirectSoundBuffer_Release(secondary);
848                 secondary=NULL;
849             }
850             --wfxe.Samples.wValidBitsPerSample;
851
852             wfxe.Samples.wValidBitsPerSample = 0;
853             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
854             ok(rc==DS_OK && secondary,
855                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
856                 rc, secondary);
857             if (secondary)
858             {
859                 IDirectSoundBuffer_Release(secondary);
860                 secondary=NULL;
861             }
862             wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample;
863
864             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
865             ok(rc==DS_OK && secondary!=NULL,
866                 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
867                 "buffer %08x\n",rc);
868
869             if (rc==DS_OK && secondary!=NULL) {
870                 if (winetest_interactive) {
871                     trace("  Testing a secondary buffer at %dx%dx%d (fmt=%d) "
872                         "with a primary buffer at %dx%dx%d\n",
873                         wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag],
874                         wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
875                 }
876                 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
877                              winetest_interactive,1.0,0,NULL,0,0);
878
879                 ref=IDirectSoundBuffer_Release(secondary);
880                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
881                    "should have 0\n",ref);
882             }
883           }
884         }
885 EXIT1:
886         ref=IDirectSoundBuffer_Release(primary);
887         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
888            "should have 0\n",ref);
889     }
890
891     /* Set the CooperativeLevel back to normal */
892     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
893     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
894     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
895
896 EXIT:
897     ref=IDirectSound8_Release(dso);
898     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
899     if (ref!=0)
900         return DSERR_GENERIC;
901
902     return rc;
903 }
904
905 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
906                                    LPCSTR lpcstrModule, LPVOID lpContext)
907 {
908     HRESULT rc;
909     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
910     rc = test_dsound8(lpGuid);
911     if (rc == DSERR_NODRIVER)
912         trace("  No Driver\n");
913     else if (rc == DSERR_ALLOCATED)
914         trace("  Already In Use\n");
915     else if (rc == E_FAIL)
916         trace("  No Device\n");
917     else {
918         test_primary8(lpGuid);
919         test_primary_secondary8(lpGuid);
920         test_secondary8(lpGuid);
921     }
922
923     return 1;
924 }
925
926 static void dsound8_tests(void)
927 {
928     HRESULT rc;
929     rc=pDirectSoundEnumerateA(&dsenum_callback,NULL);
930     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %08x\n",rc);
931 }
932
933
934 START_TEST(dsound8)
935 {
936     HMODULE hDsound;
937
938     CoInitialize(NULL);
939
940     hDsound = LoadLibrary("dsound.dll");
941     if (hDsound)
942     {
943
944         pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound,
945             "DirectSoundEnumerateA");
946         pDirectSoundCreate8 = (void*)GetProcAddress(hDsound,
947             "DirectSoundCreate8");
948         if (pDirectSoundCreate8)
949         {
950             IDirectSound8_tests();
951             dsound8_tests();
952         }
953         else
954             skip("dsound8 test skipped\n");
955
956         FreeLibrary(hDsound);
957     }
958     else
959         skip("dsound.dll not found!\n");
960
961     CoUninitialize();
962 }