ReactOS  0.4.13-dev-235-g7373cb3
capture.c
Go to the documentation of this file.
1 /*
2  * Test winmm sound capture in each sound format
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "mmddk.h"
31 #include "mmsystem.h"
32 #define NOBITMAP
33 #include "mmreg.h"
34 
37 
38 #include "winmm_test.h"
39 
40 static const char * wave_in_error(MMRESULT error)
41 {
42  static char msg[1024];
43  static char long_msg[1100];
44  MMRESULT rc;
45 
46  rc = waveInGetErrorTextA(error, msg, sizeof(msg));
47  if (rc != MMSYSERR_NOERROR)
48  sprintf(long_msg, "waveInGetErrorTextA(%x) failed with error %x", error, rc);
49  else
50  sprintf(long_msg, "%s(%s)", mmsys_error(error), msg);
51  return long_msg;
52 }
53 
54 static void check_position(int device, HWAVEIN win, DWORD bytes,
55  LPWAVEFORMATEX pwfx )
56 {
57  MMTIME mmtime;
58  MMRESULT rc;
59  DWORD returned;
60 
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  if (mmtime.wType != TIME_BYTES && winetest_debug > 1)
66  trace("waveInGetPosition(%s): TIME_BYTES not supported, returned %s\n",
68  returned = time_to_bytes(&mmtime, pwfx);
69  ok(returned == bytes, "waveInGetPosition(%s): returned %d bytes, "
70  "should be %d\n", dev_name(device), returned, bytes);
71 
72  mmtime.wType = TIME_SAMPLES;
73  rc=waveInGetPosition(win, &mmtime, sizeof(mmtime));
74  ok(rc==MMSYSERR_NOERROR,
75  "waveInGetPosition(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
76  if (mmtime.wType != TIME_SAMPLES && winetest_debug > 1)
77  trace("waveInGetPosition(%s): TIME_SAMPLES not supported, "
78  "returned %s\n",dev_name(device),wave_time_format(mmtime.wType));
79  returned = time_to_bytes(&mmtime, pwfx);
80  ok(returned == bytes, "waveInGetPosition(%s): returned %d samples, "
81  "should be %d\n", dev_name(device), bytes_to_samples(returned, pwfx),
82  bytes_to_samples(bytes, pwfx));
83 
84  mmtime.wType = TIME_MS;
85  rc=waveInGetPosition(win, &mmtime, sizeof(mmtime));
86  ok(rc==MMSYSERR_NOERROR,
87  "waveInGetPosition(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
88  if (mmtime.wType != TIME_MS && winetest_debug > 1)
89  trace("waveInGetPosition(%s): TIME_MS not supported, returned %s\n",
91  returned = time_to_bytes(&mmtime, pwfx);
92  ok(returned == bytes, "waveInGetPosition(%s): returned %d ms, "
93  "should be %d\n", dev_name(device), bytes_to_ms(returned, pwfx),
94  bytes_to_ms(bytes, pwfx));
95 
96  mmtime.wType = TIME_SMPTE;
97  rc=waveInGetPosition(win, &mmtime, sizeof(mmtime));
98  ok(rc==MMSYSERR_NOERROR,
99  "waveInGetPosition(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
100  if (mmtime.wType != TIME_SMPTE && winetest_debug > 1)
101  trace("waveInGetPosition(%s): TIME_SMPTE not supported, returned %s\n",
103  returned = time_to_bytes(&mmtime, pwfx);
104  ok(returned == bytes, "waveInGetPosition(%s): SMPTE test failed\n",
105  dev_name(device));
106 
107  mmtime.wType = TIME_MIDI;
108  rc=waveInGetPosition(win, &mmtime, sizeof(mmtime));
109  ok(rc==MMSYSERR_NOERROR,
110  "waveInGetPosition(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
111  if (mmtime.wType != TIME_MIDI && winetest_debug > 1)
112  trace("waveInGetPosition(%s): TIME_MIDI not supported, returned %s\n",
114  returned = time_to_bytes(&mmtime, pwfx);
115  ok(returned == bytes, "waveInGetPosition(%s): MIDI test failed\n",
116  dev_name(device));
117 
118  mmtime.wType = TIME_TICKS;
119  rc=waveInGetPosition(win, &mmtime, sizeof(mmtime));
120  ok(rc==MMSYSERR_NOERROR,
121  "waveInGetPosition(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
122  if (mmtime.wType != TIME_TICKS && winetest_debug > 1)
123  trace("waveInGetPosition(%s): TIME_TICKS not supported, returned %s\n",
125  returned = time_to_bytes(&mmtime, pwfx);
126  ok(returned == bytes, "waveInGetPosition(%s): TICKS test failed\n",
127  dev_name(device));
128 }
129 
131  WAVEINCAPSA *pcaps)
132 {
133  HWAVEIN win;
135  WAVEHDR frag;
136  MMRESULT rc;
137  DWORD res;
138  MMTIME mmt;
139  WORD nChannels = pwfx->nChannels;
140  WORD wBitsPerSample = pwfx->wBitsPerSample;
141  DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
142 
143  win=NULL;
145  /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
148  rc==MMSYSERR_ALLOCATED ||
149  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
150  (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
151  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
152  (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
153  !(pcaps->dwFormats & format)) ||
155  "waveInOpen(%s): format=%dx%2dx%d flags=%x(%s) rc=%s\n",
159  if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
160  (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
161  trace(" Reason: The device lists this format as supported in its "
162  "capabilities but opening it failed.\n");
163  if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
164  !(pcaps->dwFormats & format))
165  trace("waveInOpen(%s): format=%dx%2dx%d %s rc=%s failed but format "
166  "not supported so OK.\n",dev_name(device),pwfx->nSamplesPerSec,
167  pwfx->wBitsPerSample,pwfx->nChannels,
168  flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
169  flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
170  if (rc!=MMSYSERR_NOERROR) {
172  return;
173  }
175  ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for open\n");
176 
177  ok(pwfx->nChannels==nChannels &&
178  pwfx->wBitsPerSample==wBitsPerSample &&
179  pwfx->nSamplesPerSec==nSamplesPerSec,
180  "got the wrong format: %dx%2dx%d instead of %dx%2dx%d\n",
181  pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
182  pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
183 
184  /* Check that the position is 0 at start */
185  check_position(device, win, 0, pwfx);
186 
188  frag.dwBufferLength=pwfx->nAvgBytesPerSec;
189  frag.dwBytesRecorded=0;
190  frag.dwUser=0;
191  frag.dwFlags=0;
192  frag.dwLoops=0;
193  frag.lpNext=0;
194 
195  rc=waveInPrepareHeader(win, &frag, sizeof(frag));
196  ok(rc==MMSYSERR_NOERROR, "waveInPrepareHeader(%s): rc=%s\n",
198  ok(frag.dwFlags&WHDR_PREPARED,"waveInPrepareHeader(%s): prepared flag "
199  "not set\n",dev_name(device));
200 
202  trace("Recording for 1 second at %5dx%2dx%d %s %s\n",
203  pwfx->nSamplesPerSec, pwfx->wBitsPerSample,pwfx->nChannels,
204  get_format_str(pwfx->wFormatTag),
205  flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
206  flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
207  rc=waveInAddBuffer(win, &frag, sizeof(frag));
208  ok(rc==MMSYSERR_NOERROR,"waveInAddBuffer(%s): rc=%s\n",
210 
211  /* Check that the position is 0 at start */
212  check_position(device, win, 0, pwfx);
213 
214  rc=waveInStart(win);
215  ok(rc==MMSYSERR_NOERROR,"waveInStart(%s): rc=%s\n",
217 
219  ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for header\n");
220  ok(frag.dwFlags&WHDR_DONE,"WHDR_DONE not set in frag.dwFlags\n");
221  ok(frag.dwBytesRecorded==pwfx->nAvgBytesPerSec,
222  "frag.dwBytesRecorded=%d, should=%d\n",
223  frag.dwBytesRecorded,pwfx->nAvgBytesPerSec);
224 
225  mmt.wType = TIME_BYTES;
226  rc=waveInGetPosition(win, &mmt, sizeof(mmt));
227  ok(rc==MMSYSERR_NOERROR,"waveInGetPosition(%s): rc=%s\n",
229  ok(mmt.wType == TIME_BYTES, "doesn't support TIME_BYTES: %u\n", mmt.wType);
230  ok(mmt.u.cb == frag.dwBytesRecorded, "Got wrong position: %u\n", mmt.u.cb);
231 
232  /* stop playing on error */
233  if (res!=WAIT_OBJECT_0) {
234  rc=waveInStop(win);
235  ok(rc==MMSYSERR_NOERROR,
236  "waveInStop(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
237  }
238  }
239 
240  rc=waveInUnprepareHeader(win, &frag, sizeof(frag));
241  ok(rc==MMSYSERR_NOERROR,"waveInUnprepareHeader(%s): rc=%s\n",
243 
244  rc=waveInClose(win);
245  ok(rc==MMSYSERR_NOERROR,
246  "waveInClose(%s): rc=%s\n",dev_name(device),wave_in_error(rc));
248  ok(res==WAIT_OBJECT_0,"WaitForSingleObject failed for close\n");
249 
251  {
252  /*
253  * Now play back what we recorded
254  */
255  HWAVEOUT wout;
256 
257  trace("Playing back recorded sound\n");
261  rc==MMSYSERR_ALLOCATED ||
262  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
263  !(pcaps->dwFormats & format)),
264  "waveOutOpen(%s) format=%dx%2dx%d flags=%x(%s) rc=%s\n",
268  if (rc==MMSYSERR_NOERROR)
269  {
270  rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
271  ok(rc==MMSYSERR_NOERROR,"waveOutPrepareHeader(%s): rc=%s\n",
273 
274  if (rc==MMSYSERR_NOERROR)
275  {
277  rc=waveOutWrite(wout, &frag, sizeof(frag));
278  ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
281 
282  rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
283  ok(rc==MMSYSERR_NOERROR,"waveOutUnprepareHeader(%s): rc=%s\n",
285  }
286  rc=waveOutClose(wout);
287  ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",
289  }
290  else
291  trace("Unable to play back the recorded sound\n");
292  }
293 
294  HeapFree(GetProcessHeap(), 0, frag.lpData);
296 }
297 
299 {
300  WAVEINCAPSA capsA;
301  WAVEINCAPSW capsW;
304  HWAVEIN win;
305  MMRESULT rc;
306  UINT f;
307  WCHAR * nameW;
308  CHAR * nameA;
309  DWORD size;
310  DWORD dwPageSize;
311  BYTE * twoPages;
312  SYSTEM_INFO sSysInfo;
313  DWORD flOldProtect;
314  BOOL res;
315 
316  GetSystemInfo(&sSysInfo);
317  dwPageSize = sSysInfo.dwPageSize;
318 
319  rc=waveInGetDevCapsA(device,&capsA,sizeof(capsA));
321  rc==MMSYSERR_NODRIVER,
322  "waveInGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
325  return;
326 
327  rc=waveInGetDevCapsW(device,&capsW,sizeof(capsW));
329  "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
330  "expected, got %s\n",dev_name(device),wave_in_error(rc));
331 
332  rc=waveInGetDevCapsA(device,NULL,sizeof(capsA));
334  "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
336 
337  rc=waveInGetDevCapsW(device,NULL,sizeof(capsW));
339  "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
340  "expected, got %s\n",dev_name(device),wave_in_error(rc));
341 
342  if (0)
343  {
344  /* FIXME: this works on windows but crashes wine */
345  rc=waveInGetDevCapsA(device,(LPWAVEINCAPSA)1,sizeof(capsA));
347  "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
349 
350  rc=waveInGetDevCapsW(device,(LPWAVEINCAPSW)1,sizeof(capsW));
352  "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
353  "expected, got %s\n",dev_name(device),wave_in_error(rc));
354  }
355 
356  rc=waveInGetDevCapsA(device,&capsA,4);
357  ok(rc==MMSYSERR_NOERROR,
358  "waveInGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
360 
361  rc=waveInGetDevCapsW(device,&capsW,4);
363  rc==MMSYSERR_INVALPARAM, /* Vista, W2K8 */
364  "waveInGetDevCapsW(%s): unexpected return value %s\n",
366 
367  nameA=NULL;
369  (DWORD_PTR)&size, 0);
372  "waveInMessage(%s): failed to get interface size: rc=%s\n",
374  if (rc==MMSYSERR_NOERROR) {
377  (DWORD_PTR)nameW, size);
378  ok(rc==MMSYSERR_NOERROR,"waveInMessage(%s): failed to get interface "
379  "name: rc=%s\n",dev_name(device),wave_in_error(rc));
380  ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),
381  "got an incorrect size %d\n", size);
382  if (rc==MMSYSERR_NOERROR) {
383  nameA = HeapAlloc(GetProcessHeap(), 0, size/sizeof(WCHAR));
385  nameA, size/sizeof(WCHAR), NULL, NULL);
386  }
388  } else if (rc==MMSYSERR_NOTSUPPORTED) {
389  nameA=HeapAlloc(GetProcessHeap(), 0, sizeof("not supported"));
390  strcpy(nameA, "not supported");
391  }
392 
393  trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
394  (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
395  capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid);
396  trace(" channels=%d formats=%05x\n",
397  capsA.wChannels,capsA.dwFormats);
398 
399  HeapFree(GetProcessHeap(), 0, nameA);
400 
401  for (f=0;f<NB_WIN_FORMATS;f++) {
402  format.wFormatTag=WAVE_FORMAT_PCM;
403  format.nChannels=win_formats[f][3];
404  format.wBitsPerSample=win_formats[f][2];
405  format.nSamplesPerSec=win_formats[f][1];
406  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
407  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
408  format.cbSize=0;
410  if (device != WAVE_MAPPER) {
412  WAVE_FORMAT_DIRECT, &capsA);
414  WAVE_MAPPED, &capsA);
415  }
416  }
417 
418  /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
419  * checking */
420  twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
422  ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
423  if (twoPages) {
424  res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
425  &flOldProtect);
426  ok(res, "Failed to set memory access on second page\n");
427  if (res) {
428  LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
429  sizeof(PCMWAVEFORMAT));
431  pwfx->nChannels=1;
432  pwfx->wBitsPerSample=8;
433  pwfx->nSamplesPerSec=22050;
434  pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
435  pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
437  if (device != WAVE_MAPPER) {
439  WAVE_FORMAT_DIRECT, &capsA);
441  WAVE_MAPPED, &capsA);
442  }
443  }
444  VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
445  }
446 
447  /* test non PCM formats */
448  format.wFormatTag=WAVE_FORMAT_MULAW;
449  format.nChannels=1;
450  format.wBitsPerSample=8;
451  format.nSamplesPerSec=8000;
452  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
453  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
454  format.cbSize=0;
456  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
458  rc==MMSYSERR_ALLOCATED,
459  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
460  if (rc==MMSYSERR_NOERROR) {
461  waveInClose(win);
462  wave_in_test_deviceIn(device,&format,0,0,&capsA);
463  } else
464  trace("waveInOpen(%s): WAVE_FORMAT_MULAW not supported\n",
465  dev_name(device));
466 
467  format.wFormatTag=WAVE_FORMAT_ADPCM;
468  format.nChannels=2;
469  format.wBitsPerSample=4;
470  format.nSamplesPerSec=22050;
471  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
472  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
473  format.cbSize=0;
475  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
477  rc==MMSYSERR_ALLOCATED,
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,&format,0,0,&capsA);
482  } else
483  trace("waveInOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
484  dev_name(device));
485 
486  /* test if WAVEFORMATEXTENSIBLE supported */
488  wfex.Format.nChannels=2;
489  wfex.Format.wBitsPerSample=16;
490  wfex.Format.nSamplesPerSec=22050;
493  wfex.Format.nBlockAlign;
494  wfex.Format.cbSize=22;
498  rc=waveInOpen(&win,device,&wfex.Format,0,0,
500  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
502  rc==MMSYSERR_ALLOCATED,
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): WAVE_FORMAT_EXTENSIBLE not supported\n",
509  dev_name(device));
510 
511  /* test if 4 channels supported */
513  wfex.Format.nChannels=4;
514  wfex.Format.wBitsPerSample=16;
515  wfex.Format.nSamplesPerSec=22050;
518  wfex.Format.nBlockAlign;
519  wfex.Format.cbSize=22;
523  rc=waveInOpen(&win,device,&wfex.Format,0,0,
525  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
527  rc==MMSYSERR_ALLOCATED,
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): 4 channels not supported\n",
534  dev_name(device));
535 
536  /* test if 6 channels supported */
538  wfex.Format.nChannels=6;
539  wfex.Format.wBitsPerSample=16;
540  wfex.Format.nSamplesPerSec=22050;
543  wfex.Format.nBlockAlign;
544  wfex.Format.cbSize=22;
548  rc=waveInOpen(&win,device,&wfex.Format,0,0,
550  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
552  rc==MMSYSERR_ALLOCATED,
553  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
554  if (rc==MMSYSERR_NOERROR) {
555  waveInClose(win);
556  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
557  } else
558  trace("waveInOpen(%s): 6 channels not supported\n",
559  dev_name(device));
560 
561  if (0)
562  {
563  /* FIXME: ALSA doesn't like this */
564  /* test if 24 bit samples supported */
566  wfex.Format.nChannels=2;
567  wfex.Format.wBitsPerSample=24;
568  wfex.Format.nSamplesPerSec=22050;
571  wfex.Format.nBlockAlign;
572  wfex.Format.cbSize=22;
576  rc=waveInOpen(&win,device,&wfex.Format,0,0,
578  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
580  rc==MMSYSERR_ALLOCATED,
581  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
582  if (rc==MMSYSERR_NOERROR) {
583  waveInClose(win);
584  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
585  } else
586  trace("waveInOpen(%s): 24 bit samples not supported\n",
587  dev_name(device));
588  }
589 
590  /* test if 32 bit samples supported */
592  wfex.Format.nChannels=2;
593  wfex.Format.wBitsPerSample=32;
594  wfex.Format.nSamplesPerSec=22050;
597  wfex.Format.nBlockAlign;
598  wfex.Format.cbSize=22;
602  rc=waveInOpen(&win,device,&wfex.Format,0,0,
604  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
606  rc==MMSYSERR_ALLOCATED,
607  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
608  if (rc==MMSYSERR_NOERROR) {
609  waveInClose(win);
610  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
611  } else
612  trace("waveInOpen(%s): 32 bit samples not supported\n",
613  dev_name(device));
614 
615  /* test if 32 bit float samples supported */
617  wfex.Format.nChannels=2;
618  wfex.Format.wBitsPerSample=32;
619  wfex.Format.nSamplesPerSec=22050;
622  wfex.Format.nBlockAlign;
623  wfex.Format.cbSize=22;
627  rc=waveInOpen(&win,device,&wfex.Format,0,0,
629  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
631  rc==MMSYSERR_ALLOCATED,
632  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
633  if (rc==MMSYSERR_NOERROR) {
634  waveInClose(win);
635  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
636  } else
637  trace("waveInOpen(%s): 32 bit float samples not supported\n",
638  dev_name(device));
639 }
640 
641 static void wave_in_tests(void)
642 {
643  WAVEINCAPSA capsA;
644  WAVEINCAPSW capsW;
646  HWAVEIN win;
647  MMRESULT rc;
648  DWORD preferred, status;
649  UINT ndev,d;
650 
651  ndev=waveInGetNumDevs();
652  trace("found %d WaveIn devices\n",ndev);
653 
655  (DWORD_PTR)&preferred, (DWORD_PTR)&status);
656  ok((ndev == 0 && (rc == MMSYSERR_NODRIVER || rc == MMSYSERR_BADDEVICEID)) ||
657  rc == MMSYSERR_NOTSUPPORTED ||
658  rc == MMSYSERR_NOERROR, "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc);
659 
660  if(rc != MMSYSERR_NOTSUPPORTED)
661  ok((ndev == 0 && (preferred == -1 || broken(preferred != -1))) ||
662  preferred < ndev, "Got invalid preferred device: 0x%x\n", preferred);
663 
664  rc=waveInGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
666  "waveInGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
667  dev_name(ndev+1),wave_in_error(rc));
668 
669  rc=waveInGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
670  ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NODRIVER || (!ndev && (rc==MMSYSERR_BADDEVICEID)),
671  "waveInGetDevCapsA(%s): got %s\n",dev_name(WAVE_MAPPER),wave_in_error(rc));
672 
673  rc=waveInGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
675  "waveInGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
676  "expected, got %s\n",dev_name(ndev+1),wave_in_error(rc));
677 
678  rc=waveInGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
680  rc==MMSYSERR_NOTSUPPORTED || (!ndev && (rc==MMSYSERR_BADDEVICEID)),
681  "waveInGetDevCapsW(%s): got %s\n", dev_name(ndev+1),wave_in_error(rc));
682 
683  format.wFormatTag=WAVE_FORMAT_PCM;
684  format.nChannels=2;
685  format.wBitsPerSample=16;
686  format.nSamplesPerSec=44100;
687  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
688  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
689  format.cbSize=0;
690  rc=waveInOpen(&win,ndev+1,&format,0,0,CALLBACK_NULL);
692  "waveInOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
693  dev_name(ndev+1),wave_in_error(rc));
694 
695  for (d=0;d<ndev;d++)
697 
698  if (ndev>0)
700 }
701 
702 START_TEST(capture)
703 {
704  wave_in_tests();
705 }
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176
static void wave_in_test_deviceIn(int device, WAVEFORMATEX *pwfx, DWORD format, DWORD flags, WAVEINCAPSA *pcaps)
Definition: capture.c:130
union WAVEFORMATEXTENSIBLE::@2888 Samples
#define trace(...)
Definition: kmt_test.h:217
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2637
#define CloseHandle
Definition: compat.h:398
const char * wave_out_error(MMRESULT error)
Definition: wave.c:270
#define WideCharToMultiByte
Definition: compat.h:101
#define DRVM_MAPPER_PREFERRED_GET
Definition: mmsys.h:37
#define error(str)
Definition: mkdosfs.c:1605
MMRESULT WINAPI waveInOpen(HWAVEIN *lphWaveIn, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2626
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1050
#define CP_ACP
Definition: compat.h:99
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD cb
Definition: mmsystem.h:969
UINT wType
Definition: mmsystem.h:965
char CHAR
Definition: xmlstorage.h:175
WORD nChannels
Definition: mmreg.h:79
static const unsigned int win_formats[][4]
Definition: render.c:47
#define SPEAKER_ALL
Definition: ksmedia.h:1345
const char * dev_name(int device)
Definition: wave.c:211
UINT MMRESULT
Definition: mmsystem.h:962
#define DRV_QUERYDEVICEINTERFACESIZE
Definition: mmddk.h:97
static void check_position(int device, HWAVEIN win, DWORD bytes, LPWAVEFORMATEX pwfx)
Definition: capture.c:54
LPSTR lpData
Definition: mmsystem.h:1014
union mmtime_tag::@2901 u
int winetest_interactive
GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
int nChannels
Definition: pcmconverter.c:96
#define lstrlenW
Definition: compat.h:407
#define MEM_COMMIT
Definition: nt_native.h:1313
int winetest_debug
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2656
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
UINT WINAPI waveInMessage(HWAVEIN hWaveIn, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2816
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
#define TIME_SAMPLES
Definition: mmsystem.h:29
static const char * wave_in_error(MMRESULT error)
Definition: capture.c:40
#define WAVE_FORMAT_DIRECT
Definition: mmsystem.h:191
UINT WINAPI waveInGetDevCapsW(UINT_PTR uDeviceID, LPWAVEINCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2576
DWORD dwLoops
Definition: mmsystem.h:1019
static void wave_in_test_device(UINT_PTR device)
Definition: capture.c:298
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define CALLBACK_EVENT
Definition: mmsystem.h:152
static HANDLE hevent
Definition: broadcast.c:38
#define WAVE_FORMAT_PCM
Definition: constants.h:425
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:74
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
DWORD dwFlags
Definition: mmsystem.h:1018
#define WAVE_FORMAT_2M08
Definition: mmsystem.h:210
#define WAVE_FORMAT_MULAW
Definition: constants.h:428
#define MEM_RESERVE
Definition: nt_native.h:1314
WORD wBitsPerSample
Definition: audioclient.idl:45
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2687
#define ok(value,...)
struct _WAVEFORMATEX * LPWAVEFORMATEX
const char * wave_open_flags(DWORD flags)
Definition: wave.c:284
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:416
GUID KSDATAFORMAT_SUBTYPE_PCM
Definition: audio_test.c:26
DWORD nSamplesPerSec
Definition: audioclient.idl:42
static const WCHAR nameW[]
Definition: main.c:46
GLfloat f
Definition: glext.h:7540
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define d
Definition: ke_i.h:81
DWORD bytes_to_ms(DWORD bytes, LPWAVEFORMATEX pwfx)
Definition: wave.c:466
__wchar_t WCHAR
Definition: xmlstorage.h:180
WAVEFORMATEX Format
Definition: ksmedia.h:538
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
#define TIME_MS
Definition: mmsystem.h:28
DWORD dwFormats
Definition: mmsystem.h:1051
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL NTAPI VirtualProtect(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:144
#define MMSYSERR_INVALFLAG
Definition: mmsystem.h:106
MMRESULT WINAPI waveInGetErrorTextA(_In_ MMRESULT mmrError, _Out_writes_(cchText) LPSTR pszText, _In_ UINT cchText)
#define NB_WIN_FORMATS
Definition: winmm_test.h:71
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MMSYSERR_NOTENABLED
Definition: mmsystem.h:99
GLbitfield flags
Definition: glext.h:7161
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2344
WORD wFormatTag
Definition: mmreg.h:78
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2720
#define TIME_SMPTE
Definition: mmsystem.h:31
DWORD dwBufferLength
Definition: mmsystem.h:1015
unsigned char BYTE
Definition: mem.h:68
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
uint32_t DWORD_PTR
Definition: typedefs.h:63
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define WAVE_FORMAT_ADPCM
Definition: constants.h:426
#define broken(x)
Definition: _sntprintf.h:21
struct wavehdr_tag * lpNext
Definition: mmsystem.h:1020
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2752
static const char * get_format_str(WORD format)
Definition: capture.c:31
UINT WINAPI waveInGetPosition(HWAVEIN hWaveIn, LPMMTIME lpTime, UINT uSize)
Definition: winmm.c:2782
WORD wValidBitsPerSample
Definition: ksmedia.h:541
DWORD dwPageSize
Definition: winbase.h:1126
#define CALLBACK_NULL
Definition: mmsystem.h:147
static real win[4][36]
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
Definition: winmm.c:2767
#define TIME_TICKS
Definition: mmsystem.h:33
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define f
Definition: ke_i.h:83
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
const char * wave_time_format(UINT type)
Definition: wave.c:391
#define WAVE_MAPPED
Definition: mmsystem.h:190
#define TIME_BYTES
Definition: mmsystem.h:30
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:142
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
unsigned int UINT
Definition: ndis.h:50
MMVERSION vDriverVersion
Definition: mmsystem.h:1049
#define WHDR_PREPARED
Definition: mmsystem.h:194
DWORD_PTR dwUser
Definition: mmsystem.h:1017
DWORD nSamplesPerSec
Definition: mmreg.h:80
#define msg(x)
Definition: auth_time.c:54
WORD nBlockAlign
Definition: mmreg.h:82
UINT WINAPI waveInGetDevCapsA(UINT_PTR uDeviceID, LPWAVEINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:2600
#define MEM_RELEASE
Definition: nt_native.h:1316
GLuint res
Definition: glext.h:9613
WORD wBitsPerSample
Definition: mmreg.h:83
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define WHDR_DONE
Definition: mmsystem.h:193
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2568
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:128
#define TIME_MIDI
Definition: mmsystem.h:32
#define bytes_to_samples
Definition: intsym.h:218
#define INFINITE
Definition: serial.h:102
static SERVICE_STATUS status
Definition: service.c:31
#define DRV_QUERYDEVICEINTERFACE
Definition: mmddk.h:96
#define HeapFree(x, y, z)
Definition: compat.h:394
DWORD time_to_bytes(LPMMTIME mmtime, LPWAVEFORMATEX pwfx)
Definition: wave.c:471
START_TEST(capture)
Definition: capture.c:749
DWORD dwBytesRecorded
Definition: mmsystem.h:1016
#define WAVE_FORMAT_EXTENSIBLE
Definition: ksmedia.h:551
#define PAGE_READWRITE
Definition: nt_native.h:1304
Definition: ps.c:97
static void wave_in_tests(void)
Definition: capture.c:641