/*
 * QEMU ALSA audio driver
 *
 * Copyright (c) 2005 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 "qemu/osdep.h"
#include <alsa/asoundlib.h>
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "audio.h"
#include "trace.h"

#pragma GCC diagnostic ignored "-Waddress"

#define AUDIO_CAP "alsa"
#include "audio_int.h"

struct pollhlp {
    snd_pcm_t *handle;
    struct pollfd *pfds;
    int count;
    int mask;
    AudioState *s;
};

typedef struct ALSAVoiceOut {
    HWVoiceOut hw;
    snd_pcm_t *handle;
    struct pollhlp pollhlp;
    Audiodev *dev;
} ALSAVoiceOut;

typedef struct ALSAVoiceIn {
    HWVoiceIn hw;
    snd_pcm_t *handle;
    struct pollhlp pollhlp;
    Audiodev *dev;
} ALSAVoiceIn;

struct alsa_params_req {
    int freq;
    snd_pcm_format_t fmt;
    int nchannels;
};

struct alsa_params_obt {
    int freq;
    AudioFormat fmt;
    int endianness;
    int nchannels;
    snd_pcm_uframes_t samples;
};

static void GCC_FMT_ATTR (2, 3) alsa_logerr (int err, const char *fmt, ...)
{
    va_list ap;

    va_start (ap, fmt);
    AUD_vlog (AUDIO_CAP, fmt, ap);
    va_end (ap);

    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
}

static void GCC_FMT_ATTR (3, 4) alsa_logerr2 (
    int err,
    const char *typ,
    const char *fmt,
    ...
    )
{
    va_list ap;

    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);

    va_start (ap, fmt);
    AUD_vlog (AUDIO_CAP, fmt, ap);
    va_end (ap);

    AUD_log (AUDIO_CAP, "Reason: %s\n", snd_strerror (err));
}

static void alsa_fini_poll (struct pollhlp *hlp)
{
    int i;
    struct pollfd *pfds = hlp->pfds;

    if (pfds) {
        for (i = 0; i < hlp->count; ++i) {
            qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
        }
        g_free (pfds);
    }
    hlp->pfds = NULL;
    hlp->count = 0;
    hlp->handle = NULL;
}

static void alsa_anal_close1 (snd_pcm_t **handlep)
{
    int err = snd_pcm_close (*handlep);
    if (err) {
        alsa_logerr (err, "Failed to close PCM handle %p\n", *handlep);
    }
    *handlep = NULL;
}

static void alsa_anal_close (snd_pcm_t **handlep, struct pollhlp *hlp)
{
    alsa_fini_poll (hlp);
    alsa_anal_close1 (handlep);
}

static int alsa_recover (snd_pcm_t *handle)
{
    int err = snd_pcm_prepare (handle);
    if (err < 0) {
        alsa_logerr (err, "Failed to prepare handle %p\n", handle);
        return -1;
    }
    return 0;
}

static int alsa_resume (snd_pcm_t *handle)
{
    int err = snd_pcm_resume (handle);
    if (err < 0) {
        alsa_logerr (err, "Failed to resume handle %p\n", handle);
        return -1;
    }
    return 0;
}

static void alsa_poll_handler (void *opaque)
{
    int err, count;
    snd_pcm_state_t state;
    struct pollhlp *hlp = opaque;
    unsigned short revents;

    count = poll (hlp->pfds, hlp->count, 0);
    if (count < 0) {
        dolog ("alsa_poll_handler: poll %s\n", strerror (errno));
        return;
    }

    if (!count) {
        return;
    }

    /* XXX: ALSA example uses initial count, not the one returned by
       poll, correct? */
    err = snd_pcm_poll_descriptors_revents (hlp->handle, hlp->pfds,
                                            hlp->count, &revents);
    if (err < 0) {
        alsa_logerr (err, "snd_pcm_poll_descriptors_revents");
        return;
    }

    if (!(revents & hlp->mask)) {
        trace_alsa_revents(revents);
        return;
    }

    state = snd_pcm_state (hlp->handle);
    switch (state) {
    case SND_PCM_STATE_SETUP:
        alsa_recover (hlp->handle);
        break;

    case SND_PCM_STATE_XRUN:
        alsa_recover (hlp->handle);
        break;

    case SND_PCM_STATE_SUSPENDED:
        alsa_resume (hlp->handle);
        break;

    case SND_PCM_STATE_PREPARED:
        audio_run(hlp->s, "alsa run (prepared)");
        break;

    case SND_PCM_STATE_RUNNING:
        audio_run(hlp->s, "alsa run (running)");
        break;

    default:
        dolog ("Unexpected state %d\n", state);
    }
}

static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
{
    int i, count, err;
    struct pollfd *pfds;

    count = snd_pcm_poll_descriptors_count (handle);
    if (count <= 0) {
        dolog ("Could not initialize poll mode\n"
               "Invalid number of poll descriptors %d\n", count);
        return -1;
    }

    pfds = audio_calloc ("alsa_poll_helper", count, sizeof (*pfds));
    if (!pfds) {
        dolog ("Could not initialize poll mode\n");
        return -1;
    }

    err = snd_pcm_poll_descriptors (handle, pfds, count);
    if (err < 0) {
        alsa_logerr (err, "Could not initialize poll mode\n"
                     "Could not obtain poll descriptors\n");
        g_free (pfds);
        return -1;
    }

    for (i = 0; i < count; ++i) {
        if (pfds[i].events & POLLIN) {
            qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, NULL, hlp);
        }
        if (pfds[i].events & POLLOUT) {
            trace_alsa_pollout(i, pfds[i].fd);
            qemu_set_fd_handler (pfds[i].fd, NULL, alsa_poll_handler, hlp);
        }
        trace_alsa_set_handler(pfds[i].events, i, pfds[i].fd, err);

    }
    hlp->pfds = pfds;
    hlp->count = count;
    hlp->handle = handle;
    hlp->mask = mask;
    return 0;
}

static int alsa_poll_out (HWVoiceOut *hw)
{
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;

    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLOUT);
}

static int alsa_poll_in (HWVoiceIn *hw)
{
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;

    return alsa_poll_helper (alsa->handle, &alsa->pollhlp, POLLIN);
}

static snd_pcm_format_t aud_to_alsafmt (AudioFormat fmt, int endianness)
{
    switch (fmt) {
    case AUDIO_FORMAT_S8:
        return SND_PCM_FORMAT_S8;

    case AUDIO_FORMAT_U8:
        return SND_PCM_FORMAT_U8;

    case AUDIO_FORMAT_S16:
        if (endianness) {
            return SND_PCM_FORMAT_S16_BE;
        }
        else {
            return SND_PCM_FORMAT_S16_LE;
        }

    case AUDIO_FORMAT_U16:
        if (endianness) {
            return SND_PCM_FORMAT_U16_BE;
        }
        else {
            return SND_PCM_FORMAT_U16_LE;
        }

    case AUDIO_FORMAT_S32:
        if (endianness) {
            return SND_PCM_FORMAT_S32_BE;
        }
        else {
            return SND_PCM_FORMAT_S32_LE;
        }

    case AUDIO_FORMAT_U32:
        if (endianness) {
            return SND_PCM_FORMAT_U32_BE;
        }
        else {
            return SND_PCM_FORMAT_U32_LE;
        }

    default:
        dolog ("Internal logic error: Bad audio format %d\n", fmt);
#ifdef DEBUG_AUDIO
        abort ();
#endif
        return SND_PCM_FORMAT_U8;
    }
}

static int alsa_to_audfmt (snd_pcm_format_t alsafmt, AudioFormat *fmt,
                           int *endianness)
{
    switch (alsafmt) {
    case SND_PCM_FORMAT_S8:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S8;
        break;

    case SND_PCM_FORMAT_U8:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U8;
        break;

    case SND_PCM_FORMAT_S16_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S16;
        break;

    case SND_PCM_FORMAT_U16_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U16;
        break;

    case SND_PCM_FORMAT_S16_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_S16;
        break;

    case SND_PCM_FORMAT_U16_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_U16;
        break;

    case SND_PCM_FORMAT_S32_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S32;
        break;

    case SND_PCM_FORMAT_U32_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U32;
        break;

    case SND_PCM_FORMAT_S32_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_S32;
        break;

    case SND_PCM_FORMAT_U32_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_U32;
        break;

    default:
        dolog ("Unrecognized audio format %d\n", alsafmt);
        return -1;
    }

    return 0;
}

static void alsa_dump_info (struct alsa_params_req *req,
                            struct alsa_params_obt *obt,
                            snd_pcm_format_t obtfmt,
                            AudiodevAlsaPerDirectionOptions *apdo)
{
    dolog("parameter | requested value | obtained value\n");
    dolog("format    |      %10d |     %10d\n", req->fmt, obtfmt);
    dolog("channels  |      %10d |     %10d\n",
          req->nchannels, obt->nchannels);
    dolog("frequency |      %10d |     %10d\n", req->freq, obt->freq);
    dolog("============================================\n");
    dolog("requested: buffer len %" PRId32 " period len %" PRId32 "\n",
          apdo->buffer_length, apdo->period_length);
    dolog("obtained: samples %ld\n", obt->samples);
}

static void alsa_set_threshold (snd_pcm_t *handle, snd_pcm_uframes_t threshold)
{
    int err;
    snd_pcm_sw_params_t *sw_params;

    snd_pcm_sw_params_alloca (&sw_params);

    err = snd_pcm_sw_params_current (handle, sw_params);
    if (err < 0) {
        dolog ("Could not fully initialize DAC\n");
        alsa_logerr (err, "Failed to get current software parameters\n");
        return;
    }

    err = snd_pcm_sw_params_set_start_threshold (handle, sw_params, threshold);
    if (err < 0) {
        dolog ("Could not fully initialize DAC\n");
        alsa_logerr (err, "Failed to set software threshold to %ld\n",
                     threshold);
        return;
    }

    err = snd_pcm_sw_params (handle, sw_params);
    if (err < 0) {
        dolog ("Could not fully initialize DAC\n");
        alsa_logerr (err, "Failed to set software parameters\n");
        return;
    }
}

static int alsa_open(bool in, struct alsa_params_req *req,
                     struct alsa_params_obt *obt, snd_pcm_t **handlep,
                     Audiodev *dev)
{
    AudiodevAlsaOptions *aopts = &dev->u.alsa;
    AudiodevAlsaPerDirectionOptions *apdo = in ? aopts->in : aopts->out;
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *hw_params;
    int err;
    unsigned int freq, nchannels;
    const char *pcm_name = apdo->has_dev ? apdo->dev : "default";
    snd_pcm_uframes_t obt_buffer_size;
    const char *typ = in ? "ADC" : "DAC";
    snd_pcm_format_t obtfmt;

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

    snd_pcm_hw_params_alloca (&hw_params);

    err = snd_pcm_open (
        &handle,
        pcm_name,
        in ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
        SND_PCM_NONBLOCK
        );
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to open `%s':\n", pcm_name);
        return -1;
    }

    err = snd_pcm_hw_params_any (handle, hw_params);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to initialize hardware parameters\n");
        goto err;
    }

    err = snd_pcm_hw_params_set_access (
        handle,
        hw_params,
        SND_PCM_ACCESS_RW_INTERLEAVED
        );
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to set access type\n");
        goto err;
    }

    err = snd_pcm_hw_params_set_format (handle, hw_params, req->fmt);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to set format %d\n", req->fmt);
    }

    err = snd_pcm_hw_params_set_rate_near (handle, hw_params, &freq, 0);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to set frequency %d\n", req->freq);
        goto err;
    }

    err = snd_pcm_hw_params_set_channels_near (
        handle,
        hw_params,
        &nchannels
        );
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to set number of channels %d\n",
                      req->nchannels);
        goto err;
    }

    if (nchannels != 1 && nchannels != 2) {
        alsa_logerr2 (err, typ,
                      "Can not handle obtained number of channels %d\n",
                      nchannels);
        goto err;
    }

    if (apdo->buffer_length) {
        int dir = 0;
        unsigned int btime = apdo->buffer_length;

        err = snd_pcm_hw_params_set_buffer_time_near(
            handle, hw_params, &btime, &dir);

        if (err < 0) {
            alsa_logerr2(err, typ, "Failed to set buffer time to %" PRId32 "\n",
                         apdo->buffer_length);
            goto err;
        }

        if (apdo->has_buffer_length && btime != apdo->buffer_length) {
            dolog("Requested buffer time %" PRId32
                  " was rejected, using %u\n", apdo->buffer_length, btime);
        }
    }

    if (apdo->period_length) {
        int dir = 0;
        unsigned int ptime = apdo->period_length;

        err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, &ptime,
                                                     &dir);

        if (err < 0) {
            alsa_logerr2(err, typ, "Failed to set period time to %" PRId32 "\n",
                         apdo->period_length);
            goto err;
        }

        if (apdo->has_period_length && ptime != apdo->period_length) {
            dolog("Requested period time %" PRId32 " was rejected, using %d\n",
                  apdo->period_length, ptime);
        }
    }

    err = snd_pcm_hw_params (handle, hw_params);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to apply audio parameters\n");
        goto err;
    }

    err = snd_pcm_hw_params_get_buffer_size (hw_params, &obt_buffer_size);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to get buffer size\n");
        goto err;
    }

    err = snd_pcm_hw_params_get_format (hw_params, &obtfmt);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Failed to get format\n");
        goto err;
    }

    if (alsa_to_audfmt (obtfmt, &obt->fmt, &obt->endianness)) {
        dolog ("Invalid format was returned %d\n", obtfmt);
        goto err;
    }

    err = snd_pcm_prepare (handle);
    if (err < 0) {
        alsa_logerr2 (err, typ, "Could not prepare handle %p\n", handle);
        goto err;
    }

    if (!in && aopts->has_threshold && aopts->threshold) {
        struct audsettings as = { .freq = freq };
        alsa_set_threshold(
            handle,
            audio_buffer_frames(qapi_AudiodevAlsaPerDirectionOptions_base(apdo),
                                &as, aopts->threshold));
    }

    obt->nchannels = nchannels;
    obt->freq = freq;
    obt->samples = obt_buffer_size;

    *handlep = handle;

    if (obtfmt != req->fmt ||
         obt->nchannels != req->nchannels ||
         obt->freq != req->freq) {
        dolog ("Audio parameters for %s\n", typ);
        alsa_dump_info(req, obt, obtfmt, apdo);
    }

#ifdef DEBUG
    alsa_dump_info(req, obt, obtfmt, pdo);
#endif
    return 0;

 err:
    alsa_anal_close1 (&handle);
    return -1;
}

static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len)
{
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
    size_t pos = 0;
    size_t len_frames = len >> hw->info.shift;

    while (len_frames) {
        char *src = advance(buf, pos);
        snd_pcm_sframes_t written;

        written = snd_pcm_writei(alsa->handle, src, len_frames);

        if (written <= 0) {
            switch (written) {
            case 0:
                trace_alsa_wrote_zero(len_frames);
                return pos;

            case -EPIPE:
                if (alsa_recover(alsa->handle)) {
                    alsa_logerr(written, "Failed to write %zu frames\n",
                                len_frames);
                    return pos;
                }
                trace_alsa_xrun_out();
                continue;

            case -ESTRPIPE:
                /*
                 * stream is suspended and waiting for an application
                 * recovery
                 */
                if (alsa_resume(alsa->handle)) {
                    alsa_logerr(written, "Failed to write %zu frames\n",
                                len_frames);
                    return pos;
                }
                trace_alsa_resume_out();
                continue;

            case -EAGAIN:
                return pos;

            default:
                alsa_logerr(written, "Failed to write %zu frames from %p\n",
                            len, src);
                return pos;
            }
        }

        pos += written << hw->info.shift;
        if (written < len_frames) {
            break;
        }
        len_frames -= written;
    }

    return pos;
}

static void alsa_fini_out (HWVoiceOut *hw)
{
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;

    ldebug ("alsa_fini\n");
    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
}

static int alsa_init_out(HWVoiceOut *hw, struct audsettings *as,
                         void *drv_opaque)
{
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
    struct alsa_params_req req;
    struct alsa_params_obt obt;
    snd_pcm_t *handle;
    struct audsettings obt_as;
    Audiodev *dev = drv_opaque;

    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
    req.freq = as->freq;
    req.nchannels = as->nchannels;

    if (alsa_open(0, &req, &obt, &handle, dev)) {
        return -1;
    }

    obt_as.freq = obt.freq;
    obt_as.nchannels = obt.nchannels;
    obt_as.fmt = obt.fmt;
    obt_as.endianness = obt.endianness;

    audio_pcm_init_info (&hw->info, &obt_as);
    hw->samples = obt.samples;

    alsa->pollhlp.s = hw->s;
    alsa->handle = handle;
    alsa->dev = dev;
    return 0;
}

#define VOICE_CTL_PAUSE 0
#define VOICE_CTL_PREPARE 1
#define VOICE_CTL_START 2

static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)
{
    int err;

    if (ctl == VOICE_CTL_PAUSE) {
        err = snd_pcm_drop (handle);
        if (err < 0) {
            alsa_logerr (err, "Could not stop %s\n", typ);
            return -1;
        }
    }
    else {
        err = snd_pcm_prepare (handle);
        if (err < 0) {
            alsa_logerr (err, "Could not prepare handle for %s\n", typ);
            return -1;
        }
        if (ctl == VOICE_CTL_START) {
            err = snd_pcm_start(handle);
            if (err < 0) {
                alsa_logerr (err, "Could not start handle for %s\n", typ);
                return -1;
            }
        }
    }

    return 0;
}

static void alsa_enable_out(HWVoiceOut *hw, bool enable)
{
    ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
    AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.out;

    if (enable) {
        bool poll_mode = apdo->try_poll;

        ldebug("enabling voice\n");
        if (poll_mode && alsa_poll_out(hw)) {
            poll_mode = 0;
        }
        hw->poll_mode = poll_mode;
        alsa_voice_ctl(alsa->handle, "playback", VOICE_CTL_PREPARE);
    } else {
        ldebug("disabling voice\n");
        if (hw->poll_mode) {
            hw->poll_mode = 0;
            alsa_fini_poll(&alsa->pollhlp);
        }
        alsa_voice_ctl(alsa->handle, "playback", VOICE_CTL_PAUSE);
    }
}

static int alsa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
    struct alsa_params_req req;
    struct alsa_params_obt obt;
    snd_pcm_t *handle;
    struct audsettings obt_as;
    Audiodev *dev = drv_opaque;

    req.fmt = aud_to_alsafmt (as->fmt, as->endianness);
    req.freq = as->freq;
    req.nchannels = as->nchannels;

    if (alsa_open(1, &req, &obt, &handle, dev)) {
        return -1;
    }

    obt_as.freq = obt.freq;
    obt_as.nchannels = obt.nchannels;
    obt_as.fmt = obt.fmt;
    obt_as.endianness = obt.endianness;

    audio_pcm_init_info (&hw->info, &obt_as);
    hw->samples = obt.samples;

    alsa->pollhlp.s = hw->s;
    alsa->handle = handle;
    alsa->dev = dev;
    return 0;
}

static void alsa_fini_in (HWVoiceIn *hw)
{
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;

    alsa_anal_close (&alsa->handle, &alsa->pollhlp);
}

static size_t alsa_read(HWVoiceIn *hw, void *buf, size_t len)
{
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
    size_t pos = 0;

    while (len) {
        void *dst = advance(buf, pos);
        snd_pcm_sframes_t nread;

        nread = snd_pcm_readi(alsa->handle, dst, len >> hw->info.shift);

        if (nread <= 0) {
            switch (nread) {
            case 0:
                trace_alsa_read_zero(len);
                return pos;;

            case -EPIPE:
                if (alsa_recover(alsa->handle)) {
                    alsa_logerr(nread, "Failed to read %zu frames\n", len);
                    return pos;
                }
                trace_alsa_xrun_in();
                continue;

            case -EAGAIN:
                return pos;

            default:
                alsa_logerr(nread, "Failed to read %zu frames to %p\n",
                            len, dst);
                return pos;;
            }
        }

        pos += nread << hw->info.shift;
        len -= nread << hw->info.shift;
    }

    return pos;
}

static void alsa_enable_in(HWVoiceIn *hw, bool enable)
{
    ALSAVoiceIn *alsa = (ALSAVoiceIn *) hw;
    AudiodevAlsaPerDirectionOptions *apdo = alsa->dev->u.alsa.in;

    if (enable) {
        bool poll_mode = apdo->try_poll;

        ldebug("enabling voice\n");
        if (poll_mode && alsa_poll_in(hw)) {
            poll_mode = 0;
        }
        hw->poll_mode = poll_mode;

        alsa_voice_ctl(alsa->handle, "capture", VOICE_CTL_START);
    } else {
        ldebug ("disabling voice\n");
        if (hw->poll_mode) {
            hw->poll_mode = 0;
            alsa_fini_poll(&alsa->pollhlp);
        }
        alsa_voice_ctl(alsa->handle, "capture", VOICE_CTL_PAUSE);
    }
}

static void alsa_init_per_direction(AudiodevAlsaPerDirectionOptions *apdo)
{
    if (!apdo->has_try_poll) {
        apdo->try_poll = true;
        apdo->has_try_poll = true;
    }
}

static void *alsa_audio_init(Audiodev *dev)
{
    AudiodevAlsaOptions *aopts;
    assert(dev->driver == AUDIODEV_DRIVER_ALSA);

    aopts = &dev->u.alsa;
    alsa_init_per_direction(aopts->in);
    alsa_init_per_direction(aopts->out);

    /*
     * need to define them, as otherwise alsa produces no sound
     * doesn't set has_* so alsa_open can identify it wasn't set by the user
     */
    if (!dev->u.alsa.out->has_period_length) {
        /* 1024 frames assuming 44100Hz */
        dev->u.alsa.out->period_length = 1024 * 1000000 / 44100;
    }
    if (!dev->u.alsa.out->has_buffer_length) {
        /* 4096 frames assuming 44100Hz */
        dev->u.alsa.out->buffer_length = 4096ll * 1000000 / 44100;
    }

    /*
     * OptsVisitor sets unspecified optional fields to zero, but do not depend
     * on it...
     */
    if (!dev->u.alsa.in->has_period_length) {
        dev->u.alsa.in->period_length = 0;
    }
    if (!dev->u.alsa.in->has_buffer_length) {
        dev->u.alsa.in->buffer_length = 0;
    }

    return dev;
}

static void alsa_audio_fini (void *opaque)
{
}

static struct audio_pcm_ops alsa_pcm_ops = {
    .init_out = alsa_init_out,
    .fini_out = alsa_fini_out,
    .write    = alsa_write,
    .enable_out = alsa_enable_out,

    .init_in  = alsa_init_in,
    .fini_in  = alsa_fini_in,
    .read     = alsa_read,
    .enable_in = alsa_enable_in,
};

static struct audio_driver alsa_audio_driver = {
    .name           = "alsa",
    .descr          = "ALSA http://www.alsa-project.org",
    .init           = alsa_audio_init,
    .fini           = alsa_audio_fini,
    .pcm_ops        = &alsa_pcm_ops,
    .can_be_default = 1,
    .max_voices_out = INT_MAX,
    .max_voices_in  = INT_MAX,
    .voice_size_out = sizeof (ALSAVoiceOut),
    .voice_size_in  = sizeof (ALSAVoiceIn)
};

static void register_audio_alsa(void)
{
    audio_driver_register(&alsa_audio_driver);
}
type_init(register_audio_alsa);
