RK android平台多MIC开发:从驱动配置到算法适配

电子说

1.4w人已加入

描述

 

 

在智能音箱、视频会议设备等场景中,多 MIC(麦克风)配置是实现远场拾音、降噪、回声消除的核心基础。瑞芯微(Rockchip在多 MIC 开发上提供了统一框架与差异化配置,本文将结合官方技术文档,从声卡注册与 DTS 配置音频测试算法集成常见问题解决四大维度,手把手教你完成多 MIC 开发,附具体文件路径与实操代码。

Mic

一、核心前提:不同芯片的共性与差异

 

瑞芯微各芯片多 MIC 开发的核心逻辑一致(基于simple-audio-card框架、依赖 TinyALSA 工具链),但需注意接口与 DTS 路径差异,下表可快速定位关键信息:

 

 

芯片型号

 

 

支持的 MIC 接口

 

 

核心参考 DTS 路径

 

 

录音设备节点(默认)

 

 

关键 Codec 示例

 

 

RK3399

 

 

I2S、外挂 ADC

 

 

无固定路径(参考 ES8323/ES7210 示例)

 

 

pcmC0D1c

 

 

ES8323ES7210RT5640

 

 

RK3326/PX30

 

 

I2SPDM

 

 

arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts

 

 

pcmC0D1c

 

 

RK809RK817

 

 

RK3566/RK3568

 

 

I2SPDM

 

 

arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-pdm-mic-array.dts

 

 

pcmC1D1c

 

 

RK809ES7202ES7243e

 

 

提示:若找不到对应 DTS 文件,可在arch/arm64/boot/dts/rockchip/目录下全局搜索pdmi2smic等关键词,或参考同系列芯片的多 MIC 配置示例。

 

 

二、关键步骤:多 MIC 开发全流程(附代码与路径)

 

 MIC 开发的核心是声卡注册(DTS 配置)→ 内核适配 → 测试验证 → 算法集成,每个步骤均需结合芯片特性调整,以下为具体实操:

 

 

1. 第一步:声卡注册与 DTS 配置(核心)

 

声卡是多 MIC 数据传输的 桥梁,需通过 DTS 配置cpu_dai(如 I2S/PDM 接口)、codec_dai(如 RK809 codec)与dai-link(连接两者),分 3 种典型场景:

 

 

场景 1PDM 多 MICRK3326/PX30/RK3566/RK3568 通用)

 

PDM 接口支持多通道(1-8ch),1-2 通道通常用于 回采3-8 通道用于 MIC 拾音,以 RK3566 为例:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
// 路径:arch/arm64/boot/dts/rockchip/rk3566-evb2-lp4x-v10-pdm-mic-array.dtsrk809_sound_micarray: rk809-sound-micarray {    compatible = "simple-audio-card";    simple-audio-card,name = "rockchip,rk809-codec"// 声卡名称    simple-audio-card,mclk-fs = <256>; // 主时钟倍数(固定)        // dai-link0:播放(I2S接口)    simple-audio-card,dai-link@0 {        format = "i2s";        cpu { sound-dai = <&i2s1_8ch>; }; // 绑定I2S1_8ch播放接口        codec { sound-dai = <&rk809_codec 0>; }; // 绑定Codec播放端    };        // dai-link1:录音(PDM接口,多MIC)    simple-audio-card,dai-link@1 {        format = "pdm";        cpu { sound-dai = <&pdm>; }; // 绑定PDM录音接口        codec { sound-dai = <&rk809_codec 1>; }; // 绑定Codec录音端    };};// 使能I2S1_8ch播放接口&i2s1_8ch {    status = "okay";    #sound-dai-cells = <0>;    rockchip,clk-trcm = <1>;    pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdo0>;};// 使能PDM录音接口(多MIC核心)&pdm {    status = "okay";    #sound-dai-cells = <0>;    pinctrl-0 = <&pdmm0_clk &pdmm0_clk1 &pdmm0_sdi0 &pdmm0_sdi1 &pdmm0_sdi2 &pdmm0_sdi3>;};// 配置RK809 Codec(需支持回采与多通道)&rk809_codec {    #sound-dai-cells = <1>;    compatible = "rockchip,rk809-codec""rockchip,rk817-codec";    clocks = <&cru I2S1_MCLKOUT>;    clock-names = "mclk";    adc-for-loopback; // 使能回采功能    pdmdata-out-enable; // PDM数据使能    hp-volume = <20>; // 耳机音量(可调整)    spk-volume = <3>; // 喇叭音量(可调整)    mic-in-differential; // 差分MIC输入(提升抗干扰)    status = "okay";};

场景 2I2S 多 MICRK3399/RK3326 通用)

 

 MIC 通过 I2S 接口连接(如 RK3399 使用 ES8323 Codec),需配置 I2S 多通道与 Codec 驱动:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
// RK3399 ES8323示例(无固定路径,需自定义)es8323-sound {    status = "okay";    compatible = "simple-audio-card";    simple-audio-card,format = "i2s";    simple-audio-card,name = "rockchip,es8323-codec";    simple-audio-card,mclk-fs = <256>;        // CPU端:绑定I2S0    simple-audio-card,cpu { sound-dai = <&i2s0>; };    // Codec端:绑定ES8323    simple-audio-card,codec { sound-dai = <&es8323>; };};// ES8323 Codec配置(I2C地址0x11)es8323: es8323@11 {    #sound-dai-cells = <0>;    compatible = "everest,es8323";    reg = <0x11>;    clocks = <&cru SCLK_I2S_8CH_OUT>;    clock-names = "mclk";    spk-con-gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>; // 喇叭控制GPIO    hp-det-gpio = <&gpio4 28 GPIO_ACTIVE_HIGH>; // 耳机检测GPIO    status = "okay";};// 同时修改ES8323驱动,支持8通道(关键!)// 路径:kernel/sound/soc/codecs/es8323.c(需全局搜索驱动文件)static struct snd_soc_dai_driver es8323_dai = {    .capture = {        .stream_name = "Capture",        .channels_min = 2,        .channels_max = 8// 原默认2,改为8通道        .rates = es8323_RATES,        .formats = es8323_FORMATS,    },};

场景 3:外挂 ADC + 虚拟声卡(所有芯片通用)

 

 ADC 驱动无标准声卡逻辑(如仅初始化寄存器),需用dummy-codec(虚拟 Codec)注册声卡:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
// 定义虚拟Codecdummy_codec: dummy-codec {    compatible = "rockchip,dummy-codec";    #sound-dai-cells = <0>;};// 注册声卡(以RT5640为播放Codec,虚拟Codec为录音)rt5640-sound {    compatible = "simple-audio-card";    simple-audio-card,name = "rockchip,rt5640-codec";    simple-audio-card,mclk-fs = <256>;        // 播放链路(RT5640    simple-audio-card,dai-link@0 {        format = "i2s";        cpu { sound-dai = <&i2s0>; };        codec { sound-dai = <&rt5640>; };    };        // 录音链路(虚拟Codec)    simple-audio-card,dai-link@1 {        format = "i2s";        cpu { sound-dai = <&i2s0>; };        codec { sound-dai = <&dummy_codec>; };    };};

2. 第二步:内核强制 通道(RK3399 、RK3576必做,其他芯片可选)

 

部分芯片(如 RK3399)默认 I2S 驱动仅支持 通道,需修改内核代码强制 通道:

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
// 路径:kernel/sound/soc/rockchip/rockchip_i2s.cstatic int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) {    // ... 原有代码 ...    if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {        regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK, val);    } else {        regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, val);                // 新增:播放时强制录音8通道(用于回采+MIC)        dev_info(i2s->dev, "for echo fixed 8 channels capture when playbackn");        val = 0;        val |= I2S_CHN_8; // 8通道        val |= I2S_TXCR_VDW(16); // 16bit(32bit需改为I2S_TXCR_VDW(32))        regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK, val);    }    // ... 原有代码 ...}// 修改DAI驱动,支持8通道static struct snd_soc_dai_driver rockchip_i2s_dai = {    .capture = {        .stream_name = "Capture",        .channels_min = 2,        .channels_max = 8// 原默认2,改为8        .rates = SNDRV_PCM_RATE_8000_192000,        .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE),    },};

3. 第三步:音频测试(验证多通道是否正常)

 

测试工具使用 TinyALSAtinycap录音、tinymix配置通路),需先通过mm编译external/tinyalsa/生成工具,再按以下步骤操作:

 

 

步骤 1:确认声卡注册成功

 

  •  
  •  
  •  
  •  
# 查看已注册声卡(需出现目标Codec,如rockchip,rk809-codec)adb shell cat /proc/asound/cards# 查看录音设备节点(多MIC通常对应pcmCxD1c,如RK3566为pcmC1D1c)adb shell ls -l /dev/snd/

示例输出(RK3566):

 

 

  •  
crw-rw---- 1 system audio 1167 2024-05-20 10:00 pcmC1D1c // 多MIC录音节点

步骤 2:打开录音通路

 

  •  
  •  
  •  
  •  
  •  
# 格式:tinymix -D [声卡ID] [通路ID] [使能值]# 示例:RK3566打开声卡1的录音通路(通路ID需根据Codec调整,默认1为录音)adb shell tinymix -D 1 1 1# (可选)打开喇叭放音通路(用于测试回采)adb shell tinymix -D 1 0 2

步骤 3:录制 通道音频

 

  •  
  •  
  •  
# 格式:tinycap [保存路径] -D [声卡ID] -d [设备ID] -c [通道数] -r [采样率] -b [位宽] -p [周期大小] -n [周期数]# 示例:RK3566录制8通道、16K采样率、16bit音频adb shell tinycap /sdcard/multi-mic-record.wav -D 1 -d 1 -c 8 -r 16000 -b 16 -p 1024 -n 3

步骤 4:分析录音文件

 

将录音文件导出到 PC,用Adobe AuditionAudacity打开,查看 8 个通道的波形:

 

 

1-2 通道:回采信号(若播放了测试音频,应有波形);

 

 

3-8 通道:MIC 拾音(说话时应有波形,静音时无杂波)。

 

 

4. 第四步:多 MIC 算法集成(对接 AI 降噪 回声消除)

 

Android 原生录音机仅支持 1-2 通道,需集成第三方多 MIC 算法(如 AEC、波束成形),核心是在tinyalsa_hal中嵌入算法,步骤如下:

 

 

步骤 1:修改 TinyALSA HAL,关闭原生降噪

 

  •  
  •  
  •  
  •  
  •  
  •  
// 路径:hardware/rockchip/audio/tinyalsa_hal/audio_hw.h#ifndef RK3368// 注释掉原生SPEEX降噪,避免与第三方算法冲突+//#define SPEEX_DENOISE_ENABLE-#define SPEEX_DENOISE_ENABLE#endif

步骤 2:屏蔽通道固定代码(避免强制 通道)

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
// 路径:external/tinyalsa/pcm.c// 注释掉以下代码(强制通道检查的逻辑)/*if(!(pcm->config.channels == 1)) {    if(channalFlags == -1 ) {        if(startCheckCount < SAMPLECOUNT) {            startCheckCount += count;        } else {            channalFlags = channel_check(data,count/2);        }    }//if(channalFlags == -1)    channel_fixed(data,count/2, channalFlags);}*/

步骤 3:嵌入第三方算法

 

hardware/rockchip/audio/tinyalsa_hal/的录音流程中(如audio_hw.cstart_input_stream函数),添加算法调用:

 

 

1.pcmCxD1c读取 8 通道原始数据;

 

 

2.调用算法处理(如 AEC 消回音、降噪);

 

 

3.输出 2 通道处理后的数据(供原生 APP 使用)。

 

 

算法集成框架参考:

 

 

Mic

三、常见问题与解决方案(避坑指南)

 

1. 问题 1:录音只有 通道,无 通道?

 

原因 1Codec 驱动channels_max未设为 8(如 ES8323 驱动需改channels_max = 8);

 

 

原因 2:内核 I2S 驱动未强制 通道(RK3399 需改rockchip_i2s.c);

 

 

解决:检查codec驱动rockchip_i2s.c的通道配置,确保均为 8

 

 

2. 问题 2:部分 MIC 通道无波形?

 

原因 1PDM/I2S 引脚未配置(需在 DTS pinctrl-0中添加所有 MIC 的引脚);

 

 

原因 2MIC 硬件故障(如虚焊、供电不足);

 

 

解决:先检查 DTS 引脚配置,再用示波器测量 MIC 接口的时钟与数据信号。

 

 

3. 问题 3:回采通道无波形?

 

原因 1:未打开回采功能(Codec 需配置adc-for-loopback);

 

 

原因 2:未播放测试音频(回采需先通过tinyplay播放音频);

 

 

解决:确认 DTS adc-for-loopback已启用,且录音时播放了测试音频。

 

 

4. 问题 4:算法集成后无输出?

 

原因 1tinyalsa_hal未读取正确的录音节点(默认是pcmC0D0c,需改为多 MIC 节点如pcmC1D1c);

 

 

解决:在audio_hw.c中修改pcm_open的参数,指定多 MIC 的声卡 ID 和设备 ID

 

 

四、开发资源汇总

 

1.关键文件路径(全局搜索关键词)

 

 

DTSarch/arm64/boot/dts/rockchip/(搜索pdmi2smic-array);

 

 

内核驱动:kernel/sound/soc/rockchip/rockchip_i2s.ckernel/sound/soc/codecs/(搜索 Codec 型号如es8323);

 

 

TinyALSAexternal/tinyalsa/hardware/rockchip/audio/tinyalsa_hal/

 

 

2.工具下载

 

 

音频分析:Audacity(免费)Adobe Audition

 

 

ADB 工具:Android SDK Platform Tools

 

 

五、总结

 

瑞芯微多 MIC 开发的核心是 DTS 配置通道 内核适配 通道 算法处理多通道数据,不同芯片的差异主要在接口(PDM/I2S)与文件路径,开发者可按以下流程快速落地:

 

 

1.确定芯片的 MIC 接口(PDM/I2S)与参考 DTS

 

 

2.配置 DTS cpu_daicodec_daidai-link

 

 

3.测试 8 通道录音,验证硬件正常;

 

 

4.集成第三方算法,对接上层 APP

 

 

附录:多 MIC 开发脑图

 

Mic  

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分