/*
 * QEMU SDL audio output driver
 * 
 * Copyright (c) 2004 Vassili Karpov (malc)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <SDL.h>
#include <SDL_thread.h>
#include "vl.h"

#include "audio/audio_int.h"

typedef struct SDLVoice {
    HWVoice hw;
} SDLVoice;

#define dolog(...) AUD_log ("sdl", __VA_ARGS__)
#ifdef DEBUG
#define ldebug(...) dolog (__VA_ARGS__)
#else
#define ldebug(...)
#endif

#define QC_SDL_SAMPLES "QEMU_SDL_SAMPLES"

#define errstr() SDL_GetError ()

static struct {
    int nb_samples;
} conf = {
    1024
};

struct SDLAudioState {
    int exit;
    SDL_mutex *mutex;
    SDL_sem *sem;
    int initialized;
} glob_sdl;
typedef struct SDLAudioState SDLAudioState;

static void sdl_hw_run (HWVoice *hw)
{
    (void) hw;
}

static int sdl_lock (SDLAudioState *s)
{
    if (SDL_LockMutex (s->mutex)) {
        dolog ("SDL_LockMutex failed\nReason: %s\n", errstr ());
        return -1;
    }
    return 0;
}

static int sdl_unlock (SDLAudioState *s)
{
    if (SDL_UnlockMutex (s->mutex)) {
        dolog ("SDL_UnlockMutex failed\nReason: %s\n", errstr ());
        return -1;
    }
    return 0;
}

static int sdl_post (SDLAudioState *s)
{
    if (SDL_SemPost (s->sem)) {
        dolog ("SDL_SemPost failed\nReason: %s\n", errstr ());
        return -1;
    }
    return 0;
}

static int sdl_wait (SDLAudioState *s)
{
    if (SDL_SemWait (s->sem)) {
        dolog ("SDL_SemWait failed\nReason: %s\n", errstr ());
        return -1;
    }
    return 0;
}

static int sdl_unlock_and_post (SDLAudioState *s)
{
    if (sdl_unlock (s))
        return -1;

    return sdl_post (s);
}

static int sdl_hw_write (SWVoice *sw, void *buf, int len)
{
    int ret;
    SDLAudioState *s = &glob_sdl;
    sdl_lock (s);
    ret = pcm_hw_write (sw, buf, len);
    sdl_unlock_and_post (s);
    return ret;
}

static int AUD_to_sdlfmt (audfmt_e fmt, int *shift)
{
    *shift = 0;
    switch (fmt) {
    case AUD_FMT_S8: return AUDIO_S8;
    case AUD_FMT_U8: return AUDIO_U8;
    case AUD_FMT_S16: *shift = 1; return AUDIO_S16LSB;
    case AUD_FMT_U16: *shift = 1; return AUDIO_U16LSB;
    default:
        dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
        exit (EXIT_FAILURE);
    }
}

static int sdl_to_audfmt (int fmt)
{
    switch (fmt) {
    case AUDIO_S8: return AUD_FMT_S8;
    case AUDIO_U8: return AUD_FMT_U8;
    case AUDIO_S16LSB: return AUD_FMT_S16;
    case AUDIO_U16LSB: return AUD_FMT_U16;
    default:
        dolog ("Internal logic error: Unrecognized SDL audio format %d\n"
               "Aborting\n", fmt);
        exit (EXIT_FAILURE);
    }
}

static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
{
    int status;

    status = SDL_OpenAudio (req, obt);
    if (status) {
        dolog ("SDL_OpenAudio failed\nReason: %s\n", errstr ());
    }
    return status;
}

static void sdl_close (SDLAudioState *s)
{
    if (s->initialized) {
        sdl_lock (s);
        s->exit = 1;
        sdl_unlock_and_post (s);
        SDL_PauseAudio (1);
        SDL_CloseAudio ();
        s->initialized = 0;
    }
}

static void sdl_callback (void *opaque, Uint8 *buf, int len)
{
    SDLVoice *sdl = opaque;
    SDLAudioState *s = &glob_sdl;
    HWVoice *hw = &sdl->hw;
    int samples = len >> hw->shift;

    if (s->exit) {
        return;
    }

    while (samples) {
        int to_mix, live, decr;

        /* dolog ("in callback samples=%d\n", samples); */
        sdl_wait (s);
        if (s->exit) {
            return;
        }

        sdl_lock (s);
        live = pcm_hw_get_live (hw);
        if (live <= 0)
            goto again;

        /* dolog ("in callback live=%d\n", live); */
        to_mix = audio_MIN (samples, live);
        decr = to_mix;
        while (to_mix) {
            int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
            st_sample_t *src = hw->mix_buf + hw->rpos;

            /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
            hw->clip (buf, src, chunk);
            memset (src, 0, chunk * sizeof (st_sample_t));
            hw->rpos = (hw->rpos + chunk) % hw->samples;
            to_mix -= chunk;
            buf += chunk << hw->shift;
        }
        samples -= decr;
        pcm_hw_dec_live (hw, decr);

    again:
        sdl_unlock (s);
    }
    /* dolog ("done len=%d\n", len); */
}

static void sdl_hw_fini (HWVoice *hw)
{
    ldebug ("sdl_hw_fini %d fixed=%d\n",
             glob_sdl.initialized, audio_state.fixed_format);
    sdl_close (&glob_sdl);
}

static int sdl_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
{
    SDLVoice *sdl = (SDLVoice *) hw;
    SDLAudioState *s = &glob_sdl;
    SDL_AudioSpec req, obt;
    int shift;

    ldebug ("sdl_hw_init %d freq=%d fixed=%d\n",
            s->initialized, freq, audio_state.fixed_format);

    if (nchannels != 2) {
        dolog ("Bogus channel count %d\n", nchannels);
        return -1;
    }

    req.freq = freq;
    req.format = AUD_to_sdlfmt (fmt, &shift);
    req.channels = nchannels;
    req.samples = conf.nb_samples;
    shift <<= nchannels == 2;

    req.callback = sdl_callback;
    req.userdata = sdl;

    if (sdl_open (&req, &obt))
        return -1;

    hw->freq = obt.freq;
    hw->fmt = sdl_to_audfmt (obt.format);
    hw->nchannels = obt.channels;
    hw->bufsize = obt.samples << shift;

    s->initialized = 1;
    s->exit = 0;
    SDL_PauseAudio (0);
    return 0;
}

static int sdl_hw_ctl (HWVoice *hw, int cmd, ...)
{
    (void) hw;

    switch (cmd) {
    case VOICE_ENABLE:
        SDL_PauseAudio (0);
        break;

    case VOICE_DISABLE:
        SDL_PauseAudio (1);
        break;
    }
    return 0;
}

static void *sdl_audio_init (void)
{
    SDLAudioState *s = &glob_sdl;
    conf.nb_samples = audio_get_conf_int (QC_SDL_SAMPLES, conf.nb_samples);

    if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
        dolog ("SDL failed to initialize audio subsystem\nReason: %s\n",
               errstr ());
        return NULL;
    }

    s->mutex = SDL_CreateMutex ();
    if (!s->mutex) {
        dolog ("Failed to create SDL mutex\nReason: %s\n", errstr ());
        SDL_QuitSubSystem (SDL_INIT_AUDIO);
        return NULL;
    }

    s->sem = SDL_CreateSemaphore (0);
    if (!s->sem) {
        dolog ("Failed to create SDL semaphore\nReason: %s\n", errstr ());
        SDL_DestroyMutex (s->mutex);
        SDL_QuitSubSystem (SDL_INIT_AUDIO);
        return NULL;
    }

    return s;
}

static void sdl_audio_fini (void *opaque)
{
    SDLAudioState *s = opaque;
    sdl_close (s);
    SDL_DestroySemaphore (s->sem);
    SDL_DestroyMutex (s->mutex);
    SDL_QuitSubSystem (SDL_INIT_AUDIO);
}

struct pcm_ops sdl_pcm_ops = {
    sdl_hw_init,
    sdl_hw_fini,
    sdl_hw_run,
    sdl_hw_write,
    sdl_hw_ctl
};

struct audio_output_driver sdl_output_driver = {
    "sdl",
    sdl_audio_init,
    sdl_audio_fini,
    &sdl_pcm_ops,
    1,
    1,
    sizeof (SDLVoice)
};
