Test sound format support with waveOutGetDevCaps and waveOutOpen.
[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 "wine/test.h"
22 #include "winbase.h"
23 #include <mmsystem.h>
24
25 /*
26  * Note that in most of this test we may get MMSYSERR_BADDEVICEID errors
27  * at about any time if the user starts another application that uses the
28  * sound device. So we should not report these as test failures.
29  */
30
31 #define TEST_FORMATS 12
32 static const int win_formats[TEST_FORMATS][4]={
33     {WAVE_FORMAT_1M08, 11025,  8, 1},
34     {WAVE_FORMAT_1S08, 11025,  8, 2},
35     {WAVE_FORMAT_1M16, 11025, 16, 1},
36     {WAVE_FORMAT_1S16, 11025, 16, 2},
37     {WAVE_FORMAT_2M08, 22050,  8, 1},
38     {WAVE_FORMAT_2S08, 22050,  8, 2},
39     {WAVE_FORMAT_2M16, 22050, 16, 1},
40     {WAVE_FORMAT_2S16, 22050, 16, 2},
41     {WAVE_FORMAT_4M08, 44100,  8, 1},
42     {WAVE_FORMAT_4S08, 44100,  8, 2},
43     {WAVE_FORMAT_4M16, 44100, 16, 1},
44     {WAVE_FORMAT_4S16, 44100, 16, 2}
45 };
46
47 void wave_out_tests()
48 {
49     WAVEOUTCAPS caps;
50     WAVEFORMATEX format;
51     HWAVEOUT wout;
52     MMRESULT rc;
53     UINT ndev,d,f;
54     int success;
55
56     ndev=waveOutGetNumDevs();
57     winetest_trace("found %d WaveOut devices\n",ndev);
58
59     todo_wine {
60         rc=waveOutGetDevCapsA(ndev+1,&caps,sizeof(caps));
61         ok(rc==MMSYSERR_BADDEVICEID,
62            "waveOutGetDevCa psA: MMSYSERR_BADDEVICEID expected, got %d",rc);
63     }
64
65     format.wFormatTag=WAVE_FORMAT_PCM;
66     format.nChannels=2;
67     format.wBitsPerSample=16;
68     format.nSamplesPerSec=44100;
69     format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
70     format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
71     format.cbSize=0;
72     rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
73     ok(rc==MMSYSERR_BADDEVICEID,
74        "waveOutOpen: MMSYSERR_BADDEVICEID expected, got %d",rc);
75
76     for (d=0;d<ndev;d++) {
77         rc=waveOutGetDevCapsA(d,&caps,sizeof(caps));
78         success=(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID);
79         ok(success,"failed to get capabilities of device %d: rc=%d",d,rc);
80         if (!success)
81             continue;
82
83         winetest_trace("  %d: \"%s\" %d.%d (%d:%d): channels=%d formats=%04lx support=%04lx\n",
84                        d,caps.szPname,caps.vDriverVersion >> 8,
85                        caps.vDriverVersion & 0xff,
86                        caps.wMid,caps.wPid,
87                        caps.wChannels,caps.dwFormats,caps.dwSupport);
88
89         for (f=0;f<TEST_FORMATS;f++) {
90             if (!(caps.dwFormats & win_formats[f][0]))
91                 continue;
92
93             format.wFormatTag=WAVE_FORMAT_PCM;
94             format.nChannels=win_formats[f][3];
95             format.wBitsPerSample=win_formats[f][2];
96             format.nSamplesPerSec=win_formats[f][1];
97             format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
98             format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
99             format.cbSize=0;
100
101             rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL);
102             success=(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID);
103             ok(success, "failed to open device %d: rc=%d",d,rc);
104             if (success) {
105                 ok(format.nChannels==win_formats[f][3] &&
106                    format.wBitsPerSample==win_formats[f][2] &&
107                    format.nSamplesPerSec==win_formats[f][1],
108                    "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
109                    format.nSamplesPerSec, format.wBitsPerSample,
110                    format.nChannels, win_formats[f][1], win_formats[f][2],
111                    win_formats[f][3]);
112             }
113             if (rc==MMSYSERR_NOERROR)
114                 waveOutClose(wout);
115
116             /* Try again with WAVE_FORMAT_DIRECT */
117             rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
118             success=(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID);
119             ok(success, "failed to open device %d: rc=%d",d,rc);
120             if (success) {
121                 ok(format.nChannels==win_formats[f][3] &&
122                    format.wBitsPerSample==win_formats[f][2] &&
123                    format.nSamplesPerSec==win_formats[f][1],
124                    "got the wrong format: %ldx%2dx%d instead of %dx%2dx%d\n",
125                    format.nSamplesPerSec, format.wBitsPerSample,
126                    format.nChannels, win_formats[f][1], win_formats[f][2],
127                    win_formats[f][3]);
128             }
129             if (rc==MMSYSERR_NOERROR)
130                 waveOutClose(wout);
131         }
132
133         /* Check an invalid format to test error handling */
134         todo_wine {
135         winetest_trace("Testing invalid 2MHz format\n");
136         format.wFormatTag=WAVE_FORMAT_PCM;
137         format.nChannels=2;
138         format.wBitsPerSample=16;
139         format.nSamplesPerSec=2000000; /* 2MHz! */
140         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
141         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
142         format.cbSize=0;
143         rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL);
144         success=(rc==WAVERR_BADFORMAT);
145         ok(success, "opening the device at 2MHz should fail %d: rc=%d",d,rc);
146         if (rc==MMSYSERR_NOERROR) {
147             winetest_trace("     got %ldx%2dx%d for %dx%2dx%d\n",
148                            format.nSamplesPerSec, format.wBitsPerSample,
149                            format.nChannels,
150                            win_formats[f][1], win_formats[f][2],
151                            win_formats[f][3]);
152             waveOutClose(wout);
153         }
154         }
155
156         format.wFormatTag=WAVE_FORMAT_PCM;
157         format.nChannels=2;
158         format.wBitsPerSample=16;
159         format.nSamplesPerSec=2000000; /* 2MHz! */
160         format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
161         format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
162         format.cbSize=0;
163         rc=waveOutOpen(&wout,d,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
164         success=(rc==WAVERR_BADFORMAT);
165         ok(success, "opening the device at 2MHz should fail %d: rc=%d",d,rc);
166         if (rc==MMSYSERR_NOERROR) {
167             winetest_trace("     got %ldx%2dx%d for %dx%2dx%d\n",
168                            format.nSamplesPerSec, format.wBitsPerSample,
169                            format.nChannels,
170                            win_formats[f][1], win_formats[f][2],
171                            win_formats[f][3]);
172             waveOutClose(wout);
173         }
174     }
175 }
176
177 START_TEST(wave)
178 {
179     wave_out_tests();
180 }