1 /** 2 * Original code: automated SDL audio test written by Edgar Simo "bobbens" 3 * New/updated tests: aschiffler at ferzkopp dot net 4 */ 5 6 #include <stdio.h> 7 #include <string.h> 8 9 #include "SDL.h" 10 #include "SDL_test.h" 11 12 /* ================= Test Case Implementation ================== */ 13 14 /* Fixture */ 15 16 void 17 _audioSetUp(void *arg) 18 { 19 /* Start SDL audio subsystem */ 20 int ret = SDL_InitSubSystem( SDL_INIT_AUDIO ); 21 SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)"); 22 SDLTest_AssertCheck(ret==0, "Check result from SDL_InitSubSystem(SDL_INIT_AUDIO)"); 23 if (ret != 0) { 24 SDLTest_LogError("%s", SDL_GetError()); 25 } 26 } 27 28 29 /* Test callback function */ 30 void _audio_testCallback(void *userdata, Uint8 *stream, int len) 31 { 32 /* TODO: add tracking if callback was called */ 33 } 34 35 36 /* Test case functions */ 37 38 /** 39 * \brief Stop and restart audio subsystem 40 * 41 * \sa http://wiki.libsdl.org/moin.cgi/SDL_QuitSubSystem 42 * \sa http://wiki.libsdl.org/moin.cgi/SDL_InitSubSystem 43 */ 44 int audio_quitInitAudioSubSystem() 45 { 46 /* Stop SDL audio subsystem */ 47 SDL_QuitSubSystem( SDL_INIT_AUDIO ); 48 SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); 49 50 /* Restart audio again */ 51 _audioSetUp(NULL); 52 53 return TEST_COMPLETED; 54 } 55 56 /** 57 * \brief Start and stop audio directly 58 * 59 * \sa http://wiki.libsdl.org/moin.cgi/SDL_InitAudio 60 * \sa http://wiki.libsdl.org/moin.cgi/SDL_QuitAudio 61 */ 62 int audio_initQuitAudio() 63 { 64 int result; 65 int i, iMax; 66 const char* audioDriver; 67 68 /* Stop SDL audio subsystem */ 69 SDL_QuitSubSystem( SDL_INIT_AUDIO ); 70 SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); 71 72 /* Loop over all available audio drivers */ 73 iMax = SDL_GetNumAudioDrivers(); 74 SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers"); 75 SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax); 76 for (i = 0; i < iMax; i++) { 77 audioDriver = SDL_GetAudioDriver(i); 78 SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i); 79 SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL"); 80 SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); 81 82 /* Call Init */ 83 result = SDL_AudioInit(audioDriver); 84 SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver); 85 SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); 86 87 /* Call Quit */ 88 SDL_AudioQuit(); 89 SDLTest_AssertPass("Call to SDL_AudioQuit()"); 90 } 91 92 /* NULL driver specification */ 93 audioDriver = NULL; 94 95 /* Call Init */ 96 result = SDL_AudioInit(audioDriver); 97 SDLTest_AssertPass("Call to SDL_AudioInit(NULL)"); 98 SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); 99 100 /* Call Quit */ 101 SDL_AudioQuit(); 102 SDLTest_AssertPass("Call to SDL_AudioQuit()"); 103 104 /* Restart audio again */ 105 _audioSetUp(NULL); 106 107 return TEST_COMPLETED; 108 } 109 110 /** 111 * \brief Start, open, close and stop audio 112 * 113 * \sa http://wiki.libsdl.org/moin.cgi/SDL_InitAudio 114 * \sa http://wiki.libsdl.org/moin.cgi/SDL_OpenAudio 115 * \sa http://wiki.libsdl.org/moin.cgi/SDL_CloseAudio 116 * \sa http://wiki.libsdl.org/moin.cgi/SDL_QuitAudio 117 */ 118 int audio_initOpenCloseQuitAudio() 119 { 120 int result; 121 int i, iMax, j; 122 const char* audioDriver; 123 SDL_AudioSpec desired; 124 125 /* Stop SDL audio subsystem */ 126 SDL_QuitSubSystem( SDL_INIT_AUDIO ); 127 SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); 128 129 /* Loop over all available audio drivers */ 130 iMax = SDL_GetNumAudioDrivers(); 131 SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers"); 132 SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax); 133 for (i = 0; i < iMax; i++) { 134 audioDriver = SDL_GetAudioDriver(i); 135 SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i); 136 SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL"); 137 SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); 138 139 /* Change specs */ 140 for (j = 0; j < 2; j++) { 141 142 /* Call Init */ 143 result = SDL_AudioInit(audioDriver); 144 SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver); 145 SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); 146 147 /* Set spec */ 148 SDL_memset(&desired, 0, sizeof(desired)); 149 switch (j) { 150 case 0: 151 /* Set standard desired spec */ 152 desired.freq = 22050; 153 desired.format = AUDIO_S16SYS; 154 desired.channels = 2; 155 desired.samples = 4096; 156 desired.callback = _audio_testCallback; 157 desired.userdata = NULL; 158 159 case 1: 160 /* Set custom desired spec */ 161 desired.freq = 48000; 162 desired.format = AUDIO_F32SYS; 163 desired.channels = 2; 164 desired.samples = 2048; 165 desired.callback = _audio_testCallback; 166 desired.userdata = NULL; 167 break; 168 } 169 170 /* Call Open */ 171 result = SDL_OpenAudio(&desired, NULL); 172 SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL)", j); 173 SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0 got: %d", result); 174 175 /* Call Close */ 176 SDL_CloseAudio(); 177 SDLTest_AssertPass("Call to SDL_CloseAudio()"); 178 179 /* Call Quit */ 180 SDL_AudioQuit(); 181 SDLTest_AssertPass("Call to SDL_AudioQuit()"); 182 183 } /* spec loop */ 184 } /* driver loop */ 185 186 /* Restart audio again */ 187 _audioSetUp(NULL); 188 189 return TEST_COMPLETED; 190 } 191 192 /** 193 * \brief Enumerate and name available audio devices (output and capture). 194 * 195 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices 196 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName 197 */ 198 int audio_enumerateAndNameAudioDevices() 199 { 200 int t, tt; 201 int i, n, nn; 202 const char *name, *nameAgain; 203 204 /* Iterate over types: t=0 output device, t=1 input/capture device */ 205 for (t=0; t<2; t++) { 206 207 /* Get number of devices. */ 208 n = SDL_GetNumAudioDevices(t); 209 SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(%i)", t); 210 SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "capture" : "output", n); 211 SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n); 212 213 /* Variation of non-zero type */ 214 if (t==1) { 215 tt = t + SDLTest_RandomIntegerInRange(1,10); 216 nn = SDL_GetNumAudioDevices(tt); 217 SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", tt, n, nn); 218 nn = SDL_GetNumAudioDevices(-tt); 219 SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", -tt, n, nn); 220 } 221 222 /* List devices. */ 223 if (n>0) { 224 for (i=0; i<n; i++) { 225 name = SDL_GetAudioDeviceName(i, t); 226 SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); 227 SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, t); 228 if (name != NULL) { 229 SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, t, name); 230 if (t==1) { 231 /* Also try non-zero type */ 232 tt = t + SDLTest_RandomIntegerInRange(1,10); 233 nameAgain = SDL_GetAudioDeviceName(i, tt); 234 SDLTest_AssertCheck(nameAgain != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, tt); 235 if (nameAgain != NULL) { 236 SDLTest_AssertCheck(nameAgain[0] != '\0', "Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, tt, nameAgain); 237 SDLTest_AssertCheck(SDL_strcmp(name, nameAgain)==0, 238 "Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string", 239 i, t, i, tt); 240 } 241 } 242 } 243 } 244 } 245 } 246 247 return TEST_COMPLETED; 248 } 249 250 /** 251 * \brief Negative tests around enumeration and naming of audio devices. 252 * 253 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDevices 254 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDeviceName 255 */ 256 int audio_enumerateAndNameAudioDevicesNegativeTests() 257 { 258 int t; 259 int i, j, no, nc; 260 const char *name; 261 262 /* Get number of devices. */ 263 no = SDL_GetNumAudioDevices(0); 264 SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); 265 nc = SDL_GetNumAudioDevices(1); 266 SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(1)"); 267 268 /* Invalid device index when getting name */ 269 for (t=0; t<2; t++) { 270 /* Negative device index */ 271 i = SDLTest_RandomIntegerInRange(-10,-1); 272 name = SDL_GetAudioDeviceName(i, t); 273 SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); 274 SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result NULL, expected NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); 275 276 /* Device index past range */ 277 for (j=0; j<3; j++) { 278 i = (t) ? nc+j : no+j; 279 name = SDL_GetAudioDeviceName(i, t); 280 SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); 281 SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); 282 } 283 284 /* Capture index past capture range but within output range */ 285 if ((no>0) && (no>nc) && (t==1)) { 286 i = no-1; 287 name = SDL_GetAudioDeviceName(i, t); 288 SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); 289 SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); 290 } 291 } 292 293 return TEST_COMPLETED; 294 } 295 296 297 /** 298 * \brief Checks available audio driver names. 299 * 300 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetNumAudioDrivers 301 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioDriver 302 */ 303 int audio_printAudioDrivers() 304 { 305 int i, n; 306 const char *name; 307 308 /* Get number of drivers */ 309 n = SDL_GetNumAudioDrivers(); 310 SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()"); 311 SDLTest_AssertCheck(n>=0, "Verify number of audio drivers >= 0, got: %i", n); 312 313 /* List drivers. */ 314 if (n>0) 315 { 316 for (i=0; i<n; i++) { 317 name = SDL_GetAudioDriver(i); 318 SDLTest_AssertPass("Call to SDL_GetAudioDriver(%i)", i); 319 SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL"); 320 if (name != NULL) { 321 SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name); 322 } 323 } 324 } 325 326 return TEST_COMPLETED; 327 } 328 329 330 /** 331 * \brief Checks current audio driver name with initialized audio. 332 * 333 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetCurrentAudioDriver 334 */ 335 int audio_printCurrentAudioDriver() 336 { 337 /* Check current audio driver */ 338 const char *name = SDL_GetCurrentAudioDriver(); 339 SDLTest_AssertPass("Call to SDL_GetCurrentAudioDriver()"); 340 SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL"); 341 if (name != NULL) { 342 SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name); 343 } 344 345 return TEST_COMPLETED; 346 } 347 348 /* Definition of all formats, channels, and frequencies used to test audio conversions */ 349 const int _numAudioFormats = 18; 350 SDL_AudioFormat _audioFormats[] = { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S16SYS, AUDIO_S16, AUDIO_U16LSB, 351 AUDIO_U16MSB, AUDIO_U16SYS, AUDIO_U16, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32SYS, AUDIO_S32, 352 AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_F32SYS, AUDIO_F32 }; 353 char *_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", "AUDIO_U16LSB", 354 "AUDIO_U16MSB", "AUDIO_U16SYS", "AUDIO_U16", "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32SYS", "AUDIO_S32", 355 "AUDIO_F32LSB", "AUDIO_F32MSB", "AUDIO_F32SYS", "AUDIO_F32" }; 356 const int _numAudioChannels = 4; 357 Uint8 _audioChannels[] = { 1, 2, 4, 6 }; 358 const int _numAudioFrequencies = 4; 359 int _audioFrequencies[] = { 11025, 22050, 44100, 48000 }; 360 361 362 /** 363 * \brief Builds various audio conversion structures 364 * 365 * \sa http://wiki.libsdl.org/moin.cgi/SDL_BuildAudioCVT 366 */ 367 int audio_buildAudioCVT() 368 { 369 int result; 370 SDL_AudioCVT cvt; 371 SDL_AudioSpec spec1; 372 SDL_AudioSpec spec2; 373 int i, ii, j, jj, k, kk; 374 375 /* No conversion needed */ 376 spec1.format = AUDIO_S16LSB; 377 spec1.channels = 2; 378 spec1.freq = 22050; 379 result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, 380 spec1.format, spec1.channels, spec1.freq); 381 SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec1)"); 382 SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0, got: %i", result); 383 384 /* Typical conversion */ 385 spec1.format = AUDIO_S8; 386 spec1.channels = 1; 387 spec1.freq = 22050; 388 spec2.format = AUDIO_S16LSB; 389 spec2.channels = 2; 390 spec2.freq = 44100; 391 result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, 392 spec2.format, spec2.channels, spec2.freq); 393 SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)"); 394 SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result); 395 396 /* All source conversions with random conversion targets, allow 'null' conversions */ 397 for (i = 0; i < _numAudioFormats; i++) { 398 for (j = 0; j < _numAudioChannels; j++) { 399 for (k = 0; k < _numAudioFrequencies; k++) { 400 spec1.format = _audioFormats[i]; 401 spec1.channels = _audioChannels[j]; 402 spec1.freq = _audioFrequencies[k]; 403 ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1); 404 jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1); 405 kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1); 406 spec2.format = _audioFormats[ii]; 407 spec2.channels = _audioChannels[jj]; 408 spec2.freq = _audioFrequencies[kk]; 409 result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, 410 spec2.format, spec2.channels, spec2.freq); 411 SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", 412 i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); 413 SDLTest_AssertCheck(result == 0 || result == 1, "Verify result value; expected: 0 or 1, got: %i", result); 414 if (result<0) { 415 SDLTest_LogError(SDL_GetError()); 416 } else { 417 SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult); 418 } 419 } 420 } 421 } 422 423 return TEST_COMPLETED; 424 } 425 426 /** 427 * \brief Checkes calls with invalid input to SDL_BuildAudioCVT 428 * 429 * \sa http://wiki.libsdl.org/moin.cgi/SDL_BuildAudioCVT 430 */ 431 int audio_buildAudioCVTNegative() 432 { 433 const char *expectedError = "Parameter 'cvt' is invalid"; 434 const char *error; 435 int result; 436 SDL_AudioCVT cvt; 437 SDL_AudioSpec spec1; 438 SDL_AudioSpec spec2; 439 int i; 440 char message[256]; 441 442 /* Valid format */ 443 spec1.format = AUDIO_S8; 444 spec1.channels = 1; 445 spec1.freq = 22050; 446 spec2.format = AUDIO_S16LSB; 447 spec2.channels = 2; 448 spec2.freq = 44100; 449 450 SDL_ClearError(); 451 SDLTest_AssertPass("Call to SDL_ClearError()"); 452 453 /* NULL input for CVT buffer */ 454 result = SDL_BuildAudioCVT((SDL_AudioCVT *)NULL, spec1.format, spec1.channels, spec1.freq, 455 spec2.format, spec2.channels, spec2.freq); 456 SDLTest_AssertPass("Call to SDL_BuildAudioCVT(NULL,...)"); 457 SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result); 458 error = SDL_GetError(); 459 SDLTest_AssertPass("Call to SDL_GetError()"); 460 SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); 461 if (error != NULL) { 462 SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 463 "Validate error message, expected: '%s', got: '%s'", expectedError, error); 464 } 465 466 /* Invalid conversions */ 467 for (i = 1; i < 64; i++) { 468 /* Valid format to start with */ 469 spec1.format = AUDIO_S8; 470 spec1.channels = 1; 471 spec1.freq = 22050; 472 spec2.format = AUDIO_S16LSB; 473 spec2.channels = 2; 474 spec2.freq = 44100; 475 476 SDL_ClearError(); 477 SDLTest_AssertPass("Call to SDL_ClearError()"); 478 479 /* Set various invalid format inputs */ 480 SDL_strlcpy(message, "Invalid: ", 256); 481 if (i & 1) { 482 SDL_strlcat(message, " spec1.format", 256); 483 spec1.format = 0; 484 } 485 if (i & 2) { 486 SDL_strlcat(message, " spec1.channels", 256); 487 spec1.channels = 0; 488 } 489 if (i & 4) { 490 SDL_strlcat(message, " spec1.freq", 256); 491 spec1.freq = 0; 492 } 493 if (i & 8) { 494 SDL_strlcat(message, " spec2.format", 256); 495 spec2.format = 0; 496 } 497 if (i & 16) { 498 SDL_strlcat(message, " spec2.channels", 256); 499 spec2.channels = 0; 500 } 501 if (i & 32) { 502 SDL_strlcat(message, " spec2.freq", 256); 503 spec2.freq = 0; 504 } 505 SDLTest_Log(message); 506 result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, 507 spec2.format, spec2.channels, spec2.freq); 508 SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)"); 509 SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result); 510 error = SDL_GetError(); 511 SDLTest_AssertPass("Call to SDL_GetError()"); 512 SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message was not NULL or empty"); 513 } 514 515 SDL_ClearError(); 516 SDLTest_AssertPass("Call to SDL_ClearError()"); 517 518 return TEST_COMPLETED; 519 } 520 521 /** 522 * \brief Checks current audio status. 523 * 524 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioStatus 525 */ 526 int audio_getAudioStatus() 527 { 528 SDL_AudioStatus result; 529 530 /* Check current audio status */ 531 result = SDL_GetAudioStatus(); 532 SDLTest_AssertPass("Call to SDL_GetAudioStatus()"); 533 SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, 534 "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", 535 SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); 536 537 return TEST_COMPLETED; 538 } 539 540 541 542 /** 543 * \brief Opens, checks current audio status, and closes a device. 544 * 545 * \sa http://wiki.libsdl.org/moin.cgi/SDL_GetAudioStatus 546 */ 547 int audio_openCloseAndGetAudioStatus() 548 { 549 SDL_AudioStatus result; 550 int i; 551 int count; 552 char *device; 553 SDL_AudioDeviceID id; 554 SDL_AudioSpec desired, obtained; 555 556 /* Get number of devices. */ 557 count = SDL_GetNumAudioDevices(0); 558 SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); 559 if (count > 0) { 560 for (i = 0; i < count; i++) { 561 /* Get device name */ 562 device = (char *)SDL_GetAudioDeviceName(i, 0); 563 SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); 564 SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); 565 if (device == NULL) return TEST_ABORTED; 566 567 /* Set standard desired spec */ 568 desired.freq=22050; 569 desired.format=AUDIO_S16SYS; 570 desired.channels=2; 571 desired.samples=4096; 572 desired.callback=_audio_testCallback; 573 desired.userdata=NULL; 574 575 /* Open device */ 576 id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); 577 SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); 578 SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); 579 if (id > 1) { 580 581 /* Check device audio status */ 582 result = SDL_GetAudioDeviceStatus(id); 583 SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()"); 584 SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, 585 "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", 586 SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); 587 588 /* Close device again */ 589 SDL_CloseAudioDevice(id); 590 SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); 591 } 592 } 593 } else { 594 SDLTest_Log("No devices to test with"); 595 } 596 597 return TEST_COMPLETED; 598 } 599 600 /** 601 * \brief Locks and unlocks open audio device. 602 * 603 * \sa http://wiki.libsdl.org/moin.cgi/SDL_LockAudioDevice 604 * \sa http://wiki.libsdl.org/moin.cgi/SDL_UnlockAudioDevice 605 */ 606 int audio_lockUnlockOpenAudioDevice() 607 { 608 int i; 609 int count; 610 char *device; 611 SDL_AudioDeviceID id; 612 SDL_AudioSpec desired, obtained; 613 614 /* Get number of devices. */ 615 count = SDL_GetNumAudioDevices(0); 616 SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); 617 if (count > 0) { 618 for (i = 0; i < count; i++) { 619 /* Get device name */ 620 device = (char *)SDL_GetAudioDeviceName(i, 0); 621 SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); 622 SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); 623 if (device == NULL) return TEST_ABORTED; 624 625 /* Set standard desired spec */ 626 desired.freq=22050; 627 desired.format=AUDIO_S16SYS; 628 desired.channels=2; 629 desired.samples=4096; 630 desired.callback=_audio_testCallback; 631 desired.userdata=NULL; 632 633 /* Open device */ 634 id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); 635 SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); 636 SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); 637 if (id > 1) { 638 /* Lock to protect callback */ 639 SDL_LockAudioDevice(id); 640 SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id); 641 642 /* Simulate callback processing */ 643 SDL_Delay(10); 644 SDLTest_Log("Simulate callback processing - delay"); 645 646 /* Unlock again */ 647 SDL_UnlockAudioDevice(id); 648 SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id); 649 650 /* Close device again */ 651 SDL_CloseAudioDevice(id); 652 SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); 653 } 654 } 655 } else { 656 SDLTest_Log("No devices to test with"); 657 } 658 659 return TEST_COMPLETED; 660 } 661 662 663 /** 664 * \brief Convert audio using various conversion structures 665 * 666 * \sa http://wiki.libsdl.org/moin.cgi/SDL_BuildAudioCVT 667 * \sa http://wiki.libsdl.org/moin.cgi/SDL_ConvertAudio 668 */ 669 int audio_convertAudio() 670 { 671 int result; 672 SDL_AudioCVT cvt; 673 SDL_AudioSpec spec1; 674 SDL_AudioSpec spec2; 675 int c; 676 char message[128]; 677 int i, ii, j, jj, k, kk, l, ll; 678 679 /* Iterate over bitmask that determines which parameters are modified in the conversion */ 680 for (c = 1; c < 8; c++) { 681 SDL_strlcpy(message, "Changing:", 128); 682 if (c & 1) { 683 SDL_strlcat(message, " Format", 128); 684 } 685 if (c & 2) { 686 SDL_strlcat(message, " Channels", 128); 687 } 688 if (c & 4) { 689 SDL_strlcat(message, " Frequencies", 128); 690 } 691 SDLTest_Log(message); 692 /* All source conversions with random conversion targets */ 693 for (i = 0; i < _numAudioFormats; i++) { 694 for (j = 0; j < _numAudioChannels; j++) { 695 for (k = 0; k < _numAudioFrequencies; k++) { 696 spec1.format = _audioFormats[i]; 697 spec1.channels = _audioChannels[j]; 698 spec1.freq = _audioFrequencies[k]; 699 700 /* Ensure we have a different target format */ 701 do { 702 if (c & 1) { 703 ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1); 704 } else { 705 ii = 1; 706 } 707 if (c & 2) { 708 jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1); 709 } else { 710 jj= j; 711 } 712 if (c & 4) { 713 kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1); 714 } else { 715 kk = k; 716 } 717 } while ((i == ii) && (j == jj) && (k == kk)); 718 spec2.format = _audioFormats[ii]; 719 spec2.channels = _audioChannels[jj]; 720 spec2.freq = _audioFrequencies[kk]; 721 722 result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, 723 spec2.format, spec2.channels, spec2.freq); 724 SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", 725 i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); 726 SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result); 727 if (result != 1) { 728 SDLTest_LogError(SDL_GetError()); 729 } else { 730 SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult); 731 if (cvt.len_mult < 1) return TEST_ABORTED; 732 733 /* Create some random data to convert */ 734 l = 64; 735 ll = l * cvt.len_mult; 736 SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, ll); 737 cvt.len = l; 738 cvt.buf = (Uint8 *)SDL_malloc(ll); 739 SDLTest_AssertCheck(cvt.buf != NULL, "Check data buffer to convert is not NULL"); 740 if (cvt.buf == NULL) return TEST_ABORTED; 741 742 /* Convert the data */ 743 result = SDL_ConvertAudio(&cvt); 744 SDLTest_AssertPass("Call to SDL_ConvertAudio()"); 745 SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0; got: %i", result); 746 SDLTest_AssertCheck(cvt.buf != NULL, "Verify conversion buffer is not NULL"); 747 SDLTest_AssertCheck(cvt.len_ratio > 0.0, "Verify conversion length ratio; expected: >0; got: %f", cvt.len_ratio); 748 749 /* Free converted buffer */ 750 SDL_free(cvt.buf); 751 cvt.buf = NULL; 752 } 753 } 754 } 755 } 756 } 757 758 return TEST_COMPLETED; 759 } 760 761 762 /** 763 * \brief Opens, checks current connected status, and closes a device. 764 * 765 * \sa http://wiki.libsdl.org/moin.cgi/SDL_AudioDeviceConnected 766 */ 767 int audio_openCloseAudioDeviceConnected() 768 { 769 int result = -1; 770 int i; 771 int count; 772 char *device; 773 SDL_AudioDeviceID id; 774 SDL_AudioSpec desired, obtained; 775 776 /* Get number of devices. */ 777 count = SDL_GetNumAudioDevices(0); 778 SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); 779 if (count > 0) { 780 for (i = 0; i < count; i++) { 781 /* Get device name */ 782 device = (char *)SDL_GetAudioDeviceName(i, 0); 783 SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); 784 SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); 785 if (device == NULL) return TEST_ABORTED; 786 787 /* Set standard desired spec */ 788 desired.freq=22050; 789 desired.format=AUDIO_S16SYS; 790 desired.channels=2; 791 desired.samples=4096; 792 desired.callback=_audio_testCallback; 793 desired.userdata=NULL; 794 795 /* Open device */ 796 id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); 797 SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); 798 SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id); 799 if (id > 1) { 800 801 /* TODO: enable test code when function is available in SDL2 */ 802 803 #ifdef AUDIODEVICECONNECTED_DEFINED 804 /* Get connected status */ 805 result = SDL_AudioDeviceConnected(id); 806 SDLTest_AssertPass("Call to SDL_AudioDeviceConnected()"); 807 #endif 808 SDLTest_AssertCheck(result == 1, "Verify returned value; expected: 1; got: %i", result); 809 810 /* Close device again */ 811 SDL_CloseAudioDevice(id); 812 SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); 813 } 814 } 815 } else { 816 SDLTest_Log("No devices to test with"); 817 } 818 819 return TEST_COMPLETED; 820 } 821 822 823 824 /* ================= Test Case References ================== */ 825 826 /* Audio test cases */ 827 static const SDLTest_TestCaseReference audioTest1 = 828 { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevices, "audio_enumerateAndNameAudioDevices", "Enumerate and name available audio devices (output and capture)", TEST_ENABLED }; 829 830 static const SDLTest_TestCaseReference audioTest2 = 831 { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevicesNegativeTests, "audio_enumerateAndNameAudioDevicesNegativeTests", "Negative tests around enumeration and naming of audio devices.", TEST_ENABLED }; 832 833 static const SDLTest_TestCaseReference audioTest3 = 834 { (SDLTest_TestCaseFp)audio_printAudioDrivers, "audio_printAudioDrivers", "Checks available audio driver names.", TEST_ENABLED }; 835 836 static const SDLTest_TestCaseReference audioTest4 = 837 { (SDLTest_TestCaseFp)audio_printCurrentAudioDriver, "audio_printCurrentAudioDriver", "Checks current audio driver name with initialized audio.", TEST_ENABLED }; 838 839 static const SDLTest_TestCaseReference audioTest5 = 840 { (SDLTest_TestCaseFp)audio_buildAudioCVT, "audio_buildAudioCVT", "Builds various audio conversion structures.", TEST_ENABLED }; 841 842 static const SDLTest_TestCaseReference audioTest6 = 843 { (SDLTest_TestCaseFp)audio_buildAudioCVTNegative, "audio_buildAudioCVTNegative", "Checks calls with invalid input to SDL_BuildAudioCVT", TEST_ENABLED }; 844 845 static const SDLTest_TestCaseReference audioTest7 = 846 { (SDLTest_TestCaseFp)audio_getAudioStatus, "audio_getAudioStatus", "Checks current audio status.", TEST_ENABLED }; 847 848 static const SDLTest_TestCaseReference audioTest8 = 849 { (SDLTest_TestCaseFp)audio_openCloseAndGetAudioStatus, "audio_openCloseAndGetAudioStatus", "Opens and closes audio device and get audio status.", TEST_ENABLED }; 850 851 static const SDLTest_TestCaseReference audioTest9 = 852 { (SDLTest_TestCaseFp)audio_lockUnlockOpenAudioDevice, "audio_lockUnlockOpenAudioDevice", "Locks and unlocks an open audio device.", TEST_ENABLED }; 853 854 /* TODO: enable test when SDL_ConvertAudio segfaults on cygwin have been fixed. */ 855 /* For debugging, test case can be run manually using --filter audio_convertAudio */ 856 857 static const SDLTest_TestCaseReference audioTest10 = 858 { (SDLTest_TestCaseFp)audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_DISABLED }; 859 860 /* TODO: enable test when SDL_AudioDeviceConnected has been implemented. */ 861 862 static const SDLTest_TestCaseReference audioTest11 = 863 { (SDLTest_TestCaseFp)audio_openCloseAudioDeviceConnected, "audio_openCloseAudioDeviceConnected", "Opens and closes audio device and get connected status.", TEST_DISABLED }; 864 865 static const SDLTest_TestCaseReference audioTest12 = 866 { (SDLTest_TestCaseFp)audio_quitInitAudioSubSystem, "audio_quitInitAudioSubSystem", "Quit and re-init audio subsystem.", TEST_ENABLED }; 867 868 /* TODO: enable when bugs 1343 and 1396 are fixed. */ 869 /* For debugging, test case can be run manually using --filter audio_initQuitAudio */ 870 871 static const SDLTest_TestCaseReference audioTest13 = 872 { (SDLTest_TestCaseFp)audio_initQuitAudio, "audio_initQuitAudio", "Init and quit audio drivers directly.", TEST_DISABLED }; 873 874 /* TODO: enable when bugs 1343 and 1396 are fixed. */ 875 /* For debugging, test case can be run manually using --filter audio_initOpenCloseQuitAudio */ 876 877 static const SDLTest_TestCaseReference audioTest14 = 878 { (SDLTest_TestCaseFp)audio_initOpenCloseQuitAudio, "audio_initOpenCloseQuitAudio", "Cycle through init, open, close and quit with various audio specs.", TEST_DISABLED }; 879 880 /* Sequence of Audio test cases */ 881 static const SDLTest_TestCaseReference *audioTests[] = { 882 &audioTest1, &audioTest2, &audioTest3, &audioTest4, &audioTest5, &audioTest6, 883 &audioTest7, &audioTest8, &audioTest9, &audioTest10, &audioTest11, 884 &audioTest12, &audioTest13, &audioTest14, NULL 885 }; 886 887 /* Audio test suite (global) */ 888 SDLTest_TestSuiteReference audioTestSuite = { 889 "Audio", 890 _audioSetUp, 891 audioTests, 892 NULL 893 }; 894