/*
 * QEMU OSS audio output driver
 * 
 * Copyright (c) 2003-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.
 */

/* Temporary kludge */
#if defined __linux__ || (defined _BSD && !defined __APPLE__)
#include <assert.h>
#include "vl.h"

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>

#define AUDIO_CAP "oss"
#include "audio/audio.h"
#include "audio/ossaudio.h"

#define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
#define QC_OSS_NFRAGS   "QEMU_OSS_NFRAGS"
#define QC_OSS_MMAP     "QEMU_OSS_MMAP"
#define QC_OSS_DEV      "QEMU_OSS_DEV"

#define errstr() strerror (errno)

static struct {
    int try_mmap;
    int nfrags;
    int fragsize;
    const char *dspname;
} conf = {
    .try_mmap = 0,
    .nfrags = 4,
    .fragsize = 4096,
    .dspname = "/dev/dsp"
};

struct oss_params {
    int freq;
    audfmt_e fmt;
    int nchannels;
    int nfrags;
    int fragsize;
};

static int oss_hw_write (SWVoice *sw, void *buf, int len)
{
    return pcm_hw_write (sw, buf, len);
}

static int AUD_to_ossfmt (audfmt_e fmt)
{
    switch (fmt) {
    case AUD_FMT_S8: return AFMT_S8;
    case AUD_FMT_U8: return AFMT_U8;
    case AUD_FMT_S16: return AFMT_S16_LE;
    case AUD_FMT_U16: return AFMT_U16_LE;
    default:
        dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
        exit (EXIT_FAILURE);
    }
}

static int oss_to_audfmt (int fmt)
{
    switch (fmt) {
    case AFMT_S8: return AUD_FMT_S8;
    case AFMT_U8: return AUD_FMT_U8;
    case AFMT_S16_LE: return AUD_FMT_S16;
    case AFMT_U16_LE: return AUD_FMT_U16;
    default:
        dolog ("Internal logic error: Unrecognized OSS audio format %d\n"
               "Aborting\n",
               fmt);
        exit (EXIT_FAILURE);
    }
}

#ifdef DEBUG_PCM
static void oss_dump_pcm_info (struct oss_params *req, struct oss_params *obt)
{
    dolog ("parameter | requested value | obtained value\n");
    dolog ("format    |      %10d |     %10d\n", req->fmt, obt->fmt);
    dolog ("channels  |      %10d |     %10d\n", req->nchannels, obt->nchannels);
    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
    dolog ("nfrags    |      %10d |     %10d\n", req->nfrags, obt->nfrags);
    dolog ("fragsize  |      %10d |     %10d\n", req->fragsize, obt->fragsize);
}
#endif

static int oss_open (struct oss_params *req, struct oss_params *obt, int *pfd)
{
    int fd;
    int mmmmssss;
    audio_buf_info abinfo;
    int fmt, freq, nchannels;
    const char *dspname = conf.dspname;

    fd = open (dspname, O_RDWR | O_NONBLOCK);
    if (-1 == fd) {
        dolog ("Could not initialize audio hardware. Failed to open `%s':\n"
               "Reason:%s\n",
               dspname,
               errstr ());
        return -1;
    }

    freq = req->freq;
    nchannels = req->nchannels;
    fmt = req->fmt;

    if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
        dolog ("Could not initialize audio hardware\n"
               "Failed to set sample size\n"
               "Reason: %s\n",
               errstr ());
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
        dolog ("Could not initialize audio hardware\n"
               "Failed to set number of channels\n"
               "Reason: %s\n",
               errstr ());
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
        dolog ("Could not initialize audio hardware\n"
               "Failed to set frequency\n"
               "Reason: %s\n",
               errstr ());
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_NONBLOCK)) {
        dolog ("Could not initialize audio hardware\n"
               "Failed to set non-blocking mode\n"
               "Reason: %s\n",
               errstr ());
        goto err;
    }

    mmmmssss = (req->nfrags << 16) | lsbindex (req->fragsize);
    if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
        dolog ("Could not initialize audio hardware\n"
               "Failed to set buffer length (%d, %d)\n"
               "Reason:%s\n",
               conf.nfrags, conf.fragsize,
               errstr ());
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_GETOSPACE, &abinfo)) {
        dolog ("Could not initialize audio hardware\n"
               "Failed to get buffer length\n"
               "Reason:%s\n",
               errstr ());
        goto err;
    }

    obt->fmt = fmt;
    obt->nchannels = nchannels;
    obt->freq = freq;
    obt->nfrags = abinfo.fragstotal;
    obt->fragsize = abinfo.fragsize;
    *pfd = fd;

    if ((req->fmt != obt->fmt) ||
        (req->nchannels != obt->nchannels) ||
        (req->freq != obt->freq) ||
        (req->fragsize != obt->fragsize) ||
        (req->nfrags != obt->nfrags)) {
#ifdef DEBUG_PCM
        dolog ("Audio parameters mismatch\n");
        oss_dump_pcm_info (req, obt);
#endif
    }

#ifdef DEBUG_PCM
    oss_dump_pcm_info (req, obt);
#endif
    return 0;

err:
    close (fd);
    return -1;
}

static void oss_hw_run (HWVoice *hw)
{
    OSSVoice *oss = (OSSVoice *) hw;
    int err, rpos, live, decr;
    int samples;
    uint8_t *dst;
    st_sample_t *src;
    struct audio_buf_info abinfo;
    struct count_info cntinfo;

    live = pcm_hw_get_live (hw);
    if (live <= 0)
        return;

    if (oss->mmapped) {
        int bytes;

        err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
        if (err < 0) {
            dolog ("SNDCTL_DSP_GETOPTR failed\nReason: %s\n", errstr ());
            return;
        }

        if (cntinfo.ptr == oss->old_optr) {
            if (abs (hw->samples - live) < 64)
                dolog ("overrun\n");
            return;
        }

        if (cntinfo.ptr > oss->old_optr) {
            bytes = cntinfo.ptr - oss->old_optr;
        }
        else {
            bytes = hw->bufsize + cntinfo.ptr - oss->old_optr;
        }

        decr = audio_MIN (bytes >> hw->shift, live);
    }
    else {
        err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
        if (err < 0) {
            dolog ("SNDCTL_DSP_GETOSPACE failed\nReason: %s\n", errstr ());
            return;
        }

        decr = audio_MIN (abinfo.bytes >> hw->shift, live);
        if (decr <= 0)
            return;
    }

    samples = decr;
    rpos = hw->rpos;
    while (samples) {
        int left_till_end_samples = hw->samples - rpos;
        int convert_samples = audio_MIN (samples, left_till_end_samples);

        src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
        dst = advance (oss->pcm_buf, rpos << hw->shift);

        hw->clip (dst, src, convert_samples);
        if (!oss->mmapped) {
            int written;

            written = write (oss->fd, dst, convert_samples << hw->shift);
            /* XXX: follow errno recommendations ? */
            if (written == -1) {
                dolog ("Failed to write audio\nReason: %s\n", errstr ());
                continue;
            }

            if (written != convert_samples << hw->shift) {
                int wsamples = written >> hw->shift;
                int wbytes = wsamples << hw->shift;
                if (wbytes != written) {
                    dolog ("Unaligned write %d, %d\n", wbytes, written);
                }
                memset (src, 0, wbytes);
                decr -= samples;
                rpos = (rpos + wsamples) % hw->samples;
                break;
            }
        }
        memset (src, 0, convert_samples * sizeof (st_sample_t));

        rpos = (rpos + convert_samples) % hw->samples;
        samples -= convert_samples;
    }
    if (oss->mmapped) {
        oss->old_optr = cntinfo.ptr;
    }

    pcm_hw_dec_live (hw, decr);
    hw->rpos = rpos;
}

static void oss_hw_fini (HWVoice *hw)
{
    int err;
    OSSVoice *oss = (OSSVoice *) hw;

    ldebug ("oss_hw_fini\n");
    err = close (oss->fd);
    if (err) {
        dolog ("Failed to close OSS descriptor\nReason: %s\n", errstr ());
    }
    oss->fd = -1;

    if (oss->pcm_buf) {
        if (oss->mmapped) {
            err = munmap (oss->pcm_buf, hw->bufsize);
            if (err) {
                dolog ("Failed to unmap OSS buffer\nReason: %s\n",
                       errstr ());
            }
        }
        else {
            qemu_free (oss->pcm_buf);
        }
        oss->pcm_buf = NULL;
    }
}

static int oss_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
{
    OSSVoice *oss = (OSSVoice *) hw;
    struct oss_params req, obt;

    assert (!oss->fd);
    req.fmt = AUD_to_ossfmt (fmt);
    req.freq = freq;
    req.nchannels = nchannels;
    req.fragsize = conf.fragsize;
    req.nfrags = conf.nfrags;

    if (oss_open (&req, &obt, &oss->fd))
        return -1;

    hw->freq = obt.freq;
    hw->fmt = oss_to_audfmt (obt.fmt);
    hw->nchannels = obt.nchannels;

    oss->nfrags = obt.nfrags;
    oss->fragsize = obt.fragsize;
    hw->bufsize = obt.nfrags * obt.fragsize;

    oss->mmapped = 0;
    if (conf.try_mmap) {
        oss->pcm_buf = mmap (0, hw->bufsize, PROT_READ | PROT_WRITE,
                             MAP_SHARED, oss->fd, 0);
        if (oss->pcm_buf == MAP_FAILED) {
            dolog ("Failed to mmap OSS device\nReason: %s\n",
                   errstr ());
        }

        for (;;) {
            int err;
            int trig = 0;
            if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
                       errstr ());
                goto fail;
            }

            trig = PCM_ENABLE_OUTPUT;
            if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
                       "Reason: %s\n", errstr ());
                goto fail;
            }
            oss->mmapped = 1;
            break;

        fail:
            err = munmap (oss->pcm_buf, hw->bufsize);
            if (err) {
                dolog ("Failed to unmap OSS device\nReason: %s\n",
                       errstr ());
            }
        }
    }

    if (!oss->mmapped) {
        oss->pcm_buf = qemu_mallocz (hw->bufsize);
        if (!oss->pcm_buf) {
            close (oss->fd);
            oss->fd = -1;
            return -1;
        }
    }

    return 0;
}

static int oss_hw_ctl (HWVoice *hw, int cmd, ...)
{
    int trig;
    OSSVoice *oss = (OSSVoice *) hw;

    if (!oss->mmapped)
        return 0;

    switch (cmd) {
    case VOICE_ENABLE:
        ldebug ("enabling voice\n");
        pcm_hw_clear (hw, oss->pcm_buf, hw->samples);
        trig = PCM_ENABLE_OUTPUT;
        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
            dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
                   "Reason: %s\n", errstr ());
            return -1;
        }
        break;

    case VOICE_DISABLE:
        ldebug ("disabling voice\n");
        trig = 0;
        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
            dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
                   errstr ());
            return -1;
        }
        break;
    }
    return 0;
}

static void *oss_audio_init (void)
{
    conf.fragsize = audio_get_conf_int (QC_OSS_FRAGSIZE, conf.fragsize);
    conf.nfrags = audio_get_conf_int (QC_OSS_NFRAGS, conf.nfrags);
    conf.try_mmap = audio_get_conf_int (QC_OSS_MMAP, conf.try_mmap);
    conf.dspname = audio_get_conf_str (QC_OSS_DEV, conf.dspname);
    return &conf;
}

static void oss_audio_fini (void *opaque)
{
}

struct pcm_ops oss_pcm_ops = {
    oss_hw_init,
    oss_hw_fini,
    oss_hw_run,
    oss_hw_write,
    oss_hw_ctl
};

struct audio_output_driver oss_output_driver = {
    "oss",
    oss_audio_init,
    oss_audio_fini,
    &oss_pcm_ops,
    1,
    INT_MAX,
    sizeof (OSSVoice)
};
#endif
