1. 音频系统概述:数字音频基础与总线协议
音频驱动开发的核心是理解声音如何从模拟信号转换为数字数据,再通过系统总线传输到编解码器(Codec)最终驱动扬声器或耳机。本章从数字音频的三个基本参数——采样率、位深、声道——开始,逐步深入到PCM数据流在内存中的组织方式,最后讲解I2S/TDM总线协议如何物理传输这些数据。这些概念是后续配置ALSA驱动和DMA传输的基石。
1.1 数字音频三要素:采样率、位深、声道
模拟声音信号在时间上和幅度上都是连续的。数字音频通过三个维度来描述一段声音:
| 参数 | 定义 | 常见值 | 对音质/带宽的影响 |
|---|---|---|---|
| 采样率 (Sample Rate) | 每秒对模拟信号采样的次数,单位 Hz (kHz) | 8k (电话), 44.1k (CD), 48k (DVD/HDMI), 96k/192k (高解析) | 决定频率上限(奈奎斯特频率 = 采样率/2)。越高越能保留高频细节,但数据量线性增长。 |
| 位深 (Bit Depth) | 每个采样点用多少比特表示幅度,决定动态范围 | 16-bit (CD), 24-bit (录音室), 32-bit float (处理) | 动态范围 ≈ 6.02 × 位深 + 1.76 dB。16-bit 约 96 dB,24-bit 约 144 dB。位深越大,信噪比越高。 |
| 声道数 (Channels) | 独立音频信号的数量 | 1 (Mono), 2 (Stereo), 6 (5.1), 8 (7.1) | 决定空间感和数据并行度。每增加一个声道,数据吞吐量翻倍。 |
工程师经验: 在嵌入式系统中,采样率和位深直接决定了DMA传输的带宽需求。例如,48kHz / 24-bit / 2声道的数据率 = 48000 × 3字节 × 2 = 288,000 字节/秒 ≈ 2.3 Mbps。如果系统总线或DMA通道带宽不足,就会出现断音(XRUN)。
1.2 PCM数据流:从内存到Codec的管道
PCM(Pulse Code Modulation,脉冲编码调制)是数字音频最基础的未压缩格式。在Linux ALSA系统中,PCM数据流是应用程序与音频硬件之间的数据通道。
一个典型的PCM数据流包含以下逻辑层次:
- 应用程序缓冲区: 用户空间程序(如aplay、媒体播放器)填充PCM数据。
- ALSA中间层缓冲区: 内核中的环形缓冲区(Ring Buffer),由ALSA PCM中间层管理。
- DMA传输: DMA控制器将数据从内存搬运到I2S/TDM控制器的FIFO。
- 串行总线: I2S/TDM控制器将并行数据转换为串行位流发送给Codec。
- Codec DAC: 数模转换器将数字位流还原为模拟信号。
PCM数据在内存中的排列(交错模式):
对于2声道、16-bit立体声,一个采样帧(Frame)包含左声道和右声道各2字节,共4字节。
内存顺序:
这种模式称为交错(Interleaved),是嵌入式系统中最常用的格式。
对于2声道、16-bit立体声,一个采样帧(Frame)包含左声道和右声道各2字节,共4字节。
内存顺序:
[L0][R0][L1][R1][L2][R2] ...这种模式称为交错(Interleaved),是嵌入式系统中最常用的格式。
下面这张SVG图展示了PCM数据从应用程序到Codec的完整流动路径:
1.3 I2S总线协议:数字音频的脊梁
I2S(Inter-IC Sound,集成电路内置音频总线)是飞利浦公司制定的串行总线标准,专门用于连接数字音频设备(如CPU与Codec、DSP与Codec)。它使用三根主要信号线:
- BCLK (位时钟): 对应数字信号的每一位。频率 = 采样率 × 位深 × 声道数。
- LRCK (左右声道时钟/帧同步): 指示当前传输的是左声道还是右声道。频率 = 采样率。
- SD (串行数据): 二进制PCM数据,通常以二进制补码格式传输。
I2S标准时序特点:
- LRCK为低电平时传输左声道数据,高电平时传输右声道数据(Philips标准)。
- 数据在BCLK的上升沿被采样,MSB(最高有效位)先传输。
- 数据位宽可以小于BCLK周期数,未使用的BCLK周期填充0。
下面这张SVG图展示了I2S总线的典型时序波形:
1.4 TDM总线协议:多声道扩展
TDM(Time Division Multiplexing,时分复用)是I2S的扩展,允许在一条数据线上传输多个声道。TDM在I2S的三线基础上,将LRCK替换为帧同步信号(FSYNC),并在一个帧周期内划分多个时隙(Slot),每个时隙对应一个声道。
| 特性 | I2S | TDM |
|---|---|---|
| 声道数 | 固定2声道(左/右) | 可配置,最多支持16或32声道 |
| 帧同步信号 | LRCK,50%占空比 | FSYNC,通常为1个位时钟宽度的脉冲 |
| 数据线 | 1条SD | 1条或多条(可配置) |
| 典型应用 | 立体声耳机/麦克风 | 多麦克风阵列、环绕声系统、数字信号处理器互联 |
| 时隙对齐 | LRCK边沿对齐 | FSYNC脉冲后第一个BCLK对齐 |
下面这张SVG图展示了TDM协议在一个帧周期内传输4个声道数据的结构:
1.5 关键参数计算与配置示例
在实际驱动开发中,需要根据硬件规格计算并配置I2S/TDM控制器的时钟分频系数。以下是一个典型的计算流程:
示例:配置I2S接口播放48kHz / 24-bit / 2声道音频
系统主时钟 (MCLK) = 12.288 MHz (常见音频主时钟)
所需BCLK = 48,000 × 24 × 2 = 2,304,000 Hz = 2.304 MHz
BCLK分频系数 = MCLK / BCLK = 12.288 MHz / 2.304 MHz = 5.333...
实际配置时,通常选择整数分频或使用PLL精确合成。许多Codec要求MCLK是采样率的整数倍(如256×fs、384×fs)。
系统主时钟 (MCLK) = 12.288 MHz (常见音频主时钟)
所需BCLK = 48,000 × 24 × 2 = 2,304,000 Hz = 2.304 MHz
BCLK分频系数 = MCLK / BCLK = 12.288 MHz / 2.304 MHz = 5.333...
实际配置时,通常选择整数分频或使用PLL精确合成。许多Codec要求MCLK是采样率的整数倍(如256×fs、384×fs)。
/* 伪代码:I2S控制器时钟配置 */
#define SAMPLE_RATE 48000
#define BIT_DEPTH 24
#define CHANNELS 2
/* 计算BCLK */
uint32_t bclk_freq = SAMPLE_RATE * BIT_DEPTH * CHANNELS; /* 2.304 MHz */
/* 假设MCLK来自外部晶振12.288 MHz */
uint32_t mclk_freq = 12288000;
uint32_t bclk_div = mclk_freq / bclk_freq; /* 分频系数 = 5 */
/* 配置I2S控制器寄存器 */
i2s_regs->I2SCKF = bclk_div - 1; /* 分频值写入时钟分频寄存器 */
i2s_regs->I2SMOD = (CHANNELS == 2) ? I2S_MODE_STEREO : I2S_MODE_MONO;
i2s_regs->I2SDWP = BIT_DEPTH; /* 数据字长配置 */
常见陷阱: 在配置TDM模式时,务必确认Codec支持的时隙数量和位宽。有些Codec要求每个时隙的BCLK数必须等于位深,而有些则允许填充额外的BCLK周期。错误的时隙配置会导致声道错位或数据丢失。