跳转至

RDK S100 音频子板入门

课程定位: 在 RDK S100 上完成 Audio Driver HAT REV2 音频子板的安装、驱动加载、设备识别、录音与播放验证,并掌握 8 通道录音与回采(AEC 参考信号)的进阶用法。

适用硬件: RDK S100

系统版本: RDK OS(S100)

配套资料: 视频讲解(录制中)/ 本讲义 / 官方音频文档


给机器人加上「听」和「说」的能力,最常用的方案就是一块 40pin 音频子板。在 RDK S100 上接音频子板时,新用户最容易卡住的不是命令,而是三件事:装了子板但系统里没有声卡;分不清录音和播放各自该用哪个设备号;想让算法拿到「喇叭实际播了什么」却不知道回采藏在哪。本课按照「先侦察 → 再操作 → 最后验证」的顺序,把音频子板在 S100 上完整跑通一遍。

1. 学习目标

完成本课后,你将能够:

  1. 说出子板上三颗芯片各自的职责(2× ES7210 录音、1× ES8156 播放)
  2. 正确完成 40pin 物理连接与拨码开关切换(40 PIN 拨码左拨、PCM 拨码右拨)
  3. modprobe 加载音频驱动,并通过 cat /proc/asound/cardsls /dev/snd/ 确认声卡 s100snd2 注册成功
  4. arecord / aplay 完成一次「录音 → 播放」闭环,并说清录音 hw:0,0、播放 hw:0,1 的设备号方向
  5. amixer 查询和调整播放音量
  6. 完成 8 通道录音,定位通道 7/8 的回采信号并用 Audacity 验证
  7. 排查「没声卡 / 打不开设备 / 没声音」三类常见问题

2. 准备材料

物料 数量 说明
RDK S100 1 已烧录系统,可通过 SSH 访问
微雪 Audio Driver HAT REV2 1 40pin 接入;2× ES7210 + 1× ES8156
耳机或喇叭 1 接子板 3.5mm 接口
(可选)模拟麦克风 4 用于麦克风阵列通道

3. 音频系统全景:三条侦察命令

S100 的音频模块基于标准 ALSA 框架实现,用户空间直接使用 alsa-lib 提供的 arecord / aplay / amixer 等工具测试。每一次录音和播放,最终都落到 ALSA 管理的三个层次上:

声卡(Card)      —— 一块物理音频硬件 = 一个序号
  └─ PCM 设备(Device) —— 卡上的功能端点,分播放与录音
       └─ 设备节点(Node) —— /dev/snd/ 下的文件,程序实际打开的东西

举例:pcmC0D0c 的意思是「声卡 0、PCM 设备 0 的录音端点」(c = capture,p = playback)。理解这个命名规则,后面的命令参数就不再是玄学。

在动任何配置之前,先记住这三条命令,本课每一段都会用到:

# 1. 看系统里注册了哪些声卡(最重要的一条)
cat /proc/asound/cards

# 2. 看用户空间的设备节点
ls /dev/snd/

# 3. 看录音/播放设备列表
arecord -l
aplay -l

侦察的意义: 你操作 -D hw:X,Y 参数时,X 就是 cat /proc/asound/cards 里的声卡序号,Y 就是 arecord -l / aplay -l 里的设备号。先侦察再操作,参数永远有据可查。

设备号方向:S100 的录音在前、播放在后

接好子板、加载驱动后,S100 会注册出一张声卡,包含两个 PCM 端点:

设备节点 含义 hw 参数 用途
pcmC0D0c 声卡 0 · 设备 0 · 录音 hw:0,0 arecord 录音
pcmC0D1p 声卡 0 · 设备 1 · 播放 hw:0,1 aplay 播放

注意这个方向:录音在 hw:0,0,播放在 hw:0,1。很多教程默认「0,0 是播放」,在 S100 上直接照搬就会报「打不开设备」。别背结论——每次先看 ls /dev/snd/ 里节点名末尾的 cp,方向永远不会错。

4. 认识音频子板:两颗录音 Codec + 一颗播放 Codec

本课使用的子板是微雪电子的 Audio Driver HAT REV2,通过 40pin 与 S100 开发板连接。板上的音频芯片分两组:

芯片 数量 I2C 地址 职责 通道
ES7210 2 颗 0x40 / 0x42 录音 最多 8 通道:4 路模拟麦克风 + 2 路 AEC 回采
ES8156 1 颗 0x8 播放 2 通道,接耳机或喇叭

记住这个分工,后面所有现象都能对上:

  • 录音走 ES7210,所以 8 通道录音、麦克风阵列、回采都发生在录音设备上;
  • 播放走 ES8156,只有 2 通道,接耳机或者喇叭出声;
  • 4 路模拟麦克风拾音,2 路回采「喇叭实际播出的信号」——后者就是回声消除算法要的参考信号。

5. 硬件安装:40pin 连接与拨码开关

5.1 物理连接

断电状态下,将子板对准 S100 的 40pin header 接入,注意方向对齐、插紧。

5.2 拨码开关:引脚功能切换

关键:S100 的 40pin 上,PCM 音频引脚与 PCIE 的 Wi-Fi 模组引脚是复用的。 硬件上通过拨码开关决定这组引脚当前给谁用。接音频子板前,必须把拨码切到 PCM 一侧:

上面的 40 PIN 拨码  →  左拨
下面的 PCM 拨码     →  右拨

两个开关都要动,只拨一个引脚功能没有完成切换。

拨错了会怎样? 引脚还连在 Wi-Fi 模组一侧,子板物理上插着、电路上却不通——驱动加载正常,声卡也可能不出现或录音全零。排查「子板装了但没反应」,第一步永远是检查拨码。

6. 驱动加载与设备识别

6.1 加载驱动

S100 的声卡模块默认以内核模块(ko)形式存在,动态加载:

modprobe hobot_cpudai_super
modprobe snd-soc-es8156
modprobe snd-soc-es7210
modprobe hobot_snd_super_ac_fdx_host

四条对应驱动链路的四段:CPU DAI(I2S 控制器)→ 播放 Codec → 录音 Codec → 声卡装配。最后一条执行完,声卡才算组装完成。

6.2 侦察验证

# 1. 声卡列表:出现 s100snd2 = 加载成功
root@ubuntu:~# cat /proc/asound/cards
 0 [s100snd2       ]: s100snd2 - s100snd2
                      s100snd2

# 2. 设备节点:一录一放一控制
root@ubuntu:~# ls /dev/snd/
controlC0  pcmC0D0c  pcmC0D1p  timer

对照第 3 节的方向表:pcmC0D0c → 录音 hw:0,0pcmC0D1p → 播放 hw:0,1

7. 录音与播放:最简闭环

7.1 录音

# 录 5 秒,48kHz / 2ch / 16bit,保存为 wav
arecord -Dhw:0,0 -c 2 -r 48000 -f S16_LE -t wav -d 5 test.wav

参数逐个对应:-D hw:0,0 设备(侦察结果)、-c 2 声道数、-r 48000 采样率、-f S16_LE 样本格式、-t wav 文件类型、-d 5 录制秒数。数据格式可按需求调整。

7.2 播放

aplay -Dhw:0,1 test.wav

aplay 会解析 wav 文件头获取格式并写入驱动,所以播放命令不需要重复指定声道/采样率。

成功标准: 录制时终端输出 Recording WAVE ... 且无报错;播放时耳机/喇叭里清楚听到刚才录下的声音。

为什么用 16bit(S16_LE)录制?

如果按 24bit(S24_LE)录制,板端 aplay 回放正常,但把文件下载到电脑播放很可能全是噪声:ALSA 的 S24_LE 是「24bit 装在 32bit 容器里」(每样本 4 字节),而 WAV 标准的 24bit 是每样本 3 字节。arecord 写出的文件头标 24bit、数据却是 4 字节/样本,电脑播放器按 3 字节切数据就整体错位。板端往返自洽,不代表文件本身标准。录制 16bit(S16_LE)即可——板端、电脑端都正常。

7.3 音量控制(amixer)

# 查询当前 codec 的所有控制项及取值
amixer scontrols
amixer scontents

# 调整播放音量(以 DAC 控制项为例)
amixer sset 'DAC' 120
amixer sget 'DAC'

调整前同样先确认目标声卡——多声卡场景下用 amixer -c 0 ... 指定卡号,避免改错卡。

8. 进阶:8 通道录音与回采

8.1 回采是什么、为什么需要它

回采(loopback)是把「播放通道的信号」同步采回来,作为参考信号供回声消除(AEC)等算法使用。在这块子板上,回采信号映射在录音通道 7 和 8

通道 用途
ch1–ch4 4 路模拟麦克风
ch7–ch8 播放回采参考信号

8.2 8 通道录音

arecord -Dhw:0,0 -c 8 -r 48000 -f S16_LE -t wav -d 5 ./8chn_test.wav --period-size=256 --buffer-size=1024

注意 --period-size:S100 的 PDMA 驱动要求数据大小满足 64 字节对齐,period-size 的设置值必须满足这个对齐要求,否则无法正常工作。

8.3 录放同步验证回采

回采录的是「播放通道的信号」,所以要边播边录,并保持同一个 I2S 上通道数、位深、采样率对齐(这块子板根据拨码开关固定了一路 I2S):

# 终端 A:开启 8 通道录音(时间留足,方便切到终端 B)
arecord -Dhw:0,0 -c 8 -r 48000 -f S16_LE -t wav -d 30 ./8chn_capture.wav --period-size=256 --buffer-size=1024

# 终端 B:同时播放格式对齐的音频(如自制的 1kHz 正弦波)
aplay -Dhw:0,1 1khz.wav --period-size=1024 --buffer-size=1024

录制完成后,用 Audacity 等音频分析软件打开 8chn_capture.wav

  • ch1–ch4 出现麦克风拾到的声音 → 麦克风通路正常;
  • ch7–ch8 出现与播放内容一致的 1kHz 频谱 → 回采功能正常。

成功标准: 8 通道文件生成;对着麦克风说话时 ch1–ch4 有波形,播放时 ch7–ch8 有对应信号。

9. 常见问题排查

Q1:子板装了,cat /proc/asound/cards 里没有 s100snd2

按顺序查三件事:① 拨码开关——40 PIN 拨码是否左拨、PCM 拨码是否右拨;② 四条 modprobe 是否都执行且无报错;③ dmesg 里有无 codec/I2S probe 失败信息。

Q2:打开设备节点报错?

  • cannot open device ... No such file or directory:驱动没加载成功或 card/device 号写错,回到侦察命令;
  • cannot set hw params: Unknown error -22:参数超出驱动支持范围(采样率/位宽/通道数的交集),改回支持的取值;
  • 打开节点卡住、无任何日志:ALSA 允许单个设备同一时刻只打开一次,检查是否有上一个进程没退出。

Q3:命令执行成功但没有声音?

按顺序查:① 目标声卡号对不对(重新侦察);② 播放设备号是否用了 hw:0,1(不是 0,0);③ 音量是否被 amixer 调到 0;④ 播放文件格式与设备能力是否匹配。

Q4:录音/播放出现「呲呲」或断续杂音?

大概率发生了 xrun(播放侧 underrun / 录音侧 overrun:应用读写速度跟不上硬件)。可尝试调大 period-size、把录音文件写到更快的存储上排查 IO 瓶颈;频发且无法恢复时需进一步定位驱动或应用实现。

Q5:pcm_read/pcm_write 返回 -5 / -32 / -16 是什么意思?

-5:DMA 或中断异常(检查寄存器配置与硬件链接);-32:发生 xrun;-16:录音过程中时钟断掉或硬件连接中断(S100 做 slave 时)。

10. 总结

一图收束本课主线:

硬件就位(40pin 对齐插紧 + 拨码切换:40PIN 左拨 / PCM 右拨)
驱动加载(modprobe ×4 → s100snd2 出现在 cards)
   ↓ 侦察(cards → /dev/snd → 确认 D0c 录音 / D1p 播放)
录放闭环(arecord hw:0,0 → aplay hw:0,1)
进阶回采(8ch 录音,ch7/8 = 播放参考信号,格式对齐)
验证(耳朵听到 + Audacity 看到各通道波形)
  • 一块子板三颗芯片: 2× ES7210 管录音(8ch 含回采),1× ES8156 管播放(2ch);
  • 引脚复用是 S100 的特色坑: 拨码决定 40pin 上的引脚给音频还是给 Wi-Fi;
  • 参数有据可查: period-size 记住 64 字节对齐;录音 hw:0,0、播放 hw:0,1ls /dev/snd/ 为准。

拓展练习: 用 8 通道录音同时录下「麦克风说话 + 喇叭播放音乐」,在 Audacity 里对比 ch1–ch4 与 ch7–ch8 的波形差异,直观理解 AEC 参考信号的意义。

11. 参考链接