2. 音频信号基础回顾:采样率、量化、Nyquist定理、dB与信噪比、短时傅里叶变换(STFT)原理

做语音算法部署这些年,我见过不少同事在滤波器参数调优时翻车。翻车的原因往往不是算法本身多复杂,而是对音频信号的基础概念理解不够扎实。说白了,采样率、量化、Nyquist 定理这些东西,就是咱们吃饭的碗。碗要是漏了,菜做得再香也白搭。

这一章咱们就把这些基础再过一遍。我会结合项目里踩过的坑来讲,争取让你看完就能用上。

2.1 采样率:时间轴上的离散化

模拟信号是连续的,计算机只能处理离散的点。采样,就是每隔一个固定的时间间隔,抓一个信号值。

这个间隔的倒数,就是采样率。单位是 Hz(赫兹)。

常见采样率速查表

采样率 典型用途 最高可表示频率
8 kHz 电话语音、对讲机 4 kHz
16 kHz 语音识别、语音增强 8 kHz
44.1 kHz CD 音质、音乐 22.05 kHz
48 kHz 影视、专业音频 24 kHz

我个人习惯在做降噪滤波器时,先用 16 kHz。为什么?因为人声的主要能量集中在 4 kHz 以下,16 kHz 采样率既能保留足够的信息,又能减少计算量。你想想看,在嵌入式设备上,每降低一倍的采样率,计算量可能减少 40% 以上。

经验之谈: 我曾经在一个项目里,为了追求所谓的"高保真",把采样率设成了 48 kHz。结果算法在开发板上跑不动,帧长调短了又导致频率分辨率不够。最后老老实实降到 16 kHz,问题全解决了。选采样率,够用就好。

2.2 量化:幅度轴上的离散化

采样解决了时间轴的问题,量化解决的是幅度轴的问题。每个采样点的幅度值,需要用有限个比特来表示。

最常见的量化位深是 16 位,也就是用 2^16 = 65536 个等级来表示一个采样点的幅度。听起来很多对吧?但在实际项目中,量化误差带来的噪声是真实存在的。

量化误差的公式很简单:

量化步长 Δ = 满量程范围 / 2^B
其中 B 是位深

量化噪声的功率大约是 Δ²/12。这个噪声是白噪声,均匀分布在 0 到 fs/2 的频带内。

注意: 量化噪声是加性的。如果你的信号本身动态范围很小,比如只有 -30 dBFS,而量化噪声在 -96 dBFS(16 位),那信噪比还有 66 dB,问题不大。但如果你做增益放大,把信号抬高了 40 dB,量化噪声也会被一起放大。我曾经在调试一个 ANC(主动降噪)算法时,就因为没注意量化噪声的放大,导致低频段出现了可闻的底噪。排查了两天才找到原因。

2.3 Nyquist 定理:采样率的底线

Nyquist 定理是音频信号处理里最硬的约束之一。它的核心就一句话:

采样率必须大于信号最高频率的两倍。

数学表达:fs > 2 * f_max

如果违反了这个定理,就会发生混叠(Aliasing)。混叠的意思是,高频信号会伪装成低频信号混进来,而且一旦混进来,就再也分不开了。

举个例子:

  • 信号频率:7 kHz
  • 采样率:8 kHz
  • Nyquist 频率:4 kHz
  • 结果:7 kHz 的信号会被混叠成 1 kHz 的信号(因为 8 - 7 = 1)

你想想看,本来想滤掉 7 kHz 的噪声,结果它变成了 1 kHz 的信号,跟人声混在一起。这滤波器还怎么设计?

避坑指南: 我在做语音采集前端时,经常发现 ADC 芯片自带的抗混叠滤波器不够陡峭。尤其是低成本方案,截止频率之后还有不少能量残留。我的做法是:在数字域再加一个低通滤波器,把 Nyquist 频率以上的能量再压一压。虽然多了一步计算,但能省掉后面无数的调试时间。

2.4 dB 与信噪比:衡量信号质量的标尺

dB(分贝)是个对数单位。为什么要用对数?因为人耳对声音的感知是对数的,而且音频信号的动态范围太大了,从 0 dB SPL(听阈)到 120 dB SPL(痛阈),差了 100 万倍。用线性坐标根本没法看。

常用的 dB 定义:

功率比:dB = 10 * log10(P1 / P2)
幅度比:dB = 20 * log10(A1 / A2)

信噪比(SNR)就是信号功率与噪声功率的比值,也用 dB 表示。

SNR 计算公式:

SNR(dB) = 10 * log10( P_signal / P_noise )

或者用幅度:SNR(dB) = 20 * log10( A_signal / A_noise )

在实际项目中,我经常用 SNR 来评估降噪滤波器的效果。比如:

  • 输入 SNR:5 dB(噪声比信号还大)
  • 输出 SNR:15 dB(提升了 10 dB)
  • 这个滤波器就算合格了

但要注意,SNR 提升 10 dB 听起来不多,实际上噪声功率已经降到了原来的 1/10。人耳能明显感觉到区别。

注意: 计算 SNR 时,一定要保证信号和噪声是同步对齐的。我曾经犯过一个低级错误:用不同时间段的信号和噪声来计算 SNR,结果算出来 30 dB,实际听起来噪声大得离谱。后来才发现是时间窗没对齐。做评估时,时间对齐是第一步。

2.5 短时傅里叶变换(STFT):时频分析的基石

傅里叶变换告诉我们信号里有哪些频率成分,但它丢失了时间信息。对于语音这种非平稳信号,我们需要知道"在什么时间出现了什么频率"。STFT 就是干这个的。

STFT 的核心思想很简单:把信号切成一小段一小段,对每一段做傅里叶变换。

STFT 的步骤:
1. 选择一个窗函数(汉宁窗、海明窗等)
2. 将窗函数与信号相乘,截取一段
3. 对这一段做 FFT
4. 滑动窗函数,重复步骤 2-3

这里有两个关键参数:

  • 帧长(window size): 每段信号的长度,决定了频率分辨率
  • 帧移(hop size): 窗函数滑动的步长,决定了时间分辨率

帧长和帧移是一对矛盾:

参数 频率分辨率 时间分辨率
帧长大 高(能区分相近频率) 低(时间定位模糊)
帧长小 低(频率模糊) 高(能捕捉瞬变)

在降噪滤波器里,我一般这样选:

  • 语音降噪:帧长 512 点(16 kHz 下约 32 ms),帧移 128 点(50% 重叠)
  • 音乐降噪:帧长 1024 点(44.1 kHz 下约 23 ms),帧移 256 点

经验之谈: 窗函数的选择也很重要。汉宁窗(Hann)的旁瓣衰减好,适合做降噪;海明窗(Hamming)的主瓣窄一点,适合做频谱分析。我习惯用汉宁窗,因为它的旁瓣衰减更快,能减少频谱泄漏。有一次我在做噪声估计时,用了矩形窗,结果频谱泄漏导致噪声谱估计严重偏差,滤波器把语音也削掉了。换成汉宁窗后,问题立刻解决。

下面这张图展示了 STFT 的完整流程:

短时傅里叶变换(STFT)流程图 输入信号 x[n] 分帧 + 加窗 FFT 频谱 X[m,k] 帧移(hop) 循环直到信号结束 关键参数说明: • 帧长 N:决定频率分辨率 Δf = fs / N • 帧移 H:决定时间分辨率,通常取 N/2 或 N/4 • 窗函数:减少频谱泄漏,常用汉宁窗、海明窗

STFT 的输出是一个复数矩阵 X[m, k],其中 m 是帧索引,k 是频率索引。这个矩阵就是我们在频域做降噪处理的基础。

在后续章节中,我们会基于 STFT 的频谱来设计各种降噪滤波器。比如谱减法、维纳滤波、MMSE 估计等,都是在 STFT 的框架下工作的。

本章核心要点:

  • 采样率决定时间分辨率,必须满足 Nyquist 定理
  • 量化位深决定动态范围,16 位是语音处理的底线
  • dB 是对数单位,SNR 是评估降噪效果的核心指标
  • STFT 是时频分析的基础,帧长和帧移的选择直接影响算法性能