首先audio调试,要先确保底层是ok的,即使用tinycap和tinyplay能够正常的录音放音即可。至于tinycap/play如何使用,具体可查百度,有详细的介绍。
tinycap录音时,报如下错误,这是由于和codec驱动中设置的通道数不一样;Unable to open PCM device (cannot set hw params: Invalid argument)
顺芯的es8323芯片手册,可以看出支持2通道的录音;即R/L为一个通道!
tinyplay播放录音文件时,如下报错,No sysclk provided,这个和mclk有关,所以先cat /sys/kernel/debug/clk/clk_summary看下mclk有没使能,dts配置加上system-clock-frequency属性设置。
tinyplay /storage/emulated/0/01.wav -D 0 -d 0 -p 1024 -n 3 <
cannot open device '/dev/snd/pcmC0D0p'
Unable to open PCM device 0.
es8316 1-0010-1: No sysclk provided
static const struct snd_soc_dai_ops es8316_ops = {
.startup = es8316_pcm_startup,
.hw_params = es8316_pcm_hw_params,
.set_fmt = es8316_set_dai_fmt,
.set_sysclk = es8316_set_dai_sysclk,
.digital_mute = es8316_mute,
};
这些都是在录音或放音的时候会调用的,所以当打不开device时,可以在这几个函数加下log打印下。
介绍下这个函数es8323_set_dai_sysclk,这个主要是设置mclk以及lrck;
//设置mclk
ret = clk_set_rate(es8323->mclk, freq);
if (ret)
return ret;
这个就是通过mclk以及ratio来计算出lrck的频率大小,一般lrck*ratio=mclk
for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
const unsigned int ratio = supported_mclk_lrck_ratios[i];
if (freq % ratio == 0)
es8323->allowed_rates[count++] = freq / ratio;
}
其中mclk-fs=<256>这个是最常见的,也就是为采样频率的256倍;驱动中如下数组定义
supported_mclk_lrck_ratios[NR_SUPPORTED_MCLK_LRCK_RATIOS] = {
256, 384, 512, 768, 1024 };
因此,在使用simple-card注册时,加上system-clock-frequency这个参数后,采样率就需要固定下来了。因此,如果需要多种采样率的,我们推荐使用multicodes-card去注册声卡,示例如下。
es8388_sound: es8388-sound {
status = "okay";
compatible = "rockchip,multicodecs-card";
rockchip,format = "i2s";
rockchip,mclk-fs = <256>;
rockchip,card-name = "es8388-codec";
rockchip,cpu = <&i2s1_8ch>;
rockchip,codec = <&es8388_codec>;
};
一句话:录音放音失败,要用示波器去测量i2s的相关信号lrck,bclk,sdi,sdo,mclk,看是否正常,波形有问题,就去对症解决。
android上层
当使用tinycap/tinyplay可以正常的录音,放音时,说明底层没有什么问题了;但正常的android播放却有问题,播放失败,报错如下;一般hal层你找下关键字“ AudioHardwareTiny“
打开声卡失败了,先确认下audio_hw.c文件中有没添加声卡,即在struct dev_proc_info SPEAKER_OUT_NAME,加上声卡的ID;
或者你可以指定device以及card,如下所示直接修改,在函数start_output_stream中
在.h文件中还能设置放音的频率