Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15366712
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2009-11-19 12:20:32

snd_pcm_oss_change_params
==> snd_pcm_plug_alloc
==> snd_pcm_plugin_alloc
static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
{
    struct snd_pcm_plugin_format *format;
    ssize_t width;
    size_t size;
    unsigned int channel;
    struct snd_pcm_plugin_channel *c;

    if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) {
        format = &plugin->src_format;
    } else {
        format = &plugin->dst_format;
    }
    if ((width = snd_pcm_format_physical_width(format->format)) < 0)
        return width;
    size = frames * format->channels * width; // frames次完全采样,所需存储空间总大小[luther.gliethttp]
    if (snd_BUG_ON(size % 8))
        return -ENXIO;
    size /= 8;
    if (plugin->buf_frames < frames) {  // 如果plugin插件预先申请的采样次数buf_frames小于这里指定的采样
        vfree(plugin->buf);             // 次数frames,那么释放plugin插件预先申请音频数据缓冲区
        plugin->buf = vmalloc(size);    // 重新申请size大小的音频缓冲区
        plugin->buf_frames = frames;    // 当前音频缓冲区可以填充frames次采样数据[luther.gliethttp]
    }
    if (!plugin->buf) {
        plugin->buf_frames = 0;
        return -ENOMEM;
    }
    c = plugin->buf_channels;
    if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
        // 读写交叉模式
        for (channel = 0; channel < format->channels; channel++, c++) {
            c->frames = frames; // 该声道数据存储空间所能存储的最大采样次数
            c->enabled = 1;
            c->wanted = 0;
            c->area.addr = plugin->buf; // 该模式下,所有声道的的数据存储地址都为起始地址
            // 具体存储流成为addr + first存入本声道数据,然后first += step;这样first指向本声道
            // 下一次采样数据存储地址[luther.gliethttp]
            c->area.first = channel * width; // 数据存放的收地址
            c->area.step = format->channels * width; // 步进大小,很明显是为了first += step;完成下一个存储地址的跳转.
        }
    } else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
        // 读写非交叉模式
        if (snd_BUG_ON(size % format->channels))
            return -EINVAL;
        size /= format->channels; // size等于一个声道进行frames次采样后所需存储空间大小
        for (channel = 0; channel < format->channels; channel++, c++) {
            c->frames = frames; // 该声道数据存储空间所能存储的最大采样次数
            c->enabled = 1;
            c->wanted = 0;
            c->area.addr = plugin->buf + (channel * size); // 很明显这样设置之后,允许一个声道从
            c->area.first = 0;  // first开始之后的连续size个字节存储空间都归该声道使用
            c->area.step = width;// 因为一个声道采样frames次,就会产生size大小的音频数据[luther.gliethttp]
        }
    } else
        return -EINVAL;
    return 0;
}
阅读(988) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~