Fixed a compile error on non-i386.
[wine] / dlls / winmm / tests / wave.c
1 /*
2  * Unit tests for winmm functions
3  *
4  * Copyright (c) 2002 Francois Gouget
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
25
26 #include "wine/test.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "mmsystem.h"
31 #include "mmddk.h"
32
33 /*
34  * Note that in most of this test we may get MMSYSERR_BADDEVICEID errors
35  * at about any time if the user starts another application that uses the
36  * sound device. So we should not report these as test failures.
37  *
38  * This test can play a test tone. But this only makes sense if someone
39  * is going to carefully listen to it, and would only bother everyone else.
40  * So this is only done if the test is being run in interactive mode.
41  */
42
43 #ifndef WAVE_FORMAT_48M08
44 #define WAVE_FORMAT_48M08      0x00001000    /* 48     kHz, Mono,   8-bit  */
45 #define WAVE_FORMAT_48S08      0x00002000    /* 48     kHz, Stereo, 8-bit  */
46 #define WAVE_FORMAT_48M16      0x00004000    /* 48     kHz, Mono,   16-bit */
47 #define WAVE_FORMAT_48S16      0x00008000    /* 48     kHz, Stereo, 16-bit */
48 #define WAVE_FORMAT_96M08      0x00010000    /* 96     kHz, Mono,   8-bit  */
49 #define WAVE_FORMAT_96S08      0x00020000    /* 96     kHz, Stereo, 8-bit  */
50 #define WAVE_FORMAT_96M16      0x00040000    /* 96     kHz, Mono,   16-bit */
51 #define WAVE_FORMAT_96S16      0x00080000    /* 96     kHz, Stereo, 16-bit */
52 #endif
53
54 static const unsigned int win_formats[][4]={
55     {WAVE_FORMAT_1M08,  11025,  8, 1},
56     {WAVE_FORMAT_1S08,  11025,  8, 2},
57     {WAVE_FORMAT_1M16,  11025, 16, 1},
58     {WAVE_FORMAT_1S16,  11025, 16, 2},
59     {WAVE_FORMAT_2M08,  22050,  8, 1},
60     {WAVE_FORMAT_2S08,  22050,  8, 2},
61     {WAVE_FORMAT_2M16,  22050, 16, 1},
62     {WAVE_FORMAT_2S16,  22050, 16, 2},
63     {WAVE_FORMAT_4M08,  44100,  8, 1},
64     {WAVE_FORMAT_4S08,  44100,  8, 2},
65     {WAVE_FORMAT_4M16,  44100, 16, 1},
66     {WAVE_FORMAT_4S16,  44100, 16, 2},
67     {WAVE_FORMAT_48M08, 48000,  8, 1},
68     {WAVE_FORMAT_48S08, 48000,  8, 2},
69     {WAVE_FORMAT_48M16, 48000, 16, 1},
70     {WAVE_FORMAT_48S16, 48000, 16, 2},
71     {WAVE_FORMAT_96M08, 96000,  8, 1},
72     {WAVE_FORMAT_96S08, 96000,  8, 2},
73     {WAVE_FORMAT_96M16, 96000, 16, 1},
74     {WAVE_FORMAT_96S16, 96000, 16, 2}
75 };
76 #define NB_WIN_FORMATS (sizeof(win_formats)/sizeof(*win_formats))
77
78 #define PI 3.14159265358979323846
79 static char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
80 {
81     int i;
82     int nb_samples;
83     char* buf;
84     char* b;
85
86     nb_samples=(int)(duration*wfx->nSamplesPerSec);
87     *size=nb_samples*wfx->nBlockAlign;
88     b=buf=malloc(*size);
89     for (i=0;i<nb_samples;i++) {
90         double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
91         if (wfx->wBitsPerSample==8) {
92             unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
93             *b++=sample;
94             if (wfx->nChannels==2)
95                *b++=sample;
96         } else {
97             signed short sample=(signed short)((double)32767.5*y-0.5);
98             b[0]=sample & 0xff;
99             b[1]=sample >> 8;
100             b+=2;
101             if (wfx->nChannels==2) {
102                 b[0]=sample & 0xff;
103                 b[1]=sample >> 8;
104                 b+=2;
105             }
106         }
107     }
108     return buf;
109 }
110
111 static const char * wave_out_error(MMRESULT error)
112 {
113     static char msg[1024];
114     MMRESULT rc;
115
116     rc = waveOutGetErrorText(error, msg, sizeof(msg));
117     if (rc != MMSYSERR_NOERROR)
118         sprintf(msg, "waveOutGetErrorText(%x) failed with error %x", error, rc);
119     return msg;
120 }
121
122 static const char * wave_open_flags(DWORD flags)
123 {
124     static char msg[1024];
125     int first = TRUE;
126     msg[0] = 0;
127     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) {
128         strcat(msg, "CALLBACK_EVENT");
129         first = FALSE;
130     }
131     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) {
132         if (!first) strcat(msg, "|");
133         strcat(msg, "CALLBACK_FUNCTION");
134         first = FALSE;
135     }
136     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_NULL) {
137         if (!first) strcat(msg, "|");
138         strcat(msg, "CALLBACK_NULL");
139         first = FALSE;
140     }
141     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) {
142         if (!first) strcat(msg, "|");
143         strcat(msg, "CALLBACK_THREAD");
144         first = FALSE;
145     }
146     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) {
147         if (!first) strcat(msg, "|");
148         strcat(msg, "CALLBACK_WINDOW");
149         first = FALSE;
150     }
151     if ((flags & WAVE_ALLOWSYNC) == WAVE_ALLOWSYNC) {
152         if (!first) strcat(msg, "|");
153         strcat(msg, "WAVE_ALLOWSYNC");
154         first = FALSE;
155     }
156     if ((flags & WAVE_FORMAT_DIRECT) == WAVE_FORMAT_DIRECT) {
157         if (!first) strcat(msg, "|");
158         strcat(msg, "WAVE_FORMAT_DIRECT");
159         first = FALSE;
160     }
161     if ((flags & WAVE_FORMAT_QUERY) == WAVE_FORMAT_QUERY) {
162         if (!first) strcat(msg, "|");
163         strcat(msg, "WAVE_FORMAT_QUERY");
164         first = FALSE;
165     }
166     if ((flags & WAVE_MAPPED) == WAVE_MAPPED) {
167         if (!first) strcat(msg, "|");
168         strcat(msg, "WAVE_MAPPED");
169         first = FALSE;
170     }
171     return msg;
172 }
173
174 static void wave_out_test_deviceOut(int device, int format, DWORD flags, LPWAVEOUTCAPS pcaps)
175 {
176     WAVEFORMATEX wfx;
177     HWAVEOUT wout;
178     HANDLE hevent;
179     WAVEHDR frag;
180     MMRESULT rc;
181     DWORD volume;
182
183     hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
184     ok(hevent!=NULL,"CreateEvent: error=%ld\n",GetLastError());
185     if (hevent==NULL)
186         return;
187
188     wfx.wFormatTag=WAVE_FORMAT_PCM;
189     wfx.nChannels=win_formats[format][3];
190     wfx.wBitsPerSample=win_formats[format][2];
191     wfx.nSamplesPerSec=win_formats[format][1];
192     wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
193     wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
194     wfx.cbSize=0;
195
196     wout=NULL;
197     rc=waveOutOpen(&wout,device,&wfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
198     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
199     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
200        (rc==WAVERR_BADFORMAT && (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & win_formats[format][0])) ||
201        (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
202        "waveOutOpen: device=%d format=%ldx%2dx%d flags=%lx(%s) rc=%d(%s)\n",device,
203        wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,CALLBACK_EVENT|flags,
204        wave_open_flags(CALLBACK_EVENT|flags),rc,wave_out_error(rc));
205     if (rc!=MMSYSERR_NOERROR) {
206         CloseHandle(hevent);
207         return;
208     }
209
210     ok(wfx.nChannels==win_formats[format][3] &&
211        wfx.wBitsPerSample==win_formats[format][2] &&
212        wfx.nSamplesPerSec==win_formats[format][1],
213        "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
214        wfx.nSamplesPerSec, wfx.wBitsPerSample,
215        wfx.nChannels, win_formats[format][1], win_formats[format][2],
216        win_formats[format][3]);
217
218     frag.lpData=wave_generate_la(&wfx,1.0,&frag.dwBufferLength);
219     frag.dwFlags=0;
220     frag.dwLoops=0;
221
222     rc=waveOutGetVolume(wout,&volume);
223     ok(rc==MMSYSERR_NOERROR,"waveOutGetVolume: device=%d rc=%d\n",device,rc);
224
225     rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
226     ok(rc==MMSYSERR_NOERROR,
227        "waveOutPrepareHeader: device=%d rc=%d\n",device,rc);
228
229     if (winetest_interactive && rc==MMSYSERR_NOERROR) {
230         trace("Playing 440Hz LA at %ldx%2dx%d %04lx\n",
231               wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels,flags);
232         rc=waveOutSetVolume(wout,0x20002000);
233         ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume: device=%d rc=%d\n",device,rc);
234         WaitForSingleObject(hevent,INFINITE);
235
236         rc=waveOutWrite(wout, &frag, sizeof(frag));
237         ok(rc==MMSYSERR_NOERROR,"waveOutWrite: device=%d rc=%d\n",device,rc);
238         WaitForSingleObject(hevent,INFINITE);
239
240         rc=waveOutSetVolume(wout,volume);
241         ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume: device=%d rc=%d\n",device,rc);
242     }
243
244     rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
245     ok(rc==MMSYSERR_NOERROR,
246        "waveOutUnprepareHeader: device=%d rc=%d\n",device,rc);
247     free(frag.lpData);
248
249     CloseHandle(hevent);
250     waveOutClose(wout);
251 }
252
253 static void wave_out_tests()
254 {
255     WAVEOUTCAPS caps;
256     WAVEFORMATEX format, oformat;
257     HWAVEOUT wout;
258     MMRESULT rc;
259     UINT ndev,d,f;
260     WCHAR * wname;
261     CHAR * name=NULL;
262     DWORD size;                                                                                 
263
264     ndev=waveOutGetNumDevs();
265     trace("found %d WaveOut devices\n",ndev);
266
267     rc=waveOutGetDevCapsA(ndev+1,&caps,sizeof(caps));
268     ok(rc==MMSYSERR_BADDEVICEID,
269        "waveOutGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %d\n",rc);
270
271     format.wFormatTag=WAVE_FORMAT_PCM;
272     format.nChannels=2;
273     format.wBitsPerSample=16;
274     format.nSamplesPerSec=44100;
275     format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
276     format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
277     format.cbSize=0;
278     rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
279     ok(rc==MMSYSERR_BADDEVICEID,
280        "waveOutOpen: MMSYSERR_BADDEVICEID expected, got %d\n",rc);
281
282     for (d=0;d<ndev;d++) {
283         rc=waveOutGetDevCapsA(d,&caps,sizeof(caps));
284         ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID,
285            "waveOutGetDevCapsA: failed to get capabilities of device %d: rc=%d\n",d,rc);
286         if (rc==MMSYSERR_BADDEVICEID)
287             continue;
288
289         rc=waveOutMessage((HWAVEOUT)d, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0);
290         ok(rc==MMSYSERR_NOERROR, "waveOutMessage: failed to get interface size for device: %d rc=%d\n",d,rc);
291         if (rc==MMSYSERR_NOERROR) {
292             wname = (WCHAR *)malloc(size);
293             rc=waveOutMessage((HWAVEOUT)d, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wname, size);
294             ok(rc==MMSYSERR_NOERROR,"waveOutMessage: failed to get interface name for device:: %d rc=%d\n",d,rc);
295             if (rc==MMSYSERR_NOERROR) {
296                 name = malloc(size/sizeof(WCHAR));
297                 WideCharToMultiByte(CP_ACP, 0, wname, size/sizeof(WCHAR), name, size/sizeof(WCHAR), NULL, NULL);
298             }
299         }
300
301         trace("  %d: \"%s\" (%s) %d.%d (%d:%d): channels=%d formats=%05lx support=%04lx\n",
302               d,caps.szPname,name,caps.vDriverVersion >> 8,
303               caps.vDriverVersion & 0xff,
304               caps.wMid,caps.wPid,
305               caps.wChannels,caps.dwFormats,caps.dwSupport);
306
307         for (f=0;f<NB_WIN_FORMATS;f++) {
308             if (caps.dwFormats & win_formats[f][0]) {
309                 wave_out_test_deviceOut(d,f,0,&caps);
310                 wave_out_test_deviceOut(d,f,WAVE_FORMAT_DIRECT,&caps);
311             }
312         }
313
314         /* Try an invalid format to test error handling */
315         trace("Testing invalid 2MHz format\n");
316         format.wFormatTag=WAVE_FORMAT_PCM;
317         format.nChannels=2;
318         format.wBitsPerSample=16;
319         format.nSamplesPerSec=2000000; /* 2MHz! */
320         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
321         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
322         format.cbSize=0;
323         oformat=format;
324         rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
325         ok(rc==WAVERR_BADFORMAT,
326            "waveOutOpen: opening the device at 2MHz should fail %d: rc=%d\n",d,rc);
327         if (rc==MMSYSERR_NOERROR) {
328             trace("     got %ldx%2dx%d for %ldx%2dx%d\n",
329                   format.nSamplesPerSec, format.wBitsPerSample,
330                   format.nChannels,
331                   oformat.nSamplesPerSec, oformat.wBitsPerSample,
332                   oformat.nChannels);
333             waveOutClose(wout);
334         }
335
336         format.wFormatTag=WAVE_FORMAT_PCM;
337         format.nChannels=2;
338         format.wBitsPerSample=16;
339         format.nSamplesPerSec=2000000; /* 2MHz! */
340         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
341         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
342         format.cbSize=0;
343         rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
344         ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG,
345            "waveOutOpen: opening the device at 2MHz should fail %d: rc=%d\n",d,rc);
346         if (rc==MMSYSERR_NOERROR) {
347             trace("     got %ldx%2dx%d for %dx%2dx%d\n",
348                   format.nSamplesPerSec, format.wBitsPerSample,
349                   format.nChannels,
350                   win_formats[f][1], win_formats[f][2],
351                   win_formats[f][3]);
352             waveOutClose(wout);
353         }
354     }
355 }
356
357 static const char * wave_in_error(MMRESULT error)
358 {
359     static char msg[1024];
360     MMRESULT rc;
361
362     rc = waveInGetErrorText(error, msg, sizeof(msg));
363     if (rc != MMSYSERR_NOERROR)
364         sprintf(msg, "waveInGetErrorText(%x) failed with error %x", error, rc);
365     return msg;
366 }
367
368 static void wave_in_test_deviceIn(int device, int format, DWORD flags, LPWAVEINCAPS pcaps)
369 {
370     WAVEFORMATEX wfx;
371     HWAVEIN win;
372     HANDLE hevent;
373     WAVEHDR frag;
374     MMRESULT rc;
375     DWORD res;
376
377     hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
378     ok(hevent!=NULL,"CreateEvent: error=%ld\n",GetLastError());
379     if (hevent==NULL)
380         return;
381
382     wfx.wFormatTag=WAVE_FORMAT_PCM;
383     wfx.nChannels=win_formats[format][3];
384     wfx.wBitsPerSample=win_formats[format][2];
385     wfx.nSamplesPerSec=win_formats[format][1];
386     wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
387     wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
388     wfx.cbSize=0;
389
390     win=NULL;
391     rc=waveInOpen(&win,device,&wfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
392     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
393     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
394        (rc==WAVERR_BADFORMAT && (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & win_formats[format][0])) ||
395        (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
396        "waveInOpen: device=%d format=%ldx%2dx%d flags=%lx(%s) rc=%d(%s)\n",device,
397        wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,CALLBACK_EVENT|flags,
398        wave_open_flags(CALLBACK_EVENT|flags),rc,wave_in_error(rc));
399     if (rc!=MMSYSERR_NOERROR) {
400         CloseHandle(hevent);
401         return;
402     }
403     res=WaitForSingleObject(hevent,1000);
404     ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for open\n");
405
406     ok(wfx.nChannels==win_formats[format][3] &&
407        wfx.wBitsPerSample==win_formats[format][2] &&
408        wfx.nSamplesPerSec==win_formats[format][1],
409        "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
410        wfx.nSamplesPerSec, wfx.wBitsPerSample,
411        wfx.nChannels, win_formats[format][1], win_formats[format][2],
412        win_formats[format][3]);
413
414     frag.lpData=malloc(wfx.nAvgBytesPerSec);
415     frag.dwBufferLength=wfx.nAvgBytesPerSec;
416     frag.dwBytesRecorded=0;
417     frag.dwUser=0;
418     frag.dwFlags=0;
419     frag.dwLoops=0;
420     frag.lpNext=0;
421
422     rc=waveInPrepareHeader(win, &frag, sizeof(frag));
423     ok(rc==MMSYSERR_NOERROR, "waveInPrepareHeader: device=%d rc=%d(%s)\n",device,rc,wave_in_error(rc));
424     ok(frag.dwFlags&WHDR_PREPARED,"waveInPrepareHeader: prepared flag not set\n");
425
426     if (winetest_interactive && rc==MMSYSERR_NOERROR) {
427         trace("Recording at %ldx%2dx%d %04lx\n",
428               wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels,flags);
429
430         rc=waveInAddBuffer(win, &frag, sizeof(frag));
431         ok(rc==MMSYSERR_NOERROR,"waveInAddBuffer: device=%d rc=%d(%s)\n",device,rc,wave_in_error(rc));
432
433         rc=waveInStart(win);
434         ok(rc==MMSYSERR_NOERROR,"waveInStart: device=%d rc=%d(%s)\n",device,rc,wave_in_error(rc));
435
436         res = WaitForSingleObject(hevent,1200);
437         ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for header\n");
438         ok(frag.dwFlags&WHDR_DONE,"WHDR_DONE not set in frag.dwFlags\n");
439         ok(frag.dwBytesRecorded==wfx.nAvgBytesPerSec,"frag.dwBytesRecorded=%ld, should=%ld\n",
440            frag.dwBytesRecorded,wfx.nAvgBytesPerSec);
441         /* stop playing on error */
442         if (res!=WAIT_OBJECT_0) {
443             rc=waveInStop(win);
444             ok(rc==MMSYSERR_NOERROR,
445                "waveInStop: device=%d rc=%d(%s)\n",device,rc,wave_in_error(rc));
446         }
447     }
448
449     rc=waveInUnprepareHeader(win, &frag, sizeof(frag));
450     ok(rc==MMSYSERR_NOERROR,
451        "waveInUnprepareHeader: device=%d rc=%d(%s)\n",device,rc,wave_in_error(rc));
452
453     waveInClose(win);
454     res=WaitForSingleObject(hevent,1000);
455     ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for close\n");
456     free(frag.lpData);
457     CloseHandle(hevent);
458 }
459
460 static void wave_in_tests()
461 {
462     WAVEINCAPS caps;
463     WAVEFORMATEX format,oformat;
464     HWAVEIN win;
465     MMRESULT rc;
466     UINT ndev,d,f;
467     WCHAR * wname;
468     CHAR * name=NULL;
469     DWORD size;                                                                                 
470
471     ndev=waveInGetNumDevs();
472     trace("found %d WaveIn devices\n",ndev);
473
474     rc=waveInGetDevCapsA(ndev+1,&caps,sizeof(caps));
475     ok(rc==MMSYSERR_BADDEVICEID,
476        "waveInGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %d(%s)\n",rc,wave_in_error(rc));
477
478     format.wFormatTag=WAVE_FORMAT_PCM;
479     format.nChannels=2;
480     format.wBitsPerSample=16;
481     format.nSamplesPerSec=44100;
482     format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
483     format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
484     format.cbSize=0;
485     rc=waveInOpen(&win,ndev+1,&format,0,0,CALLBACK_NULL);
486     ok(rc==MMSYSERR_BADDEVICEID,
487        "waveInOpen: MMSYSERR_BADDEVICEID expected, got %d(%s)\n",rc,wave_in_error(rc));
488
489     for (d=0;d<ndev;d++) {
490         rc=waveInGetDevCapsA(d,&caps,sizeof(caps));
491         ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID,
492            "waveInGetDevCapsA: failed to get capabilities of device %d: rc=%d(%s)\n",d,rc,wave_in_error(rc));
493         if (rc==MMSYSERR_BADDEVICEID)
494             continue;
495
496         rc=waveInMessage((HWAVEIN)d, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0);
497         ok(rc==MMSYSERR_NOERROR, "waveInMessage: failed to get interface size for device: %d rc=%d(%s)\n",d,rc,wave_in_error(rc));
498         if (rc==MMSYSERR_NOERROR) {
499             wname = (WCHAR *)malloc(size);
500             rc=waveInMessage((HWAVEIN)d, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wname, size);
501             ok(rc==MMSYSERR_NOERROR,"waveInMessage: failed to get interface name for device:: %d rc=%d(%s)\n",d,rc,wave_in_error(rc));
502             if (rc==MMSYSERR_NOERROR) {
503                 name = malloc(size/sizeof(WCHAR));
504                 WideCharToMultiByte(CP_ACP, 0, wname, size/sizeof(WCHAR), name, size/sizeof(WCHAR), NULL, NULL);
505             }
506         }
507
508         trace("  %d: \"%s\" (%s) %d.%d (%d:%d): channels=%d formats=%05lx\n",
509               d,caps.szPname,name,caps.vDriverVersion >> 8,
510               caps.vDriverVersion & 0xff,
511               caps.wMid,caps.wPid,
512               caps.wChannels,caps.dwFormats);
513
514         for (f=0;f<NB_WIN_FORMATS;f++) {
515             if (caps.dwFormats & win_formats[f][0]) {
516                 wave_in_test_deviceIn(d,f,0, &caps);
517                 wave_in_test_deviceIn(d,f,WAVE_FORMAT_DIRECT, &caps);
518             }
519         }
520
521         /* Try an invalid format to test error handling */
522         trace("Testing invalid 2MHz format\n");
523         format.wFormatTag=WAVE_FORMAT_PCM;
524         format.nChannels=2;
525         format.wBitsPerSample=16;
526         format.nSamplesPerSec=2000000; /* 2MHz! */
527         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
528         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
529         format.cbSize=0;
530         oformat=format;
531         rc=waveInOpen(&win,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
532         ok(rc==WAVERR_BADFORMAT,
533            "waveInOpen: opening the device at 2MHz should fail %d: rc=%d\n",d,rc);
534         if (rc==MMSYSERR_NOERROR) {
535             trace("     got %ldx%2dx%d for %ldx%2dx%d\n",
536                   format.nSamplesPerSec, format.wBitsPerSample,
537                   format.nChannels,
538                   oformat.nSamplesPerSec, oformat.wBitsPerSample,
539                   oformat.nChannels);
540             waveInClose(win);
541         }
542
543         format.wFormatTag=WAVE_FORMAT_PCM;
544         format.nChannels=2;
545         format.wBitsPerSample=16;
546         format.nSamplesPerSec=2000000; /* 2MHz! */
547         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
548         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
549         format.cbSize=0;
550         rc=waveInOpen(&win,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
551         ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG,
552            "waveInOpen: opening the device at 2MHz should fail %d: rc=%d\n",d,rc);
553         if (rc==MMSYSERR_NOERROR) {
554             trace("     got %ldx%2dx%d for %dx%2dx%d\n",
555                   format.nSamplesPerSec, format.wBitsPerSample,
556                   format.nChannels,
557                   win_formats[f][1], win_formats[f][2],
558                   win_formats[f][3]);
559             waveInClose(win);
560         }
561     }
562 }
563
564 START_TEST(wave)
565 {
566     wave_out_tests();
567     wave_in_tests();
568 }