3、音频信号基础:采样定理、量化与位深、dB与声压级、时域与频域表示

好,咱们正式开始讲干货了。

做助听器降噪,说白了就是在跟「声音」打交道。但数字芯片里的声音,跟咱们耳朵听到的声音,其实是两码事。你得先搞懂数字音频的底层逻辑,后面写代码、调参数才不会懵。

这一章,我把几个最基础、也最容易踩坑的概念串起来讲。采样定理、量化位深、dB、时域频域——嗯,都是老生常谈,但我在项目里见过太多人在这上面翻车。

3.1 采样定理:别让信号「假摔」

先问个问题:模拟信号是连续的,数字信号是离散的。怎么用离散的点,还原出连续的波形?

答案就是采样定理,也叫奈奎斯特定理。说白了就一句话:采样频率必须大于信号最高频率的两倍

核心公式:

f_s > 2 × f_max

其中 f_s 是采样率,f_max 是信号中的最高频率成分。

举个例子。助听器通常处理的音频带宽是 8kHz(高频损失的用户,再高也听不见了)。那采样率至少得 16kHz。实际产品里,我常用 16kHz 或 24kHz。为什么?留点余量,给抗混叠滤波器一点喘息空间。

避坑指南:

我曾经在一个项目里,为了省功耗,把采样率压到刚好 16kHz。结果高频段出现严重的混叠噪声,怎么调降噪算法都没用。后来一查,是前端模拟滤波器的截止特性不够陡,16kHz 采样根本扛不住。从那以后,我习惯采样率至少留 20% 的余量。

混叠是什么?就是高频信号「伪装」成低频信号混进来。你想想看,一个 9kHz 的信号,用 16kHz 采样,出来的结果跟 7kHz 一模一样。降噪算法一看,哎这有个 7kHz 的噪声,给我干掉——结果把真实信号也削了。

3.2 量化与位深:精度和动态范围的博弈

采样是把时间离散化,量化就是把幅度离散化。

每个采样点,都得用一个二进制数来表示。这个二进制数的位数,就是位深(bit depth)。

位深 量化级数 动态范围(理论) 常见应用
8 bit 256 ~48 dB 语音通信(早年电话)
16 bit 65536 ~96 dB CD、助听器主流
24 bit 16777216 ~144 dB 专业录音、高端助听器
32 bit float —— 极大 算法内部处理

我个人习惯,在助听器芯片里,ADC 出来用 16 bit 就够了。为什么?因为助听器的麦克风、受话器本身的动态范围也就 80-100 dB,你用 24 bit 纯属浪费功耗和内存。

但注意,算法内部处理一定要用高精度。我在定点 DSP 上做降噪时,中间变量至少用 32 bit,甚至用 40 bit 累加器。否则,量化噪声会一点点累积,最后输出全是「嘶嘶」声。

小技巧:

量化误差本质上是一种噪声。它的功率跟 LSB(最低有效位)的平方成正比。每增加 1 bit,信噪比提升约 6 dB。所以,别小看那 1 bit,有时候就是它决定了你的降噪底噪能不能做到 20 dB 以下。

3.3 dB 与声压级:算法工程师的「度量衡」

做音频算法,你天天跟 dB 打交道。但很多人对 dB 的理解,其实模模糊糊。

dB 不是一个绝对单位,它是一个比值。说白了,就是「这个信号比那个信号大多少」。

在助听器领域,最常用的是这几个:

  • dB SPL(声压级):绝对单位,以 20 μPa 为参考。0 dB SPL 是人耳能听到的最小声。
  • dB FS(满量程):数字域的单位,0 dB FS 是 ADC 能表示的最大值。
  • dB A:加了 A 计权的声压级,模拟人耳对不同频率的敏感度。

我记得刚入行时,有个同事把 dB SPL 和 dB FS 直接混用,结果增益算出来差了 30 dB。用户戴上助听器,差点没把耳朵震聋。嗯,从那以后,我每次写代码都要在注释里标清楚:这个变量是 dB SPL 还是 dB FS。

实用换算:

// 功率比转 dB
dB = 10 * log10(P1 / P2)

// 幅度比转 dB
dB = 20 * log10(A1 / A2)

// 数字域:假设 16 bit 满量程是 ±32767
// 一个采样值 16384,对应 -6 dB FS
dB_FS = 20 * log10(|sample| / 32767)

为什么降噪算法里老用 dB?因为人耳对声音的感知是对数的。你从 50 dB 加到 60 dB,感觉变化很大;但从 80 dB 加到 90 dB,感觉变化没那么明显。用 dB 做计算,正好匹配人耳的听觉特性。

3.4 时域与频域:降噪算法的「两副眼镜」

同一个信号,从不同角度看,完全不一样。

  • 时域:横轴是时间,纵轴是幅度。你看的是「声音怎么随时间变化」。
  • 频域:横轴是频率,纵轴是幅度(或能量)。你看的是「声音里有哪些频率成分」。

做降噪,你两副眼镜都得戴。

时域处理,比如自适应滤波、噪声门,响应快,适合处理瞬态噪声(比如关门声、键盘敲击声)。

频域处理,比如维纳滤波、谱减法,能精细地控制每个频段的增益,适合处理稳态噪声(比如空调声、风扇声)。

我个人习惯,在助听器里用混合架构:先做一版快速的时域噪声抑制,把明显的冲击噪声压下去;然后做 FFT 到频域,做精细的谱降噪。最后再转回时域输出。

经验之谈:

FFT 的点数怎么选?我一般用 256 点或 512 点(采样率 16kHz 时)。点数太少,频率分辨率不够,降噪会「糊」;点数太多,延迟太大,助听器用户会感觉「声音慢了半拍」。这个平衡点,得根据具体芯片的算力来调。

时域和频域的转换,靠的是傅里叶变换。但在嵌入式里,我们用的是 FFT(快速傅里叶变换)。

核心思路:

// 时域信号 x[n] 经过 FFT 得到频域 X[k]
// X[k] 的幅度谱表示每个频率分量的强度
// X[k] 的相位谱表示每个频率分量的时间偏移

// 降噪流程(简化版):
// 1. 对输入帧做 FFT
// 2. 估计噪声谱
// 3. 计算增益(每个频段一个增益值)
// 4. 用增益乘以频域信号
// 5. IFFT 转回时域输出

你想想看,在时域里,噪声和语音是混在一起的,你很难分开。但在频域里,语音主要集中在 300 Hz - 4 kHz,而噪声可能分布在更宽的频段。你只要把噪声占主导的频段压下去,语音就清晰了。

这就是频域降噪的基本逻辑。

好了,这一章的基础概念就这些。采样、量化、dB、时频域——看起来简单,但每一个都直接决定了你后面算法的成败。下一章,我会讲助听器里最常用的几种降噪算法,到时候咱们再细聊。