/*
 * QEMU "simple" Windows audio driver
 *
 * Copyright (c) 2007 The Android Open Source Project
 *
 * 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.
 */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>

#define AUDIO_CAP "winaudio"
#include "audio_int.h"

/* define DEBUG to 1 to dump audio debugging info at runtime to stderr */
#define  DEBUG  0

#if 1
#  define  D_ACTIVE    1
#else
#  define  D_ACTIVE  DEBUG
#endif

#if DEBUG
#  define  D(...)   do{ if (D_ACTIVE) printf(__VA_ARGS__); } while(0)
#else
#  define  D(...)   ((void)0)
#endif

static struct {
    int nb_samples;
} conf = {
    1024
};

#if DEBUG
int64_t  start_time;
int64_t  last_time;
#endif

#define  NUM_OUT_BUFFERS  8  /* must be at least 2 */

/** COMMON UTILITIES
 **/

#if DEBUG
static void
dump_mmerror( const char*  func, MMRESULT  error )
{
    const char*  reason = NULL;

    fprintf(stderr, "%s returned error: ", func);
    switch (error) {
            case MMSYSERR_ALLOCATED:   reason="specified resource is already allocated"; break;
            case MMSYSERR_BADDEVICEID: reason="bad device id"; break;
            case MMSYSERR_NODRIVER:    reason="no driver is present"; break;
            case MMSYSERR_NOMEM:       reason="unable to allocate or lock memory"; break;
            case WAVERR_BADFORMAT:     reason="unsupported waveform-audio format"; break;
            case WAVERR_SYNC:          reason="device is synchronous"; break;
            default:
                    fprintf(stderr, "unknown(%d)\n", error);
    }
    if (reason)
            fprintf(stderr, "%s\n", reason);
}
#else
#  define  dump_mmerror(func,error)  ((void)0)
#endif


/** AUDIO OUT
 **/

typedef struct WinAudioOut {
    HWVoiceOut        hw;
    HWAVEOUT          waveout;
    int               silence;
    CRITICAL_SECTION  lock;
    unsigned char*    buffer_bytes;
    WAVEHDR           buffers[ NUM_OUT_BUFFERS ];
    int               write_index;   /* starting first writable buffer      */
    int               write_count;   /* available writable buffers count    */
    int               write_pos;     /* position in current writable buffer */
    int               write_size;    /* size in bytes of each buffer        */
} WinAudioOut;

/* The Win32 callback that is called when a buffer has finished playing */
static void CALLBACK
winaudio_out_buffer_done (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
			              DWORD dwParam1, DWORD dwParam2)
{
    WinAudioOut*  s = (WinAudioOut*) dwInstance;

    /* Only service "buffer done playing" messages */
    if ( uMsg != WOM_DONE )
            return;

    /* Signal that we are done playing a buffer */
    EnterCriticalSection( &s->lock );
    if (s->write_count < NUM_OUT_BUFFERS)
        s->write_count += 1;
    LeaveCriticalSection( &s->lock );
}

static int
winaudio_out_write (SWVoiceOut *sw, void *buf, int len)
{
    return audio_pcm_sw_write (sw, buf, len);
}

static void
winaudio_out_fini (HWVoiceOut *hw)
{
    WinAudioOut*  s = (WinAudioOut*) hw;
    int           i;

    if (s->waveout) {
        waveOutReset(s->waveout);
        s->waveout = 0;
    }

    for ( i=0; i<NUM_OUT_BUFFERS; ++i ) {
        if ( s->buffers[i].dwUser != 0xFFFF ) {
            waveOutUnprepareHeader(
                s->waveout, &s->buffers[i], sizeof(s->buffers[i]) );
                s->buffers[i].dwUser = 0xFFFF;
        }
    }

    if (s->buffer_bytes != NULL) {
        qemu_free(s->buffer_bytes);
        s->buffer_bytes = NULL;
    }

    if (s->waveout) {
        waveOutClose(s->waveout);
        s->waveout = NULL;
    }
}


static int
winaudio_out_init (HWVoiceOut *hw, struct audsettings *as)
{
    WinAudioOut*   s = (WinAudioOut*) hw;
    MMRESULT       result;
    WAVEFORMATEX   format;
    int            shift, i, samples_size;

    s->waveout = NULL;
    InitializeCriticalSection( &s->lock );
    for (i = 0; i < NUM_OUT_BUFFERS; i++) {
            s->buffers[i].dwUser = 0xFFFF;
    }
    s->buffer_bytes = NULL;

    /* compute desired wave output format */
    format.wFormatTag      = WAVE_FORMAT_PCM;
    format.nChannels       = as->nchannels;
    format.nSamplesPerSec  = as->freq;
    format.nAvgBytesPerSec = as->freq*as->nchannels;

    s->silence = 0;

    switch (as->fmt) {
        case AUD_FMT_S8:   shift = 0; break;
        case AUD_FMT_U8:   shift = 0; s->silence = 0x80; break;
        case AUD_FMT_S16:  shift = 1; break;
        case AUD_FMT_U16:  shift = 1; s->silence = 0x8000; break;
        default:
            fprintf(stderr, "qemu: winaudio: Bad output audio format: %d\n",
                    as->fmt);
                return -1;
    }

    format.nAvgBytesPerSec = (format.nSamplesPerSec & format.nChannels) << shift;
    format.nBlockAlign     = format.nChannels << shift;
    format.wBitsPerSample  = 8 << shift;
    format.cbSize          = 0;

    /* open the wave out device */
    result = waveOutOpen( &s->waveout, WAVE_MAPPER, &format,
                                  (DWORD_PTR)winaudio_out_buffer_done, (DWORD_PTR) hw,
                                              CALLBACK_FUNCTION);
    if ( result != MMSYSERR_NOERROR ) {
        dump_mmerror( "qemu: winaudio: waveOutOpen()", result);
            return -1;
    }

    samples_size    = format.nBlockAlign * conf.nb_samples;
    s->buffer_bytes = qemu_malloc( NUM_OUT_BUFFERS * samples_size );
    if (s->buffer_bytes == NULL) {
            waveOutClose( s->waveout );
            s->waveout = NULL;
            fprintf(stderr, "not enough memory for Windows audio buffers\n");
            return -1;
    }

    for (i = 0; i < NUM_OUT_BUFFERS; i++) {
        memset( &s->buffers[i], 0, sizeof(s->buffers[i]) );
        s->buffers[i].lpData         = (LPSTR)(s->buffer_bytes + i*samples_size);
        s->buffers[i].dwBufferLength = samples_size;
        s->buffers[i].dwFlags        = WHDR_DONE;

        result = waveOutPrepareHeader( s->waveout, &s->buffers[i],
                               sizeof(s->buffers[i]) );
        if ( result != MMSYSERR_NOERROR ) {
            dump_mmerror("waveOutPrepareHeader()", result);
            return -1;
        }
    }

#if DEBUG
    /* Check the sound device we retrieved */
    {
        WAVEOUTCAPS caps;

        result = waveOutGetDevCaps((UINT) s->waveout, &caps, sizeof(caps));
        if ( result != MMSYSERR_NOERROR ) {
            dump_mmerror("waveOutGetDevCaps()", result);
        } else
            printf("Audio out device: %s\n", caps.szPname);
    }
#endif

    audio_pcm_init_info (&hw->info, as);
    hw->samples = conf.nb_samples*2;

    s->write_index = 0;
    s->write_count = NUM_OUT_BUFFERS;
    s->write_pos   = 0;
    s->write_size  = samples_size;
    return 0;
}


static int
winaudio_out_run (HWVoiceOut *hw, int live)
{
    WinAudioOut*  s      = (WinAudioOut*) hw;
    int           played = 0;
    int           has_buffer;

    if (!live) {
        return 0;
    }

    EnterCriticalSection( &s->lock );
    has_buffer = (s->write_count > 0);
    LeaveCriticalSection( &s->lock );

    if (has_buffer) {
        while (live > 0) {
            WAVEHDR*      wav_buffer  = s->buffers + s->write_index;
            int           wav_bytes   = (s->write_size - s->write_pos);
            int           wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
            int           hw_samples  = audio_MIN(hw->samples - hw->rpos, live);
            struct st_sample*  src         = hw->mix_buf + hw->rpos;
            uint8_t*      dst         = (uint8_t*)wav_buffer->lpData + s->write_pos;

            if (wav_samples > hw_samples) {
                    wav_samples = hw_samples;
            }

            wav_bytes = wav_samples << hw->info.shift;

            //D("run_out: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d rpos:%d hwsamples:%d\n", s->write_index,
            //   s->write_pos, s->write_size, wav_samples, wav_bytes, live, hw->rpos, hw->samples);
            hw->clip (dst, src, wav_samples);
            hw->rpos += wav_samples;
            if (hw->rpos >= hw->samples)
                    hw->rpos -= hw->samples;

            live         -= wav_samples;
            played       += wav_samples;
            s->write_pos += wav_bytes;
            if (s->write_pos == s->write_size) {
#if xxDEBUG
                int64_t  now  = qemu_get_clock(vm_clock) - start_time;
                int64_t  diff = now - last_time;

                D("run_out: (%7.3f:%7d):waveOutWrite buffer:%d\n",
                   now/1e9, (now-last_time)/1e9, s->write_index);
                last_time = now;
#endif
                waveOutWrite( s->waveout, wav_buffer, sizeof(*wav_buffer) );
                s->write_pos    = 0;
                s->write_index += 1;
                if (s->write_index == NUM_OUT_BUFFERS)
                    s->write_index = 0;

                EnterCriticalSection( &s->lock );
                if (--s->write_count == 0) {
                        live = 0;
                }
                LeaveCriticalSection( &s->lock );
            }
        }

    }
    return played;
}

static int
winaudio_out_ctl (HWVoiceOut *hw, int cmd, ...)
{
    WinAudioOut*  s = (WinAudioOut*) hw;

    switch (cmd) {
    case VOICE_ENABLE:
        waveOutRestart( s->waveout );
        break;

    case VOICE_DISABLE:
        waveOutPause( s->waveout );
        break;
    }
    return 0;
}

/** AUDIO IN
 **/

#define  NUM_IN_BUFFERS  2

typedef struct WinAudioIn {
    HWVoiceIn         hw;
    HWAVEIN           wavein;
    CRITICAL_SECTION  lock;
    unsigned char*    buffer_bytes;
    WAVEHDR           buffers[ NUM_IN_BUFFERS ];
    int               read_index;
    int               read_count;
    int               read_pos;
    int               read_size;
} WinAudioIn;

/* The Win32 callback that is called when a buffer has finished playing */
static void CALLBACK
winaudio_in_buffer_done (HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance,
                         DWORD dwParam1, DWORD dwParam2)
{
    WinAudioIn*  s = (WinAudioIn*) dwInstance;

    /* Only service "buffer done playing" messages */
    if ( uMsg != WIM_DATA )
        return;

    /* Signal that we are done playing a buffer */
    EnterCriticalSection( &s->lock );
    if (s->read_count < NUM_IN_BUFFERS)
        s->read_count += 1;
        //D(".%c",s->read_count + '0'); fflush(stdout);
    LeaveCriticalSection( &s->lock );
}

static void
winaudio_in_fini (HWVoiceIn *hw)
{
    WinAudioIn*  s = (WinAudioIn*) hw;
    int           i;

    if (s->wavein) {
        waveInReset(s->wavein);
            s->wavein = 0;
    }

    for ( i=0; i<NUM_IN_BUFFERS; ++i ) {
        if ( s->buffers[i].dwUser != 0xFFFF ) {
            waveInUnprepareHeader(
                s->wavein, &s->buffers[i], sizeof(s->buffers[i]) );
                s->buffers[i].dwUser = 0xFFFF;
        }
    }

    if (s->buffer_bytes != NULL) {
        qemu_free(s->buffer_bytes);
        s->buffer_bytes = NULL;
    }

    if (s->wavein) {
        waveInClose(s->wavein);
        s->wavein = NULL;
    }
}


static int
winaudio_in_init (HWVoiceIn *hw, struct audsettings *as)
{
    WinAudioIn*   s = (WinAudioIn*) hw;
    MMRESULT       result;
    WAVEFORMATEX   format;
    int            shift, i, samples_size;

    s->wavein = NULL;
    InitializeCriticalSection( &s->lock );
    for (i = 0; i < NUM_IN_BUFFERS; i++) {
            s->buffers[i].dwUser = 0xFFFF;
    }
    s->buffer_bytes = NULL;

    /* compute desired wave input format */
    format.wFormatTag      = WAVE_FORMAT_PCM;
    format.nChannels       = as->nchannels;
    format.nSamplesPerSec  = as->freq;
    format.nAvgBytesPerSec = as->freq*as->nchannels;

    switch (as->fmt) {
        case AUD_FMT_S8:   shift = 0; break;
        case AUD_FMT_U8:   shift = 0; break;
        case AUD_FMT_S16:  shift = 1; break;
        case AUD_FMT_U16:  shift = 1; break;
        default:
            fprintf(stderr, "qemu: winaudio: Bad input audio format: %d\n",
                    as->fmt);
                return -1;
    }

    format.nAvgBytesPerSec = (format.nSamplesPerSec * format.nChannels) << shift;
    format.nBlockAlign     = format.nChannels << shift;
    format.wBitsPerSample  = 8 << shift;
    format.cbSize          = 0;

    /* open the wave in device */
    result = waveInOpen( &s->wavein, WAVE_MAPPER, &format,
                         (DWORD_PTR)winaudio_in_buffer_done, (DWORD_PTR) hw,
                         CALLBACK_FUNCTION);
    if ( result != MMSYSERR_NOERROR ) {
        dump_mmerror( "qemu: winaudio: waveInOpen()", result);
            return -1;
    }

    samples_size    = format.nBlockAlign * conf.nb_samples;
    s->buffer_bytes = qemu_malloc( NUM_IN_BUFFERS * samples_size );
    if (s->buffer_bytes == NULL) {
            waveInClose( s->wavein );
            s->wavein = NULL;
            fprintf(stderr, "not enough memory for Windows audio buffers\n");
            return -1;
    }

    for (i = 0; i < NUM_IN_BUFFERS; i++) {
        memset( &s->buffers[i], 0, sizeof(s->buffers[i]) );
        s->buffers[i].lpData         = (LPSTR)(s->buffer_bytes + i*samples_size);
        s->buffers[i].dwBufferLength = samples_size;
        s->buffers[i].dwFlags        = WHDR_DONE;

        result = waveInPrepareHeader( s->wavein, &s->buffers[i],
                               sizeof(s->buffers[i]) );
        if ( result != MMSYSERR_NOERROR ) {
                dump_mmerror("waveInPrepareHeader()", result);
                return -1;
        }

        result = waveInAddBuffer( s->wavein, &s->buffers[i],
                              sizeof(s->buffers[i]) );
        if ( result != MMSYSERR_NOERROR ) {
            dump_mmerror("waveInAddBuffer()", result);
            return -1;
        }
    }

#if DEBUG
    /* Check the sound device we retrieved */
    {
        WAVEINCAPS caps;

        result = waveInGetDevCaps((UINT) s->wavein, &caps, sizeof(caps));
        if ( result != MMSYSERR_NOERROR ) {
            dump_mmerror("waveInGetDevCaps()", result);
        } else
            printf("Audio in device: %s\n", caps.szPname);
    }
#endif

    audio_pcm_init_info (&hw->info, as);
    hw->samples = conf.nb_samples*2;

    s->read_index = 0;
    s->read_count = 0;
    s->read_pos   = 0;
    s->read_size  = samples_size;
    return 0;
}


/* report the number of captured samples to the audio subsystem */
static int
winaudio_in_run (HWVoiceIn *hw)
{
    WinAudioIn*  s        = (WinAudioIn*) hw;
    int          captured = 0;
    int          has_buffer;
    int          live = hw->samples - hw->total_samples_captured;

    if (!live) {
#if 0
        static int  counter;
        if (++counter == 100) {
            D("0"); fflush(stdout);
            counter = 0;
        }
#endif
            return 0;
    }

    EnterCriticalSection( &s->lock );
    has_buffer = (s->read_count > 0);
    LeaveCriticalSection( &s->lock );

    if (has_buffer > 0) {
        while (live > 0) {
            WAVEHDR*      wav_buffer  = s->buffers + s->read_index;
            int           wav_bytes   = (s->read_size - s->read_pos);
            int           wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
            int           hw_samples  = audio_MIN(hw->samples - hw->wpos, live);
            struct st_sample*  dst    = hw->conv_buf + hw->wpos;
            uint8_t*      src         = (uint8_t*)wav_buffer->lpData + s->read_pos;

            if (wav_samples > hw_samples) {
                wav_samples = hw_samples;
            }

            wav_bytes = wav_samples << hw->info.shift;

            D("%s: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d wpos:%d hwsamples:%d\n",
               __FUNCTION__, s->read_index, s->read_pos, s->read_size, wav_samples, wav_bytes, live,
               hw->wpos, hw->samples);

            hw->conv(dst, src, wav_samples, &nominal_volume);

            hw->wpos += wav_samples;
            if (hw->wpos >= hw->samples)
                hw->wpos -= hw->samples;

            live        -= wav_samples;
            captured    += wav_samples;
            s->read_pos += wav_bytes;
            if (s->read_pos == s->read_size) {
                s->read_pos    = 0;
                s->read_index += 1;
                if (s->read_index == NUM_IN_BUFFERS)
                    s->read_index = 0;

                waveInAddBuffer( s->wavein, wav_buffer, sizeof(*wav_buffer) );

                EnterCriticalSection( &s->lock );
                if (--s->read_count == 0) {
                    live = 0;
                }
                LeaveCriticalSection( &s->lock );
            }
        }
    }
    return  captured;
}


static int
winaudio_in_read (SWVoiceIn *sw, void *buf, int len)
{
    int  ret = audio_pcm_sw_read (sw, buf, len);
    if (ret > 0)
        D("%s: (%d) returned %d\n", __FUNCTION__, len, ret);
    return ret;
}


static int
winaudio_in_ctl (HWVoiceIn *hw, int cmd, ...)
{
	WinAudioIn*  s = (WinAudioIn*) hw;

    switch (cmd) {
    case VOICE_ENABLE:
        D("%s: enable audio in\n", __FUNCTION__);
        waveInStart( s->wavein );
        break;

    case VOICE_DISABLE:
        D("%s: disable audio in\n", __FUNCTION__);
        waveInStop( s->wavein );
        break;
    }
    return 0;
}

/** AUDIO STATE
 **/

typedef struct WinAudioState {
    int  dummy;
} WinAudioState;

static WinAudioState  g_winaudio;

static void*
winaudio_init(void)
{
    WinAudioState*  s = &g_winaudio;

#if DEBUG
    start_time = qemu_get_clock(vm_clock);
    last_time  = 0;
#endif

    return s;
}


static void
winaudio_fini (void *opaque)
{
}

static struct audio_option winaudio_options[] = {
    {"SAMPLES", AUD_OPT_INT, &conf.nb_samples,
     "Size of Windows audio buffer in samples", NULL, 0},
    {NULL, 0, NULL, NULL, NULL, 0}
};

static struct audio_pcm_ops winaudio_pcm_ops = {
    winaudio_out_init,
    winaudio_out_fini,
    winaudio_out_run,
    winaudio_out_write,
    winaudio_out_ctl,

    winaudio_in_init,
    winaudio_in_fini,
    winaudio_in_run,
    winaudio_in_read,
    winaudio_in_ctl
};

struct audio_driver win_audio_driver = {
    INIT_FIELD (name           = ) "winaudio",
    INIT_FIELD (descr          = ) "Windows wave audio",
    INIT_FIELD (options        = ) winaudio_options,
    INIT_FIELD (init           = ) winaudio_init,
    INIT_FIELD (fini           = ) winaudio_fini,
    INIT_FIELD (pcm_ops        = ) &winaudio_pcm_ops,
    INIT_FIELD (can_be_default = ) 1,
    INIT_FIELD (max_voices_out = ) 1,
    INIT_FIELD (max_voices_in  = ) 1,
    INIT_FIELD (voice_size_out = ) sizeof (WinAudioOut),
    INIT_FIELD (voice_size_in  = ) sizeof (WinAudioIn)
};
