ReactOS  0.4.15-dev-1201-gb2cf5a4
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  rc=waveInOpen(&win,device,pwfx,(DWORD_PTR)hevent,0,flags);
146  /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
149  rc==MMSYSERR_ALLOCATED ||
150  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
151  (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
152  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
153  (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
154  !(pcaps->dwFormats & format)) ||
156  "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=CALLBACK_EVENT rc=%s\n",
266  pwfx->nChannels,wave_out_error(rc));
267  if (rc==MMSYSERR_NOERROR)
268  {
269  rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
270  ok(rc==MMSYSERR_NOERROR,"waveOutPrepareHeader(%s): rc=%s\n",
272 
273  if (rc==MMSYSERR_NOERROR)
274  {
276  rc=waveOutWrite(wout, &frag, sizeof(frag));
277  ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
280 
281  rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
282  ok(rc==MMSYSERR_NOERROR,"waveOutUnprepareHeader(%s): rc=%s\n",
284  }
285  rc=waveOutClose(wout);
286  ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",
288  }
289  else
290  trace("Unable to play back the recorded sound\n");
291  }
292 
293  HeapFree(GetProcessHeap(), 0, frag.lpData);
295 }
296 
298 {
299  WAVEINCAPSA capsA;
300  WAVEINCAPSW capsW;
303  HWAVEIN win;
304  MMRESULT rc;
305  UINT f;
306  WCHAR * nameW;
307  CHAR * nameA;
308  DWORD size;
309  DWORD dwPageSize;
310  BYTE * twoPages;
311  SYSTEM_INFO sSysInfo;
312  DWORD flOldProtect;
313  BOOL res;
314 
315  GetSystemInfo(&sSysInfo);
316  dwPageSize = sSysInfo.dwPageSize;
317 
318  rc=waveInGetDevCapsA(device,&capsA,sizeof(capsA));
320  rc==MMSYSERR_NODRIVER,
321  "waveInGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
324  return;
325 
326  rc=waveInGetDevCapsW(device,&capsW,sizeof(capsW));
328  "waveInGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
329  "expected, got %s\n",dev_name(device),wave_in_error(rc));
330 
331  rc=waveInGetDevCapsA(device,NULL,sizeof(capsA));
333  "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
335 
336  rc=waveInGetDevCapsW(device,NULL,sizeof(capsW));
338  "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
339  "expected, got %s\n",dev_name(device),wave_in_error(rc));
340 
341  if (0)
342  {
343  /* FIXME: this works on windows but crashes wine */
344  rc=waveInGetDevCapsA(device,(LPWAVEINCAPSA)1,sizeof(capsA));
346  "waveInGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
348 
349  rc=waveInGetDevCapsW(device,(LPWAVEINCAPSW)1,sizeof(capsW));
351  "waveInGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
352  "expected, got %s\n",dev_name(device),wave_in_error(rc));
353  }
354 
355  rc=waveInGetDevCapsA(device,&capsA,4);
356  ok(rc==MMSYSERR_NOERROR,
357  "waveInGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
359 
360  rc=waveInGetDevCapsW(device,&capsW,4);
362  rc==MMSYSERR_INVALPARAM, /* Vista, W2K8 */
363  "waveInGetDevCapsW(%s): unexpected return value %s\n",
365 
366  nameA=NULL;
368  (DWORD_PTR)&size, 0);
371  "waveInMessage(%s): failed to get interface size: rc=%s\n",
373  if (rc==MMSYSERR_NOERROR) {
376  (DWORD_PTR)nameW, size);
377  ok(rc==MMSYSERR_NOERROR,"waveInMessage(%s): failed to get interface "
378  "name: rc=%s\n",dev_name(device),wave_in_error(rc));
379  ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),
380  "got an incorrect size %d\n", size);
381  if (rc==MMSYSERR_NOERROR) {
382  nameA = HeapAlloc(GetProcessHeap(), 0, size/sizeof(WCHAR));
384  nameA, size/sizeof(WCHAR), NULL, NULL);
385  }
387  } else if (rc==MMSYSERR_NOTSUPPORTED) {
388  nameA=HeapAlloc(GetProcessHeap(), 0, sizeof("not supported"));
389  strcpy(nameA, "not supported");
390  }
391 
392  trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
393  (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
394  capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid);
395  trace(" channels=%d formats=%05x\n",
396  capsA.wChannels,capsA.dwFormats);
397 
398  HeapFree(GetProcessHeap(), 0, nameA);
399 
400  for (f = 0; f < ARRAY_SIZE(win_formats); f++) {
401  format.wFormatTag=WAVE_FORMAT_PCM;
402  format.nChannels=win_formats[f][3];
403  format.wBitsPerSample=win_formats[f][2];
404  format.nSamplesPerSec=win_formats[f][1];
405  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
406  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
407  format.cbSize=0;
409  if (device != WAVE_MAPPER) {
411  WAVE_FORMAT_DIRECT, &capsA);
413  WAVE_MAPPED, &capsA);
414  }
415  }
416 
417  /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
418  * checking */
419  twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
421  ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
422  if (twoPages) {
423  res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
424  &flOldProtect);
425  ok(res, "Failed to set memory access on second page\n");
426  if (res) {
427  LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
428  sizeof(PCMWAVEFORMAT));
430  pwfx->nChannels=1;
431  pwfx->wBitsPerSample=8;
432  pwfx->nSamplesPerSec=22050;
433  pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
434  pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
436  if (device != WAVE_MAPPER) {
438  WAVE_FORMAT_DIRECT, &capsA);
440  WAVE_MAPPED, &capsA);
441  }
442  }
443  VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
444  }
445 
446  /* test non PCM formats */
447  format.wFormatTag=WAVE_FORMAT_MULAW;
448  format.nChannels=1;
449  format.wBitsPerSample=8;
450  format.nSamplesPerSec=8000;
451  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
452  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
453  format.cbSize=0;
455  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
457  rc==MMSYSERR_ALLOCATED,
458  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
459  if (rc==MMSYSERR_NOERROR) {
460  waveInClose(win);
461  wave_in_test_deviceIn(device,&format,0,0,&capsA);
462  } else
463  trace("waveInOpen(%s): WAVE_FORMAT_MULAW not supported\n",
464  dev_name(device));
465 
466  format.wFormatTag=WAVE_FORMAT_ADPCM;
467  format.nChannels=2;
468  format.wBitsPerSample=4;
469  format.nSamplesPerSec=22050;
470  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
471  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
472  format.cbSize=0;
474  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
476  rc==MMSYSERR_ALLOCATED,
477  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
478  if (rc==MMSYSERR_NOERROR) {
479  waveInClose(win);
480  wave_in_test_deviceIn(device,&format,0,0,&capsA);
481  } else
482  trace("waveInOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
483  dev_name(device));
484 
485  /* test if WAVEFORMATEXTENSIBLE supported */
487  wfex.Format.nChannels=2;
488  wfex.Format.wBitsPerSample=16;
489  wfex.Format.nSamplesPerSec=22050;
492  wfex.Format.nBlockAlign;
493  wfex.Format.cbSize=22;
497  rc=waveInOpen(&win,device,&wfex.Format,0,0,
499  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
501  rc==MMSYSERR_ALLOCATED,
502  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
503  if (rc==MMSYSERR_NOERROR) {
504  waveInClose(win);
505  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
506  } else
507  trace("waveInOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
508  dev_name(device));
509 
510  /* test if 4 channels supported */
512  wfex.Format.nChannels=4;
513  wfex.Format.wBitsPerSample=16;
514  wfex.Format.nSamplesPerSec=22050;
517  wfex.Format.nBlockAlign;
518  wfex.Format.cbSize=22;
522  rc=waveInOpen(&win,device,&wfex.Format,0,0,
524  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
526  rc==MMSYSERR_ALLOCATED,
527  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
528  if (rc==MMSYSERR_NOERROR) {
529  waveInClose(win);
530  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
531  } else
532  trace("waveInOpen(%s): 4 channels not supported\n",
533  dev_name(device));
534 
535  /* test if 6 channels supported */
537  wfex.Format.nChannels=6;
538  wfex.Format.wBitsPerSample=16;
539  wfex.Format.nSamplesPerSec=22050;
542  wfex.Format.nBlockAlign;
543  wfex.Format.cbSize=22;
547  rc=waveInOpen(&win,device,&wfex.Format,0,0,
549  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
551  rc==MMSYSERR_ALLOCATED,
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): 6 channels not supported\n",
558  dev_name(device));
559 
560  if (0)
561  {
562  /* FIXME: ALSA doesn't like this */
563  /* test if 24 bit samples supported */
565  wfex.Format.nChannels=2;
566  wfex.Format.wBitsPerSample=24;
567  wfex.Format.nSamplesPerSec=22050;
570  wfex.Format.nBlockAlign;
571  wfex.Format.cbSize=22;
575  rc=waveInOpen(&win,device,&wfex.Format,0,0,
577  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
579  rc==MMSYSERR_ALLOCATED,
580  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
581  if (rc==MMSYSERR_NOERROR) {
582  waveInClose(win);
583  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
584  } else
585  trace("waveInOpen(%s): 24 bit samples not supported\n",
586  dev_name(device));
587  }
588 
589  /* test if 32 bit samples supported */
591  wfex.Format.nChannels=2;
592  wfex.Format.wBitsPerSample=32;
593  wfex.Format.nSamplesPerSec=22050;
596  wfex.Format.nBlockAlign;
597  wfex.Format.cbSize=22;
601  rc=waveInOpen(&win,device,&wfex.Format,0,0,
603  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
605  rc==MMSYSERR_ALLOCATED,
606  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
607  if (rc==MMSYSERR_NOERROR) {
608  waveInClose(win);
609  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
610  } else
611  trace("waveInOpen(%s): 32 bit samples not supported\n",
612  dev_name(device));
613 
614  /* test if 32 bit float samples supported */
616  wfex.Format.nChannels=2;
617  wfex.Format.wBitsPerSample=32;
618  wfex.Format.nSamplesPerSec=22050;
621  wfex.Format.nBlockAlign;
622  wfex.Format.cbSize=22;
626  rc=waveInOpen(&win,device,&wfex.Format,0,0,
628  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
630  rc==MMSYSERR_ALLOCATED,
631  "waveInOpen(%s): returned: %s\n",dev_name(device),wave_in_error(rc));
632  if (rc==MMSYSERR_NOERROR) {
633  waveInClose(win);
634  wave_in_test_deviceIn(device,&wfex.Format,0,0,&capsA);
635  } else
636  trace("waveInOpen(%s): 32 bit float samples not supported\n",
637  dev_name(device));
638 }
639 
640 static void wave_in_tests(void)
641 {
642  WAVEINCAPSA capsA;
643  WAVEINCAPSW capsW;
645  HWAVEIN win;
646  MMRESULT rc;
647  DWORD preferred, status;
648  UINT ndev,d;
649 
650  ndev=waveInGetNumDevs();
651  trace("found %d WaveIn devices\n",ndev);
652 
654  (DWORD_PTR)&preferred, (DWORD_PTR)&status);
655  ok((ndev == 0 && (rc == MMSYSERR_NODRIVER || rc == MMSYSERR_BADDEVICEID)) ||
656  rc == MMSYSERR_NOTSUPPORTED ||
657  rc == MMSYSERR_NOERROR, "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc);
658 
659  if(rc != MMSYSERR_NOTSUPPORTED)
660  ok((ndev == 0 && (preferred == -1 || broken(preferred != -1))) ||
661  preferred < ndev, "Got invalid preferred device: 0x%x\n", preferred);
662 
664  (DWORD_PTR)-1 , 0);
665  ok(rc == MMSYSERR_INVALPARAM || rc == MMSYSERR_BADDEVICEID, /* w2008+wvista */
666  "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc);
667 
669  0, (DWORD_PTR)&status);
670  ok(rc == MMSYSERR_INVALPARAM || rc == MMSYSERR_BADDEVICEID, /* w2008+wvista */
671  "waveInMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc);
672 
673  rc=waveInGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
675  "waveInGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
676  dev_name(ndev+1),wave_in_error(rc));
677 
678  rc=waveInGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
679  ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NODRIVER || (!ndev && (rc==MMSYSERR_BADDEVICEID)),
680  "waveInGetDevCapsA(%s): got %s\n",dev_name(WAVE_MAPPER),wave_in_error(rc));
681 
682  rc=waveInGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
684  "waveInGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
685  "expected, got %s\n",dev_name(ndev+1),wave_in_error(rc));
686 
687  rc=waveInGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
689  rc==MMSYSERR_NOTSUPPORTED || (!ndev && (rc==MMSYSERR_BADDEVICEID)),
690  "waveInGetDevCapsW(%s): got %s\n", dev_name(ndev+1),wave_in_error(rc));
691 
692  format.wFormatTag=WAVE_FORMAT_PCM;
693  format.nChannels=2;
694  format.wBitsPerSample=16;
695  format.nSamplesPerSec=44100;
696  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
697  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
698  format.cbSize=0;
699  rc=waveInOpen(&win,ndev+1,&format,0,0,CALLBACK_NULL);
701  "waveInOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
702  dev_name(ndev+1),wave_in_error(rc));
703 
704  for (d=0;d<ndev;d++)
706 
707  if (ndev>0)
709 }
710 
711 START_TEST(capture)
712 {
713  wave_in_tests();
714 }
#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
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2637
#define CloseHandle
Definition: compat.h:598
const char * wave_out_error(MMRESULT error)
Definition: wave.c:270
union WAVEFORMATEXTENSIBLE::@2978 Samples
#define WideCharToMultiByte
Definition: compat.h:111
#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:109
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
int winetest_interactive
GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
int nChannels
Definition: pcmconverter.c:95
#define lstrlenW
Definition: compat.h:609
#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:651
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:297
#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:34
#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
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
union mmtime_tag::@2991 u
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
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:595
#define trace
Definition: atltest.h:70
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)
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
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
uint32_t DWORD_PTR
Definition: typedefs.h:65
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
unsigned char BYTE
Definition: xxhash.c:193
#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:1139
#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 ARRAY_SIZE(a)
Definition: main.h:24
#define f
Definition: ke_i.h:83
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
#define ok(value,...)
Definition: atltest.h:57
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:226
#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:594
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:640