Refactored common test code into subroutines.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 #define NONAMELESSSTRUCT
29 #define NONAMELESSUNION
30 #include <windows.h>
31
32 #include <math.h>
33 #include <stdlib.h>
34
35 #include "wine/test.h"
36 #include "windef.h"
37 #include "wingdi.h"
38 #include "dsound.h"
39 #include "dxerr8.h"
40 #include "dsconf.h"
41
42 #include "dsound_test.h"
43
44 static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
45                                LPCGUID lpGuid)
46 {
47     HRESULT rc;
48     DSCAPS dscaps;
49     int ref;
50     IUnknown * unknown;
51     IDirectSound * ds;
52     IDirectSound8 * ds8;
53     DWORD speaker_config, new_speaker_config;
54     DWORD certified;
55
56     /* Try to Query for objects */
57     rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
58     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
59        DXGetErrorString8(rc));
60     if (rc==DS_OK)
61         IDirectSound8_Release(unknown);
62
63     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
64     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
65        DXGetErrorString8(rc));
66     if (rc==DS_OK)
67         IDirectSound_Release(ds);
68
69     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
70     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
71        "should have failed: %s\n",DXGetErrorString8(rc));
72     if (rc==DS_OK)
73         IDirectSound8_Release(ds8);
74
75     if (initialized == FALSE) {
76         /* try unitialized object */
77         rc=IDirectSound8_GetCaps(dso,0);
78         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
79            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
80            DXGetErrorString8(rc));
81
82         rc=IDirectSound8_GetCaps(dso,&dscaps);
83         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
84            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
85            DXGetErrorString8(rc));
86
87         rc=IDirectSound8_Compact(dso);
88         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
89            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
90            DXGetErrorString8(rc));
91
92         rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
93         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
94            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
95            DXGetErrorString8(rc));
96
97         rc=IDirectSound8_VerifyCertification(dso, &certified);
98         ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
99            "should have returned DSERR_UNINITIALIZED, returned: %s\n",
100            DXGetErrorString8(rc));
101
102         rc=IDirectSound8_Initialize(dso,lpGuid);
103         ok(rc==DS_OK,"IDirectSound8_Initialize() failed: %s\n",
104            DXGetErrorString8(rc));
105     }
106
107     /* DSOUND: Error: Invalid caps buffer */
108     rc=IDirectSound8_GetCaps(dso,0);
109     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
110        "should have failed: %s\n",DXGetErrorString8(rc));
111
112     ZeroMemory(&dscaps, sizeof(dscaps));
113
114     /* DSOUND: Error: Invalid caps buffer */
115     rc=IDirectSound8_GetCaps(dso,&dscaps);
116     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
117        "should have failed: %s\n",DXGetErrorString8(rc));
118
119     dscaps.dwSize=sizeof(dscaps);
120
121     /* DSOUND: Running on a certified driver */
122     rc=IDirectSound8_GetCaps(dso,&dscaps);
123     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
124
125     rc=IDirectSound8_Compact(dso);
126     ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
127        DXGetErrorString8(rc));
128
129     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
130     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
131        DXGetErrorString8(rc));
132
133     rc=IDirectSound8_Compact(dso);
134     ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));
135
136     rc=IDirectSound8_GetSpeakerConfig(dso,0);
137     ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
138        "should have failed: %s\n",DXGetErrorString8(rc));
139
140     rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
141     ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
142        DXGetErrorString8(rc));
143
144     speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
145                                         DSSPEAKER_GEOMETRY_WIDE);
146     rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
147     ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
148        DXGetErrorString8(rc));
149     if (rc==DS_OK) {
150         rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
151         ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
152            DXGetErrorString8(rc));
153         if (rc==DS_OK)
154             ok(speaker_config==new_speaker_config,
155                "IDirectSound8_GetSpeakerConfig() failed to set speaker config: "
156                "expected 0x%08lx, got 0x%08lx\n",
157                speaker_config,new_speaker_config);
158     }
159
160     rc=IDirectSound8_VerifyCertification(dso, &certified);
161     ok(rc==DS_OK,"IDirectSound8_VerifyCertification() failed: %s\n",
162        DXGetErrorString8(rc));
163
164     ref=IDirectSound8_Release(dso);
165     ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
166 }
167
168 static void IDirectSound8_tests()
169 {
170     HRESULT rc;
171     LPDIRECTSOUND8 dso=NULL;
172
173     trace("Testing IDirectSound8\n");
174
175     /* try the COM class factory method of creation with no device specified */
176     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
177                         &IID_IDirectSound8, (void**)&dso);
178     ok(rc==S_OK,"CoCreateInstance failed: %s\n",DXGetErrorString8(rc));
179     if (dso)
180         IDirectSound8_test(dso, FALSE, NULL);
181
182     /* try the COM class factory method of creation with default playback
183      *  device specified */
184     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
185                         &IID_IDirectSound8, (void**)&dso);
186     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
187        DXGetErrorString8(rc));
188     if (dso)
189         IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback);
190
191     /* try the COM class factory method of creation with default voice
192      * playback device specified */
193     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
194                         &IID_IDirectSound8, (void**)&dso);
195     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %s\n",
196        DXGetErrorString8(rc));
197     if (dso)
198         IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback);
199
200     /* try the COM class factory method of creation with a bad
201      * IID specified */
202     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
203                         &CLSID_DirectSoundPrivate, (void**)&dso);
204     ok(rc==E_NOINTERFACE,
205        "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) "
206        "should have failed: %s\n",DXGetErrorString8(rc));
207
208     /* try the COM class factory method of creation with a bad
209      * GUID and IID specified */
210     rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER,
211                         &IID_IDirectSound8, (void**)&dso);
212     ok(rc==REGDB_E_CLASSNOTREG,
213        "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) "
214        "should have failed: %s\n",DXGetErrorString8(rc));
215
216     /* try with no device specified */
217     rc=DirectSoundCreate8(NULL,&dso,NULL);
218     ok(rc==S_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
219     if (dso)
220         IDirectSound8_test(dso, TRUE, NULL);
221
222     /* try with default playback device specified */
223     rc=DirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL);
224     ok(rc==S_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
225     if (dso)
226         IDirectSound8_test(dso, TRUE, NULL);
227
228     /* try with default voice playback device specified */
229     rc=DirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL);
230     ok(rc==S_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
231     if (dso)
232         IDirectSound8_test(dso, TRUE, NULL);
233
234     /* try with a bad device specified */
235     rc=DirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL);
236     ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) "
237        "should have failed: %s\n",DXGetErrorString8(rc));
238 }
239
240 static HRESULT test_dsound8(LPGUID lpGuid)
241 {
242     HRESULT rc;
243     LPDIRECTSOUND8 dso=NULL;
244     int ref;
245
246     /* DSOUND: Error: Invalid interface buffer */
247     rc=DirectSoundCreate8(lpGuid,0,NULL);
248     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8 should have failed: %s\n",
249        DXGetErrorString8(rc));
250
251     /* Create the DirectSound8 object */
252     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
253     ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
254     if (rc!=DS_OK)
255         return rc;
256
257     /* Try the enumerated device */
258     IDirectSound8_test(dso, TRUE, lpGuid);
259
260     /* Try the COM class factory method of creation with enumerated device */
261     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER,
262                         &IID_IDirectSound8, (void**)&dso);
263     ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %s\n",
264        DXGetErrorString8(rc));
265     if (dso)
266         IDirectSound8_test(dso, FALSE, lpGuid);
267
268     /* Create a DirectSound8 object */
269     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
270     ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString8(rc));
271     if (rc==DS_OK) {
272         LPDIRECTSOUND8 dso1=NULL;
273
274         /* Create a second DirectSound8 object */
275         rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
276         ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
277         if (rc==DS_OK) {
278             /* Release the second DirectSound8 object */
279             ref=IDirectSound8_Release(dso1);
280             ok(ref==0,"IDirectSound8_Release has %d references, "
281                "should have 0\n",ref);
282             ok(dso!=dso1,"DirectSound8 objects should be unique: "
283                "dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
284         }
285
286         /* Release the first DirectSound8 object */
287         ref=IDirectSound8_Release(dso);
288         ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",
289            ref);
290         if (ref!=0)
291             return DSERR_GENERIC;
292     } else
293         return rc;
294
295     /* Create a DirectSound8 object */
296     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
297     ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
298     if (rc==DS_OK) {
299         LPDIRECTSOUNDBUFFER secondary;
300         DSBUFFERDESC bufdesc;
301         WAVEFORMATEX wfx;
302
303         init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
304         ZeroMemory(&bufdesc, sizeof(bufdesc));
305         bufdesc.dwSize=sizeof(bufdesc);
306         bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D;
307         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
308         bufdesc.lpwfxFormat=&wfx;
309         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
310         ok(rc==DS_OK && secondary!=NULL,
311            "IDirectSound8_CreateSoundBuffer failed to create a secondary "
312            "buffer %s\n",DXGetErrorString8(rc));
313         if (rc==DS_OK && secondary!=NULL) {
314             LPDIRECTSOUND3DBUFFER buffer3d;
315             LPDIRECTSOUNDBUFFER8 buffer8;
316             rc=IDirectSound8_QueryInterface(secondary,
317                                             &IID_IDirectSound3DBuffer,
318                                             (void **)&buffer3d);
319             ok(rc==DS_OK && buffer3d!=NULL,
320                "IDirectSound8_QueryInterface failed: %s\n",
321                DXGetErrorString8(rc));
322             if (rc==DS_OK && buffer3d!=NULL) {
323                 ref=IDirectSound3DBuffer_AddRef(buffer3d);
324                 ok(ref==2,"IDirectSound3DBuffer_AddRef has %d references, "
325                    "should have 2\n",ref);
326             }
327             rc=IDirectSound8_QueryInterface(secondary,
328                                             &IID_IDirectSoundBuffer8,
329                                             (void **)&buffer8);
330             if (rc==DS_OK && buffer8!=NULL) {
331                 ref=IDirectSoundBuffer8_AddRef(buffer8);
332                 ok(ref==3,"IDirectSoundBuffer8_AddRef has %d references, "
333                    "should have 3\n",ref);
334             }
335             ref=IDirectSoundBuffer_AddRef(secondary);
336             ok(ref==4,"IDirectSoundBuffer_AddRef has %d references, "
337                "should have 4\n",ref);
338         }
339         /* release with buffer */
340         ref=IDirectSound8_Release(dso);
341         ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",
342            ref);
343         if (ref!=0)
344             return DSERR_GENERIC;
345     } else
346         return rc;
347
348     return DS_OK;
349 }
350
351 static HRESULT test_primary8(LPGUID lpGuid)
352 {
353     HRESULT rc;
354     LPDIRECTSOUND8 dso=NULL;
355     LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
356     DSBUFFERDESC bufdesc;
357     DSCAPS dscaps;
358     int ref;
359
360     /* Create the DirectSound object */
361     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
362     ok(rc==DS_OK,"DirectSoundCreate8() failed: %s\n",DXGetErrorString8(rc));
363     if (rc!=DS_OK)
364         return rc;
365
366     /* Get the device capabilities */
367     ZeroMemory(&dscaps, sizeof(dscaps));
368     dscaps.dwSize=sizeof(dscaps);
369     rc=IDirectSound8_GetCaps(dso,&dscaps);
370     ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));
371     if (rc!=DS_OK)
372         goto EXIT;
373
374     /* DSOUND: Error: Invalid buffer description pointer */
375     rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
376     ok(rc==DSERR_INVALIDPARAM,
377        "IDirectSound8_CreateSoundBuffer should have failed: %s\n",
378        DXGetErrorString8(rc));
379
380     /* DSOUND: Error: Invalid buffer description pointer */
381     rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
382     ok(rc==DSERR_INVALIDPARAM && primary==0,
383        "IDirectSound8_CreateSoundBuffer should have failed: rc=%s,dsbo=0x%lx\n",
384        DXGetErrorString8(rc),(DWORD)primary);
385
386     /* DSOUND: Error: Invalid buffer description pointer */
387     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
388     ok(rc==DSERR_INVALIDPARAM && primary==0,
389        "IDirectSound8_CreateSoundBuffer should have failed: rc=%s,dsbo=0x%lx\n",
390        DXGetErrorString8(rc),(DWORD)primary);
391
392     ZeroMemory(&bufdesc, sizeof(bufdesc));
393
394     /* DSOUND: Error: Invalid size */
395     /* DSOUND: Error: Invalid buffer description */
396     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
397     ok(rc==DSERR_INVALIDPARAM && primary==0,
398        "IDirectSound8_CreateSoundBuffer should have failed: rc=%s,"
399        "primary=0x%lx\n",DXGetErrorString8(rc),(DWORD)primary);
400
401     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
402     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
403     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
404     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel failed: %s\n",
405        DXGetErrorString8(rc));
406     if (rc!=DS_OK)
407         goto EXIT;
408
409     /* Testing the primary buffer */
410     primary=NULL;
411     ZeroMemory(&bufdesc, sizeof(bufdesc));
412     bufdesc.dwSize=sizeof(bufdesc);
413     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
414     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
415     ok(rc==DS_OK && primary!=NULL,
416        "IDirectSound8_CreateSoundBuffer failed to create a primary buffer: "
417        "%s\n",DXGetErrorString8(rc));
418     if (rc==DS_OK && primary!=NULL) {
419         LONG vol;
420
421         /* Try to create a second primary buffer */
422         /* DSOUND: Error: The primary buffer already exists.
423          * Any changes made to the buffer description will be ignored. */
424         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
425         ok(rc==DS_OK && second==primary,
426            "IDirectSound8_CreateSoundBuffer should have returned original "
427            "primary buffer: %s\n",DXGetErrorString8(rc));
428         ref=IDirectSoundBuffer_Release(second);
429         ok(ref==1,"IDirectSoundBuffer_Release primary has %d references, "
430            "should have 1\n",ref);
431
432         /* Try to duplicate a primary buffer */
433         /* DSOUND: Error: Can't duplicate primary buffers */
434         rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
435         /* rc=0x88780032 */
436         ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer primary buffer should "
437            "have failed %s\n",DXGetErrorString8(rc));
438
439         rc=IDirectSoundBuffer_GetVolume(primary,&vol);
440         ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume failed: %s\n",
441            DXGetErrorString8(rc));
442
443         if (winetest_interactive) {
444             trace("Playing a 5 seconds reference tone at the current volume.\n");
445             if (rc==DS_OK)
446                 trace("(the current volume is %ld according to DirectSound)\n",
447                       vol);
448             trace("All subsequent tones should be identical to this one.\n");
449             trace("Listen for stutter, changes in pitch, volume, etc.\n");
450         }
451         test_buffer8(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
452                      !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
453
454         ref=IDirectSoundBuffer_Release(primary);
455         ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, "
456            "should have 0\n",ref);
457     }
458
459     /* Set the CooperativeLevel back to normal */
460     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
461     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
462     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel failed: %s\n",
463        DXGetErrorString8(rc));
464
465 EXIT:
466     ref=IDirectSound8_Release(dso);
467     ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
468     if (ref!=0)
469         return DSERR_GENERIC;
470
471     return rc;
472 }
473
474 static HRESULT test_secondary8(LPGUID lpGuid)
475 {
476     HRESULT rc;
477     LPDIRECTSOUND8 dso=NULL;
478     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
479     DSBUFFERDESC bufdesc;
480     DSCAPS dscaps;
481     WAVEFORMATEX wfx;
482     int f,ref;
483
484     /* Create the DirectSound object */
485     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
486     ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString8(rc));
487     if (rc!=DS_OK)
488         return rc;
489
490     /* Get the device capabilities */
491     ZeroMemory(&dscaps, sizeof(dscaps));
492     dscaps.dwSize=sizeof(dscaps);
493     rc=IDirectSound8_GetCaps(dso,&dscaps);
494     ok(rc==DS_OK,"IDirectSound8_GetCaps failed: %s\n",DXGetErrorString8(rc));
495     if (rc!=DS_OK)
496         goto EXIT;
497
498     /* We must call SetCooperativeLevel before creating primary buffer */
499     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
500     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
501     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel failed: %s\n",
502        DXGetErrorString8(rc));
503     if (rc!=DS_OK)
504         goto EXIT;
505
506     ZeroMemory(&bufdesc, sizeof(bufdesc));
507     bufdesc.dwSize=sizeof(bufdesc);
508     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
509     rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
510     ok(rc==DS_OK && primary!=NULL,
511        "IDirectSound8_CreateSoundBuffer failed to create a primary buffer %s\n",
512        DXGetErrorString8(rc));
513
514     if (rc==DS_OK && primary!=NULL) {
515         for (f=0;f<NB_FORMATS;f++) {
516             init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
517                         formats[f][2]);
518             secondary=NULL;
519             ZeroMemory(&bufdesc, sizeof(bufdesc));
520             bufdesc.dwSize=sizeof(bufdesc);
521             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
522             bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
523             bufdesc.lpwfxFormat=&wfx;
524             trace("  Testing a secondary buffer at %ldx%dx%d\n",
525                   wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
526             rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
527             ok(rc==DS_OK && secondary!=NULL,
528                "IDirectSound8_CreateSoundBuffer failed to create a secondary "
529                "buffer %s\n",DXGetErrorString8(rc));
530
531             if (rc==DS_OK && secondary!=NULL) {
532                 test_buffer8(dso,secondary,0,FALSE,0,FALSE,0,
533                              winetest_interactive,1.0,0,NULL,0,0);
534
535                 ref=IDirectSoundBuffer_Release(secondary);
536                 ok(ref==0,"IDirectSoundBuffer_Release has %d references, "
537                    "should have 0\n",ref);
538             }
539         }
540
541         ref=IDirectSoundBuffer_Release(primary);
542         ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, "
543            "should have 0\n",ref);
544     }
545
546     /* Set the CooperativeLevel back to normal */
547     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
548     rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
549     ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel failed: %s\n",
550        DXGetErrorString8(rc));
551
552 EXIT:
553     ref=IDirectSound8_Release(dso);
554     ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
555     if (ref!=0)
556         return DSERR_GENERIC;
557
558     return rc;
559 }
560
561 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
562                                    LPCSTR lpcstrModule, LPVOID lpContext)
563 {
564     trace("*** Testing %s - %s\n",lpcstrDescription,lpcstrModule);
565     test_dsound8(lpGuid);
566     test_primary8(lpGuid);
567     test_secondary8(lpGuid);
568
569     return 1;
570 }
571
572 static void dsound8_tests()
573 {
574     HRESULT rc;
575     rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
576     ok(rc==DS_OK,"DirectSoundEnumerate failed: %ld\n",rc);
577 }
578
579 START_TEST(dsound8)
580 {
581     HMODULE hDsound;
582     FARPROC pFunc;
583
584     CoInitialize(NULL);
585
586     hDsound = LoadLibraryA("dsound.dll");
587     if (!hDsound) {
588         trace("dsound.dll not found\n");
589         return;
590     }
591
592     pFunc = (void*)GetProcAddress(hDsound, "DirectSoundCreate8");
593     if (!pFunc) {
594         trace("dsound8 test skipped\n");
595         return;
596     }
597
598     IDirectSound8_tests();
599     dsound8_tests();
600 }