test/testautomation_audio.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 25 Jun 2014 17:24:06 -0400
changeset 8956 a99e30f2bf0a
parent 8853 a25dcbe4fb02
child 8989 25582ffe1dec
permissions -rw-r--r--
Patched to compile on Windows.
     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("%s", 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("%s", 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("%s", 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("%s", 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 };