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