[RK3288][Android6.0] 调试笔记 --- 修改录音采样率提示报错问题
来源:互联网 发布:多线程网络爬虫 编辑:程序博客网 时间:2024/06/15 21:16
Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92
需求:
由于app采样率设置的是16k,而硬件用的是44.1kHz,为了避免重采样带来的损耗,因此将HAL层改了16kHz,logcat提示如下error:
01-21 23:01:23.047 210 1207 E AudioHardwareTiny: pcm_open() failed: cannot set hw params: Invalid argument
调试:
调用的流程是
pcm_open -> pcm.c
ioctl -> //cmd SNDRV_PCM_IOCTL_HW_PARAMS
snd_pcm_capture_ioctl1 ->
snd_pcm_common_ioctl1 ->
snd_pcm_hw_params_user ->
snd_pcm_hw_params ->
snd_pcm_hw_refine ->
snd_interval_refine ->
snd_interval_checkempty
跑进snd_interval_checkempty()说明传进来的值在经过计算后不符合要求,所以成了empty。往回看snd_interval_refine()的第二个参数constrs_interval(constrs, k)
snd_pcm_capture_open ->
snd_pcm_open ->
snd_pcm_open_substream ->
soc_pcm_open ->
soc_pcm_apply_symmetry ->
snd_pcm_hw_constraint_minmax //注意这里的最后两个参数都是soc_dai->rate
snd_interval_refine //最后把这两个参数更新到hw_constraints中rate对应的interval中去
soc_pcm_apply_symmetry()需要拿出来说下
![](http://img.blog.csdn.net/20170605161519924?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva3Jpc19mZWk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
static struct snd_soc_dai_driver rockchip_i2s_dai = {
......
.ops = &rockchip_i2s_dai_ops,
.symmetric_rates = 1,
};
那么上面的soc_dai->rate是在哪里设置的呢?我也是恍然大悟才想起来录音的同时先开启了playback stream,此值是在打开播放的时候设置的,困扰了我好一会,尴尬...
也正由于这个机制,之前我用tinycap直接验证录音也没发现此问题就提交了代码.
因此, 如果不是同时使用的话,那么采样率是可以修改的。
参考:
https://searchcode.com/codesearch/view/30197122/
https://git.congatec.com/arm/qmx6_kernel/commit/7912f03c2b2a0c43eae9b758fa768796fa9095d3
OS: Android 6.0
Kernel: 3.10.92
需求:
由于app采样率设置的是16k,而硬件用的是44.1kHz,为了避免重采样带来的损耗,因此将HAL层改了16kHz,logcat提示如下error:
01-21 23:01:23.047 210 1207 E AudioHardwareTiny: pcm_open() failed: cannot set hw params: Invalid argument
调试:
调用的流程是
pcm_open -> pcm.c
ioctl -> //cmd SNDRV_PCM_IOCTL_HW_PARAMS
snd_pcm_capture_ioctl1 ->
snd_pcm_common_ioctl1 ->
snd_pcm_hw_params_user ->
snd_pcm_hw_params ->
snd_pcm_hw_refine ->
snd_interval_refine ->
snd_interval_checkempty
跑进snd_interval_checkempty()说明传进来的值在经过计算后不符合要求,所以成了empty。往回看snd_interval_refine()的第二个参数constrs_interval(constrs, k)
static inline struct snd_interval *constrs_interval(struct snd_pcm_hw_constraints *constrs, snd_pcm_hw_param_t var){ return &constrs->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];}k即SNDRV_PCM_HW_PARAM_RATE, constrs即substream->runtime->hw_constraints,找到对hw_constraints中的设置是在open的时候
snd_pcm_capture_open ->
snd_pcm_open ->
snd_pcm_open_substream ->
soc_pcm_open ->
soc_pcm_apply_symmetry ->
snd_pcm_hw_constraint_minmax //注意这里的最后两个参数都是soc_dai->rate
snd_interval_refine //最后把这两个参数更新到hw_constraints中rate对应的interval中去
soc_pcm_apply_symmetry()需要拿出来说下
static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_dai *soc_dai){ struct snd_soc_pcm_runtime *rtd = substream->private_data; int ret; if (!soc_dai->driver->symmetric_rates && !rtd->dai_link->symmetric_rates) return 0;...... dev_info(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate); //使用soc_dai->rate作为默认的采样率,这里有可能是cpu dai的也有可能是codec dai的rate ret = snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_RATE, soc_dai->rate, soc_dai->rate);......}这里有个很重要的判断,判断soc_dai->driver->symmetric_rates或者rtd->dai_link->symmetric_rates是不是有设置,那么symmetric_rates有什么意义,摘录两段commit:
简单地说,就是由于audio codec由于硬件限制,而当你又要同时使用playback和capture的时候,它是无法同时输出两个不同的clock来满足不同的播放和录音采样率,所以当你使用其中一个substream的时候,另一个type的substream的采样率就会受到限制。
可以看到,rk_i2s.c也就是平台的cpu dai也做了限制:static struct snd_soc_dai_driver rockchip_i2s_dai = {
......
.ops = &rockchip_i2s_dai_ops,
.symmetric_rates = 1,
};
那么上面的soc_dai->rate是在哪里设置的呢?我也是恍然大悟才想起来录音的同时先开启了playback stream,此值是在打开播放的时候设置的,困扰了我好一会,尴尬...
也正由于这个机制,之前我用tinycap直接验证录音也没发现此问题就提交了代码.
因此, 如果不是同时使用的话,那么采样率是可以修改的。
参考:
https://searchcode.com/codesearch/view/30197122/
https://git.congatec.com/arm/qmx6_kernel/commit/7912f03c2b2a0c43eae9b758fa768796fa9095d3
阅读全文
2 0
- [RK3288][Android6.0] 调试笔记 --- 修改录音采样率提示报错问题
- [RK3288][Android6.0] 调试笔记 --- 实时录音会有呲呲噪音问题
- [RK3288][Android6.0] 调试笔记 --- 录音apk无权限录音问题
- [RK3288][Android6.0] 调试笔记 --- Audio录音PCM数据抓取
- [RK3288][Android6.0] 调试笔记 --- 命令行录音方法
- [RK3288][Android6.0] 调试笔记 --- 关闭按键音后无法录音问题
- [RK3288][Android6.0] 调试笔记 --- 录音音量从HAL到APP层会变小问题
- [RK3288][Android6.0] 调试笔记 --- 开机提示mmc rescan错误
- [RK3288][Android6.0] 调试笔记 --- 修改浏览器默认地址
- [RK3288][Android6.0] 调试笔记 --- 修改系统按键
- [RK3288][Android6.0] 调试笔记 --- 修改boot.img后进入Recovery模式问题
- [RK3288][Android6.0] 调试笔记 --- I2C通信失败问题
- [RK3288][Android6.0] 调试笔记 --- Camera没有权限打开问题
- [RK3288][Android6.0] 调试笔记 --- AndroidTool低格无效问题
- [RK3288][Android6.0] 调试笔记 --- edp屏无法点亮问题
- [RK3288][Android6.0] 调试笔记 --- Audio驱动层判断录音数据是否异常
- [RK3288][Android6.0] 调试笔记 --- RT5640录音时的Codec寄存器列表
- [RK3288][Android6.0] 调试笔记 --- 修改默认system/bin/下可执行程序权限
- Java中PO,VO,BO,DTO,POJO,以及之间的区别
- Android 中Edittext输入内容 下方展示内容跟着变色
- 基于Docker布署分布式hadoop环境
- 对俩个有序数组合并排序
- es6之箭头函数
- [RK3288][Android6.0] 调试笔记 --- 修改录音采样率提示报错问题
- 《金融行业IT面试360度全方位解读》
- 洛谷 P2031 脑力达人之分割字串
- 《现代软件工程:构建之法》读后感
- java多线程
- 大话设计模式阅读笔记-工厂方法模式
- python json的问题
- Word2Vec教程(2)- Negative Sampling
- Java利用POI实现数据的Excel导入