alsa插件之plugin plug的使用陷阱
2.问题背景
产品:V853开发板
硬件:v853
软件:tina-sdk, mpp
3.问题描述
3.1复现步骤
v853-perf1工程,在asound.conf中编写采集插件pcm.Capture1Mic时,用了plugin plug,这是为了利用
自动转换插件可以做声道数的转换的功能。当客户用单MIC采集,但想出双声道的数据源时,用
plugin plug就很方便实现,部分代码如下:
slave.pcm {
type plug
slave {
pcm “hw:0,0”
channels 1
}
}
但用sample_aec实测回声消除时,配置采样率为16000,经常出现读不到数据导致EPIPE错误的现象。
3.2具体表现
出现EPIPE的次数不是很频繁,但每隔十几秒出现一次。这会导致回声消除时采集的音频数据间断
,是无法接受的。
4.问题分析
用arecord采集音频,arecord -D Capture1Mic -f S16_LE -r 16000 -c 1 -d 3600 -v
/mnt/extsd/16K1Ch16Bit.wav
加上-v参数,查看具体的alsa插件通路,发现Slave: Plug PCM: Rate conversion PCM (32000,
sformat=S16_LE)。也就是自动转换插件将32000的采样率转换为16000的采样率。
查看procfs系统的调试节点
cat /proc/asound/card0/pcm0c/sub0/hw_params
cat /proc/asound/card1/pcm0c/sub0/hw_params
也发现硬件采样率被设置为32000。
通过这些数据,说明:plugin plug截取了用户设置下来的sampleRate,没有设置给slave plugin中的硬件
设备。设置给硬件设备hw:0,0的采样率是默认的32000。然后plugin plug自己将32000的采样率转换为
16000。但这种转换比较耗时,结果造成数据没有及时准备好,导致上层app拿不到数据,出现
EPIPE。
5.根本原因
通过分析,可以得出结论:plugin plug不会把设置给它的采样率、声道数等信息再往下设置给硬件设
备。而是当做自己的转换的目标参数。
6.解决办法
解决办法就是直接指定plugin plug内的slave plugin的参数:
slave.pcm {
type plug
slave {
pcm “hw:0,0”
channels 1
rate 16000或rate $SAMPLERATE
}
}
如上,可以直接写固定的采样率16000,也可以使用运行时参数(runtime arguments)。app通过运行
时参数将硬件采样率设置给plugin plug,plugin plug配置给slave plugin中的硬件PCM设备。