Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15498764
  • 博文数量: 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-17 13:35:52

int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask)
{
    int i;

// 检查format对应的mask->bits[]是否置位有效[luther.gliethttp]
// 对于snd_pcm_oss_change_params函数中调用该函数之前,
// 已经执行_snd_pcm_hw_params_any(sparams);将mask->bits[]中内容全部置1
// 所以这里一定成立
    if (snd_mask_test(format_mask, format))
        return format;
// 如果format对应的mask->bits[]为0,那么继续往下执行[luther.gliethttp]
    if (! snd_pcm_plug_formats(format_mask, format)) // 扩容format_mask中的format格式   《浅析alsa声卡驱动snd_pcm_plug_formats函数》
        return -EINVAL; // 如果经过扩容之后,仍然没有包含format格式的支持,那么很sorry了[luther.gliethttp]
// ok,上面的snd_pcm_plug_formats动态扩容format_mask中的format格式的操作生效,
// format就是snd_pcm_plug_formats被扩容的几个格式中的1个,下面进一步细分查找锁定[luther.gliethttp].
    if (snd_pcm_format_linear(format)) {
// 如果pcm_formats[format].signd非负,即format整数﹑负数均可,那么就表示为线性[luther.gliethttp]
        unsigned int width = snd_pcm_format_width(format); // 返回pcm_formats[format].width
        int unsignd = snd_pcm_format_unsigned(format) > 0; // 检查format是有符号还是无符号,1表无符号
        int big = snd_pcm_format_big_endian(format) > 0; // 检查pcm_formats[format].le大小端,1表大端
        unsigned int badness, best = -1; // 因为是无符号数,所以这里-1对应最大值
        int best_format = -1;
        for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
            int f = preferred_formats[i];
            unsigned int w;
            if (!snd_mask_test(format_mask, f))
                continue; // 优选数组preferred_formats中的该格式没有被format_mask支持,那么continue.
            // 进一步审查格式优选数组preferred_formats中最先在format_mask中使能的格式.
            w = snd_pcm_format_width(f); // 返回pcm_formats[f].width
            if (w >= width)
                badness = w - width;
            else
                badness = width - w + 32;// 这里加32,完全是为了惩罚32分,所以也可以从侧面看出,
                                         // 自动匹配功能更倾向于使用大于width的format
            badness += snd_pcm_format_unsigned(f) != unsignd; // 如果符号不相同,那么惩罚1分
            badness += snd_pcm_format_big_endian(f) != big; // 如果大小端不相同,那么惩罚1分
            if (badness < best) { // 无符号类型比较,所以-1初始值为全f,是最大值[luther.gliethttp]
                best_format = f;  // 使用算法策略中差距最小的一个format临时作为best_format
                best = badness;
            }
        }
        return best_format >= 0 ? best_format : -EINVAL; // 返回最终结果
    } else {
// format格式为非线性格式,即:pcm_formats[format].signd小于0
        switch (format) {
        case SNDRV_PCM_FORMAT_MU_LAW:
// 对于非线性format格式,我们只对u律格式进行进一步处理[luther.gliethttp]
            for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
                int format1 = preferred_formats[i]; // 使用格式优选数组preferred_formats中最先
                if (snd_mask_test(format_mask, format1)) // 在format_mask中使能的格式.
                    return format1;
            }
        default:
            return -EINVAL;
        }
    }
}
阅读(1066) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~