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
26 #include "wine/test.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)
56 WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE*)wfx;
58 nb_samples=(int)(duration*wfx->nSamplesPerSec);
59 *size=nb_samples*wfx->nBlockAlign;
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++)
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++) {
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++) {
78 b[1]=(sample >> 8) & 0xff;
79 b[2]=(sample >> 16) & 0xff;
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++) {
88 b[1]=(sample >> 8) & 0xff;
89 b[2]=(sample >> 16) & 0xff;
90 b[3]=(sample >> 24) & 0xff;
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;
97 for (j = 0; j < wfx->nChannels; j++) {
109 static char* wave_generate_silence(WAVEFORMATEX* wfx, double duration, DWORD* size)
115 WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE*)wfx;
117 nb_samples=(int)(duration*wfx->nSamplesPerSec);
118 *size=nb_samples*wfx->nBlockAlign;
120 for (i=0;i<nb_samples;i++) {
121 if (wfx->wBitsPerSample==8) {
122 for (j = 0; j < wfx->nChannels; j++)
124 } else if (wfx->wBitsPerSample==16) {
125 for (j = 0; j < wfx->nChannels; j++) {
130 } else if (wfx->wBitsPerSample==24) {
131 for (j = 0; j < wfx->nChannels; j++) {
137 } else if ((wfx->wBitsPerSample==32) && ((wfx->wFormatTag == WAVE_FORMAT_PCM) ||
138 ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
139 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)))) {
140 for (j = 0; j < wfx->nChannels; j++) {
147 } else if ((wfx->wBitsPerSample==32) && (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
148 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
149 union { float f; char c[4]; } sample;
151 for (j = 0; j < wfx->nChannels; j++) {
163 const char * dev_name(int device)
165 static char name[16];
166 if (device == WAVE_MAPPER)
167 return "WAVE_MAPPER";
168 sprintf(name, "%d", device);
172 const char* mmsys_error(MMRESULT error)
174 #define ERR_TO_STR(dev) case dev: return #dev
175 static char unknown[32];
177 ERR_TO_STR(MMSYSERR_NOERROR);
178 ERR_TO_STR(MMSYSERR_ERROR);
179 ERR_TO_STR(MMSYSERR_BADDEVICEID);
180 ERR_TO_STR(MMSYSERR_NOTENABLED);
181 ERR_TO_STR(MMSYSERR_ALLOCATED);
182 ERR_TO_STR(MMSYSERR_INVALHANDLE);
183 ERR_TO_STR(MMSYSERR_NODRIVER);
184 ERR_TO_STR(MMSYSERR_NOMEM);
185 ERR_TO_STR(MMSYSERR_NOTSUPPORTED);
186 ERR_TO_STR(MMSYSERR_BADERRNUM);
187 ERR_TO_STR(MMSYSERR_INVALFLAG);
188 ERR_TO_STR(MMSYSERR_INVALPARAM);
189 ERR_TO_STR(WAVERR_BADFORMAT);
190 ERR_TO_STR(WAVERR_STILLPLAYING);
191 ERR_TO_STR(WAVERR_UNPREPARED);
192 ERR_TO_STR(WAVERR_SYNC);
193 ERR_TO_STR(MIDIERR_UNPREPARED);
194 ERR_TO_STR(MIDIERR_STILLPLAYING);
195 ERR_TO_STR(MIDIERR_NOTREADY);
196 ERR_TO_STR(MIDIERR_NODEVICE);
197 ERR_TO_STR(MIDIERR_INVALIDSETUP);
198 ERR_TO_STR(TIMERR_NOCANDO);
199 ERR_TO_STR(TIMERR_STRUCT);
200 ERR_TO_STR(JOYERR_PARMS);
201 ERR_TO_STR(JOYERR_NOCANDO);
202 ERR_TO_STR(JOYERR_UNPLUGGED);
203 ERR_TO_STR(MIXERR_INVALLINE);
204 ERR_TO_STR(MIXERR_INVALCONTROL);
205 ERR_TO_STR(MIXERR_INVALVALUE);
206 ERR_TO_STR(MMIOERR_FILENOTFOUND);
207 ERR_TO_STR(MMIOERR_OUTOFMEMORY);
208 ERR_TO_STR(MMIOERR_CANNOTOPEN);
209 ERR_TO_STR(MMIOERR_CANNOTCLOSE);
210 ERR_TO_STR(MMIOERR_CANNOTREAD);
211 ERR_TO_STR(MMIOERR_CANNOTWRITE);
212 ERR_TO_STR(MMIOERR_CANNOTSEEK);
213 ERR_TO_STR(MMIOERR_CANNOTEXPAND);
214 ERR_TO_STR(MMIOERR_CHUNKNOTFOUND);
215 ERR_TO_STR(MMIOERR_UNBUFFERED);
217 sprintf(unknown, "Unknown(0x%08x)", error);
222 const char* wave_out_error(MMRESULT error)
224 static char msg[1024];
225 static char long_msg[1100];
228 rc = waveOutGetErrorText(error, msg, sizeof(msg));
229 if (rc != MMSYSERR_NOERROR)
230 sprintf(long_msg, "waveOutGetErrorText(%x) failed with error %x",
233 sprintf(long_msg, "%s(%s)", mmsys_error(error), msg);
237 const char * wave_open_flags(DWORD flags)
239 static char msg[1024];
242 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) {
243 strcat(msg, "CALLBACK_EVENT");
246 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) {
247 if (!first) strcat(msg, "|");
248 strcat(msg, "CALLBACK_FUNCTION");
251 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_NULL) {
252 if (!first) strcat(msg, "|");
253 strcat(msg, "CALLBACK_NULL");
256 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) {
257 if (!first) strcat(msg, "|");
258 strcat(msg, "CALLBACK_THREAD");
261 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) {
262 if (!first) strcat(msg, "|");
263 strcat(msg, "CALLBACK_WINDOW");
266 if ((flags & WAVE_ALLOWSYNC) == WAVE_ALLOWSYNC) {
267 if (!first) strcat(msg, "|");
268 strcat(msg, "WAVE_ALLOWSYNC");
271 if ((flags & WAVE_FORMAT_DIRECT) == WAVE_FORMAT_DIRECT) {
272 if (!first) strcat(msg, "|");
273 strcat(msg, "WAVE_FORMAT_DIRECT");
276 if ((flags & WAVE_FORMAT_QUERY) == WAVE_FORMAT_QUERY) {
277 if (!first) strcat(msg, "|");
278 strcat(msg, "WAVE_FORMAT_QUERY");
281 if ((flags & WAVE_MAPPED) == WAVE_MAPPED) {
282 if (!first) strcat(msg, "|");
283 strcat(msg, "WAVE_MAPPED");
289 static const char * wave_out_caps(DWORD dwSupport)
291 #define ADD_FLAG(f) if (dwSupport & f) strcat(msg, " " #f)
292 static char msg[256];
295 ADD_FLAG(WAVECAPS_PITCH);
296 ADD_FLAG(WAVECAPS_PLAYBACKRATE);
297 ADD_FLAG(WAVECAPS_VOLUME);
298 ADD_FLAG(WAVECAPS_LRVOLUME);
299 ADD_FLAG(WAVECAPS_SYNC);
300 ADD_FLAG(WAVECAPS_SAMPLEACCURATE);
302 return msg[0] ? msg + 1 : "";
306 static const char * wave_time_format(UINT type)
309 #define TIME_FORMAT(f) case f: return #f
311 TIME_FORMAT(TIME_MS);
312 TIME_FORMAT(TIME_SAMPLES);
313 TIME_FORMAT(TIME_BYTES);
314 TIME_FORMAT(TIME_SMPTE);
315 TIME_FORMAT(TIME_MIDI);
316 TIME_FORMAT(TIME_TICKS);
319 sprintf(msg, "Unknown(0x%04x)", type);
323 const char * get_format_str(WORD format)
326 #define WAVE_FORMAT(f) case f: return #f
328 WAVE_FORMAT(WAVE_FORMAT_PCM);
329 WAVE_FORMAT(WAVE_FORMAT_ADPCM);
330 WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD);
331 WAVE_FORMAT(WAVE_FORMAT_ALAW);
332 WAVE_FORMAT(WAVE_FORMAT_MULAW);
333 WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM);
334 WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM);
335 WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM);
336 WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM);
337 WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM);
338 WAVE_FORMAT(WAVE_FORMAT_DIGISTD);
339 WAVE_FORMAT(WAVE_FORMAT_DIGIFIX);
340 WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM);
341 WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM);
342 WAVE_FORMAT(WAVE_FORMAT_SONARC);
343 WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH);
344 WAVE_FORMAT(WAVE_FORMAT_ECHOSC1);
345 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36);
346 WAVE_FORMAT(WAVE_FORMAT_APTX);
347 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10);
348 WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2);
349 WAVE_FORMAT(WAVE_FORMAT_GSM610);
350 WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME);
351 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC);
352 WAVE_FORMAT(WAVE_FORMAT_DIGIREAL);
353 WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM);
354 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10);
355 WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM);
356 WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM);
357 WAVE_FORMAT(WAVE_FORMAT_MPEG);
358 WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3);
359 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM);
360 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8);
361 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10);
362 WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND);
363 WAVE_FORMAT(WAVE_FORMAT_OLIGSM);
364 WAVE_FORMAT(WAVE_FORMAT_OLIADPCM);
365 WAVE_FORMAT(WAVE_FORMAT_OLICELP);
366 WAVE_FORMAT(WAVE_FORMAT_OLISBC);
367 WAVE_FORMAT(WAVE_FORMAT_OLIOPR);
368 WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT);
369 WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE);
372 sprintf(msg, "Unknown(0x%04x)", format);
376 static void check_position(int device, HWAVEOUT wout, DWORD bytes,
377 LPWAVEFORMATEX pwfx )
384 samples=bytes/(pwfx->wBitsPerSample/8*pwfx->nChannels);
385 duration=((double)samples)/pwfx->nSamplesPerSec;
387 mmtime.wType = TIME_BYTES;
388 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
389 ok(rc==MMSYSERR_NOERROR,
390 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
391 if (mmtime.wType == TIME_BYTES)
392 ok(mmtime.u.cb==bytes,
393 "waveOutGetPosition(%s): returned %ld bytes, should be %ld\n",
394 dev_name(device),mmtime.u.cb, bytes);
396 trace("waveOutGetPosition(%s): TIME_BYTES not supported, returned %s\n",
397 dev_name(device),wave_time_format(mmtime.wType));
399 mmtime.wType = TIME_SAMPLES;
400 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
401 ok(rc==MMSYSERR_NOERROR,
402 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
403 if (mmtime.wType == TIME_SAMPLES)
404 ok(mmtime.u.sample==samples,
405 "waveOutGetPosition(%s): returned %ld samples, should be %ld\n",
406 dev_name(device), mmtime.u.sample, samples);
408 trace("waveOutGetPosition(%s): TIME_SAMPLES not supported, "
409 "returned %s\n",dev_name(device),wave_time_format(mmtime.wType));
411 mmtime.wType = TIME_MS;
412 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
413 ok(rc==MMSYSERR_NOERROR,
414 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
415 if (mmtime.wType == TIME_MS)
416 ok(mmtime.u.ms==floor(duration*1000.0),
417 "waveOutGetPosition(%s): returned %ld ms, should be %ld\n",
418 dev_name(device), mmtime.u.ms, (long)floor(duration*1000.0));
420 trace("waveOutGetPosition(%s): TIME_MS not supported, returned %s\n",
421 dev_name(device),wave_time_format(mmtime.wType));
423 mmtime.wType = TIME_SMPTE;
424 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime));
425 ok(rc==MMSYSERR_NOERROR,
426 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
427 if (mmtime.wType == TIME_SMPTE)
429 BYTE frames=(BYTE)ceil(fmod(duration*mmtime.u.smpte.fps, mmtime.u.smpte.fps));
430 ok(mmtime.u.smpte.hour==(BYTE)(floor(duration/(60*60))) &&
431 mmtime.u.smpte.min==(BYTE)(fmod(floor(duration/60), 60)) &&
432 mmtime.u.smpte.sec==(BYTE)(fmod(duration,60)) &&
433 mmtime.u.smpte.frame==frames,
434 "waveOutGetPosition(%s): returned %d:%d:%d %d, "
435 "should be %d:%d:%d %d\n", dev_name(device), mmtime.u.smpte.hour,
436 mmtime.u.smpte.min, mmtime.u.smpte.sec, mmtime.u.smpte.frame,
437 (BYTE)(floor(duration/(60*60))),
438 (BYTE)(fmod(floor(duration/60), 60)),
439 (BYTE)(fmod(duration,60)),
443 trace("waveOutGetPosition(%s): TIME_SMPTE not supported, returned %s\n",
444 dev_name(device),wave_time_format(mmtime.wType));
447 static void wave_out_test_deviceOut(int device, double duration,
448 LPWAVEFORMATEX pwfx, DWORD format,
449 DWORD flags, LPWAVEOUTCAPS pcaps,
450 BOOL interactive, BOOL sine)
457 WORD nChannels = pwfx->nChannels;
458 WORD wBitsPerSample = pwfx->wBitsPerSample;
459 DWORD nSamplesPerSec = pwfx->nSamplesPerSec;
460 BOOL has_volume = pcaps->dwSupport & WAVECAPS_VOLUME;
462 hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
463 ok(hevent!=NULL,"CreateEvent(): error=%ld\n",GetLastError());
468 rc=waveOutOpen(&wout,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
469 /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
470 /* It is acceptable to fail on formats that are not specified to work */
471 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
472 rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
473 rc==MMSYSERR_ALLOCATED ||
474 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
475 (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
476 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
477 (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
478 !(pcaps->dwFormats & format)) ||
479 (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
480 "waveOutOpen(%s): format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",
481 dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
482 pwfx->nChannels,CALLBACK_EVENT|flags,
483 wave_open_flags(CALLBACK_EVENT|flags),wave_out_error(rc));
484 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
485 (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
486 trace(" Reason: The device lists this format as supported in it's "
487 "capabilities but opening it failed.\n");
488 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
489 !(pcaps->dwFormats & format))
490 trace("waveOutOpen(%s): format=%ldx%2dx%d %s rc=%s failed but format "
491 "not supported so OK.\n", dev_name(device), pwfx->nSamplesPerSec,
492 pwfx->wBitsPerSample,pwfx->nChannels,
493 flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
494 flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
495 if (rc!=MMSYSERR_NOERROR) {
500 ok(pwfx->nChannels==nChannels &&
501 pwfx->wBitsPerSample==wBitsPerSample &&
502 pwfx->nSamplesPerSec==nSamplesPerSec,
503 "got the wrong format: %ldx%2dx%d instead of %ldx%2dx%d\n",
504 pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
505 pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
508 frag.lpData=wave_generate_la(pwfx,duration,&frag.dwBufferLength);
510 frag.lpData=wave_generate_silence(pwfx,duration,&frag.dwBufferLength);
515 rc=waveOutGetVolume(wout,&volume);
516 ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED,
517 "waveOutGetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
519 rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
520 ok(rc==MMSYSERR_NOERROR,
521 "waveOutPrepareHeader(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
523 if (interactive && rc==MMSYSERR_NOERROR) {
525 trace("Playing %g second %s at %5ldx%2dx%d %s %s\n",duration,
526 sine ? "440Hz tone" : "silence",pwfx->nSamplesPerSec,
527 pwfx->wBitsPerSample,pwfx->nChannels,
528 get_format_str(pwfx->wFormatTag),
529 flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
530 flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
532 trace("*** Warning the sound is muted, you will not hear the test\n");
534 /* Check that the position is 0 at start */
535 check_position(device, wout, 0, pwfx);
537 rc=waveOutSetVolume(wout,0x20002000);
538 ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED,
539 "waveOutSetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
540 WaitForSingleObject(hevent,INFINITE);
542 rc=waveOutSetVolume(wout,volume);
543 ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED,
544 "waveOutSetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
546 start=GetTickCount();
547 rc=waveOutWrite(wout, &frag, sizeof(frag));
548 ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
549 dev_name(device),wave_out_error(rc));
550 WaitForSingleObject(hevent,INFINITE);
552 /* Check the sound duration was within 10% of the expected value */
554 if (winetest_debug > 1)
555 trace("sound duration=%ld\n",end-start);
556 ok(fabs(1000*duration-end+start)<=100*duration,
557 "The sound played for %ld ms instead of %g ms\n",
558 end-start,1000*duration);
560 check_position(device, wout, frag.dwBufferLength, pwfx);
563 rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
564 ok(rc==MMSYSERR_NOERROR,
565 "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device),
570 rc=waveOutClose(wout);
571 ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device),
575 static void wave_out_test_device(int device)
579 WAVEFORMATEX format, oformat;
580 WAVEFORMATEXTENSIBLE wfex;
589 SYSTEM_INFO sSysInfo;
593 GetSystemInfo(&sSysInfo);
594 dwPageSize = sSysInfo.dwPageSize;
596 rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA));
597 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
598 rc==MMSYSERR_NODRIVER,
599 "waveOutGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
600 dev_name(device),wave_out_error(rc));
601 if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER)
604 rc=waveOutGetDevCapsW(device,&capsW,sizeof(capsW));
605 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
606 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
607 "expected, got %s\n",dev_name(device),wave_out_error(rc));
609 rc=waveOutGetDevCapsA(device,0,sizeof(capsA));
610 ok(rc==MMSYSERR_INVALPARAM,
611 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, "
612 "got %s\n",dev_name(device),wave_out_error(rc));
614 rc=waveOutGetDevCapsW(device,0,sizeof(capsW));
615 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
616 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
617 "expected, got %s\n",dev_name(device),wave_out_error(rc));
619 #if 0 /* FIXME: this works on windows but crashes wine */
620 rc=waveOutGetDevCapsA(device,(LPWAVEOUTCAPSA)1,sizeof(capsA));
621 ok(rc==MMSYSERR_INVALPARAM,
622 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
623 dev_name(device),wave_out_error(rc));
625 rc=waveOutGetDevCapsW(device,(LPWAVEOUTCAPSW)1,sizeof(capsW));
626 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
627 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
628 "expected, got %s\n",dev_name(device),wave_out_error(rc));
631 rc=waveOutGetDevCapsA(device,&capsA,4);
632 ok(rc==MMSYSERR_NOERROR,
633 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
634 dev_name(device),wave_out_error(rc));
636 rc=waveOutGetDevCapsW(device,&capsW,4);
637 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
638 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
639 "expected, got %s\n",dev_name(device),wave_out_error(rc));
642 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACESIZE,
643 (DWORD_PTR)&size, 0);
644 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM ||
645 rc==MMSYSERR_NOTSUPPORTED,
646 "waveOutMessage(%s): failed to get interface size, rc=%s\n",
647 dev_name(device),wave_out_error(rc));
648 if (rc==MMSYSERR_NOERROR) {
649 nameW = (WCHAR *)malloc(size);
650 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACE,
651 (DWORD_PTR)nameW, size);
652 ok(rc==MMSYSERR_NOERROR,"waveOutMessage(%s): failed to get interface "
653 "name, rc=%s\n",dev_name(device),wave_out_error(rc));
654 ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),"got an incorrect size: "
655 "%ld instead of %d\n",size,(lstrlenW(nameW)+1)*sizeof(WCHAR));
656 if (rc==MMSYSERR_NOERROR) {
657 nameA = malloc(size/sizeof(WCHAR));
658 WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR), nameA,
659 size/sizeof(WCHAR), NULL, NULL);
663 else if (rc==MMSYSERR_NOTSUPPORTED) {
664 nameA=strdup("not supported");
667 trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
668 (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
669 capsA.vDriverVersion & 0xff, capsA.wMid,capsA.wPid);
670 trace(" channels=%d formats=%05lx support=%04lx\n",
671 capsA.wChannels,capsA.dwFormats,capsA.dwSupport);
672 trace(" %s\n",wave_out_caps(capsA.dwSupport));
675 if (winetest_interactive && (device != WAVE_MAPPER))
677 trace("Playing a 5 seconds reference tone.\n");
678 trace("All subsequent tones should be identical to this one.\n");
679 trace("Listen for stutter, changes in pitch, volume, etc.\n");
680 format.wFormatTag=WAVE_FORMAT_PCM;
682 format.wBitsPerSample=8;
683 format.nSamplesPerSec=22050;
684 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
685 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
687 wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,0,&capsA,
690 format.wFormatTag=WAVE_FORMAT_PCM;
692 format.wBitsPerSample=8;
693 format.nSamplesPerSec=22050;
694 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
695 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
697 wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,0,&capsA,
701 for (f=0;f<NB_WIN_FORMATS;f++) {
702 format.wFormatTag=WAVE_FORMAT_PCM;
703 format.nChannels=win_formats[f][3];
704 format.wBitsPerSample=win_formats[f][2];
705 format.nSamplesPerSec=win_formats[f][1];
706 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
707 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
709 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
710 0,&capsA,winetest_interactive,TRUE);
711 if (device != WAVE_MAPPER)
713 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
714 WAVE_FORMAT_DIRECT,&capsA,winetest_interactive,
716 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
717 WAVE_MAPPED,&capsA,winetest_interactive,
722 /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
724 twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
726 ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
728 res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
730 ok(res, "Failed to set memory access on second page\n");
732 LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
733 sizeof(PCMWAVEFORMAT));
734 pwfx->wFormatTag=WAVE_FORMAT_PCM;
736 pwfx->wBitsPerSample=8;
737 pwfx->nSamplesPerSec=22050;
738 pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
739 pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
740 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,0,
741 &capsA,winetest_interactive,TRUE);
742 if (device != WAVE_MAPPER)
744 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
745 WAVE_FORMAT_DIRECT,&capsA,
746 winetest_interactive,TRUE);
747 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
748 WAVE_MAPPED,&capsA,winetest_interactive,
752 VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
755 /* Testing invalid format: 11 bits per sample */
756 format.wFormatTag=WAVE_FORMAT_PCM;
758 format.wBitsPerSample=11;
759 format.nSamplesPerSec=22050;
760 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
761 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
764 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
765 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
766 rc==MMSYSERR_INVALPARAM,
767 "waveOutOpen(%s): opening the device in 11 bits mode should fail: "
768 "rc=%s\n",dev_name(device),wave_out_error(rc));
769 if (rc==MMSYSERR_NOERROR) {
770 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
771 format.nSamplesPerSec, format.wBitsPerSample,
773 oformat.nSamplesPerSec, oformat.wBitsPerSample,
778 /* Testing invalid format: 2 MHz sample rate */
779 format.wFormatTag=WAVE_FORMAT_PCM;
781 format.wBitsPerSample=16;
782 format.nSamplesPerSec=2000000;
783 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
784 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
787 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
788 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
789 rc==MMSYSERR_INVALPARAM,
790 "waveOutOpen(%s): opening the device at 2 MHz sample rate should fail: "
791 "rc=%s\n",dev_name(device),wave_out_error(rc));
792 if (rc==MMSYSERR_NOERROR) {
793 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
794 format.nSamplesPerSec, format.wBitsPerSample,
796 oformat.nSamplesPerSec, oformat.wBitsPerSample,
801 /* try some non PCM formats */
802 format.wFormatTag=WAVE_FORMAT_MULAW;
804 format.wBitsPerSample=8;
805 format.nSamplesPerSec=8000;
806 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
807 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
810 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
811 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
812 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
813 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
814 if (rc==MMSYSERR_NOERROR) {
816 wave_out_test_deviceOut(device,1.0,&format,0,0,
817 &capsA,winetest_interactive,TRUE);
819 trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n",
822 format.wFormatTag=WAVE_FORMAT_ADPCM;
824 format.wBitsPerSample=4;
825 format.nSamplesPerSec=22050;
826 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
827 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
830 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
831 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
832 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
833 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
834 if (rc==MMSYSERR_NOERROR) {
836 wave_out_test_deviceOut(device,1.0,&format,0,0,
837 &capsA,winetest_interactive,TRUE);
839 trace("waveOutOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
842 /* test if WAVEFORMATEXTENSIBLE supported */
843 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
844 wfex.Format.nChannels=2;
845 wfex.Format.wBitsPerSample=16;
846 wfex.Format.nSamplesPerSec=22050;
847 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
848 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
849 wfex.Format.nBlockAlign;
850 wfex.Format.cbSize=22;
851 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
852 wfex.dwChannelMask=SPEAKER_ALL;
853 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
854 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
855 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
856 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
857 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
858 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
859 if (rc==MMSYSERR_NOERROR) {
861 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
862 &capsA,winetest_interactive,TRUE);
864 trace("waveOutOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
867 /* test if 4 channels supported */
868 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
869 wfex.Format.nChannels=4;
870 wfex.Format.wBitsPerSample=16;
871 wfex.Format.nSamplesPerSec=22050;
872 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
873 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
874 wfex.Format.nBlockAlign;
875 wfex.Format.cbSize=22;
876 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
877 wfex.dwChannelMask=SPEAKER_ALL;
878 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
879 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
880 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
881 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
882 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
883 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
884 if (rc==MMSYSERR_NOERROR) {
886 wave_out_test_deviceOut(device,1.0,&wfex.Format,0,0,
887 &capsA,winetest_interactive,TRUE);
889 trace("waveOutOpen(%s): 4 channels not supported\n",
892 /* test if 6 channels supported */
893 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
894 wfex.Format.nChannels=6;
895 wfex.Format.wBitsPerSample=16;
896 wfex.Format.nSamplesPerSec=22050;
897 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
898 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
899 wfex.Format.nBlockAlign;
900 wfex.Format.cbSize=22;
901 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
902 wfex.dwChannelMask=SPEAKER_ALL;
903 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
904 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
905 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
906 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
907 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
908 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
909 if (rc==MMSYSERR_NOERROR) {
911 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
912 &capsA,winetest_interactive,TRUE);
914 trace("waveOutOpen(%s): 6 channels not supported\n",
917 #if 0 /* ALSA doesn't like this format */
918 /* test if 24 bit samples supported */
919 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
920 wfex.Format.nChannels=2;
921 wfex.Format.wBitsPerSample=24;
922 wfex.Format.nSamplesPerSec=22050;
923 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
924 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
925 wfex.Format.nBlockAlign;
926 wfex.Format.cbSize=22;
927 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
928 wfex.dwChannelMask=SPEAKER_ALL;
929 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
930 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
931 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
932 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
933 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
934 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
935 if (rc==MMSYSERR_NOERROR) {
937 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
938 &capsA,winetest_interactive,TRUE);
940 trace("waveOutOpen(%s): 24 bit samples not supported\n",
944 /* test if 32 bit samples supported */
945 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
946 wfex.Format.nChannels=2;
947 wfex.Format.wBitsPerSample=32;
948 wfex.Format.nSamplesPerSec=22050;
949 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
950 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
951 wfex.Format.nBlockAlign;
952 wfex.Format.cbSize=22;
953 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
954 wfex.dwChannelMask=SPEAKER_ALL;
955 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
956 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
957 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
958 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
959 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
960 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
961 if (rc==MMSYSERR_NOERROR) {
963 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
964 &capsA,winetest_interactive,TRUE);
966 trace("waveOutOpen(%s): 32 bit samples not supported\n",
969 /* test if 32 bit float samples supported */
970 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
971 wfex.Format.nChannels=2;
972 wfex.Format.wBitsPerSample=32;
973 wfex.Format.nSamplesPerSec=22050;
974 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
975 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
976 wfex.Format.nBlockAlign;
977 wfex.Format.cbSize=22;
978 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
979 wfex.dwChannelMask=SPEAKER_ALL;
980 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
981 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
982 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
983 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
984 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
985 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
986 if (rc==MMSYSERR_NOERROR) {
988 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
989 &capsA,winetest_interactive,TRUE);
991 trace("waveOutOpen(%s): 32 bit float samples not supported\n",
995 static void wave_out_tests()
1004 ndev=waveOutGetNumDevs();
1005 trace("found %d WaveOut devices\n",ndev);
1007 rc=waveOutGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
1008 ok(rc==MMSYSERR_BADDEVICEID,
1009 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
1010 dev_name(ndev+1),mmsys_error(rc));
1012 rc=waveOutGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
1013 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NOTSUPPORTED,
1014 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
1015 "expected, got %s\n",dev_name(ndev+1),mmsys_error(rc));
1017 rc=waveOutGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
1019 ok(rc==MMSYSERR_NOERROR,
1020 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
1021 dev_name(WAVE_MAPPER),mmsys_error(rc));
1023 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER,
1024 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
1025 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
1027 rc=waveOutGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
1029 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
1030 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
1031 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
1033 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER ||
1034 rc==MMSYSERR_NOTSUPPORTED,
1035 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
1036 " or MMSYSERR_NOTSUPPORTED expected, got %s\n",
1037 dev_name(WAVE_MAPPER),mmsys_error(rc));
1039 format.wFormatTag=WAVE_FORMAT_PCM;
1041 format.wBitsPerSample=16;
1042 format.nSamplesPerSec=44100;
1043 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1044 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1046 rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
1047 ok(rc==MMSYSERR_BADDEVICEID,
1048 "waveOutOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
1049 dev_name(ndev+1),mmsys_error(rc));
1051 for (d=0;d<ndev;d++)
1052 wave_out_test_device(d);
1055 wave_out_test_device(WAVE_MAPPER);