Rockchip 音频常见问题排查指南

电子说

1.4w人已加入

描述

音频问题是嵌入式开发中最让人头疼的一类:现象五花八门(没声音、杂音、变调、断音),根因可能藏在硬件、驱动、DTS、Android HAL 任何一个环节。
这篇文章整理了 Rockchip 平台最常见的音频问题,每个问题都给出现象、排查步骤和解决方案。建议收藏,出问题时直接按图索骥。

一、声卡根本没注册出来

现象

cat /proc/asound/cards 为空,或者没有你期望的声卡。

排查步骤

第 1 步:检查 DTS 配置

 

# 确认设备树里 sound 节点存在且格式正确dtc -I dtb -O dts /boot/dtbs/rockchip/rk3576-evb.dtb | grep -A 20 "simple-audio-card"

 

重点检查:

•sound-dai 的 phandle 是否指向了正确的节点

•子 DAI 节点(如 i2s0、sai1)的status 是否为"okay"

•CODEC 节点是否存在

第 2 步:检查驱动是否加载

 

dmesg | grep -E 'simple-card|snd_soc|ASoC|audio'

 

第 3 步:检查 I2C 设备(外部 CODEC)

 

i2cdetect -y 0

 

如果 CODEC 的 I2C 地址没扫出来,先查硬件:上拉电阻、电源、地址引脚电平。

音频

常见错误速查

内核日志 根因 解决
ASoC: no CODEC DAI found CODEC 节点未定义或 status 不为 okay 检查 DTS 中的 codec 节点
ASoC: failed to instantiate card -19 CPU DAI 驱动未加载 确认 I2S/SAI 驱动编译进内核
snd_soc_register_card failed dai_link 配置错误 检查 sound-dai phandle 是否有效
failed to get clock 时钟未在 DTS 中定义 补充 clocks /clock-names 属性

二、播放完全没声音

这是最高频的问题。按这个流程排查,不要跳步:

流程图

 

播放无声    │    ├── ① 声卡存在? → cat /proc/asound/cards    │       │否 → 回到"声卡未注册"排查    │       │是    │       ▼    ├── ② 设备节点存在? → ls /dev/snd/    │       │否 → 检查 udev / SELinux    │       │是    │       ▼    ├── ③ PCM 状态 RUNNING? → cat /proc/asound/card0/pcm0p/sub0/status    │       │否 → 检查 hw_params 失败原因    │       │是    │       ▼    ├── ④ 时钟正常? → clk_summary | grep i2s    │       │否 → 检查 mclk-fs / PLL 配置    │       │是    │       ▼    ├── ⑤ 输出路径正确? → tinymix | grep path    │       │否 → 设置 Playback Path    │       │是    │       ▼    ├── ⑥ 增益不为 0? → tinymix | grep volume    │       │否 → 设置 DAC Volume    │       │是    │       ▼    ├── ⑦ 有数据波形? → 示波器看 SDO    │       │否 → 检查 DAI 寄存器配置    │       │是    │       ▼    └── ⑧ 扬声器/耳机正常?            │否 → 硬件故障            │是 → 可能是 Android AudioFlinger 层问题

 

每一步的具体操作

步骤③:确认 PCM 状态

 

cat /proc/asound/card0/pcm0p/sub0/status# 应该显示 state: RUNNING

 

如果状态不是 RUNNING,检查 hw_params 是否成功:

 

cat /proc/asound/card0/pcm0p/sub0/hw_params

 

步骤⑤:检查播放路径

 

# Androidtinymix | grep -i "path|output|speaker|headphone"# 设置扬声器输出tinymix "Playback Path" SPK# 或设置耳机输出tinymix "Playback Path" HP

 

步骤⑥:检查增益

 

# 确认 DAC Volume 不为 0tinymix | grep -i "volume|gain|dac"# 设置音量(以 ES8388 为例,范围 0-192)tinymix "DAC Volume" 175

 

步骤⑦:DAPM 电源状态

 

cat /sys/kernel/debug/asoc/*/dapm/widget | grep -E "Headphone|Speaker|DAC"# 确认相关 widget 的状态是 On

 

三、录制完全没声音

排查步骤

第 1 步:检查录制路径

 

tinymix | grep -i "mic|capture|input|record"tinymix "Capture Path" "Main Mic"   # 选择主麦克风

 

第 2 步:检查 MICBIAS
电容麦克风需要偏置电压才能工作:

 

tinymix | grep -i "micbias"tinymix "MICBIAS" 1   # 开启偏置电压

 

第 3 步:检查 ADC 增益

 

tinymix "ADC Volume" 175

 

第 4 步:检查 CODEC 寄存器

 

cat /sys/kernel/debug/regmap/0-001c/registers | grep -i "adc|capture"

 

常见原因速查

原因 解决
MICBIAS 未开启 设置 MICBIAS 控件
录制路径未选择 设置 Capture Path
ADC 增益为 0 设置 ADC Volume
PDM 时钟未配置 检查 PDM 驱动和 DTS

四、播放失真 / 有杂音

先判断失真类型

失真表现 可能原因
大音量时破音 削波失真:DAC 增益过大,超过量程
小音量时粗糙 量化失真:位深不足
音调异常 / 速度异常 时钟失真:BCLK/LRCK 频率错误
规律性断音 断续失真:XRUN、时钟不同步

排查步骤

第 1 步:降低音量测试

 

# 把 DAC 增益降到一半,看是否还破音tinymix "DAC Volume" 100

 

如果降低音量后破音消失,说明是削波失真。调小增益,或检查 CODEC 的满量程输出是否和负载匹配。

第 2 步:检查时钟频率

 

cat /sys/kernel/debug/clk/clk_summary | grep -E 'bclk|lrck'# BCLK 应该 = 采样率 × 位深 × 通道数

 

第 3 步:检查数据格式

 

cat /proc/asound/card0/pcm0p/sub0/hw_params | grep format# 确认格式(S16_LE / S24_LE)和 CODEC 支持的一致

 

五、播放速度过快或过慢

这是时钟问题的典型症状。

根因分析

表现 原因 解决
播放过快 BCLK 频率过高 检查 mclk-fs 配置
播放过慢 BCLK 频率过低 检查 PLL 配置
音调变化 采样率设置错误 确认 hw_params 中的 rate

验证方法

 

# 1. 检查实际时钟频率cat /sys/kernel/debug/clk/clk_summary | grep mclk# 2. 检查播放参数cat /proc/asound/card0/pcm0p/sub0/hw_params | grep rate# 3. 手动计算预期 BCLK# BCLK = rate × width × channels# 例:48000 × 16 × 2 = 1,536,000 Hz

 

如果mclk-fs 配成了 128 但 CODEC 需要 256,MCLK 就会差一倍,所有下游时钟(BCLK、LRCK)都跟着错,最终表现为播放速度快一倍或慢一倍。

六、规律性断音(咔嗒咔嗒)

可能原因

原因 说明 排查
XRUN 缓冲区溢出 / 下溢 echo 7 > /proc/asound/card0/pcm0p/xrun_debug
时钟中断 PM 休眠导致时钟被切 检查电源管理配置
period_size 不匹配 period 和 buffer 比例不当 调整 period/buffer 大小

解决 XRUN

 

# 增大 period 和 bufferaplay -D hw:0,0 --period-size=2048 --buffer-size=8192 test.wav# 或使用 ALSA 插件提供缓冲aplay -D plug:dmix test.wav

 

如果增大 buffer 后仍频繁 XRUN,检查 CPU 负载:

 

top# 看是否有进程占用了大量 CPU,导致来不及填充音频 buffer

 

七、I/O Error

现象

 

tinyplay: error: pcm_write failed: I/O errortinycap: error: pcm_read failed: I/O error

 

排查步骤

第 1 步:检查声卡是否被占用

 

cat /proc/asound/card0/pcm0p/sub0/status# 如果 state: RUNNING 且有 owner_pid,说明被其他进程占用

 

第 2 步:检查 CODEC 是否掉线

 

i2cget -f -y 0 0x1c 0x00 b# 如果返回 I/O error,说明 I2C 通信失败

 

I2C 通信失败常见原因:

•CODEC 复位脚没拉高

•CODEC 电源没起来

•I2C 地址错了

•I2C 总线上拉电阻缺失

第 3 步:检查 DAI 状态

 

cat /sys/kernel/debug/regmap/ff800000.i2s/registers# 检查 DAI 控制寄存器是否被意外复位

 

八、HDMI 音频没声音

排查步骤

 

# 1. 确认 HDMI 声卡存在cat /proc/asound/cards | grep hdmi# 2. 检查 HDMI codec 驱动dmesg | grep hdmi-codec# 3. 检查 DRM 状态(HDMI 音频依赖 DRM 框架)cat /sys/class/drm/card*/status# 4. 检查 HDMI MCLK(通常用 128 倍频)cat /sys/kernel/debug/clk/clk_summary | grep hdmi

 

注意:HDMI 音频需要显示器 / 电视正确识别到 HDMI 信号后才会初始化。如果显示器没点亮,先解决显示问题。

九、排查思路总结

遇到任何音频问题,记住这个优先级:

1.先软后硬:先确认软件配置正确,再上示波器

2.从外到内:声卡注册→ PCM 设备 → 时钟 → 寄存器 → 硬件信号

3.对比验证:用已知正常的配置做对照,缩小变量范围

4.分段隔离:逐步排除可能原因,不要同时改多处

快速决策树

 

问题现象    │    ├── 声卡不存在? → 查 DTS / 驱动加载 / I2C    │    ├── 播放/录制无声? → 查路径 / 增益 / 时钟 / 路由    │    ├── 声音异常(快/慢/变调)? → 查时钟频率 / mclk-fs    │    ├── 杂音/破音? → 查增益 / 格式 / XRUN    │    ├── 规律性断音? → 查 XRUN / buffer / CPU 负载    │    └── I/O Error? → 查声卡占用 / I2C 通信 / CODEC 状态

 

十、还有什么没覆盖到?

这篇文章整理了最常见的问题,但实际项目中总会遇到一些 "奇葩" 情况:

•特定 CODEC 的电源上电时序问题

•多声道数据排列顺序错误

•Android HAL 层路由配置和 DTS 不匹配

•热插拔(耳机插入 / 拔出)时的状态同步问题

你在项目中还遇到过什么奇怪的音频 Bug?欢迎在评论区补充,一起完善这份排查清单。

审核编辑 黄宇

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

全部0条评论

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

×
20
完善资料,
赚取积分