Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1306421
  • 博文数量: 860
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-20 19:57
个人简介

对技术执着

文章分类

全部博文(860)

文章存档

2019年(16)

2018年(12)

2015年(732)

2013年(85)

2012年(15)

我的朋友

分类: LINUX

2015-03-14 17:12:40

static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
                    const struct snd_pcm_plugin_channel *src_channels,
                    struct snd_pcm_plugin_channel *dst_channels,
                    snd_pcm_uframes_t frames)
{
    int nsrcs, ndsts, dst;
    struct snd_pcm_plugin_channel *dvp;
    int format;

    if (snd_BUG_ON(!plugin || !src_channels || !dst_channels))
        return -ENXIO;
    if (frames == 0)
        return 0;

    nsrcs = plugin->src_format.channels;    // src声道数目
    ndsts = plugin->dst_format.channels;    // dst声道数目

    format = plugin->dst_format.format;
    dvp = dst_channels;
    if (nsrcs <= 1) {
        // src音频数据源只有1个声道
        /* expand to all channels */
        for (dst = 0; dst < ndsts; ++dst) {
        // 将1个声道的数据分别填充到ndsts个放音声道数据缓冲区中[luther.gliethttp]
        // frames为the number of samples采样的样点个数
            copy_area(src_channels, dvp, frames, format); 《浅析alsa声卡驱动copy_area和snd_pcm_area_copy函数》
            dvp++;
        }
        return frames;
    }

    for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) {  // dst来计数, 直到ndsts和nsrcs中的最小者[luther.gliethttp]
        copy_area(src_channels, dvp, frames, format);   // 过程就和上面雷同了[luther.gliethttp]
        dvp++;                                          // 移动到dst的下一个chanel
        src_channels++;                                 // 移动到src的下一个chanel[luther.gliethttp]
    }
    if (dst < ndsts)                                    // 如果nsrcs小于ndsts,那么还有ndsts - dst个chanels没有填充数据,
        zero_areas(dvp, ndsts - dst, frames, format);   // 见后
    return frames;
}

static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
               snd_pcm_uframes_t frames, int format)
{
    int dst = 0;
    for (; dst < ndsts; ++dst) {
        if (dvp->wanted)            // 如果dst的该chanel确实需要数据,又因为route_transfer函数中src的chanel数目小于
                                    // dst的chanel数目,所以这里就必须给它添上静音数据[luther.gliethttp]
            snd_pcm_area_silence(&dvp->area, 0, frames, format);
        dvp->enabled = 0;
        dvp++;                      // 移动到dst的下一个chanel[luther.gliethttp]
    }
}

阅读(412) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~