1 /* 2 * Test winmm sound playback in each sound format 3 * 4 * Copyright (c) 2002 Francois Gouget 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <math.h> 25 26 #include "wine/test.h" 27 #include "windef.h" 28 #include "winbase.h" 29 #include "winuser.h" 30 #include "winnls.h" 31 #include "mmsystem.h" 32 #define NOBITMAP 33 #include "mmddk.h" 34 #include "mmreg.h" 35 #include "ks.h" 36 #include "ksguid.h" 37 #ifndef __REACTOS__ 38 #include "ksmedia.h" 39 #endif 40 41 #include "winmm_test.h" 42 43 #ifdef __REACTOS__ /* FIXME */ 44 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 45 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); 46 #endif 47 48 static DWORD g_tid; 49 50 static void test_multiple_waveopens(void) 51 { 52 HWAVEOUT handle1, handle2; 53 MMRESULT ret; 54 WAVEFORMATEX wfx; 55 56 wfx.wFormatTag = WAVE_FORMAT_PCM; 57 wfx.nChannels = 1; 58 wfx.nSamplesPerSec = 11025; 59 wfx.nBlockAlign = 1; 60 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 61 wfx.wBitsPerSample = 8; 62 wfx.cbSize = 0; 63 64 ret = waveOutOpen(&handle1, 0, &wfx, 0, 0, 0); 65 if (ret != MMSYSERR_NOERROR) 66 { 67 skip("Could not do the duplicate waveopen test\n"); 68 return; 69 } 70 71 ret = waveOutOpen(&handle2, 0, &wfx, 0, 0, 0); 72 /* Modern Windows allows for wave-out devices to be opened multiple times. 73 * Some Wine audio drivers allow that and some don't. To avoid false alarms 74 * for those that do, don't "todo_wine ok(...)" on success. 75 */ 76 if (ret != MMSYSERR_NOERROR) 77 { 78 todo_wine ok(ret == MMSYSERR_NOERROR || broken(ret == MMSYSERR_ALLOCATED), /* winME */ 79 "second waveOutOpen returns: %x\n", ret); 80 } 81 else 82 waveOutClose(handle2); 83 84 waveOutClose(handle1); 85 } 86 87 /* 88 * Note that in most of this test we may get MMSYSERR_BADDEVICEID errors 89 * at about any time if the user starts another application that uses the 90 * sound device. So we should not report these as test failures. 91 * 92 * This test can play a test tone. But this only makes sense if someone 93 * is going to carefully listen to it, and would only bother everyone else. 94 * So this is only done if the test is being run in interactive mode. 95 */ 96 97 #define PI 3.14159265358979323846 98 static char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size) 99 { 100 int i,j; 101 int nb_samples; 102 char* buf; 103 char* b; 104 WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE*)wfx; 105 106 nb_samples=(int)(duration*wfx->nSamplesPerSec); 107 *size=nb_samples*wfx->nBlockAlign; 108 b=buf=HeapAlloc(GetProcessHeap(), 0, *size); 109 for (i=0;i<nb_samples;i++) { 110 double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec); 111 if (wfx->wBitsPerSample==8) { 112 unsigned char sample=(unsigned char)(127.5*(y+1.0)); 113 for (j = 0; j < wfx->nChannels; j++) 114 *b++=sample; 115 } else if (wfx->wBitsPerSample==16) { 116 signed short sample=(signed short)(32767.5*y-0.5); 117 for (j = 0; j < wfx->nChannels; j++) { 118 b[0]=sample & 0xff; 119 b[1]=sample >> 8; 120 b+=2; 121 } 122 } else if (wfx->wBitsPerSample==24) { 123 signed int sample=(signed int)(((double)0x7fffff+0.5)*y-0.5); 124 for (j = 0; j < wfx->nChannels; j++) { 125 b[0]=sample & 0xff; 126 b[1]=(sample >> 8) & 0xff; 127 b[2]=(sample >> 16) & 0xff; 128 b+=3; 129 } 130 } else if ((wfx->wBitsPerSample==32) && ((wfx->wFormatTag == WAVE_FORMAT_PCM) || 131 ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) && 132 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)))) { 133 signed int sample=(signed int)(((double)0x7fffffff+0.5)*y-0.5); 134 for (j = 0; j < wfx->nChannels; j++) { 135 b[0]=sample & 0xff; 136 b[1]=(sample >> 8) & 0xff; 137 b[2]=(sample >> 16) & 0xff; 138 b[3]=(sample >> 24) & 0xff; 139 b+=4; 140 } 141 } else if ((wfx->wBitsPerSample==32) && (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) && 142 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) { 143 union { float f; char c[4]; } sample; 144 sample.f=(float)y; 145 for (j = 0; j < wfx->nChannels; j++) { 146 b[0]=sample.c[0]; 147 b[1]=sample.c[1]; 148 b[2]=sample.c[2]; 149 b[3]=sample.c[3]; 150 b+=4; 151 } 152 } 153 } 154 return buf; 155 } 156 157 static char* wave_generate_silence(WAVEFORMATEX* wfx, double duration, DWORD* size) 158 { 159 int i,j; 160 int nb_samples; 161 char* buf; 162 char* b; 163 WAVEFORMATEXTENSIBLE *wfex = (WAVEFORMATEXTENSIBLE*)wfx; 164 165 nb_samples=(int)(duration*wfx->nSamplesPerSec); 166 *size=nb_samples*wfx->nBlockAlign; 167 b=buf=HeapAlloc(GetProcessHeap(), 0, *size); 168 for (i=0;i<nb_samples;i++) { 169 if (wfx->wBitsPerSample==8) { 170 for (j = 0; j < wfx->nChannels; j++) 171 *b++=128; 172 } else if (wfx->wBitsPerSample==16) { 173 for (j = 0; j < wfx->nChannels; j++) { 174 b[0]=0; 175 b[1]=0; 176 b+=2; 177 } 178 } else if (wfx->wBitsPerSample==24) { 179 for (j = 0; j < wfx->nChannels; j++) { 180 b[0]=0; 181 b[1]=0; 182 b[2]=0; 183 b+=3; 184 } 185 } else if ((wfx->wBitsPerSample==32) && ((wfx->wFormatTag == WAVE_FORMAT_PCM) || 186 ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) && 187 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)))) { 188 for (j = 0; j < wfx->nChannels; j++) { 189 b[0]=0; 190 b[1]=0; 191 b[2]=0; 192 b[3]=0; 193 b+=4; 194 } 195 } else if ((wfx->wBitsPerSample==32) && (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) && 196 IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) { 197 union { float f; char c[4]; } sample; 198 sample.f=0; 199 for (j = 0; j < wfx->nChannels; j++) { 200 b[0]=sample.c[0]; 201 b[1]=sample.c[1]; 202 b[2]=sample.c[2]; 203 b[3]=sample.c[3]; 204 b+=4; 205 } 206 } 207 } 208 return buf; 209 } 210 211 const char * dev_name(int device) 212 { 213 static char name[16]; 214 if (device == WAVE_MAPPER) 215 return "WAVE_MAPPER"; 216 sprintf(name, "%d", device); 217 return name; 218 } 219 220 const char* mmsys_error(MMRESULT error) 221 { 222 #define ERR_TO_STR(dev) case dev: return #dev 223 static char unknown[32]; 224 switch (error) { 225 ERR_TO_STR(MMSYSERR_NOERROR); 226 ERR_TO_STR(MMSYSERR_ERROR); 227 ERR_TO_STR(MMSYSERR_BADDEVICEID); 228 ERR_TO_STR(MMSYSERR_NOTENABLED); 229 ERR_TO_STR(MMSYSERR_ALLOCATED); 230 ERR_TO_STR(MMSYSERR_INVALHANDLE); 231 ERR_TO_STR(MMSYSERR_NODRIVER); 232 ERR_TO_STR(MMSYSERR_NOMEM); 233 ERR_TO_STR(MMSYSERR_NOTSUPPORTED); 234 ERR_TO_STR(MMSYSERR_BADERRNUM); 235 ERR_TO_STR(MMSYSERR_INVALFLAG); 236 ERR_TO_STR(MMSYSERR_INVALPARAM); 237 ERR_TO_STR(WAVERR_BADFORMAT); 238 ERR_TO_STR(WAVERR_STILLPLAYING); 239 ERR_TO_STR(WAVERR_UNPREPARED); 240 ERR_TO_STR(WAVERR_SYNC); 241 ERR_TO_STR(MIDIERR_UNPREPARED); 242 ERR_TO_STR(MIDIERR_STILLPLAYING); 243 ERR_TO_STR(MIDIERR_NOTREADY); 244 ERR_TO_STR(MIDIERR_NODEVICE); 245 ERR_TO_STR(MIDIERR_INVALIDSETUP); 246 ERR_TO_STR(TIMERR_NOCANDO); 247 ERR_TO_STR(TIMERR_STRUCT); 248 ERR_TO_STR(JOYERR_PARMS); 249 ERR_TO_STR(JOYERR_NOCANDO); 250 ERR_TO_STR(JOYERR_UNPLUGGED); 251 ERR_TO_STR(MIXERR_INVALLINE); 252 ERR_TO_STR(MIXERR_INVALCONTROL); 253 ERR_TO_STR(MIXERR_INVALVALUE); 254 ERR_TO_STR(MMIOERR_FILENOTFOUND); 255 ERR_TO_STR(MMIOERR_OUTOFMEMORY); 256 ERR_TO_STR(MMIOERR_CANNOTOPEN); 257 ERR_TO_STR(MMIOERR_CANNOTCLOSE); 258 ERR_TO_STR(MMIOERR_CANNOTREAD); 259 ERR_TO_STR(MMIOERR_CANNOTWRITE); 260 ERR_TO_STR(MMIOERR_CANNOTSEEK); 261 ERR_TO_STR(MMIOERR_CANNOTEXPAND); 262 ERR_TO_STR(MMIOERR_CHUNKNOTFOUND); 263 ERR_TO_STR(MMIOERR_UNBUFFERED); 264 } 265 sprintf(unknown, "Unknown(0x%08x)", error); 266 return unknown; 267 #undef ERR_TO_STR 268 } 269 270 const char* wave_out_error(MMRESULT error) 271 { 272 static char msg[1024]; 273 static char long_msg[1100]; 274 MMRESULT rc; 275 276 rc = waveOutGetErrorTextA(error, msg, sizeof(msg)); 277 if (rc != MMSYSERR_NOERROR) 278 sprintf(long_msg, "waveOutGetErrorTextA(%x) failed with error %x", error, rc); 279 else 280 sprintf(long_msg, "%s(%s)", mmsys_error(error), msg); 281 return long_msg; 282 } 283 284 const char * wave_open_flags(DWORD flags) 285 { 286 static char msg[1024]; 287 BOOL first = TRUE; 288 msg[0] = 0; 289 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) { 290 strcat(msg, "CALLBACK_EVENT"); 291 first = FALSE; 292 } 293 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) { 294 if (!first) strcat(msg, "|"); 295 strcat(msg, "CALLBACK_FUNCTION"); 296 first = FALSE; 297 } 298 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_NULL) { 299 if (!first) strcat(msg, "|"); 300 strcat(msg, "CALLBACK_NULL"); 301 first = FALSE; 302 } 303 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) { 304 if (!first) strcat(msg, "|"); 305 strcat(msg, "CALLBACK_THREAD"); 306 first = FALSE; 307 } 308 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) { 309 if (!first) strcat(msg, "|"); 310 strcat(msg, "CALLBACK_WINDOW"); 311 first = FALSE; 312 } 313 if ((flags & WAVE_ALLOWSYNC) == WAVE_ALLOWSYNC) { 314 if (!first) strcat(msg, "|"); 315 strcat(msg, "WAVE_ALLOWSYNC"); 316 first = FALSE; 317 } 318 if ((flags & WAVE_FORMAT_DIRECT) == WAVE_FORMAT_DIRECT) { 319 if (!first) strcat(msg, "|"); 320 strcat(msg, "WAVE_FORMAT_DIRECT"); 321 first = FALSE; 322 } 323 if ((flags & WAVE_FORMAT_QUERY) == WAVE_FORMAT_QUERY) { 324 if (!first) strcat(msg, "|"); 325 strcat(msg, "WAVE_FORMAT_QUERY"); 326 first = FALSE; 327 } 328 if ((flags & WAVE_MAPPED) == WAVE_MAPPED) { 329 if (!first) strcat(msg, "|"); 330 strcat(msg, "WAVE_MAPPED"); 331 } 332 return msg; 333 } 334 335 static const char * wave_header_flags(DWORD flags) 336 { 337 #define WHDR_MASK (WHDR_BEGINLOOP|WHDR_DONE|WHDR_ENDLOOP|WHDR_INQUEUE|WHDR_PREPARED) 338 static char msg[1024]; 339 BOOL first = TRUE; 340 msg[0] = 0; 341 if (flags & WHDR_BEGINLOOP) { 342 strcat(msg, "WHDR_BEGINLOOP"); 343 first = FALSE; 344 } 345 if (flags & WHDR_DONE) { 346 if (!first) strcat(msg, " "); 347 strcat(msg, "WHDR_DONE"); 348 first = FALSE; 349 } 350 if (flags & WHDR_ENDLOOP) { 351 if (!first) strcat(msg, " "); 352 strcat(msg, "WHDR_ENDLOOP"); 353 first = FALSE; 354 } 355 if (flags & WHDR_INQUEUE) { 356 if (!first) strcat(msg, " "); 357 strcat(msg, "WHDR_INQUEUE"); 358 first = FALSE; 359 } 360 if (flags & WHDR_PREPARED) { 361 if (!first) strcat(msg, " "); 362 strcat(msg, "WHDR_PREPARED"); 363 first = FALSE; 364 } 365 if (flags & ~WHDR_MASK) { 366 char temp[32]; 367 sprintf(temp, "UNKNOWN(0x%08x)", flags & ~WHDR_MASK); 368 if (!first) strcat(msg, " "); 369 strcat(msg, temp); 370 } 371 return msg; 372 } 373 374 static const char * wave_out_caps(DWORD dwSupport) 375 { 376 #define ADD_FLAG(f) if (dwSupport & f) strcat(msg, " " #f) 377 static char msg[256]; 378 msg[0] = 0; 379 380 ADD_FLAG(WAVECAPS_PITCH); 381 ADD_FLAG(WAVECAPS_PLAYBACKRATE); 382 ADD_FLAG(WAVECAPS_VOLUME); 383 ADD_FLAG(WAVECAPS_LRVOLUME); 384 ADD_FLAG(WAVECAPS_SYNC); 385 ADD_FLAG(WAVECAPS_SAMPLEACCURATE); 386 387 return msg[0] ? msg + 1 : ""; 388 #undef ADD_FLAG 389 } 390 391 const char * wave_time_format(UINT type) 392 { 393 static char msg[32]; 394 #define TIME_FORMAT(f) case f: return #f 395 switch (type) { 396 TIME_FORMAT(TIME_MS); 397 TIME_FORMAT(TIME_SAMPLES); 398 TIME_FORMAT(TIME_BYTES); 399 TIME_FORMAT(TIME_SMPTE); 400 TIME_FORMAT(TIME_MIDI); 401 TIME_FORMAT(TIME_TICKS); 402 } 403 #undef TIME_FORMAT 404 sprintf(msg, "Unknown(0x%04x)", type); 405 return msg; 406 } 407 408 const char * get_format_str(WORD format) 409 { 410 static char msg[32]; 411 #define WAVE_FORMAT(f) case f: return #f 412 switch (format) { 413 WAVE_FORMAT(WAVE_FORMAT_PCM); 414 WAVE_FORMAT(WAVE_FORMAT_ADPCM); 415 WAVE_FORMAT(WAVE_FORMAT_IBM_CVSD); 416 WAVE_FORMAT(WAVE_FORMAT_ALAW); 417 WAVE_FORMAT(WAVE_FORMAT_MULAW); 418 WAVE_FORMAT(WAVE_FORMAT_OKI_ADPCM); 419 WAVE_FORMAT(WAVE_FORMAT_IMA_ADPCM); 420 WAVE_FORMAT(WAVE_FORMAT_MEDIASPACE_ADPCM); 421 WAVE_FORMAT(WAVE_FORMAT_SIERRA_ADPCM); 422 WAVE_FORMAT(WAVE_FORMAT_G723_ADPCM); 423 WAVE_FORMAT(WAVE_FORMAT_DIGISTD); 424 WAVE_FORMAT(WAVE_FORMAT_DIGIFIX); 425 WAVE_FORMAT(WAVE_FORMAT_DIALOGIC_OKI_ADPCM); 426 WAVE_FORMAT(WAVE_FORMAT_YAMAHA_ADPCM); 427 WAVE_FORMAT(WAVE_FORMAT_SONARC); 428 WAVE_FORMAT(WAVE_FORMAT_DSPGROUP_TRUESPEECH); 429 WAVE_FORMAT(WAVE_FORMAT_ECHOSC1); 430 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF36); 431 WAVE_FORMAT(WAVE_FORMAT_APTX); 432 WAVE_FORMAT(WAVE_FORMAT_AUDIOFILE_AF10); 433 WAVE_FORMAT(WAVE_FORMAT_DOLBY_AC2); 434 WAVE_FORMAT(WAVE_FORMAT_GSM610); 435 WAVE_FORMAT(WAVE_FORMAT_ANTEX_ADPCME); 436 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_VQLPC); 437 WAVE_FORMAT(WAVE_FORMAT_DIGIREAL); 438 WAVE_FORMAT(WAVE_FORMAT_DIGIADPCM); 439 WAVE_FORMAT(WAVE_FORMAT_CONTROL_RES_CR10); 440 WAVE_FORMAT(WAVE_FORMAT_NMS_VBXADPCM); 441 WAVE_FORMAT(WAVE_FORMAT_G721_ADPCM); 442 WAVE_FORMAT(WAVE_FORMAT_MPEG); 443 WAVE_FORMAT(WAVE_FORMAT_MPEGLAYER3); 444 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_ADPCM); 445 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH8); 446 WAVE_FORMAT(WAVE_FORMAT_CREATIVE_FASTSPEECH10); 447 WAVE_FORMAT(WAVE_FORMAT_FM_TOWNS_SND); 448 WAVE_FORMAT(WAVE_FORMAT_OLIGSM); 449 WAVE_FORMAT(WAVE_FORMAT_OLIADPCM); 450 WAVE_FORMAT(WAVE_FORMAT_OLICELP); 451 WAVE_FORMAT(WAVE_FORMAT_OLISBC); 452 WAVE_FORMAT(WAVE_FORMAT_OLIOPR); 453 WAVE_FORMAT(WAVE_FORMAT_DEVELOPMENT); 454 WAVE_FORMAT(WAVE_FORMAT_EXTENSIBLE); 455 } 456 #undef WAVE_FORMAT 457 sprintf(msg, "Unknown(0x%04x)", format); 458 return msg; 459 } 460 461 DWORD bytes_to_samples(DWORD bytes, LPWAVEFORMATEX pwfx) 462 { 463 return bytes / pwfx->nBlockAlign; 464 } 465 466 DWORD bytes_to_ms(DWORD bytes, LPWAVEFORMATEX pwfx) 467 { 468 return bytes_to_samples(bytes, pwfx) * 1000 / pwfx->nSamplesPerSec; 469 } 470 471 DWORD time_to_bytes(LPMMTIME mmtime, LPWAVEFORMATEX pwfx) 472 { 473 if (mmtime->wType == TIME_BYTES) 474 return mmtime->u.cb; 475 else if (mmtime->wType == TIME_SAMPLES) 476 return mmtime->u.sample * pwfx->nBlockAlign; 477 else if (mmtime->wType == TIME_MS) 478 return mmtime->u.ms * pwfx->nAvgBytesPerSec / 1000; 479 else if (mmtime->wType == TIME_SMPTE) 480 return ((mmtime->u.smpte.hour * 60 * 60) + 481 (mmtime->u.smpte.min * 60) + 482 (mmtime->u.smpte.sec)) * pwfx->nAvgBytesPerSec + 483 mmtime->u.smpte.frame * pwfx->nAvgBytesPerSec / 30; 484 485 trace("FIXME: time_to_bytes() type not supported\n"); 486 return -1; 487 } 488 489 static void check_position(int device, HWAVEOUT wout, DWORD bytes, 490 LPWAVEFORMATEX pwfx ) 491 { 492 MMTIME mmtime; 493 MMRESULT rc; 494 DWORD returned; 495 496 mmtime.wType = TIME_BYTES; 497 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime) - 1); 498 ok(rc==MMSYSERR_ERROR, 499 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 500 501 mmtime.wType = TIME_BYTES; 502 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime) + 1); 503 ok(rc==MMSYSERR_NOERROR, 504 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 505 if (mmtime.wType != TIME_BYTES && winetest_debug > 1) 506 trace("waveOutGetPosition(%s): TIME_BYTES not supported, returned %s\n", 507 dev_name(device),wave_time_format(mmtime.wType)); 508 returned = time_to_bytes(&mmtime, pwfx); 509 ok(returned == bytes, "waveOutGetPosition(%s): returned %d bytes, " 510 "should be %d\n", dev_name(device), returned, bytes); 511 512 mmtime.wType = TIME_SAMPLES; 513 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); 514 ok(rc==MMSYSERR_NOERROR, 515 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 516 if (mmtime.wType != TIME_SAMPLES && winetest_debug > 1) 517 trace("waveOutGetPosition(%s): TIME_SAMPLES not supported, " 518 "returned %s\n",dev_name(device),wave_time_format(mmtime.wType)); 519 returned = time_to_bytes(&mmtime, pwfx); 520 ok(returned == bytes, "waveOutGetPosition(%s): returned %d samples " 521 "(%d bytes), should be %d (%d bytes)\n", dev_name(device), 522 bytes_to_samples(returned, pwfx), returned, 523 bytes_to_samples(bytes, pwfx), bytes); 524 525 mmtime.wType = TIME_MS; 526 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); 527 ok(rc==MMSYSERR_NOERROR, 528 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 529 if (mmtime.wType != TIME_MS && winetest_debug > 1) 530 trace("waveOutGetPosition(%s): TIME_MS not supported, returned %s\n", 531 dev_name(device), wave_time_format(mmtime.wType)); 532 returned = time_to_bytes(&mmtime, pwfx); 533 ok(returned == bytes, "waveOutGetPosition(%s): returned %d ms, " 534 "(%d bytes), should be %d (%d bytes)\n", dev_name(device), 535 bytes_to_ms(returned, pwfx), returned, 536 bytes_to_ms(bytes, pwfx), bytes); 537 538 mmtime.wType = TIME_SMPTE; 539 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); 540 ok(rc==MMSYSERR_NOERROR, 541 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 542 if (mmtime.wType != TIME_SMPTE && winetest_debug > 1) 543 trace("waveOutGetPosition(%s): TIME_SMPTE not supported, returned %s\n", 544 dev_name(device),wave_time_format(mmtime.wType)); 545 returned = time_to_bytes(&mmtime, pwfx); 546 ok(returned == bytes, "waveOutGetPosition(%s): SMPTE test failed\n", 547 dev_name(device)); 548 549 mmtime.wType = TIME_MIDI; 550 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); 551 ok(rc==MMSYSERR_NOERROR, 552 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 553 if (mmtime.wType != TIME_MIDI && winetest_debug > 1) 554 trace("waveOutGetPosition(%s): TIME_MIDI not supported, returned %s\n", 555 dev_name(device),wave_time_format(mmtime.wType)); 556 returned = time_to_bytes(&mmtime, pwfx); 557 ok(returned == bytes, "waveOutGetPosition(%s): MIDI test failed\n", 558 dev_name(device)); 559 560 mmtime.wType = TIME_TICKS; 561 rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); 562 ok(rc==MMSYSERR_NOERROR, 563 "waveOutGetPosition(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 564 if (mmtime.wType != TIME_TICKS && winetest_debug > 1) 565 trace("waveOutGetPosition(%s): TIME_TICKS not supported, returned %s\n", 566 dev_name(device),wave_time_format(mmtime.wType)); 567 returned = time_to_bytes(&mmtime, pwfx); 568 ok(returned == bytes, "waveOutGetPosition(%s): TICKS test failed\n", 569 dev_name(device)); 570 } 571 572 static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg, 573 DWORD_PTR dwInstance, 574 DWORD dwParam1, DWORD dwParam2) 575 { 576 if(uMsg == WOM_OPEN || uMsg == WOM_CLOSE) 577 ok(GetCurrentThreadId() == g_tid, "Got different thread ID\n"); 578 SetEvent((HANDLE)dwInstance); 579 } 580 581 static DWORD WINAPI callback_thread(LPVOID lpParameter) 582 { 583 MSG msg; 584 585 PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ); /* make sure the thread has a message queue */ 586 SetEvent(lpParameter); 587 588 while (GetMessageA(&msg, 0, 0, 0)) { 589 UINT message = msg.message; 590 /* for some reason XP sends a WM_USER message before WOM_OPEN */ 591 ok (message == WOM_OPEN || message == WOM_DONE || 592 message == WOM_CLOSE || message == WM_USER || message == WM_APP, 593 "GetMessageA returned unexpected message: %u\n", message); 594 if (message == WOM_OPEN || message == WOM_DONE || message == WOM_CLOSE) 595 SetEvent(lpParameter); 596 else if (message == WM_APP) { 597 SetEvent(lpParameter); 598 return 0; 599 } 600 } 601 602 return 0; 603 } 604 605 static void wave_out_test_deviceOut(int device, double duration, int headers, int loops, 606 WAVEFORMATEX *pwfx, DWORD format, DWORD flags, WAVEOUTCAPSA *pcaps, BOOL interactive, 607 BOOL sine, BOOL pause) 608 { 609 HWAVEOUT wout; 610 HANDLE hevent = CreateEventW(NULL, FALSE, FALSE, NULL); 611 WAVEHDR *frags = 0; 612 MMRESULT rc; 613 DWORD volume; 614 WORD nChannels = pwfx->nChannels; 615 WORD wBitsPerSample = pwfx->wBitsPerSample; 616 DWORD nSamplesPerSec = pwfx->nSamplesPerSec; 617 BOOL has_volume = (pcaps->dwSupport & WAVECAPS_VOLUME) != 0; 618 double paused = 0.0; 619 DWORD_PTR callback = 0; 620 DWORD_PTR callback_instance = 0; 621 HANDLE thread = 0; 622 DWORD thread_id; 623 char * buffer; 624 DWORD length; 625 DWORD frag_length; 626 int i, j; 627 628 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_EVENT) { 629 callback = (DWORD_PTR)hevent; 630 callback_instance = 0; 631 } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_FUNCTION) { 632 callback = (DWORD_PTR)callback_func; 633 callback_instance = (DWORD_PTR)hevent; 634 } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) { 635 thread = CreateThread(NULL, 0, callback_thread, hevent, 0, &thread_id); 636 if (thread) { 637 /* make sure thread is running */ 638 WaitForSingleObject(hevent,10000); 639 callback = thread_id; 640 callback_instance = 0; 641 } else { 642 trace("CreateThread() failed\n"); 643 CloseHandle(hevent); 644 return; 645 } 646 } else if ((flags & CALLBACK_TYPEMASK) == CALLBACK_WINDOW) { 647 trace("CALLBACK_THREAD not implemented\n"); 648 CloseHandle(hevent); 649 return; 650 } else if (flags & CALLBACK_TYPEMASK) { 651 trace("Undefined callback type!\n"); 652 CloseHandle(hevent); 653 return; 654 } else { 655 trace("CALLBACK_NULL not implemented\n"); 656 CloseHandle(hevent); 657 return; 658 } 659 wout=NULL; 660 g_tid = GetCurrentThreadId(); 661 rc=waveOutOpen(&wout,device,pwfx,callback,callback_instance,flags); 662 /* Note: Win9x doesn't know WAVE_FORMAT_DIRECT */ 663 /* It is acceptable to fail on formats that are not specified to work */ 664 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID || 665 rc==MMSYSERR_NOTENABLED || rc==MMSYSERR_NODRIVER || 666 rc==MMSYSERR_ALLOCATED || 667 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) && 668 (flags & WAVE_FORMAT_DIRECT) && !(pcaps->dwFormats & format)) || 669 ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) && 670 (!(flags & WAVE_FORMAT_DIRECT) || (flags & WAVE_MAPPED)) && 671 !(pcaps->dwFormats & format)) || 672 (rc==MMSYSERR_INVALFLAG && (flags & WAVE_FORMAT_DIRECT)), 673 "waveOutOpen(%s): format=%dx%2dx%d flags=%x(%s) rc=%s\n", 674 dev_name(device),pwfx->nSamplesPerSec,pwfx->wBitsPerSample, 675 pwfx->nChannels,flags,wave_open_flags(flags),wave_out_error(rc)); 676 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) && 677 (flags & WAVE_FORMAT_DIRECT) && (pcaps->dwFormats & format)) 678 trace(" Reason: The device lists this format as supported in its " 679 "capabilities but opening it failed.\n"); 680 if ((rc==WAVERR_BADFORMAT || rc==MMSYSERR_NOTSUPPORTED) && 681 !(pcaps->dwFormats & format)) 682 trace("waveOutOpen(%s): format=%dx%2dx%d %s rc=%s failed but format " 683 "not supported so OK.\n", dev_name(device), pwfx->nSamplesPerSec, 684 pwfx->wBitsPerSample,pwfx->nChannels, 685 flags & WAVE_FORMAT_DIRECT ? "flags=WAVE_FORMAT_DIRECT" : 686 flags & WAVE_MAPPED ? "flags=WAVE_MAPPED" : "", mmsys_error(rc)); 687 if (rc!=MMSYSERR_NOERROR) 688 goto EXIT; 689 690 rc=WaitForSingleObject(hevent,9000); 691 ok(rc==WAIT_OBJECT_0, "missing WOM_OPEN notification\n"); 692 693 ok(pwfx->nChannels==nChannels && 694 pwfx->wBitsPerSample==wBitsPerSample && 695 pwfx->nSamplesPerSec==nSamplesPerSec, 696 "got the wrong format: %dx%2dx%d instead of %dx%2dx%d\n", 697 pwfx->nSamplesPerSec, pwfx->wBitsPerSample, 698 pwfx->nChannels, nSamplesPerSec, wBitsPerSample, nChannels); 699 700 frags = HeapAlloc(GetProcessHeap(), 0, headers * sizeof(WAVEHDR)); 701 702 if (sine) 703 buffer=wave_generate_la(pwfx,duration / (loops + 1),&length); 704 else 705 buffer=wave_generate_silence(pwfx,duration / (loops + 1),&length); 706 707 rc=waveOutGetVolume(wout,0); 708 ok(rc==MMSYSERR_INVALPARAM,"waveOutGetVolume(%s,0) expected " 709 "MMSYSERR_INVALPARAM, got %s\n", dev_name(device),wave_out_error(rc)); 710 rc=waveOutGetVolume(wout,&volume); 711 if (rc == MMSYSERR_NOTSUPPORTED) has_volume = FALSE; 712 ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED, 713 "waveOutGetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 714 715 /* make sure fragment length is a multiple of block size */ 716 frag_length = ((length / headers) / pwfx->nBlockAlign) * pwfx->nBlockAlign; 717 718 for (i = 0; i < headers; i++) { 719 frags[i].lpData=buffer + (i * frag_length); 720 if (i != (headers-1)) 721 frags[i].dwBufferLength=frag_length; 722 else { 723 /* use remainder of buffer for last fragment */ 724 frags[i].dwBufferLength=length - (i * frag_length); 725 } 726 frags[i].dwFlags=0; 727 frags[i].dwLoops=0; 728 rc=waveOutPrepareHeader(wout, &frags[i], sizeof(frags[0])); 729 ok(rc==MMSYSERR_NOERROR, 730 "waveOutPrepareHeader(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 731 } 732 733 if (interactive && rc==MMSYSERR_NOERROR) { 734 trace("Playing %g second %s at %5dx%2dx%d %2d header%s %d loop%s %d bytes %s %s\n",duration, 735 sine ? "440 Hz tone" : "silence", pwfx->nSamplesPerSec, 736 pwfx->wBitsPerSample,pwfx->nChannels, headers, headers > 1 ? "s": " ", 737 loops, loops == 1 ? " " : "s", length * (loops + 1), 738 get_format_str(pwfx->wFormatTag), 739 wave_open_flags(flags)); 740 if (sine && has_volume && volume == 0) 741 trace("*** Warning the sound is muted, you will not hear the test\n"); 742 743 /* Check that the position is 0 at start */ 744 check_position(device, wout, 0, pwfx); 745 746 rc=waveOutSetVolume(wout,0x20002000); 747 ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED, 748 "waveOutSetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 749 750 rc=waveOutSetVolume(wout,volume); 751 ok(has_volume ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED, 752 "waveOutSetVolume(%s): rc=%s\n",dev_name(device),wave_out_error(rc)); 753 754 rc=waveOutWrite(wout, &frags[0], sizeof(frags[0])); 755 ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s): rc=%s\n", 756 dev_name(device),wave_out_error(rc)); 757 758 ok(frags[0].dwFlags==(WHDR_PREPARED|WHDR_INQUEUE), 759 "WHDR_INQUEUE WHDR_PREPARED expected, got= %s\n", 760 wave_header_flags(frags[0].dwFlags)); 761 762 rc=waveOutWrite(wout, &frags[0], sizeof(frags[0])); 763 ok(rc==WAVERR_STILLPLAYING, 764 "waveOutWrite(%s): WAVE_STILLPLAYING expected, got %s\n", 765 dev_name(device),wave_out_error(rc)); 766 767 ok(frags[0].dwFlags==(WHDR_PREPARED|WHDR_INQUEUE), 768 "WHDR_INQUEUE WHDR_PREPARED expected, got %s\n", 769 wave_header_flags(frags[0].dwFlags)); 770 771 if (headers == 1 && loops == 0 && pause) { 772 paused = duration / 2; 773 Sleep(paused * 1000); 774 rc=waveOutPause(wout); 775 ok(rc==MMSYSERR_NOERROR,"waveOutPause(%s): rc=%s\n", 776 dev_name(device),wave_out_error(rc)); 777 trace("pausing for %g seconds\n", paused); 778 Sleep(paused * 1000); 779 rc=waveOutRestart(wout); 780 ok(rc==MMSYSERR_NOERROR,"waveOutRestart(%s): rc=%s\n", 781 dev_name(device),wave_out_error(rc)); 782 } 783 784 for (j = 0; j <= loops; j++) { 785 for (i = 0; i < headers; i++) { 786 /* don't do last one */ 787 if (!((j == loops) && (i == (headers - 1)))) { 788 if (j > 0) 789 frags[(i+1) % headers].dwFlags = WHDR_PREPARED; 790 rc=waveOutWrite(wout, &frags[(i+1) % headers], sizeof(frags[0])); 791 ok(rc==MMSYSERR_NOERROR,"waveOutWrite(%s, header[%d]): rc=%s\n", 792 dev_name(device),(i+1)%headers,wave_out_error(rc)); 793 } 794 rc=WaitForSingleObject(hevent,8000); 795 ok(rc==WAIT_OBJECT_0, "missing WOM_DONE notification\n"); 796 } 797 } 798 799 for (i = 0; i < headers; i++) { 800 ok(frags[i].dwFlags==(WHDR_DONE|WHDR_PREPARED) || 801 broken((flags & CALLBACK_TYPEMASK)==CALLBACK_EVENT && 802 frags[i].dwFlags==(WHDR_DONE|WHDR_PREPARED|0x1000)), /* < NT4 */ 803 "(%02d) WHDR_DONE WHDR_PREPARED expected, got %s\n", 804 i, wave_header_flags(frags[i].dwFlags)); 805 } 806 check_position(device, wout, length * (loops + 1), pwfx); 807 } 808 809 for (i = 0; i < headers; i++) { 810 rc=waveOutUnprepareHeader(wout, &frags[i], sizeof(frags[0])); 811 ok(rc==MMSYSERR_NOERROR, 812 "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device), 813 wave_out_error(rc)); 814 } 815 816 ok(frags[0].dwFlags==(interactive ? WHDR_DONE : 0), "dwFlags(%d)=%x\n",device,frags[0].dwFlags); 817 818 frags[0].dwFlags |= WHDR_DONE; 819 rc=waveOutUnprepareHeader(wout, &frags[0], sizeof(frags[0])); 820 ok(rc==MMSYSERR_NOERROR, "waveOutUnprepareHeader(%d): rc=%s\n",device,wave_out_error(rc)); 821 ok(frags[0].dwFlags==WHDR_DONE, "dwFlags(%d)=%x\n",device,frags[0].dwFlags); 822 823 frags[0].dwFlags |= WHDR_INQUEUE; 824 rc=waveOutPrepareHeader(wout, &frags[0], sizeof(frags[0])); 825 ok(rc==MMSYSERR_NOERROR, "waveOutPrepareHeader(%d): rc=%s\n",device,wave_out_error(rc)); 826 ok(frags[0].dwFlags==WHDR_PREPARED, "dwFlags(%d)=%x\n",device,frags[0].dwFlags); 827 828 frags[0].dwFlags |= WHDR_INQUEUE; 829 rc=waveOutPrepareHeader(wout, &frags[0], sizeof(frags[0])); 830 ok(rc==MMSYSERR_NOERROR, "waveOutPrepareHeader(%d): rc=%s\n",device,wave_out_error(rc)); 831 ok(frags[0].dwFlags==(WHDR_PREPARED|WHDR_INQUEUE), "dwFlags(%d)=%x\n",device,frags[0].dwFlags); 832 833 frags[0].dwFlags &= ~(WHDR_INQUEUE|WHDR_DONE); 834 rc=waveOutUnprepareHeader(wout, &frags[0], sizeof(frags[0])); 835 ok(rc==MMSYSERR_NOERROR, "waveOutUnprepareHeader(%d): rc=%s\n",device,wave_out_error(rc)); 836 ok(frags[0].dwFlags==0, "dwFlags(%d)=%x\n",device,frags[0].dwFlags); 837 838 rc=waveOutClose(wout); 839 ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device), 840 wave_out_error(rc)); 841 if (rc==WAVERR_STILLPLAYING) { 842 /* waveOutReset ought to return all buffers s.t. waveOutClose succeeds */ 843 rc=waveOutReset(wout); 844 ok(rc==MMSYSERR_NOERROR,"waveOutReset(%s): rc=%s\n",dev_name(device), 845 wave_out_error(rc)); 846 847 for (i = 0; i < headers; i++) { 848 rc=waveOutUnprepareHeader(wout, &frags[i], sizeof(frags[0])); 849 ok(rc==MMSYSERR_NOERROR, 850 "waveOutUnprepareHeader(%s): rc=%s\n",dev_name(device), 851 wave_out_error(rc)); 852 } 853 rc=waveOutClose(wout); 854 ok(rc==MMSYSERR_NOERROR,"waveOutClose(%s): rc=%s\n",dev_name(device), 855 wave_out_error(rc)); 856 } 857 rc=WaitForSingleObject(hevent,1500); 858 ok(rc==WAIT_OBJECT_0, "missing WOM_CLOSE notification\n"); 859 860 wout = (HWAVEOUT)0xdeadf00d; 861 rc=waveOutOpen(&wout,device,pwfx,callback,callback_instance,flags|WAVE_FORMAT_QUERY); 862 ok(rc==MMSYSERR_NOERROR, "WAVE_FORMAT_QUERY(%s): rc=%s\n",dev_name(device), 863 wave_out_error(rc)); 864 ok(wout==(HWAVEOUT)0xdeadf00d, "WAVE_FORMAT_QUERY handle %p\n", wout); 865 866 rc=WaitForSingleObject(hevent,20); 867 ok(rc==WAIT_TIMEOUT, "Notification from %s rc=%x\n", 868 wave_open_flags(flags|WAVE_FORMAT_QUERY),rc); 869 870 HeapFree(GetProcessHeap(), 0, buffer); 871 EXIT: 872 if ((flags & CALLBACK_TYPEMASK) == CALLBACK_THREAD) { 873 PostThreadMessageW(thread_id, WM_APP, 0, 0); 874 WaitForSingleObject(hevent,10000); 875 } 876 CloseHandle(hevent); 877 HeapFree(GetProcessHeap(), 0, frags); 878 } 879 880 static void wave_out_test_device(UINT_PTR device) 881 { 882 WAVEOUTCAPSA capsA; 883 WAVEOUTCAPSW capsW; 884 WAVEFORMATEX format; 885 WAVEFORMATEXTENSIBLE wfex; 886 IMAADPCMWAVEFORMAT wfa; 887 HWAVEOUT wout; 888 MMRESULT rc; 889 UINT f; 890 WCHAR * nameW; 891 CHAR * nameA; 892 DWORD size; 893 DWORD dwPageSize; 894 BYTE * twoPages; 895 SYSTEM_INFO sSysInfo; 896 DWORD flOldProtect; 897 BOOL res; 898 899 GetSystemInfo(&sSysInfo); 900 dwPageSize = sSysInfo.dwPageSize; 901 902 rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA)); 903 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_BADDEVICEID || 904 rc==MMSYSERR_NODRIVER, 905 "waveOutGetDevCapsA(%s): failed to get capabilities: rc=%s\n", 906 dev_name(device),wave_out_error(rc)); 907 if (rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER) 908 return; 909 910 rc=waveOutGetDevCapsW(device,&capsW,sizeof(capsW)); 911 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED, 912 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED " 913 "expected, got %s\n",dev_name(device),wave_out_error(rc)); 914 915 rc=waveOutGetDevCapsA(device,0,sizeof(capsA)); 916 ok(rc==MMSYSERR_INVALPARAM, 917 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, " 918 "got %s\n",dev_name(device),wave_out_error(rc)); 919 920 rc=waveOutGetDevCapsW(device,0,sizeof(capsW)); 921 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED, 922 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED " 923 "expected, got %s\n",dev_name(device),wave_out_error(rc)); 924 925 if (0) 926 { 927 /* FIXME: this works on windows but crashes wine */ 928 rc=waveOutGetDevCapsA(device,(LPWAVEOUTCAPSA)1,sizeof(capsA)); 929 ok(rc==MMSYSERR_INVALPARAM, 930 "waveOutGetDevCapsA(%s): MMSYSERR_INVALPARAM expected, got %s\n", 931 dev_name(device),wave_out_error(rc)); 932 933 rc=waveOutGetDevCapsW(device,(LPWAVEOUTCAPSW)1,sizeof(capsW)); 934 ok(rc==MMSYSERR_INVALPARAM || rc==MMSYSERR_NOTSUPPORTED, 935 "waveOutGetDevCapsW(%s): MMSYSERR_INVALPARAM or MMSYSERR_NOTSUPPORTED " 936 "expected, got %s\n",dev_name(device),wave_out_error(rc)); 937 } 938 939 rc=waveOutGetDevCapsA(device,&capsA,4); 940 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_INVALPARAM, 941 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR or MMSYSERR_INVALPARAM " 942 "expected, got %s\n", dev_name(device),wave_out_error(rc)); 943 944 rc=waveOutGetDevCapsW(device,&capsW,4); 945 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED || 946 rc==MMSYSERR_INVALPARAM, /* Vista, W2K8 */ 947 "waveOutGetDevCapsW(%s): unexpected return value %s\n", 948 dev_name(device),wave_out_error(rc)); 949 950 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYMAPPABLE, 0, 0); 951 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED, 952 "DRV_QUERYMAPPABLE(%s): unexpected return value %s\n", 953 dev_name(device),wave_out_error(rc)); 954 955 nameA=NULL; 956 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACESIZE, 957 (DWORD_PTR)&size, 0); 958 ok(rc==MMSYSERR_NOERROR || broken(rc==MMSYSERR_INVALPARAM || 959 rc==MMSYSERR_NOTSUPPORTED), 960 "waveOutMessage(%s): failed to get interface size, rc=%s\n", 961 dev_name(device),wave_out_error(rc)); 962 if (rc==MMSYSERR_NOERROR) { 963 nameW = HeapAlloc(GetProcessHeap(), 0, size); 964 rc=waveOutMessage((HWAVEOUT)device, DRV_QUERYDEVICEINTERFACE, 965 (DWORD_PTR)nameW, size); 966 ok(rc==MMSYSERR_NOERROR,"waveOutMessage(%s): failed to get interface " 967 "name, rc=%s\n",dev_name(device),wave_out_error(rc)); 968 ok(lstrlenW(nameW)+1==size/sizeof(WCHAR),"got an incorrect size %d\n",size); 969 if (rc==MMSYSERR_NOERROR) { 970 nameA = HeapAlloc(GetProcessHeap(), 0, size/sizeof(WCHAR)); 971 WideCharToMultiByte(CP_ACP, 0, nameW, size/sizeof(WCHAR), nameA, 972 size/sizeof(WCHAR), NULL, NULL); 973 } 974 HeapFree(GetProcessHeap(), 0, nameW); 975 } 976 else if (rc==MMSYSERR_NOTSUPPORTED) { 977 nameA=HeapAlloc(GetProcessHeap(), 0, sizeof("not supported")); 978 strcpy(nameA, "not supported"); 979 } 980 981 rc=waveOutGetDevCapsA(device,&capsA,sizeof(capsA)); 982 ok(rc==MMSYSERR_NOERROR, 983 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n", 984 dev_name(device),wave_out_error(rc)); 985 if (rc!=MMSYSERR_NOERROR) 986 { 987 HeapFree(GetProcessHeap(), 0, nameA); 988 return; 989 } 990 991 trace(" %s: \"%s\" (%s) %d.%d (%d:%d)\n",dev_name(device),capsA.szPname, 992 (nameA?nameA:"failed"),capsA.vDriverVersion >> 8, 993 capsA.vDriverVersion & 0xff, capsA.wMid,capsA.wPid); 994 trace(" channels=%d formats=%05x support=%04x\n", 995 capsA.wChannels,capsA.dwFormats,capsA.dwSupport); 996 trace(" %s\n",wave_out_caps(capsA.dwSupport)); 997 HeapFree(GetProcessHeap(), 0, nameA); 998 999 if (winetest_interactive && (device != WAVE_MAPPER)) 1000 { 1001 trace("Playing a 5 seconds reference tone.\n"); 1002 trace("All subsequent tones should be identical to this one.\n"); 1003 trace("Listen for stutter, changes in pitch, volume, etc.\n"); 1004 format.wFormatTag=WAVE_FORMAT_PCM; 1005 format.nChannels=1; 1006 format.wBitsPerSample=8; 1007 format.nSamplesPerSec=22050; 1008 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; 1009 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; 1010 format.cbSize=0; 1011 1012 wave_out_test_deviceOut(device,5.0,1,0,&format,WAVE_FORMAT_2M08, 1013 CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE); 1014 wave_out_test_deviceOut(device,5.0,1,0,&format,WAVE_FORMAT_2M08, 1015 CALLBACK_FUNCTION,&capsA,TRUE,TRUE,FALSE); 1016 wave_out_test_deviceOut(device,5.0,1,0,&format,WAVE_FORMAT_2M08, 1017 CALLBACK_THREAD,&capsA,TRUE,TRUE,FALSE); 1018 1019 wave_out_test_deviceOut(device,5.0,10,0,&format,WAVE_FORMAT_2M08, 1020 CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE); 1021 wave_out_test_deviceOut(device,5.0,5,1,&format,WAVE_FORMAT_2M08, 1022 CALLBACK_EVENT,&capsA,TRUE,TRUE,FALSE); 1023 } else { 1024 format.wFormatTag=WAVE_FORMAT_PCM; 1025 format.nChannels=1; 1026 format.wBitsPerSample=8; 1027 format.nSamplesPerSec=22050; 1028 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; 1029 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; 1030 format.cbSize=0; 1031 wave_out_test_deviceOut(device,0.6,1,0,&format,WAVE_FORMAT_2M08, 1032 CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE); 1033 wave_out_test_deviceOut(device,0.6,1,0,&format,WAVE_FORMAT_2M08, 1034 CALLBACK_EVENT,&capsA,TRUE,FALSE,TRUE); 1035 wave_out_test_deviceOut(device,0.6,1,0,&format,WAVE_FORMAT_2M08, 1036 CALLBACK_FUNCTION,&capsA,TRUE,FALSE,FALSE); 1037 wave_out_test_deviceOut(device,0.6,1,0,&format,WAVE_FORMAT_2M08, 1038 CALLBACK_FUNCTION,&capsA,TRUE,FALSE,TRUE); 1039 wave_out_test_deviceOut(device,0.6,1,0,&format,WAVE_FORMAT_2M08, 1040 CALLBACK_THREAD,&capsA,TRUE,FALSE,FALSE); 1041 wave_out_test_deviceOut(device,0.6,1,0,&format,WAVE_FORMAT_2M08, 1042 CALLBACK_THREAD,&capsA,TRUE,FALSE,TRUE); 1043 1044 wave_out_test_deviceOut(device,0.8,10,0,&format,WAVE_FORMAT_2M08, 1045 CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE); 1046 wave_out_test_deviceOut(device,1.0,5,1,&format,WAVE_FORMAT_2M08, 1047 CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE); 1048 } 1049 1050 for (f = 0; f < ARRAY_SIZE(win_formats); f++) { 1051 format.wFormatTag=WAVE_FORMAT_PCM; 1052 format.nChannels=win_formats[f][3]; 1053 format.wBitsPerSample=win_formats[f][2]; 1054 format.nSamplesPerSec=win_formats[f][1]; 1055 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; 1056 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; 1057 format.cbSize=0; 1058 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1059 CALLBACK_EVENT,&capsA,winetest_interactive, 1060 TRUE,FALSE); 1061 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1062 CALLBACK_FUNCTION,&capsA,winetest_interactive, 1063 TRUE,FALSE); 1064 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1065 CALLBACK_THREAD,&capsA,winetest_interactive, 1066 TRUE,FALSE); 1067 1068 wave_out_test_deviceOut(device,1.0,10,0,&format,win_formats[f][0], 1069 CALLBACK_EVENT,&capsA,winetest_interactive, 1070 TRUE,FALSE); 1071 wave_out_test_deviceOut(device,1.0,5,1,&format,win_formats[f][0], 1072 CALLBACK_EVENT,&capsA,winetest_interactive, 1073 TRUE,FALSE); 1074 1075 if (winetest_interactive) { 1076 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1077 CALLBACK_EVENT,&capsA,winetest_interactive, 1078 TRUE,TRUE); 1079 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1080 CALLBACK_FUNCTION,&capsA,winetest_interactive, 1081 TRUE,TRUE); 1082 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1083 CALLBACK_THREAD,&capsA,winetest_interactive, 1084 TRUE,TRUE); 1085 1086 wave_out_test_deviceOut(device,1.0,10,0,&format,win_formats[f][0], 1087 CALLBACK_EVENT,&capsA,winetest_interactive, 1088 TRUE,TRUE); 1089 wave_out_test_deviceOut(device,1.0,5,1,&format,win_formats[f][0], 1090 CALLBACK_EVENT,&capsA,winetest_interactive, 1091 TRUE,TRUE); 1092 } 1093 if (device != WAVE_MAPPER) 1094 { 1095 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1096 CALLBACK_EVENT|WAVE_FORMAT_DIRECT,&capsA, 1097 winetest_interactive,TRUE,FALSE); 1098 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1099 CALLBACK_EVENT|WAVE_MAPPED,&capsA, 1100 winetest_interactive,TRUE,FALSE); 1101 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1102 CALLBACK_FUNCTION|WAVE_FORMAT_DIRECT,&capsA, 1103 winetest_interactive,TRUE,FALSE); 1104 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1105 CALLBACK_FUNCTION|WAVE_MAPPED,&capsA, 1106 winetest_interactive,TRUE,FALSE); 1107 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1108 CALLBACK_THREAD|WAVE_FORMAT_DIRECT,&capsA, 1109 winetest_interactive,TRUE,FALSE); 1110 wave_out_test_deviceOut(device,1.0,1,0,&format,win_formats[f][0], 1111 CALLBACK_THREAD|WAVE_MAPPED,&capsA, 1112 winetest_interactive,TRUE,FALSE); 1113 1114 wave_out_test_deviceOut(device,1.0,10,0,&format,win_formats[f][0], 1115 CALLBACK_EVENT|WAVE_FORMAT_DIRECT,&capsA, 1116 winetest_interactive,TRUE,FALSE); 1117 wave_out_test_deviceOut(device,1.0,5,1,&format,win_formats[f][0], 1118 CALLBACK_EVENT|WAVE_FORMAT_DIRECT,&capsA, 1119 winetest_interactive,TRUE,FALSE); 1120 } 1121 } 1122 1123 /* Try a PCMWAVEFORMAT aligned next to an unaccessible page for bounds 1124 * checking */ 1125 twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, 1126 PAGE_READWRITE); 1127 ok(twoPages!=NULL,"Failed to allocate 2 pages of memory\n"); 1128 if (twoPages) { 1129 res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, 1130 &flOldProtect); 1131 ok(res, "Failed to set memory access on second page\n"); 1132 if (res) { 1133 LPWAVEFORMATEX pwfx = (LPWAVEFORMATEX)(twoPages + dwPageSize - 1134 sizeof(PCMWAVEFORMAT)); 1135 pwfx->wFormatTag=WAVE_FORMAT_PCM; 1136 pwfx->nChannels=1; 1137 pwfx->wBitsPerSample=8; 1138 pwfx->nSamplesPerSec=22050; 1139 pwfx->nBlockAlign=pwfx->nChannels*pwfx->wBitsPerSample/8; 1140 pwfx->nAvgBytesPerSec=pwfx->nSamplesPerSec*pwfx->nBlockAlign; 1141 wave_out_test_deviceOut(device,1.0,1,0,pwfx,WAVE_FORMAT_2M08, 1142 CALLBACK_EVENT,&capsA,winetest_interactive, 1143 TRUE,FALSE); 1144 wave_out_test_deviceOut(device,1.0,10,0,pwfx,WAVE_FORMAT_2M08, 1145 CALLBACK_EVENT,&capsA,winetest_interactive, 1146 TRUE,FALSE); 1147 wave_out_test_deviceOut(device,1.0,5,1,pwfx,WAVE_FORMAT_2M08, 1148 CALLBACK_EVENT,&capsA,winetest_interactive, 1149 TRUE,FALSE); 1150 if (device != WAVE_MAPPER) 1151 { 1152 wave_out_test_deviceOut(device,1.0,1,0,pwfx,WAVE_FORMAT_2M08, 1153 CALLBACK_EVENT|WAVE_FORMAT_DIRECT, 1154 &capsA,winetest_interactive,TRUE,FALSE); 1155 wave_out_test_deviceOut(device,1.0,1,0,pwfx,WAVE_FORMAT_2M08, 1156 CALLBACK_EVENT|WAVE_MAPPED,&capsA, 1157 winetest_interactive,TRUE,FALSE); 1158 wave_out_test_deviceOut(device,1.0,10,0,pwfx,WAVE_FORMAT_2M08, 1159 CALLBACK_EVENT|WAVE_FORMAT_DIRECT, 1160 &capsA,winetest_interactive,TRUE,FALSE); 1161 wave_out_test_deviceOut(device,1.0,10,0,pwfx,WAVE_FORMAT_2M08, 1162 CALLBACK_EVENT|WAVE_MAPPED,&capsA, 1163 winetest_interactive,TRUE,FALSE); 1164 wave_out_test_deviceOut(device,1.0,5,1,pwfx,WAVE_FORMAT_2M08, 1165 CALLBACK_EVENT|WAVE_FORMAT_DIRECT, 1166 &capsA,winetest_interactive,TRUE,FALSE); 1167 wave_out_test_deviceOut(device,1.0,5,1,pwfx,WAVE_FORMAT_2M08, 1168 CALLBACK_EVENT|WAVE_MAPPED,&capsA, 1169 winetest_interactive,TRUE,FALSE); 1170 } 1171 } 1172 VirtualFree(twoPages, 0, MEM_RELEASE); 1173 } 1174 1175 /* try some non PCM formats */ 1176 format.wFormatTag=WAVE_FORMAT_MULAW; 1177 format.nChannels=1; 1178 format.wBitsPerSample=8; 1179 format.nSamplesPerSec=8000; 1180 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; 1181 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; 1182 format.cbSize=0; 1183 rc=waveOutOpen(&wout,device,&format,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1184 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT || 1185 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1186 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1187 if (rc==MMSYSERR_NOERROR) { 1188 waveOutClose(wout); 1189 wave_out_test_deviceOut(device,1.0,1,0,&format,0,CALLBACK_EVENT, 1190 &capsA,winetest_interactive,TRUE,FALSE); 1191 wave_out_test_deviceOut(device,1.0,10,0,&format,0,CALLBACK_EVENT, 1192 &capsA,winetest_interactive,TRUE,FALSE); 1193 wave_out_test_deviceOut(device,1.0,5,1,&format,0,CALLBACK_EVENT, 1194 &capsA,winetest_interactive,TRUE,FALSE); 1195 } else { 1196 MMRESULT query_rc; 1197 1198 trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n", 1199 dev_name(device)); 1200 1201 query_rc = waveOutOpen(NULL, device, &format, 0, 0, CALLBACK_NULL | WAVE_FORMAT_QUERY); 1202 ok(query_rc==MMSYSERR_NOERROR || query_rc==WAVERR_BADFORMAT || query_rc==MMSYSERR_INVALPARAM, 1203 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1204 1205 rc = waveOutOpen(&wout, device, &format, 0, 0, CALLBACK_NULL); 1206 ok(rc == query_rc, 1207 "waveOutOpen(%s): returned different from query: %s\n",dev_name(device),wave_out_error(rc)); 1208 if(rc == MMSYSERR_NOERROR) 1209 waveOutClose(wout); 1210 } 1211 1212 wfa.wfx.wFormatTag=WAVE_FORMAT_IMA_ADPCM; 1213 wfa.wfx.nChannels=1; 1214 wfa.wfx.nSamplesPerSec=11025; 1215 wfa.wfx.nAvgBytesPerSec=5588; 1216 wfa.wfx.nBlockAlign=256; 1217 wfa.wfx.wBitsPerSample=4; /* see imaadp32.c */ 1218 wfa.wfx.cbSize=2; 1219 wfa.wSamplesPerBlock=505; 1220 rc=waveOutOpen(&wout,device,&wfa.wfx,0,0,CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1221 ok(rc==MMSYSERR_NOERROR ||rc==WAVERR_BADFORMAT || 1222 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1223 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1224 if (rc==MMSYSERR_NOERROR) { 1225 waveOutClose(wout); 1226 /* TODO: teach wave_generate_* ADPCM 1227 wave_out_test_deviceOut(device,1.0,1,0,&wfa.wfx,0,CALLBACK_EVENT, 1228 &capsA,winetest_interactive,TRUE,FALSE); 1229 wave_out_test_deviceOut(device,1.0,10,0,&wfa.wfx,0,CALLBACK_EVENT, 1230 &capsA,winetest_interactive,TRUE,FALSE); 1231 wave_out_test_deviceOut(device,1.0,5,1,&wfa.wfx,0,CALLBACK_EVENT, 1232 &capsA,winetest_interactive,TRUE,FALSE); 1233 */ 1234 } else 1235 trace("waveOutOpen(%s): WAVE_FORMAT_IMA_ADPCM not supported\n", 1236 dev_name(device)); 1237 1238 /* test if WAVEFORMATEXTENSIBLE supported */ 1239 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; 1240 wfex.Format.nChannels=2; 1241 wfex.Format.wBitsPerSample=16; 1242 wfex.Format.nSamplesPerSec=22050; 1243 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; 1244 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* 1245 wfex.Format.nBlockAlign; 1246 wfex.Format.cbSize=22; 1247 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; 1248 wfex.dwChannelMask=SPEAKER_ALL; 1249 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; 1250 rc=waveOutOpen(&wout,device,&wfex.Format,0,0, 1251 CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1252 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || 1253 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1254 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1255 if (rc==MMSYSERR_NOERROR) { 1256 waveOutClose(wout); 1257 wave_out_test_deviceOut(device,1.0,1,0,&wfex.Format,WAVE_FORMAT_2M16, 1258 CALLBACK_EVENT,&capsA,winetest_interactive, 1259 TRUE,FALSE); 1260 wave_out_test_deviceOut(device,1.0,10,0,&wfex.Format,WAVE_FORMAT_2M16, 1261 CALLBACK_EVENT,&capsA,winetest_interactive, 1262 TRUE,FALSE); 1263 wave_out_test_deviceOut(device,1.0,5,1,&wfex.Format,WAVE_FORMAT_2M16, 1264 CALLBACK_EVENT,&capsA,winetest_interactive, 1265 TRUE,FALSE); 1266 } else 1267 trace("waveOutOpen(%s): WAVE_FORMAT_EXTENSIBLE not supported\n", 1268 dev_name(device)); 1269 1270 /* test if 4 channels supported */ 1271 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; 1272 wfex.Format.nChannels=4; 1273 wfex.Format.wBitsPerSample=16; 1274 wfex.Format.nSamplesPerSec=22050; 1275 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; 1276 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* 1277 wfex.Format.nBlockAlign; 1278 wfex.Format.cbSize=22; 1279 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; 1280 wfex.dwChannelMask=SPEAKER_ALL; 1281 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; 1282 rc=waveOutOpen(&wout,device,&wfex.Format,0,0, 1283 CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1284 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || 1285 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1286 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1287 if (rc==MMSYSERR_NOERROR) { 1288 waveOutClose(wout); 1289 wave_out_test_deviceOut(device,1.0,1,0,&wfex.Format,0,CALLBACK_EVENT, 1290 &capsA,winetest_interactive,TRUE,FALSE); 1291 wave_out_test_deviceOut(device,1.0,10,0,&wfex.Format,0,CALLBACK_EVENT, 1292 &capsA,winetest_interactive,TRUE,FALSE); 1293 wave_out_test_deviceOut(device,1.0,5,1,&wfex.Format,0,CALLBACK_EVENT, 1294 &capsA,winetest_interactive,TRUE,FALSE); 1295 } else 1296 trace("waveOutOpen(%s): 4 channels not supported\n", 1297 dev_name(device)); 1298 1299 /* test if 6 channels supported */ 1300 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; 1301 wfex.Format.nChannels=6; 1302 wfex.Format.wBitsPerSample=16; 1303 wfex.Format.nSamplesPerSec=22050; 1304 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; 1305 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* 1306 wfex.Format.nBlockAlign; 1307 wfex.Format.cbSize=22; 1308 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; 1309 wfex.dwChannelMask=SPEAKER_ALL; 1310 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; 1311 rc=waveOutOpen(&wout,device,&wfex.Format,0,0, 1312 CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1313 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || 1314 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1315 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1316 if (rc==MMSYSERR_NOERROR) { 1317 waveOutClose(wout); 1318 wave_out_test_deviceOut(device,1.0,1,0,&wfex.Format,WAVE_FORMAT_2M16, 1319 CALLBACK_EVENT,&capsA,winetest_interactive, 1320 TRUE,FALSE); 1321 wave_out_test_deviceOut(device,1.0,10,0,&wfex.Format,WAVE_FORMAT_2M16, 1322 CALLBACK_EVENT,&capsA,winetest_interactive, 1323 TRUE,FALSE); 1324 wave_out_test_deviceOut(device,1.0,5,1,&wfex.Format,WAVE_FORMAT_2M16, 1325 CALLBACK_EVENT,&capsA,winetest_interactive, 1326 TRUE,FALSE); 1327 } else 1328 trace("waveOutOpen(%s): 6 channels not supported\n", 1329 dev_name(device)); 1330 1331 if (0) 1332 { 1333 /* FIXME: ALSA doesn't like this format */ 1334 /* test if 24 bit samples supported */ 1335 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; 1336 wfex.Format.nChannels=2; 1337 wfex.Format.wBitsPerSample=24; 1338 wfex.Format.nSamplesPerSec=22050; 1339 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; 1340 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* 1341 wfex.Format.nBlockAlign; 1342 wfex.Format.cbSize=22; 1343 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; 1344 wfex.dwChannelMask=SPEAKER_ALL; 1345 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; 1346 rc=waveOutOpen(&wout,device,&wfex.Format,0,0, 1347 CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1348 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || 1349 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1350 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1351 if (rc==MMSYSERR_NOERROR) { 1352 waveOutClose(wout); 1353 wave_out_test_deviceOut(device,1.0,1,0,&wfex.Format,WAVE_FORMAT_2M16, 1354 CALLBACK_EVENT,&capsA,winetest_interactive, 1355 TRUE,FALSE); 1356 } else 1357 trace("waveOutOpen(%s): 24 bit samples not supported\n", 1358 dev_name(device)); 1359 } 1360 1361 /* test if 32 bit samples supported */ 1362 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; 1363 wfex.Format.nChannels=2; 1364 wfex.Format.wBitsPerSample=32; 1365 wfex.Format.nSamplesPerSec=22050; 1366 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; 1367 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* 1368 wfex.Format.nBlockAlign; 1369 wfex.Format.cbSize=22; 1370 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; 1371 wfex.dwChannelMask=SPEAKER_ALL; 1372 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_PCM; 1373 rc=waveOutOpen(&wout,device,&wfex.Format,0,0, 1374 CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1375 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || 1376 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1377 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1378 if (rc==MMSYSERR_NOERROR) { 1379 waveOutClose(wout); 1380 wave_out_test_deviceOut(device,1.0,1,0,&wfex.Format,WAVE_FORMAT_2M16, 1381 CALLBACK_EVENT,&capsA,winetest_interactive, 1382 TRUE,FALSE); 1383 wave_out_test_deviceOut(device,1.0,10,0,&wfex.Format,WAVE_FORMAT_2M16, 1384 CALLBACK_EVENT,&capsA,winetest_interactive, 1385 TRUE,FALSE); 1386 wave_out_test_deviceOut(device,1.0,5,1,&wfex.Format,WAVE_FORMAT_2M16, 1387 CALLBACK_EVENT,&capsA,winetest_interactive, 1388 TRUE,FALSE); 1389 } else 1390 trace("waveOutOpen(%s): 32 bit samples not supported\n", 1391 dev_name(device)); 1392 1393 /* test if 32 bit float samples supported */ 1394 wfex.Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE; 1395 wfex.Format.nChannels=2; 1396 wfex.Format.wBitsPerSample=32; 1397 wfex.Format.nSamplesPerSec=22050; 1398 wfex.Format.nBlockAlign=wfex.Format.nChannels*wfex.Format.wBitsPerSample/8; 1399 wfex.Format.nAvgBytesPerSec=wfex.Format.nSamplesPerSec* 1400 wfex.Format.nBlockAlign; 1401 wfex.Format.cbSize=22; 1402 wfex.Samples.wValidBitsPerSample=wfex.Format.wBitsPerSample; 1403 wfex.dwChannelMask=SPEAKER_ALL; 1404 wfex.SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; 1405 rc=waveOutOpen(&wout,device,&wfex.Format,0,0, 1406 CALLBACK_NULL|WAVE_FORMAT_DIRECT); 1407 ok(rc==MMSYSERR_NOERROR || rc==WAVERR_BADFORMAT || 1408 rc==MMSYSERR_INVALFLAG || rc==MMSYSERR_INVALPARAM, 1409 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1410 if (rc==MMSYSERR_NOERROR) { 1411 waveOutClose(wout); 1412 wave_out_test_deviceOut(device,1.0,1,0,&wfex.Format,WAVE_FORMAT_2M16, 1413 CALLBACK_EVENT,&capsA,winetest_interactive, 1414 TRUE,FALSE); 1415 wave_out_test_deviceOut(device,1.0,10,0,&wfex.Format,WAVE_FORMAT_2M16, 1416 CALLBACK_EVENT,&capsA,winetest_interactive, 1417 TRUE,FALSE); 1418 wave_out_test_deviceOut(device,1.0,5,1,&wfex.Format,WAVE_FORMAT_2M16, 1419 CALLBACK_EVENT,&capsA,winetest_interactive, 1420 TRUE,FALSE); 1421 } else 1422 trace("waveOutOpen(%s): 32 bit float samples not supported\n", 1423 dev_name(device)); 1424 1425 /* Test invalid parameters */ 1426 1427 format.wFormatTag = WAVE_FORMAT_PCM; 1428 format.nChannels = 1; 1429 format.nSamplesPerSec = 11025; 1430 format.nBlockAlign = 1; 1431 format.nAvgBytesPerSec = 11025 * 1; 1432 format.wBitsPerSample = 8; 1433 format.cbSize = 0; 1434 1435 format.nAvgBytesPerSec = 0; 1436 rc = waveOutOpen(&wout, device, &format, 0, 0, 0); 1437 ok(rc == MMSYSERR_NOERROR, 1438 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1439 waveOutClose(wout); 1440 format.nAvgBytesPerSec = 11025 * 1; 1441 1442 format.nSamplesPerSec = 0; 1443 rc = waveOutOpen(&wout, device, &format, 0, 0, 0); 1444 ok(rc == MMSYSERR_INVALPARAM || rc == WAVERR_BADFORMAT, /* XP and lower return WAVERR_BADFORMAT */ 1445 "waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc)); 1446 } 1447 1448 static void wave_out_tests(void) 1449 { 1450 WAVEOUTCAPSA capsA; 1451 WAVEOUTCAPSW capsW; 1452 WAVEFORMATEX format; 1453 HWAVEOUT wout; 1454 MMRESULT rc; 1455 DWORD preferred, status; 1456 UINT ndev,d; 1457 1458 ndev=waveOutGetNumDevs(); 1459 trace("found %d WaveOut devices\n",ndev); 1460 1461 rc = waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, 1462 (DWORD_PTR)&preferred, (DWORD_PTR)&status); 1463 ok((ndev == 0 && (rc == MMSYSERR_NODRIVER || rc == MMSYSERR_BADDEVICEID)) || 1464 rc == MMSYSERR_NOTSUPPORTED || 1465 rc == MMSYSERR_NOERROR, "waveOutMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc); 1466 1467 if(rc != MMSYSERR_NOTSUPPORTED) 1468 ok((ndev == 0 && (preferred == -1 || broken(preferred != -1))) || 1469 preferred < ndev, "Got invalid preferred device: 0x%x\n", preferred); 1470 1471 rc = waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, 1472 (DWORD_PTR)-1 , 0); 1473 ok(rc == MMSYSERR_INVALPARAM || rc == MMSYSERR_BADDEVICEID, /* w2008+wvista */ 1474 "waveOutMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc); 1475 1476 rc = waveOutMessage((HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, 1477 0, (DWORD_PTR)&status); 1478 ok(rc == MMSYSERR_INVALPARAM || rc == MMSYSERR_BADDEVICEID, /* w2008+wvista */ 1479 "waveOutMessage(DRVM_MAPPER_PREFERRED_GET) failed: %u\n", rc); 1480 1481 rc=waveOutGetDevCapsA(ndev+1,&capsA,sizeof(capsA)); 1482 ok(rc==MMSYSERR_BADDEVICEID, 1483 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID expected, got %s\n", 1484 dev_name(ndev+1),mmsys_error(rc)); 1485 1486 rc=waveOutGetDevCapsW(ndev+1,&capsW,sizeof(capsW)); 1487 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NOTSUPPORTED, 1488 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED " 1489 "expected, got %s\n",dev_name(ndev+1),mmsys_error(rc)); 1490 1491 rc=waveOutGetDevCapsA(WAVE_MAPPER,&capsA,sizeof(capsA)); 1492 if (ndev>0) 1493 ok(rc==MMSYSERR_NOERROR, 1494 "waveOutGetDevCapsA(%s): MMSYSERR_NOERROR expected, got %s\n", 1495 dev_name(WAVE_MAPPER),mmsys_error(rc)); 1496 else 1497 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER, 1498 "waveOutGetDevCapsA(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER " 1499 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc)); 1500 1501 rc=waveOutGetDevCapsW(WAVE_MAPPER,&capsW,sizeof(capsW)); 1502 if (ndev>0) 1503 ok(rc==MMSYSERR_NOERROR || rc==MMSYSERR_NOTSUPPORTED, 1504 "waveOutGetDevCapsW(%s): MMSYSERR_NOERROR or MMSYSERR_NOTSUPPORTED " 1505 "expected, got %s\n",dev_name(WAVE_MAPPER),mmsys_error(rc)); 1506 else 1507 ok(rc==MMSYSERR_BADDEVICEID || rc==MMSYSERR_NODRIVER || 1508 rc==MMSYSERR_NOTSUPPORTED, 1509 "waveOutGetDevCapsW(%s): MMSYSERR_BADDEVICEID or MMSYSERR_NODRIVER " 1510 " or MMSYSERR_NOTSUPPORTED expected, got %s\n", 1511 dev_name(WAVE_MAPPER),mmsys_error(rc)); 1512 1513 format.wFormatTag=WAVE_FORMAT_PCM; 1514 format.nChannels=2; 1515 format.wBitsPerSample=16; 1516 format.nSamplesPerSec=44100; 1517 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; 1518 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; 1519 format.cbSize=0; 1520 rc=waveOutOpen(&wout,ndev+1,&format,0,0,CALLBACK_NULL); 1521 ok(rc==MMSYSERR_BADDEVICEID, 1522 "waveOutOpen(%s): MMSYSERR_BADDEVICEID expected, got %s\n", 1523 dev_name(ndev+1),mmsys_error(rc)); 1524 1525 if(winetest_interactive) 1526 for (d=0;d<ndev;d++) 1527 wave_out_test_device(d); 1528 1529 if (ndev>0) 1530 wave_out_test_device(WAVE_MAPPER); 1531 } 1532 1533 static void test_sndPlaySound(void) 1534 { 1535 BOOL br; 1536 1537 static const WCHAR not_existW[] = {'C',':','\\','n','o','t','_','e','x','i','s','t','.','w','a','v',0}; 1538 static const WCHAR SystemAsteriskW[] = {'S','y','s','t','e','m','A','s','t','e','r','i','s','k',0}; 1539 1540 br = sndPlaySoundA((LPCSTR)SND_ALIAS_SYSTEMASTERISK, SND_ALIAS_ID|SND_SYNC); 1541 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1542 1543 br = sndPlaySoundW((LPCWSTR)SND_ALIAS_SYSTEMASTERISK, SND_ALIAS_ID|SND_SYNC); 1544 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1545 1546 br = sndPlaySoundA((LPCSTR)sndAlias('X','Y'), SND_ALIAS_ID|SND_SYNC); 1547 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1548 1549 br = sndPlaySoundW((LPCWSTR)sndAlias('X','Y'), SND_ALIAS_ID|SND_SYNC); 1550 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1551 1552 br = sndPlaySoundA("SystemAsterisk", SND_ALIAS|SND_SYNC); 1553 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1554 1555 br = sndPlaySoundW(SystemAsteriskW, SND_ALIAS|SND_SYNC); 1556 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1557 1558 br = sndPlaySoundA("C:\not_exist.wav", SND_FILENAME|SND_SYNC); 1559 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1560 1561 br = sndPlaySoundW(not_existW, SND_FILENAME|SND_SYNC); 1562 ok(br == TRUE || br == FALSE, "sndPlaySound gave strange return: %u\n", br); 1563 } 1564 1565 static void test_fragmentsize(void) 1566 { 1567 MMRESULT rc; 1568 WAVEHDR hdr[2]; 1569 HWAVEOUT wout; 1570 WAVEFORMATEX fmt; 1571 MMTIME mmtime; 1572 DWORD wait; 1573 HANDLE hevent; 1574 1575 if(waveOutGetNumDevs() == 0) 1576 return; 1577 1578 fmt.wFormatTag = WAVE_FORMAT_PCM; 1579 fmt.nChannels = 2; 1580 fmt.nSamplesPerSec = 44100; 1581 fmt.wBitsPerSample = 16; 1582 fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; 1583 fmt.nAvgBytesPerSec = fmt.nBlockAlign * fmt.nSamplesPerSec; 1584 fmt.cbSize = sizeof(WAVEFORMATEX); 1585 1586 hevent = CreateEventW(NULL, FALSE, FALSE, NULL); 1587 g_tid = GetCurrentThreadId(); 1588 1589 rc = waveOutOpen(&wout, WAVE_MAPPER, &fmt, (DWORD_PTR)callback_func, 1590 (DWORD_PTR)hevent, CALLBACK_FUNCTION); 1591 ok(rc == MMSYSERR_NOERROR || rc == WAVERR_BADFORMAT || 1592 rc == MMSYSERR_INVALFLAG || rc == MMSYSERR_INVALPARAM, 1593 "waveOutOpen(%s) failed: %s\n", dev_name(WAVE_MAPPER), wave_out_error(rc)); 1594 if(rc != MMSYSERR_NOERROR){ 1595 CloseHandle(hevent); 1596 return; 1597 } 1598 1599 wait = WaitForSingleObject(hevent, 1000); 1600 ok(wait == WAIT_OBJECT_0, "wave open callback missed\n"); 1601 1602 memset(hdr, 0, sizeof(hdr)); 1603 hdr[0].dwBufferLength = (fmt.nSamplesPerSec * fmt.nBlockAlign / 4) + 1; 1604 hdr[1].dwBufferLength = hdr[0].dwBufferLength - 2; 1605 hdr[1].lpData = hdr[0].lpData = 1606 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, hdr[0].dwBufferLength); 1607 1608 rc = waveOutPrepareHeader(wout, &hdr[0], sizeof(hdr[0])); 1609 ok(rc == MMSYSERR_NOERROR, "waveOutPrepareHeader failed: %s\n", wave_out_error(rc)); 1610 1611 rc = waveOutPrepareHeader(wout, &hdr[1], sizeof(hdr[1])); 1612 ok(rc == MMSYSERR_NOERROR, "waveOutPrepareHeader failed: %s\n", wave_out_error(rc)); 1613 1614 trace("writing %u bytes then %u bytes\n", hdr[0].dwBufferLength, hdr[1].dwBufferLength); 1615 rc = waveOutWrite(wout, &hdr[0], sizeof(hdr[0])); 1616 ok(rc == MMSYSERR_NOERROR, "waveOutWrite failed: %s\n", wave_out_error(rc)); 1617 1618 rc = waveOutWrite(wout, &hdr[1], sizeof(hdr[1])); 1619 ok(rc == MMSYSERR_NOERROR, "waveOutWrite failed: %s\n", wave_out_error(rc)); 1620 1621 wait = WaitForSingleObject(hevent, 1000); 1622 ok(wait == WAIT_OBJECT_0, "header 1 callback missed\n"); 1623 1624 wait = WaitForSingleObject(hevent, 1000); 1625 ok(wait == WAIT_OBJECT_0, "header 2 callback missed\n"); 1626 1627 memset(&mmtime, 0, sizeof(mmtime)); 1628 mmtime.wType = TIME_BYTES; 1629 1630 rc = waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); 1631 ok(rc == MMSYSERR_NOERROR, "waveOutGetPosition failed: %s\n", wave_out_error(rc)); 1632 1633 /* windows behavior is inconsistent */ 1634 ok(mmtime.u.cb == 88200 || 1635 mmtime.u.cb == 88196, "after position: %u\n", mmtime.u.cb); 1636 1637 rc = waveOutClose(wout); 1638 ok(rc == MMSYSERR_NOERROR, "waveOutClose failed: %s\n", wave_out_error(rc)); 1639 1640 HeapFree(GetProcessHeap(), 0, hdr[0].lpData); 1641 CloseHandle(hevent); 1642 } 1643 1644 static void create_wav_file(char *temp_file) 1645 { 1646 WAVEFORMATEX format; 1647 HMMIO h; 1648 MMCKINFO riff_chunk, chunk; 1649 MMRESULT rc; 1650 LONG written; 1651 DWORD length; 1652 char *buffer; 1653 1654 format.wFormatTag=WAVE_FORMAT_PCM; 1655 format.cbSize = 0; 1656 format.nChannels=1; 1657 format.wBitsPerSample=8; 1658 format.nSamplesPerSec=8000; 1659 format.nBlockAlign=format.nChannels*format.wBitsPerSample/8; 1660 format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; 1661 1662 h = mmioOpenA(temp_file, NULL, MMIO_ALLOCBUF | MMIO_WRITE | MMIO_CREATE); 1663 ok(h != NULL, "Can't open temp_file\n"); 1664 1665 riff_chunk.fccType = mmioFOURCC('W','A','V','E'); 1666 riff_chunk.cksize = 0; 1667 rc = mmioCreateChunk(h, &riff_chunk, MMIO_CREATERIFF); 1668 ok(rc == MMSYSERR_NOERROR, "mmioCreateChunk failed, got %u\n", rc); 1669 1670 chunk.ckid = mmioFOURCC('f','m','t',' '); 1671 chunk.cksize = 0; 1672 rc = mmioCreateChunk(h, &chunk, 0); 1673 ok(rc == MMSYSERR_NOERROR, "mmioCreateChunk failed, got %u\n", rc); 1674 written = mmioWrite(h, (char*)&format, sizeof(format)); 1675 ok(written == sizeof(format), "mmioWrite failed, got %d\n", written); 1676 rc = mmioAscend(h, &chunk, 0); 1677 ok(rc == MMSYSERR_NOERROR, "mmioAscend failed, got %d\n", rc); 1678 1679 chunk.ckid = mmioFOURCC('d','a','t','a'); 1680 rc = mmioCreateChunk(h, &chunk, 0); 1681 ok(rc == MMSYSERR_NOERROR, "mmioCreateChunk failed, got %u\n", rc); 1682 buffer = wave_generate_silence(&format, .1, &length); 1683 written = mmioWrite(h, buffer, length); 1684 ok(written == length, "mmioWrite failed, got %d\n", written); 1685 rc = mmioAscend(h, &chunk, 0); 1686 ok(rc == MMSYSERR_NOERROR, "mmioAscend failed, got %d\n", rc); 1687 HeapFree(GetProcessHeap(), 0, buffer); 1688 1689 rc = mmioAscend(h, &riff_chunk, 0); 1690 ok(rc == MMSYSERR_NOERROR, "mmioAscend failed, got %d\n", rc); 1691 1692 rc = mmioClose(h, 0); 1693 ok(rc == MMSYSERR_NOERROR, "mmioClose failed, got %u\n", rc); 1694 } 1695 1696 static void test_PlaySound(void) 1697 { 1698 BOOL br; 1699 char test_file[MAX_PATH], temp[MAX_PATH], *exts; 1700 void *psound_ordinal, *psound_name; 1701 HMODULE dll = GetModuleHandleA("winmm.dll"); 1702 1703 psound_name = GetProcAddress(dll, "PlaySound"); 1704 psound_ordinal = GetProcAddress(dll, (LPCSTR) 2); 1705 ok(psound_name == psound_ordinal, "Expected ordinal 2 to be PlaySound function\n"); 1706 1707 if(waveOutGetNumDevs() == 0) { 1708 skip("No output devices available\n"); 1709 return; 1710 } 1711 1712 GetTempPathA(sizeof(test_file), test_file); 1713 strcat(test_file, "mysound.wav"); 1714 create_wav_file(test_file); 1715 1716 br = PlaySoundA(test_file, NULL, SND_FILENAME | SND_NODEFAULT); 1717 ok(br, "PlaySound failed, got %d\n", br); 1718 1719 /* SND_ALIAS fallbacks to SND_FILENAME */ 1720 br = PlaySoundA(test_file, NULL, SND_ALIAS | SND_NODEFAULT); 1721 ok(br, "PlaySound failed, got %d\n", br); 1722 1723 strcpy(temp, test_file); 1724 exts = strrchr(temp, '.'); 1725 1726 /* no extensions */ 1727 *exts = '\0'; 1728 br = PlaySoundA(temp, NULL, SND_FILENAME | SND_NODEFAULT); 1729 ok(br, "PlaySound failed, got %d\n", br); 1730 1731 /* ends with a dot */ 1732 strcpy(exts, "."); 1733 br = PlaySoundA(temp, NULL, SND_FILENAME | SND_NODEFAULT); 1734 ok(!br || broken(br), "PlaySound succeeded, got %d\n", br); 1735 1736 DeleteFileA(test_file); 1737 } 1738 1739 START_TEST(wave) 1740 { 1741 test_multiple_waveopens(); 1742 wave_out_tests(); 1743 test_sndPlaySound(); 1744 test_fragmentsize(); 1745 test_PlaySound(); 1746 } 1747