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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "wine/test.h"
35 extern GUID KSDATAFORMAT_SUBTYPE_PCM
;
36 extern GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
;
38 #include "winmm_test.h"
40 static const char * wave_in_error(MMRESULT error
)
42 static char msg
[1024];
43 static char long_msg
[1100];
46 rc
= waveInGetErrorTextA(error
, msg
, sizeof(msg
));
47 if (rc
!= MMSYSERR_NOERROR
)
48 sprintf(long_msg
, "waveInGetErrorTextA(%x) failed with error %x", error
, rc
);
50 sprintf(long_msg
, "%s(%s)", mmsys_error(error
), msg
);
54 static void check_position(int device
, HWAVEIN win
, DWORD bytes
,
61 mmtime
.wType
= TIME_BYTES
;
62 rc
=waveInGetPosition(win
, &mmtime
, sizeof(mmtime
));
63 ok(rc
==MMSYSERR_NOERROR
,
64 "waveInGetPosition(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
65 ok(mmtime
.wType
== TIME_BYTES
, "waveInGetPosition(%s): returned %s\n",
66 dev_name(device
), wave_time_format(mmtime
.wType
));
67 returned
= time_to_bytes(&mmtime
, pwfx
);
68 ok(returned
== bytes
, "waveInGetPosition(%s): returned %d bytes, "
69 "should be %d\n", dev_name(device
), returned
, bytes
);
71 mmtime
.wType
= TIME_SAMPLES
;
72 rc
=waveInGetPosition(win
, &mmtime
, sizeof(mmtime
));
73 ok(rc
==MMSYSERR_NOERROR
,
74 "waveInGetPosition(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
75 ok(mmtime
.wType
== TIME_SAMPLES
, "waveInGetPosition(%s): returned %s\n",
76 dev_name(device
), wave_time_format(mmtime
.wType
));
77 returned
= time_to_bytes(&mmtime
, pwfx
);
78 ok(returned
== bytes
, "waveInGetPosition(%s): returned %d samples, "
79 "should be %d\n", dev_name(device
), bytes_to_samples(returned
, pwfx
),
80 bytes_to_samples(bytes
, pwfx
));
82 mmtime
.wType
= TIME_MS
;
83 rc
=waveInGetPosition(win
, &mmtime
, sizeof(mmtime
));
84 ok(rc
==MMSYSERR_NOERROR
,
85 "waveInGetPosition(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
86 ok(mmtime
.wType
== TIME_BYTES
, "waveInGetPosition(%s): returned %s\n",
87 dev_name(device
), wave_time_format(mmtime
.wType
));
88 returned
= time_to_bytes(&mmtime
, pwfx
);
89 ok(returned
== bytes
, "waveInGetPosition(%s): TIME_MS test failed\n",
92 mmtime
.wType
= TIME_SMPTE
;
93 rc
=waveInGetPosition(win
, &mmtime
, sizeof(mmtime
));
94 ok(rc
==MMSYSERR_NOERROR
,
95 "waveInGetPosition(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
96 ok(mmtime
.wType
== TIME_BYTES
, "waveInGetPosition(%s): returned %s\n",
97 dev_name(device
), wave_time_format(mmtime
.wType
));
98 returned
= time_to_bytes(&mmtime
, pwfx
);
99 ok(returned
== bytes
, "waveInGetPosition(%s): SMPTE test failed\n",
102 mmtime
.wType
= TIME_MIDI
;
103 rc
=waveInGetPosition(win
, &mmtime
, sizeof(mmtime
));
104 ok(rc
==MMSYSERR_NOERROR
,
105 "waveInGetPosition(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
106 ok(mmtime
.wType
== TIME_BYTES
, "waveInGetPosition(%s): returned %s\n",
107 dev_name(device
), wave_time_format(mmtime
.wType
));
108 returned
= time_to_bytes(&mmtime
, pwfx
);
109 ok(returned
== bytes
, "waveInGetPosition(%s): MIDI test failed\n",
112 mmtime
.wType
= TIME_TICKS
;
113 rc
=waveInGetPosition(win
, &mmtime
, sizeof(mmtime
));
114 ok(rc
==MMSYSERR_NOERROR
,
115 "waveInGetPosition(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
116 ok(mmtime
.wType
== TIME_BYTES
, "waveInGetPosition(%s): returned %s\n",
117 dev_name(device
), wave_time_format(mmtime
.wType
));
118 returned
= time_to_bytes(&mmtime
, pwfx
);
119 ok(returned
== bytes
, "waveInGetPosition(%s): TICKS test failed\n",
123 static void wave_in_test_deviceIn(int device
, WAVEFORMATEX
*pwfx
, DWORD format
, DWORD flags
,
127 HANDLE hevent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
132 WORD nChannels
= pwfx
->nChannels
;
133 WORD wBitsPerSample
= pwfx
->wBitsPerSample
;
134 DWORD nSamplesPerSec
= pwfx
->nSamplesPerSec
;
138 flags
|= CALLBACK_EVENT
;
139 rc
=waveInOpen(&win
,device
,pwfx
,(DWORD_PTR
)hevent
,0,flags
);
140 /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
141 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_BADDEVICEID
||
142 rc
==MMSYSERR_NOTENABLED
|| rc
==MMSYSERR_NODRIVER
||
143 rc
==MMSYSERR_ALLOCATED
||
144 ((rc
==WAVERR_BADFORMAT
|| rc
==MMSYSERR_NOTSUPPORTED
) &&
145 (flags
& WAVE_FORMAT_DIRECT
) && !(pcaps
->dwFormats
& format
)) ||
146 ((rc
==WAVERR_BADFORMAT
|| rc
==MMSYSERR_NOTSUPPORTED
) &&
147 (!(flags
& WAVE_FORMAT_DIRECT
) || (flags
& WAVE_MAPPED
)) &&
148 !(pcaps
->dwFormats
& format
)) ||
149 (rc
==MMSYSERR_INVALFLAG
&& (flags
& WAVE_FORMAT_DIRECT
)),
150 "waveInOpen(%s): format=%dx%2dx%d flags=%x(%s) rc=%s\n",
151 dev_name(device
),pwfx
->nSamplesPerSec
,pwfx
->wBitsPerSample
,
152 pwfx
->nChannels
,flags
,wave_open_flags(flags
),wave_in_error(rc
));
153 if ((rc
==WAVERR_BADFORMAT
|| rc
==MMSYSERR_NOTSUPPORTED
) &&
154 (flags
& WAVE_FORMAT_DIRECT
) && (pcaps
->dwFormats
& format
))
155 trace(" Reason: The device lists this format as supported in its "
156 "capabilities but opening it failed.\n");
157 if ((rc
==WAVERR_BADFORMAT
|| rc
==MMSYSERR_NOTSUPPORTED
) &&
158 !(pcaps
->dwFormats
& format
))
159 trace("waveInOpen(%s): format=%dx%2dx%d %s rc=%s failed but format "
160 "not supported so OK.\n",dev_name(device
),pwfx
->nSamplesPerSec
,
161 pwfx
->wBitsPerSample
,pwfx
->nChannels
,
162 flags
& WAVE_FORMAT_DIRECT
? "flags=WAVE_FORMAT_DIRECT" :
163 flags
& WAVE_MAPPED
? "flags=WAVE_MAPPED" : "", mmsys_error(rc
));
164 if (rc
!=MMSYSERR_NOERROR
) {
168 res
=WaitForSingleObject(hevent
,1000);
169 ok(res
==WAIT_OBJECT_0
,"WaitForSingleObject failed for open\n");
171 ok(pwfx
->nChannels
==nChannels
&&
172 pwfx
->wBitsPerSample
==wBitsPerSample
&&
173 pwfx
->nSamplesPerSec
==nSamplesPerSec
,
174 "got the wrong format: %dx%2dx%d instead of %dx%2dx%d\n",
175 pwfx
->nSamplesPerSec
, pwfx
->wBitsPerSample
,
176 pwfx
->nChannels
, nSamplesPerSec
, wBitsPerSample
, nChannels
);
178 /* waveInGetDevCaps allows an open handle instead of a device id */
179 rc
=waveInGetDevCapsW(HandleToUlong(win
),&capsW
,sizeof(capsW
));
180 ok(rc
==MMSYSERR_NOERROR
,
181 "waveInGetDevCapsW(%s): MMSYSERR_NOERROR "
182 "expected, got %s\n",dev_name(device
),wave_in_error(rc
));
184 /* waveInOpen does not allow an open handle instead of a device id */
185 rc
=waveInOpen(&win2
,HandleToUlong(win
),pwfx
,0,0,CALLBACK_NULL
);
186 ok(rc
==MMSYSERR_BADDEVICEID
,
187 "waveInOpen(%s): MMSYSERR_BADDEVICEID "
188 "expected, got %s\n",dev_name(device
),wave_in_error(rc
));
189 if(rc
==MMSYSERR_NOERROR
)
192 /* Check that the position is 0 at start */
193 check_position(device
, win
, 0, pwfx
);
195 frag
.lpData
=HeapAlloc(GetProcessHeap(), 0, pwfx
->nAvgBytesPerSec
);
196 frag
.dwBufferLength
=pwfx
->nAvgBytesPerSec
;
197 frag
.dwBytesRecorded
=0;
203 rc
=waveInPrepareHeader(win
, &frag
, sizeof(frag
));
204 ok(rc
==MMSYSERR_NOERROR
, "waveInPrepareHeader(%s): rc=%s\n",
205 dev_name(device
),wave_in_error(rc
));
206 ok(frag
.dwFlags
&WHDR_PREPARED
,"waveInPrepareHeader(%s): prepared flag "
207 "not set\n",dev_name(device
));
209 if (winetest_interactive
&& rc
==MMSYSERR_NOERROR
) {
210 trace("Recording for 1 second at %5dx%2dx%d %s %s\n",
211 pwfx
->nSamplesPerSec
, pwfx
->wBitsPerSample
,pwfx
->nChannels
,
212 get_format_str(pwfx
->wFormatTag
),
213 flags
& WAVE_FORMAT_DIRECT
? "WAVE_FORMAT_DIRECT" :
214 flags
& WAVE_MAPPED
? "WAVE_MAPPED" : "");
215 rc
=waveInAddBuffer(win
, &frag
, sizeof(frag
));
216 ok(rc
==MMSYSERR_NOERROR
,"waveInAddBuffer(%s): rc=%s\n",
217 dev_name(device
),wave_in_error(rc
));
219 /* Check that the position is 0 at start */
220 check_position(device
, win
, 0, pwfx
);
223 ok(rc
==MMSYSERR_NOERROR
,"waveInStart(%s): rc=%s\n",
224 dev_name(device
),wave_in_error(rc
));
226 res
= WaitForSingleObject(hevent
,1200);
227 ok(res
==WAIT_OBJECT_0
,"WaitForSingleObject failed for header\n");
228 ok(frag
.dwFlags
&WHDR_DONE
,"WHDR_DONE not set in frag.dwFlags\n");
229 ok(frag
.dwBytesRecorded
==pwfx
->nAvgBytesPerSec
,
230 "frag.dwBytesRecorded=%d, should=%d\n",
231 frag
.dwBytesRecorded
,pwfx
->nAvgBytesPerSec
);
233 mmt
.wType
= TIME_BYTES
;
234 rc
=waveInGetPosition(win
, &mmt
, sizeof(mmt
));
235 ok(rc
==MMSYSERR_NOERROR
,"waveInGetPosition(%s): rc=%s\n",
236 dev_name(device
),wave_in_error(rc
));
237 ok(mmt
.wType
== TIME_BYTES
, "doesn't support TIME_BYTES: %u\n", mmt
.wType
);
238 ok(mmt
.u
.cb
== frag
.dwBytesRecorded
, "Got wrong position: %u\n", mmt
.u
.cb
);
240 /* stop playing on error */
241 if (res
!=WAIT_OBJECT_0
) {
243 ok(rc
==MMSYSERR_NOERROR
,
244 "waveInStop(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
248 rc
=waveInUnprepareHeader(win
, &frag
, sizeof(frag
));
249 ok(rc
==MMSYSERR_NOERROR
,"waveInUnprepareHeader(%s): rc=%s\n",
250 dev_name(device
),wave_in_error(rc
));
253 ok(rc
==MMSYSERR_NOERROR
,
254 "waveInClose(%s): rc=%s\n",dev_name(device
),wave_in_error(rc
));
255 res
=WaitForSingleObject(hevent
,1000);
256 ok(res
==WAIT_OBJECT_0
,"WaitForSingleObject failed for close\n");
258 if (winetest_interactive
)
261 * Now play back what we recorded
265 trace("Playing back recorded sound\n");
266 rc
=waveOutOpen(&wout
,WAVE_MAPPER
,pwfx
,(DWORD_PTR
)hevent
,0,CALLBACK_EVENT
);
267 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_BADDEVICEID
||
268 rc
==MMSYSERR_NOTENABLED
|| rc
==MMSYSERR_NODRIVER
||
269 rc
==MMSYSERR_ALLOCATED
||
270 ((rc
==WAVERR_BADFORMAT
|| rc
==MMSYSERR_NOTSUPPORTED
) &&
271 !(pcaps
->dwFormats
& format
)),
272 "waveOutOpen(%s) format=%dx%2dx%d flags=CALLBACK_EVENT rc=%s\n",
273 dev_name(device
),pwfx
->nSamplesPerSec
,pwfx
->wBitsPerSample
,
274 pwfx
->nChannels
,wave_out_error(rc
));
275 if (rc
==MMSYSERR_NOERROR
)
277 rc
=waveOutPrepareHeader(wout
, &frag
, sizeof(frag
));
278 ok(rc
==MMSYSERR_NOERROR
,"waveOutPrepareHeader(%s): rc=%s\n",
279 dev_name(device
),wave_out_error(rc
));
281 if (rc
==MMSYSERR_NOERROR
)
283 WaitForSingleObject(hevent
,INFINITE
);
284 rc
=waveOutWrite(wout
, &frag
, sizeof(frag
));
285 ok(rc
==MMSYSERR_NOERROR
,"waveOutWrite(%s): rc=%s\n",
286 dev_name(device
),wave_out_error(rc
));
287 WaitForSingleObject(hevent
,INFINITE
);
289 rc
=waveOutUnprepareHeader(wout
, &frag
, sizeof(frag
));
290 ok(rc
==MMSYSERR_NOERROR
,"waveOutUnprepareHeader(%s): rc=%s\n",
291 dev_name(device
),wave_out_error(rc
));
293 rc
=waveOutClose(wout
);
294 ok(rc
==MMSYSERR_NOERROR
,"waveOutClose(%s): rc=%s\n",
295 dev_name(device
),wave_out_error(rc
));
298 trace("Unable to play back the recorded sound\n");
301 HeapFree(GetProcessHeap(), 0, frag
.lpData
);
305 static void wave_in_test_device(UINT_PTR device
)
310 WAVEFORMATEXTENSIBLE wfex
;
319 SYSTEM_INFO sSysInfo
;
323 GetSystemInfo(&sSysInfo
);
324 dwPageSize
= sSysInfo
.dwPageSize
;
326 rc
=waveInGetDevCapsA(device
,&capsA
,sizeof(capsA
));
327 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_BADDEVICEID
||
328 rc
==MMSYSERR_NODRIVER
,
329 "waveInGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
330 dev_name(device
),wave_in_error(rc
));
331 if (rc
==MMSYSERR_BADDEVICEID
|| rc
==MMSYSERR_NODRIVER
)
334 rc
=waveInGetDevCapsW(device
,&capsW
,sizeof(capsW
));
335 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_NOTSUPPORTED
,
336 "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
337 "expected, got %s\n",dev_name(device
),wave_in_error(rc
));
339 rc
=waveInGetDevCapsA(device
,NULL
,sizeof(capsA
));
340 ok(rc
==MMSYSERR_INVALPARAM
,
341 "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
342 dev_name(device
),wave_in_error(rc
));
344 rc
=waveInGetDevCapsW(device
,NULL
,sizeof(capsW
));
345 ok(rc
==MMSYSERR_INVALPARAM
|| rc
==MMSYSERR_NOTSUPPORTED
,
346 "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
347 "expected, got %s\n",dev_name(device
),wave_in_error(rc
));
351 /* FIXME: this works on windows but crashes wine */
352 rc
=waveInGetDevCapsA(device
,(LPWAVEINCAPSA
)1,sizeof(capsA
));
353 ok(rc
==MMSYSERR_INVALPARAM
,
354 "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
355 dev_name(device
),wave_in_error(rc
));
357 rc
=waveInGetDevCapsW(device
,(LPWAVEINCAPSW
)1,sizeof(capsW
));
358 ok(rc
==MMSYSERR_INVALPARAM
|| rc
==MMSYSERR_NOTSUPPORTED
,
359 "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
360 "expected, got %s\n",dev_name(device
),wave_in_error(rc
));
363 rc
=waveInGetDevCapsA(device
,&capsA
,4);
364 ok(rc
==MMSYSERR_NOERROR
,
365 "waveInGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
366 dev_name(device
),wave_in_error(rc
));
368 rc
=waveInGetDevCapsW(device
,&capsW
,4);
369 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_NOTSUPPORTED
||
370 rc
==MMSYSERR_INVALPARAM
, /* Vista, W2K8 */
371 "waveInGetDevCapsW(%s): unexpected return value %s\n",
372 dev_name(device
),wave_in_error(rc
));
375 rc
=waveInMessage((HWAVEIN
)device
, DRV_QUERYDEVICEINTERFACESIZE
,
376 (DWORD_PTR
)&size
, 0);
377 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_INVALPARAM
||
378 rc
==MMSYSERR_NOTSUPPORTED
,
379 "waveInMessage(%s): failed to get interface size: rc=%s\n",
380 dev_name(device
),wave_in_error(rc
));
381 if (rc
==MMSYSERR_NOERROR
) {
382 nameW
= HeapAlloc(GetProcessHeap(), 0, size
);
383 rc
=waveInMessage((HWAVEIN
)device
, DRV_QUERYDEVICEINTERFACE
,
384 (DWORD_PTR
)nameW
, size
);
385 ok(rc
==MMSYSERR_NOERROR
,"waveInMessage(%s): failed to get interface "
386 "name: rc=%s\n",dev_name(device
),wave_in_error(rc
));
387 ok(lstrlenW(nameW
)+1==size
/sizeof(WCHAR
),
388 "got an incorrect size %d\n", size
);
389 if (rc
==MMSYSERR_NOERROR
) {
390 nameA
= HeapAlloc(GetProcessHeap(), 0, size
/sizeof(WCHAR
));
391 WideCharToMultiByte(CP_ACP
, 0, nameW
, size
/sizeof(WCHAR
),
392 nameA
, size
/sizeof(WCHAR
), NULL
, NULL
);
394 HeapFree(GetProcessHeap(), 0, nameW
);
395 } else if (rc
==MMSYSERR_NOTSUPPORTED
) {
396 nameA
=HeapAlloc(GetProcessHeap(), 0, sizeof("not supported"));
397 strcpy(nameA
, "not supported");
400 trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device
),capsA
.szPname
,
401 (nameA
?nameA
:"failed"),capsA
.vDriverVersion
>> 8,
402 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
);
403 trace(" channels=%d formats=%05x\n",
404 capsA
.wChannels
,capsA
.dwFormats
);
406 HeapFree(GetProcessHeap(), 0, nameA
);
408 for (f
= 0; f
< ARRAY_SIZE(win_formats
); f
++) {
409 format
.wFormatTag
=WAVE_FORMAT_PCM
;
410 format
.nChannels
=win_formats
[f
][3];
411 format
.wBitsPerSample
=win_formats
[f
][2];
412 format
.nSamplesPerSec
=win_formats
[f
][1];
413 format
.nBlockAlign
=format
.nChannels
*format
.wBitsPerSample
/8;
414 format
.nAvgBytesPerSec
=format
.nSamplesPerSec
*format
.nBlockAlign
;
416 wave_in_test_deviceIn(device
,&format
,win_formats
[f
][0],0, &capsA
);
417 if (device
!= WAVE_MAPPER
) {
418 wave_in_test_deviceIn(device
,&format
,win_formats
[f
][0],
419 WAVE_FORMAT_DIRECT
, &capsA
);
420 wave_in_test_deviceIn(device
,&format
,win_formats
[f
][0],
421 WAVE_MAPPED
, &capsA
);
425 /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
427 twoPages
= VirtualAlloc(NULL
, 2 * dwPageSize
, MEM_RESERVE
| MEM_COMMIT
,
429 ok(twoPages
!=NULL
,"Failed to allocate 2 pages of memory\n");
431 res
= VirtualProtect(twoPages
+ dwPageSize
, dwPageSize
, PAGE_NOACCESS
,
433 ok(res
, "Failed to set memory access on second page\n");
435 LPWAVEFORMATEX pwfx
= (LPWAVEFORMATEX
)(twoPages
+ dwPageSize
-
436 sizeof(PCMWAVEFORMAT
));
437 pwfx
->wFormatTag
=WAVE_FORMAT_PCM
;
439 pwfx
->wBitsPerSample
=8;
440 pwfx
->nSamplesPerSec
=22050;
441 pwfx
->nBlockAlign
=pwfx
->nChannels
*pwfx
->wBitsPerSample
/8;
442 pwfx
->nAvgBytesPerSec
=pwfx
->nSamplesPerSec
*pwfx
->nBlockAlign
;
443 wave_in_test_deviceIn(device
,pwfx
,WAVE_FORMAT_2M08
,0, &capsA
);
444 if (device
!= WAVE_MAPPER
) {
445 wave_in_test_deviceIn(device
,pwfx
,WAVE_FORMAT_2M08
,
446 WAVE_FORMAT_DIRECT
, &capsA
);
447 wave_in_test_deviceIn(device
,pwfx
,WAVE_FORMAT_2M08
,
448 WAVE_MAPPED
, &capsA
);
451 VirtualFree(twoPages
, 2 * dwPageSize
, MEM_RELEASE
);
454 /* test non PCM formats */
455 format
.wFormatTag
=WAVE_FORMAT_MULAW
;
457 format
.wBitsPerSample
=8;
458 format
.nSamplesPerSec
=8000;
459 format
.nBlockAlign
=format
.nChannels
*format
.wBitsPerSample
/8;
460 format
.nAvgBytesPerSec
=format
.nSamplesPerSec
*format
.nBlockAlign
;
462 rc
=waveInOpen(&win
,device
,&format
,0,0,CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
463 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
464 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
465 rc
==MMSYSERR_ALLOCATED
,
466 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
467 if (rc
==MMSYSERR_NOERROR
) {
469 wave_in_test_deviceIn(device
,&format
,0,0,&capsA
);
471 trace("waveInOpen(%s): WAVE_FORMAT_MULAW not supported\n",
474 format
.wFormatTag
=WAVE_FORMAT_ADPCM
;
476 format
.wBitsPerSample
=4;
477 format
.nSamplesPerSec
=22050;
478 format
.nBlockAlign
=format
.nChannels
*format
.wBitsPerSample
/8;
479 format
.nAvgBytesPerSec
=format
.nSamplesPerSec
*format
.nBlockAlign
;
481 rc
=waveInOpen(&win
,device
,&format
,0,0,CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
482 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
483 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
484 rc
==MMSYSERR_ALLOCATED
,
485 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
486 if (rc
==MMSYSERR_NOERROR
) {
488 wave_in_test_deviceIn(device
,&format
,0,0,&capsA
);
490 trace("waveInOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
493 /* test if WAVEFORMATEXTENSIBLE supported */
494 wfex
.Format
.wFormatTag
=WAVE_FORMAT_EXTENSIBLE
;
495 wfex
.Format
.nChannels
=2;
496 wfex
.Format
.wBitsPerSample
=16;
497 wfex
.Format
.nSamplesPerSec
=22050;
498 wfex
.Format
.nBlockAlign
=wfex
.Format
.nChannels
*wfex
.Format
.wBitsPerSample
/8;
499 wfex
.Format
.nAvgBytesPerSec
=wfex
.Format
.nSamplesPerSec
*
500 wfex
.Format
.nBlockAlign
;
501 wfex
.Format
.cbSize
=22;
502 wfex
.Samples
.wValidBitsPerSample
=wfex
.Format
.wBitsPerSample
;
503 wfex
.dwChannelMask
=SPEAKER_ALL
;
504 wfex
.SubFormat
=KSDATAFORMAT_SUBTYPE_PCM
;
505 rc
=waveInOpen(&win
,device
,&wfex
.Format
,0,0,
506 CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
507 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
508 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
509 rc
==MMSYSERR_ALLOCATED
,
510 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
511 if (rc
==MMSYSERR_NOERROR
) {
513 wave_in_test_deviceIn(device
,&wfex
.Format
,0,0,&capsA
);
515 trace("waveInOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
518 /* test if 4 channels supported */
519 wfex
.Format
.wFormatTag
=WAVE_FORMAT_EXTENSIBLE
;
520 wfex
.Format
.nChannels
=4;
521 wfex
.Format
.wBitsPerSample
=16;
522 wfex
.Format
.nSamplesPerSec
=22050;
523 wfex
.Format
.nBlockAlign
=wfex
.Format
.nChannels
*wfex
.Format
.wBitsPerSample
/8;
524 wfex
.Format
.nAvgBytesPerSec
=wfex
.Format
.nSamplesPerSec
*
525 wfex
.Format
.nBlockAlign
;
526 wfex
.Format
.cbSize
=22;
527 wfex
.Samples
.wValidBitsPerSample
=wfex
.Format
.wBitsPerSample
;
528 wfex
.dwChannelMask
=SPEAKER_ALL
;
529 wfex
.SubFormat
=KSDATAFORMAT_SUBTYPE_PCM
;
530 rc
=waveInOpen(&win
,device
,&wfex
.Format
,0,0,
531 CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
532 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
533 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
534 rc
==MMSYSERR_ALLOCATED
,
535 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
536 if (rc
==MMSYSERR_NOERROR
) {
538 wave_in_test_deviceIn(device
,&wfex
.Format
,0,0,&capsA
);
540 trace("waveInOpen(%s): 4 channels not supported\n",
543 /* test if 6 channels supported */
544 wfex
.Format
.wFormatTag
=WAVE_FORMAT_EXTENSIBLE
;
545 wfex
.Format
.nChannels
=6;
546 wfex
.Format
.wBitsPerSample
=16;
547 wfex
.Format
.nSamplesPerSec
=22050;
548 wfex
.Format
.nBlockAlign
=wfex
.Format
.nChannels
*wfex
.Format
.wBitsPerSample
/8;
549 wfex
.Format
.nAvgBytesPerSec
=wfex
.Format
.nSamplesPerSec
*
550 wfex
.Format
.nBlockAlign
;
551 wfex
.Format
.cbSize
=22;
552 wfex
.Samples
.wValidBitsPerSample
=wfex
.Format
.wBitsPerSample
;
553 wfex
.dwChannelMask
=SPEAKER_ALL
;
554 wfex
.SubFormat
=KSDATAFORMAT_SUBTYPE_PCM
;
555 rc
=waveInOpen(&win
,device
,&wfex
.Format
,0,0,
556 CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
557 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
558 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
559 rc
==MMSYSERR_ALLOCATED
,
560 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
561 if (rc
==MMSYSERR_NOERROR
) {
563 wave_in_test_deviceIn(device
,&wfex
.Format
,0,0,&capsA
);
565 trace("waveInOpen(%s): 6 channels not supported\n",
570 /* FIXME: ALSA doesn't like this */
571 /* test if 24 bit samples supported */
572 wfex
.Format
.wFormatTag
=WAVE_FORMAT_EXTENSIBLE
;
573 wfex
.Format
.nChannels
=2;
574 wfex
.Format
.wBitsPerSample
=24;
575 wfex
.Format
.nSamplesPerSec
=22050;
576 wfex
.Format
.nBlockAlign
=wfex
.Format
.nChannels
*wfex
.Format
.wBitsPerSample
/8;
577 wfex
.Format
.nAvgBytesPerSec
=wfex
.Format
.nSamplesPerSec
*
578 wfex
.Format
.nBlockAlign
;
579 wfex
.Format
.cbSize
=22;
580 wfex
.Samples
.wValidBitsPerSample
=wfex
.Format
.wBitsPerSample
;
581 wfex
.dwChannelMask
=SPEAKER_ALL
;
582 wfex
.SubFormat
=KSDATAFORMAT_SUBTYPE_PCM
;
583 rc
=waveInOpen(&win
,device
,&wfex
.Format
,0,0,
584 CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
585 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
586 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
587 rc
==MMSYSERR_ALLOCATED
,
588 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
589 if (rc
==MMSYSERR_NOERROR
) {
591 wave_in_test_deviceIn(device
,&wfex
.Format
,0,0,&capsA
);
593 trace("waveInOpen(%s): 24 bit samples not supported\n",
597 /* test if 32 bit samples supported */
598 wfex
.Format
.wFormatTag
=WAVE_FORMAT_EXTENSIBLE
;
599 wfex
.Format
.nChannels
=2;
600 wfex
.Format
.wBitsPerSample
=32;
601 wfex
.Format
.nSamplesPerSec
=22050;
602 wfex
.Format
.nBlockAlign
=wfex
.Format
.nChannels
*wfex
.Format
.wBitsPerSample
/8;
603 wfex
.Format
.nAvgBytesPerSec
=wfex
.Format
.nSamplesPerSec
*
604 wfex
.Format
.nBlockAlign
;
605 wfex
.Format
.cbSize
=22;
606 wfex
.Samples
.wValidBitsPerSample
=wfex
.Format
.wBitsPerSample
;
607 wfex
.dwChannelMask
=SPEAKER_ALL
;
608 wfex
.SubFormat
=KSDATAFORMAT_SUBTYPE_PCM
;
609 rc
=waveInOpen(&win
,device
,&wfex
.Format
,0,0,
610 CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
611 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
612 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
613 rc
==MMSYSERR_ALLOCATED
,
614 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
615 if (rc
==MMSYSERR_NOERROR
) {
617 wave_in_test_deviceIn(device
,&wfex
.Format
,0,0,&capsA
);
619 trace("waveInOpen(%s): 32 bit samples not supported\n",
622 /* test if 32 bit float samples supported */
623 wfex
.Format
.wFormatTag
=WAVE_FORMAT_EXTENSIBLE
;
624 wfex
.Format
.nChannels
=2;
625 wfex
.Format
.wBitsPerSample
=32;
626 wfex
.Format
.nSamplesPerSec
=22050;
627 wfex
.Format
.nBlockAlign
=wfex
.Format
.nChannels
*wfex
.Format
.wBitsPerSample
/8;
628 wfex
.Format
.nAvgBytesPerSec
=wfex
.Format
.nSamplesPerSec
*
629 wfex
.Format
.nBlockAlign
;
630 wfex
.Format
.cbSize
=22;
631 wfex
.Samples
.wValidBitsPerSample
=wfex
.Format
.wBitsPerSample
;
632 wfex
.dwChannelMask
=SPEAKER_ALL
;
633 wfex
.SubFormat
=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
;
634 rc
=waveInOpen(&win
,device
,&wfex
.Format
,0,0,
635 CALLBACK_NULL
|WAVE_FORMAT_DIRECT
);
636 ok(rc
==MMSYSERR_NOERROR
|| rc
==WAVERR_BADFORMAT
||
637 rc
==MMSYSERR_INVALFLAG
|| rc
==MMSYSERR_INVALPARAM
||
638 rc
==MMSYSERR_ALLOCATED
,
639 "waveInOpen(%s): returned: %s\n",dev_name(device
),wave_in_error(rc
));
640 if (rc
==MMSYSERR_NOERROR
) {
642 wave_in_test_deviceIn(device
,&wfex
.Format
,0,0,&capsA
);
644 trace("waveInOpen(%s): 32 bit float samples not supported\n",
648 static void wave_in_tests(void)
655 DWORD preferred
, status
;
658 ndev
=waveInGetNumDevs();
659 trace("found %d WaveIn devices\n",ndev
);
661 rc
= waveInMessage((HWAVEIN
)WAVE_MAPPER
, DRVM_MAPPER_PREFERRED_GET
,
662 (DWORD_PTR
)&preferred
, (DWORD_PTR
)&status
);
663 ok((ndev
== 0 && (rc
== MMSYSERR_NODRIVER
|| rc
== MMSYSERR_BADDEVICEID
)) ||
664 rc
== MMSYSERR_NOTSUPPORTED
||
665 rc
== MMSYSERR_NOERROR
, "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc
);
667 if(rc
!= MMSYSERR_NOTSUPPORTED
)
668 ok((ndev
== 0 && (preferred
== -1 || broken(preferred
!= -1))) ||
669 preferred
< ndev
, "Got invalid preferred device: 0x%x\n", preferred
);
671 rc
= waveInMessage((HWAVEIN
)WAVE_MAPPER
, DRVM_MAPPER_PREFERRED_GET
,
673 ok(rc
== MMSYSERR_INVALPARAM
|| rc
== MMSYSERR_BADDEVICEID
, /* w2008+wvista */
674 "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc
);
676 rc
= waveInMessage((HWAVEIN
)WAVE_MAPPER
, DRVM_MAPPER_PREFERRED_GET
,
677 0, (DWORD_PTR
)&status
);
678 ok(rc
== MMSYSERR_INVALPARAM
|| rc
== MMSYSERR_BADDEVICEID
, /* w2008+wvista */
679 "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc
);
681 rc
=waveInGetDevCapsA(ndev
+1,&capsA
,sizeof(capsA
));
682 ok(rc
==MMSYSERR_BADDEVICEID
,
683 "waveInGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
684 dev_name(ndev
+1),wave_in_error(rc
));
686 rc
=waveInGetDevCapsA(WAVE_MAPPER
,&capsA
,sizeof(capsA
));
687 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_NODRIVER
|| (!ndev
&& (rc
==MMSYSERR_BADDEVICEID
)),
688 "waveInGetDevCapsA(%s): got %s\n",dev_name(WAVE_MAPPER
),wave_in_error(rc
));
690 rc
=waveInGetDevCapsW(ndev
+1,&capsW
,sizeof(capsW
));
691 ok(rc
==MMSYSERR_BADDEVICEID
|| rc
==MMSYSERR_NOTSUPPORTED
,
692 "waveInGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
693 "expected, got %s\n",dev_name(ndev
+1),wave_in_error(rc
));
695 rc
=waveInGetDevCapsW(WAVE_MAPPER
,&capsW
,sizeof(capsW
));
696 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_NODRIVER
||
697 rc
==MMSYSERR_NOTSUPPORTED
|| (!ndev
&& (rc
==MMSYSERR_BADDEVICEID
)),
698 "waveInGetDevCapsW(%s): got %s\n", dev_name(ndev
+1),wave_in_error(rc
));
700 format
.wFormatTag
=WAVE_FORMAT_PCM
;
702 format
.wBitsPerSample
=16;
703 format
.nSamplesPerSec
=44100;
704 format
.nBlockAlign
=format
.nChannels
*format
.wBitsPerSample
/8;
705 format
.nAvgBytesPerSec
=format
.nSamplesPerSec
*format
.nBlockAlign
;
707 rc
=waveInOpen(&win
,ndev
+1,&format
,0,0,CALLBACK_NULL
);
708 ok(rc
==MMSYSERR_BADDEVICEID
,
709 "waveInOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
710 dev_name(ndev
+1),wave_in_error(rc
));
713 wave_in_test_device(d
);
716 wave_in_test_device(WAVE_MAPPER
);