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;
}
}
}
阅读(1077) | 评论(0) | 转发(0) |