Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15532998
  • 博文数量: 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 12:07:06

static int choose_rate(struct snd_pcm_substream *substream,
               struct snd_pcm_hw_params *params, unsigned int best_rate)
{
    struct snd_interval *it;
    struct snd_pcm_hw_params *save;
    unsigned int rate, prev;

    save = kmalloc(sizeof(*save), GFP_KERNEL);
    if (save == NULL)
        return -ENOMEM;
    *save = *params; // 预先保存一份params的拷贝到save,然后对params进行尝试性修改,如果修改成功,那么
                     // 将直接返回成功数据,如果万一失败,那么使用*save恢复params到原始数据.
    // 使用save中的it,下面将对it进行只读操作[luther.gliethttp]
    // 在snd_pcm_oss_change_params==>_snd_pcm_hw_params_any中
    // 已经将所有it范围定义在了[0, UINT_MAX]区间[luther.gliethttp]
    it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE);

    /* try multiples of the best rate */
    rate = best_rate; // 这里以采样率8000为例
    for (;;) {
        // 如果rate比it->max都大,那么没有可以选择的了
        // openmin和openmax表示开集,如果2个全为1,那么就表示,range范围为(min,max)
        // openmin为1,openmax为0,range范围为(min,max]
        // integer等于1,表示it不是一个范围区间,而是一个固定的interger整型值
        if (it->max < rate || (it->max == rate && it->openmax))
            break;
        // 执行到这里表示rate小于it->max
        if (it->min < rate || (it->min == rate && !it->openmin)) {
        // 表示rate >= min,所以可以进行采样率数值最佳匹配尝试[luther.gliethttp]
            int ret;
        // 设置params的SNDRV_PCM_HW_PARAM_RATE参数为integer整型数值rate,(dir=0表示为integer整型)
            ret = snd_pcm_hw_param_set(substream, params,
                           SNDRV_PCM_HW_PARAM_RATE,
                           rate, 0);
            if (ret == (int)rate) { // 是否成功设置为rate
                kfree(save);
                return rate;
            }
            *params = *save;    // 如果没有将params成功设置为rate整型值,那么说明rate设置失败
        }                       // 数据回滚,恢复*save中的内容到*params[luther.gliethttp]
        prev = rate;
        rate += best_rate;      // 将rate*n,即再次尝试n倍rate的速率[luther.gliethttp]
        if (rate <= prev)       // 整型溢出成为负数了,那么这是一定要强行退出的.
            break;
    }

    /* not found, use the nearest rate */
    // ok, 那就没有办法了,就连n倍rate的数值都不能设置,那么进行如下近似计算[我感觉不会发生下面的情况]
    kfree(save);
    return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); 《浅析alsa声卡驱动snd_pcm_hw_param_near函数》
}
阅读(1013) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~