/*
 * Copyright (C) 2010 Red Hat, Inc.
 *
 * maintained by Gerd Hoffmann <kraxel@redhat.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 or
 * (at your option) version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "ui/qemu-spice.h"

#define AUDIO_CAP "spice"
#include "audio.h"
#include "audio_int.h"

#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
#define LINE_OUT_SAMPLES (480 * 4)
#else
#define LINE_OUT_SAMPLES (256 * 4)
#endif

#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
#define LINE_IN_SAMPLES (480 * 4)
#else
#define LINE_IN_SAMPLES (256 * 4)
#endif

typedef struct SpiceRateCtl {
    int64_t               start_ticks;
    int64_t               bytes_sent;
} SpiceRateCtl;

typedef struct SpiceVoiceOut {
    HWVoiceOut            hw;
    SpicePlaybackInstance sin;
    SpiceRateCtl          rate;
    int                   active;
    uint32_t              *frame;
    uint32_t              *fpos;
    uint32_t              fsize;
} SpiceVoiceOut;

typedef struct SpiceVoiceIn {
    HWVoiceIn             hw;
    SpiceRecordInstance   sin;
    SpiceRateCtl          rate;
    int                   active;
    uint32_t              samples[LINE_IN_SAMPLES];
} SpiceVoiceIn;

static const SpicePlaybackInterface playback_sif = {
    .base.type          = SPICE_INTERFACE_PLAYBACK,
    .base.description   = "playback",
    .base.major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
    .base.minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
};

static const SpiceRecordInterface record_sif = {
    .base.type          = SPICE_INTERFACE_RECORD,
    .base.description   = "record",
    .base.major_version = SPICE_INTERFACE_RECORD_MAJOR,
    .base.minor_version = SPICE_INTERFACE_RECORD_MINOR,
};

static void *spice_audio_init(Audiodev *dev)
{
    if (!using_spice) {
        return NULL;
    }
    return &spice_audio_init;
}

static void spice_audio_fini (void *opaque)
{
    /* nothing */
}

static void rate_start (SpiceRateCtl *rate)
{
    memset (rate, 0, sizeof (*rate));
    rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}

static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
{
    int64_t now;
    int64_t ticks;
    int64_t bytes;
    int64_t samples;

    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    ticks = now - rate->start_ticks;
    bytes = muldiv64(ticks, info->bytes_per_second, NANOSECONDS_PER_SECOND);
    samples = (bytes - rate->bytes_sent) >> info->shift;
    if (samples < 0 || samples > 65536) {
        error_report("Resetting rate control (%" PRId64 " samples)", samples);
        rate_start(rate);
        samples = 0;
    }
    rate->bytes_sent += samples << info->shift;
    return samples;
}

/* playback */

static int line_out_init(HWVoiceOut *hw, struct audsettings *as,
                         void *drv_opaque)
{
    SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
    struct audsettings settings;

#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
    settings.freq       = spice_server_get_best_playback_rate(NULL);
#else
    settings.freq       = SPICE_INTERFACE_PLAYBACK_FREQ;
#endif
    settings.nchannels  = SPICE_INTERFACE_PLAYBACK_CHAN;
    settings.fmt        = AUDIO_FORMAT_S16;
    settings.endianness = AUDIO_HOST_ENDIANNESS;

    audio_pcm_init_info (&hw->info, &settings);
    hw->samples = LINE_OUT_SAMPLES;
    out->active = 0;

    out->sin.base.sif = &playback_sif.base;
    qemu_spice_add_interface (&out->sin.base);
#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
    spice_server_set_playback_rate(&out->sin, settings.freq);
#endif
    return 0;
}

static void line_out_fini (HWVoiceOut *hw)
{
    SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);

    spice_server_remove_interface (&out->sin.base);
}

static size_t line_out_run (HWVoiceOut *hw, size_t live)
{
    SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
    size_t rpos, decr;
    size_t samples;

    if (!live) {
        return 0;
    }

    decr = rate_get_samples (&hw->info, &out->rate);
    decr = MIN (live, decr);

    samples = decr;
    rpos = hw->rpos;
    while (samples) {
        int left_till_end_samples = hw->samples - rpos;
        int len = MIN (samples, left_till_end_samples);

        if (!out->frame) {
            spice_server_playback_get_buffer (&out->sin, &out->frame, &out->fsize);
            out->fpos = out->frame;
        }
        if (out->frame) {
            len = MIN (len, out->fsize);
            hw->clip (out->fpos, hw->mix_buf + rpos, len);
            out->fsize -= len;
            out->fpos  += len;
            if (out->fsize == 0) {
                spice_server_playback_put_samples (&out->sin, out->frame);
                out->frame = out->fpos = NULL;
            }
        }
        rpos = (rpos + len) % hw->samples;
        samples -= len;
    }
    hw->rpos = rpos;
    return decr;
}

static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
{
    SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);

    switch (cmd) {
    case VOICE_ENABLE:
        if (out->active) {
            break;
        }
        out->active = 1;
        rate_start (&out->rate);
        spice_server_playback_start (&out->sin);
        break;
    case VOICE_DISABLE:
        if (!out->active) {
            break;
        }
        out->active = 0;
        if (out->frame) {
            memset (out->fpos, 0, out->fsize << 2);
            spice_server_playback_put_samples (&out->sin, out->frame);
            out->frame = out->fpos = NULL;
        }
        spice_server_playback_stop (&out->sin);
        break;
    case VOICE_VOLUME:
        {
#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
            SWVoiceOut *sw;
            va_list ap;
            uint16_t vol[2];

            va_start (ap, cmd);
            sw = va_arg (ap, SWVoiceOut *);
            va_end (ap);

            vol[0] = sw->vol.l / ((1ULL << 16) + 1);
            vol[1] = sw->vol.r / ((1ULL << 16) + 1);
            spice_server_playback_set_volume (&out->sin, 2, vol);
            spice_server_playback_set_mute (&out->sin, sw->vol.mute);
#endif
            break;
        }
    }

    return 0;
}

/* record */

static int line_in_init(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
    SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
    struct audsettings settings;

#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
    settings.freq       = spice_server_get_best_record_rate(NULL);
#else
    settings.freq       = SPICE_INTERFACE_RECORD_FREQ;
#endif
    settings.nchannels  = SPICE_INTERFACE_RECORD_CHAN;
    settings.fmt        = AUDIO_FORMAT_S16;
    settings.endianness = AUDIO_HOST_ENDIANNESS;

    audio_pcm_init_info (&hw->info, &settings);
    hw->samples = LINE_IN_SAMPLES;
    in->active = 0;

    in->sin.base.sif = &record_sif.base;
    qemu_spice_add_interface (&in->sin.base);
#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
    spice_server_set_record_rate(&in->sin, settings.freq);
#endif
    return 0;
}

static void line_in_fini (HWVoiceIn *hw)
{
    SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);

    spice_server_remove_interface (&in->sin.base);
}

static size_t line_in_run(HWVoiceIn *hw)
{
    SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
    size_t num_samples;
    int ready;
    size_t len[2];
    uint64_t delta_samp;
    const uint32_t *samples;

    if (!(num_samples = hw->samples - audio_pcm_hw_get_live_in (hw))) {
        return 0;
    }

    delta_samp = rate_get_samples (&hw->info, &in->rate);
    num_samples = MIN (num_samples, delta_samp);

    ready = spice_server_record_get_samples (&in->sin, in->samples, num_samples);
    samples = in->samples;
    if (ready == 0) {
        static const uint32_t silence[LINE_IN_SAMPLES];
        samples = silence;
        ready = LINE_IN_SAMPLES;
    }

    num_samples = MIN (ready, num_samples);

    if (hw->wpos + num_samples > hw->samples) {
        len[0] = hw->samples - hw->wpos;
        len[1] = num_samples - len[0];
    } else {
        len[0] = num_samples;
        len[1] = 0;
    }

    hw->conv (hw->conv_buf + hw->wpos, samples, len[0]);

    if (len[1]) {
        hw->conv (hw->conv_buf, samples + len[0], len[1]);
    }

    hw->wpos = (hw->wpos + num_samples) % hw->samples;

    return num_samples;
}

static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)
{
    SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);

    switch (cmd) {
    case VOICE_ENABLE:
        if (in->active) {
            break;
        }
        in->active = 1;
        rate_start (&in->rate);
        spice_server_record_start (&in->sin);
        break;
    case VOICE_DISABLE:
        if (!in->active) {
            break;
        }
        in->active = 0;
        spice_server_record_stop (&in->sin);
        break;
    case VOICE_VOLUME:
        {
#if ((SPICE_INTERFACE_RECORD_MAJOR >= 2) && (SPICE_INTERFACE_RECORD_MINOR >= 2))
            SWVoiceIn *sw;
            va_list ap;
            uint16_t vol[2];

            va_start (ap, cmd);
            sw = va_arg (ap, SWVoiceIn *);
            va_end (ap);

            vol[0] = sw->vol.l / ((1ULL << 16) + 1);
            vol[1] = sw->vol.r / ((1ULL << 16) + 1);
            spice_server_record_set_volume (&in->sin, 2, vol);
            spice_server_record_set_mute (&in->sin, sw->vol.mute);
#endif
            break;
        }
    }

    return 0;
}

static struct audio_pcm_ops audio_callbacks = {
    .init_out = line_out_init,
    .fini_out = line_out_fini,
    .run_out  = line_out_run,
    .ctl_out  = line_out_ctl,

    .init_in  = line_in_init,
    .fini_in  = line_in_fini,
    .run_in   = line_in_run,
    .ctl_in   = line_in_ctl,
};

static struct audio_driver spice_audio_driver = {
    .name           = "spice",
    .descr          = "spice audio driver",
    .init           = spice_audio_init,
    .fini           = spice_audio_fini,
    .pcm_ops        = &audio_callbacks,
    .max_voices_out = 1,
    .max_voices_in  = 1,
    .voice_size_out = sizeof (SpiceVoiceOut),
    .voice_size_in  = sizeof (SpiceVoiceIn),
#if ((SPICE_INTERFACE_PLAYBACK_MAJOR >= 1) && (SPICE_INTERFACE_PLAYBACK_MINOR >= 2))
    .ctl_caps       = VOICE_VOLUME_CAP
#endif
};

void qemu_spice_audio_init (void)
{
    spice_audio_driver.can_be_default = 1;
}

static void register_audio_spice(void)
{
    audio_driver_register(&spice_audio_driver);
}
type_init(register_audio_spice);
