1. 音频基础概念

在嵌入式Linux音频驱动开发中,理解音频的基础概念是第一步。音频信号从自然界的声音到数字设备可处理的二进制数据,经历了从模拟到数字的转换过程。本章将系统梳理这些核心概念,为后续ALSA驱动开发打下坚实的理论基础。

1.1 模拟信号与数字信号

声音在自然界中以模拟信号的形式存在——这是一种连续变化的物理量,通常表现为空气压力的波动。麦克风将这种声压变化转换为连续变化的电压信号,即模拟音频信号。

数字信号则是将模拟信号在时间和幅度上进行离散化处理后的结果,由一系列二进制数值(0和1)表示。数字信号具有抗干扰能力强、易于存储和处理、可无损复制等优势。

核心理解: 模拟信号是连续的,数字信号是离散的。ALSA驱动工作的核心对象是数字化的PCM数据,而非原始的模拟电压。
模拟信号 vs 数字信号 模拟信号(连续) 数字信号(离散) 连续波形,任意时刻都有值 幅度无限精细 离散采样点,仅在固定时刻取值 幅度按位深度量化

1.2 采样率(Sample Rate)

采样率是指每秒从模拟信号中采集的样本数量,单位是赫兹(Hz)或千赫兹(kHz)。根据奈奎斯特采样定理,采样率必须至少为信号最高频率的两倍,才能无失真地重建原始信号。

采样率 常见用途 可还原最高频率
8 kHz 电话语音通信 4 kHz
16 kHz VoIP、语音识别 8 kHz
44.1 kHz CD音质音乐 22.05 kHz
48 kHz DVD、电影、专业音频 24 kHz
96 kHz 高解析度音频 48 kHz
192 kHz 超高解析度录音/混音 96 kHz
驱动开发提示: ALSA驱动中,采样率通过 snd_pcm_hw_params_set_rate() 设置。嵌入式设备通常支持 8kHz、16kHz、44.1kHz、48kHz 等标准采样率。并非所有硬件都支持任意采样率,驱动需要提供 hw_constraints 来声明支持的采样率范围。

1.3 位深度(Bit Depth)

位深度(又称采样精度、量化位数)表示每个样本用多少位二进制数来表示。位深度决定了数字信号的动态范围和信噪比。

位深度每增加1位,量化级数翻倍,动态范围增加约6 dB。常见位深度如下:

  • 8位:256级量化,动态范围约48 dB,常见于早期游戏机、低端语音设备
  • 16位:65536级量化,动态范围约96 dB,CD音质标准
  • 24位:16777216级量化,动态范围约144 dB,专业录音/混音标准
  • 32位:约42.9亿级量化,动态范围约192 dB,常用于浮点处理内部格式
常见误区: 位深度不是越高越好。更高的位深度意味着更大的数据量和更高的处理开销。在嵌入式系统中,16位是性价比最高的选择;24位用于对音质要求较高的场景;32位浮点通常只在DSP或应用层处理时使用,驱动层很少直接处理32位浮点PCM。

1.4 声道数(Channels)

声道数表示音频信号中独立的声音通道数量。不同的声道配置对应不同的听感体验和数据结构布局。

声道数 名称 典型应用
1 单声道(Mono) 语音通话、对讲机、IoT设备
2 立体声(Stereo) 音乐播放、耳机、电视
4 四声道(Quad) 早期环绕声
6 5.1环绕声 家庭影院、电影
8 7.1环绕声 高端影院、游戏

在PCM数据流中,多声道数据采用交错(Interleaved)或非交错(Non-interleaved)两种布局方式:

  • 交错布局:声道样本交替排列,如 L R L R L R ...(立体声),这是ALSA默认和最常用的格式
  • 非交错布局:每个声道的数据连续存放,如 L L L ... R R R ...,需要驱动或应用层特殊处理

1.5 PCM数据格式

PCM(Pulse Code Modulation,脉冲编码调制)是数字音频最基础的编码格式。它将模拟信号经过采样、量化、编码三个步骤转换为二进制数据。

在ALSA驱动中,PCM数据格式由以下参数共同定义:

  • 采样率:每秒样本数
  • 位深度:每个样本的位数
  • 声道数:独立通道数量
  • 字节序:大端(Big Endian)或小端(Little Endian)
  • 符号性:有符号(Signed)或无符号(Unsigned)
  • 样本排列:交错或非交错

ALSA使用 snd_pcm_format_t 枚举类型来标识PCM格式,常见格式包括:

/* ALSA标准PCM格式定义(部分) */
SND_PCM_FORMAT_S16_LE   /* 16位有符号小端,最常用 */
SND_PCM_FORMAT_S16_BE   /* 16位有符号大端 */
SND_PCM_FORMAT_U16_LE   /* 16位无符号小端 */
SND_PCM_FORMAT_S24_LE   /* 24位有符号小端,3字节 */
SND_PCM_FORMAT_S32_LE   /* 32位有符号小端,4字节 */
SND_PCM_FORMAT_FLOAT_LE /* 32位浮点小端 */
SND_PCM_FORMAT_S8       /* 8位有符号 */
SND_PCM_FORMAT_U8       /* 8位无符号 */
驱动开发要点: 在嵌入式Linux中,SND_PCM_FORMAT_S16_LE 是最广泛支持的格式。编写ALSA驱动时,通常优先实现S16_LE格式,再根据硬件能力扩展其他格式。格式转换(如24位转16位)可以在驱动层或ALSA中间层完成。
PCM数据格式与音频流处理流程 模拟信号 连续电压波形 采样 时间离散化 量化 幅度离散化 编码 二进制 PCM数据流 = 采样率 × 位深度 × 声道数 × 交错/非交错布局 例:CD音质 = 44100 Hz × 16 bit × 2 ch = 1411.2 kbps(未压缩) 立体声交错PCM数据流(S16_LE格式) L低字节 L高字节 R低字节 R高字节 L低字节 L高字节 R低字节 R高字节 ... 样本1(左声道) 样本1(右声道) 样本2(左声道) 样本2(右声道) ALSA驱动通过DMA将PCM数据从内存搬运到I2S控制器,再由DAC转换为模拟信号输出 驱动需正确配置采样率、格式、声道数,确保硬件与软件参数一致

1.6 数据率计算

PCM音频流的数据率(比特率)由采样率、位深度和声道数共同决定,计算公式如下:

数据率 (bps) = 采样率 (Hz) × 位深度 (bit) × 声道数

示例:
CD音质:44100 × 16 × 2 = 1,411,200 bps ≈ 1.41 Mbps
电话语音:8000 × 16 × 1 = 128,000 bps = 128 kbps
高清音频:96000 × 24 × 2 = 4,608,000 bps ≈ 4.61 Mbps

在嵌入式系统中,数据率直接影响DMA带宽、内存占用和功耗。驱动开发时需要根据硬件能力合理选择参数组合,避免超出总线带宽或DMA传输上限。

实战建议: 在编写ALSA驱动时,建议在 hw_params 回调中打印当前配置的PCM参数,便于调试:
static int my_pcm_hw_params(struct snd_pcm_substream *substream,
                             struct snd_pcm_hw_params *params)
{
    unsigned int rate = params_rate(params);
    snd_pcm_format_t format = params_format(params);
    unsigned int channels = params_channels(params);
    unsigned int buffer_size = params_buffer_size(params);
    unsigned int period_size = params_period_size(params);

    dev_dbg(dev, "rate=%d, format=%d, channels=%d, "
                 "buffer=%d, period=%d\n",
            rate, format, channels,
            buffer_size, period_size);
    // ... 后续硬件配置
}

1.7 本章小结

本章涵盖了音频驱动开发必须掌握的基础概念:

  • 模拟信号是连续波形,数字信号是离散采样值
  • 采样率决定时间分辨率,需满足奈奎斯特采样定理
  • 位深度决定幅度精度和动态范围
  • 声道数决定空间感和数据布局方式
  • PCM格式是数字音频的基础编码,ALSA通过 snd_pcm_format_t 统一管理