[端侧驰算 · 踩坑记 03] 资源博弈:在树莓派 5 上构建“看、听、说”并发流水线01--听得到与讲得出
[端侧驰算 · 踩坑记 03] 资源博弈:在树莓派 5 上构建“看、听、说”并发流水线01–听得到与讲得出
本文隶属于「端侧AI实战与系统架构」系列,专注嵌入式端侧AI,本篇涉及ALSA与 tinyalsa ,适合对端侧开发、车机、Android 底层音频感兴趣的新手阅读。
工欲善其事必先利其器,任何一个新的平台都应该先验证其硬件配置与基本功能。本文从树莓派 5 音频硬件识别开始,一步步打通“录音 + 播放”链路,并在无标准 ALSA 库环境下,使用 tinyalsa 完成耳返验证,为后续“看、听、说”并发流水线构建打下基础。如果需要展开ALSA深入讲解,请关注并私信我,我会根据实际情况在新的专栏中展开讲解。
目录
一、树莓派 5 麦克风到 /dev 节点的音频通路
1.1 查看音频硬件
cat /proc/asound/cards
执行结果:
0 [Audio ]: USB-Audio - USB Audio
Generic USB Audio at usb-xhci-hcd.1-2, high speed
1 [vc4hdmi0 ]: vc4-hdmi - vc4-hdmi-0
vc4-hdmi-0
2 [vc4hdmi1 ]: vc4-hdmi - vc4-hdmi-1
vc4-hdmi-1

1.2 查看 PCM 设备节点
ls /dev/snd/
执行结果:
by-id by-path controlC0 controlC1 controlC2 pcmC0D0c pcmC0D0p pcmC1D0p pcmC2D0p seq timer
节点结构说明:
/dev/snd/
├── controlC0 # USB Audio 控制接口
├── controlC1 # HDMI 0 控制接口
├── controlC2 # HDMI 1 控制接口
├── pcmC0D0c # USB Audio - 录音设备 (capture)
├── pcmC0D0p # USB Audio - 播放设备 (playback)
├── pcmC1D0p # HDMI 0 - 仅播放
├── pcmC2D0p # HDMI 1 - 仅播放
├── seq # 音序器
└── timer # 定时器
1.3 查看音频设备路由
cat /proc/asound/pcm
执行结果:
00-00: USB Audio : USB Audio : playback 1 : capture 1
01-00: MAI PCM i2s-hifi-0 : MAI PCM i2s-hifi-0 : playback 1
02-00: MAI PCM i2s-hifi-0 : MAI PCM i2s-hifi-0 : playback 1
查看完整 USB 音频路由拓扑:
cat /proc/asound/card0/stream0
执行结果:
Generic USB Audio at usb-xhci-hcd.1-2, high speed : USB Audio
Playback:
Status: Stop
Interface 2
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 44100
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 2
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 44100
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Interface 2
Altset 3
Format: S16_LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 48000
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 2
Altset 4
Format: S24_3LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 48000
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Interface 2
Altset 5
Format: S16_LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 96000
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 2
Altset 6
Format: S24_3LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 96000
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Interface 2
Altset 7
Format: S16_LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 192000
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 2
Altset 8
Format: S24_3LE
Channels: 2
Endpoint: 0x02 (2 OUT) (ADAPTIVE)
Rates: 192000
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Capture:
Status: Stop
Interface 1
Altset 1
Format: S16_LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 44100
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 1
Altset 2
Format: S24_3LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 44100
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Interface 1
Altset 3
Format: S16_LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 48000
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 1
Altset 4
Format: S24_3LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 48000
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Interface 1
Altset 5
Format: S16_LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 96000
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 1
Altset 6
Format: S24_3LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 96000
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
Interface 1
Altset 7
Format: S16_LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 192000
Data packet interval: 1000 us
Bits: 16
Channel map: FL FR
Interface 1
Altset 8
Format: S24_3LE
Channels: 2
Endpoint: 0x81 (1 IN) (ASYNC)
Rates: 192000
Data packet interval: 1000 us
Bits: 24
Channel map: FL FR
1.4 音频数据流通路(美观版流程图)
🎤 录音通路(USB 麦克风 → 应用程序)
┌─────────────────┐
│ USB 麦克风硬件 │
└────────┬────────┘
↓
┌─────────────────┐
│ USB 物理接口 │
│ xhci-hcd.1-2 │
└────────┬────────┘
↓
┌─────────────────┐
│ USB Audio 驱动 │
│ snd-usb-audio │
└────────┬────────┘
↓
┌─────────────────┐
│ ALSA 核心层 │
└────────┬────────┘
↓
┌─────────────────┐
│ 设备节点文件 │
│ /dev/snd/pcmC0D0c │
└────────┬────────┘
↓
┌─────────────────┐
│ 用户应用程序 │
└─────────────────┘
🔊 播放通路(应用程序 → 音箱/HDMI)
┌─────────────────┐
│ 用户应用程序 │
└────────┬────────┘
↓
┌───────────────────────────────┐
│ 设备节点(三选一) │
│ • /dev/snd/pcmC0D0p USB 输出 │
│ • /dev/snd/pcmC1D0p HDMI 0 │
│ • /dev/snd/pcmC2D0p HDMI 1 │
└───────────────┬───────────────┘
↓
┌─────────────────┐
│ 对应硬件驱动 │
└────────┬────────┘
↓
┌─────────────────┐
│ USB 音箱 / HDMI │
└─────────────────┘
🔁 完整音频分层流转架构
┌─────────────────────────────────────────────────────┐
│ 硬件层 │
│ USB Audio Class 2.0 设备 │
└───────────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ USB 驱动层 │
│ xhci-hcd → snd-usb-audio │
└───────────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 内核缓冲层 │
│ DMA 环形缓冲区 & 中断 │
└───────────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ ALSA 中间层 │
│ 格式转换 · 声道映射 · 采样率规整 │
└───────────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 路由混音层 │
│ 多路复用 · 混音 · 通路控制 │
└───────────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 设备节点层 │
│ /dev/snd/controlC* / pcmC*D* │
└───────────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 用户空间 │
│ tinycap / tinyplay / 业务APP │
└─────────────────────────────────────────────────────┘
二、环境问题:无音频库,直接操作 PCM 节点失败
直接 open /dev/snd/pcmC0D0c 这类节点是无法直接录音播放的,必须完成 ALSA 底层初始化流程,否则会出现设备无法打开、参数配置失败等问题。
常见环境缺失表现:
-
系统中无
aplay、arecord等基础音频工具 -
缺失
libasound2-dev等 ALSA 开发库,无法编译依赖 ALSA 的程序 -
嵌入式/样机环境禁止联网,无法通过 apt 命令安装任何依赖
环境检查常用命令:
# 查看是否有 aplay 工具
which aplay
# 查看 tinyalsa 头文件是否存在
ls /usr/include/tinyalsa/ 2>/dev/null
# 查看系统是否有 ALSA 相关库文件
ls /usr/lib/*asound* 2>/dev/null
# 全局查找 arecord 工具
find / -name "arecord" 2>/dev/null
# 查找系统中所有音频相关工具
find /system /vendor -name "*audio*" 2>/dev/null
三、解决办法与取舍
多数教程都会直接让你执行以下命令,快速安装 ALSA 开发库,从而完成音频验证:
sudo apt install libasound2-dev
但在真实量产、车机样机、嵌入式离线环境中,这种方式是不现实的——设备往往无外网权限,且不允许随意安装第三方库。我在面试端侧音频方向候选人时,也会重点询问 ALSA 底层细节,核心目的就是识别候选人能否脱离“教程式安装”,直接上手解决真实环境的问题,而非背诵八股文。
方案对比与取舍:
路径 A:直接调用内核 ALSA API
-
优点:最底层、零依赖,完全脱离第三方库,适配所有 Linux 嵌入式环境
-
缺点:接口复杂,需深入理解 ALSA 内核的 ioctl 控制机制,调试难度高、耗时久
-
结论:适合专门花时间深入研究 ALSA 内核原理,现阶段为了快速打通音频链路,不使用此方案。
-
如果对希望博主对ALSA进行深入讲解,请关注和私信。
路径 B:使用 tinyalsa(推荐)
-
优势:体积小、无冗余依赖,大量 Android 设备、车机黑盒样机默认内置;接口简洁,易上手,可静态编译,一次编译可在多台设备复用;贴近真实生产环境,同时能为后续深入学习 ALSA 内核打下基础
-
结论:优先选择,既能快速打通“录音+播放”链路,又能贴合实际开发场景,性价比最高
四、tinyalsa 源码编译安装
推荐通过源码编译的方式安装 tinyalsa,可灵活适配树莓派 5 环境,同时便于后续查看源码、深入学习:
git clone https://github.com/tinyalsa/tinyalsa.git
cd tinyalsa
make
编译完成后,会在项目的 utils/ 目录下生成两个核心工具:
-
tinycap:用于录制 PCM 原始音频数据 -
tinyplay:用于播放 PCM 原始音频或 WAV 音频文件
小贴士:tinyalsa 源码是学习 ALSA 机制的优质素材,可配合 AI 辅助理解源码逻辑,但切勿完全依赖 AI 结论,需结合实际调试验证。如果对AI在嵌入式开发中的使用感兴趣的朋友可以关注和私信我。
五、功能实测:录音 + 播放
编译完成后,通过 tinycap 和 tinyplay 工具,可快速实现功能,验证音频链路是否完全打通。
5.1 录制 PCM 原始音频
./utils/tinycap test.raw -D 0 -d 0 -c 2 -r 44100 -b 16 -t 5
参数说明(重点标注):
-
-D 0:指定声卡卡号为 0(对应前文查到的 USB Audio 设备) -
-d 0:指定设备号为 0 -
-c 2:设置录音声道为双声道(立体声) -
-r 44100:设置采样率为 44.1kHz(主流音频采样率,适配大多数设备) -
-b 16:设置音频位深为 16bit(兼顾音质与存储) -
-t 5:设置录制时长为 5 秒(可根据需求调整)
5.2 播放音频
# 播放刚才录制的 PCM 原始音频文件
./utils/tinyplay test.raw -D 0 -d 0 -c 2 -r 44100 -b 16
# 若有 WAV 文件,可直接播放(无需指定格式参数)
./utils/tinyplay test.wav -D 0 -d 0
执行成功后,即可通过音箱/HDMI 设备听到刚才录制的声音,证明树莓派 5 的音频“录音+播放”链路已完全打通。
六、查看 PCM 设备状态信息
在调试音频问题(如设备占用、格式不匹配)时,可通过以下命令查看 PCM 设备的详细状态信息,辅助定位问题:
cat /proc/asound/card0/pcm0c/info # 查看录音设备(pcm0c)状态
cat /proc/asound/card0/pcm0p/info # 查看播放设备(pcm0p)状态
七、下期预告
至此,音频的录音和播放已经验证完成。你是否也在思考路径A该如何实现?在评论区发表你的意见吧。
下期继续主线:
[端侧驰算 · 踩坑记 03] 资源博弈:在树莓派 5 上构建“看、听、说”并发流水线02–听得懂
标签:#树莓派5 #嵌入式开发 #ALSA #音频 #端侧AI
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)