Fix the case of product and company names.
[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 "mmsystem.h"
30
31 /*
32  * Note that in most of this test we may get MMSYSERR_BADDEVICEID errors
33  * at about any time if the user starts another application that uses the
34  * sound device. So we should not report these as test failures.
35  *
36  * This test can play a test tone. But this only makes sense if someone
37  * is going to carefully listen to it, and would only bother everyone else.
38  * So this is only done if the test is being run in interactive mode.
39  */
40
41 #ifndef WAVE_FORMAT_48M08
42 #define WAVE_FORMAT_48M08      0x00001000    /* 48     kHz, Mono,   8-bit  */
43 #define WAVE_FORMAT_48S08      0x00002000    /* 48     kHz, Stereo, 8-bit  */
44 #define WAVE_FORMAT_48M16      0x00004000    /* 48     kHz, Mono,   16-bit */
45 #define WAVE_FORMAT_48S16      0x00008000    /* 48     kHz, Stereo, 16-bit */
46 #define WAVE_FORMAT_96M08      0x00010000    /* 96     kHz, Mono,   8-bit  */
47 #define WAVE_FORMAT_96S08      0x00020000    /* 96     kHz, Stereo, 8-bit  */
48 #define WAVE_FORMAT_96M16      0x00040000    /* 96     kHz, Mono,   16-bit */
49 #define WAVE_FORMAT_96S16      0x00080000    /* 96     kHz, Stereo, 16-bit */
50 #endif
51
52 static const unsigned int win_formats[][4]={
53     {WAVE_FORMAT_1M08,  11025,  8, 1},
54     {WAVE_FORMAT_1S08,  11025,  8, 2},
55     {WAVE_FORMAT_1M16,  11025, 16, 1},
56     {WAVE_FORMAT_1S16,  11025, 16, 2},
57     {WAVE_FORMAT_2M08,  22050,  8, 1},
58     {WAVE_FORMAT_2S08,  22050,  8, 2},
59     {WAVE_FORMAT_2M16,  22050, 16, 1},
60     {WAVE_FORMAT_2S16,  22050, 16, 2},
61     {WAVE_FORMAT_4M08,  44100,  8, 1},
62     {WAVE_FORMAT_4S08,  44100,  8, 2},
63     {WAVE_FORMAT_4M16,  44100, 16, 1},
64     {WAVE_FORMAT_4S16,  44100, 16, 2},
65     {WAVE_FORMAT_48M08, 48000,  8, 1},
66     {WAVE_FORMAT_48S08, 48000,  8, 2},
67     {WAVE_FORMAT_48M16, 48000, 16, 1},
68     {WAVE_FORMAT_48S16, 48000, 16, 2},
69     {WAVE_FORMAT_96M08, 96000,  8, 1},
70     {WAVE_FORMAT_96S08, 96000,  8, 2},
71     {WAVE_FORMAT_96M16, 96000, 16, 1},
72     {WAVE_FORMAT_96S16, 96000, 16, 2}
73 };
74 #define NB_WIN_FORMATS (sizeof(win_formats)/sizeof(*win_formats))
75
76 #define PI 3.14159265358979323846
77 static char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
78 {
79     int i;
80     int nb_samples;
81     char* buf;
82     char* b;
83
84     nb_samples=(int)(duration*wfx->nSamplesPerSec);
85     *size=nb_samples*wfx->nBlockAlign;
86     b=buf=malloc(*size);
87     for (i=0;i<nb_samples;i++) {
88         double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
89         if (wfx->wBitsPerSample==8) {
90             unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
91             *b++=sample;
92             if (wfx->nChannels==2)
93                *b++=sample;
94         } else {
95             signed short sample=(signed short)((double)32767.5*y-0.5);
96             b[0]=sample & 0xff;
97             b[1]=sample >> 8;
98             b+=2;
99             if (wfx->nChannels==2) {
100                 b[0]=sample & 0xff;
101                 b[1]=sample >> 8;
102                 b+=2;
103             }
104         }
105     }
106     return buf;
107 }
108
109 static const char * wave_out_error(MMRESULT error)
110 {
111     static char msg[1024];
112     MMRESULT rc;
113
114     rc = waveOutGetErrorText(error, msg, sizeof(msg));
115     if (rc != MMSYSERR_NOERROR)
116         sprintf(msg, "waveOutGetErrorText(%x) failed with error %x", error, rc);
117     return msg;
118 }
119
120 static const char * wave_open_flags(DWORD flags)
121 {
122     static char msg[1024];
123     int first = TRUE;
124     msg[0] = 0;
125     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) {
126         strcat(msg, "CALLBACK_EVENT");
127         first = FALSE;
128     }
129     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) {
130         if (!first) strcat(msg, "|");
131         strcat(msg, "CALLBACK_FUNCTION");
132         first = FALSE;
133     }
134     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_NULL) {
135         if (!first) strcat(msg, "|");
136         strcat(msg, "CALLBACK_NULL");
137         first = FALSE;
138     }
139     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) {
140         if (!first) strcat(msg, "|");
141         strcat(msg, "CALLBACK_THREAD");
142         first = FALSE;
143     }
144     if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) {
145         if (!first) strcat(msg, "|");
146         strcat(msg, "CALLBACK_WINDOW");
147         first = FALSE;
148     }
149     if ((flags & WAVE_ALLOWSYNC) == WAVE_ALLOWSYNC) {
150         if (!first) strcat(msg, "|");
151         strcat(msg, "WAVE_ALLOWSYNC");
152         first = FALSE;
153     }
154     if ((flags & WAVE_FORMAT_DIRECT) == WAVE_FORMAT_DIRECT) {
155         if (!first) strcat(msg, "|");
156         strcat(msg, "WAVE_FORMAT_DIRECT");
157         first = FALSE;
158     }
159     if ((flags & WAVE_FORMAT_QUERY) == WAVE_FORMAT_QUERY) {
160         if (!first) strcat(msg, "|");
161         strcat(msg, "WAVE_FORMAT_QUERY");
162         first = FALSE;
163     }
164     if ((flags & WAVE_MAPPED) == WAVE_MAPPED) {
165         if (!first) strcat(msg, "|");
166         strcat(msg, "WAVE_MAPPED");
167         first = FALSE;
168     }
169     return msg;
170 }
171
172 static void wave_out_test_deviceOut(int device, int format, DWORD flags)
173 {
174     WAVEFORMATEX wfx;
175     HWAVEOUT wout;
176     HANDLE hevent;
177     WAVEHDR frag;
178     MMRESULT rc;
179     DWORD volume;
180
181     hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
182     ok(hevent!=NULL,"CreateEvent: error=%ld\n",GetLastError());
183     if (hevent==NULL)
184         return;
185
186     wfx.wFormatTag=WAVE_FORMAT_PCM;
187     wfx.nChannels=win_formats[format][3];
188     wfx.wBitsPerSample=win_formats[format][2];
189     wfx.nSamplesPerSec=win_formats[format][1];
190     wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
191     wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
192     wfx.cbSize=0;
193
194     wout=NULL;
195     rc=waveOutOpen(&wout,device,&wfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
196     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
197     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
198        (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
199        "waveOutOpen: device=%d format=%ldx%2dx%d flags=%lx(%s) rc=%d(%s)",device,
200        wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,CALLBACK_EVENT|flags,
201        wave_open_flags(CALLBACK_EVENT|flags),rc,wave_out_error(rc));
202     if (rc!=MMSYSERR_NOERROR) {
203         CloseHandle(hevent);
204         return;
205     }
206
207     ok(wfx.nChannels==win_formats[format][3] &&
208        wfx.wBitsPerSample==win_formats[format][2] &&
209        wfx.nSamplesPerSec==win_formats[format][1],
210        "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
211        wfx.nSamplesPerSec, wfx.wBitsPerSample,
212        wfx.nChannels, win_formats[format][1], win_formats[format][2],
213        win_formats[format][3]);
214
215     frag.lpData=wave_generate_la(&wfx,1.0,&frag.dwBufferLength);
216     frag.dwFlags=0;
217     frag.dwLoops=0;
218
219     rc=waveOutGetVolume(wout,&volume);
220     ok(rc==MMSYSERR_NOERROR,"waveOutGetVolume: device=%d rc=%d\n",device,rc);
221
222     rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
223     ok(rc==MMSYSERR_NOERROR,
224        "waveOutPrepareHeader: device=%d rc=%d\n",device,rc);
225
226     if (winetest_interactive && rc==MMSYSERR_NOERROR) {
227         trace("Playing 440Hz LA at %ldx%2dx%d %04lx\n",
228               wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels,flags);
229         rc=waveOutSetVolume(wout,0x20002000);
230         ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume: device=%d rc=%d\n",device,rc);
231         WaitForSingleObject(hevent,INFINITE);
232
233         rc=waveOutWrite(wout, &frag, sizeof(frag));
234         ok(rc==MMSYSERR_NOERROR,"waveOutWrite: device=%d rc=%d\n",device,rc);
235         WaitForSingleObject(hevent,INFINITE);
236
237         rc=waveOutSetVolume(wout,volume);
238         ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume: device=%d rc=%d\n",device,rc);
239     }
240
241     rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
242     ok(rc==MMSYSERR_NOERROR,
243        "waveOutUnprepareHeader: device=%d rc=%d\n",device,rc);
244     free(frag.lpData);
245
246     CloseHandle(hevent);
247     waveOutClose(wout);
248 }
249
250 static void wave_out_tests()
251 {
252     WAVEOUTCAPS caps;
253     WAVEFORMATEX format, oformat;
254     HWAVEOUT wout;
255     MMRESULT rc;
256     UINT ndev,d,f;
257
258     ndev=waveOutGetNumDevs();
259     trace("found %d WaveOut devices\n",ndev);
260
261     rc=waveOutGetDevCapsA(ndev+1,&caps,sizeof(caps));
262     ok(rc==MMSYSERR_BADDEVICEID,
263        "waveOutGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %d",rc);
264
265     format.wFormatTag=WAVE_FORMAT_PCM;
266     format.nChannels=2;
267     format.wBitsPerSample=16;
268     format.nSamplesPerSec=44100;
269     format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
270     format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
271     format.cbSize=0;
272     rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
273     ok(rc==MMSYSERR_BADDEVICEID,
274        "waveOutOpen: MMSYSERR_BADDEVICEID expected, got %d",rc);
275
276     for (d=0;d<ndev;d++) {
277         rc=waveOutGetDevCapsA(d,&caps,sizeof(caps));
278         ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID,
279            "waveOutGetDevCapsA: failed to get capabilities of device %d: rc=%d",d,rc);
280         if (rc==MMSYSERR_BADDEVICEID)
281             continue;
282
283         trace("  %d: \"%s\" %d.%d (%d:%d): channels=%d formats=%05lx support=%04lx\n",
284               d,caps.szPname,caps.vDriverVersion >> 8,
285               caps.vDriverVersion & 0xff,
286               caps.wMid,caps.wPid,
287               caps.wChannels,caps.dwFormats,caps.dwSupport);
288
289         for (f=0;f<NB_WIN_FORMATS;f++) {
290             if (caps.dwFormats & win_formats[f][0]) {
291                 wave_out_test_deviceOut(d,f,0);
292                 wave_out_test_deviceOut(d,f,WAVE_FORMAT_DIRECT);
293             }
294         }
295
296         /* Try an invalid format to test error handling */
297         trace("Testing invalid 2MHz format\n");
298         format.wFormatTag=WAVE_FORMAT_PCM;
299         format.nChannels=2;
300         format.wBitsPerSample=16;
301         format.nSamplesPerSec=2000000; /* 2MHz! */
302         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
303         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
304         format.cbSize=0;
305         oformat=format;
306         rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
307         ok(rc==WAVERR_BADFORMAT,
308            "waveOutOpen: opening the device at 2MHz should fail %d: rc=%d",d,rc);
309         if (rc==MMSYSERR_NOERROR) {
310             trace("     got %ldx%2dx%d for %ldx%2dx%d\n",
311                   format.nSamplesPerSec, format.wBitsPerSample,
312                   format.nChannels,
313                   oformat.nSamplesPerSec, oformat.wBitsPerSample,
314                   oformat.nChannels);
315             waveOutClose(wout);
316         }
317
318         format.wFormatTag=WAVE_FORMAT_PCM;
319         format.nChannels=2;
320         format.wBitsPerSample=16;
321         format.nSamplesPerSec=2000000; /* 2MHz! */
322         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
323         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
324         format.cbSize=0;
325         rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
326         ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG,
327            "waveOutOpen: opening the device at 2MHz should fail %d: rc=%d",d,rc);
328         if (rc==MMSYSERR_NOERROR) {
329             trace("     got %ldx%2dx%d for %dx%2dx%d\n",
330                   format.nSamplesPerSec, format.wBitsPerSample,
331                   format.nChannels,
332                   win_formats[f][1], win_formats[f][2],
333                   win_formats[f][3]);
334             waveOutClose(wout);
335         }
336     }
337 }
338
339 static const char * wave_in_error(MMRESULT error)
340 {
341     static char msg[1024];
342     MMRESULT rc;
343
344     rc = waveInGetErrorText(error, msg, sizeof(msg));
345     if (rc != MMSYSERR_NOERROR)
346         sprintf(msg, "waveInGetErrorText(%x) failed with error %x", error, rc);
347     return msg;
348 }
349
350 static void wave_in_test_deviceIn(int device, int format, DWORD flags)
351 {
352     WAVEFORMATEX wfx;
353     HWAVEIN win;
354     HANDLE hevent;
355     WAVEHDR frag;
356     MMRESULT rc;
357
358     hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
359     ok(hevent!=NULL,"CreateEvent: error=%ld\n",GetLastError());
360     if (hevent==NULL)
361         return;
362
363     wfx.wFormatTag=WAVE_FORMAT_PCM;
364     wfx.nChannels=win_formats[format][3];
365     wfx.wBitsPerSample=win_formats[format][2];
366     wfx.nSamplesPerSec=win_formats[format][1];
367     wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
368     wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
369     wfx.cbSize=0;
370
371     win=NULL;
372     rc=waveInOpen(&win,device,&wfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
373     /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
374     ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
375        (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
376        "waveInOpen: device=%d format=%ldx%2dx%d flags=%lx(%s) rc=%d(%s)",device,
377        wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,CALLBACK_EVENT|flags,
378        wave_open_flags(CALLBACK_EVENT|flags),rc,wave_in_error(rc));
379     if (rc!=MMSYSERR_NOERROR) {
380         CloseHandle(hevent);
381         return;
382     }
383
384     ok(wfx.nChannels==win_formats[format][3] &&
385        wfx.wBitsPerSample==win_formats[format][2] &&
386        wfx.nSamplesPerSec==win_formats[format][1],
387        "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
388        wfx.nSamplesPerSec, wfx.wBitsPerSample,
389        wfx.nChannels, win_formats[format][1], win_formats[format][2],
390        win_formats[format][3]);
391
392     frag.lpData=malloc(wfx.nAvgBytesPerSec);
393     frag.dwBufferLength=wfx.nAvgBytesPerSec;
394     frag.dwFlags=0;
395     frag.dwLoops=0;
396
397     rc=waveInPrepareHeader(win, &frag, sizeof(frag));
398     ok(rc==MMSYSERR_NOERROR, "waveOutPrepareHeader: device=%d rc=%d\n",device,rc);
399
400     if (winetest_interactive && rc==MMSYSERR_NOERROR) {
401         trace("Recording at %ldx%2dx%d %04lx\n",
402               wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels,flags);
403
404         rc=waveInAddBuffer(win, &frag, sizeof(frag));
405         ok(rc==MMSYSERR_NOERROR,"waveInAddBuffer: device=%d rc=%d\n",device,rc);
406
407         rc=waveInStart(win);
408         ok(rc==MMSYSERR_NOERROR,"waveInStart: device=%d rc=%d\n",device,rc);
409         WaitForSingleObject(hevent,INFINITE);
410     }
411
412     rc=waveInUnprepareHeader(win, &frag, sizeof(frag));
413     ok(rc==MMSYSERR_NOERROR,
414        "waveInUnprepareHeader: device=%d rc=%d\n",device,rc);
415
416     free(frag.lpData);
417     CloseHandle(hevent);
418     waveInClose(win);
419 }
420
421 static void wave_in_tests()
422 {
423     WAVEINCAPS caps;
424     WAVEFORMATEX format,oformat;
425     HWAVEIN win;
426     MMRESULT rc;
427     UINT ndev,d,f;
428
429     ndev=waveInGetNumDevs();
430     trace("found %d WaveIn devices\n",ndev);
431
432     rc=waveInGetDevCapsA(ndev+1,&caps,sizeof(caps));
433     ok(rc==MMSYSERR_BADDEVICEID,
434        "waveInGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %d",rc);
435
436     format.wFormatTag=WAVE_FORMAT_PCM;
437     format.nChannels=2;
438     format.wBitsPerSample=16;
439     format.nSamplesPerSec=44100;
440     format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
441     format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
442     format.cbSize=0;
443     rc=waveInOpen(&win,ndev+1,&format,0,0,CALLBACK_NULL);
444     ok(rc==MMSYSERR_BADDEVICEID,
445        "waveInOpen: MMSYSERR_BADDEVICEID expected, got %d",rc);
446
447     for (d=0;d<ndev;d++) {
448         rc=waveInGetDevCapsA(d,&caps,sizeof(caps));
449         ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID,
450            "waveInGetDevCapsA: failed to get capabilities of device %d: rc=%d",d,rc);
451         if (rc==MMSYSERR_BADDEVICEID)
452             continue;
453
454         trace("  %d: \"%s\" %d.%d (%d:%d): channels=%d formats=%05lx\n",
455               d,caps.szPname,caps.vDriverVersion >> 8,
456               caps.vDriverVersion & 0xff,
457               caps.wMid,caps.wPid,
458               caps.wChannels,caps.dwFormats);
459
460         for (f=0;f<NB_WIN_FORMATS;f++) {
461             if (caps.dwFormats & win_formats[f][0]) {
462                 wave_in_test_deviceIn(d,f,0);
463                 wave_in_test_deviceIn(d,f,WAVE_FORMAT_DIRECT);
464             }
465         }
466
467         /* Try an invalid format to test error handling */
468         trace("Testing invalid 2MHz format\n");
469         format.wFormatTag=WAVE_FORMAT_PCM;
470         format.nChannels=2;
471         format.wBitsPerSample=16;
472         format.nSamplesPerSec=2000000; /* 2MHz! */
473         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
474         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
475         format.cbSize=0;
476         oformat=format;
477         rc=waveInOpen(&win,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
478         ok(rc==WAVERR_BADFORMAT,
479            "waveInOpen: opening the device at 2MHz should fail %d: rc=%d",d,rc);
480         if (rc==MMSYSERR_NOERROR) {
481             trace("     got %ldx%2dx%d for %ldx%2dx%d\n",
482                   format.nSamplesPerSec, format.wBitsPerSample,
483                   format.nChannels,
484                   oformat.nSamplesPerSec, oformat.wBitsPerSample,
485                   oformat.nChannels);
486             waveInClose(win);
487         }
488
489         format.wFormatTag=WAVE_FORMAT_PCM;
490         format.nChannels=2;
491         format.wBitsPerSample=16;
492         format.nSamplesPerSec=2000000; /* 2MHz! */
493         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
494         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
495         format.cbSize=0;
496         rc=waveInOpen(&win,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
497         ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG,
498            "waveInOpen: opening the device at 2MHz should fail %d: rc=%d",d,rc);
499         if (rc==MMSYSERR_NOERROR) {
500             trace("     got %ldx%2dx%d for %dx%2dx%d\n",
501                   format.nSamplesPerSec, format.wBitsPerSample,
502                   format.nChannels,
503                   win_formats[f][1], win_formats[f][2],
504                   win_formats[f][3]);
505             waveInClose(win);
506         }
507     }
508 }
509
510 START_TEST(wave)
511 {
512     wave_out_tests();
513     wave_in_tests();
514 }