pdm接口数字mic调试
首先,rk3566平台是带有pdm接口,因此使用数字mic不需要外挂7210这样的ic
只需要配置接口即可
rk817-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,name = "rockchip,rk817-codec"; simple-audio-card,mclk-fs = <256>; //chencx add simple-audio-card,dai-link@0 { format = "i2s"; cpu { sound-dai = <&i2s1_8ch>; //这是模拟功放的 }; codec { sound-dai = <&rk817_codec 0>; //这是codec节点 }; }; simple-audio-card,dai-link@1 { format = "pdm"; cpu { sound-dai = <&pdm>; //这是数字pdm节点,需要自己配置 }; codec { sound-dai = <&rk817_codec 1>; //把数字Pdm加入到codec声卡中 }; }; };
接着就是配置pdm参数而已,这个可以参考doc下面文档,我也是参照配置来的
//chencx add pdm &pdm { status = "okay"; #sound-dai-cells = <0>; pinctrl-names = "default"; rockchip,path-map = <1 0 2 3>; //修改默认通道顺序 capture,channel-mapping = <2>; pinctrl-0 = < &pdmm0_clk1 &pdmm0_sdi1 //接的sdi1接口,这个按照原理图来 >; };
文档在 Y:\rk\rk3566\rk3566\RKDocs\common\Audio\Rockchip_Developer_Guide_Audio_CN.pdf
然后需要在codec下面增加pdmdata-out-enable的属性
rk817_codec: codec { #sound-dai-cells = <1>; compatible = "rockchip,rk817-codec"; clocks = <&cru I2S1_MCLKOUT_TX>; clock-names = "mclk"; //assigned-clocks = <&cru I2S1_MCLKOUT_TX>; //assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; assigned-clocks = <&cru I2S1_MCLKOUT>, <&cru I2S1_MCLK_TX_IOE>; assigned-clock-rates = <12288000>; //assigned-clock-rates = <11289600>; assigned-clock-parents = <&cru I2S1_MCLKOUT_TX>, <&cru I2S1_MCLKOUT_TX>; pinctrl-names = "default"; pinctrl-0 = <&i2s1m0_mclk>; hp-volume = <3>; spk-volume = <3>;//max-0 min-255 out-l2spk-r2hp; //数字pdm pdmdata-out-enable; //喇叭控制脚 spk-ctl-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>; mic-ctl-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>; status = "okay"; }; }; };
查看生成的节点
ls /dev/snd/* -ls crw-rw---- 1 system audio 116, 5 2021-12-04 06:44 controlC0 crwxrwxrwx 1 system audio 116, 2 2021-12-04 06:44 pcmC0D0c crw-rw---- 1 system audio 116, 4 2021-12-04 06:44 pcmC0D1c //增加的输入节点 crw-rw---- 1 system audio 116, 3 2021-12-04 06:44 pcmC0D1p crw-rw---- 1 system audio 116, 33 2021-12-04 06:44 timer
调试中遇到的问题
使用tinuycap的时候 -D 是声卡 -d是devices,所以这里使用命令-d为1
tinycap 32bit-44k.wav -D 0 -d 1 -c 2 -r 16000 -b 32 -p 1024 -n 3 -T 20
使用后发现还是没有声音,命令改为-c 8才有,因为默认通道0 1 上面采集数据,这里是多通道配置,所以没有声音,-c 8后面就看到声音很小,实际上是有声音的而且正常
之后修改声卡声音顺序,把通道顺序调整,就可以在默认声卡使用了
rockchip,path-map = <1 0 2 3>; //先采集1 通道 然后 0 2 3 。这样就把有声音的通道1作为 优先采集了
经过这次操作 就可以录制到正常的声卡声音,但是声音比较小
之后,使用拾音算法,就可增加声音增益了,
修改 external/tinyalsa//pcm.c
static short out_vol = 5.0; static void volume_process(const void *buffer, unsigned int channels,size_t length, short volume) { short * buffer_end = (short*)buffer + length/2; short * pcmData = (short *)buffer; int i = 0; int pcmval; int tenp = channels ; while (pcmData < buffer_end) { /// if (i % channels != 1 && i % channels != 0) { /// printf("***\n"); pcmval = (short)*pcmData * volume; if (pcmval < 32768 && pcmval > -32768) { *pcmData = pcmval; } else if (pcmval > 32767) { *pcmData = 32767; } else if (pcmval < -32767) { *pcmData = -32767; } ///} ++pcmData; i++; } } ......... int pcm_read(struct pcm *pcm, void *data, unsigned int count) { struct snd_xferi x; int i = 0 ; short *temp = (short*)data ; if (!(pcm->flags & PCM_IN)) return -EINVAL; //printf("start---read---\n") ; memset(data, 0, count); x.buf = data; x.frames = count / (pcm->config.channels * pcm_format_to_bits(pcm->config.format) / 8); for (;;) { if (!pcm->running) { if (pcm_start(pcm) < 0) { fprintf(stderr, "start error"); return -errno; } } .................................................. for(i=0;i<10;i++) { printf("%d\n", temp[i]) ; } //printf("---\n"); volume_process(x.buf, pcm->config.channels,count , out_vol); return 0; } }
到这里,使用是没有什么问题了