cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

testautomation_audio.c (38568B)


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