1.主题
tina+v853+audio+dvr多路mic采集和回声消除方案
2.问题背景
产品:
硬件:主控 + audio +tp9930
软件:tina + audio/ai
其他:客户需要调试6路mic,其中2路为v853内部audio codec mic,四路为tp9930 外部i2s mic,且其中一路audio mic与lineout硬件相连,作为aec回声消除。
3.复现步骤
1.搭建客户硬件环境。
2.配置tp9930音频输出,并用示波器查看bclk dout lrck波形。
4.问题分析
需要配置好底层音频i2s1,ai中间件声卡插件,并在app层拆分各个声道数据。
5.解决办法
需求分解:
1.根据原理图配置i2s1板级配置;
&daudio1_plat {
tdm-num = <1>;
tx-pin = <0>;
rx-pin = <0>;
pinctrl-used;
pinctrl-names= “default”,“sleep”;
pinctrl-0 = <&daudio1_pins_a>;
pinctrl-1 = <&daudio1_pins_b>;
tx-hub-en;
rx-sync-en;
status = “okay”; //打开i2s1声卡
};
&daudio1_mach {
soundcard-mach,format = “i2s”; //根据tp9930的输出格式选择dsp模式或者i2s模式
soundcard-mach,frame-master = <&daudio1_codec>;
soundcard-mach,bitclock-master = <&daudio1_codec>;
/* soundcard-mach,frame-inversion; /
/ soundcard-mach,bitclock-inversion; /
soundcard-mach,slot-num = <16>; //tp9930默认配置16声道slot
soundcard-mach,slot-width = <16>; //声道位深16bit
status = “okay”;
daudio1_cpu: soundcard-mach,cpu {
sound-dai = <&daudio1_plat>; //作为从机配置配置为daudio1_plat,主机配置为daudio1_cpu
soundcard-mach,pll-fs = <1>; / pll freq = 24.576M or 22.5792M * pll-fs /
soundcard-mach,mclk-fs = <0>; / mclk freq = pcm rate * mclk-fs */ //不需要mclk时钟
};
daudio1_codec: soundcard-mach,codec { //mclk时钟源,做从机无需配置。
};
};
2.tp9930驱动配置i2s输出, 16bit 16slot,由于是v853做从机所以无需新增codec驱动,直接在sensor驱动配置。
static struct regval_list reg_audio_init[] = {
{0x40, 0x40},
{0x00, 0x00},
{0x01, 0x00},
{0x02, 0x00},
{0x03, 0x00},
{0x00, 0x01},
{0x01, 0x02},
{0x08, 0x03},
{0x09, 0x04},
{0x17, 0x00 | (DATA_BIT << 2)},
{0x1B, 0x01 | (DATA_BIT << 6)},
{0x18, 0x80 | (SAMPLE_RATE)},
{0x19, 0x0F},
{0x1A, 0x15},
{0x37, 0x20},
{0x38, 0x38},
{0x3E, 0x00},
{0x3d, 0x01},
{0x40, 0x00},
};
static void tp9930_audio_dataSet(struct v4l2_subdev *sd)
{
sensor_write_array(sd, reg_audio_init, ARRAY_SIZE(reg_audio_init));
}
3.使用alsa原生工具测试,
arecord -Dplug:Capture1Mic:8000 /tmp/1.wav -f S16_LE -c 16 -r 8000 -d 10 可以录到tp9930四路pcm数据
使用sdk demo 发现无声音,经排查v853公版配置i2s1模式作为aec回录,自动打开回录功能,amixer cset numid=3 0 -c 1 修改控件后可以录到声音。
因此需要关闭sdk config aec开关
4.声卡复合插件的配置
在target/allwinner/v853-perf1/busybox-init-base-files/etc/asound.conf中配置复合插件如下
复合声卡插件
pcm.Capture1MicPlusAec {
type route
slave.pcm {
type multi
slaves {
a {pcm Capture2MicHard channels 2} //主控两路声卡
b {pcm CaptureI2SRX channels 4} //tp9930 4路
}
bindings {
0 {slave a channel 0}
1 {slave a channel 1}
2 {slave b channel 0}
3 {slave b channel 1}
4 {slave b channel 2}
5 {slave b channel 3}
}
}
ttable.0.0 1
ttable.1.1 1
ttable.2.2 1
ttable.3.3 1
ttable.4.4 1
ttable.5.5 1
}
tp9930四路mic
pcm.CaptureI2SRX {
type hooks
slave.pcm "hw:snddaudio1,0"
hooks.0 {
type ctl_elems
hook_args [
{
name "loopback debug"
preserve true
optional true
value 0
}
]
}
}
//主控两路mic
pcm.Capture2MicHard {
type hooks
slave.pcm "hw:0,0"
hooks.0 {
type ctl_elems
hook_args [
{
name "MIC1 Switch"
preserve true
optional true
value 1
}
{
name "MIC2 Switch"
preserve true
optional true
value 1
}
]
}
}
sampe ai conf修改如下
[parameter]
pcm_file_path = "/tmp/sample_ai_pcm.wav"
pcm_sample_rate = 8000
pcm_channel_cnt = 6
pcm_bit_width = 16
pcm_frame_size = 1024
pcm_cap_duration = 10
pcm_ai_gain = 100
测试后可以录到6路音频
5.aec应用层接口
首先需要拆分audio codec mic0 的数据,位深16bit,交错模式下,一个声道两个字节,参考aec demo mic1作为近端数据,mic1为远端录音
WebRtcAec_BufferFarend(aecmInst, far_frame, NN);
WebRtcAec_Process(aecmInst, near_frame, NULL, out_frame, NULL, NN,40,0);
最后可以录到out frame 回声消除后的pcm数据。
6.aenc编码
将拆分后的声道数据frame送到aenc chn编码输出为aac格式码流,可参考aenc_sample.c