Use system metrics values in TOOLBAR_DrawPattern instead of hardcoded
[wine] / dlls / dsound / tests / dsound.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 "dxerr9.h"
40
41 #include "dsound_test.h"
42
43 static void dsound_dsound_tests()
44 {
45     HRESULT rc;
46     LPDIRECTSOUND dso=NULL;
47     DSCAPS dscaps;
48     int ref;
49     IUnknown * unknown;
50     IDirectSound * ds;
51     IDirectSound8 * ds8;
52
53     rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&dso);
54     ok(rc==S_OK,"CoCreateInstance failed: %s\n",DXGetErrorString9(rc));
55     if (dso) {
56         /* Try to Query for objects */
57         rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
58         ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
59         if (rc==DS_OK)
60             IDirectSound_Release(unknown);
61
62         rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
63         ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
64         if (rc==DS_OK)
65             IDirectSound_Release(ds);
66
67         rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
68         ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
69         if (rc==DS_OK)
70             IDirectSound8_Release(ds8);
71
72         rc=IDirectSound_Initialize(dso,NULL);
73         ok(rc==DS_OK,"IDirectSound_Initialize(NULL) failed: %s\n",DXGetErrorString9(rc));
74
75         /* DSOUND: Error: Invalid caps buffer */
76         rc=IDirectSound_GetCaps(dso,0);
77         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
78
79         ZeroMemory(&dscaps, sizeof(dscaps));
80
81         /* DSOUND: Error: Invalid caps buffer */
82         rc=IDirectSound_GetCaps(dso,&dscaps);
83         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
84
85         dscaps.dwSize=sizeof(dscaps);
86
87         /* DSOUND: Running on a certified driver */
88         rc=IDirectSound_GetCaps(dso,&dscaps);
89         ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
90         if (rc==DS_OK) {
91             trace("  DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
92                   dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
93                   dscaps.dwMaxSecondarySampleRate);
94         }
95
96         ref=IDirectSound_Release(dso);
97         ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
98     }
99
100     rc=DirectSoundCreate(NULL,&dso,NULL);
101     ok(rc==S_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
102     if (dso) {
103         /* Try to Query for objects */
104         rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
105         ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
106         if (rc==DS_OK)
107             IDirectSound_Release(unknown);
108
109         rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
110         ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
111         if (rc==DS_OK)
112             IDirectSound_Release(ds);
113
114         rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
115         ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
116         if (rc==DS_OK)
117             IDirectSound8_Release(ds8);
118
119         /* DSOUND: Error: Invalid caps buffer */
120         rc=IDirectSound_GetCaps(dso,0);
121         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
122
123         ZeroMemory(&dscaps, sizeof(dscaps));
124
125         /* DSOUND: Error: Invalid caps buffer */
126         rc=IDirectSound_GetCaps(dso,&dscaps);
127         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
128
129         dscaps.dwSize=sizeof(dscaps);
130
131         /* DSOUND: Running on a certified driver */
132         rc=IDirectSound_GetCaps(dso,&dscaps);
133         ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
134         if (rc==DS_OK) {
135             trace("  DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
136                   dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
137                   dscaps.dwMaxSecondarySampleRate);
138         }
139
140         ref=IDirectSound_Release(dso);
141         ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
142     }
143 }
144
145 static void dsound_dsound8_tests()
146 {
147     HRESULT rc;
148     LPDIRECTSOUND8 dso=NULL;
149     DSCAPS dscaps;
150     int ref;
151     IUnknown * unknown;
152     IDirectSound * ds;
153     IDirectSound8 * ds8;
154
155     rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso);
156     ok(rc==S_OK,"CoCreateInstance failed: %s\n",DXGetErrorString9(rc));
157     if (dso) {
158         /* Try to Query for objects */
159         rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
160         ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
161         if (rc==DS_OK)
162             IDirectSound8_Release(unknown);
163
164         rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
165         ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
166         if (rc==DS_OK)
167             IDirectSound_Release(ds);
168
169         rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
170         ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
171         if (rc==DS_OK)
172             IDirectSound8_Release(ds8);
173
174         rc=IDirectSound8_Initialize(dso,NULL);
175         ok(rc==DS_OK,"IDirectSound_Initialize(NULL) failed: %s\n",DXGetErrorString9(rc));
176
177         /* DSOUND: Error: Invalid caps buffer */
178         rc=IDirectSound8_GetCaps(dso,0);
179         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
180
181         ZeroMemory(&dscaps, sizeof(dscaps));
182
183         /* DSOUND: Error: Invalid caps buffer */
184         rc=IDirectSound8_GetCaps(dso,&dscaps);
185         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
186
187         dscaps.dwSize=sizeof(dscaps);
188
189         /* DSOUND: Running on a certified driver */
190         rc=IDirectSound8_GetCaps(dso,&dscaps);
191         ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
192         if (rc==DS_OK) {
193             trace("  DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
194                   dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
195                   dscaps.dwMaxSecondarySampleRate);
196         }
197
198         ref=IDirectSound8_Release(dso);
199         ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
200     }
201
202     rc=DirectSoundCreate8(NULL,&dso,NULL);
203     ok(rc==S_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
204     if (dso) {
205         /* Try to Query for objects */
206         rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
207         ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
208         if (rc==DS_OK)
209             IDirectSound8_Release(unknown);
210
211         rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
212         ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
213         if (rc==DS_OK)
214             IDirectSound_Release(ds);
215
216         rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
217         ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
218         if (rc==DS_OK)
219             IDirectSound8_Release(ds8);
220
221         /* DSOUND: Error: Invalid caps buffer */
222         rc=IDirectSound8_GetCaps(dso,0);
223         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
224
225         ZeroMemory(&dscaps, sizeof(dscaps));
226
227         /* DSOUND: Error: Invalid caps buffer */
228         rc=IDirectSound8_GetCaps(dso,&dscaps);
229         ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
230
231         dscaps.dwSize=sizeof(dscaps);
232
233         /* DSOUND: Running on a certified driver */
234         rc=IDirectSound8_GetCaps(dso,&dscaps);
235         ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
236         if (rc==DS_OK) {
237             trace("  DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
238                   dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
239                   dscaps.dwMaxSecondarySampleRate);
240         }
241
242         ref=IDirectSound8_Release(dso);
243         ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
244     }
245 }
246
247 static HRESULT test_dsound(LPGUID lpGuid)
248 {
249     HRESULT rc;
250     LPDIRECTSOUND dso=NULL;
251     DSCAPS dscaps;
252     int ref;
253     IUnknown * unknown;
254     IDirectSound * ds;
255     IDirectSound8 * ds8;
256
257     /* DSOUND: Error: Invalid interface buffer */
258     rc=DirectSoundCreate(lpGuid,0,NULL);
259     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: %s\n",DXGetErrorString9(rc));
260
261     /* Create the DirectSound object */
262     rc=DirectSoundCreate(lpGuid,&dso,NULL);
263     ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
264     if (rc!=DS_OK)
265         return rc;
266
267     /* Try to Query for objects */
268     rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
269     ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
270     if (rc==DS_OK)
271         IDirectSound_Release(unknown);
272
273     rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
274     ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
275     if (rc==DS_OK)
276         IDirectSound_Release(ds);
277
278     rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
279     ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
280     if (rc==DS_OK)
281         IDirectSound8_Release(ds8);
282
283     /* DSOUND: Error: Invalid caps buffer */
284     rc=IDirectSound_GetCaps(dso,0);
285     ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
286
287     ZeroMemory(&dscaps, sizeof(dscaps));
288
289     /* DSOUND: Error: Invalid caps buffer */
290     rc=IDirectSound_GetCaps(dso,&dscaps);
291     ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
292
293     dscaps.dwSize=sizeof(dscaps);
294
295     /* DSOUND: Running on a certified driver */
296     rc=IDirectSound_GetCaps(dso,&dscaps);
297     ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
298     if (rc==DS_OK) {
299         trace("  DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
300               dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
301               dscaps.dwMaxSecondarySampleRate);
302     }
303
304     /* Release the DirectSound object */
305     ref=IDirectSound_Release(dso);
306     ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
307     if (ref!=0)
308         return DSERR_GENERIC;
309
310     /* Create a DirectSound object */
311     rc=DirectSoundCreate(lpGuid,&dso,NULL);
312     ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
313     if (rc==DS_OK) {
314         LPDIRECTSOUND dso1=NULL;
315
316         /* Create a second DirectSound object */
317         rc=DirectSoundCreate(lpGuid,&dso1,NULL);
318         ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
319         if (rc==DS_OK) {
320             /* Release the second DirectSound object */
321             ref=IDirectSound_Release(dso1);
322             ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
323             ok(dso!=dso1,"DirectSound objects should be unique: dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
324         }
325
326         /* Release the first DirectSound object */
327         ref=IDirectSound_Release(dso);
328         ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
329         if (ref!=0)
330             return DSERR_GENERIC;
331     } else
332         return rc;
333
334     /* Create a DirectSound object */
335     rc=DirectSoundCreate(lpGuid,&dso,NULL);
336     ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
337     if (rc==DS_OK) {
338         LPDIRECTSOUNDBUFFER secondary;
339         DSBUFFERDESC bufdesc;
340         WAVEFORMATEX wfx;
341
342         init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
343         ZeroMemory(&bufdesc, sizeof(bufdesc));
344         bufdesc.dwSize=sizeof(bufdesc);
345         bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME;
346         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
347         bufdesc.lpwfxFormat=&wfx;
348         rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
349         ok(rc==DS_OK && secondary!=NULL,"CreateSoundBuffer failed to create a secondary buffer 0x%lx\n", rc);
350         if (rc==DS_OK && secondary!=NULL) {
351             /* add some more refs */
352             IDirectSoundBuffer_AddRef(secondary);
353         }
354         /* release with buffer */
355         ref=IDirectSound_Release(dso);
356         ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
357         if (ref!=0)
358             return DSERR_GENERIC;
359     } else
360         return rc;
361
362     return DS_OK;
363 }
364
365 static HRESULT test_dsound8(LPGUID lpGuid)
366 {
367     HRESULT rc;
368     LPDIRECTSOUND8 dso=NULL;
369     DSCAPS dscaps;
370     int ref;
371     IUnknown * unknown;
372     IDirectSound * ds;
373     IDirectSound8 * ds8;
374
375     /* DSOUND: Error: Invalid interface buffer */
376     rc=DirectSoundCreate8(lpGuid,0,NULL);
377     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8 should have failed: %s\n",DXGetErrorString9(rc));
378
379     /* Create the DirectSound8 object */
380     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
381     ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
382     if (rc!=DS_OK)
383         return rc;
384
385     /* Try to Query for objects */
386     rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
387     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
388     if (rc==DS_OK)
389         IDirectSound8_Release(unknown);
390
391     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
392     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
393     if (rc==DS_OK)
394         IDirectSound_Release(ds);
395
396     rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
397     ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) failed: %s\n",DXGetErrorString9(rc));
398     if (rc==DS_OK)
399         IDirectSound8_Release(ds8);
400
401     /* DSOUND: Error: Invalid caps buffer */
402     rc=IDirectSound8_GetCaps(dso,0);
403     ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
404
405     ZeroMemory(&dscaps, sizeof(dscaps));
406
407     /* DSOUND: Error: Invalid caps buffer */
408     rc=IDirectSound8_GetCaps(dso,&dscaps);
409     ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
410
411     dscaps.dwSize=sizeof(dscaps);
412
413     /* DSOUND: Running on a certified driver */
414     rc=IDirectSound8_GetCaps(dso,&dscaps);
415     ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
416     if (rc==DS_OK) {
417         trace("  DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
418               dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
419               dscaps.dwMaxSecondarySampleRate);
420     }
421
422     /* Release the DirectSound8 object */
423     ref=IDirectSound8_Release(dso);
424     ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
425     if (ref!=0)
426         return DSERR_GENERIC;
427
428     /* Create a DirectSound8 object */
429     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
430     ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
431     if (rc==DS_OK) {
432         LPDIRECTSOUND8 dso1=NULL;
433
434         /* Create a second DirectSound8 object */
435         rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
436         ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
437         if (rc==DS_OK) {
438             /* Release the second DirectSound8 object */
439             ref=IDirectSound8_Release(dso1);
440             ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
441             ok(dso!=dso1,"DirectSound8 objects should be unique: dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
442         }
443
444         /* Release the first DirectSound8 object */
445         ref=IDirectSound8_Release(dso);
446         ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
447         if (ref!=0)
448             return DSERR_GENERIC;
449     } else
450         return rc;
451
452     /* Create a DirectSound8 object */
453     rc=DirectSoundCreate8(lpGuid,&dso,NULL);
454     ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
455     if (rc==DS_OK) {
456         LPDIRECTSOUNDBUFFER secondary;
457         DSBUFFERDESC bufdesc;
458         WAVEFORMATEX wfx;
459
460         init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
461         ZeroMemory(&bufdesc, sizeof(bufdesc));
462         bufdesc.dwSize=sizeof(bufdesc);
463         bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME;
464         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
465         bufdesc.lpwfxFormat=&wfx;
466         rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
467         ok(rc==DS_OK && secondary!=NULL,"CreateSoundBuffer failed to create a secondary buffer 0x%lx\n", rc);
468         if (rc==DS_OK && secondary!=NULL) {
469             /* add some more refs */
470             IDirectSoundBuffer8_AddRef(secondary);
471         }
472         /* release with buffer */
473         ref=IDirectSound8_Release(dso);
474         ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
475         if (ref!=0)
476             return DSERR_GENERIC;
477     } else
478         return rc;
479
480     return DS_OK;
481 }
482
483 static HRESULT test_primary(LPGUID lpGuid)
484 {
485     HRESULT rc;
486     LPDIRECTSOUND dso=NULL;
487     LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
488     DSBUFFERDESC bufdesc;
489     DSCAPS dscaps;
490     int ref;
491
492     /* Create the DirectSound object */
493     rc=DirectSoundCreate(lpGuid,&dso,NULL);
494     ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
495     if (rc!=DS_OK)
496         return rc;
497
498     /* Get the device capabilities */
499     ZeroMemory(&dscaps, sizeof(dscaps));
500     dscaps.dwSize=sizeof(dscaps);
501     rc=IDirectSound_GetCaps(dso,&dscaps);
502     ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
503     if (rc!=DS_OK)
504         goto EXIT;
505
506     /* DSOUND: Error: Invalid buffer description pointer */
507     rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL);
508     ok(rc==DSERR_INVALIDPARAM,"CreateSoundBuffer should have failed: 0x%lx\n",rc);
509
510     /* DSOUND: Error: Invalid buffer description pointer */
511     rc=IDirectSound_CreateSoundBuffer(dso,0,&primary,NULL);
512     ok(rc==DSERR_INVALIDPARAM && primary==0,"CreateSoundBuffer should have failed: rc=0x%lx,dsbo=0x%lx\n",rc,(DWORD)primary);
513
514     /* DSOUND: Error: Invalid buffer description pointer */
515     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,0,NULL);
516     ok(rc==DSERR_INVALIDPARAM && primary==0,"CreateSoundBuffer should have failed: rc=0x%lx,dsbo=0x%lx\n",rc,(DWORD)primary);
517
518     ZeroMemory(&bufdesc, sizeof(bufdesc));
519
520     /* DSOUND: Error: Invalid size */
521     /* DSOUND: Error: Invalid buffer description */
522     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
523     ok(rc==DSERR_INVALIDPARAM && primary==0,"CreateSoundBuffer should have failed: rc=0x%lx,primary=0x%lx\n",rc,(DWORD)primary);
524
525     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
526     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
527     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
528     ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
529     if (rc!=DS_OK)
530         goto EXIT;
531
532     /* Testing the primary buffer */
533     primary=NULL;
534     ZeroMemory(&bufdesc, sizeof(bufdesc));
535     bufdesc.dwSize=sizeof(bufdesc);
536     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
537     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
538     ok(rc==DS_OK && primary!=NULL,"CreateSoundBuffer failed to create a primary buffer: 0x%lx\n",rc);
539     if (rc==DS_OK && primary!=NULL) {
540         LONG vol;
541
542         /* Try to create a second primary buffer */
543         /* DSOUND: Error: The primary buffer already exists.  Any changes made to the buffer description will be ignored. */
544         rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
545         ok(rc==DS_OK && second==primary,"CreateSoundBuffer should have returned original primary buffer: 0x%lx\n",rc);
546         ref=IDirectSoundBuffer_Release(second);
547         ok(ref==1,"IDirectSoundBuffer_Release primary has %d references, should have 1\n",ref);
548
549         /* Try to duplicate a primary buffer */
550         /* DSOUND: Error: Can't duplicate primary buffers */
551         rc=IDirectSound_DuplicateSoundBuffer(dso,primary,&third);
552         /* rc=0x88780032 */
553         ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer primary buffer should have failed 0x%lx\n",rc);
554
555         rc=IDirectSoundBuffer_GetVolume(primary,&vol);
556         ok(rc==DS_OK,"GetVolume failed: 0x%lx\n",rc);
557
558         if (winetest_interactive)
559         {
560             trace("Playing a 5 seconds reference tone at the current volume.\n");
561             if (rc==DS_OK)
562                 trace("(the current volume is %ld according to DirectSound)\n",vol);
563             trace("All subsequent tones should be identical to this one.\n");
564             trace("Listen for stutter, changes in pitch, volume, etc.\n");
565         }
566         test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);
567
568         ref=IDirectSoundBuffer_Release(primary);
569         ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
570     }
571
572     /* Set the CooperativeLevel back to normal */
573     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
574     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
575     ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%lx\n",rc);
576
577 EXIT:
578     ref=IDirectSound_Release(dso);
579     ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
580     if (ref!=0)
581         return DSERR_GENERIC;
582
583     return rc;
584 }
585
586 static HRESULT test_secondary(LPGUID lpGuid)
587 {
588     HRESULT rc;
589     LPDIRECTSOUND dso=NULL;
590     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
591     DSBUFFERDESC bufdesc;
592     DSCAPS dscaps;
593     WAVEFORMATEX wfx;
594     int f,ref;
595
596     /* Create the DirectSound object */
597     rc=DirectSoundCreate(lpGuid,&dso,NULL);
598     ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
599     if (rc!=DS_OK)
600         return rc;
601
602     /* Get the device capabilities */
603     ZeroMemory(&dscaps, sizeof(dscaps));
604     dscaps.dwSize=sizeof(dscaps);
605     rc=IDirectSound_GetCaps(dso,&dscaps);
606     ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
607     if (rc!=DS_OK)
608         goto EXIT;
609
610     /* We must call SetCooperativeLevel before creating primary buffer */
611     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
612     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
613     ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
614     if (rc!=DS_OK)
615         goto EXIT;
616
617     ZeroMemory(&bufdesc, sizeof(bufdesc));
618     bufdesc.dwSize=sizeof(bufdesc);
619     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
620     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
621     ok(rc==DS_OK && primary!=NULL,"CreateSoundBuffer failed to create a primary buffer 0x%lx\n", rc);
622
623     if (rc==DS_OK && primary!=NULL) {
624         for (f=0;f<NB_FORMATS;f++) {
625             init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],formats[f][2]);
626             secondary=NULL;
627             ZeroMemory(&bufdesc, sizeof(bufdesc));
628             bufdesc.dwSize=sizeof(bufdesc);
629             bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
630             bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
631             bufdesc.lpwfxFormat=&wfx;
632             trace("  Testing a secondary buffer at %ldx%dx%d\n",
633                   wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
634             rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
635             ok(rc==DS_OK && secondary!=NULL,"CreateSoundBuffer failed to create a secondary buffer 0x%lx\n",rc);
636
637             if (rc==DS_OK && secondary!=NULL) {
638                 test_buffer(dso,secondary,0,FALSE,0,FALSE,0,winetest_interactive,1.0,0,NULL,0,0);
639
640                 ref=IDirectSoundBuffer_Release(secondary);
641                 ok(ref==0,"IDirectSoundBuffer_Release has %d references, should have 0\n",ref);
642             }
643         }
644
645         ref=IDirectSoundBuffer_Release(primary);
646         ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
647     }
648
649     /* Set the CooperativeLevel back to normal */
650     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
651     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
652     ok(rc==DS_OK,"SetCooperativeLevel failed: 0x%0lx\n",rc);
653
654 EXIT:
655     ref=IDirectSound_Release(dso);
656     ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
657     if (ref!=0)
658         return DSERR_GENERIC;
659
660     return rc;
661 }
662
663 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
664                                    LPCSTR lpcstrModule, LPVOID lpContext)
665 {
666     trace("*** Testing %s - %s\n",lpcstrDescription,lpcstrModule);
667     test_dsound(lpGuid);
668     test_dsound8(lpGuid);
669     test_primary(lpGuid);
670     test_secondary(lpGuid);
671
672     return 1;
673 }
674
675 static void dsound_tests()
676 {
677     HRESULT rc;
678     rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
679     ok(rc==DS_OK,"DirectSoundEnumerate failed: %ld\n",rc);
680 }
681
682 START_TEST(dsound)
683 {
684     CoInitialize(NULL);
685
686     dsound_dsound_tests();
687     dsound_dsound8_tests();
688     dsound_tests();
689 }