1. 音频系统概述
1.1 嵌入式音频系统组成
嵌入式音频系统通常由硬件层、内核驱动层和用户空间应用层三部分构成。硬件层负责音频信号的采集与回放;驱动层通过ALSA框架向上提供统一的设备节点;应用层则通过ALSA库或第三方音频引擎完成播放、录音与处理。
核心硬件组件:
- 音频编解码器(Codec):完成ADC/DAC转换、音量控制、混音、滤波等模拟与数字信号处理。
- 数字音频接口(DAI):负责数字音频数据的传输,常见接口包括I2S、PCM、TDM、AC97等。
- CPU侧音频控制器:集成在SoC内部,提供DMA引擎、FIFO缓冲和时钟生成,驱动DAI总线与Codec通信。
- 时钟源与电源管理:为音频子系统提供精确的MCLK/BCLK,并管理低功耗状态。
1.2 数字音频基础
数字音频是将连续的模拟声波信号离散化为二进制数据的过程。三个核心参数决定了音频质量与数据量:采样率(Sample Rate)、位深(Bit Depth)和声道数(Channels)。
| 参数 | 定义 | 常见值 | 对质量/带宽的影响 |
|---|---|---|---|
| 采样率 | 每秒对模拟信号采样的次数,单位 Hz | 8k, 16k, 44.1k, 48k, 96k, 192k | 决定最高可还原频率(奈奎斯特频率 = 采样率/2) |
| 位深 | 每个采样点用多少比特表示 | 8, 16, 20, 24, 32 | 决定动态范围(理论 SNR ≈ 6.02 × 位深 + 1.76 dB) |
| 声道数 | 独立音频通道的数量 | 1 (Mono), 2 (Stereo), 5.1, 7.1 | 直接倍增数据速率:数据率 = 采样率 × 位深 × 声道数 |
设计提示: 嵌入式场景中,语音通信常用 16kHz/16bit/Mono(数据率 256kbps),而高保真音乐播放则需 48kHz/24bit/Stereo(数据率 2.304Mbps)。选择参数时需平衡音质与总线带宽、存储空间和功耗。
1.3 I2S / PCM 总线协议
I2S(Inter-IC Sound)和 PCM(Pulse Code Modulation)是嵌入式音频中最常用的数字音频串行总线协议。两者在物理层高度兼容,主要差异在帧同步与数据对齐方式。
1.3.1 总线信号定义
| 信号 | 全称 | 功能描述 |
|---|---|---|
| MCLK | Master Clock | 系统主时钟,频率通常为采样率的 256× 或 512×,用于 Codec 内部 PLL 与数字滤波 |
| BCLK | Bit Clock | 位时钟,每个脉冲对应一位数据,频率 = 采样率 × 位深 × 声道数 |
| LRCLK / FS | Left-Right Clock / Frame Sync | 帧同步信号,I2S 模式下高电平左声道、低电平右声道;PCM 模式下为帧起始脉冲 |
| SD | Serial Data | 串行数据线,通常分为 SDI(输入)和 SDO(输出) |
1.3.2 I2S 协议时序
I2S 由飞利浦(现 NXP)制定,采用左对齐或右对齐数据格式。标准 I2S 模式下,数据在 BCLK 的下降沿变化,在上升沿被接收;LRCLK 在数据发送前一个 BCLK 周期切换,保证 MSB 与 LRCLK 边沿对齐。
1.3.3 I2S 与 PCM 对比
| 对比项 | I2S | PCM(标准模式) |
|---|---|---|
| 帧同步方式 | LRCLK 电平高低区分左右声道 | FS 脉冲指示帧起始,后续时隙依次排列 |
| 数据对齐 | MSB 紧跟在 LRCLK 切换后(延迟 1 BCLK) | MSB 与 FS 脉冲对齐(左对齐)或延迟 N 位 |
| 声道扩展 | 仅支持 2 声道(左/右) | 通过 TDM 模式支持 2/4/8/16 声道 |
| 典型应用 | 立体声音乐播放、耳机输出 | 多麦克风阵列、语音助手、会议系统 |
| Linux 驱动适配 | dai_fmt 设置 SND_SOC_DAIFMT_I2S | dai_fmt 设置 SND_SOC_DAIFMT_DSP_A/B |
常见误区: 许多开发者误以为 I2S 和 PCM 是完全不同的总线。实际上,在嵌入式 Linux 的 DAI 驱动中,两者共享相同的物理引脚(BCLK、FS、SD),差异仅在于帧同步的时序逻辑。ALSA 通过
snd_soc_dai_set_fmt() 中的格式标志来区分,硬件上往往可以配置为兼容模式。
1.4 数据流与时钟关系
音频数据在 I2S/PCM 总线上的传输速率由采样率、位深和声道数共同决定。以下公式用于计算总线 BCLK 频率:
BCLK (Hz) = 采样率 (Hz) × 位深 (bits) × 声道数
示例:
48 kHz × 16 bit × 2 ch = 1.536 MHz
48 kHz × 24 bit × 2 ch = 2.304 MHz
16 kHz × 16 bit × 1 ch = 256 kHz
MCLK 通常为 BCLK 的整数倍,常见倍数为 2×、4×、8×,或直接与采样率成固定比例(如 256×fs、512×fs)。驱动中需通过时钟树配置确保 MCLK、BCLK 和 LRCLK 之间保持精确的整数分频关系,否则会产生时钟抖动或数据错位。
关键设计原则:
- I2S/PCM 总线上的所有时钟必须同源,避免异步时钟域带来的同步问题。
- Codec 的主时钟模式(Master)与 CPU 的从时钟模式(Slave)需匹配,或反之。
- DMA 传输的 FIFO 阈值应设置为至少一个音频帧(如 2 × 16bit = 4 字节)的整数倍,防止 underrun/overrun。