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;
461 hevent=CreateEvent(NULL,FALSE,FALSE,NULL);
462 ok(hevent!=NULL,"CreateEvent(): error=%ld\n",GetLastError());
467 rc=waveOutOpen(&wout,device,pwfx,(DWORD)hevent,0,CALLBACK_EVENT|flags);
468 /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */
469 /* It is acceptable to fail on formats that are not specified to work */
470 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
471 rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER ||
472 rc==MMSYSERR_ALLOCATED ||
473 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
474 (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) ||
475 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
476 (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) &&
477 !(pcaps->dwFormats & format)) ||
478 (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)),
479 "waveOutOpen(%s): format=%ldx%2dx%d flags=%lx(%s) rc=%s\n",
480 dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample,
481 pwfx->nChannels,CALLBACK_EVENT|flags,
482 wave_open_flags(CALLBACK_EVENT|flags),wave_out_error(rc));
483 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
484 (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format))
485 trace(" Reason: The device lists this format as supported in it's "
486 "capabilities but opening it failed.\n");
487 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) &&
488 !(pcaps->dwFormats & format))
489 trace("waveOutOpen(%s): format=%ldx%2dx%d %s rc=%s failed but format "
490 "not supported so OK.\n", dev_name(device), pwfx->nSamplesPerSec,
491 pwfx->wBitsPerSample,pwfx->nChannels,
492 flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" :
493 flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc));
494 if (rc!=MMSYSERR_NOERROR) {
499 ok(pwfx->nChannels==nChannels &&
500 pwfx->wBitsPerSample==wBitsPerSample &&
501 pwfx->nSamplesPerSec==nSamplesPerSec,
502 "got the wrong format: %ldx%2dx%d instead of %ldx%2dx%d\n",
503 pwfx->nSamplesPerSec, pwfx->wBitsPerSample,
504 pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels);
507 frag.lpData=wave_generate_la(pwfx,duration,&frag.dwBufferLength);
509 frag.lpData=wave_generate_silence(pwfx,duration,&frag.dwBufferLength);
514 rc=waveOutGetVolume(wout,&volume);
515 ok(rc==MMSYSERR_NOERROR,"waveOutGetVolume(%s): rc=%s\n",
516 dev_name(device),wave_out_error(rc));
518 rc=waveOutPrepareHeader(wout, &frag, sizeof(frag));
519 ok(rc==MMSYSERR_NOERROR,
520 "waveOutPrepareHeader(%s): rc=%s\n",dev_name(device),wave_out_error(rc));
522 if (interactive && rc==MMSYSERR_NOERROR) {
524 trace("Playing %g second %s at %5ldx%2dx%d %s %s\n",duration,
525 sine ? "440Hz tone" : "silence",pwfx->nSamplesPerSec,
526 pwfx->wBitsPerSample,pwfx->nChannels,
527 get_format_str(pwfx->wFormatTag),
528 flags & WAVE_FORMAT_DIRECT ? "WAVE_FORMAT_DIRECT" :
529 flags & WAVE_MAPPED ? "WAVE_MAPPED" : "");
531 /* Check that the position is 0 at start */
532 check_position(device, wout, 0, pwfx);
534 rc=waveOutSetVolume(wout,0x20002000);
535 ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume(%s): rc=%s\n",
536 dev_name(device),wave_out_error(rc));
537 WaitForSingleObject(hevent,INFINITE);
539 start=GetTickCount();
540 rc=waveOutWrite(wout, &frag, sizeof(frag));
541 ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n",
542 dev_name(device),wave_out_error(rc));
543 WaitForSingleObject(hevent,INFINITE);
545 /* Check the sound duration was within 10% of the expected value */
547 if (winetest_debug > 1)
548 trace("sound duration=%ld\n",end-start);
549 ok(fabs(1000*duration-end+start)<=100*duration,
550 "The sound played for %ld ms instead of %g ms\n",
551 end-start,1000*duration);
553 rc=waveOutSetVolume(wout,volume);
554 ok(rc==MMSYSERR_NOERROR,"waveOutSetVolume(%s): rc=%s\n",
555 dev_name(device),wave_out_error(rc));
557 check_position(device, wout, frag.dwBufferLength, pwfx);
560 rc=waveOutUnprepareHeader(wout, &frag, sizeof(frag));
561 ok(rc==MMSYSERR_NOERROR,
562 "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device),
567 rc=waveOutClose(wout);
568 ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device),
572 static void wave_out_test_device(int device)
576 WAVEFORMATEX format, oformat;
577 WAVEFORMATEXTENSIBLE wfex;
586 SYSTEM_INFO sSysInfo;
590 GetSystemInfo(&sSysInfo);
591 dwPageSize = sSysInfo.dwPageSize;
593 rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA));
594 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID ||
595 rc==MMSYSERR_NODRIVER,
596 "waveOutGetDevCapsA(%s): failed to get capabilities: rc=%s\n",
597 dev_name(device),wave_out_error(rc));
598 if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER)
601 rc=waveOutGetDevCapsW(device,&capsW,sizeof(capsW));
602 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
603 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
604 "expected, got %s\n",dev_name(device),wave_out_error(rc));
606 rc=waveOutGetDevCapsA(device,0,sizeof(capsA));
607 ok(rc==MMSYSERR_INVALPARAM,
608 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, "
609 "got %s\n",dev_name(device),wave_out_error(rc));
611 rc=waveOutGetDevCapsW(device,0,sizeof(capsW));
612 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
613 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
614 "expected, got %s\n",dev_name(device),wave_out_error(rc));
616 #if 0 /* FIXME: this works on windows but crashes wine */
617 rc=waveOutGetDevCapsA(device,(LPWAVEOUTCAPSA)1,sizeof(capsA));
618 ok(rc==MMSYSERR_INVALPARAM,
619 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n",
620 dev_name(device),wave_out_error(rc));
622 rc=waveOutGetDevCapsW(device,(LPWAVEOUTCAPSW)1,sizeof(capsW));
623 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED,
624 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED "
625 "expected, got %s\n",dev_name(device),wave_out_error(rc));
628 rc=waveOutGetDevCapsA(device,&capsA,4);
629 ok(rc==MMSYSERR_NOERROR,
630 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
631 dev_name(device),wave_out_error(rc));
633 rc=waveOutGetDevCapsW(device,&capsW,4);
634 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
635 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
636 "expected, got %s\n",dev_name(device),wave_out_error(rc));
639 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACESIZE,
640 (DWORD_PTR)&size, 0);
641 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM ||
642 rc==MMSYSERR_NOTSUPPORTED,
643 "waveOutMessage(%s): failed to get interface size, rc=%s\n",
644 dev_name(device),wave_out_error(rc));
645 if (rc==MMSYSERR_NOERROR) {
646 nameW = (WCHAR *)malloc(size);
647 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACE,
648 (DWORD_PTR)nameW, size);
649 ok(rc==MMSYSERR_NOERROR,"waveOutMessage(%s): failed to get interface "
650 "name, rc=%s\n",dev_name(device),wave_out_error(rc));
651 ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),"got an incorrect size: "
652 "%ld instead of %d\n",size,(lstrlenW(nameW)+1)*sizeof(WCHAR));
653 if (rc==MMSYSERR_NOERROR) {
654 nameA = malloc(size/sizeof(WCHAR));
655 WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR), nameA,
656 size/sizeof(WCHAR), NULL, NULL);
660 else if (rc==MMSYSERR_NOTSUPPORTED) {
661 nameA=strdup("not supported");
664 trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname,
665 (nameA?nameA:"failed"),capsA.vDriverVersion >> 8,
666 capsA.vDriverVersion & 0xff, capsA.wMid,capsA.wPid);
667 trace(" channels=%d formats=%05lx support=%04lx\n",
668 capsA.wChannels,capsA.dwFormats,capsA.dwSupport);
669 trace(" %s\n",wave_out_caps(capsA.dwSupport));
672 if (winetest_interactive && (device != WAVE_MAPPER))
674 trace("Playing a 5 seconds reference tone.\n");
675 trace("All subsequent tones should be identical to this one.\n");
676 trace("Listen for stutter, changes in pitch, volume, etc.\n");
677 format.wFormatTag=WAVE_FORMAT_PCM;
679 format.wBitsPerSample=8;
680 format.nSamplesPerSec=22050;
681 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
682 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
684 wave_out_test_deviceOut(device,5.0,&format,WAVE_FORMAT_2M08,0,&capsA,
687 format.wFormatTag=WAVE_FORMAT_PCM;
689 format.wBitsPerSample=8;
690 format.nSamplesPerSec=22050;
691 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
692 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
694 wave_out_test_deviceOut(device,1.0,&format,WAVE_FORMAT_2M08,0,&capsA,
698 for (f=0;f<NB_WIN_FORMATS;f++) {
699 format.wFormatTag=WAVE_FORMAT_PCM;
700 format.nChannels=win_formats[f][3];
701 format.wBitsPerSample=win_formats[f][2];
702 format.nSamplesPerSec=win_formats[f][1];
703 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
704 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
706 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
707 0,&capsA,winetest_interactive,TRUE);
708 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
709 WAVE_FORMAT_DIRECT,&capsA,winetest_interactive,
711 if (device != WAVE_MAPPER)
712 wave_out_test_deviceOut(device,1.0,&format,win_formats[f][0],
713 WAVE_MAPPED,&capsA,winetest_interactive,
717 /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds
719 twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT,
721 ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n");
723 res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS,
725 ok(res, "Failed to set memory access on second page\n");
727 LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize -
728 sizeof(PCMWAVEFORMAT));
729 pwfx->wFormatTag=WAVE_FORMAT_PCM;
731 pwfx->wBitsPerSample=8;
732 pwfx->nSamplesPerSec=22050;
733 pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8;
734 pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign;
735 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,0,
736 &capsA,winetest_interactive,TRUE);
737 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
738 WAVE_FORMAT_DIRECT,&capsA,
739 winetest_interactive,TRUE);
740 if (device != WAVE_MAPPER)
741 wave_out_test_deviceOut(device,1.0,pwfx,WAVE_FORMAT_2M08,
742 WAVE_MAPPED,&capsA,winetest_interactive,
745 VirtualFree(twoPages, 2 * dwPageSize, MEM_RELEASE);
748 /* Testing invalid format: 11 bits per sample */
749 format.wFormatTag=WAVE_FORMAT_PCM;
751 format.wBitsPerSample=11;
752 format.nSamplesPerSec=22050;
753 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
754 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
757 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
758 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
759 rc==MMSYSERR_INVALPARAM,
760 "waveOutOpen(%s): opening the device in 11 bits mode should fail: "
761 "rc=%s\n",dev_name(device),wave_out_error(rc));
762 if (rc==MMSYSERR_NOERROR) {
763 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
764 format.nSamplesPerSec, format.wBitsPerSample,
766 oformat.nSamplesPerSec, oformat.wBitsPerSample,
771 /* Testing invalid format: 2 MHz sample rate */
772 format.wFormatTag=WAVE_FORMAT_PCM;
774 format.wBitsPerSample=16;
775 format.nSamplesPerSec=2000000;
776 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
777 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
780 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
781 ok(rc==WAVERR_BADFORMAT || rc==MMSYSERR_INVALFLAG ||
782 rc==MMSYSERR_INVALPARAM,
783 "waveOutOpen(%s): opening the device at 2 MHz sample rate should fail: "
784 "rc=%s\n",dev_name(device),wave_out_error(rc));
785 if (rc==MMSYSERR_NOERROR) {
786 trace(" got %ldx%2dx%d for %ldx%2dx%d\n",
787 format.nSamplesPerSec, format.wBitsPerSample,
789 oformat.nSamplesPerSec, oformat.wBitsPerSample,
794 /* try some non PCM formats */
795 format.wFormatTag=WAVE_FORMAT_MULAW;
797 format.wBitsPerSample=8;
798 format.nSamplesPerSec=8000;
799 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
800 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
803 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
804 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
805 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
806 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
807 if (rc==MMSYSERR_NOERROR) {
809 wave_out_test_deviceOut(device,1.0,&format,0,0,
810 &capsA,winetest_interactive,TRUE);
812 trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n",
815 format.wFormatTag=WAVE_FORMAT_ADPCM;
817 format.wBitsPerSample=4;
818 format.nSamplesPerSec=22050;
819 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
820 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
823 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT);
824 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT ||
825 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
826 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
827 if (rc==MMSYSERR_NOERROR) {
829 wave_out_test_deviceOut(device,1.0,&format,0,0,
830 &capsA,winetest_interactive,TRUE);
832 trace("waveOutOpen(%s): WAVE_FORMAT_ADPCM not supported\n",
835 /* test if WAVEFORMATEXTENSIBLE supported */
836 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
837 wfex.Format.nChannels=2;
838 wfex.Format.wBitsPerSample=16;
839 wfex.Format.nSamplesPerSec=22050;
840 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
841 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
842 wfex.Format.nBlockAlign;
843 wfex.Format.cbSize=22;
844 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
845 wfex.dwChannelMask=SPEAKER_ALL;
846 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
847 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
848 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
849 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
850 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
851 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
852 if (rc==MMSYSERR_NOERROR) {
854 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
855 &capsA,winetest_interactive,TRUE);
857 trace("waveOutOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n",
860 /* test if 4 channels supported */
861 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
862 wfex.Format.nChannels=4;
863 wfex.Format.wBitsPerSample=16;
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) {
879 wave_out_test_deviceOut(device,1.0,&wfex.Format,0,0,
880 &capsA,winetest_interactive,TRUE);
882 trace("waveOutOpen(%s): 4 channels not supported\n",
885 /* test if 6 channels supported */
886 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
887 wfex.Format.nChannels=6;
888 wfex.Format.wBitsPerSample=16;
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_PCM;
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) {
904 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
905 &capsA,winetest_interactive,TRUE);
907 trace("waveOutOpen(%s): 6 channels not supported\n",
910 #if 0 /* ALSA doesn't like this format */
911 /* test if 24 bit samples supported */
912 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
913 wfex.Format.nChannels=2;
914 wfex.Format.wBitsPerSample=24;
915 wfex.Format.nSamplesPerSec=22050;
916 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
917 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
918 wfex.Format.nBlockAlign;
919 wfex.Format.cbSize=22;
920 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
921 wfex.dwChannelMask=SPEAKER_ALL;
922 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
923 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
924 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
925 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
926 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
927 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
928 if (rc==MMSYSERR_NOERROR) {
930 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
931 &capsA,winetest_interactive,TRUE);
933 trace("waveOutOpen(%s): 24 bit samples not supported\n",
937 /* test if 32 bit samples supported */
938 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
939 wfex.Format.nChannels=2;
940 wfex.Format.wBitsPerSample=32;
941 wfex.Format.nSamplesPerSec=22050;
942 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
943 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
944 wfex.Format.nBlockAlign;
945 wfex.Format.cbSize=22;
946 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
947 wfex.dwChannelMask=SPEAKER_ALL;
948 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
949 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
950 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
951 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
952 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
953 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
954 if (rc==MMSYSERR_NOERROR) {
956 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
957 &capsA,winetest_interactive,TRUE);
959 trace("waveOutOpen(%s): 32 bit samples not supported\n",
962 /* test if 32 bit float samples supported */
963 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
964 wfex.Format.nChannels=2;
965 wfex.Format.wBitsPerSample=32;
966 wfex.Format.nSamplesPerSec=22050;
967 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8;
968 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec*
969 wfex.Format.nBlockAlign;
970 wfex.Format.cbSize=22;
971 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample;
972 wfex.dwChannelMask=SPEAKER_ALL;
973 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
974 rc=waveOutOpen(&wout,device,&wfex.Format,0,0,
975 CALLBACK_NULL|WAVE_FORMAT_DIRECT);
976 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT ||
977 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM,
978 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
979 if (rc==MMSYSERR_NOERROR) {
981 wave_out_test_deviceOut(device,1.0,&wfex.Format,WAVE_FORMAT_2M16,0,
982 &capsA,winetest_interactive,TRUE);
984 trace("waveOutOpen(%s): 32 bit float samples not supported\n",
988 static void wave_out_tests()
997 ndev=waveOutGetNumDevs();
998 trace("found %d WaveOut devices\n",ndev);
1000 rc=waveOutGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
1001 ok(rc==MMSYSERR_BADDEVICEID,
1002 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
1003 dev_name(ndev+1),mmsys_error(rc));
1005 rc=waveOutGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
1006 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NOTSUPPORTED,
1007 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
1008 "expected, got %s\n",dev_name(ndev+1),mmsys_error(rc));
1010 rc=waveOutGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA));
1012 ok(rc==MMSYSERR_NOERROR,
1013 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n",
1014 dev_name(WAVE_MAPPER),mmsys_error(rc));
1016 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER,
1017 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
1018 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
1020 rc=waveOutGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW));
1022 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED,
1023 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED "
1024 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc));
1026 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER ||
1027 rc==MMSYSERR_NOTSUPPORTED,
1028 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER "
1029 " or MMSYSERR_NOTSUPPORTED expected, got %s\n",
1030 dev_name(WAVE_MAPPER),mmsys_error(rc));
1032 format.wFormatTag=WAVE_FORMAT_PCM;
1034 format.wBitsPerSample=16;
1035 format.nSamplesPerSec=44100;
1036 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
1037 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
1039 rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL);
1040 ok(rc==MMSYSERR_BADDEVICEID,
1041 "waveOutOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n",
1042 dev_name(ndev+1),mmsys_error(rc));
1044 for (d=0;d<ndev;d++)
1045 wave_out_test_device(d);
1048 wave_out_test_device(WAVE_MAPPER);