/**
 * Original code: automated SDL audio test written by Edgar Simo "bobbens"
 * New/updated tests: aschiffler at ferzkopp dot net
 */

/* quiet windows compiler warnings */
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <string.h>

#include "SDL.h"
#include "SDL_test.h"

/* ================= Test Case Implementation ================== */

/* Fixture */

void
_audioSetUp(void *arg)
{
    /* Start SDL audio subsystem */
    int ret = SDL_InitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)");
    SDLTest_AssertCheck(ret==0, "Check result from SDL_InitSubSystem(SDL_INIT_AUDIO)");
    if (ret != 0) {
           SDLTest_LogError("%s", SDL_GetError());
        }
}

void
_audioTearDown(void *arg)
{
    /* Remove a possibly created file from SDL disk writer audio driver; ignore errors */
    remove("sdlaudio.raw");

    SDLTest_AssertPass("Cleanup of test files completed");
}


/* Global counter for callback invocation */
int _audio_testCallbackCounter;

/* Global accumulator for total callback length */
int _audio_testCallbackLength;


/* Test callback function */
void SDLCALL _audio_testCallback(void *userdata, Uint8 *stream, int len)
{
   /* track that callback was called */
   _audio_testCallbackCounter++;
   _audio_testCallbackLength += len;
}


/* Test case functions */

/**
 * \brief Stop and restart audio subsystem
 *
 * \sa https://wiki.libsdl.org/SDL_QuitSubSystem
 * \sa https://wiki.libsdl.org/SDL_InitSubSystem
 */
int audio_quitInitAudioSubSystem()
{
    /* Stop SDL audio subsystem */
    SDL_QuitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");

        /* Restart audio again */
        _audioSetUp(NULL);

    return TEST_COMPLETED;
}

/**
 * \brief Start and stop audio directly
 *
 * \sa https://wiki.libsdl.org/SDL_InitAudio
 * \sa https://wiki.libsdl.org/SDL_QuitAudio
 */
int audio_initQuitAudio()
{
        int result;
    int i, iMax;
    const char* audioDriver;

    /* Stop SDL audio subsystem */
    SDL_QuitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");

        /* Loop over all available audio drivers */
        iMax = SDL_GetNumAudioDrivers();
        SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
        SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
        for (i = 0; i < iMax; i++) {
            audioDriver = SDL_GetAudioDriver(i);
            SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
            SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
            SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);

            /* Call Init */
            result = SDL_AudioInit(audioDriver);
            SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
            SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);

            /* Call Quit */
            SDL_AudioQuit();
            SDLTest_AssertPass("Call to SDL_AudioQuit()");
    }

    /* NULL driver specification */
    audioDriver = NULL;

    /* Call Init */
    result = SDL_AudioInit(audioDriver);
    SDLTest_AssertPass("Call to SDL_AudioInit(NULL)");
    SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);

    /* Call Quit */
    SDL_AudioQuit();
    SDLTest_AssertPass("Call to SDL_AudioQuit()");

        /* Restart audio again */
        _audioSetUp(NULL);

    return TEST_COMPLETED;
}

/**
 * \brief Start, open, close and stop audio
 *
 * \sa https://wiki.libsdl.org/SDL_InitAudio
 * \sa https://wiki.libsdl.org/SDL_OpenAudio
 * \sa https://wiki.libsdl.org/SDL_CloseAudio
 * \sa https://wiki.libsdl.org/SDL_QuitAudio
 */
int audio_initOpenCloseQuitAudio()
{
    int result, expectedResult;
    int i, iMax, j, k;
    const char* audioDriver;
    SDL_AudioSpec desired;

    /* Stop SDL audio subsystem */
    SDL_QuitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");

        /* Loop over all available audio drivers */
        iMax = SDL_GetNumAudioDrivers();
        SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
        SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
        for (i = 0; i < iMax; i++) {
            audioDriver = SDL_GetAudioDriver(i);
            SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
            SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
            SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);

            /* Change specs */
            for (j = 0; j < 2; j++) {

                /* Call Init */
                result = SDL_AudioInit(audioDriver);
                SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
                SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);

                /* Set spec */
                SDL_memset(&desired, 0, sizeof(desired));
                switch (j) {
                    case 0:
                    /* Set standard desired spec */
                    desired.freq = 22050;
                    desired.format = AUDIO_S16SYS;
                    desired.channels = 2;
                    desired.samples = 4096;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;

                    case 1:
                    /* Set custom desired spec */
                    desired.freq = 48000;
                    desired.format = AUDIO_F32SYS;
                    desired.channels = 2;
                    desired.samples = 2048;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;
                    break;
            }

            /* Call Open (maybe multiple times) */
            for (k=0; k <= j; k++) {
                result = SDL_OpenAudio(&desired, NULL);
                SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL), call %d", j, k+1);
                expectedResult = (k==0) ? 0 : -1;
                SDLTest_AssertCheck(result == expectedResult, "Verify return value; expected: %d, got: %d", expectedResult, result);
            }

            /* Call Close (maybe multiple times) */
            for (k=0; k <= j; k++) {
                SDL_CloseAudio();
                SDLTest_AssertPass("Call to SDL_CloseAudio(), call %d", k+1);
            }

            /* Call Quit (maybe multiple times) */
            for (k=0; k <= j; k++) {
                SDL_AudioQuit();
                SDLTest_AssertPass("Call to SDL_AudioQuit(), call %d", k+1);
            }

        } /* spec loop */
    } /* driver loop */

        /* Restart audio again */
        _audioSetUp(NULL);

    return TEST_COMPLETED;
}

/**
 * \brief Pause and unpause audio
 *
 * \sa https://wiki.libsdl.org/SDL_PauseAudio
 */
int audio_pauseUnpauseAudio()
{
    int result;
    int i, iMax, j, k, l;
    int totalDelay;
    int pause_on;
    int originalCounter;
    const char* audioDriver;
    SDL_AudioSpec desired;

    /* Stop SDL audio subsystem */
    SDL_QuitSubSystem( SDL_INIT_AUDIO );
        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");

        /* Loop over all available audio drivers */
        iMax = SDL_GetNumAudioDrivers();
        SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
        SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax);
        for (i = 0; i < iMax; i++) {
            audioDriver = SDL_GetAudioDriver(i);
            SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i);
            SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL");
            SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver);

            /* Change specs */
            for (j = 0; j < 2; j++) {

                /* Call Init */
                result = SDL_AudioInit(audioDriver);
                SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
                SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);

                /* Set spec */
                SDL_memset(&desired, 0, sizeof(desired));
                switch (j) {
                    case 0:
                    /* Set standard desired spec */
                    desired.freq = 22050;
                    desired.format = AUDIO_S16SYS;
                    desired.channels = 2;
                    desired.samples = 4096;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;

                    case 1:
                    /* Set custom desired spec */
                    desired.freq = 48000;
                    desired.format = AUDIO_F32SYS;
                    desired.channels = 2;
                    desired.samples = 2048;
                    desired.callback = _audio_testCallback;
                    desired.userdata = NULL;
                    break;
            }

            /* Call Open */
            result = SDL_OpenAudio(&desired, NULL);
            SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL)", j);
            SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0 got: %d", result);

            /* Start and stop audio multiple times */
            for (l=0; l<3; l++) {
                SDLTest_Log("Pause/Unpause iteration: %d", l+1);
            
                /* Reset callback counters */
                _audio_testCallbackCounter = 0;
                _audio_testCallbackLength = 0;

                /* Un-pause audio to start playing (maybe multiple times) */
                pause_on = 0;
                for (k=0; k <= j; k++) {
                    SDL_PauseAudio(pause_on);
                    SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1);
                }
            
                /* Wait for callback */
                totalDelay = 0;
                do {
                    SDL_Delay(10);
                    totalDelay += 10;
                } 
                while (_audio_testCallbackCounter == 0 && totalDelay < 1000);
                SDLTest_AssertCheck(_audio_testCallbackCounter > 0, "Verify callback counter; expected: >0 got: %d", _audio_testCallbackCounter);
                SDLTest_AssertCheck(_audio_testCallbackLength > 0, "Verify callback length; expected: >0 got: %d", _audio_testCallbackLength);

                /* Pause audio to stop playing (maybe multiple times) */
                for (k=0; k <= j; k++) {
                    pause_on = (k==0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999);
                    SDL_PauseAudio(pause_on);
                    SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1);
                }
            
                /* Ensure callback is not called again */
                originalCounter = _audio_testCallbackCounter;
                SDL_Delay(totalDelay + 10);
                SDLTest_AssertCheck(originalCounter == _audio_testCallbackCounter, "Verify callback counter; expected: %d, got: %d", originalCounter, _audio_testCallbackCounter);
            }

            /* Call Close */
            SDL_CloseAudio();
            SDLTest_AssertPass("Call to SDL_CloseAudio()");

            /* Call Quit */
            SDL_AudioQuit();
            SDLTest_AssertPass("Call to SDL_AudioQuit()");

        } /* spec loop */
    } /* driver loop */

    /* Restart audio again */
    _audioSetUp(NULL);

    return TEST_COMPLETED;
}

/**
 * \brief Enumerate and name available audio devices (output and capture).
 *
 * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices
 * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName
 */
int audio_enumerateAndNameAudioDevices()
{
   int t, tt;
   int i, n, nn;
   const char *name, *nameAgain;

   /* Iterate over types: t=0 output device, t=1 input/capture device */
   for (t=0; t<2; t++) {

      /* Get number of devices. */
      n = SDL_GetNumAudioDevices(t);
      SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(%i)", t);
      SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "capture" : "output", n);
      SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n);

      /* Variation of non-zero type */
      if (t==1) {
         tt = t + SDLTest_RandomIntegerInRange(1,10);
         nn = SDL_GetNumAudioDevices(tt);
         SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", tt, n, nn);
         nn = SDL_GetNumAudioDevices(-tt);
         SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", -tt, n, nn);
      }

      /* List devices. */
      if (n>0) {
         for (i=0; i<n; i++) {
            name = SDL_GetAudioDeviceName(i, t);
            SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
            SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, t);
            if (name != NULL) {
              SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, t, name);
              if (t==1) {
                  /* Also try non-zero type */
                  tt = t + SDLTest_RandomIntegerInRange(1,10);
                  nameAgain = SDL_GetAudioDeviceName(i, tt);
                  SDLTest_AssertCheck(nameAgain != NULL, "Verify result from SDL_GetAudioDeviceName(%i, %i) is not NULL", i, tt);
                  if (nameAgain != NULL) {
                    SDLTest_AssertCheck(nameAgain[0] != '\0', "Verify result from SDL_GetAudioDeviceName(%i, %i) is not empty, got: '%s'", i, tt, nameAgain);
                    SDLTest_AssertCheck(SDL_strcmp(name, nameAgain)==0,
                      "Verify SDL_GetAudioDeviceName(%i, %i) and SDL_GetAudioDeviceName(%i %i) return the same string",
                      i, t, i, tt);
                  }
               }
            }
         }
      }
   }

   return TEST_COMPLETED;
}

/**
 * \brief Negative tests around enumeration and naming of audio devices.
 *
 * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices
 * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName
 */
int audio_enumerateAndNameAudioDevicesNegativeTests()
{
   int t;
   int i, j, no, nc;
   const char *name;

   /* Get number of devices. */
   no = SDL_GetNumAudioDevices(0);
   SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
   nc = SDL_GetNumAudioDevices(1);
   SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(1)");

   /* Invalid device index when getting name */
   for (t=0; t<2; t++) {
      /* Negative device index */
      i = SDLTest_RandomIntegerInRange(-10,-1);
      name = SDL_GetAudioDeviceName(i, t);
      SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
      SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result NULL, expected NULL, got: %s", i, t, (name == NULL) ? "NULL" : name);

      /* Device index past range */
      for (j=0; j<3; j++) {
         i = (t) ? nc+j : no+j;
         name = SDL_GetAudioDeviceName(i, t);
         SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
         SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name);
      }

      /* Capture index past capture range but within output range */
      if ((no>0) && (no>nc) && (t==1)) {
         i = no-1;
         name = SDL_GetAudioDeviceName(i, t);
         SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t);
         SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name);
      }
   }

   return TEST_COMPLETED;
}


/**
 * \brief Checks available audio driver names.
 *
 * \sa https://wiki.libsdl.org/SDL_GetNumAudioDrivers
 * \sa https://wiki.libsdl.org/SDL_GetAudioDriver
 */
int audio_printAudioDrivers()
{
   int i, n;
   const char *name;

   /* Get number of drivers */
   n = SDL_GetNumAudioDrivers();
   SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()");
   SDLTest_AssertCheck(n>=0, "Verify number of audio drivers >= 0, got: %i", n);

   /* List drivers. */
   if (n>0)
   {
      for (i=0; i<n; i++) {
         name = SDL_GetAudioDriver(i);
         SDLTest_AssertPass("Call to SDL_GetAudioDriver(%i)", i);
         SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL");
         if (name != NULL) {
            SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name);
         }
      }
   }

   return TEST_COMPLETED;
}


/**
 * \brief Checks current audio driver name with initialized audio.
 *
 * \sa https://wiki.libsdl.org/SDL_GetCurrentAudioDriver
 */
int audio_printCurrentAudioDriver()
{
   /* Check current audio driver */
   const char *name = SDL_GetCurrentAudioDriver();
   SDLTest_AssertPass("Call to SDL_GetCurrentAudioDriver()");
   SDLTest_AssertCheck(name != NULL, "Verify returned name is not NULL");
   if (name != NULL) {
      SDLTest_AssertCheck(name[0] != '\0', "Verify returned name is not empty, got: '%s'", name);
   }

   return TEST_COMPLETED;
}

/* Definition of all formats, channels, and frequencies used to test audio conversions */
const int _numAudioFormats = 18;
SDL_AudioFormat _audioFormats[] = { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S16SYS, AUDIO_S16, AUDIO_U16LSB,
                AUDIO_U16MSB, AUDIO_U16SYS, AUDIO_U16, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32SYS, AUDIO_S32,
                                AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_F32SYS, AUDIO_F32 };
const char *_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", "AUDIO_U16LSB",
                "AUDIO_U16MSB", "AUDIO_U16SYS", "AUDIO_U16", "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32SYS", "AUDIO_S32",
                                "AUDIO_F32LSB", "AUDIO_F32MSB", "AUDIO_F32SYS", "AUDIO_F32" };
const int _numAudioChannels = 4;
Uint8 _audioChannels[] = { 1, 2, 4, 6 };
const int _numAudioFrequencies = 4;
int _audioFrequencies[] = { 11025, 22050, 44100, 48000 };


/**
 * \brief Builds various audio conversion structures
 *
 * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT
 */
int audio_buildAudioCVT()
{
  int result;
  SDL_AudioCVT  cvt;
  SDL_AudioSpec spec1;
  SDL_AudioSpec spec2;
  int i, ii, j, jj, k, kk;

  /* No conversion needed */
  spec1.format = AUDIO_S16LSB;
  spec1.channels = 2;
  spec1.freq = 22050;
  result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
                                   spec1.format, spec1.channels, spec1.freq);
  SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec1)");
  SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0, got: %i", result);

  /* Typical conversion */
  spec1.format = AUDIO_S8;
  spec1.channels = 1;
  spec1.freq = 22050;
  spec2.format = AUDIO_S16LSB;
  spec2.channels = 2;
  spec2.freq = 44100;
  result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
                                   spec2.format, spec2.channels, spec2.freq);
  SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)");
  SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result);

  /* All source conversions with random conversion targets, allow 'null' conversions */
  for (i = 0; i < _numAudioFormats; i++) {
    for (j = 0; j < _numAudioChannels; j++) {
      for (k = 0; k < _numAudioFrequencies; k++) {
        spec1.format = _audioFormats[i];
        spec1.channels = _audioChannels[j];
        spec1.freq = _audioFrequencies[k];
        ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1);
        jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1);
        kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1);
        spec2.format = _audioFormats[ii];
        spec2.channels = _audioChannels[jj];
        spec2.freq = _audioFrequencies[kk];
        result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
                                         spec2.format, spec2.channels, spec2.freq);
        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)",
            i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq);
        SDLTest_AssertCheck(result == 0 || result == 1, "Verify result value; expected: 0 or 1, got: %i", result);
        if (result<0) {
          SDLTest_LogError("%s", SDL_GetError());
        } else {
          SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult);
        }
      }
    }
  }

   return TEST_COMPLETED;
}

/**
 * \brief Checkes calls with invalid input to SDL_BuildAudioCVT
 *
 * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT
 */
int audio_buildAudioCVTNegative()
{
  const char *expectedError = "Parameter 'cvt' is invalid";
  const char *error;
  int result;
  SDL_AudioCVT  cvt;
  SDL_AudioSpec spec1;
  SDL_AudioSpec spec2;
  int i;
  char message[256];

  /* Valid format */
  spec1.format = AUDIO_S8;
  spec1.channels = 1;
  spec1.freq = 22050;
  spec2.format = AUDIO_S16LSB;
  spec2.channels = 2;
  spec2.freq = 44100;

  SDL_ClearError();
  SDLTest_AssertPass("Call to SDL_ClearError()");

  /* NULL input for CVT buffer */
  result = SDL_BuildAudioCVT((SDL_AudioCVT *)NULL, spec1.format, spec1.channels, spec1.freq,
                                                   spec2.format, spec2.channels, spec2.freq);
  SDLTest_AssertPass("Call to SDL_BuildAudioCVT(NULL,...)");
  SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result);
  error = SDL_GetError();
  SDLTest_AssertPass("Call to SDL_GetError()");
  SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
  if (error != NULL) {
      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0,
          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
  }

  /* Invalid conversions */
  for (i = 1; i < 64; i++) {
    /* Valid format to start with */
    spec1.format = AUDIO_S8;
    spec1.channels = 1;
    spec1.freq = 22050;
    spec2.format = AUDIO_S16LSB;
    spec2.channels = 2;
    spec2.freq = 44100;

    SDL_ClearError();
    SDLTest_AssertPass("Call to SDL_ClearError()");

    /* Set various invalid format inputs */
    SDL_strlcpy(message, "Invalid: ", 256);
    if (i & 1) {
        SDL_strlcat(message, " spec1.format", 256);
        spec1.format = 0;
    }
    if (i & 2) {
        SDL_strlcat(message, " spec1.channels", 256);
        spec1.channels = 0;
    }
    if (i & 4) {
        SDL_strlcat(message, " spec1.freq", 256);
        spec1.freq = 0;
    }
    if (i & 8) {
        SDL_strlcat(message, " spec2.format", 256);
        spec2.format = 0;
    }
    if (i & 16) {
        SDL_strlcat(message, " spec2.channels", 256);
        spec2.channels = 0;
    }
    if (i & 32) {
        SDL_strlcat(message, " spec2.freq", 256);
        spec2.freq = 0;
    }
    SDLTest_Log("%s", message);
    result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
                                   spec2.format, spec2.channels, spec2.freq);
    SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)");
    SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result);
    error = SDL_GetError();
    SDLTest_AssertPass("Call to SDL_GetError()");
    SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message was not NULL or empty");
  }

  SDL_ClearError();
  SDLTest_AssertPass("Call to SDL_ClearError()");

  return TEST_COMPLETED;
}

/**
 * \brief Checks current audio status.
 *
 * \sa https://wiki.libsdl.org/SDL_GetAudioStatus
 */
int audio_getAudioStatus()
{
   SDL_AudioStatus result;

   /* Check current audio status */
   result = SDL_GetAudioStatus();
   SDLTest_AssertPass("Call to SDL_GetAudioStatus()");
   SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED,
        "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i",
        SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result);

   return TEST_COMPLETED;
}



/**
 * \brief Opens, checks current audio status, and closes a device.
 *
 * \sa https://wiki.libsdl.org/SDL_GetAudioStatus
 */
int audio_openCloseAndGetAudioStatus()
{
   SDL_AudioStatus result;
   int i;
   int count;
   const char *device;
   SDL_AudioDeviceID id;
   SDL_AudioSpec desired, obtained;

   /* Get number of devices. */
   count = SDL_GetNumAudioDevices(0);
   SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
   if (count > 0) {
     for (i = 0; i < count; i++) {
       /* Get device name */
       device = SDL_GetAudioDeviceName(i, 0);
       SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
       SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
       if (device == NULL) return TEST_ABORTED;

       /* Set standard desired spec */
       desired.freq=22050;
       desired.format=AUDIO_S16SYS;
       desired.channels=2;
       desired.samples=4096;
       desired.callback=_audio_testCallback;
       desired.userdata=NULL;

       /* Open device */
       id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
       SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
       SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id);
       if (id > 1) {

         /* Check device audio status */
         result = SDL_GetAudioDeviceStatus(id);
         SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()");
         SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED,
            "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i",
            SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result);

         /* Close device again */
         SDL_CloseAudioDevice(id);
         SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
       }
     }
   } else {
     SDLTest_Log("No devices to test with");
   }

   return TEST_COMPLETED;
}

/**
 * \brief Locks and unlocks open audio device.
 *
 * \sa https://wiki.libsdl.org/SDL_LockAudioDevice
 * \sa https://wiki.libsdl.org/SDL_UnlockAudioDevice
 */
int audio_lockUnlockOpenAudioDevice()
{
   int i;
   int count;
   const char *device;
   SDL_AudioDeviceID id;
   SDL_AudioSpec desired, obtained;

   /* Get number of devices. */
   count = SDL_GetNumAudioDevices(0);
   SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
   if (count > 0) {
     for (i = 0; i < count; i++) {
       /* Get device name */
       device = SDL_GetAudioDeviceName(i, 0);
       SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
       SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
       if (device == NULL) return TEST_ABORTED;

       /* Set standard desired spec */
       desired.freq=22050;
       desired.format=AUDIO_S16SYS;
       desired.channels=2;
       desired.samples=4096;
       desired.callback=_audio_testCallback;
       desired.userdata=NULL;

       /* Open device */
       id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
       SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
       SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id);
       if (id > 1) {
         /* Lock to protect callback */
         SDL_LockAudioDevice(id);
         SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id);

         /* Simulate callback processing */
         SDL_Delay(10);
         SDLTest_Log("Simulate callback processing - delay");

         /* Unlock again */
         SDL_UnlockAudioDevice(id);
         SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id);

         /* Close device again */
         SDL_CloseAudioDevice(id);
         SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
       }
     }
   } else {
     SDLTest_Log("No devices to test with");
   }

   return TEST_COMPLETED;
}


/**
 * \brief Convert audio using various conversion structures
 *
 * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT
 * \sa https://wiki.libsdl.org/SDL_ConvertAudio
 */
int audio_convertAudio()
{
  int result;
  SDL_AudioCVT  cvt;
  SDL_AudioSpec spec1;
  SDL_AudioSpec spec2;
  int c;
  char message[128];
  int i, ii, j, jj, k, kk, l, ll;

  /* Iterate over bitmask that determines which parameters are modified in the conversion */
  for (c = 1; c < 8; c++) {
    SDL_strlcpy(message, "Changing:", 128);
    if (c & 1) {
      SDL_strlcat(message, " Format", 128);
    }
    if (c & 2) {
      SDL_strlcat(message, " Channels", 128);
    }
    if (c & 4) {
      SDL_strlcat(message, " Frequencies", 128);
    }
    SDLTest_Log("%s", message);
    /* All source conversions with random conversion targets */
    for (i = 0; i < _numAudioFormats; i++) {
      for (j = 0; j < _numAudioChannels; j++) {
        for (k = 0; k < _numAudioFrequencies; k++) {
          spec1.format = _audioFormats[i];
          spec1.channels = _audioChannels[j];
          spec1.freq = _audioFrequencies[k];

          /* Ensure we have a different target format */
          do {
            if (c & 1) {
              ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1);
            } else {
              ii = 1;
            }
            if (c & 2) {
              jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1);
            } else {
              jj= j;
            }
            if (c & 4) {
              kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1);
            } else {
              kk = k;
            }
          } while ((i == ii) && (j == jj) && (k == kk));
          spec2.format = _audioFormats[ii];
          spec2.channels = _audioChannels[jj];
          spec2.freq = _audioFrequencies[kk];

          result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq,
                                           spec2.format, spec2.channels, spec2.freq);
          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)",
            i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq);
          SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result);
          if (result != 1) {
            SDLTest_LogError("%s", SDL_GetError());
          } else {
            SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult);
            if (cvt.len_mult < 1) return TEST_ABORTED;

            /* Create some random data to convert */
            l = 64;
            ll = l * cvt.len_mult;
            SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, ll);
            cvt.len = l;
            cvt.buf = (Uint8 *)SDL_malloc(ll);
            SDLTest_AssertCheck(cvt.buf != NULL, "Check data buffer to convert is not NULL");
            if (cvt.buf == NULL) return TEST_ABORTED;

            /* Convert the data */
            result = SDL_ConvertAudio(&cvt);
            SDLTest_AssertPass("Call to SDL_ConvertAudio()");
            SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0; got: %i", result);
            SDLTest_AssertCheck(cvt.buf != NULL, "Verify conversion buffer is not NULL");
            SDLTest_AssertCheck(cvt.len_ratio > 0.0, "Verify conversion length ratio; expected: >0; got: %f", cvt.len_ratio);

            /* Free converted buffer */
            SDL_free(cvt.buf);
            cvt.buf = NULL;
          }
        }
      }
    }
  }

   return TEST_COMPLETED;
}


/**
 * \brief Opens, checks current connected status, and closes a device.
 *
 * \sa https://wiki.libsdl.org/SDL_AudioDeviceConnected
 */
int audio_openCloseAudioDeviceConnected()
{
   int result = -1;
   int i;
   int count;
   const char *device;
   SDL_AudioDeviceID id;
   SDL_AudioSpec desired, obtained;

   /* Get number of devices. */
   count = SDL_GetNumAudioDevices(0);
   SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)");
   if (count > 0) {
     for (i = 0; i < count; i++) {
       /* Get device name */
       device = SDL_GetAudioDeviceName(i, 0);
       SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i);
       SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL");
       if (device == NULL) return TEST_ABORTED;

       /* Set standard desired spec */
       desired.freq=22050;
       desired.format=AUDIO_S16SYS;
       desired.channels=2;
       desired.samples=4096;
       desired.callback=_audio_testCallback;
       desired.userdata=NULL;

       /* Open device */
       id = SDL_OpenAudioDevice(device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
       SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device);
       SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id);
       if (id > 1) {

/* TODO: enable test code when function is available in SDL2 */

#ifdef AUDIODEVICECONNECTED_DEFINED
         /* Get connected status */
         result = SDL_AudioDeviceConnected(id);
         SDLTest_AssertPass("Call to SDL_AudioDeviceConnected()");
#endif
         SDLTest_AssertCheck(result == 1, "Verify returned value; expected: 1; got: %i", result);

         /* Close device again */
         SDL_CloseAudioDevice(id);
         SDLTest_AssertPass("Call to SDL_CloseAudioDevice()");
       }
     }
   } else {
     SDLTest_Log("No devices to test with");
   }

   return TEST_COMPLETED;
}



/* ================= Test Case References ================== */

/* Audio test cases */
static const SDLTest_TestCaseReference audioTest1 =
        { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevices, "audio_enumerateAndNameAudioDevices", "Enumerate and name available audio devices (output and capture)", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest2 =
        { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevicesNegativeTests, "audio_enumerateAndNameAudioDevicesNegativeTests", "Negative tests around enumeration and naming of audio devices.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest3 =
        { (SDLTest_TestCaseFp)audio_printAudioDrivers, "audio_printAudioDrivers", "Checks available audio driver names.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest4 =
        { (SDLTest_TestCaseFp)audio_printCurrentAudioDriver, "audio_printCurrentAudioDriver", "Checks current audio driver name with initialized audio.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest5 =
        { (SDLTest_TestCaseFp)audio_buildAudioCVT, "audio_buildAudioCVT", "Builds various audio conversion structures.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest6 =
        { (SDLTest_TestCaseFp)audio_buildAudioCVTNegative, "audio_buildAudioCVTNegative", "Checks calls with invalid input to SDL_BuildAudioCVT", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest7 =
        { (SDLTest_TestCaseFp)audio_getAudioStatus, "audio_getAudioStatus", "Checks current audio status.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest8 =
        { (SDLTest_TestCaseFp)audio_openCloseAndGetAudioStatus, "audio_openCloseAndGetAudioStatus", "Opens and closes audio device and get audio status.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest9 =
        { (SDLTest_TestCaseFp)audio_lockUnlockOpenAudioDevice, "audio_lockUnlockOpenAudioDevice", "Locks and unlocks an open audio device.", TEST_ENABLED };

/* TODO: enable test when SDL_ConvertAudio segfaults on cygwin have been fixed.    */
/* For debugging, test case can be run manually using --filter audio_convertAudio  */

static const SDLTest_TestCaseReference audioTest10 =
        { (SDLTest_TestCaseFp)audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_DISABLED };

/* TODO: enable test when SDL_AudioDeviceConnected has been implemented.           */

static const SDLTest_TestCaseReference audioTest11 =
        { (SDLTest_TestCaseFp)audio_openCloseAudioDeviceConnected, "audio_openCloseAudioDeviceConnected", "Opens and closes audio device and get connected status.", TEST_DISABLED };

static const SDLTest_TestCaseReference audioTest12 =
        { (SDLTest_TestCaseFp)audio_quitInitAudioSubSystem, "audio_quitInitAudioSubSystem", "Quit and re-init audio subsystem.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest13 =
        { (SDLTest_TestCaseFp)audio_initQuitAudio, "audio_initQuitAudio", "Init and quit audio drivers directly.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest14 =
        { (SDLTest_TestCaseFp)audio_initOpenCloseQuitAudio, "audio_initOpenCloseQuitAudio", "Cycle through init, open, close and quit with various audio specs.", TEST_ENABLED };

static const SDLTest_TestCaseReference audioTest15 =
        { (SDLTest_TestCaseFp)audio_pauseUnpauseAudio, "audio_pauseUnpauseAudio", "Pause and Unpause audio for various audio specs while testing callback.", TEST_ENABLED };

/* Sequence of Audio test cases */
static const SDLTest_TestCaseReference *audioTests[] =  {
    &audioTest1, &audioTest2, &audioTest3, &audioTest4, &audioTest5, &audioTest6,
    &audioTest7, &audioTest8, &audioTest9, &audioTest10, &audioTest11,
    &audioTest12, &audioTest13, &audioTest14, &audioTest15, NULL
};

/* Audio test suite (global) */
SDLTest_TestSuiteReference audioTestSuite = {
    "Audio",
    _audioSetUp,
    audioTests,
    _audioTearDown
};
