Move initialization to IDirectSound_Initialize.
[wine] / dlls / dsound / tests / capture.c
1 /*
2  * Unit tests for capture functions
3  *
4  * Copyright (c) 2002 Francois Gouget
5  * Copyright (c) 2003 Robert Reif
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define NONAMELESSSTRUCT
23 #define NONAMELESSUNION
24 #include <windows.h>
25
26 #include <stdio.h>
27
28 #include "wine/test.h"
29 #include "dsound.h"
30 #include "mmreg.h"
31 #include "dxerr8.h"
32
33 #include "dsound_test.h"
34
35 #define NOTIFICATIONS    5
36
37 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
38 static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
39
40 static const char * get_format_str(WORD format)
41 {
42     static char msg[32];
43 #define WAVE_FORMAT(f) case f: return #f
44     switch (format) {
45     WAVE_FORMAT(WAVE_FORMAT_PCM);
46     WAVE_FORMAT(WAVE_FORMAT_ADPCM);
47     WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
48     WAVE_FORMAT(WAVE_FORMAT_ALAW);
49     WAVE_FORMAT(WAVE_FORMAT_MULAW);
50     WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
51     WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
52     WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
53     WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
54     WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
55     WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
56     WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
57     WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
58     WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
59     WAVE_FORMAT(WAVE_FORMAT_SONARC);
60     WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
61     WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
62     WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
63     WAVE_FORMAT(WAVE_FORMAT_APTX);
64     WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
65     WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
66     WAVE_FORMAT(WAVE_FORMAT_GSM610);
67     WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
68     WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
69     WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
70     WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
71     WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
72     WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
73     WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
74     WAVE_FORMAT(WAVE_FORMAT_MPEG);
75     WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
76     WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
77     WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
78     WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
79     WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
80     WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
81     WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
82     WAVE_FORMAT(WAVE_FORMAT_OLICELP);
83     WAVE_FORMAT(WAVE_FORMAT_OLISBC);
84     WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
85     WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
86     WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
87     }
88 #undef WAVE_FORMAT
89     sprintf(msg, "Unknown(0x%04x)", format);
90     return msg;
91 }
92
93 static char * format_string(WAVEFORMATEX* wfx)
94 {
95     static char str[64];
96
97     sprintf(str, "%5ldx%2dx%d %s",
98         wfx->nSamplesPerSec, wfx->wBitsPerSample, wfx->nChannels,
99         get_format_str(wfx->wFormatTag));
100
101     return str;
102 }
103
104 typedef struct {
105     char* wave;
106     DWORD wave_len;
107
108     LPDIRECTSOUNDCAPTUREBUFFER dscbo;
109     LPWAVEFORMATEX wfx;
110     DSBPOSITIONNOTIFY posnotify[NOTIFICATIONS];
111     HANDLE event[NOTIFICATIONS];
112     LPDIRECTSOUNDNOTIFY notify;
113
114     DWORD buffer_size;
115     DWORD read;
116     DWORD offset;
117     DWORD size;
118
119     DWORD last_pos;
120 } capture_state_t;
121
122 static int capture_buffer_service(capture_state_t* state)
123 {
124     HRESULT rc;
125     LPVOID ptr1,ptr2;
126     DWORD len1,len2;
127     DWORD capture_pos,read_pos;
128
129     rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos,
130                                                     &read_pos);
131     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %s\n",
132        DXGetErrorString8(rc));
133     if (rc!=DS_OK)
134         return 0;
135
136     rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size,
137                                       &ptr1,&len1,&ptr2,&len2,0);
138     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %s\n",
139        DXGetErrorString8(rc));
140     if (rc!=DS_OK)
141         return 0;
142
143     rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2);
144     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %s\n",
145        DXGetErrorString8(rc));
146     if (rc!=DS_OK)
147         return 0;
148
149     state->offset = (state->offset + state->size) % state->buffer_size;
150
151     return 1;
152 }
153
154 static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
155                                 LPDIRECTSOUNDCAPTUREBUFFER dscbo, int record)
156 {
157     HRESULT rc;
158     DSCBCAPS dscbcaps;
159     WAVEFORMATEX wfx;
160     DWORD size,status;
161     capture_state_t state;
162     int i, ref;
163
164     /* Private dsound.dll: Error: Invalid caps pointer */
165     rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,0);
166     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
167        "have returned DSERR_INVALIDPARAM, returned: %s\n",
168        DXGetErrorString8(rc));
169
170     /* Private dsound.dll: Error: Invalid caps pointer */
171     dscbcaps.dwSize=0;
172     rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
173     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetCaps() should "
174        "have returned DSERR_INVALIDPARAM, returned: %s\n",
175        DXGetErrorString8(rc));
176
177     dscbcaps.dwSize=sizeof(dscbcaps);
178     rc=IDirectSoundCaptureBuffer_GetCaps(dscbo,&dscbcaps);
179     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCaps() failed: %s\n",
180        DXGetErrorString8(rc));
181     if (rc==DS_OK && winetest_debug > 1) {
182         trace("    Caps: size = %ld flags=0x%08lx buffer size=%ld\n",
183             dscbcaps.dwSize,dscbcaps.dwFlags,dscbcaps.dwBufferBytes);
184     }
185
186     /* Query the format size. Note that it may not match sizeof(wfx) */
187     /* Private dsound.dll: Error: Either pwfxFormat or pdwSizeWritten must
188      * be non-NULL */
189     rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,NULL);
190     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetFormat() should "
191        "have returned DSERR_INVALIDPARAM, returned: %s\n",
192        DXGetErrorString8(rc));
193
194     size=0;
195     rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,NULL,0,&size);
196     ok(rc==DS_OK && size!=0,"IDirectSoundCaptureBuffer_GetFormat() should "
197        "have returned the needed size: rc=%s, size=%ld\n",
198        DXGetErrorString8(rc),size);
199
200     rc=IDirectSoundCaptureBuffer_GetFormat(dscbo,&wfx,sizeof(wfx),NULL);
201     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetFormat() failed: %s\n",
202        DXGetErrorString8(rc));
203     if (rc==DS_OK && winetest_debug > 1) {
204         trace("    Format: tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
205               wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
206               wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
207     }
208
209     /* Private dsound.dll: Error: Invalid status pointer */
210     rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,0);
211     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCaptureBuffer_GetStatus() should "
212        "have returned DSERR_INVALIDPARAM, returned: %s\n",
213        DXGetErrorString8(rc));
214
215     rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
216     ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
217        DXGetErrorString8(rc));
218     if (rc==DS_OK && winetest_debug > 1) {
219         trace("    Status=0x%04lx\n",status);
220     }
221
222     ZeroMemory(&state, sizeof(state));
223     state.dscbo=dscbo;
224     state.wfx=&wfx;
225     state.buffer_size = dscbcaps.dwBufferBytes;
226     for (i = 0; i < NOTIFICATIONS; i++)
227         state.event[i] = CreateEvent( NULL, FALSE, FALSE, NULL );
228     state.size = dscbcaps.dwBufferBytes / NOTIFICATIONS;
229
230     rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
231                                                 (void **)&(state.notify));
232     ok((rc==DS_OK)&&(state.notify!=NULL),
233        "IDirectSoundCaptureBuffer_QueryInterface() failed: %s\n",
234        DXGetErrorString8(rc));
235     if (rc!=DS_OK)
236         return;
237
238     for (i = 0; i < NOTIFICATIONS; i++) {
239         state.posnotify[i].dwOffset = (i * state.size) + state.size - 1;
240         state.posnotify[i].hEventNotify = state.event[i];
241     }
242
243     rc=IDirectSoundNotify_SetNotificationPositions(state.notify,NOTIFICATIONS,
244                                                    state.posnotify);
245     ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions() failed: %s\n",
246        DXGetErrorString8(rc));
247     if (rc!=DS_OK)
248         return;
249
250     ref=IDirectSoundNotify_Release(state.notify);
251     ok(ref==0,"IDirectSoundNotify_Release(): has %d references, should have "
252        "0\n",ref);
253     if (ref!=0)
254         return;
255
256     if (record) {
257         rc=IDirectSoundCaptureBuffer_Start(dscbo,DSCBSTART_LOOPING);
258         ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Start() failed: %s\n",
259            DXGetErrorString8(rc));
260         if (rc!=DS_OK)
261             return;
262
263         rc=IDirectSoundCaptureBuffer_GetStatus(dscbo,&status);
264         ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetStatus() failed: %s\n",
265            DXGetErrorString8(rc));
266         ok(status==(DSCBSTATUS_CAPTURING|DSCBSTATUS_LOOPING),
267            "GetStatus: bad status: %lx\n",status);
268         if (rc!=DS_OK)
269             return;
270
271         /* wait for the notifications */
272         for (i = 0; i < (NOTIFICATIONS * 2); i++) {
273             rc=WaitForMultipleObjects(NOTIFICATIONS,state.event,FALSE,3000);
274             ok(rc==(WAIT_OBJECT_0+(i%NOTIFICATIONS)),
275                "WaitForMultipleObjects failed: 0x%lx\n",rc);
276             if (rc!=(WAIT_OBJECT_0+(i%NOTIFICATIONS))) {
277                 ok((rc==WAIT_TIMEOUT)||(rc==WAIT_FAILED),
278                    "Wrong notification: should be %d, got %ld\n",
279                     i%NOTIFICATIONS,rc-WAIT_OBJECT_0);
280             }
281             if (!capture_buffer_service(&state))
282                 break;
283         }
284
285         rc=IDirectSoundCaptureBuffer_Stop(dscbo);
286         ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Stop() failed: %s\n",
287            DXGetErrorString8(rc));
288         if (rc!=DS_OK)
289             return;
290     }
291 }
292
293 static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
294                                     LPCSTR lpcstrModule, LPVOID lpContext)
295 {
296     HRESULT rc;
297     LPDIRECTSOUNDCAPTURE dsco=NULL;
298     LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
299     DSCBUFFERDESC bufdesc;
300     WAVEFORMATEX wfx;
301     DSCCAPS dsccaps;
302     DWORD f;
303     int ref;
304
305     /* Private dsound.dll: Error: Invalid interface buffer */
306     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
307     rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
308     ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
309        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
310     if (rc==DS_OK) {
311         ref=IDirectSoundCapture_Release(dsco);
312         ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
313            "have 0\n",ref);
314     }
315
316     rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
317     ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
318        "DirectSoundCaptureCreate() failed: %s\n",DXGetErrorString8(rc));
319     if (rc!=DS_OK) {
320         if (rc==DSERR_NODRIVER)
321             trace("  No Driver\n");
322         else if (rc==E_FAIL)
323             trace("  No Device\n");
324         else if (rc==DSERR_ALLOCATED)
325             trace("  Already In Use\n");
326         goto EXIT;
327     }
328
329     /* Private dsound.dll: Error: Invalid caps buffer */
330     rc=IDirectSoundCapture_GetCaps(dsco,NULL);
331     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
332        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
333
334     /* Private dsound.dll: Error: Invalid caps buffer */
335     dsccaps.dwSize=0;
336     rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
337     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
338        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
339
340     dsccaps.dwSize=sizeof(dsccaps);
341     rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
342     ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %s\n",
343        DXGetErrorString8(rc));
344     if (rc==DS_OK && winetest_debug > 1) {
345         trace("  Caps: size=%ld flags=0x%08lx formats=%05lx channels=%ld\n",
346               dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
347               dsccaps.dwChannels);
348     }
349
350     /* Private dsound.dll: Error: Invalid size */
351     /* Private dsound.dll: Error: Invalid capture buffer description */
352     ZeroMemory(&bufdesc, sizeof(bufdesc));
353     bufdesc.dwSize=0;
354     bufdesc.dwFlags=0;
355     bufdesc.dwBufferBytes=0;
356     bufdesc.dwReserved=0;
357     bufdesc.lpwfxFormat=NULL;
358     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
359     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
360        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
361        DXGetErrorString8(rc));
362     if (rc==DS_OK) {
363         ref=IDirectSoundCaptureBuffer_Release(dscbo);
364         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
365            "should have 0\n",ref);
366     }
367
368     /* Private dsound.dll: Error: Invalid buffer size */
369     /* Private dsound.dll: Error: Invalid capture buffer description */
370     ZeroMemory(&bufdesc, sizeof(bufdesc));
371     bufdesc.dwSize=sizeof(bufdesc);
372     bufdesc.dwFlags=0;
373     bufdesc.dwBufferBytes=0;
374     bufdesc.dwReserved=0;
375     bufdesc.lpwfxFormat=NULL;
376     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
377     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
378        "should have returned DSERR_INVALIDPARAM, returned %s\n",
379        DXGetErrorString8(rc));
380     if (rc==DS_OK) {
381         ref=IDirectSoundCaptureBuffer_Release(dscbo);
382         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
383            "should have 0\n",ref);
384     }
385
386     /* Private dsound.dll: Error: Invalid buffer size */
387     /* Private dsound.dll: Error: Invalid capture buffer description */
388     ZeroMemory(&bufdesc, sizeof(bufdesc));
389     ZeroMemory(&wfx, sizeof(wfx));
390     bufdesc.dwSize=sizeof(bufdesc);
391     bufdesc.dwFlags=0;
392     bufdesc.dwBufferBytes=0;
393     bufdesc.dwReserved=0;
394     bufdesc.lpwfxFormat=&wfx;
395     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
396     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
397        "should have returned DSERR_INVALIDPARAM, returned :%s\n",
398        DXGetErrorString8(rc));
399     if (rc==DS_OK) {
400         ref=IDirectSoundCaptureBuffer_Release(dscbo);
401         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
402            "should have 0\n",ref);
403     }
404
405     /* Private dsound.dll: Error: Invalid buffer size */
406     /* Private dsound.dll: Error: Invalid capture buffer description */
407     init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
408     ZeroMemory(&bufdesc, sizeof(bufdesc));
409     bufdesc.dwSize=sizeof(bufdesc);
410     bufdesc.dwFlags=0;
411     bufdesc.dwBufferBytes=0;
412     bufdesc.dwReserved=0;
413     bufdesc.lpwfxFormat=&wfx;
414     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
415     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
416        "should have returned DSERR_INVALIDPARAM, returned: %s\n",
417        DXGetErrorString8(rc));
418     if (rc==DS_OK) {
419         ref=IDirectSoundCaptureBuffer_Release(dscbo);
420         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
421            "should have 0\n",ref);
422     }
423
424     for (f=0;f<NB_FORMATS;f++) {
425         dscbo=NULL;
426         init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
427                     formats[f][2]);
428         ZeroMemory(&bufdesc, sizeof(bufdesc));
429         bufdesc.dwSize=sizeof(bufdesc);
430         bufdesc.dwFlags=0;
431         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
432         bufdesc.dwReserved=0;
433         bufdesc.lpwfxFormat=&wfx;
434         if (winetest_interactive)
435             trace("  Testing the capture buffer at %s\n", format_string(&wfx));
436         rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
437         ok(((rc==DS_OK)&&(dscbo!=NULL))||(rc==DSERR_BADFORMAT)||
438            (rc==DSERR_ALLOCATED)||(rc==E_INVALIDARG),
439            "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
440            "%s capture buffer: %s\n",format_string(&wfx),DXGetErrorString8(rc));
441         if (rc==DS_OK) {
442             test_capture_buffer(dsco, dscbo, winetest_interactive);
443             ref=IDirectSoundCaptureBuffer_Release(dscbo);
444             ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
445                "should have 0\n",ref);
446         } else if (rc==DSERR_BADFORMAT) {
447             ok(!(dsccaps.dwFormats & formats[f][3]),
448                "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
449                "capture buffer: format listed as supported but using it failed\n");
450             if (!(dsccaps.dwFormats & formats[f][3]))
451                 trace("  Format not supported: %s\n", format_string(&wfx));
452         } else if (rc==DSERR_ALLOCATED) {
453             trace("  Already In Use\n");
454         } else if (rc==E_INVALIDARG) { /* try the old version struct */
455             DSCBUFFERDESC1 bufdesc1;
456             ZeroMemory(&bufdesc1, sizeof(bufdesc1));
457             bufdesc1.dwSize=sizeof(bufdesc1);
458             bufdesc1.dwFlags=0;
459             bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
460             bufdesc1.dwReserved=0;
461             bufdesc1.lpwfxFormat=&wfx;
462             rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
463                 (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
464             ok(rc==DS_OK,
465                "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
466                "%s capture buffer: %s\n",format_string(&wfx),
467                DXGetErrorString8(rc));
468             if (rc==DS_OK) {
469                 test_capture_buffer(dsco, dscbo, winetest_interactive);
470                 ref=IDirectSoundCaptureBuffer_Release(dscbo);
471                 ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
472                    "references, should have 0\n",ref);
473             }
474         }
475     }
476
477     /* try a non PCM format */
478 #if 0
479     init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
480     ZeroMemory(&bufdesc, sizeof(bufdesc));
481     bufdesc.dwSize=sizeof(bufdesc);
482     bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
483     bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
484     bufdesc.dwReserved=0;
485     bufdesc.lpwfxFormat=&wfx;
486     if (winetest_interactive)
487         trace("  Testing the capture buffer at %s\n", format_string(&wfx));
488     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
489     ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
490        "failed to create a capture buffer: %s\n",DXGetErrorString8(rc));
491     if ((rc==DS_OK)&&(dscbo!=NULL)) {
492         test_capture_buffer(dsco, dscbo, winetest_interactive);
493         ref=IDirectSoundCaptureBuffer_Release(dscbo);
494         ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
495            "should have 0\n",ref);
496     }
497 #endif
498
499     /* Try an invalid format to test error handling */
500 #if 0
501     init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
502     ZeroMemory(&bufdesc, sizeof(bufdesc));
503     bufdesc.dwSize=sizeof(bufdesc);
504     bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
505     bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
506     bufdesc.dwReserved=0;
507     bufdesc.lpwfxFormat=&wfx;
508     if (winetest_interactive)
509         trace("  Testing the capture buffer at %s\n", format_string(&wfx));
510     rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
511     ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
512        "at 2 MHz %s\n",DXGetErrorString8(rc));
513 #endif
514
515 EXIT:
516     if (dsco!=NULL) {
517         ref=IDirectSoundCapture_Release(dsco);
518         ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
519            "have 0\n",ref);
520     }
521
522     return TRUE;
523 }
524
525 static void capture_tests()
526 {
527     HRESULT rc;
528     rc=pDirectSoundCaptureEnumerateA(&dscenum_callback,NULL);
529     ok(rc==DS_OK,"DirectSoundCaptureEnumerateA() failed: %s\n",
530        DXGetErrorString8(rc));
531 }
532
533 START_TEST(capture)
534 {
535     HMODULE hDsound;
536
537     CoInitialize(NULL);
538
539     hDsound = LoadLibraryA("dsound.dll");
540     if (!hDsound) {
541         trace("dsound.dll not found\n");
542         return;
543     }
544
545     trace("DLL Version: %s\n", get_file_version("dsound.dll"));
546
547     pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,"DirectSoundCaptureCreate");
548     pDirectSoundCaptureEnumerateA=(void*)GetProcAddress(hDsound,"DirectSoundCaptureEnumerateA");
549     if (!pDirectSoundCaptureCreate || !pDirectSoundCaptureEnumerateA)
550     {
551         trace("capture test skipped\n");
552         return;
553     }
554
555     capture_tests();
556
557     CoUninitialize();
558 }