/*
  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely.
*/

/* Program to test hotplugging of audio devices */

#include "SDL_config.h"

#include <stdio.h>
#include <stdlib.h>

#if HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif

#include "SDL.h"
#include "testutils.h"

static SDL_AudioSpec spec;
static Uint8 *sound = NULL;     /* Pointer to wave data */
static Uint32 soundlen = 0;     /* Length of wave data */

static int posindex = 0;
static Uint32 positions[64];

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void
quit(int rc)
{
    SDL_Quit();
    exit(rc);
}

void SDLCALL
fillerup(void *_pos, Uint8 * stream, int len)
{
    Uint32 pos = *((Uint32 *) _pos);
    Uint8 *waveptr;
    int waveleft;

    /* Set up the pointers */
    waveptr = sound + pos;
    waveleft = soundlen - pos;

    /* Go! */
    while (waveleft <= len) {
        SDL_memcpy(stream, waveptr, waveleft);
        stream += waveleft;
        len -= waveleft;
        waveptr = sound;
        waveleft = soundlen;
        pos = 0;
    }
    SDL_memcpy(stream, waveptr, len);
    pos += len;
    *((Uint32 *) _pos) = pos;
}

static int done = 0;
void
poked(int sig)
{
    done = 1;
}

static const char*
devtypestr(int iscapture)
{
    return iscapture ? "capture" : "output";
}

static void
iteration()
{
    SDL_Event e;
    SDL_AudioDeviceID dev;
    while (SDL_PollEvent(&e)) {
        if (e.type == SDL_QUIT) {
            done = 1;
        } else if (e.type == SDL_KEYUP) {
            if (e.key.keysym.sym == SDLK_ESCAPE)
                done = 1;
        } else if (e.type == SDL_AUDIODEVICEADDED) {
            int index = e.adevice.which;
            int iscapture = e.adevice.iscapture;
            const char *name = SDL_GetAudioDeviceName(index, iscapture);
            if (name != NULL)
                SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int) index, name);
            else {
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device at index %u, but failed to get the name: %s\n",
                    devtypestr(iscapture), (unsigned int) index, SDL_GetError());
                continue;
            }
            if (!iscapture) {
                positions[posindex] = 0;
                spec.userdata = &positions[posindex++];
                spec.callback = fillerup;
                dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);
                if (!dev) {
                    SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
                } else {
                    SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev);
                    SDL_PauseAudioDevice(dev, 0);
                }
            }
        } else if (e.type == SDL_AUDIODEVICEREMOVED) {
            dev = (SDL_AudioDeviceID) e.adevice.which;
            SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int) dev);
            SDL_CloseAudioDevice(dev);
        }
    }
}

#ifdef __EMSCRIPTEN__
void
loop()
{
    if(done)
        emscripten_cancel_main_loop();
    else
        iteration();
}
#endif

int
main(int argc, char *argv[])
{
    int i;
    char *filename = NULL;

    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Load the SDL library */
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        return (1);
    }

    /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */
    SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));

    filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");

    if (filename == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
        quit(1);
    }

    /* Load the wave file into memory */
    if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
        quit(1);
    }

#if HAVE_SIGNAL_H
    /* Set the signals */
#ifdef SIGHUP
    signal(SIGHUP, poked);
#endif
    signal(SIGINT, poked);
#ifdef SIGQUIT
    signal(SIGQUIT, poked);
#endif
    signal(SIGTERM, poked);
#endif /* HAVE_SIGNAL_H */

    /* Show the list of available drivers */
    SDL_Log("Available audio drivers:");
    for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
        SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
    }

    SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n");
    SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(loop, 0, 1);
#else
    while (!done) {
        SDL_Delay(100);
        iteration();
    }
#endif

    /* Clean up on signal */
    /* Quit audio first, then free WAV. This prevents access violations in the audio threads. */
    SDL_QuitSubSystem(SDL_INIT_AUDIO);
    SDL_FreeWAV(sound);
    SDL_free(filename);
    SDL_Quit();
    return (0);
}

/* vi: set ts=4 sw=4 expandtab: */
