ReactOS  0.4.14-dev-552-g2fad488
wave.c
Go to the documentation of this file.
1 /*
2  * Test winmm sound playback 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 "winuser.h"
30 #include "winnls.h"
31 #include "mmsystem.h"
32 #define NOBITMAP
33 #include "mmddk.h"
34 #include "mmreg.h"
35 #include "ks.h"
36 #include "ksguid.h"
37 #ifndef __REACTOS__
38 #include "ksmedia.h"
39 #endif
40 
41 #include "winmm_test.h"
42 
43 #ifdef __REACTOS__ /* FIXME */
44 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
45 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
46 #endif
47 
48 static DWORD g_tid;
49 
50 static void test_multiple_waveopens(void)
51 {
52  HWAVEOUT handle1, handle2;
53  MMRESULT ret;
54  WAVEFORMATEX wfx;
55 
57  wfx.nChannels = 1;
58  wfx.nSamplesPerSec = 11025;
59  wfx.nBlockAlign = 1;
61  wfx.wBitsPerSample = 8;
62  wfx.cbSize = 0;
63 
64  ret = waveOutOpen(&handle1, 0, &wfx, 0, 0, 0);
65  if (ret != MMSYSERR_NOERROR)
66  {
67  skip("Could not do the duplicate waveopen test\n");
68  return;
69  }
70 
71  ret = waveOutOpen(&handle2, 0, &wfx, 0, 0, 0);
72  /* Modern Windows allows for wave-out devices to be opened multiple times.
73  * Some Wine audio drivers allow that and some don't. To avoid false alarms
74  * for those that do, don't "todo_wine ok(...)" on success.
75  */
76  if (ret != MMSYSERR_NOERROR)
77  {
79  "second waveOutOpen returns: %x\n", ret);
80  }
81  else
82  waveOutClose(handle2);
83 
84  waveOutClose(handle1);
85 }
86 
87 /*
88  * Note that in most of this test we may get MMSYSERR_BADDEVICEID errors
89  * at about any time if the user starts another application that uses the
90  * sound device. So we should not report these as test failures.
91  *
92  * This test can play a test tone. But this only makes sense if someone
93  * is going to carefully listen to it, and would only bother everyone else.
94  * So this is only done if the test is being run in interactive mode.
95  */
96 
97 #define PI 3.14159265358979323846
98 static char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
99 {
100  int i,j;
101  int nb_samples;
102  char* buf;
103  char* b;
105 
106  nb_samples=(int)(duration*wfx->nSamplesPerSec);
107  *size=nb_samples*wfx->nBlockAlign;
109  for (i=0;i<nb_samples;i++) {
110  double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
111  if (wfx->wBitsPerSample==8) {
112  unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
113  for (j = 0; j < wfx->nChannels; j++)
114  *b++=sample;
115  } else if (wfx->wBitsPerSample==16) {
116  signed short sample=(signed short)((double)32767.5*y-0.5);
117  for (j = 0; j < wfx->nChannels; j++) {
118  b[0]=sample & 0xff;
119  b[1]=sample >> 8;
120  b+=2;
121  }
122  } else if (wfx->wBitsPerSample==24) {
123  signed int sample=(signed int)(((double)0x7fffff+0.5)*y-0.5);
124  for (j = 0; j < wfx->nChannels; j++) {
125  b[0]=sample & 0xff;
126  b[1]=(sample >> 8) & 0xff;
127  b[2]=(sample >> 16) & 0xff;
128  b+=3;
129  }
130  } else if ((wfx->wBitsPerSample==32) && ((wfx->wFormatTag == WAVE_FORMAT_PCM) ||
131  ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
133  signed int sample=(signed int)(((double)0x7fffffff+0.5)*y-0.5);
134  for (j = 0; j < wfx->nChannels; j++) {
135  b[0]=sample & 0xff;
136  b[1]=(sample >> 8) & 0xff;
137  b[2]=(sample >> 16) & 0xff;
138  b[3]=(sample >> 24) & 0xff;
139  b+=4;
140  }
141  } else if ((wfx->wBitsPerSample==32) && (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
143  union { float f; char c[4]; } sample;
144  sample.f=(float)y;
145  for (j = 0; j < wfx->nChannels; j++) {
146  b[0]=sample.c[0];
147  b[1]=sample.c[1];
148  b[2]=sample.c[2];
149  b[3]=sample.c[3];
150  b+=4;
151  }
152  }
153  }
154  return buf;
155 }
156 
157 static char* wave_generate_silence(WAVEFORMATEX* wfx, double duration, DWORD* size)
158 {
159  int i,j;
160  int nb_samples;
161  char* buf;
162  char* b;
164 
165  nb_samples=(int)(duration*wfx->nSamplesPerSec);
166  *size=nb_samples*wfx->nBlockAlign;
168  for (i=0;i<nb_samples;i++) {
169  if (wfx->wBitsPerSample==8) {
170  for (j = 0; j < wfx->nChannels; j++)
171  *b++=128;
172  } else if (wfx->wBitsPerSample==16) {
173  for (j = 0; j < wfx->nChannels; j++) {
174  b[0]=0;
175  b[1]=0;
176  b+=2;
177  }
178  } else if (wfx->wBitsPerSample==24) {
179  for (j = 0; j < wfx->nChannels; j++) {
180  b[0]=0;
181  b[1]=0;
182  b[2]=0;
183  b+=3;
184  }
185  } else if ((wfx->wBitsPerSample==32) && ((wfx->wFormatTag == WAVE_FORMAT_PCM) ||
186  ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
188  for (j = 0; j < wfx->nChannels; j++) {
189  b[0]=0;
190  b[1]=0;
191  b[2]=0;
192  b[3]=0;
193  b+=4;
194  }
195  } else if ((wfx->wBitsPerSample==32) && (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
197  union { float f; char c[4]; } sample;
198  sample.f=0;
199  for (j = 0; j < wfx->nChannels; j++) {
200  b[0]=sample.c[0];
201  b[1]=sample.c[1];
202  b[2]=sample.c[2];
203  b[3]=sample.c[3];
204  b+=4;
205  }
206  }
207  }
208  return buf;
209 }
210 
211 const char * dev_name(int device)
212 {
213  static char name[16];
214  if (device == WAVE_MAPPER)
215  return "WAVE_MAPPER";
216  sprintf(name, "%d", device);
217  return name;
218 }
219 
221 {
222 #define ERR_TO_STR(dev) case dev: return #dev
223  static char unknown[32];
224  switch (error) {
264  }
265  sprintf(unknown, "Unknown(0x%08x)", error);
266  return unknown;
267 #undef ERR_TO_STR
268 }
269 
271 {
272  static char msg[1024];
273  static char long_msg[1100];
274  MMRESULT rc;
275 
276  rc = waveOutGetErrorTextA(error, msg, sizeof(msg));
277  if (rc != MMSYSERR_NOERROR)
278  sprintf(long_msg, "waveOutGetErrorTextA(%x) failed with error %x", error, rc);
279  else
280  sprintf(long_msg, "%s(%s)", mmsys_error(error), msg);
281  return long_msg;
282 }
283 
285 {
286  static char msg[1024];
287  BOOL first = TRUE;
288  msg[0] = 0;
290  strcat(msg, "CALLBACK_EVENT");
291  first = FALSE;
292  }
294  if (!first) strcat(msg, "|");
295  strcat(msg, "CALLBACK_FUNCTION");
296  first = FALSE;
297  }
299  if (!first) strcat(msg, "|");
300  strcat(msg, "CALLBACK_NULL");
301  first = FALSE;
302  }
304  if (!first) strcat(msg, "|");
305  strcat(msg, "CALLBACK_THREAD");
306  first = FALSE;
307  }
309  if (!first) strcat(msg, "|");
310  strcat(msg, "CALLBACK_WINDOW");
311  first = FALSE;
312  }
313  if ((flags & WAVE_ALLOWSYNC) == WAVE_ALLOWSYNC) {
314  if (!first) strcat(msg, "|");
315  strcat(msg, "WAVE_ALLOWSYNC");
316  first = FALSE;
317  }
319  if (!first) strcat(msg, "|");
320  strcat(msg, "WAVE_FORMAT_DIRECT");
321  first = FALSE;
322  }
324  if (!first) strcat(msg, "|");
325  strcat(msg, "WAVE_FORMAT_QUERY");
326  first = FALSE;
327  }
328  if ((flags & WAVE_MAPPED) == WAVE_MAPPED) {
329  if (!first) strcat(msg, "|");
330  strcat(msg, "WAVE_MAPPED");
331  }
332  return msg;
333 }
334 
335 static const char * wave_header_flags(DWORD flags)
336 {
337 #define WHDR_MASK (WHDR_BEGINLOOP|WHDR_DONE|WHDR_ENDLOOP|WHDR_INQUEUE|WHDR_PREPARED)
338  static char msg[1024];
339  BOOL first = TRUE;
340  msg[0] = 0;
341  if (flags & WHDR_BEGINLOOP) {
342  strcat(msg, "WHDR_BEGINLOOP");
343  first = FALSE;
344  }
345  if (flags & WHDR_DONE) {
346  if (!first) strcat(msg, " ");
347  strcat(msg, "WHDR_DONE");
348  first = FALSE;
349  }
350  if (flags & WHDR_ENDLOOP) {
351  if (!first) strcat(msg, " ");
352  strcat(msg, "WHDR_ENDLOOP");
353  first = FALSE;
354  }
355  if (flags & WHDR_INQUEUE) {
356  if (!first) strcat(msg, " ");
357  strcat(msg, "WHDR_INQUEUE");
358  first = FALSE;
359  }
360  if (flags & WHDR_PREPARED) {
361  if (!first) strcat(msg, " ");
362  strcat(msg, "WHDR_PREPARED");
363  first = FALSE;
364  }
365  if (flags & ~WHDR_MASK) {
366  char temp[32];
367  sprintf(temp, "UNKNOWN(0x%08x)", flags & ~WHDR_MASK);
368  if (!first) strcat(msg, " ");
369  strcat(msg, temp);
370  }
371  return msg;
372 }
373 
374 static const char * wave_out_caps(DWORD dwSupport)
375 {
376 #define ADD_FLAG(f) if (dwSupport & f) strcat(msg, " " #f)
377  static char msg[256];
378  msg[0] = 0;
379 
386 
387  return msg[0] ? msg + 1 : "";
388 #undef ADD_FLAG
389 }
390 
392 {
393  static char msg[32];
394 #define TIME_FORMAT(f) case f: return #f
395  switch (type) {
402  }
403 #undef TIME_FORMAT
404  sprintf(msg, "Unknown(0x%04x)", type);
405  return msg;
406 }
407 
409 {
410  static char msg[32];
411 #define WAVE_FORMAT(f) case f: return #f
412  switch (format) {
455  }
456 #undef WAVE_FORMAT
457  sprintf(msg, "Unknown(0x%04x)", format);
458  return msg;
459 }
460 
462 {
463  return bytes / pwfx->nBlockAlign;
464 }
465 
467 {
468  return bytes_to_samples(bytes, pwfx) * 1000 / pwfx->nSamplesPerSec;
469 }
470 
472 {
473  if (mmtime->wType == TIME_BYTES)
474  return mmtime->u.cb;
475  else if (mmtime->wType == TIME_SAMPLES)
476  return mmtime->u.sample * pwfx->nBlockAlign;
477  else if (mmtime->wType == TIME_MS)
478  return mmtime->u.ms * pwfx->nAvgBytesPerSec / 1000;
479  else if (mmtime->wType == TIME_SMPTE)
480  return ((mmtime->u.smpte.hour * 60 * 60) +
481  (mmtime->u.smpte.min * 60) +
482  (mmtime->u.smpte.sec)) * pwfx->nAvgBytesPerSec +
483  mmtime->u.smpte.frame * pwfx->nAvgBytesPerSec / 30;
484 
485  trace("FIXME: time_to_bytes() type not supported\n");
486  return -1;
487 }
488 
489 static void check_position(int device, HWAVEOUT wout, DWORD bytes,
490  LPWAVEFORMATEX pwfx )
491 {
492  MMTIME mmtime;
493  MMRESULT rc;
494  DWORD returned;
495 
496  mmtime.wType = TIME_BYTES;
497  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime) - 1);
498  ok(rc==MMSYSERR_ERROR,
499  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
500 
501  mmtime.wType = TIME_BYTES;
502  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime) + 1);
503  ok(rc==MMSYSERR_NOERROR,
504  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
505  if (mmtime.wType != TIME_BYTES && winetest_debug > 1)
506  trace("waveOutGetPosition(%s): TIME_BYTES not supported, returned %s\n",
508  returned = time_to_bytes(&mmtime, pwfx);
509  ok(returned == bytes, "waveOutGetPosition(%s): returned %d bytes, "
510  "should be %d\n", dev_name(device), returned, bytes);
511 
512  mmtime.wType = TIME_SAMPLES;
513  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
514  ok(rc==MMSYSERR_NOERROR,
515  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
516  if (mmtime.wType != TIME_SAMPLES && winetest_debug > 1)
517  trace("waveOutGetPosition(%s): TIME_SAMPLES not supported, "
518  "returned %s\n",dev_name(device),wave_time_format(mmtime.wType));
519  returned = time_to_bytes(&mmtime, pwfx);
520  ok(returned == bytes, "waveOutGetPosition(%s): returned %d samples "
521  "(%d bytes), should be %d (%d bytes)\n", dev_name(device),
522  bytes_to_samples(returned, pwfx), returned,
523  bytes_to_samples(bytes, pwfx), bytes);
524 
525  mmtime.wType = TIME_MS;
526  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
527  ok(rc==MMSYSERR_NOERROR,
528  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
529  if (mmtime.wType != TIME_MS && winetest_debug > 1)
530  trace("waveOutGetPosition(%s): TIME_MS not supported, returned %s\n",
532  returned = time_to_bytes(&mmtime, pwfx);
533  ok(returned == bytes, "waveOutGetPosition(%s): returned %d ms, "
534  "(%d bytes), should be %d (%d bytes)\n", dev_name(device),
535  bytes_to_ms(returned, pwfx), returned,
536  bytes_to_ms(bytes, pwfx), bytes);
537 
538  mmtime.wType = TIME_SMPTE;
539  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
540  ok(rc==MMSYSERR_NOERROR,
541  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
542  if (mmtime.wType != TIME_SMPTE && winetest_debug > 1)
543  trace("waveOutGetPosition(%s): TIME_SMPTE not supported, returned %s\n",
545  returned = time_to_bytes(&mmtime, pwfx);
546  ok(returned == bytes, "waveOutGetPosition(%s): SMPTE test failed\n",
547  dev_name(device));
548 
549  mmtime.wType = TIME_MIDI;
550  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
551  ok(rc==MMSYSERR_NOERROR,
552  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
553  if (mmtime.wType != TIME_MIDI && winetest_debug > 1)
554  trace("waveOutGetPosition(%s): TIME_MIDI not supported, returned %s\n",
556  returned = time_to_bytes(&mmtime, pwfx);
557  ok(returned == bytes, "waveOutGetPosition(%s): MIDI test failed\n",
558  dev_name(device));
559 
560  mmtime.wType = TIME_TICKS;
561  rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
562  ok(rc==MMSYSERR_NOERROR,
563  "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
564  if (mmtime.wType != TIME_TICKS && winetest_debug > 1)
565  trace("waveOutGetPosition(%s): TIME_TICKS not supported, returned %s\n",
567  returned = time_to_bytes(&mmtime, pwfx);
568  ok(returned == bytes, "waveOutGetPosition(%s): TICKS test failed\n",
569  dev_name(device));
570 }
571 
572 static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg,
573  DWORD_PTR dwInstance,
574  DWORD dwParam1, DWORD dwParam2)
575 {
576  if(uMsg == WOM_OPEN || uMsg == WOM_CLOSE)
577  ok(GetCurrentThreadId() == g_tid, "Got different thread ID\n");
578  SetEvent((HANDLE)dwInstance);
579 }
580 
582 {
583  MSG msg;
584 
585  PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ); /* make sure the thread has a message queue */
587 
588  while (GetMessageA(&msg, 0, 0, 0)) {
589  UINT message = msg.message;
590  /* for some reason XP sends a WM_USER message before WOM_OPEN */
591  ok (message == WOM_OPEN || message == WOM_DONE ||
593  "GetMessageA returned unexpected message: %u\n", message);
594  if (message == WOM_OPEN || message == WOM_DONE || message == WOM_CLOSE)
596  else if (message == WM_APP) {
598  return 0;
599  }
600  }
601 
602  return 0;
603 }
604 
605 static void wave_out_test_deviceOut(int device, double duration, int headers, int loops,
607  BOOL sine, BOOL pause)
608 {
609  HWAVEOUT wout;
611  WAVEHDR *frags = 0;
612  MMRESULT rc;
613  DWORD volume;
614  WORD nChannels = pwfx->nChannels;
615  WORD wBitsPerSample = pwfx->wBitsPerSample;
616  DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
617  BOOL has_volume = (pcaps->dwSupport & WAVECAPS_VOLUME) != 0;
618  double paused = 0.0;
619  DWORD_PTR callback = 0;
620  DWORD_PTR callback_instance = 0;
621  HANDLE thread = 0;
623  char * buffer;
624  DWORD length;
625  DWORD frag_length;
626  int i, j;
627 
630  callback_instance = 0;
631  } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) {
633  callback_instance = (DWORD_PTR)hevent;
634  } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) {
636  if (thread) {
637  /* make sure thread is running */
640  callback_instance = 0;
641  } else {
642  trace("CreateThread() failed\n");
644  return;
645  }
646  } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) {
647  trace("CALLBACK_THREAD not implemented\n");
649  return;
650  } else if (flags & CALLBACK_TYPEMASK) {
651  trace("Undefined callback type!\n");
653  return;
654  } else {
655  trace("CALLBACK_NULL not implemented\n");
657  return;
658  }
659  wout=NULL;
661  rc=waveOutOpen(&wout,device,pwfx,callback,callback_instance,flags);
662  /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
663  /* It is acceptable to fail on formats that are not specified to work */
666  rc==MMSYSERR_ALLOCATED ||
667  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
668  (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
669  ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
670  (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
671  !(pcaps->dwFormats & format)) ||
673  "waveOutOpen(%s): format=%dx%2dx%d flags=%x(%s) rc=%s\n",
677  if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
678  (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
679  trace(" Reason: The device lists this format as supported in its "
680  "capabilities but opening it failed.\n");
681  if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
682  !(pcaps->dwFormats & format))
683  trace("waveOutOpen(%s): format=%dx%2dx%d %s rc=%s failed but format "
684  "not supported so OK.\n", dev_name(device), pwfx->nSamplesPerSec,
685  pwfx->wBitsPerSample,pwfx->nChannels,
686  flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
687  flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
688  if (rc!=MMSYSERR_NOERROR)
689  goto EXIT;
690 
691  rc=WaitForSingleObject(hevent,9000);
692  ok(rc==WAIT_OBJECT_0, "missing WOM_OPEN notification\n");
693 
694  ok(pwfx->nChannels==nChannels &&
695  pwfx->wBitsPerSample==wBitsPerSample &&
696  pwfx->nSamplesPerSec==nSamplesPerSec,
697  "got the wrong format: %dx%2dx%d instead of %dx%2dx%d\n",
698  pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
699  pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
700 
701  frags = HeapAlloc(GetProcessHeap(), 0, headers * sizeof(WAVEHDR));
702 
703  if (sine)
704  buffer=wave_generate_la(pwfx,duration / (loops + 1),&length);
705  else
706  buffer=wave_generate_silence(pwfx,duration / (loops + 1),&length);
707 
708  rc=waveOutGetVolume(wout,0);
709  ok(rc==MMSYSERR_INVALPARAM,"waveOutGetVolume(%s,0) expected "
710  "MMSYSERR_INVALPARAM, got %s\n", dev_name(device),wave_out_error(rc));
711  rc=waveOutGetVolume(wout,&volume);
712  if (rc == MMSYSERR_NOTSUPPORTED) has_volume = FALSE;
713  ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED,
714  "waveOutGetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
715 
716  /* make sure fragment length is a multiple of block size */
717  frag_length = ((length / headers) / pwfx->nBlockAlign) * pwfx->nBlockAlign;
718 
719  for (i = 0; i < headers; i++) {
720  frags[i].lpData=buffer + (i * frag_length);
721  if (i != (headers-1))
722  frags[i].dwBufferLength=frag_length;
723  else {
724  /* use remainder of buffer for last fragment */
725  frags[i].dwBufferLength=length - (i * frag_length);
726  }
727  frags[i].dwFlags=0;
728  frags[i].dwLoops=0;
729  rc=waveOutPrepareHeader(wout, &frags[i], sizeof(frags[0]));
730  ok(rc==MMSYSERR_NOERROR,
731  "waveOutPrepareHeader(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
732  }
733 
734  if (interactive && rc==MMSYSERR_NOERROR) {
735  trace("Playing %g second %s at %5dx%2dx%d %2d header%s %d loop%s %d bytes %s %s\n",duration,
736  sine ? "440 Hz tone" : "silence", pwfx->nSamplesPerSec,
737  pwfx->wBitsPerSample,pwfx->nChannels, headers, headers > 1 ? "s": " ",
738  loops, loops == 1 ? " " : "s", length * (loops + 1),
739  get_format_str(pwfx->wFormatTag),
741  if (sine && has_volume && volume == 0)
742  trace("*** Warning the sound is muted, you will not hear the test\n");
743 
744  /* Check that the position is 0 at start */
745  check_position(device, wout, 0, pwfx);
746 
747  rc=waveOutSetVolume(wout,0x20002000);
748  ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED,
749  "waveOutSetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
750 
751  rc=waveOutSetVolume(wout,volume);
752  ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED,
753  "waveOutSetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
754 
755  rc=waveOutWrite(wout, &frags[0], sizeof(frags[0]));
756  ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
758 
759  ok(frags[0].dwFlags==(WHDR_PREPARED|WHDR_INQUEUE),
760  "WHDR_INQUEUE WHDR_PREPARED expected, got= %s\n",
761  wave_header_flags(frags[0].dwFlags));
762 
763  rc=waveOutWrite(wout, &frags[0], sizeof(frags[0]));
765  "waveOutWrite(%s): WAVE_STILLPLAYING expected, got %s\n",
767 
768  ok(frags[0].dwFlags==(WHDR_PREPARED|WHDR_INQUEUE),
769  "WHDR_INQUEUE WHDR_PREPARED expected, got %s\n",
770  wave_header_flags(frags[0].dwFlags));
771 
772  if (headers == 1 && loops == 0 && pause) {
773  paused = duration / 2;
774  Sleep(paused * 1000);
775  rc=waveOutPause(wout);
776  ok(rc==MMSYSERR_NOERROR,"waveOutPause(%s): rc=%s\n",
778  trace("pausing for %g seconds\n", paused);
779  Sleep(paused * 1000);
780  rc=waveOutRestart(wout);
781  ok(rc==MMSYSERR_NOERROR,"waveOutRestart(%s): rc=%s\n",
783  }
784 
785  for (j = 0; j <= loops; j++) {
786  for (i = 0; i < headers; i++) {
787  /* don't do last one */
788  if (!((j == loops) && (i == (headers - 1)))) {
789  if (j > 0)
790  frags[(i+1) % headers].dwFlags = WHDR_PREPARED;
791  rc=waveOutWrite(wout, &frags[(i+1) % headers], sizeof(frags[0]));
792  ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s, header[%d]): rc=%s\n",
794  }
795  rc=WaitForSingleObject(hevent,8000);
796  ok(rc==WAIT_OBJECT_0, "missing WOM_DONE notification\n");
797  }
798  }
799 
800  for (i = 0; i < headers; i++) {
801  ok(frags[i].dwFlags==(WHDR_DONE|WHDR_PREPARED) ||
803  frags[i].dwFlags==(WHDR_DONE|WHDR_PREPARED|0x1000)), /* < NT4 */
804  "(%02d) WHDR_DONE WHDR_PREPARED expected, got %s\n",
805  i, wave_header_flags(frags[i].dwFlags));
806  }
807  check_position(device, wout, length * (loops + 1), pwfx);
808  }
809 
810  for (i = 0; i < headers; i++) {
811  rc=waveOutUnprepareHeader(wout, &frags[i], sizeof(frags[0]));
812  ok(rc==MMSYSERR_NOERROR,
813  "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device),
814  wave_out_error(rc));
815  }
816 
817  ok(frags[0].dwFlags==(interactive ? WHDR_DONE : 0), "dwFlags(%d)=%x\n",device,frags[0].dwFlags);
818 
819  frags[0].dwFlags |= WHDR_DONE;
820  rc=waveOutUnprepareHeader(wout, &frags[0], sizeof(frags[0]));
821  ok(rc==MMSYSERR_NOERROR, "waveOutUnprepareHeader(%d): rc=%s\n",device,wave_out_error(rc));
822  ok(frags[0].dwFlags==WHDR_DONE, "dwFlags(%d)=%x\n",device,frags[0].dwFlags);
823 
824  frags[0].dwFlags |= WHDR_INQUEUE;
825  rc=waveOutPrepareHeader(wout, &frags[0], sizeof(frags[0]));
826  ok(rc==MMSYSERR_NOERROR, "waveOutPrepareHeader(%d): rc=%s\n",device,wave_out_error(rc));
827  ok(frags[0].dwFlags==WHDR_PREPARED, "dwFlags(%d)=%x\n",device,frags[0].dwFlags);
828 
829  frags[0].dwFlags |= WHDR_INQUEUE;
830  rc=waveOutPrepareHeader(wout, &frags[0], sizeof(frags[0]));
831  ok(rc==MMSYSERR_NOERROR, "waveOutPrepareHeader(%d): rc=%s\n",device,wave_out_error(rc));
832  ok(frags[0].dwFlags==(WHDR_PREPARED|WHDR_INQUEUE), "dwFlags(%d)=%x\n",device,frags[0].dwFlags);
833 
834  frags[0].dwFlags &= ~(WHDR_INQUEUE|WHDR_DONE);
835  rc=waveOutUnprepareHeader(wout, &frags[0], sizeof(frags[0]));
836  ok(rc==MMSYSERR_NOERROR, "waveOutUnprepareHeader(%d): rc=%s\n",device,wave_out_error(rc));
837  ok(frags[0].dwFlags==0, "dwFlags(%d)=%x\n",device,frags[0].dwFlags);
838 
839  rc=waveOutClose(wout);
840  ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device),
841  wave_out_error(rc));
842  if (rc==WAVERR_STILLPLAYING) {
843  /* waveOutReset ought to return all buffers s.t. waveOutClose succeeds */
844  rc=waveOutReset(wout);
845  ok(rc==MMSYSERR_NOERROR,"waveOutReset(%s): rc=%s\n",dev_name(device),
846  wave_out_error(rc));
847 
848  for (i = 0; i < headers; i++) {
849  rc=waveOutUnprepareHeader(wout, &frags[i], sizeof(frags[0]));
850  ok(rc==MMSYSERR_NOERROR,
851  "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device),
852  wave_out_error(rc));
853  }
854  rc=waveOutClose(wout);
855  ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device),
856  wave_out_error(rc));
857  }
858  rc=WaitForSingleObject(hevent,1500);
859  ok(rc==WAIT_OBJECT_0, "missing WOM_CLOSE notification\n");
860 
861  wout = (HWAVEOUT)0xdeadf00d;
862  rc=waveOutOpen(&wout,device,pwfx,callback,callback_instance,flags|WAVE_FORMAT_QUERY);
863  ok(rc==MMSYSERR_NOERROR, "WAVE_FORMAT_QUERY(%s): rc=%s\n",dev_name(device),
864  wave_out_error(rc));
865  ok(wout==(HWAVEOUT)0xdeadf00d, "WAVE_FORMAT_QUERY handle %p\n", wout);
866 
868  ok(rc==WAIT_TIMEOUT, "Notification from %s rc=%x\n",
870 
872 EXIT:
876  }
878  HeapFree(GetProcessHeap(), 0, frags);
879 }
880 
882 {
883  WAVEOUTCAPSA capsA;
884  WAVEOUTCAPSW capsW;
887  IMAADPCMWAVEFORMAT wfa;
888  HWAVEOUT wout;
889  MMRESULT rc;
890  UINT f;
891  WCHAR * nameW;
892  CHAR * nameA;
893  DWORD size;
894  DWORD dwPageSize;
895  BYTE * twoPages;
896  SYSTEM_INFO sSysInfo;
897  DWORD flOldProtect;
898  BOOL res;
899 
900  GetSystemInfo(&sSysInfo);
901  dwPageSize = sSysInfo.dwPageSize;
902 
903  rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA));
905  rc==MMSYSERR_NODRIVER,
906  "waveOutGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
909  return;
910 
911  rc=waveOutGetDevCapsW(device,&capsW,sizeof(capsW));
913  "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
914  "expected, got %s\n",dev_name(device),wave_out_error(rc));
915 
916  rc=waveOutGetDevCapsA(device,0,sizeof(capsA));
918  "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, "
919  "got %s\n",dev_name(device),wave_out_error(rc));
920 
921  rc=waveOutGetDevCapsW(device,0,sizeof(capsW));
923  "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
924  "expected, got %s\n",dev_name(device),wave_out_error(rc));
925 
926  if (0)
927  {
928  /* FIXME: this works on windows but crashes wine */
929  rc=waveOutGetDevCapsA(device,(LPWAVEOUTCAPSA)1,sizeof(capsA));
931  "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
933 
934  rc=waveOutGetDevCapsW(device,(LPWAVEOUTCAPSW)1,sizeof(capsW));
936  "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
937  "expected, got %s\n",dev_name(device),wave_out_error(rc));
938  }
939 
940  rc=waveOutGetDevCapsA(device,&capsA,4);
942  "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR or MMSYSERR_INVALPARAM "
943  "expected, got %s\n", dev_name(device),wave_out_error(rc));
944 
945  rc=waveOutGetDevCapsW(device,&capsW,4);
947  rc==MMSYSERR_INVALPARAM, /* Vista, W2K8 */
948  "waveOutGetDevCapsW(%s): unexpected return value %s\n",
950 
951  rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYMAPPABLE, 0, 0);
953  "DRV_QUERYMAPPABLE(%s): unexpected return value %s\n",
955 
956  nameA=NULL;
958  (DWORD_PTR)&size, 0);
961  "waveOutMessage(%s): failed to get interface size, rc=%s\n",
963  if (rc==MMSYSERR_NOERROR) {
966  (DWORD_PTR)nameW, size);
967  ok(rc==MMSYSERR_NOERROR,"waveOutMessage(%s): failed to get interface "
968  "name, rc=%s\n",dev_name(device),wave_out_error(rc));
969  ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),"got an incorrect size %d\n",size);
970  if (rc==MMSYSERR_NOERROR) {
971  nameA = HeapAlloc(GetProcessHeap(), 0, size/sizeof(WCHAR));
972  WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR), nameA,
973  size/sizeof(WCHAR), NULL, NULL);
974  }
976  }
977  else if (rc==MMSYSERR_NOTSUPPORTED) {
978  nameA=HeapAlloc(GetProcessHeap(), 0, sizeof("not supported"));
979  strcpy(nameA, "not supported");
980  }
981 
982  rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA));
983  ok(rc==MMSYSERR_NOERROR,
984  "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
986  if (rc!=MMSYSERR_NOERROR)
987  {
988  HeapFree(GetProcessHeap(), 0, nameA);
989  return;
990  }
991 
992  trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
993  (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
994  capsA.vDriverVersion & 0xff, capsA.wMid,capsA.wPid);
995  trace(" channels=%d formats=%05x support=%04x\n",
996  capsA.wChannels,capsA.dwFormats,capsA.dwSupport);
997  trace(" %s\n",wave_out_caps(capsA.dwSupport));
998  HeapFree(GetProcessHeap(), 0, nameA);
999 
1001  {
1002  trace("Playing a 5 seconds reference tone.\n");
1003  trace("All subsequent tones should be identical to this one.\n");
1004  trace("Listen for stutter, changes in pitch, volume, etc.\n");
1005  format.wFormatTag=WAVE_FORMAT_PCM;
1006  format.nChannels=1;
1007  format.wBitsPerSample=8;
1008  format.nSamplesPerSec=22050;
1009  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1010  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1011  format.cbSize=0;
1012 
1014  CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE);
1016  CALLBACK_FUNCTION,&capsA,TRUE,TRUE,FALSE);
1018  CALLBACK_THREAD,&capsA,TRUE,TRUE,FALSE);
1019 
1021  CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE);
1023  CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE);
1024  } else {
1025  format.wFormatTag=WAVE_FORMAT_PCM;
1026  format.nChannels=1;
1027  format.wBitsPerSample=8;
1028  format.nSamplesPerSec=22050;
1029  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1030  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1031  format.cbSize=0;
1033  CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE);
1035  CALLBACK_EVENT,&capsA,TRUE,FALSE,TRUE);
1039  CALLBACK_FUNCTION,&capsA,TRUE,FALSE,TRUE);
1041  CALLBACK_THREAD,&capsA,TRUE,FALSE,FALSE);
1043  CALLBACK_THREAD,&capsA,TRUE,FALSE,TRUE);
1044 
1046  CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE);
1048  CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE);
1049  }
1050 
1051  for (f=0;f<NB_WIN_FORMATS;f++) {
1052  format.wFormatTag=WAVE_FORMAT_PCM;
1053  format.nChannels=win_formats[f][3];
1054  format.wBitsPerSample=win_formats[f][2];
1055  format.nSamplesPerSec=win_formats[f][1];
1056  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1057  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1058  format.cbSize=0;
1061  TRUE,FALSE);
1064  TRUE,FALSE);
1067  TRUE,FALSE);
1068 
1071  TRUE,FALSE);
1074  TRUE,FALSE);
1075 
1076  if (winetest_interactive) {
1079  TRUE,TRUE);
1082  TRUE,TRUE);
1085  TRUE,TRUE);
1086 
1089  TRUE,TRUE);
1092  TRUE,TRUE);
1093  }
1094  if (device != WAVE_MAPPER)
1095  {
1100  CALLBACK_EVENT|WAVE_MAPPED,&capsA,
1114 
1121  }
1122  }
1123 
1124  /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
1125  * checking */
1126  twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
1127  PAGE_READWRITE);
1128  ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
1129  if (twoPages) {
1130  res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
1131  &flOldProtect);
1132  ok(res, "Failed to set memory access on second page\n");
1133  if (res) {
1134  LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
1135  sizeof(PCMWAVEFORMAT));
1137  pwfx->nChannels=1;
1138  pwfx->wBitsPerSample=8;
1139  pwfx->nSamplesPerSec=22050;
1140  pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
1141  pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
1144  TRUE,FALSE);
1147  TRUE,FALSE);
1150  TRUE,FALSE);
1151  if (device != WAVE_MAPPER)
1152  {
1157  CALLBACK_EVENT|WAVE_MAPPED,&capsA,
1163  CALLBACK_EVENT|WAVE_MAPPED,&capsA,
1169  CALLBACK_EVENT|WAVE_MAPPED,&capsA,
1171  }
1172  }
1173  VirtualFree(twoPages, 0, MEM_RELEASE);
1174  }
1175 
1176  /* try some non PCM formats */
1177  format.wFormatTag=WAVE_FORMAT_MULAW;
1178  format.nChannels=1;
1179  format.wBitsPerSample=8;
1180  format.nSamplesPerSec=8000;
1181  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1182  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1183  format.cbSize=0;
1185  ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
1187  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1188  if (rc==MMSYSERR_NOERROR) {
1189  waveOutClose(wout);
1196  } else {
1197  MMRESULT query_rc;
1198 
1199  trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n",
1200  dev_name(device));
1201 
1202  query_rc = waveOutOpen(NULL, device, &format, 0, 0, CALLBACK_NULL | WAVE_FORMAT_QUERY);
1203  ok(query_rc==MMSYSERR_NOERROR || query_rc==WAVERR_BADFORMAT || query_rc==MMSYSERR_INVALPARAM,
1204  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1205 
1206  rc = waveOutOpen(&wout, device, &format, 0, 0, CALLBACK_NULL);
1207  ok(rc == query_rc,
1208  "waveOutOpen(%s): returned different from query: %s\n",dev_name(device),wave_out_error(rc));
1209  if(rc == MMSYSERR_NOERROR)
1210  waveOutClose(wout);
1211  }
1212 
1214  wfa.wfx.nChannels=1;
1215  wfa.wfx.nSamplesPerSec=11025;
1216  wfa.wfx.nAvgBytesPerSec=5588;
1217  wfa.wfx.nBlockAlign=256;
1218  wfa.wfx.wBitsPerSample=4; /* see imaadp32.c */
1219  wfa.wfx.cbSize=2;
1220  wfa.wSamplesPerBlock=505;
1222  ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
1224  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1225  if (rc==MMSYSERR_NOERROR) {
1226  waveOutClose(wout);
1227  /* TODO: teach wave_generate_* ADPCM
1228  wave_out_test_deviceOut(device,1.0,1,0,&wfa.wfx,0,CALLBACK_EVENT,
1229  &capsA,winetest_interactive,TRUE,FALSE);
1230  wave_out_test_deviceOut(device,1.0,10,0,&wfa.wfx,0,CALLBACK_EVENT,
1231  &capsA,winetest_interactive,TRUE,FALSE);
1232  wave_out_test_deviceOut(device,1.0,5,1,&wfa.wfx,0,CALLBACK_EVENT,
1233  &capsA,winetest_interactive,TRUE,FALSE);
1234  */
1235  } else
1236  trace("waveOutOpen(%s): WAVE_FORMAT_IMA_ADPCM not supported\n",
1237  dev_name(device));
1238 
1239  /* test if WAVEFORMATEXTENSIBLE supported */
1241  wfex.Format.nChannels=2;
1242  wfex.Format.wBitsPerSample=16;
1243  wfex.Format.nSamplesPerSec=22050;
1246  wfex.Format.nBlockAlign;
1247  wfex.Format.cbSize=22;
1251  rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
1253  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
1255  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1256  if (rc==MMSYSERR_NOERROR) {
1257  waveOutClose(wout);
1260  TRUE,FALSE);
1263  TRUE,FALSE);
1266  TRUE,FALSE);
1267  } else
1268  trace("waveOutOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
1269  dev_name(device));
1270 
1271  /* test if 4 channels supported */
1273  wfex.Format.nChannels=4;
1274  wfex.Format.wBitsPerSample=16;
1275  wfex.Format.nSamplesPerSec=22050;
1278  wfex.Format.nBlockAlign;
1279  wfex.Format.cbSize=22;
1283  rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
1285  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
1287  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1288  if (rc==MMSYSERR_NOERROR) {
1289  waveOutClose(wout);
1296  } else
1297  trace("waveOutOpen(%s): 4 channels not supported\n",
1298  dev_name(device));
1299 
1300  /* test if 6 channels supported */
1302  wfex.Format.nChannels=6;
1303  wfex.Format.wBitsPerSample=16;
1304  wfex.Format.nSamplesPerSec=22050;
1307  wfex.Format.nBlockAlign;
1308  wfex.Format.cbSize=22;
1312  rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
1314  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
1316  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1317  if (rc==MMSYSERR_NOERROR) {
1318  waveOutClose(wout);
1321  TRUE,FALSE);
1324  TRUE,FALSE);
1327  TRUE,FALSE);
1328  } else
1329  trace("waveOutOpen(%s): 6 channels not supported\n",
1330  dev_name(device));
1331 
1332  if (0)
1333  {
1334  /* FIXME: ALSA doesn't like this format */
1335  /* test if 24 bit samples supported */
1337  wfex.Format.nChannels=2;
1338  wfex.Format.wBitsPerSample=24;
1339  wfex.Format.nSamplesPerSec=22050;
1342  wfex.Format.nBlockAlign;
1343  wfex.Format.cbSize=22;
1347  rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
1349  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
1351  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1352  if (rc==MMSYSERR_NOERROR) {
1353  waveOutClose(wout);
1356  TRUE,FALSE);
1357  } else
1358  trace("waveOutOpen(%s): 24 bit samples not supported\n",
1359  dev_name(device));
1360  }
1361 
1362  /* test if 32 bit samples supported */
1364  wfex.Format.nChannels=2;
1365  wfex.Format.wBitsPerSample=32;
1366  wfex.Format.nSamplesPerSec=22050;
1369  wfex.Format.nBlockAlign;
1370  wfex.Format.cbSize=22;
1374  rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
1376  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
1378  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1379  if (rc==MMSYSERR_NOERROR) {
1380  waveOutClose(wout);
1383  TRUE,FALSE);
1386  TRUE,FALSE);
1389  TRUE,FALSE);
1390  } else
1391  trace("waveOutOpen(%s): 32 bit samples not supported\n",
1392  dev_name(device));
1393 
1394  /* test if 32 bit float samples supported */
1396  wfex.Format.nChannels=2;
1397  wfex.Format.wBitsPerSample=32;
1398  wfex.Format.nSamplesPerSec=22050;
1401  wfex.Format.nBlockAlign;
1402  wfex.Format.cbSize=22;
1406  rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
1408  ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
1410  "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
1411  if (rc==MMSYSERR_NOERROR) {
1412  waveOutClose(wout);
1415  TRUE,FALSE);
1418  TRUE,FALSE);
1421  TRUE,FALSE);
1422  } else
1423  trace("waveOutOpen(%s): 32 bit float samples not supported\n",
1424  dev_name(device));
1425 }
1426 
1427 static void wave_out_tests(void)
1428 {
1429  WAVEOUTCAPSA capsA;
1430  WAVEOUTCAPSW capsW;
1432  HWAVEOUT wout;
1433  MMRESULT rc;
1434  DWORD preferred, status;
1435  UINT ndev,d;
1436 
1437  ndev=waveOutGetNumDevs();
1438  trace("found %d WaveOut devices\n",ndev);
1439 
1441  (DWORD_PTR)&preferred, (DWORD_PTR)&status);
1442  ok((ndev == 0 && (rc == MMSYSERR_NODRIVER || rc == MMSYSERR_BADDEVICEID)) ||
1443  rc == MMSYSERR_NOTSUPPORTED ||
1444  rc == MMSYSERR_NOERROR, "waveOutMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc);
1445 
1446  if(rc != MMSYSERR_NOTSUPPORTED)
1447  ok((ndev == 0 && (preferred == -1 || broken(preferred != -1))) ||
1448  preferred < ndev, "Got invalid preferred device: 0x%x\n", preferred);
1449 
1450  rc=waveOutGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
1452  "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
1453  dev_name(ndev+1),mmsys_error(rc));
1454 
1455  rc=waveOutGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
1457  "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
1458  "expected, got %s\n",dev_name(ndev+1),mmsys_error(rc));
1459 
1460  rc=waveOutGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
1461  if (ndev>0)
1462  ok(rc==MMSYSERR_NOERROR,
1463  "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
1465  else
1467  "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
1468  "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
1469 
1470  rc=waveOutGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
1471  if (ndev>0)
1473  "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
1474  "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
1475  else
1478  "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
1479  " or MMSYSERR_NOTSUPPORTED expected, got %s\n",
1481 
1482  format.wFormatTag=WAVE_FORMAT_PCM;
1483  format.nChannels=2;
1484  format.wBitsPerSample=16;
1485  format.nSamplesPerSec=44100;
1486  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1487  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1488  format.cbSize=0;
1489  rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
1491  "waveOutOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
1492  dev_name(ndev+1),mmsys_error(rc));
1493 
1495  for (d=0;d<ndev;d++)
1497 
1498  if (ndev>0)
1500 }
1501 
1502 static void test_sndPlaySound(void)
1503 {
1504  BOOL br;
1505 
1506  static const WCHAR not_existW[] = {'C',':','\\','n','o','t','_','e','x','i','s','t','.','w','a','v',0};
1507  static const WCHAR SystemAsteriskW[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0};
1508 
1510  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1511 
1513  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1514 
1516  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1517 
1519  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1520 
1521  br = sndPlaySoundA("SystemAsterisk", SND_ALIAS|SND_SYNC);
1522  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1523 
1524  br = sndPlaySoundW(SystemAsteriskW, SND_ALIAS|SND_SYNC);
1525  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1526 
1527  br = sndPlaySoundA("C:\not_exist.wav", SND_FILENAME|SND_SYNC);
1528  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1529 
1530  br = sndPlaySoundW(not_existW, SND_FILENAME|SND_SYNC);
1531  ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br);
1532 }
1533 
1534 static void test_fragmentsize(void)
1535 {
1536  MMRESULT rc;
1537  WAVEHDR hdr[2];
1538  HWAVEOUT wout;
1539  WAVEFORMATEX fmt;
1540  MMTIME mmtime;
1541  DWORD wait;
1542  HANDLE hevent;
1543 
1544  if(waveOutGetNumDevs() == 0)
1545  return;
1546 
1547  fmt.wFormatTag = WAVE_FORMAT_PCM;
1548  fmt.nChannels = 2;
1549  fmt.nSamplesPerSec = 44100;
1550  fmt.wBitsPerSample = 16;
1551  fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
1552  fmt.nAvgBytesPerSec = fmt.nBlockAlign * fmt.nSamplesPerSec;
1553  fmt.cbSize = sizeof(WAVEFORMATEX);
1554 
1557 
1560  ok(rc == MMSYSERR_NOERROR || rc == WAVERR_BADFORMAT ||
1561  rc == MMSYSERR_INVALFLAG || rc == MMSYSERR_INVALPARAM,
1562  "waveOutOpen(%s) failed: %s\n", dev_name(WAVE_MAPPER), wave_out_error(rc));
1563  if(rc != MMSYSERR_NOERROR){
1565  return;
1566  }
1567 
1568  wait = WaitForSingleObject(hevent, 1000);
1569  ok(wait == WAIT_OBJECT_0, "wave open callback missed\n");
1570 
1571  memset(hdr, 0, sizeof(hdr));
1572  hdr[0].dwBufferLength = (fmt.nSamplesPerSec * fmt.nBlockAlign / 4) + 1;
1573  hdr[1].dwBufferLength = hdr[0].dwBufferLength - 2;
1574  hdr[1].lpData = hdr[0].lpData =
1575  HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, hdr[0].dwBufferLength);
1576 
1577  rc = waveOutPrepareHeader(wout, &hdr[0], sizeof(hdr[0]));
1578  ok(rc == MMSYSERR_NOERROR, "waveOutPrepareHeader failed: %s\n", wave_out_error(rc));
1579 
1580  rc = waveOutPrepareHeader(wout, &hdr[1], sizeof(hdr[1]));
1581  ok(rc == MMSYSERR_NOERROR, "waveOutPrepareHeader failed: %s\n", wave_out_error(rc));
1582 
1583  trace("writing %u bytes then %u bytes\n", hdr[0].dwBufferLength, hdr[1].dwBufferLength);
1584  rc = waveOutWrite(wout, &hdr[0], sizeof(hdr[0]));
1585  ok(rc == MMSYSERR_NOERROR, "waveOutWrite failed: %s\n", wave_out_error(rc));
1586 
1587  rc = waveOutWrite(wout, &hdr[1], sizeof(hdr[1]));
1588  ok(rc == MMSYSERR_NOERROR, "waveOutWrite failed: %s\n", wave_out_error(rc));
1589 
1590  wait = WaitForSingleObject(hevent, 1000);
1591  ok(wait == WAIT_OBJECT_0, "header 1 callback missed\n");
1592 
1593  wait = WaitForSingleObject(hevent, 1000);
1594  ok(wait == WAIT_OBJECT_0, "header 2 callback missed\n");
1595 
1596  memset(&mmtime, 0, sizeof(mmtime));
1597  mmtime.wType = TIME_BYTES;
1598 
1599  rc = waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
1600  ok(rc == MMSYSERR_NOERROR, "waveOutGetPosition failed: %s\n", wave_out_error(rc));
1601 
1602  /* windows behavior is inconsistent */
1603  ok(mmtime.u.cb == 88200 ||
1604  mmtime.u.cb == 88196, "after position: %u\n", mmtime.u.cb);
1605 
1606  rc = waveOutClose(wout);
1607  ok(rc == MMSYSERR_NOERROR, "waveOutClose failed: %s\n", wave_out_error(rc));
1608 
1609  HeapFree(GetProcessHeap(), 0, hdr[0].lpData);
1611 }
1612 
1613 static void create_wav_file(char *temp_file)
1614 {
1616  HMMIO h;
1617  MMCKINFO riff_chunk, chunk;
1618  MMRESULT rc;
1619  LONG written;
1620  DWORD length;
1621  char *buffer;
1622 
1623  format.wFormatTag=WAVE_FORMAT_PCM;
1624  format.cbSize = 0;
1625  format.nChannels=1;
1626  format.wBitsPerSample=8;
1627  format.nSamplesPerSec=8000;
1628  format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1629  format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1630 
1632  ok(h != NULL, "Can't open temp_file\n");
1633 
1634  riff_chunk.fccType = mmioFOURCC('W','A','V','E');
1635  riff_chunk.cksize = 0;
1636  rc = mmioCreateChunk(h, &riff_chunk, MMIO_CREATERIFF);
1637  ok(rc == MMSYSERR_NOERROR, "mmioCreateChunk failed, got %u\n", rc);
1638 
1639  chunk.ckid = mmioFOURCC('f','m','t',' ');
1640  chunk.cksize = 0;
1641  rc = mmioCreateChunk(h, &chunk, 0);
1642  ok(rc == MMSYSERR_NOERROR, "mmioCreateChunk failed, got %u\n", rc);
1643  written = mmioWrite(h, (char*)&format, sizeof(format));
1644  ok(written == sizeof(format), "mmioWrite failed, got %d\n", written);
1645  rc = mmioAscend(h, &chunk, 0);
1646  ok(rc == MMSYSERR_NOERROR, "mmioAscend failed, got %d\n", rc);
1647 
1648  chunk.ckid = mmioFOURCC('d','a','t','a');
1649  rc = mmioCreateChunk(h, &chunk, 0);
1650  ok(rc == MMSYSERR_NOERROR, "mmioCreateChunk failed, got %u\n", rc);
1652  written = mmioWrite(h, buffer, length);
1653  ok(written == length, "mmioWrite failed, got %d\n", written);
1654  rc = mmioAscend(h, &chunk, 0);
1655  ok(rc == MMSYSERR_NOERROR, "mmioAscend failed, got %d\n", rc);
1657 
1658  rc = mmioAscend(h, &riff_chunk, 0);
1659  ok(rc == MMSYSERR_NOERROR, "mmioAscend failed, got %d\n", rc);
1660 
1661  rc = mmioClose(h, 0);
1662  ok(rc == MMSYSERR_NOERROR, "mmioClose failed, got %u\n", rc);
1663 }
1664 
1665 static void test_PlaySound(void)
1666 {
1667  BOOL br;
1668  char test_file[MAX_PATH], temp[MAX_PATH], *exts;
1669  void *psound_ordinal, *psound_name;
1670  HMODULE dll = GetModuleHandleA("winmm.dll");
1671 
1672  psound_name = GetProcAddress(dll, "PlaySound");
1673  psound_ordinal = GetProcAddress(dll, (LPCSTR) 2);
1674  ok(psound_name == psound_ordinal, "Expected ordinal 2 to be PlaySound function\n");
1675 
1676  if(waveOutGetNumDevs() == 0) {
1677  skip("No output devices available\n");
1678  return;
1679  }
1680 
1681  GetTempPathA(sizeof(test_file), test_file);
1682  strcat(test_file, "mysound.wav");
1684 
1686  ok(br, "PlaySound failed, got %d\n", br);
1687 
1688  /* SND_ALIAS fallbacks to SND_FILENAME */
1690  ok(br, "PlaySound failed, got %d\n", br);
1691 
1692  strcpy(temp, test_file);
1693  exts = strrchr(temp, '.');
1694 
1695  /* no extensions */
1696  *exts = '\0';
1698  ok(br, "PlaySound failed, got %d\n", br);
1699 
1700  /* ends with a dot */
1701  strcpy(exts, ".");
1703  ok(!br || broken(br), "PlaySound succeeded, got %d\n", br);
1704 
1706 }
1707 
1709 {
1711  wave_out_tests();
1714  test_PlaySound();
1715 }
UINT WINAPI waveOutGetPosition(HWAVEOUT hWaveOut, LPMMTIME lpTime, UINT uSize)
Definition: winmm.c:2416
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176
#define WAVECAPS_PITCH
Definition: mmsystem.h:198
#define WOM_DONE
Definition: mmsystem.h:183
#define WAVE_FORMAT_IBM_CVSD
Definition: mmreg.h:98
#define MMIOERR_CANNOTSEEK
Definition: mmsystem.h:515
#define SND_SYNC
Definition: mmsystem.h:153
#define WAVE_FORMAT_SIERRA_ADPCM
Definition: mmreg.h:105
#define SND_ALIAS_ID
Definition: mmsystem.h:161
#define WAVE_FORMAT_QUERY
Definition: mmsystem.h:188
Definition: tftpd.h:59
#define JOYERR_PARMS
Definition: mmsystem.h:430
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define MMIOERR_CANNOTCLOSE
Definition: mmsystem.h:512
char hdr[14]
Definition: iptest.cpp:33
#define MMIOERR_CANNOTEXPAND
Definition: mmsystem.h:516
const char * wave_out_error(MMRESULT error)
Definition: wave.c:270
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
struct mmtime_tag::@2933::@2934 smpte
Definition: fci.c:109
#define JOYERR_NOCANDO
Definition: mmsystem.h:431
#define DWORD_PTR
Definition: treelist.c:76
#define WideCharToMultiByte
Definition: compat.h:101
#define DRVM_MAPPER_PREFERRED_GET
Definition: mmsys.h:37
#define WAVE_FORMAT_DSPGROUP_TRUESPEECH
Definition: mmreg.h:112
#define error(str)
Definition: mkdosfs.c:1605
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define WAVE_FORMAT_APTX
Definition: mmreg.h:115
UINT WINAPI waveOutMessage(HWAVEOUT hWaveOut, UINT uMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: winmm.c:2541
static void test_fragmentsize(void)
Definition: wave.c:1534
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define ERR_TO_STR(dev)
#define WAVECAPS_SYNC
Definition: mmsystem.h:202
static IBackgroundCopyFile * test_file
Definition: file.c:39
#define WAVE_FORMAT_DIGISTD
Definition: mmreg.h:107
#define MMIOERR_CANNOTWRITE
Definition: mmsystem.h:514
#define CP_ACP
Definition: compat.h:99
#define SND_NODEFAULT
Definition: mmsystem.h:155
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
#define WHDR_BEGINLOOP
Definition: mmsystem.h:195
DWORD cb
Definition: mmsystem.h:969
UINT wType
Definition: mmsystem.h:965
#define MIDIERR_STILLPLAYING
Definition: mmsystem.h:232
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1204
char CHAR
Definition: xmlstorage.h:175
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
WORD nChannels
Definition: mmreg.h:79
const GLint * first
Definition: glext.h:5794
#define WAVE_FORMAT_AUDIOFILE_AF36
Definition: mmreg.h:114
#define WAVE_ALLOWSYNC
Definition: mmsystem.h:189
#define WHDR_ENDLOOP
Definition: mmsystem.h:196
#define CALLBACK
Definition: compat.h:27
const char * fmt
Definition: wsprintf.c:30
static const unsigned int win_formats[][4]
Definition: render.c:47
static void wave_out_test_deviceOut(int device, double duration, int headers, int loops, WAVEFORMATEX *pwfx, DWORD format, DWORD flags, WAVEOUTCAPSA *pcaps, BOOL interactive, BOOL sine, BOOL pause)
Definition: wave.c:605
#define WAVE_FORMAT_SONARC
Definition: mmreg.h:111
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define SPEAKER_ALL
Definition: ksmedia.h:1345
BOOL WINAPI sndPlaySoundW(LPCWSTR pszSound, UINT uFlags)
Definition: playsound.c:548
#define WAVE_FORMAT_CONTROL_RES_CR10
Definition: mmreg.h:123
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
const char * dev_name(int device)
Definition: wave.c:211
#define WAVE_FORMAT_OLICELP
Definition: mmreg.h:136
UINT MMRESULT
Definition: mmsystem.h:962
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
GLuint buffer
Definition: glext.h:5915
static void test_multiple_waveopens(void)
Definition: wave.c:50
#define JOYERR_UNPLUGGED
Definition: mmsystem.h:432
#define DRV_QUERYDEVICEINTERFACESIZE
Definition: mmddk.h:97
vector< Header * > headers
Definition: sdkparse.cpp:39
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
#define MIXERR_INVALCONTROL
Definition: mmsystem.h:296
#define interactive
Definition: rosglue.h:34
#define WAVECAPS_VOLUME
Definition: mmsystem.h:200
#define SND_ALIAS_SYSTEMASTERISK
Definition: mmsystem.h:168
#define MIXERR_INVALLINE
Definition: mmsystem.h:295
LPSTR lpData
Definition: mmsystem.h:1014
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
int winetest_interactive
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define MMIOERR_FILENOTFOUND
Definition: mmsystem.h:509
BOOL WINAPI PlaySoundA(LPCSTR pszSoundA, HMODULE hmod, DWORD fdwSound)
Definition: playsound.c:523
#define CALLBACK_TYPEMASK
Definition: mmsystem.h:146
static void test_sndPlaySound(void)
Definition: wave.c:1502
unsigned char wave[]
Definition: in.h:3
GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
#define TIMERR_NOCANDO
Definition: mmsystem.h:419
int nChannels
Definition: pcmconverter.c:95
#define WOM_OPEN
Definition: mmsystem.h:181
#define lstrlenW
Definition: compat.h:415
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:692
#define MEM_COMMIT
Definition: nt_native.h:1313
#define WAVE_FORMAT_OKI_ADPCM
Definition: mmreg.h:101
int winetest_debug
static const char * wave_header_flags(DWORD flags)
Definition: wave.c:335
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 waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
#define TIME_SAMPLES
Definition: mmsystem.h:29
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define WAVE_FORMAT_MEDIASPACE_ADPCM
Definition: mmreg.h:104
#define WAVE_FORMAT_MPEG
Definition: mmreg.h:126
#define PM_NOREMOVE
Definition: winuser.h:1181
#define WAVE_FORMAT_DIRECT
Definition: mmsystem.h:191
#define WAVE_FORMAT_CREATIVE_ADPCM
Definition: mmreg.h:130
DWORD dwLoops
Definition: mmsystem.h:1019
union WAVEFORMATEXTENSIBLE::@2920 Samples
static HMODULE dll
Definition: str.c:188
#define sprintf(buf, format,...)
Definition: sprintf.c:55
const char * get_format_str(WORD format)
Definition: wave.c:408
#define WAVECAPS_SAMPLEACCURATE
Definition: mmsystem.h:203
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
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:93
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define WOM_CLOSE
Definition: mmsystem.h:182
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UINT WINAPI waveOutGetVolume(HWAVEOUT hWaveOut, LPDWORD lpdw)
Definition: winmm.c:2488
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define WAVE_FORMAT_DIGIFIX
Definition: mmreg.h:108
#define MIDIERR_UNPREPARED
Definition: mmsystem.h:231
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
DWORD bytes_to_samples(DWORD bytes, LPWAVEFORMATEX pwfx)
Definition: wave.c:461
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
UINT WINAPI waveOutGetDevCapsW(UINT_PTR uDeviceID, LPWAVEOUTCAPSW lpCaps, UINT uSize)
Definition: winmm.c:2176
unsigned int BOOL
Definition: ntddk_ex.h:94
const GUID KSDATAFORMAT_SUBTYPE_PCM
Definition: wave.c:16
long LONG
Definition: pedump.c:60
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
Definition: devices.h:37
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
#define WAVECAPS_LRVOLUME
Definition: mmsystem.h:201
DWORD dwFlags
Definition: mmsystem.h:1018
#define WAVE_FORMAT_AUDIOFILE_AF10
Definition: mmreg.h:116
#define WAVE_FORMAT_2M08
Definition: mmsystem.h:210
#define WAVE_FORMAT_MULAW
Definition: constants.h:428
static char * wave_generate_silence(WAVEFORMATEX *wfx, double duration, DWORD *size)
Definition: wave.c:157
#define MEM_RESERVE
Definition: nt_native.h:1314
WORD wBitsPerSample
Definition: audioclient.idl:45
struct _WAVEFORMATEX * LPWAVEFORMATEX
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:781
#define WAVE_FORMAT_2M16
Definition: mmsystem.h:212
const char * wave_open_flags(DWORD flags)
Definition: wave.c:284
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define WAVE_FORMAT_G723_ADPCM
Definition: mmreg.h:106
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
smooth NULL
Definition: ftsmooth.c:416
#define MMIOERR_UNBUFFERED
Definition: mmsystem.h:518
MMVERSION vDriverVersion
Definition: mmsystem.h:1027
#define WAVE_FORMAT_CREATIVE_FASTSPEECH10
Definition: mmreg.h:132
unsigned char
Definition: typeof.h:29
#define SND_ALIAS
Definition: mmsystem.h:160
UINT WINAPI waveOutSetVolume(HWAVEOUT hWaveOut, DWORD dw)
Definition: winmm.c:2508
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
FOURCC fccType
Definition: mmsystem.h:1509
const char * LPCSTR
Definition: xmlstorage.h:183
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2140
static void check_position(int device, HWAVEOUT wout, DWORD bytes, LPWAVEFORMATEX pwfx)
Definition: wave.c:489
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:458
#define sndAlias(c0, c1)
Definition: mmsystem.h:167
#define b
Definition: ke_i.h:79
START_TEST(wave)
Definition: wave.c:1708
DWORD nSamplesPerSec
Definition: audioclient.idl:42
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static const WCHAR nameW[]
Definition: main.c:46
static void wave_out_test_device(UINT_PTR device)
Definition: wave.c:881
#define TIME_FORMAT(f)
#define WAVE_FORMAT_DIGIREAL
Definition: mmreg.h:121
MmuTrapHandler callback[0x30]
Definition: mmuobject.c:44
GLfloat f
Definition: glext.h:7540
DWORD sample
Definition: mmsystem.h:968
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLsizeiptr size
Definition: glext.h:5919
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define WAVE_FORMAT_NMS_VBXADPCM
Definition: mmreg.h:124
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define GetProcessHeap()
Definition: compat.h:403
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define d
Definition: ke_i.h:81
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
DWORD bytes_to_ms(DWORD bytes, LPWAVEFORMATEX pwfx)
Definition: wave.c:466
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
#define MIXERR_INVALVALUE
Definition: mmsystem.h:297
__wchar_t WCHAR
Definition: xmlstorage.h:180
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2374
WAVEFORMATEX Format
Definition: ksmedia.h:538
#define WAVE_FORMAT_CONTROL_RES_VQLPC
Definition: mmreg.h:120
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define WAVE_FORMAT(f)
#define TIME_MS
Definition: mmsystem.h:28
#define MMIOERR_OUTOFMEMORY
Definition: mmsystem.h:510
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
const GLubyte * c
Definition: glext.h:8905
#define WAVE_FORMAT_OLIADPCM
Definition: mmreg.h:135
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 CALLBACK_THREAD
Definition: mmsystem.h:151
#define MMSYSERR_INVALFLAG
Definition: mmsystem.h:106
#define NB_WIN_FORMATS
Definition: winmm_test.h:71
DWORD cksize
Definition: mmsystem.h:1508
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define WAVERR_SYNC
Definition: mmsystem.h:179
Definition: id3.c:18
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define PI
Definition: wave.c:97
#define MMSYSERR_NOTENABLED
Definition: mmsystem.h:99
BOOL WINAPI sndPlaySoundA(LPCSTR pszSoundA, UINT uFlags)
Definition: playsound.c:539
#define WAVECAPS_PLAYBACKRATE
Definition: mmsystem.h:199
GLbitfield flags
Definition: glext.h:7161
#define WAIT_TIMEOUT
Definition: dderror.h:14
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2344
#define MIDIERR_INVALIDSETUP
Definition: mmsystem.h:236
static HANDLE thread
Definition: service.c:33
#define MMIOERR_CANNOTREAD
Definition: mmsystem.h:513
WORD wFormatTag
Definition: mmreg.h:78
int ret
#define WAVE_FORMAT_OLISBC
Definition: mmreg.h:137
#define WAVE_FORMAT_DEVELOPMENT
Definition: mmreg.h:160
#define todo_wine
Definition: test.h:163
#define WAVE_FORMAT_YAMAHA_ADPCM
Definition: mmreg.h:110
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO *lpck, UINT uFlags)
Definition: mmio.c:1238
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define TIME_SMPTE
Definition: mmsystem.h:31
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define ADD_FLAG(f)
LPVOID lpParameter
Definition: kernel32.h:241
#define MMSYSERR_BADERRNUM
Definition: mmsystem.h:105
DWORD dwBufferLength
Definition: mmsystem.h:1015
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define WM_APP
Definition: eventvwr.h:70
#define DRV_QUERYMAPPABLE
Definition: mmddk.h:93
uint32_t DWORD_PTR
Definition: typedefs.h:63
static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD dwParam1, DWORD dwParam2)
Definition: wave.c:572
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define WM_USER
Definition: winuser.h:1877
#define WAVE_FORMAT_ADPCM
Definition: constants.h:426
#define broken(x)
Definition: _sntprintf.h:21
#define MMIO_CREATERIFF
Definition: mmsystem.h:554
static const struct encodedExtensions exts[]
Definition: encode.c:2703
UINT WINAPI waveOutGetErrorTextA(UINT uError, LPSTR lpText, UINT uSize)
Definition: winmm.c:2201
#define SND_FILENAME
Definition: mmsystem.h:162
WORD wValidBitsPerSample
Definition: ksmedia.h:541
DWORD dwPageSize
Definition: winbase.h:1133
#define CALLBACK_NULL
Definition: mmsystem.h:147
#define WAVE_FORMAT_FM_TOWNS_SND
Definition: mmreg.h:133
static const char * wave_out_caps(DWORD dwSupport)
Definition: wave.c:374
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
#define WAVE_FORMAT_OLIOPR
Definition: mmreg.h:138
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
#define TIME_TICKS
Definition: mmsystem.h:33
static float(__cdecl *square_half_float)(float x
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
static calc_node_t temp
Definition: rpn_ieee.c:38
#define WHDR_INQUEUE
Definition: mmsystem.h:197
#define MMIOERR_CHUNKNOTFOUND
Definition: mmsystem.h:517
#define f
Definition: ke_i.h:83
static DWORD thread_id
Definition: protocol.c:159
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
static void test_PlaySound(void)
Definition: wave.c:1665
static DWORD WINAPI callback_thread(LPVOID lpParameter)
Definition: wave.c:581
#define ok(value,...)
Definition: atltest.h:57
#define WAVE_FORMAT_DIALOGIC_OKI_ADPCM
Definition: mmreg.h:109
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
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static void create_wav_file(char *temp_file)
Definition: wave.c:1613
#define WHDR_PREPARED
Definition: mmsystem.h:194
UINT WINAPI waveOutGetDevCapsA(UINT_PTR uDeviceID, LPWAVEOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:2148
union mmtime_tag::@2933 u
#define WAVE_FORMAT_ALAW
Definition: constants.h:427
#define skip(...)
Definition: atltest.h:64
DWORD nSamplesPerSec
Definition: mmreg.h:80
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2402
#define msg(x)
Definition: auth_time.c:54
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
#define MMIOERR_CANNOTOPEN
Definition: mmsystem.h:511
WORD nBlockAlign
Definition: mmreg.h:82
#define MEM_RELEASE
Definition: nt_native.h:1316
Definition: name.c:38
GLuint res
Definition: glext.h:9613
#define MIDIERR_NOTREADY
Definition: mmsystem.h:234
WORD wBitsPerSample
Definition: mmreg.h:83
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define WAVE_FORMAT_DIGIADPCM
Definition: mmreg.h:122
#define WHDR_DONE
Definition: mmsystem.h:193
#define WAVE_FORMAT_DOLBY_AC2
Definition: mmreg.h:117
#define GetProcAddress(x, y)
Definition: compat.h:418
#define MMIO_CREATE
Definition: mmsystem.h:528
#define WAVE_FORMAT_GSM610
Definition: mmreg.h:118
#define WAVE_FORMAT_ECHOSC1
Definition: mmreg.h:113
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:128
#define MIDIERR_NODEVICE
Definition: mmsystem.h:235
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1028
#define WAVE_FORMAT_CREATIVE_FASTSPEECH8
Definition: mmreg.h:131
#define TIME_MIDI
Definition: mmsystem.h:32
#define WHDR_MASK
#define MMIO_WRITE
Definition: mmsystem.h:536
static void wave_out_tests(void)
Definition: wave.c:1427
#define memset(x, y, z)
Definition: compat.h:39
DWORD ms
Definition: mmsystem.h:967
static SERVICE_STATUS status
Definition: service.c:31
#define DRV_QUERYDEVICEINTERFACE
Definition: mmddk.h:96
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WAVE_FORMAT_OLIGSM
Definition: mmreg.h:134
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388
Definition: dsound.c:943
static DWORD g_tid
Definition: wave.c:48
#define HeapFree(x, y, z)
Definition: compat.h:402
DWORD time_to_bytes(LPMMTIME mmtime, LPWAVEFORMATEX pwfx)
Definition: wave.c:471
static char * wave_generate_la(WAVEFORMATEX *wfx, double duration, DWORD *size)
Definition: wave.c:98
#define TIMERR_STRUCT
Definition: mmsystem.h:420
#define WAVE_FORMAT_G721_ADPCM
Definition: mmreg.h:125
#define WAVE_FORMAT_EXTENSIBLE
Definition: ksmedia.h:551
WAVEFORMATEX wfx
Definition: mmreg.h:187
#define WAVE_FORMAT_ANTEX_ADPCME
Definition: mmreg.h:119
#define PAGE_READWRITE
Definition: nt_native.h:1304
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
Definition: ps.c:97
GLuint const GLchar * name
Definition: glext.h:6031