dinput: Fix printing NULL strings.
[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                 todo_wine ok(primary->lpVtbl==secondary->lpVtbl,
643                             "Primary and secondary buffers have different vtbls.\n");
644
645                 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
646                              winetest_interactive,1.0,0,NULL,0,0);
647
648                 ref=IDirectSoundBuffer_Release(secondary);
649                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
650                    "should have 0\n",ref);
651             }
652           }
653         }
654
655         ref=IDirectSoundBuffer_Release(primary);
656         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
657            "should have 0\n",ref);
658     }
659
660     /* Set the CooperativeLevel back to normal */
661     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
662     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
663     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
664
665 EXIT:
666     ref=IDirectSound8_Release(dso);
667     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
668     if (ref!=0)
669         return DSERR_GENERIC;
670
671     return rc;
672 }
673
674 static HRESULT test_secondary8(LPGUID lpGuid)
675 {
676     HRESULT rc;
677     LPDIRECTSOUND8 dso=NULL;
678     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
679     DSBUFFERDESC bufdesc;
680     DSCAPS dscaps;
681     WAVEFORMATEX wfx, wfx1;
682     DWORD f, tag;
683     int ref;
684
685     /* Create the DirectSound object */
686     rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
687     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
688        "DirectSoundCreate8() failed: %08x\n",rc);
689     if (rc!=DS_OK)
690         return rc;
691
692     /* Get the device capabilities */
693     ZeroMemory(&dscaps, sizeof(dscaps));
694     dscaps.dwSize=sizeof(dscaps);
695     rc=IDirectSound8_GetCaps(dso,&dscaps);
696     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
697     if (rc!=DS_OK)
698         goto EXIT;
699
700     /* We must call SetCooperativeLevel before creating primary buffer */
701     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
702     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
703     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
704     if (rc!=DS_OK)
705         goto EXIT;
706
707     ZeroMemory(&bufdesc, sizeof(bufdesc));
708     bufdesc.dwSize=sizeof(bufdesc);
709     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
710     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
711     ok(rc==DS_OK && primary!=NULL,
712        "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
713        "%08x\n",rc);
714
715     if (rc==DS_OK && primary!=NULL) {
716         rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
717         ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc);
718         if (rc!=DS_OK)
719             goto EXIT1;
720
721         for (f=0;f<NB_FORMATS;f++) {
722           for (tag=0;tag<NB_TAGS;tag++) {
723             WAVEFORMATEXTENSIBLE wfxe;
724
725             /* if float, we only want to test 32-bit */
726             if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
727                 continue;
728
729             init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1],
730                         formats[f][2]);
731             secondary=NULL;
732             ZeroMemory(&bufdesc, sizeof(bufdesc));
733             bufdesc.dwSize=sizeof(bufdesc);
734             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
735             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
736                                         wfx.nBlockAlign);
737             rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
738             ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
739                "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
740             if (rc==DS_OK && secondary!=NULL)
741                 IDirectSoundBuffer_Release(secondary);
742
743             secondary=NULL;
744             ZeroMemory(&bufdesc, sizeof(bufdesc));
745             bufdesc.dwSize=sizeof(bufdesc);
746             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
747             bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
748                                         wfx.nBlockAlign);
749             bufdesc.lpwfxFormat=&wfx;
750             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
751             if (wfx.wBitsPerSample != 8 && wfx.wBitsPerSample != 16)
752                 ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary)
753                     || rc == DS_OK, /* driver dependent? */
754                     "IDirectSound_CreateSoundBuffer() "
755                     "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
756                     "and NULL, returned: %08x %p\n", rc, secondary);
757             else
758                 ok(rc==DS_OK && secondary!=NULL,
759                     "IDirectSound_CreateSoundBuffer() failed to create a secondary "
760                     "buffer %08x\n",rc);
761             if (secondary)
762                 IDirectSoundBuffer_Release(secondary);
763             secondary = NULL;
764
765             bufdesc.lpwfxFormat=(WAVEFORMATEX*)&wfxe;
766             wfxe.Format = wfx;
767             wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
768             wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
769             wfxe.Format.cbSize = 1;
770             wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample;
771             wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO);
772
773             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
774             ok(rc==DSERR_INVALIDPARAM && !secondary,
775                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
776                 rc, secondary);
777             if (secondary)
778             {
779                 IDirectSoundBuffer_Release(secondary);
780                 secondary=NULL;
781             }
782
783             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1;
784
785             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
786             ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary)
787                 || rc==DS_OK /* driver dependent? */,
788                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
789                 rc, secondary);
790             if (secondary)
791             {
792                 IDirectSoundBuffer_Release(secondary);
793                 secondary=NULL;
794             }
795
796             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
797             wfxe.SubFormat = GUID_NULL;
798             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
799             ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary,
800                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
801                 rc, secondary);
802             if (secondary)
803             {
804                 IDirectSoundBuffer_Release(secondary);
805                 secondary=NULL;
806             }
807
808             wfxe.Format.cbSize = sizeof(wfxe);
809             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
810             ok((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL || rc==E_INVALIDARG) && !secondary,
811                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
812                 rc, secondary);
813             if (secondary)
814             {
815                 IDirectSoundBuffer_Release(secondary);
816                 secondary=NULL;
817             }
818
819             wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT);
820             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
821             ok(rc==DS_OK && secondary,
822                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
823                 rc, secondary);
824             if (secondary)
825             {
826                 IDirectSoundBuffer_Release(secondary);
827                 secondary=NULL;
828             }
829
830             wfxe.Format.cbSize = sizeof(wfxe) + 1;
831             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
832             ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary)
833                 || rc==DS_OK /* driver dependent? */,
834                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
835                 rc, secondary);
836             if (secondary)
837             {
838                 IDirectSoundBuffer_Release(secondary);
839                 secondary=NULL;
840             }
841
842             wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
843             ++wfxe.Samples.wValidBitsPerSample;
844             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
845             ok(rc==DSERR_INVALIDPARAM && !secondary,
846                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
847                 rc, secondary);
848             if (secondary)
849             {
850                 IDirectSoundBuffer_Release(secondary);
851                 secondary=NULL;
852             }
853             --wfxe.Samples.wValidBitsPerSample;
854
855             wfxe.Samples.wValidBitsPerSample = 0;
856             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
857             ok(rc==DS_OK && secondary,
858                 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
859                 rc, secondary);
860             if (secondary)
861             {
862                 IDirectSoundBuffer_Release(secondary);
863                 secondary=NULL;
864             }
865             wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample;
866
867             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
868             ok(rc==DS_OK && secondary!=NULL,
869                 "IDirectSound_CreateSoundBuffer() failed to create a secondary "
870                 "buffer %08x\n",rc);
871
872             if (rc==DS_OK && secondary!=NULL) {
873                 if (winetest_interactive) {
874                     trace("  Testing a secondary buffer at %dx%dx%d (fmt=%d) "
875                         "with a primary buffer at %dx%dx%d\n",
876                         wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag],
877                         wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
878                 }
879                 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
880                              winetest_interactive,1.0,0,NULL,0,0);
881
882                 ref=IDirectSoundBuffer_Release(secondary);
883                 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
884                    "should have 0\n",ref);
885             }
886           }
887         }
888 EXIT1:
889         ref=IDirectSoundBuffer_Release(primary);
890         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
891            "should have 0\n",ref);
892     }
893
894     /* Set the CooperativeLevel back to normal */
895     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
896     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
897     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
898
899 EXIT:
900     ref=IDirectSound8_Release(dso);
901     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
902     if (ref!=0)
903         return DSERR_GENERIC;
904
905     return rc;
906 }
907
908 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
909                                    LPCSTR lpcstrModule, LPVOID lpContext)
910 {
911     HRESULT rc;
912     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
913     rc = test_dsound8(lpGuid);
914     if (rc == DSERR_NODRIVER)
915         trace("  No Driver\n");
916     else if (rc == DSERR_ALLOCATED)
917         trace("  Already In Use\n");
918     else if (rc == E_FAIL)
919         trace("  No Device\n");
920     else {
921         test_primary8(lpGuid);
922         test_primary_secondary8(lpGuid);
923         test_secondary8(lpGuid);
924     }
925
926     return 1;
927 }
928
929 static void dsound8_tests(void)
930 {
931     HRESULT rc;
932     rc=pDirectSoundEnumerateA(&dsenum_callback,NULL);
933     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %08x\n",rc);
934 }
935
936
937 START_TEST(dsound8)
938 {
939     HMODULE hDsound;
940
941     CoInitialize(NULL);
942
943     hDsound = LoadLibrary("dsound.dll");
944     if (hDsound)
945     {
946
947         pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound,
948             "DirectSoundEnumerateA");
949         pDirectSoundCreate8 = (void*)GetProcAddress(hDsound,
950             "DirectSoundCreate8");
951         if (pDirectSoundCreate8)
952         {
953             IDirectSound8_tests();
954             dsound8_tests();
955         }
956         else
957             skip("dsound8 test skipped\n");
958
959         FreeLibrary(hDsound);
960     }
961     else
962         skip("dsound.dll not found!\n");
963
964     CoUninitialize();
965 }