⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    switch (as->fmt) {    case AUD_FMT_S8:        AUD_log (NULL, "S8");        break;    case AUD_FMT_U8:        AUD_log (NULL, "U8");        break;    case AUD_FMT_S16:        AUD_log (NULL, "S16");        break;    case AUD_FMT_U16:        AUD_log (NULL, "U16");        break;    default:        AUD_log (NULL, "invalid(%d)", as->fmt);        break;    }    AUD_log (NULL, "\n");}static int audio_validate_settigs (audsettings_t *as){    int invalid;    invalid = as->nchannels != 1 && as->nchannels != 2;    switch (as->fmt) {    case AUD_FMT_S8:    case AUD_FMT_U8:    case AUD_FMT_S16:    case AUD_FMT_U16:        break;    default:        invalid = 1;        break;    }    invalid |= as->freq <= 0;    if (invalid) {        return -1;    }    return 0;}static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as){    int bits = 8, sign = 0;    switch (as->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;    }    return info->freq == as->freq        && info->nchannels == as->nchannels        && info->sign == sign        && info->bits == bits;}void audio_pcm_init_info (    struct audio_pcm_info *info,    audsettings_t *as,    int swap_endian    ){    int bits = 8, sign = 0;    switch (as->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;    }    info->freq = as->freq;    info->bits = bits;    info->sign = sign;    info->nchannels = as->nchannels;    info->shift = (as->nchannels == 2) + (bits == 16);    info->align = (1 << info->shift) - 1;    info->bytes_per_second = info->freq << info->shift;    info->swap_endian = swap_endian;}void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len){    if (!len) {        return;    }    if (info->sign) {        memset (buf, len << info->shift, 0x00);    }    else {        if (info->bits == 8) {            memset (buf, len << info->shift, 0x80);        }        else {            int i;            uint16_t *p = buf;            int shift = info->nchannels - 1;            short s = INT16_MAX;            if (info->swap_endian) {                s = bswap16 (s);            }            for (i = 0; i < len << shift; i++) {                p[i] = s;            }        }    }}/* * Hard voice (capture) */static int audio_pcm_hw_find_min_in (HWVoiceIn *hw){    SWVoiceIn *sw;    int m = hw->total_samples_captured;    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {        if (sw->active) {            m = audio_MIN (m, sw->total_hw_samples_acquired);        }    }    return m;}int audio_pcm_hw_get_live_in (HWVoiceIn *hw){    int live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {        dolog ("live=%d hw->samples=%d\n", live, hw->samples);        return 0;    }    return live;}/* * Soft voice (capture) */static int audio_pcm_sw_get_rpos_in (SWVoiceIn *sw){    HWVoiceIn *hw = sw->hw;    int live = hw->total_samples_captured - sw->total_hw_samples_acquired;    int rpos;    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {        dolog ("live=%d hw->samples=%d\n", live, hw->samples);        return 0;    }    rpos = hw->wpos - live;    if (rpos >= 0) {        return rpos;    }    else {        return hw->samples + rpos;    }}int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size){    HWVoiceIn *hw = sw->hw;    int samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;    st_sample_t *src, *dst = sw->buf;    rpos = audio_pcm_sw_get_rpos_in (sw) % hw->samples;    live = hw->total_samples_captured - sw->total_hw_samples_acquired;    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {        dolog ("live_in=%d hw->samples=%d\n", live, hw->samples);        return 0;    }    samples = size >> sw->info.shift;    if (!live) {        return 0;    }    swlim = (live * sw->ratio) >> 32;    swlim = audio_MIN (swlim, samples);    while (swlim) {        src = hw->conv_buf + rpos;        isamp = hw->wpos - rpos;        /* XXX: <= ? */        if (isamp <= 0) {            isamp = hw->samples - rpos;        }        if (!isamp) {            break;        }        osamp = swlim;        if (audio_bug (AUDIO_FUNC, osamp < 0)) {            dolog ("osamp=%d\n", osamp);            return 0;        }        st_rate_flow (sw->rate, src, dst, &isamp, &osamp);        swlim -= osamp;        rpos = (rpos + isamp) % hw->samples;        dst += osamp;        ret += osamp;        total += isamp;    }    sw->clip (buf, sw->buf, ret);    sw->total_hw_samples_acquired += total;    return ret << sw->info.shift;}/* * Hard voice (playback) */static int audio_pcm_hw_find_min_out (HWVoiceOut *hw, int *nb_livep){    SWVoiceOut *sw;    int m = INT_MAX;    int nb_live = 0;    for (sw = hw->sw_head.lh_first; sw; sw = sw->entries.le_next) {        if (sw->active || !sw->empty) {            m = audio_MIN (m, sw->total_hw_samples_mixed);            nb_live += 1;        }    }    *nb_livep = nb_live;    return m;}int audio_pcm_hw_get_live_out2 (HWVoiceOut *hw, int *nb_live){    int smin;    smin = audio_pcm_hw_find_min_out (hw, nb_live);    if (!*nb_live) {        return 0;    }    else {        int live = smin;        if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {            dolog ("live=%d hw->samples=%d\n", live, hw->samples);            return 0;        }        return live;    }}int audio_pcm_hw_get_live_out (HWVoiceOut *hw){    int nb_live;    int live;    live = audio_pcm_hw_get_live_out2 (hw, &nb_live);    if (audio_bug (AUDIO_FUNC, live < 0 || live > hw->samples)) {        dolog ("live=%d hw->samples=%d\n", live, hw->samples);        return 0;    }    return live;}/* * Soft voice (playback) */int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int size){    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;    int ret = 0, pos = 0, total = 0;    if (!sw) {        return size;    }    hwsamples = sw->hw->samples;    live = sw->total_hw_samples_mixed;    if (audio_bug (AUDIO_FUNC, live < 0 || live > hwsamples)){        dolog ("live=%d hw->samples=%d\n", live, hwsamples);        return 0;    }    if (live == hwsamples) {        return 0;    }    wpos = (sw->hw->rpos + live) % hwsamples;    samples = size >> sw->info.shift;    dead = hwsamples - live;    swlim = ((int64_t) dead << 32) / sw->ratio;    swlim = audio_MIN (swlim, samples);    if (swlim) {        sw->conv (sw->buf, buf, swlim, &sw->vol);    }    while (swlim) {        dead = hwsamples - live;        left = hwsamples - wpos;        blck = audio_MIN (dead, left);        if (!blck) {            break;        }        isamp = swlim;        osamp = blck;        st_rate_flow_mix (            sw->rate,            sw->buf + pos,            sw->hw->mix_buf + wpos,            &isamp,            &osamp            );        ret += isamp;        swlim -= isamp;        pos += isamp;        live += osamp;        wpos = (wpos + osamp) % hwsamples;        total += osamp;    }    sw->total_hw_samples_mixed += total;    sw->empty = sw->total_hw_samples_mixed == 0;#ifdef DEBUG_OUT    dolog (        "%s: write size %d ret %d total sw %d\n",        SW_NAME (sw),        size >> sw->info.shift,        ret,        sw->total_hw_samples_mixed        );#endif    return ret << sw->info.shift;}#ifdef DEBUG_AUDIOstatic void audio_pcm_print_info (const char *cap, struct audio_pcm_info *info){    dolog ("%s: bits %d, sign %d, freq %d, nchan %d\n",           cap, info->bits, info->sign, info->freq, info->nchannels);}#endif#define DAC#include "audio_template.h"#undef DAC#include "audio_template.h"int AUD_write (SWVoiceOut *sw, void *buf, int size){    int bytes;    if (!sw) {        /* XXX: Consider options */        return size;    }    if (!sw->hw->enabled) {        dolog ("Writing to disabled voice %s\n", SW_NAME (sw));        return 0;    }    bytes = sw->hw->pcm_ops->write (sw, buf, size);    return bytes;}int AUD_read (SWVoiceIn *sw, void *buf, int size){    int bytes;    if (!sw) {        /* XXX: Consider options */        return size;    }    if (!sw->hw->enabled) {        dolog ("Reading from disabled voice %s\n", SW_NAME (sw));        return 0;    }    bytes = sw->hw->pcm_ops->read (sw, buf, size);    return bytes;}int AUD_get_buffer_size_out (SWVoiceOut *sw){    return sw->hw->samples << sw->hw->info.shift;}void AUD_set_active_out (SWVoiceOut *sw, int on){    HWVoiceOut *hw;    if (!sw) {        return;    }    hw = sw->hw;    if (sw->active != on) {        SWVoiceOut *temp_sw;        if (on) {            int total;            hw->pending_disable = 0;            if (!hw->enabled) {                hw->enabled = 1;                hw->pcm_ops->ctl_out (hw, VOICE_ENABLE);            }            if (sw->empty) {                total = 0;            }        }        else {            if (hw->enabled) {                int nb_active = 0;                for (temp_sw = hw->sw_head.lh_first; temp_sw;                     temp_sw = temp_sw->entries.le_next) {                    nb_active += temp_sw->active != 0;                }                hw->pending_disable = nb_active == 1;            }        }        sw->active = on;    }}void AUD_set_active_in (SWVoiceIn *sw, int on){    HWVoiceIn *hw;    if (!sw) {        return;    }    hw = sw->hw;    if (sw->active != on) {        SWVoiceIn *temp_sw;        if (on) {            if (!hw->enabled) {                hw->enabled = 1;                hw->pcm_ops->ctl_in (hw, VOICE_ENABLE);            }            sw->total_hw_samples_acquired = hw->total_samples_captured;        }        else {            if (hw->enabled) {                int nb_active = 0;                for (temp_sw = hw->sw_head.lh_first; temp_sw;                     temp_sw = temp_sw->entries.le_next) {                    nb_active += temp_sw->active != 0;                }                if (nb_active == 1) {                    hw->enabled = 0;                    hw->pcm_ops->ctl_in (hw, VOICE_DISABLE);                }            }        }        sw->active = on;    }}static int audio_get_avail (SWVoiceIn *sw){    int live;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -