Don't include 'mmddk.h', it's not needed. The winmm tests can now be
[wine/wine-kai.git] / dlls / winmm / tests / wave.c
blob76866ecc231c3a911f5376921877d54898e96641
1 /*
2 * Test winmm sound playback in each sound format
4 * Copyright (c) 2002 Francois Gouget
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
26 #include "wine/test.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "mmsystem.h"
31 #define NOBITMAP
32 #include "mmreg.h"
33 #include "ks.h"
34 #include "ksguid.h"
35 #include "ksmedia.h"
37 #include "winmm_test.h"
40 * Note that in most of this test we may get MMSYSERR_BADDEVICEID errors
41 * at about any time if the user starts another application that uses the
42 * sound device. So we should not report these as test failures.
44 * This test can play a test tone. But this only makes sense if someone
45 * is going to carefully listen to it, and would only bother everyone else.
46 * So this is only done if the test is being run in interactive mode.
49 #define PI 3.14159265358979323846
50 static char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
52 int i,j;
53 int nb_samples;
54 char* buf;
55 char* b;
56 WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE*)wfx;
58 nb_samples=(int)(duration*wfx->nSamplesPerSec);
59 *size=nb_samples*wfx->nBlockAlign;
60 b=buf=malloc(*size);
61 for (i=0;i<nb_samples;i++) {
62 double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
63 if (wfx->wBitsPerSample==8) {
64 unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
65 for (j = 0; j < wfx->nChannels; j++)
66 *b++=sample;
67 } else if (wfx->wBitsPerSample==16) {
68 signed short sample=(signed short)((double)32767.5*y-0.5);
69 for (j = 0; j < wfx->nChannels; j++) {
70 b[0]=sample & 0xff;
71 b[1]=sample >> 8;
72 b+=2;
74 } else if (wfx->wBitsPerSample==24) {
75 signed int sample=(signed int)(((double)0x7fffff+0.5)*y-0.5);
76 for (j = 0; j < wfx->nChannels; j++) {
77 b[0]=sample & 0xff;
78 b[1]=(sample >> 8) & 0xff;
79 b[2]=(sample >> 16) & 0xff;
80 b+=3;
82 } else if ((wfx->wBitsPerSample==32) && ((wfx->wFormatTag == WAVE_FORMAT_PCM) ||
83 ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
84 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)))) {
85 signed int sample=(signed int)(((double)0x7fffffff+0.5)*y-0.5);
86 for (j = 0; j < wfx->nChannels; j++) {
87 b[0]=sample & 0xff;
88 b[1]=(sample >> 8) & 0xff;
89 b[2]=(sample >> 16) & 0xff;
90 b[3]=(sample >> 24) & 0xff;
91 b+=4;
93 } else if ((wfx->wBitsPerSample==32) && (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
94 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
95 union { float f; char c[4]; } sample;
96 sample.f=y;
97 for (j = 0; j < wfx->nChannels; j++) {
98 b[0]=sample.c[0];
99 b[1]=sample.c[1];
100 b[2]=sample.c[2];
101 b[3]=sample.c[3];
102 b+=4;
106 return buf;
109 const char * dev_name(int device)
111 static char name[16];
112 if (device == WAVE_MAPPER)
113 return "WAVE_MAPPER";
114 sprintf(name, "%d", device);
115 return name;
118 const char* mmsys_error(MMRESULT error)
120 #define ERR_TO_STR(dev) case dev: return #dev
121 static char unknown[32];
122 switch (error) {
123 ERR_TO_STR(MMSYSERR_NOERROR);
124 ERR_TO_STR(MMSYSERR_ERROR);
125 ERR_TO_STR(MMSYSERR_BADDEVICEID);
126 ERR_TO_STR(MMSYSERR_NOTENABLED);
127 ERR_TO_STR(MMSYSERR_ALLOCATED);
128 ERR_TO_STR(MMSYSERR_INVALHANDLE);
129 ERR_TO_STR(MMSYSERR_NODRIVER);
130 ERR_TO_STR(MMSYSERR_NOMEM);
131 ERR_TO_STR(MMSYSERR_NOTSUPPORTED);
132 ERR_TO_STR(MMSYSERR_BADERRNUM);
133 ERR_TO_STR(MMSYSERR_INVALFLAG);
134 ERR_TO_STR(MMSYSERR_INVALPARAM);
135 ERR_TO_STR(WAVERR_BADFORMAT);
136 ERR_TO_STR(WAVERR_STILLPLAYING);
137 ERR_TO_STR(WAVERR_UNPREPARED);
138 ERR_TO_STR(WAVERR_SYNC);
139 ERR_TO_STR(MIDIERR_UNPREPARED);
140 ERR_TO_STR(MIDIERR_STILLPLAYING);
141 ERR_TO_STR(MIDIERR_NOTREADY);
142 ERR_TO_STR(MIDIERR_NODEVICE);
143 ERR_TO_STR(MIDIERR_INVALIDSETUP);
144 ERR_TO_STR(TIMERR_NOCANDO);
145 ERR_TO_STR(TIMERR_STRUCT);
146 ERR_TO_STR(JOYERR_PARMS);
147 ERR_TO_STR(JOYERR_NOCANDO);
148 ERR_TO_STR(JOYERR_UNPLUGGED);
149 ERR_TO_STR(MIXERR_INVALLINE);
150 ERR_TO_STR(MIXERR_INVALCONTROL);
151 ERR_TO_STR(MIXERR_INVALVALUE);
152 ERR_TO_STR(MMIOERR_FILENOTFOUND);
153 ERR_TO_STR(MMIOERR_OUTOFMEMORY);
154 ERR_TO_STR(MMIOERR_CANNOTOPEN);
155 ERR_TO_STR(MMIOERR_CANNOTCLOSE);
156 ERR_TO_STR(MMIOERR_CANNOTREAD);
157 ERR_TO_STR(MMIOERR_CANNOTWRITE);
158 ERR_TO_STR(MMIOERR_CANNOTSEEK);
159 ERR_TO_STR(MMIOERR_CANNOTEXPAND);
160 ERR_TO_STR(MMIOERR_CHUNKNOTFOUND);
161 ERR_TO_STR(MMIOERR_UNBUFFERED);
163 sprintf(unknown, "Unknown(0x%08x)", error);
164 return unknown;
165 #undef ERR_TO_STR
168 const char* wave_out_error(MMRESULT error)
170 static char msg[1024];
171 static char long_msg[1100];
172 MMRESULT rc;
174 rc = waveOutGetErrorText(error, msg, sizeof(msg));
175 if (rc != MMSYSERR_NOERROR)
176 sprintf(long_msg, "waveOutGetErrorText(%x) failed with error %x",
177 error, rc);
178 else
179 sprintf(long_msg, "%s(%s)", mmsys_error(error), msg);
180 return long_msg;
183 const char * wave_open_flags(DWORD flags)
185 static char msg[1024];
186 int first = TRUE;
187 msg[0] = 0;
188 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) {
189 strcat(msg, "CALLBACK_EVENT");
190 first = FALSE;
192 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) {
193 if (!first) strcat(msg, "|");
194 strcat(msg, "CALLBACK_FUNCTION");
195 first = FALSE;
197 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_NULL) {
198 if (!first) strcat(msg, "|");
199 strcat(msg, "CALLBACK_NULL");
200 first = FALSE;
202 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) {
203 if (!first) strcat(msg, "|");
204 strcat(msg, "CALLBACK_THREAD");
205 first = FALSE;
207 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) {
208 if (!first) strcat(msg, "|");
209 strcat(msg, "CALLBACK_WINDOW");
210 first = FALSE;
212 if ((flags & WAVE_ALLOWSYNC) == WAVE_ALLOWSYNC) {
213 if (!first) strcat(msg, "|");
214 strcat(msg, "WAVE_ALLOWSYNC");
215 first = FALSE;
217 if ((flags & WAVE_FORMAT_DIRECT) == WAVE_FORMAT_DIRECT) {
218 if (!first) strcat(msg, "|");
219 strcat(msg, "WAVE_FORMAT_DIRECT");
220 first = FALSE;
222 if ((flags & WAVE_FORMAT_QUERY) == WAVE_FORMAT_QUERY) {
223 if (!first) strcat(msg, "|");
224 strcat(msg, "WAVE_FORMAT_QUERY");
225 first = FALSE;
227 if ((flags & WAVE_MAPPED) == WAVE_MAPPED) {
228 if (!first) strcat(msg, "|");
229 strcat(msg, "WAVE_MAPPED");
230 first = FALSE;
232 return msg;
235 static const char * wave_out_caps(DWORD dwSupport)
237 #define ADD_FLAG(f) if (dwSupport & f) strcat(msg, " " #f)
238 static char msg[256];
239 msg[0] = 0;
241 ADD_FLAG(WAVECAPS_PITCH);
242 ADD_FLAG(WAVECAPS_PLAYBACKRATE);
243 ADD_FLAG(WAVECAPS_VOLUME);
244 ADD_FLAG(WAVECAPS_LRVOLUME);
245 ADD_FLAG(WAVECAPS_SYNC);
246 ADD_FLAG(WAVECAPS_SAMPLEACCURATE);
248 return msg[0] ? msg + 1 : "";
249 #undef ADD_FLAG
252 static const char * wave_time_format(UINT type)
254 static char msg[32];
255 #define TIME_FORMAT(f) case f: return #f
256 switch (type) {
257 TIME_FORMAT(TIME_MS);
258 TIME_FORMAT(TIME_SAMPLES);
259 TIME_FORMAT(TIME_BYTES);
260 TIME_FORMAT(TIME_SMPTE);
261 TIME_FORMAT(TIME_MIDI);
262 TIME_FORMAT(TIME_TICKS);
264 #undef TIME_FORMAT
265 sprintf(msg, "Unknown(0x%04x)", type);
266 return msg;
269 const char * get_format_str(WORD format)
271 static char msg[32];
272 #define WAVE_FORMAT(f) case f: return #f
273 switch (format) {
274 WAVE_FORMAT(WAVE_FORMAT_PCM);
275 WAVE_FORMAT(WAVE_FORMAT_ADPCM);
276 WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
277 WAVE_FORMAT(WAVE_FORMAT_ALAW);
278 WAVE_FORMAT(WAVE_FORMAT_MULAW);
279 WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
280 WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
281 WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
282 WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
283 WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
284 WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
285 WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
286 WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
287 WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
288 WAVE_FORMAT(WAVE_FORMAT_SONARC);
289 WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
290 WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
291 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
292 WAVE_FORMAT(WAVE_FORMAT_APTX);
293 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
294 WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
295 WAVE_FORMAT(WAVE_FORMAT_GSM610);
296 WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
297 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
298 WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
299 WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
300 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
301 WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
302 WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
303 WAVE_FORMAT(WAVE_FORMAT_MPEG);
304 WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
305 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
306 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
307 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
308 WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
309 WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
310 WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
311 WAVE_FORMAT(WAVE_FORMAT_OLICELP);
312 WAVE_FORMAT(WAVE_FORMAT_OLISBC);
313 WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
314 WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
315 WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
317 #undef WAVE_FORMAT
318 sprintf(msg, "Unknown(0x%04x)", format);
319 return msg;
322 static void check_position(int device, HWAVEOUT wout, DWORD bytes,
323 LPWAVEFORMATEX pwfx )
325 MMTIME mmtime;
326 DWORD samples;
327 double duration;
328 MMRESULT rc;
330 samples=bytes/(pwfx->wBitsPerSample/8*pwfx->nChannels);
331 duration=((double)samples)/pwfx->nSamplesPerSec;
333 mmtime.wType = TIME_BYTES;
334 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
335 ok(rc==MMSYSERR_NOERROR,
336 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
337 if (mmtime.wType == TIME_BYTES)
338 ok(mmtime.u.cb==bytes,
339 "waveOutGetPosition(%s): returned %ld bytes, should be %ld\n",
340 dev_name(device),mmtime.u.cb, bytes);
341 else
342 trace("waveOutGetPosition(%s): TIME_BYTES not supported, returned %s\n",
343 dev_name(device),wave_time_format(mmtime.wType));
345 mmtime.wType = TIME_SAMPLES;
346 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
347 ok(rc==MMSYSERR_NOERROR,
348 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
349 if (mmtime.wType == TIME_SAMPLES)
350 ok(mmtime.u.sample==samples,
351 "waveOutGetPosition(%s): returned %ld samples, should be %ld\n",
352 dev_name(device), mmtime.u.sample, samples);
353 else
354 trace("waveOutGetPosition(%s): TIME_SAMPLES not supported, "
355 "returned %s\n",dev_name(device),wave_time_format(mmtime.wType));
357 mmtime.wType = TIME_MS;
358 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
359 ok(rc==MMSYSERR_NOERROR,
360 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
361 if (mmtime.wType == TIME_MS)
362 ok(mmtime.u.ms==floor(duration*1000.0),
363 "waveOutGetPosition(%s): returned %ld ms, should be %ld\n",
364 dev_name(device), mmtime.u.ms, (long)floor(duration*1000.0));
365 else
366 trace("waveOutGetPosition(%s): TIME_MS not supported, returned %s\n",
367 dev_name(device),wave_time_format(mmtime.wType));
369 mmtime.wType = TIME_SMPTE;
370 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
371 ok(rc==MMSYSERR_NOERROR,
372 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
373 if (mmtime.wType == TIME_SMPTE)
375 BYTE frames=ceil(fmod(duration*mmtime.u.smpte.fps, mmtime.u.smpte.fps));
376 ok(mmtime.u.smpte.hour==(BYTE)(floor(duration/(60*60))) &&
377 mmtime.u.smpte.min==(BYTE)(fmod(floor(duration/60), 60)) &&
378 mmtime.u.smpte.sec==(BYTE)(fmod(duration,60)) &&
379 mmtime.u.smpte.frame==frames,
380 "waveOutGetPosition(%s): returned %d:%d:%d %d, "
381 "should be %d:%d:%d %d\n", dev_name(device), mmtime.u.smpte.hour,
382 mmtime.u.smpte.min, mmtime.u.smpte.sec, mmtime.u.smpte.frame,
383 (BYTE)(floor(duration/(60*60))),
384 (BYTE)(fmod(floor(duration/60), 60)),
385 (BYTE)(fmod(duration,60)),
386 frames);
388 else
389 trace("waveOutGetPosition(%s): TIME_SMPTE not supported, returned %s\n",
390 dev_name(device),wave_time_format(mmtime.wType));
393 static void wave_out_test_deviceOut(int device, double duration,
394 LPWAVEFORMATEX pwfx, DWORD format,
395 DWORD flags, LPWAVEOUTCAPS pcaps)
397 HWAVEOUT wout;
398 HANDLE hevent;
399 WAVEHDR frag;
400 MMRESULT rc;
401 DWORD volume;
402 WORD nChannels = pwfx->nChannels;
403 WORD wBitsPerSample = pwfx->wBitsPerSample;
404 DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
406 hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
407 ok(hevent!=NULL,"CreateEvent(): error=%ld\n",GetLastError());
408 if (hevent==NULL)
409 return;
411 wout=NULL;
412 rc=waveOutOpen(&wout,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
413 /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
414 /* It is acceptable to fail on formats that are not specified to work */
415 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
416 rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
417 rc==MMSYSERR_ALLOCATED ||
418 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
419 (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
420 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
421 (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
422 !(pcaps->dwFormats & format)) ||
423 (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
424 "waveOutOpen(%s): format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",
425 dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
426 pwfx->nChannels,CALLBACK_EVENT|flags,
427 wave_open_flags(CALLBACK_EVENT|flags),wave_out_error(rc));
428 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
429 (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
430 trace(" Reason: The device lists this format as supported in it's "
431 "capabilities but opening it failed.\n");
432 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
433 !(pcaps->dwFormats & format))
434 trace("waveOutOpen(%s): format=%ldx%2dx%d %s rc=%s failed but format "
435 "not supported so OK.\n", dev_name(device), pwfx->nSamplesPerSec,
436 pwfx->wBitsPerSample,pwfx->nChannels,
437 flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
438 flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
439 if (rc!=MMSYSERR_NOERROR) {
440 CloseHandle(hevent);
441 return;
444 ok(pwfx->nChannels==nChannels &&
445 pwfx->wBitsPerSample==wBitsPerSample &&
446 pwfx->nSamplesPerSec==nSamplesPerSec,
447 "got the wrong format: %ldx%2dx%d instead of %ldx%2dx%d\n",
448 pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
449 pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
451 frag.lpData=wave_generate_la(pwfx,duration,&frag.dwBufferLength);
452 frag.dwFlags=0;
453 frag.dwLoops=0;
455 rc=waveOutGetVolume(wout,&volume);
456 ok(rc==MMSYSERR_NOERROR,"waveOutGetVolume(%s): rc=%s\n",
457 dev_name(device),wave_out_error(rc));
459 rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
460 ok(rc==MMSYSERR_NOERROR,
461 "waveOutPrepareHeader(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
463 if (winetest_interactive && rc==MMSYSERR_NOERROR) {
464 DWORD start,end;
465 trace("Playing %g second 440Hz tone at %5ldx%2dx%d %s %s\n",duration,
466 pwfx->nSamplesPerSec, pwfx->wBitsPerSample,pwfx->nChannels,
467 get_format_str(pwfx->wFormatTag),
468 flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
469 flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
471 /* Check that the position is 0 at start */
472 check_position(device, wout, 0.0, pwfx);
474 rc=waveOutSetVolume(wout,0x20002000);
475 ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume(%s): rc=%s\n",
476 dev_name(device),wave_out_error(rc));
477 WaitForSingleObject(hevent,INFINITE);
479 start=GetTickCount();
480 rc=waveOutWrite(wout, &frag, sizeof(frag));
481 ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
482 dev_name(device),wave_out_error(rc));
483 WaitForSingleObject(hevent,INFINITE);
485 /* Check the sound duration was within 10% of the expected value */
486 end=GetTickCount();
487 if (winetest_debug > 1)
488 trace("sound duration=%ld\n",end-start);
489 ok(fabs(1000*duration-end+start)<=100*duration,
490 "The sound played for %ld ms instead of %g ms\n",
491 end-start,1000*duration);
493 rc=waveOutSetVolume(wout,volume);
494 ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume(%s): rc=%s\n",
495 dev_name(device),wave_out_error(rc));
497 check_position(device, wout, frag.dwBufferLength, pwfx);
500 rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
501 ok(rc==MMSYSERR_NOERROR,
502 "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device),
503 wave_out_error(rc));
504 free(frag.lpData);
506 CloseHandle(hevent);
507 rc=waveOutClose(wout);
508 ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device),
509 wave_out_error(rc));
512 static void wave_out_test_device(int device)
514 WAVEOUTCAPSA capsA;
515 WAVEOUTCAPSW capsW;
516 WAVEFORMATEX format, oformat;
517 WAVEFORMATEXTENSIBLE wfex;
518 HWAVEOUT wout;
519 MMRESULT rc;
520 UINT f;
521 WCHAR * nameW;
522 CHAR * nameA;
523 DWORD size;
524 DWORD dwPageSize;
525 BYTE * twoPages;
526 SYSTEM_INFO sSysInfo;
527 DWORD flOldProtect;
528 BOOL res;
530 GetSystemInfo(&sSysInfo);
531 dwPageSize = sSysInfo.dwPageSize;
533 rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA));
534 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
535 rc==MMSYSERR_NODRIVER,
536 "waveOutGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
537 dev_name(device),wave_out_error(rc));
538 if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER)
539 return;
541 rc=waveOutGetDevCapsW(device,&capsW,sizeof(capsW));
542 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
543 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
544 "expected, got %s\n",dev_name(device),wave_out_error(rc));
546 rc=waveOutGetDevCapsA(device,0,sizeof(capsA));
547 ok(rc==MMSYSERR_INVALPARAM,
548 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, "
549 "got %s\n",dev_name(device),wave_out_error(rc));
551 rc=waveOutGetDevCapsW(device,0,sizeof(capsW));
552 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
553 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
554 "expected, got %s\n",dev_name(device),wave_out_error(rc));
556 #if 0 /* FIXME: this works on windows but crashes wine */
557 rc=waveOutGetDevCapsA(device,(LPWAVEOUTCAPSA)1,sizeof(capsA));
558 ok(rc==MMSYSERR_INVALPARAM,
559 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
560 dev_name(device),wave_out_error(rc));
562 rc=waveOutGetDevCapsW(device,(LPWAVEOUTCAPSW)1,sizeof(capsW));
563 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
564 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
565 "expected, got %s\n",dev_name(device),wave_out_error(rc));
566 #endif
568 rc=waveOutGetDevCapsA(device,&capsA,4);
569 ok(rc==MMSYSERR_NOERROR,
570 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
571 dev_name(device),wave_out_error(rc));
573 rc=waveOutGetDevCapsW(device,&capsW,4);
574 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
575 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
576 "expected, got %s\n",dev_name(device),wave_out_error(rc));
578 nameA=NULL;
579 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACESIZE,
580 (DWORD_PTR)&size, 0);
581 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM ||
582 rc==MMSYSERR_NOTSUPPORTED,
583 "waveOutMessage(%s): failed to get interface size, rc=%s\n",
584 dev_name(device),wave_out_error(rc));
585 if (rc==MMSYSERR_NOERROR) {
586 nameW = (WCHAR *)malloc(size);
587 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACE,
588 (DWORD_PTR)nameW, size);
589 ok(rc==MMSYSERR_NOERROR,"waveOutMessage(%s): failed to get interface "
590 "name, rc=%s\n",dev_name(device),wave_out_error(rc));
591 ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),"got an incorrect size: "
592 "%ld instead of %d\n",size,(lstrlenW(nameW)+1)*sizeof(WCHAR));
593 if (rc==MMSYSERR_NOERROR) {
594 nameA = malloc(size/sizeof(WCHAR));
595 WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR), nameA,
596 size/sizeof(WCHAR), NULL, NULL);
598 free(nameW);
600 else if (rc==MMSYSERR_NOTSUPPORTED) {
601 nameA=strdup("not supported");
604 trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
605 (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
606 capsA.vDriverVersion & 0xff, capsA.wMid,capsA.wPid);
607 trace(" channels=%d formats=%05lx support=%04lx\n",
608 capsA.wChannels,capsA.dwFormats,capsA.dwSupport);
609 trace(" %s\n",wave_out_caps(capsA.dwSupport));
610 free(nameA);
612 if (winetest_interactive && (device != WAVE_MAPPER))
614 trace("Playing a 5 seconds reference tone.\n");
615 trace("All subsequent tones should be identical to this one.\n");
616 trace("Listen for stutter, changes in pitch, volume, etc.\n");
617 format.wFormatTag=WAVE_FORMAT_PCM;
618 format.nChannels=1;
619 format.wBitsPerSample=8;
620 format.nSamplesPerSec=22050;
621 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
622 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
623 format.cbSize=0;
624 wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,0,&capsA);
627 for (f=0;f<NB_WIN_FORMATS;f++) {
628 format.wFormatTag=WAVE_FORMAT_PCM;
629 format.nChannels=win_formats[f][3];
630 format.wBitsPerSample=win_formats[f][2];
631 format.nSamplesPerSec=win_formats[f][1];
632 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
633 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
634 format.cbSize=0;
635 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],0,&capsA);
636 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
637 WAVE_FORMAT_DIRECT,&capsA);
638 if (device != WAVE_MAPPER)
639 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
640 WAVE_MAPPED,&capsA);
643 /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
644 * checking */
645 twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
646 PAGE_READWRITE);
647 ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
648 if (twoPages) {
649 res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
650 &flOldProtect);
651 ok(res, "Failed to set memory access on second page\n");
652 if (res) {
653 LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
654 sizeof(PCMWAVEFORMAT));
655 pwfx->wFormatTag=WAVE_FORMAT_PCM;
656 pwfx->nChannels=1;
657 pwfx->wBitsPerSample=8;
658 pwfx->nSamplesPerSec=22050;
659 pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
660 pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
661 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,0,&capsA);
662 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
663 WAVE_FORMAT_DIRECT,&capsA);
664 if (device != WAVE_MAPPER)
665 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
666 WAVE_MAPPED,&capsA);
668 VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
671 /* Testing invalid format: 11 bits per sample */
672 format.wFormatTag=WAVE_FORMAT_PCM;
673 format.nChannels=2;
674 format.wBitsPerSample=11;
675 format.nSamplesPerSec=22050;
676 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
677 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
678 format.cbSize=0;
679 oformat=format;
680 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
681 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
682 rc==MMSYSERR_INVALPARAM,
683 "waveOutOpen(%s): opening the device in 11 bits mode should fail: "
684 "rc=%s\n",dev_name(device),wave_out_error(rc));
685 if (rc==MMSYSERR_NOERROR) {
686 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
687 format.nSamplesPerSec, format.wBitsPerSample,
688 format.nChannels,
689 oformat.nSamplesPerSec, oformat.wBitsPerSample,
690 oformat.nChannels);
691 waveOutClose(wout);
694 /* Testing invalid format: 2 MHz sample rate */
695 format.wFormatTag=WAVE_FORMAT_PCM;
696 format.nChannels=2;
697 format.wBitsPerSample=16;
698 format.nSamplesPerSec=2000000;
699 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
700 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
701 format.cbSize=0;
702 oformat=format;
703 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
704 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
705 rc==MMSYSERR_INVALPARAM,
706 "waveOutOpen(%s): opening the device at 2 MHz sample rate should fail: "
707 "rc=%s\n",dev_name(device),wave_out_error(rc));
708 if (rc==MMSYSERR_NOERROR) {
709 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
710 format.nSamplesPerSec, format.wBitsPerSample,
711 format.nChannels,
712 oformat.nSamplesPerSec, oformat.wBitsPerSample,
713 oformat.nChannels);
714 waveOutClose(wout);
717 /* try some non PCM formats */
718 format.wFormatTag=WAVE_FORMAT_MULAW;
719 format.nChannels=1;
720 format.wBitsPerSample=8;
721 format.nSamplesPerSec=8000;
722 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
723 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
724 format.cbSize=0;
725 oformat=format;
726 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
727 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
728 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
729 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
730 if (rc==MMSYSERR_NOERROR) {
731 waveOutClose(wout);
732 wave_out_test_deviceOut(device,1.0,&format,0,0,
733 &capsA);
734 } else
735 trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n",
736 dev_name(device));
738 format.wFormatTag=WAVE_FORMAT_ADPCM;
739 format.nChannels=2;
740 format.wBitsPerSample=4;
741 format.nSamplesPerSec=22050;
742 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
743 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
744 format.cbSize=0;
745 oformat=format;
746 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
747 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
748 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
749 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
750 if (rc==MMSYSERR_NOERROR) {
751 waveOutClose(wout);
752 wave_out_test_deviceOut(device,1.0,&format,0,0,
753 &capsA);
754 } else
755 trace("waveOutOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
756 dev_name(device));
758 /* test if WAVEFORMATEXTENSIBLE supported */
759 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
760 wfex.Format.nChannels=2;
761 wfex.Format.wBitsPerSample=16;
762 wfex.Format.nSamplesPerSec=22050;
763 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
764 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
765 wfex.Format.nBlockAlign;
766 wfex.Format.cbSize=22;
767 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
768 wfex.dwChannelMask=SPEAKER_ALL;
769 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
770 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
771 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
772 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
773 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
774 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
775 if (rc==MMSYSERR_NOERROR) {
776 waveOutClose(wout);
777 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
778 &capsA);
779 } else
780 trace("waveOutOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
781 dev_name(device));
783 /* test if 4 channels supported */
784 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
785 wfex.Format.nChannels=4;
786 wfex.Format.wBitsPerSample=16;
787 wfex.Format.nSamplesPerSec=22050;
788 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
789 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
790 wfex.Format.nBlockAlign;
791 wfex.Format.cbSize=22;
792 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
793 wfex.dwChannelMask=SPEAKER_ALL;
794 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
795 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
796 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
797 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
798 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
799 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
800 if (rc==MMSYSERR_NOERROR) {
801 waveOutClose(wout);
802 wave_out_test_deviceOut(device,1.0,&wfex.Format,0,0,
803 &capsA);
804 } else
805 trace("waveOutOpen(%s): 4 channels not supported\n",
806 dev_name(device));
808 /* test if 6 channels supported */
809 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
810 wfex.Format.nChannels=6;
811 wfex.Format.wBitsPerSample=16;
812 wfex.Format.nSamplesPerSec=22050;
813 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
814 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
815 wfex.Format.nBlockAlign;
816 wfex.Format.cbSize=22;
817 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
818 wfex.dwChannelMask=SPEAKER_ALL;
819 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
820 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
821 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
822 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
823 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
824 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
825 if (rc==MMSYSERR_NOERROR) {
826 waveOutClose(wout);
827 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
828 &capsA);
829 } else
830 trace("waveOutOpen(%s): 6 channels not supported\n",
831 dev_name(device));
833 #if 0 /* ALSA doesn't like this format */
834 /* test if 24 bit samples supported */
835 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
836 wfex.Format.nChannels=2;
837 wfex.Format.wBitsPerSample=24;
838 wfex.Format.nSamplesPerSec=22050;
839 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
840 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
841 wfex.Format.nBlockAlign;
842 wfex.Format.cbSize=22;
843 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
844 wfex.dwChannelMask=SPEAKER_ALL;
845 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
846 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
847 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
848 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
849 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
850 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
851 if (rc==MMSYSERR_NOERROR) {
852 waveOutClose(wout);
853 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
854 &capsA);
855 } else
856 trace("waveOutOpen(%s): 24 bit samples not supported\n",
857 dev_name(device));
858 #endif
860 /* test if 32 bit samples supported */
861 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
862 wfex.Format.nChannels=2;
863 wfex.Format.wBitsPerSample=32;
864 wfex.Format.nSamplesPerSec=22050;
865 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
866 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
867 wfex.Format.nBlockAlign;
868 wfex.Format.cbSize=22;
869 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
870 wfex.dwChannelMask=SPEAKER_ALL;
871 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
872 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
873 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
874 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
875 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
876 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
877 if (rc==MMSYSERR_NOERROR) {
878 waveOutClose(wout);
879 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
880 &capsA);
881 } else
882 trace("waveOutOpen(%s): 32 bit samples not supported\n",
883 dev_name(device));
885 /* test if 32 bit float samples supported */
886 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
887 wfex.Format.nChannels=2;
888 wfex.Format.wBitsPerSample=32;
889 wfex.Format.nSamplesPerSec=22050;
890 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
891 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
892 wfex.Format.nBlockAlign;
893 wfex.Format.cbSize=22;
894 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
895 wfex.dwChannelMask=SPEAKER_ALL;
896 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
897 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
898 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
899 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
900 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
901 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
902 if (rc==MMSYSERR_NOERROR) {
903 waveOutClose(wout);
904 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
905 &capsA);
906 } else
907 trace("waveOutOpen(%s): 32 bit float samples not supported\n",
908 dev_name(device));
911 static void wave_out_tests()
913 WAVEOUTCAPSA capsA;
914 WAVEOUTCAPSW capsW;
915 WAVEFORMATEX format;
916 HWAVEOUT wout;
917 MMRESULT rc;
918 UINT ndev,d;
920 ndev=waveOutGetNumDevs();
921 trace("found %d WaveOut devices\n",ndev);
923 rc=waveOutGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
924 ok(rc==MMSYSERR_BADDEVICEID,
925 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
926 dev_name(ndev+1),mmsys_error(rc));
928 rc=waveOutGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
929 ok(rc==MMSYSERR_BADDEVICEID,
930 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
931 dev_name(ndev+1),mmsys_error(rc));
933 rc=waveOutGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
934 if (ndev>0)
935 ok(rc==MMSYSERR_NOERROR,
936 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
937 dev_name(WAVE_MAPPER),mmsys_error(rc));
938 else
939 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER,
940 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
941 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
943 rc=waveOutGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
944 if (ndev>0)
945 ok(rc==MMSYSERR_NOERROR,
946 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR expected, got %s\n",
947 dev_name(WAVE_MAPPER),mmsys_error(rc));
948 else
949 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER,
950 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
951 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
953 format.wFormatTag=WAVE_FORMAT_PCM;
954 format.nChannels=2;
955 format.wBitsPerSample=16;
956 format.nSamplesPerSec=44100;
957 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
958 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
959 format.cbSize=0;
960 rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
961 ok(rc==MMSYSERR_BADDEVICEID,
962 "waveOutOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
963 dev_name(ndev+1),mmsys_error(rc));
965 for (d=0;d<ndev;d++)
966 wave_out_test_device(d);
968 if (ndev>0)
969 wave_out_test_device(WAVE_MAPPER);
972 START_TEST(wave)
974 wave_out_tests();