Don't consider no driver a test failure.
[wine/multimedia.git] / dlls / winmm / tests / capture.c
blob2dca642878c549922710e32b278508b8a328ef2a
1 /*
2 * Test winmm sound capture in each sound format
4 * Copyright (c) 2002 Francois Gouget
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.
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.
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
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
26 #include "wine/test.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "mmsystem.h"
31 #define NOBITMAP
32 #include "mmreg.h"
34 extern GUID KSDATAFORMAT_SUBTYPE_PCM;
35 extern GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
37 #include "winmm_test.h"
39 static const char * wave_in_error(MMRESULT error)
41 static char msg[1024];
42 static char long_msg[1100];
43 MMRESULT rc;
45 rc = waveInGetErrorText(error, msg, sizeof(msg));
46 if (rc != MMSYSERR_NOERROR)
47 sprintf(long_msg, "waveInGetErrorText(%x) failed with error %x", error, rc);
48 else
49 sprintf(long_msg, "%s(%s)", mmsys_error(error), msg);
50 return long_msg;
53 static void wave_in_test_deviceIn(int device, LPWAVEFORMATEX pwfx, DWORD format, DWORD flags, LPWAVEINCAPS pcaps)
55 HWAVEIN win;
56 HANDLE hevent;
57 WAVEHDR frag;
58 MMRESULT rc;
59 DWORD res;
60 WORD nChannels = pwfx->nChannels;
61 WORD wBitsPerSample = pwfx->wBitsPerSample;
62 DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
64 hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
65 ok(hevent!=NULL,"CreateEvent(): error=%ld\n",GetLastError());
66 if (hevent==NULL)
67 return;
69 win=NULL;
70 rc=waveInOpen(&win,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
71 /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
72 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
73 rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
74 rc==MMSYSERR_ALLOCATED ||
75 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
76 (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
77 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
78 (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
79 !(pcaps->dwFormats & format)) ||
80 (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
81 "waveInOpen(%s): format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",
82 dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
83 pwfx->nChannels,CALLBACK_EVENT|flags,
84 wave_open_flags(CALLBACK_EVENT|flags),wave_in_error(rc));
85 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
86 (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
87 trace(" Reason: The device lists this format as supported in it's "
88 "capabilities but opening it failed.\n");
89 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
90 !(pcaps->dwFormats & format))
91 trace("waveInOpen(%s): format=%ldx%2dx%d %s rc=%s failed but format "
92 "not supported so OK.\n",dev_name(device),pwfx->nSamplesPerSec,
93 pwfx->wBitsPerSample,pwfx->nChannels,
94 flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
95 flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
96 if (rc!=MMSYSERR_NOERROR) {
97 CloseHandle(hevent);
98 return;
100 res=WaitForSingleObject(hevent,1000);
101 ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for open\n");
103 ok(pwfx->nChannels==nChannels &&
104 pwfx->wBitsPerSample==wBitsPerSample &&
105 pwfx->nSamplesPerSec==nSamplesPerSec,
106 "got the wrong format: %ldx%2dx%d instead of %ldx%2dx%d\n",
107 pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
108 pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
110 frag.lpData=malloc(pwfx->nAvgBytesPerSec);
111 frag.dwBufferLength=pwfx->nAvgBytesPerSec;
112 frag.dwBytesRecorded=0;
113 frag.dwUser=0;
114 frag.dwFlags=0;
115 frag.dwLoops=0;
116 frag.lpNext=0;
118 rc=waveInPrepareHeader(win, &frag, sizeof(frag));
119 ok(rc==MMSYSERR_NOERROR, "waveInPrepareHeader(%s): rc=%s\n",
120 dev_name(device),wave_in_error(rc));
121 ok(frag.dwFlags&WHDR_PREPARED,"waveInPrepareHeader(%s): prepared flag "
122 "not set\n",dev_name(device));
124 if (winetest_interactive && rc==MMSYSERR_NOERROR) {
125 trace("Recording for 1 second at %5ldx%2dx%d %s %s\n",
126 pwfx->nSamplesPerSec, pwfx->wBitsPerSample,pwfx->nChannels,
127 get_format_str(pwfx->wFormatTag),
128 flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
129 flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
130 rc=waveInAddBuffer(win, &frag, sizeof(frag));
131 ok(rc==MMSYSERR_NOERROR,"waveInAddBuffer(%s): rc=%s\n",
132 dev_name(device),wave_in_error(rc));
134 rc=waveInStart(win);
135 ok(rc==MMSYSERR_NOERROR,"waveInStart(%s): rc=%s\n",
136 dev_name(device),wave_in_error(rc));
138 res = WaitForSingleObject(hevent,1200);
139 ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for header\n");
140 ok(frag.dwFlags&WHDR_DONE,"WHDR_DONE not set in frag.dwFlags\n");
141 ok(frag.dwBytesRecorded==pwfx->nAvgBytesPerSec,
142 "frag.dwBytesRecorded=%ld, should=%ld\n",
143 frag.dwBytesRecorded,pwfx->nAvgBytesPerSec);
144 /* stop playing on error */
145 if (res!=WAIT_OBJECT_0) {
146 rc=waveInStop(win);
147 ok(rc==MMSYSERR_NOERROR,
148 "waveInStop(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
152 rc=waveInUnprepareHeader(win, &frag, sizeof(frag));
153 ok(rc==MMSYSERR_NOERROR,"waveInUnprepareHeader(%s): rc=%s\n",
154 dev_name(device),wave_in_error(rc));
156 rc=waveInClose(win);
157 ok(rc==MMSYSERR_NOERROR,
158 "waveInClose(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
159 res=WaitForSingleObject(hevent,1000);
160 ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for close\n");
162 if (winetest_interactive)
165 * Now play back what we recorded
167 HWAVEOUT wout;
169 trace("Playing back recorded sound\n");
170 rc=waveOutOpen(&wout,WAVE_MAPPER,pwfx,(DWORD)hevent,0,CALLBACK_EVENT);
171 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
172 rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
173 rc==MMSYSERR_ALLOCATED ||
174 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
175 !(pcaps->dwFormats & format)),
176 "waveOutOpen(%s) format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",
177 dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
178 pwfx->nChannels,CALLBACK_EVENT|flags,
179 wave_open_flags(CALLBACK_EVENT),wave_out_error(rc));
180 if (rc==MMSYSERR_NOERROR)
182 rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
183 ok(rc==MMSYSERR_NOERROR,"waveOutPrepareHeader(%s): rc=%s\n",
184 dev_name(device),wave_out_error(rc));
186 if (rc==MMSYSERR_NOERROR)
188 WaitForSingleObject(hevent,INFINITE);
189 rc=waveOutWrite(wout, &frag, sizeof(frag));
190 ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
191 dev_name(device),wave_out_error(rc));
192 WaitForSingleObject(hevent,INFINITE);
194 rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
195 ok(rc==MMSYSERR_NOERROR,"waveOutUnprepareHeader(%s): rc=%s\n",
196 dev_name(device),wave_out_error(rc));
198 rc=waveOutClose(wout);
199 ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",
200 dev_name(device),wave_out_error(rc));
202 else
203 trace("Unable to play back the recorded sound\n");
206 free(frag.lpData);
207 CloseHandle(hevent);
210 static void wave_in_test_device(int device)
212 WAVEINCAPSA capsA;
213 WAVEINCAPSW capsW;
214 WAVEFORMATEX format,oformat;
215 WAVEFORMATEXTENSIBLE wfex;
216 HWAVEIN win;
217 MMRESULT rc;
218 UINT f;
219 WCHAR * nameW;
220 CHAR * nameA;
221 DWORD size;
222 DWORD dwPageSize;
223 BYTE * twoPages;
224 SYSTEM_INFO sSysInfo;
225 DWORD flOldProtect;
226 BOOL res;
228 GetSystemInfo(&sSysInfo);
229 dwPageSize = sSysInfo.dwPageSize;
231 rc=waveInGetDevCapsA(device,&capsA,sizeof(capsA));
232 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
233 rc==MMSYSERR_NODRIVER,
234 "waveInGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
235 dev_name(device),wave_in_error(rc));
236 if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER)
237 return;
239 rc=waveInGetDevCapsW(device,&capsW,sizeof(capsW));
240 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
241 "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
242 "expected, got %s\n",dev_name(device),wave_in_error(rc));
244 rc=waveInGetDevCapsA(device,0,sizeof(capsA));
245 ok(rc==MMSYSERR_INVALPARAM,
246 "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
247 dev_name(device),wave_in_error(rc));
249 rc=waveInGetDevCapsW(device,0,sizeof(capsW));
250 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
251 "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
252 "expected, got %s\n",dev_name(device),wave_in_error(rc));
254 #if 0 /* FIXME: this works on windows but crashes wine */
255 rc=waveInGetDevCapsA(device,1,sizeof(capsA));
256 ok(rc==MMSYSERR_INVALPARAM,
257 "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
258 dev_name(device),wave_in_error(rc));
260 rc=waveInGetDevCapsW(device,1,sizeof(capsW));
261 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
262 "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
263 "expected, got %s\n",dev_name(device),wave_in_error(rc));
264 #endif
266 rc=waveInGetDevCapsA(device,&capsA,4);
267 ok(rc==MMSYSERR_NOERROR,
268 "waveInGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
269 dev_name(device),wave_in_error(rc));
271 rc=waveInGetDevCapsW(device,&capsW,4);
272 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
273 "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
274 "expected, got %s\n",dev_name(device),wave_in_error(rc));
276 nameA=NULL;
277 rc=waveInMessage((HWAVEIN)device, DRV_QUERYDEVICEINTERFACESIZE,
278 (DWORD_PTR)&size, 0);
279 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM ||
280 rc==MMSYSERR_NOTSUPPORTED,
281 "waveInMessage(%s): failed to get interface size: rc=%s\n",
282 dev_name(device),wave_in_error(rc));
283 if (rc==MMSYSERR_NOERROR) {
284 nameW = (WCHAR *)malloc(size);
285 rc=waveInMessage((HWAVEIN)device, DRV_QUERYDEVICEINTERFACE,
286 (DWORD_PTR)nameW, size);
287 ok(rc==MMSYSERR_NOERROR,"waveInMessage(%s): failed to get interface "
288 "name: rc=%s\n",dev_name(device),wave_in_error(rc));
289 ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),
290 "got an incorrect size: %ld instead of %d\n",
291 size,(lstrlenW(nameW)+1)*sizeof(WCHAR));
292 if (rc==MMSYSERR_NOERROR) {
293 nameA = malloc(size/sizeof(WCHAR));
294 WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR),
295 nameA, size/sizeof(WCHAR), NULL, NULL);
297 free(nameW);
298 } else if (rc==MMSYSERR_NOTSUPPORTED) {
299 nameA=strdup("not supported");
302 trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
303 (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
304 capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid);
305 trace(" channels=%d formats=%05lx\n",
306 capsA.wChannels,capsA.dwFormats);
308 free(nameA);
310 for (f=0;f<NB_WIN_FORMATS;f++) {
311 format.wFormatTag=WAVE_FORMAT_PCM;
312 format.nChannels=win_formats[f][3];
313 format.wBitsPerSample=win_formats[f][2];
314 format.nSamplesPerSec=win_formats[f][1];
315 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
316 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
317 format.cbSize=0;
318 wave_in_test_deviceIn(device,&format,win_formats[f][0],0, &capsA);
319 wave_in_test_deviceIn(device,&format,win_formats[f][0],
320 WAVE_FORMAT_DIRECT, &capsA);
321 if (device != WAVE_MAPPER)
322 wave_in_test_deviceIn(device,&format,win_formats[f][0],
323 WAVE_MAPPED, &capsA);
326 /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
327 * checking */
328 twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
329 PAGE_READWRITE);
330 ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
331 if (twoPages) {
332 res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
333 &flOldProtect);
334 ok(res, "Failed to set memory access on second page\n");
335 if (res) {
336 LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
337 sizeof(PCMWAVEFORMAT));
338 pwfx->wFormatTag=WAVE_FORMAT_PCM;
339 pwfx->nChannels=1;
340 pwfx->wBitsPerSample=8;
341 pwfx->nSamplesPerSec=22050;
342 pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
343 pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
344 wave_in_test_deviceIn(device,pwfx,WAVE_FORMAT_2M08,0, &capsA);
345 wave_in_test_deviceIn(device,pwfx,WAVE_FORMAT_2M08,
346 WAVE_FORMAT_DIRECT, &capsA);
347 if (device != WAVE_MAPPER)
348 wave_in_test_deviceIn(device,pwfx,WAVE_FORMAT_2M08,
349 WAVE_MAPPED, &capsA);
351 VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
354 /* Testing invalid format: 2 MHz sample rate */
355 format.wFormatTag=WAVE_FORMAT_PCM;
356 format.nChannels=2;
357 format.wBitsPerSample=16;
358 format.nSamplesPerSec=2000000;
359 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
360 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
361 format.cbSize=0;
362 oformat=format;
363 rc=waveInOpen(&win,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
364 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
365 rc==MMSYSERR_INVALPARAM,
366 "waveInOpen(%s): opening the device with 2 MHz sample rate should fail: "
367 " rc=%s\n",dev_name(device),wave_in_error(rc));
368 if (rc==MMSYSERR_NOERROR) {
369 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
370 format.nSamplesPerSec, format.wBitsPerSample,
371 format.nChannels,
372 oformat.nSamplesPerSec, oformat.wBitsPerSample,
373 oformat.nChannels);
374 waveInClose(win);
377 /* test non PCM formats */
378 format.wFormatTag=WAVE_FORMAT_MULAW;
379 format.nChannels=1;
380 format.wBitsPerSample=8;
381 format.nSamplesPerSec=8000;
382 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
383 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
384 format.cbSize=0;
385 rc=waveInOpen(&win,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
386 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
387 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
388 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
389 if (rc==MMSYSERR_NOERROR) {
390 waveInClose(win);
391 wave_in_test_deviceIn(device,&format,0,0,&capsA);
392 } else
393 trace("waveInOpen(%s): WAVE_FORMAT_MULAW not supported\n",
394 dev_name(device));
396 format.wFormatTag=WAVE_FORMAT_ADPCM;
397 format.nChannels=2;
398 format.wBitsPerSample=4;
399 format.nSamplesPerSec=22050;
400 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
401 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
402 format.cbSize=0;
403 rc=waveInOpen(&win,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
404 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
405 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
406 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
407 if (rc==MMSYSERR_NOERROR) {
408 waveInClose(win);
409 wave_in_test_deviceIn(device,&format,0,0,&capsA);
410 } else
411 trace("waveInOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
412 dev_name(device));
414 /* test if WAVEFORMATEXTENSIBLE supported */
415 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
416 wfex.Format.nChannels=2;
417 wfex.Format.wBitsPerSample=16;
418 wfex.Format.nSamplesPerSec=22050;
419 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
420 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
421 wfex.Format.nBlockAlign;
422 wfex.Format.cbSize=22;
423 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
424 wfex.dwChannelMask=SPEAKER_ALL;
425 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
426 rc=waveInOpen(&win,device,&wfex.Format,0,0,
427 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
428 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
429 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
430 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
431 if (rc==MMSYSERR_NOERROR) {
432 waveInClose(win);
433 wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
434 } else
435 trace("waveInOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
436 dev_name(device));
438 /* test if 4 channels supported */
439 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
440 wfex.Format.nChannels=4;
441 wfex.Format.wBitsPerSample=16;
442 wfex.Format.nSamplesPerSec=22050;
443 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
444 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
445 wfex.Format.nBlockAlign;
446 wfex.Format.cbSize=22;
447 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
448 wfex.dwChannelMask=SPEAKER_ALL;
449 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
450 rc=waveInOpen(&win,device,&wfex.Format,0,0,
451 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
452 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
453 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
454 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
455 if (rc==MMSYSERR_NOERROR) {
456 waveInClose(win);
457 wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
458 } else
459 trace("waveInOpen(%s): 4 channels not supported\n",
460 dev_name(device));
462 /* test if 6 channels supported */
463 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
464 wfex.Format.nChannels=6;
465 wfex.Format.wBitsPerSample=16;
466 wfex.Format.nSamplesPerSec=22050;
467 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
468 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
469 wfex.Format.nBlockAlign;
470 wfex.Format.cbSize=22;
471 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
472 wfex.dwChannelMask=SPEAKER_ALL;
473 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
474 rc=waveInOpen(&win,device,&wfex.Format,0,0,
475 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
476 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
477 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
478 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
479 if (rc==MMSYSERR_NOERROR) {
480 waveInClose(win);
481 wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
482 } else
483 trace("waveInOpen(%s): 6 channels not supported\n",
484 dev_name(device));
486 #if 0 /* ALSA doesn't like this */
487 /* test if 24 bit samples supported */
488 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
489 wfex.Format.nChannels=2;
490 wfex.Format.wBitsPerSample=24;
491 wfex.Format.nSamplesPerSec=22050;
492 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
493 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
494 wfex.Format.nBlockAlign;
495 wfex.Format.cbSize=22;
496 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
497 wfex.dwChannelMask=SPEAKER_ALL;
498 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
499 rc=waveInOpen(&win,device,&wfex.Format,0,0,
500 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
501 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
502 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
503 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
504 if (rc==MMSYSERR_NOERROR) {
505 waveInClose(win);
506 wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
507 } else
508 trace("waveInOpen(%s): 24 bit samples not supported\n",
509 dev_name(device));
510 #endif
512 /* test if 32 bit samples supported */
513 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
514 wfex.Format.nChannels=2;
515 wfex.Format.wBitsPerSample=32;
516 wfex.Format.nSamplesPerSec=22050;
517 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
518 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
519 wfex.Format.nBlockAlign;
520 wfex.Format.cbSize=22;
521 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
522 wfex.dwChannelMask=SPEAKER_ALL;
523 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
524 rc=waveInOpen(&win,device,&wfex.Format,0,0,
525 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
526 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
527 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
528 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
529 if (rc==MMSYSERR_NOERROR) {
530 waveInClose(win);
531 wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
532 } else
533 trace("waveInOpen(%s): 32 bit samples not supported\n",
534 dev_name(device));
536 /* test if 32 bit float samples supported */
537 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
538 wfex.Format.nChannels=2;
539 wfex.Format.wBitsPerSample=32;
540 wfex.Format.nSamplesPerSec=22050;
541 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
542 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
543 wfex.Format.nBlockAlign;
544 wfex.Format.cbSize=22;
545 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
546 wfex.dwChannelMask=SPEAKER_ALL;
547 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
548 rc=waveInOpen(&win,device,&wfex.Format,0,0,
549 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
550 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
551 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
552 "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
553 if (rc==MMSYSERR_NOERROR) {
554 waveInClose(win);
555 wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
556 } else
557 trace("waveInOpen(%s): 32 bit float samples not supported\n",
558 dev_name(device));
561 static void wave_in_tests()
563 WAVEINCAPSA capsA;
564 WAVEINCAPSW capsW;
565 WAVEFORMATEX format;
566 HWAVEIN win;
567 MMRESULT rc;
568 UINT ndev,d;
570 ndev=waveInGetNumDevs();
571 trace("found %d WaveIn devices\n",ndev);
573 rc=waveInGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
574 ok(rc==MMSYSERR_BADDEVICEID,
575 "waveInGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
576 dev_name(ndev+1),wave_in_error(rc));
578 rc=waveInGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
579 if (ndev>0)
580 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NODRIVER,
581 "waveInGetDevCapsA(%s): MMSYSERR_NOERROR or MMSYSERR_NODRIVER "
582 "expected, got %s\n",dev_name(WAVE_MAPPER),wave_in_error(rc));
583 else
584 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER,
585 "waveInGetDevCapsA(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
586 "expected, got %s\n",dev_name(WAVE_MAPPER),wave_in_error(rc));
588 rc=waveInGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
589 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NOTSUPPORTED,
590 "waveInGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
591 "expected, got %s\n",dev_name(ndev+1),wave_in_error(rc));
593 rc=waveInGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
594 if (ndev>0)
595 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NODRIVER ||
596 rc==MMSYSERR_NOTSUPPORTED,
597 "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NODRIVER or "
598 "MMSYSERR_NOTSUPPORTED expected, got %s\n",
599 dev_name(ndev+1),wave_in_error(rc));
600 else
601 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER,
602 "waveInGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
603 "expected, got %s\n",dev_name(ndev+1),wave_in_error(rc));
605 format.wFormatTag=WAVE_FORMAT_PCM;
606 format.nChannels=2;
607 format.wBitsPerSample=16;
608 format.nSamplesPerSec=44100;
609 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
610 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
611 format.cbSize=0;
612 rc=waveInOpen(&win,ndev+1,&format,0,0,CALLBACK_NULL);
613 ok(rc==MMSYSERR_BADDEVICEID,
614 "waveInOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
615 dev_name(ndev+1),wave_in_error(rc));
617 for (d=0;d<ndev;d++)
618 wave_in_test_device(d);
620 if (ndev>0)
621 wave_in_test_device(WAVE_MAPPER);
624 START_TEST(capture)
626 wave_in_tests();