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

📄 audio.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * QEMU Audio subsystem * * Copyright (c) 2003-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 "vl.h"#define AUDIO_CAP "audio"#include "audio_int.h"/* #define DEBUG_PLIVE *//* #define DEBUG_LIVE *//* #define DEBUG_OUT *//* #define DEBUG_CAPTURE */#define SW_NAME(sw) (sw)->name ? (sw)->name : "unknown"static struct audio_driver *drvtab[] = {#ifdef CONFIG_OSS    &oss_audio_driver,#endif#ifdef CONFIG_ALSA    &alsa_audio_driver,#endif#ifdef CONFIG_COREAUDIO    &coreaudio_audio_driver,#endif#ifdef CONFIG_DSOUND    &dsound_audio_driver,#endif#ifdef CONFIG_FMOD    &fmod_audio_driver,#endif#ifdef CONFIG_SDL    &sdl_audio_driver,#endif    &no_audio_driver,    &wav_audio_driver};struct fixed_settings {    int enabled;    int nb_voices;    int greedy;    audsettings_t settings;};static struct {    struct fixed_settings fixed_out;    struct fixed_settings fixed_in;    union {        int hz;        int64_t ticks;    } period;    int plive;    int log_to_monitor;} conf = {    {                           /* DAC fixed settings */        1,                      /* enabled */        1,                      /* nb_voices */        1,                      /* greedy */        {            44100,              /* freq */            2,                  /* nchannels */            AUD_FMT_S16         /* fmt */        }    },    {                           /* ADC fixed settings */        1,                      /* enabled */        1,                      /* nb_voices */        1,                      /* greedy */        {            44100,              /* freq */            2,                  /* nchannels */            AUD_FMT_S16         /* fmt */        }    },    { 0 },                      /* period */    0,                          /* plive */    0                           /* log_to_monitor */};static AudioState glob_audio_state;volume_t nominal_volume = {    0,#ifdef FLOAT_MIXENG    1.0,    1.0#else    UINT_MAX,    UINT_MAX#endif};/* 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);}#ifdef AUDIO_IS_FLAWLESS_AND_NO_CHECKS_ARE_REQURIED#error No its not#elseint audio_bug (const char *funcname, int cond){    if (cond) {        static int shown;        AUD_log (NULL, "A bug was just triggered in %s\n", funcname);        if (!shown) {            shown = 1;            AUD_log (NULL, "Save all your work and restart without audio\n");            AUD_log (NULL, "Please send bug report to malc@pulsesoft.com\n");            AUD_log (NULL, "I am sorry\n");        }        AUD_log (NULL, "Context:\n");#if defined AUDIO_BREAKPOINT_ON_BUG#  if defined HOST_I386#    if defined __GNUC__        __asm__ ("int3");#    elif defined _MSC_VER        _asm _emit 0xcc;#    else        abort ();#    endif#  else        abort ();#  endif#endif    }    return cond;}#endifvoid *audio_calloc (const char *funcname, int nmemb, size_t size){    int cond;    size_t len;    len = nmemb * size;    cond = !nmemb || !size;    cond |= nmemb < 0;    cond |= len < size;    if (audio_bug ("audio_calloc", cond)) {        AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",                 funcname);        AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);        return NULL;    }    return qemu_mallocz (len);}static char *audio_alloc_prefix (const char *s){    const char qemu_prefix[] = "QEMU_";    size_t len;    char *r;    if (!s) {        return NULL;    }    len = strlen (s);    r = qemu_malloc (len + sizeof (qemu_prefix));    if (r) {        size_t i;        char *u = r + sizeof (qemu_prefix) - 1;        strcpy (r, qemu_prefix);        strcat (r, s);        for (i = 0; i < len; ++i) {            u[i] = toupper ((uint8_t)u[i]);        }    }    return r;}const char *audio_audfmt_to_string (audfmt_e fmt){    switch (fmt) {    case AUD_FMT_U8:        return "U8";    case AUD_FMT_U16:        return "U16";    case AUD_FMT_S8:        return "S8";    case AUD_FMT_S16:        return "S16";    }    dolog ("Bogus audfmt %d returning S16\n", fmt);    return "S16";}audfmt_e audio_string_to_audfmt (const char *s, audfmt_e defval, int *defaultp){    if (!strcasecmp (s, "u8")) {        *defaultp = 0;        return AUD_FMT_U8;    }    else if (!strcasecmp (s, "u16")) {        *defaultp = 0;        return AUD_FMT_U16;    }    else if (!strcasecmp (s, "s8")) {        *defaultp = 0;        return AUD_FMT_S8;    }    else if (!strcasecmp (s, "s16")) {        *defaultp = 0;        return AUD_FMT_S16;    }    else {        dolog ("Bogus audio format `%s' using %s\n",               s, audio_audfmt_to_string (defval));        *defaultp = 1;        return defval;    }}static audfmt_e audio_get_conf_fmt (const char *envname,                                    audfmt_e defval,                                    int *defaultp){    const char *var = getenv (envname);    if (!var) {        *defaultp = 1;        return defval;    }    return audio_string_to_audfmt (var, defval, defaultp);}static int audio_get_conf_int (const char *key, int defval, int *defaultp){    int val;    char *strval;    strval = getenv (key);    if (strval) {        *defaultp = 0;        val = atoi (strval);        return val;    }    else {        *defaultp = 1;        return defval;    }}static const char *audio_get_conf_str (const char *key,                                       const char *defval,                                       int *defaultp){    const char *val = getenv (key);    if (!val) {        *defaultp = 1;        return defval;    }    else {        *defaultp = 0;        return val;    }}void AUD_vlog (const char *cap, const char *fmt, va_list ap){    if (conf.log_to_monitor) {        if (cap) {            term_printf ("%s: ", cap);        }        term_vprintf (fmt, ap);    }    else {        if (cap) {            fprintf (stderr, "%s: ", cap);        }        vfprintf (stderr, fmt, ap);    }}void AUD_log (const char *cap, const char *fmt, ...){    va_list ap;    va_start (ap, fmt);    AUD_vlog (cap, fmt, ap);    va_end (ap);}static void audio_print_options (const char *prefix,                                 struct audio_option *opt){    char *uprefix;    if (!prefix) {        dolog ("No prefix specified\n");        return;    }    if (!opt) {        dolog ("No options\n");        return;    }    uprefix = audio_alloc_prefix (prefix);    for (; opt->name; opt++) {        const char *state = "default";        printf ("  %s_%s: ", uprefix, opt->name);        if (opt->overridenp && *opt->overridenp) {            state = "current";        }        switch (opt->tag) {        case AUD_OPT_BOOL:            {                int *intp = opt->valp;                printf ("boolean, %s = %d\n", state, *intp ? 1 : 0);            }            break;        case AUD_OPT_INT:            {                int *intp = opt->valp;                printf ("integer, %s = %d\n", state, *intp);            }            break;        case AUD_OPT_FMT:            {                audfmt_e *fmtp = opt->valp;                printf (                    "format, %s = %s, (one of: U8 S8 U16 S16)\n",                    state,                    audio_audfmt_to_string (*fmtp)                    );            }            break;        case AUD_OPT_STR:            {                const char **strp = opt->valp;                printf ("string, %s = %s\n",                        state,                        *strp ? *strp : "(not set)");            }            break;        default:            printf ("???\n");            dolog ("Bad value tag for option %s_%s %d\n",                   uprefix, opt->name, opt->tag);            break;        }        printf ("    %s\n", opt->descr);    }    qemu_free (uprefix);}static void audio_process_options (const char *prefix,                                   struct audio_option *opt){    char *optname;    const char qemu_prefix[] = "QEMU_";    size_t preflen;    if (audio_bug (AUDIO_FUNC, !prefix)) {        dolog ("prefix = NULL\n");        return;    }    if (audio_bug (AUDIO_FUNC, !opt)) {        dolog ("opt = NULL\n");        return;    }    preflen = strlen (prefix);    for (; opt->name; opt++) {        size_t len, i;        int def;        if (!opt->valp) {            dolog ("Option value pointer for `%s' is not set\n",                   opt->name);            continue;        }        len = strlen (opt->name);        /* len of opt->name + len of prefix + size of qemu_prefix         * (includes trailing zero) + zero + underscore (on behalf of         * sizeof) */        optname = qemu_malloc (len + preflen + sizeof (qemu_prefix) + 1);        if (!optname) {            dolog ("Could not allocate memory for option name `%s'\n",                   opt->name);            continue;        }        strcpy (optname, qemu_prefix);        /* copy while upper-casing, including trailing zero */        for (i = 0; i <= preflen; ++i) {            optname[i + sizeof (qemu_prefix) - 1] = toupper ((uint8_t)prefix[i]);        }        strcat (optname, "_");        strcat (optname, opt->name);        def = 1;        switch (opt->tag) {        case AUD_OPT_BOOL:        case AUD_OPT_INT:            {                int *intp = opt->valp;                *intp = audio_get_conf_int (optname, *intp, &def);            }            break;        case AUD_OPT_FMT:            {                audfmt_e *fmtp = opt->valp;                *fmtp = audio_get_conf_fmt (optname, *fmtp, &def);            }

⌨️ 快捷键说明

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