/*
 * QEMU Audio subsystem
 * 
 * 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.
 */
#include <assert.h>
#include "vl.h"

#define USE_WAV_AUDIO

#include "audio/audio_int.h"

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

#define QC_AUDIO_DRV    "QEMU_AUDIO_DRV"
#define QC_VOICES       "QEMU_VOICES"
#define QC_FIXED_FORMAT "QEMU_FIXED_FORMAT"
#define QC_FIXED_FREQ   "QEMU_FIXED_FREQ"

static HWVoice *hw_voices;

AudioState audio_state = {
    1,                          /* use fixed settings */
    44100,                      /* fixed frequency */
    2,                          /* fixed channels */
    AUD_FMT_S16,                /* fixed format */
    1,                          /* number of hw voices */
    -1                          /* voice size */
};

/* http://www.df.lth.se/~john_e/gems/gem002d.html */
/* http://www.multi-platforms.com/Tips/PopCount.htm */
uint32_t popcount (uint32_t u)
{
    u = ((u&0x55555555) + ((u>>1)&0x55555555));
    u = ((u&0x33333333) + ((u>>2)&0x33333333));
    u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
    u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
    u = ( u&0x0000ffff) + (u>>16);
    return u;
}

inline uint32_t lsbindex (uint32_t u)
{
    return popcount ((u&-u)-1);
}

int audio_get_conf_int (const char *key, int defval)
{
    int val = defval;
    char *strval;

    strval = getenv (key);
    if (strval) {
        val = atoi (strval);
    }

    return val;
}

const char *audio_get_conf_str (const char *key, const char *defval)
{
    const char *val = getenv (key);
    if (!val)
        return defval;
    else
        return val;
}

void AUD_log (const char *cap, const char *fmt, ...)
{
    va_list ap;
    fprintf (stderr, "%s: ", cap);
    va_start (ap, fmt);
    vfprintf (stderr, fmt, ap);
    va_end (ap);
}

/*
 * Soft Voice
 */
void pcm_sw_free_resources (SWVoice *sw)
{
    if (sw->buf) qemu_free (sw->buf);
    if (sw->rate) st_rate_stop (sw->rate);
    sw->buf = NULL;
    sw->rate = NULL;
}

int pcm_sw_alloc_resources (SWVoice *sw)
{
    sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
    if (!sw->buf)
        return -1;

    sw->rate = st_rate_start (sw->freq, sw->hw->freq);
    if (!sw->rate) {
        qemu_free (sw->buf);
        sw->buf = NULL;
        return -1;
    }
    return 0;
}

void pcm_sw_fini (SWVoice *sw)
{
    pcm_sw_free_resources (sw);
}

int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
                 int nchannels, audfmt_e fmt)
{
    int bits = 8, sign = 0;

    switch (fmt) {
    case AUD_FMT_S8:
        sign = 1;
    case AUD_FMT_U8:
        break;

    case AUD_FMT_S16:
        sign = 1;
    case AUD_FMT_U16:
        bits = 16;
        break;
    }

    sw->hw = hw;
    sw->freq = freq;
    sw->fmt = fmt;
    sw->nchannels = nchannels;
    sw->shift = (nchannels == 2) + (bits == 16);
    sw->align = (1 << sw->shift) - 1;
    sw->left = 0;
    sw->pos = 0;
    sw->wpos = 0;
    sw->live = 0;
    sw->ratio = (sw->hw->freq * ((int64_t) INT_MAX)) / sw->freq;
    sw->bytes_per_second = sw->freq << sw->shift;
    sw->conv = mixeng_conv[nchannels == 2][sign][bits == 16];

    pcm_sw_free_resources (sw);
    return pcm_sw_alloc_resources (sw);
}

/* Hard voice */
void pcm_hw_free_resources (HWVoice *hw)
{
    if (hw->mix_buf)
        qemu_free (hw->mix_buf);
    hw->mix_buf = NULL;
}

int pcm_hw_alloc_resources (HWVoice *hw)
{
    hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
    if (!hw->mix_buf)
        return -1;
    return 0;
}

void pcm_hw_fini (HWVoice *hw)
{
    if (hw->active) {
        ldebug ("pcm_hw_fini: %d %d %d\n", hw->freq, hw->nchannels, hw->fmt);
        pcm_hw_free_resources (hw);
        hw->pcm_ops->fini (hw);
        memset (hw, 0, audio_state.drv->voice_size);
    }
}

void pcm_hw_gc (HWVoice *hw)
{
    if (hw->nb_voices)
        return;

    pcm_hw_fini (hw);
}

int pcm_hw_get_live (HWVoice *hw)
{
    int i, alive = 0, live = hw->samples;

    for (i = 0; i < hw->nb_voices; i++) {
        if (hw->pvoice[i]->live) {
            live = audio_MIN (hw->pvoice[i]->live, live);
            alive += 1;
        }
    }

    if (alive)
        return live;
    else
        return -1;
}

int pcm_hw_get_live2 (HWVoice *hw, int *nb_active)
{
    int i, alive = 0, live = hw->samples;

    *nb_active = 0;
    for (i = 0; i < hw->nb_voices; i++) {
        if (hw->pvoice[i]->live) {
            if (hw->pvoice[i]->live < live) {
                *nb_active = hw->pvoice[i]->active != 0;
                live = hw->pvoice[i]->live;
            }
            alive += 1;
        }
    }

    if (alive)
        return live;
    else
        return -1;
}

void pcm_hw_dec_live (HWVoice *hw, int decr)
{
    int i;

    for (i = 0; i < hw->nb_voices; i++) {
        if (hw->pvoice[i]->live) {
            hw->pvoice[i]->live -= decr;
        }
    }
}

void pcm_hw_clear (HWVoice *hw, void *buf, int len)
{
    if (!len)
        return;

    switch (hw->fmt) {
    case AUD_FMT_S16:
    case AUD_FMT_S8:
        memset (buf, len << hw->shift, 0x00);
        break;

    case AUD_FMT_U8:
        memset (buf, len << hw->shift, 0x80);
        break;

    case AUD_FMT_U16:
        {
            unsigned int i;
            uint16_t *p = buf;
            int shift = hw->nchannels - 1;

            for (i = 0; i < len << shift; i++) {
                p[i] = INT16_MAX;
            }
        }
        break;
    }
}

int pcm_hw_write (SWVoice *sw, void *buf, int size)
{
    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
    int ret = 0, pos = 0;
    if (!sw)
        return size;

    hwsamples = sw->hw->samples;
    samples = size >> sw->shift;

    if (!sw->live) {
        sw->wpos = sw->hw->rpos;
    }
    wpos = sw->wpos;
    live = sw->live;
    dead = hwsamples - live;
    swlim = (dead * ((int64_t) INT_MAX)) / sw->ratio;
    swlim = audio_MIN (swlim, samples);

    ldebug ("size=%d live=%d dead=%d swlim=%d wpos=%d\n",
           size, live, dead, swlim, wpos);
    if (swlim)
        sw->conv (sw->buf, buf, swlim);

    while (swlim) {
        dead = hwsamples - live;
        left = hwsamples - wpos;
        blck = audio_MIN (dead, left);
        if (!blck) {
            /* dolog ("swlim=%d\n", swlim); */
            break;
        }
        isamp = swlim;
        osamp = blck;
        st_rate_flow (sw->rate, sw->buf + pos, sw->hw->mix_buf + wpos, &isamp, &osamp);
        ret += isamp;
        swlim -= isamp;
        pos += isamp;
        live += osamp;
        wpos = (wpos + osamp) % hwsamples;
    }

    sw->wpos = wpos;
    sw->live = live;
    return ret << sw->shift;
}

int pcm_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
{
    int sign = 0, bits = 8;

    pcm_hw_fini (hw);
    ldebug ("pcm_hw_init: %d %d %d\n", freq, nchannels, fmt);
    if (hw->pcm_ops->init (hw, freq, nchannels, fmt)) {
        memset (hw, 0, audio_state.drv->voice_size);
        return -1;
    }

    switch (hw->fmt) {
    case AUD_FMT_S8:
        sign = 1;
    case AUD_FMT_U8:
        break;

    case AUD_FMT_S16:
        sign = 1;
    case AUD_FMT_U16:
        bits = 16;
        break;
    }

    hw->nb_voices = 0;
    hw->active = 1;
    hw->shift = (hw->nchannels == 2) + (bits == 16);
    hw->bytes_per_second = hw->freq << hw->shift;
    hw->align = (1 << hw->shift) - 1;
    hw->samples = hw->bufsize >> hw->shift;
    hw->clip = mixeng_clip[hw->nchannels == 2][sign][bits == 16];
    if (pcm_hw_alloc_resources (hw)) {
        pcm_hw_fini (hw);
        return -1;
    }
    return 0;
}

static int dist (void *hw)
{
    if (hw) {
        return (((uint8_t *) hw - (uint8_t *) hw_voices)
                / audio_state.drv->voice_size) + 1;
    }
    else {
        return 0;
    }
}

#define ADVANCE(hw) \
    ((hw) ? advance (hw, audio_state.drv->voice_size) : hw_voices)

HWVoice *pcm_hw_find_any (HWVoice *hw)
{
    int i = dist (hw);
    for (; i < audio_state.nb_hw_voices; i++) {
        hw = ADVANCE (hw);
        return hw;
    }
    return NULL;
}

HWVoice *pcm_hw_find_any_active (HWVoice *hw)
{
    int i = dist (hw);
    for (; i < audio_state.nb_hw_voices; i++) {
        hw = ADVANCE (hw);
        if (hw->active)
            return hw;
    }
    return NULL;
}

HWVoice *pcm_hw_find_any_active_enabled (HWVoice *hw)
{
    int i = dist (hw);
    for (; i < audio_state.nb_hw_voices; i++) {
        hw = ADVANCE (hw);
        if (hw->active && hw->enabled)
            return hw;
    }
    return NULL;
}

HWVoice *pcm_hw_find_any_passive (HWVoice *hw)
{
    int i = dist (hw);
    for (; i < audio_state.nb_hw_voices; i++) {
        hw = ADVANCE (hw);
        if (!hw->active)
            return hw;
    }
    return NULL;
}

HWVoice *pcm_hw_find_specific (HWVoice *hw, int freq,
                               int nchannels, audfmt_e fmt)
{
    while ((hw = pcm_hw_find_any_active (hw))) {
        if (hw->freq == freq &&
            hw->nchannels == nchannels &&
            hw->fmt == fmt)
            return hw;
    }
    return NULL;
}

HWVoice *pcm_hw_add (int freq, int nchannels, audfmt_e fmt)
{
    HWVoice *hw;

    if (audio_state.fixed_format) {
        freq = audio_state.fixed_freq;
        nchannels = audio_state.fixed_channels;
        fmt = audio_state.fixed_fmt;
    }

    hw = pcm_hw_find_specific (NULL, freq, nchannels, fmt);

    if (hw)
        return hw;

    hw = pcm_hw_find_any_passive (NULL);
    if (hw) {
        hw->pcm_ops = audio_state.drv->pcm_ops;
        if (!hw->pcm_ops)
            return NULL;

        if (pcm_hw_init (hw, freq, nchannels, fmt)) {
            pcm_hw_gc (hw);
            return NULL;
        }
        else
            return hw;
    }

    return pcm_hw_find_any (NULL);
}

int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw)
{
    SWVoice **pvoice = qemu_mallocz ((hw->nb_voices + 1) * sizeof (sw));
    if (!pvoice)
        return -1;

    memcpy (pvoice, hw->pvoice, hw->nb_voices * sizeof (sw));
    qemu_free (hw->pvoice);
    hw->pvoice = pvoice;
    hw->pvoice[hw->nb_voices++] = sw;
    return 0;
}

int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw)
{
    int i, j;
    if (hw->nb_voices > 1) {
        SWVoice **pvoice = qemu_mallocz ((hw->nb_voices - 1) * sizeof (sw));

        if (!pvoice) {
            dolog ("Can not maintain consistent state (not enough memory)\n");
            return -1;
        }

        for (i = 0, j = 0; i < hw->nb_voices; i++) {
            if (j >= hw->nb_voices - 1) {
                dolog ("Can not maintain consistent state "
                       "(invariant violated)\n");
                return -1;
            }
            if (hw->pvoice[i] != sw)
                pvoice[j++] = hw->pvoice[i];
        }
        qemu_free (hw->pvoice);
        hw->pvoice = pvoice;
        hw->nb_voices -= 1;
    }
    else {
        qemu_free (hw->pvoice);
        hw->pvoice = NULL;
        hw->nb_voices = 0;
    }
    return 0;
}

SWVoice *pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt)
{
    SWVoice *sw;
    HWVoice *hw;

    sw = qemu_mallocz (sizeof (*sw));
    if (!sw)
        goto err1;

    hw = pcm_hw_add (freq, nchannels, fmt);
    if (!hw)
        goto err2;

    if (pcm_hw_add_sw (hw, sw))
        goto err3;

    if (pcm_sw_init (sw, hw, freq, nchannels, fmt))
        goto err4;

    return sw;

err4:
    pcm_hw_del_sw (hw, sw);
err3:
    pcm_hw_gc (hw);
err2:
    qemu_free (sw);
err1:
    return NULL;
}

SWVoice *AUD_open (SWVoice *sw, const char *name,
                   int freq, int nchannels, audfmt_e fmt)
{
    if (!audio_state.drv) {
        return NULL;
    }

    if (sw && freq == sw->freq && sw->nchannels == nchannels && sw->fmt == fmt) {
        return sw;
    }

    if (sw) {
        ldebug ("Different format %s %d %d %d\n",
                name,
                sw->freq == freq,
                sw->nchannels == nchannels,
                sw->fmt == fmt);
    }

    if (nchannels != 1 && nchannels != 2) {
        dolog ("Bogus channel count %d for voice %s\n", nchannels, name);
        return NULL;
    }

    if (!audio_state.fixed_format && sw) {
        pcm_sw_fini (sw);
        pcm_hw_del_sw (sw->hw, sw);
        pcm_hw_gc (sw->hw);
        if (sw->name) {
            qemu_free (sw->name);
            sw->name = NULL;
        }
        qemu_free (sw);
        sw = NULL;
    }

    if (sw) {
        HWVoice *hw = sw->hw;
        if (!hw) {
            dolog ("Internal logic error voice %s has no hardware store\n",
                   name);
            return sw;
        }

        if (pcm_sw_init (sw, hw, freq, nchannels, fmt)) {
            pcm_sw_fini (sw);
            pcm_hw_del_sw (hw, sw);
            pcm_hw_gc (hw);
            if (sw->name) {
                qemu_free (sw->name);
                sw->name = NULL;
            }
            qemu_free (sw);
            return NULL;
        }
    }
    else {
        sw = pcm_create_voice_pair (freq, nchannels, fmt);
        if (!sw) {
            dolog ("Failed to create voice %s\n", name);
            return NULL;
        }
    }

    if (sw->name) {
        qemu_free (sw->name);
        sw->name = NULL;
    }
    sw->name = qemu_strdup (name);
    return sw;
}

void AUD_close (SWVoice *sw)
{
    if (!sw)
        return;

    pcm_sw_fini (sw);
    pcm_hw_del_sw (sw->hw, sw);
    pcm_hw_gc (sw->hw);
    if (sw->name) {
        qemu_free (sw->name);
        sw->name = NULL;
    }
    qemu_free (sw);
}

int AUD_write (SWVoice *sw, void *buf, int size)
{
    int bytes;

    if (!sw->hw->enabled)
        dolog ("Writing to disabled voice %s\n", sw->name);
    bytes = sw->hw->pcm_ops->write (sw, buf, size);
    return bytes;
}

void AUD_run (void)
{
    HWVoice *hw = NULL;

    while ((hw = pcm_hw_find_any_active_enabled (hw))) {
        int i;
        if (hw->pending_disable && pcm_hw_get_live (hw) <= 0) {
            hw->enabled = 0;
            hw->pcm_ops->ctl (hw, VOICE_DISABLE);
            for (i = 0; i < hw->nb_voices; i++) {
                hw->pvoice[i]->live = 0;
                /* hw->pvoice[i]->old_ticks = 0; */
            }
            continue;
        }

        hw->pcm_ops->run (hw);
        assert (hw->rpos < hw->samples);
        for (i = 0; i < hw->nb_voices; i++) {
            SWVoice *sw = hw->pvoice[i];
            if (!sw->active && !sw->live && sw->old_ticks) {
                int64_t delta = qemu_get_clock (vm_clock) - sw->old_ticks;
                if (delta > audio_state.ticks_threshold) {
                    ldebug ("resetting old_ticks for %s\n", sw->name);
                    sw->old_ticks = 0;
                }
            }
        }
    }
}

int AUD_get_free (SWVoice *sw)
{
    int free;

    if (!sw)
        return 4096;

    free = ((sw->hw->samples - sw->live) << sw->hw->shift) * sw->ratio
        / INT_MAX;

    free &= ~sw->hw->align;
    if (!free) return 0;

    return free;
}

int AUD_get_buffer_size (SWVoice *sw)
{
    return sw->hw->bufsize;
}

void AUD_adjust (SWVoice *sw, int bytes)
{
    if (!sw)
        return;
    sw->old_ticks += (ticks_per_sec * (int64_t) bytes) / sw->bytes_per_second;
}

void AUD_reset (SWVoice *sw)
{
    sw->active = 0;
    sw->old_ticks = 0;
}

int AUD_calc_elapsed (SWVoice *sw)
{
    int64_t now, delta, bytes;
    int dead, swlim;

    if (!sw)
        return 0;

    now = qemu_get_clock (vm_clock);
    delta = now - sw->old_ticks;
    bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
    if (delta < 0) {
        dolog ("whoops delta(<0)=%lld\n", delta);
        return 0;
    }

    dead = sw->hw->samples - sw->live;
    swlim = ((dead * (int64_t) INT_MAX) / sw->ratio);

    if (bytes > swlim) {
        return swlim;
    }
    else {
        return bytes;
    }
}

void AUD_enable (SWVoice *sw, int on)
{
    int i;
    HWVoice *hw;

    if (!sw)
        return;

    hw = sw->hw;
    if (on) {
        if (!sw->live)
            sw->wpos = sw->hw->rpos;
        if (!sw->old_ticks) {
            sw->old_ticks = qemu_get_clock (vm_clock);
        }
    }

    if (sw->active != on) {
        if (on) {
            hw->pending_disable = 0;
            if (!hw->enabled) {
                hw->enabled = 1;
                for (i = 0; i < hw->nb_voices; i++) {
                    ldebug ("resetting voice\n");
                    sw = hw->pvoice[i];
                    sw->old_ticks = qemu_get_clock (vm_clock);
                }
                hw->pcm_ops->ctl (hw, VOICE_ENABLE);
            }
        }
        else {
            if (hw->enabled && !hw->pending_disable) {
                int nb_active = 0;
                for (i = 0; i < hw->nb_voices; i++) {
                    nb_active += hw->pvoice[i]->active != 0;
                }

                if (nb_active == 1) {
                    hw->pending_disable = 1;
                }
            }
        }
        sw->active = on;
    }
}

static struct audio_output_driver *drvtab[] = {
#ifdef CONFIG_OSS
    &oss_output_driver,
#endif
#ifdef CONFIG_FMOD
    &fmod_output_driver,
#endif
#ifdef CONFIG_SDL
    &sdl_output_driver,
#endif
    &no_output_driver,
#ifdef USE_WAV_AUDIO
    &wav_output_driver,
#endif
};

static int voice_init (struct audio_output_driver *drv)
{
    audio_state.opaque = drv->init ();
    if (audio_state.opaque) {
        if (audio_state.nb_hw_voices > drv->max_voices) {
            dolog ("`%s' does not support %d multiple hardware channels\n"
                   "Resetting to %d\n",
                   drv->name, audio_state.nb_hw_voices, drv->max_voices);
            audio_state.nb_hw_voices = drv->max_voices;
        }
        hw_voices = qemu_mallocz (audio_state.nb_hw_voices * drv->voice_size);
        if (hw_voices) {
            audio_state.drv = drv;
            return 1;
        }
        else {
            dolog ("Not enough memory for %d `%s' voices (each %d bytes)\n",
                   audio_state.nb_hw_voices, drv->name, drv->voice_size);
            drv->fini (audio_state.opaque);
            return 0;
        }
    }
    else {
        dolog ("Could not init `%s' audio\n", drv->name);
        return 0;
    }
}

static void audio_vm_stop_handler (void *opaque, int reason)
{
    HWVoice *hw = NULL;

    while ((hw = pcm_hw_find_any (hw))) {
        if (!hw->pcm_ops)
            continue;

        hw->pcm_ops->ctl (hw, reason ? VOICE_ENABLE : VOICE_DISABLE);
    }
}

static void audio_atexit (void)
{
    HWVoice *hw = NULL;

    while ((hw = pcm_hw_find_any (hw))) {
        if (!hw->pcm_ops)
            continue;

        hw->pcm_ops->ctl (hw, VOICE_DISABLE);
        hw->pcm_ops->fini (hw);
    }
    audio_state.drv->fini (audio_state.opaque);
}

static void audio_save (QEMUFile *f, void *opaque)
{
}

static int audio_load (QEMUFile *f, void *opaque, int version_id)
{
    if (version_id != 1)
        return -EINVAL;

    return 0;
}

void AUD_init (void)
{
    int i;
    int done = 0;
    const char *drvname;

    audio_state.fixed_format =
        !!audio_get_conf_int (QC_FIXED_FORMAT, audio_state.fixed_format);
    audio_state.fixed_freq =
        audio_get_conf_int (QC_FIXED_FREQ, audio_state.fixed_freq);
    audio_state.nb_hw_voices =
        audio_get_conf_int (QC_VOICES, audio_state.nb_hw_voices);

    if (audio_state.nb_hw_voices <= 0) {
        dolog ("Bogus number of voices %d, resetting to 1\n",
               audio_state.nb_hw_voices);
    }

    drvname = audio_get_conf_str (QC_AUDIO_DRV, NULL);
    if (drvname) {
        int found = 0;
        for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
            if (!strcmp (drvname, drvtab[i]->name)) {
                done = voice_init (drvtab[i]);
                found = 1;
                break;
            }
        }
        if (!found) {
            dolog ("Unknown audio driver `%s'\n", drvname);
        }
    }

    qemu_add_vm_stop_handler (audio_vm_stop_handler, NULL);
    atexit (audio_atexit);

    if (!done) {
        for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
            if (drvtab[i]->can_be_default)
                done = voice_init (drvtab[i]);
        }
    }

    audio_state.ticks_threshold = ticks_per_sec / 50;
    audio_state.freq_threshold = 100;

    register_savevm ("audio", 0, 1, audio_save, audio_load, NULL);
    if (!done) {
        dolog ("Can not initialize audio subsystem\n");
        voice_init (&no_output_driver);
    }
}
