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

📄 ossaudio.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    if (oss->mmapped) {        oss->old_optr = cntinfo.ptr;    }    hw->rpos = rpos;    return decr;}static void oss_fini_out (HWVoiceOut *hw){    int err;    OSSVoiceOut *oss = (OSSVoiceOut *) hw;    ldebug ("oss_fini\n");    oss_anal_close (&oss->fd);    if (oss->pcm_buf) {        if (oss->mmapped) {            err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);            if (err) {                oss_logerr (errno, "Failed to unmap buffer %p, size %d\n",                            oss->pcm_buf, hw->samples << hw->info.shift);            }        }        else {            qemu_free (oss->pcm_buf);        }        oss->pcm_buf = NULL;    }}static int oss_init_out (HWVoiceOut *hw, audsettings_t *as){    OSSVoiceOut *oss = (OSSVoiceOut *) hw;    struct oss_params req, obt;    int endianness;    int err;    int fd;    audfmt_e effective_fmt;    audsettings_t obt_as;    oss->fd = -1;    req.fmt = aud_to_ossfmt (as->fmt);    req.freq = as->freq;    req.nchannels = as->nchannels;    req.fragsize = conf.fragsize;    req.nfrags = conf.nfrags;    if (oss_open (0, &req, &obt, &fd)) {        return -1;    }    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);    if (err) {        oss_anal_close (&fd);        return -1;    }    obt_as.freq = obt.freq;    obt_as.nchannels = obt.nchannels;    obt_as.fmt = effective_fmt;    audio_pcm_init_info (        &hw->info,        &obt_as,        audio_need_to_swap_endian (endianness)        );    oss->nfrags = obt.nfrags;    oss->fragsize = obt.fragsize;    if (obt.nfrags * obt.fragsize & hw->info.align) {        dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",               obt.nfrags * obt.fragsize, hw->info.align + 1);    }    hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;    oss->mmapped = 0;    if (conf.try_mmap) {        oss->pcm_buf = mmap (            0,            hw->samples << hw->info.shift,            PROT_READ | PROT_WRITE,            MAP_SHARED,            fd,            0            );        if (oss->pcm_buf == MAP_FAILED) {            oss_logerr (errno, "Failed to map %d bytes of DAC\n",                        hw->samples << hw->info.shift);        } else {            int err;            int trig = 0;            if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {                oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");            }            else {                trig = PCM_ENABLE_OUTPUT;                if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {                    oss_logerr (                        errno,                        "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"                        );                }                else {                    oss->mmapped = 1;                }            }            if (!oss->mmapped) {                err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);                if (err) {                    oss_logerr (errno, "Failed to unmap buffer %p size %d\n",                                oss->pcm_buf, hw->samples << hw->info.shift);                }            }        }    }    if (!oss->mmapped) {        oss->pcm_buf = audio_calloc (            AUDIO_FUNC,            hw->samples,            1 << hw->info.shift            );        if (!oss->pcm_buf) {            dolog (                "Could not allocate DAC buffer (%d samples, each %d bytes)\n",                hw->samples,                1 << hw->info.shift                );            oss_anal_close (&fd);            return -1;        }    }    oss->fd = fd;    return 0;}static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...){    int trig;    OSSVoiceOut *oss = (OSSVoiceOut *) hw;    if (!oss->mmapped) {        return 0;    }    switch (cmd) {    case VOICE_ENABLE:        ldebug ("enabling voice\n");        audio_pcm_info_clear_buf (&hw->info, oss->pcm_buf, hw->samples);        trig = PCM_ENABLE_OUTPUT;        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {            oss_logerr (                errno,                "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"                );            return -1;        }        break;    case VOICE_DISABLE:        ldebug ("disabling voice\n");        trig = 0;        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {            oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");            return -1;        }        break;    }    return 0;}static int oss_init_in (HWVoiceIn *hw, audsettings_t *as){    OSSVoiceIn *oss = (OSSVoiceIn *) hw;    struct oss_params req, obt;    int endianness;    int err;    int fd;    audfmt_e effective_fmt;    audsettings_t obt_as;    oss->fd = -1;    req.fmt = aud_to_ossfmt (as->fmt);    req.freq = as->freq;    req.nchannels = as->nchannels;    req.fragsize = conf.fragsize;    req.nfrags = conf.nfrags;    if (oss_open (1, &req, &obt, &fd)) {        return -1;    }    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);    if (err) {        oss_anal_close (&fd);        return -1;    }    obt_as.freq = obt.freq;    obt_as.nchannels = obt.nchannels;    obt_as.fmt = effective_fmt;    audio_pcm_init_info (        &hw->info,        &obt_as,        audio_need_to_swap_endian (endianness)        );    oss->nfrags = obt.nfrags;    oss->fragsize = obt.fragsize;    if (obt.nfrags * obt.fragsize & hw->info.align) {        dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",               obt.nfrags * obt.fragsize, hw->info.align + 1);    }    hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;    oss->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);    if (!oss->pcm_buf) {        dolog ("Could not allocate ADC buffer (%d samples, each %d bytes)\n",               hw->samples, 1 << hw->info.shift);        oss_anal_close (&fd);        return -1;    }    oss->fd = fd;    return 0;}static void oss_fini_in (HWVoiceIn *hw){    OSSVoiceIn *oss = (OSSVoiceIn *) hw;    oss_anal_close (&oss->fd);    if (oss->pcm_buf) {        qemu_free (oss->pcm_buf);        oss->pcm_buf = NULL;    }}static int oss_run_in (HWVoiceIn *hw){    OSSVoiceIn *oss = (OSSVoiceIn *) hw;    int hwshift = hw->info.shift;    int i;    int live = audio_pcm_hw_get_live_in (hw);    int dead = hw->samples - live;    size_t read_samples = 0;    struct {        int add;        int len;    } bufs[2] = {        { hw->wpos, 0 },        { 0, 0 }    };    if (!dead) {        return 0;    }    if (hw->wpos + dead > hw->samples) {        bufs[0].len = (hw->samples - hw->wpos) << hwshift;        bufs[1].len = (dead - (hw->samples - hw->wpos)) << hwshift;    }    else {        bufs[0].len = dead << hwshift;    }    for (i = 0; i < 2; ++i) {        ssize_t nread;        if (bufs[i].len) {            void *p = advance (oss->pcm_buf, bufs[i].add << hwshift);            nread = read (oss->fd, p, bufs[i].len);            if (nread > 0) {                if (nread & hw->info.align) {                    dolog ("warning: Misaligned read %zd (requested %d), "                           "alignment %d\n", nread, bufs[i].add << hwshift,                           hw->info.align + 1);                }                read_samples += nread >> hwshift;                hw->conv (hw->conv_buf + bufs[i].add, p, nread >> hwshift,                          &nominal_volume);            }            if (bufs[i].len - nread) {                if (nread == -1) {                    switch (errno) {                    case EINTR:                    case EAGAIN:                        break;                    default:                        oss_logerr (                            errno,                            "Failed to read %d bytes of audio (to %p)\n",                            bufs[i].len, p                            );                        break;                    }                }                break;            }        }    }    hw->wpos = (hw->wpos + read_samples) % hw->samples;    return read_samples;}static int oss_read (SWVoiceIn *sw, void *buf, int size){    return audio_pcm_sw_read (sw, buf, size);}static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...){    (void) hw;    (void) cmd;    return 0;}static void *oss_audio_init (void){    return &conf;}static void oss_audio_fini (void *opaque){    (void) opaque;}static struct audio_option oss_options[] = {    {"FRAGSIZE", AUD_OPT_INT, &conf.fragsize,     "Fragment size in bytes", NULL, 0},    {"NFRAGS", AUD_OPT_INT, &conf.nfrags,     "Number of fragments", NULL, 0},    {"MMAP", AUD_OPT_BOOL, &conf.try_mmap,     "Try using memory mapped access", NULL, 0},    {"DAC_DEV", AUD_OPT_STR, &conf.devpath_out,     "Path to DAC device", NULL, 0},    {"ADC_DEV", AUD_OPT_STR, &conf.devpath_in,     "Path to ADC device", NULL, 0},    {NULL, 0, NULL, NULL, NULL, 0}};static struct audio_pcm_ops oss_pcm_ops = {    oss_init_out,    oss_fini_out,    oss_run_out,    oss_write,    oss_ctl_out,    oss_init_in,    oss_fini_in,    oss_run_in,    oss_read,    oss_ctl_in};struct audio_driver oss_audio_driver = {    INIT_FIELD (name           = ) "oss",    INIT_FIELD (descr          = ) "OSS http://www.opensound.com",    INIT_FIELD (options        = ) oss_options,    INIT_FIELD (init           = ) oss_audio_init,    INIT_FIELD (fini           = ) oss_audio_fini,    INIT_FIELD (pcm_ops        = ) &oss_pcm_ops,    INIT_FIELD (can_be_default = ) 1,    INIT_FIELD (max_voices_out = ) INT_MAX,    INIT_FIELD (max_voices_in  = ) INT_MAX,    INIT_FIELD (voice_size_out = ) sizeof (OSSVoiceOut),    INIT_FIELD (voice_size_in  = ) sizeof (OSSVoiceIn)};

⌨️ 快捷键说明

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