3. 噪声特性分析:噪声分类与常见模型
做语音算法这些年,我最大的感触就是——噪声从来不是“均匀”的敌人。你想想看,会议室里的空调嗡嗡声,和马路上的车流呼啸,它们对语音的污染方式完全不同。如果不先把噪声的“脾气”摸清楚,后面设计滤波器基本就是瞎蒙。
这一节,我们就来系统地拆解噪声。我会从两个维度切入:分类体系和常见模型。搞懂这些,你才能知道什么时候该用谱减法,什么时候该上维纳滤波,什么时候得祭出深度学习。
3.1 噪声的两大分类维度
噪声分类有很多种方法,但实战中最常用的就两个维度:平稳性和叠加方式。我个人习惯把它们放在一起看,这样能快速定位降噪策略。
3.1.1 平稳噪声 vs 非平稳噪声
这个分类看的是噪声的统计特性随时间变不变。
- 平稳噪声:统计特性(均值、方差、功率谱)随时间基本不变。比如空调的嗡嗡声、风扇的呼呼声、白噪声发生器。这类噪声最好处理,因为你可以用一段“纯噪声”帧来估计它的谱,然后直接减掉。
- 非平稳噪声:统计特性随时间剧烈变化。比如突然的关门声、键盘敲击声、街道上的车流声。这类噪声是语音降噪的“硬骨头”。
3.1.2 加性噪声 vs 乘性噪声
这个分类看的是噪声和语音信号怎么“结合”的。
- 加性噪声:噪声直接加到语音信号上。数学上就是
y(t) = x(t) + n(t)。这是最常见的情况,比如麦克风采集到的环境噪声。处理起来相对直接,谱减法、维纳滤波都是基于这个模型。 - 乘性噪声:噪声和语音信号相乘。数学上是
y(t) = x(t) * n(t)。这种情况通常出现在信道衰落、麦克风振膜老化等场景。处理乘性噪声,一般先取对数,把它变成加性噪声再处理。
3.2 常见噪声模型详解
理论说完了,我们来看看实战中经常遇到的几种噪声。我按频率特性和应用场景把它们分成了四类。
3.2.1 白噪声
白噪声是所有频率上功率谱密度都相等的噪声。它就像一束“全频段”的光,均匀地照亮每个频点。
- 特点:功率谱平坦,自相关函数是冲激函数。
- 应用:常用于算法测试、系统辨识、心理声学实验。
- 生成方式:用随机数生成器产生高斯分布或均匀分布的序列即可。
# Python 生成白噪声示例
import numpy as np
def generate_white_noise(length, fs=16000):
"""生成高斯白噪声"""
noise = np.random.randn(length)
# 归一化到 [-1, 1]
noise = noise / np.max(np.abs(noise))
return noise
# 生成1秒的白噪声,采样率16kHz
white_noise = generate_white_noise(16000)
3.2.2 粉红噪声
粉红噪声的功率谱密度与频率成反比,即每倍频程下降3dB。它比白噪声更“自然”,因为自然界中很多声音(比如瀑布、风声)都接近粉红噪声。
- 特点:低频能量大,高频能量小。听起来比白噪声“柔和”。
- 应用:模拟环境背景噪声、音频设备测试。
- 生成方式:对白噪声进行低通滤波,或者用Voss-McCartney算法。
3.2.3 汽车噪声
汽车噪声是典型的非平稳、加性噪声。它由多种声源叠加而成:发动机轰鸣、轮胎与路面摩擦、风噪、空调压缩机等。
我做过一个车载语音项目,当时采集了不同车速下的噪声数据。结果发现:
- 低速(0-40 km/h):主要是发动机低频轰鸣,频率集中在100-300 Hz。
- 中速(40-80 km/h):轮胎噪声开始占主导,频率范围扩展到500-2000 Hz。
- 高速(80 km/h以上):风噪成为主要成分,高频能量明显增加。
| 车速范围 | 主要噪声源 | 频率范围 | 平稳性 |
|---|---|---|---|
| 0-40 km/h | 发动机 | 100-300 Hz | 准平稳 |
| 40-80 km/h | 轮胎 | 500-2000 Hz | 非平稳 |
| 80+ km/h | 风噪 | 2000-8000 Hz | 非平稳 |
3.2.4 人群噪声
人群噪声(babble noise)是多个说话人同时说话时产生的背景声。它是最难处理的噪声之一,因为它的频谱特性和语音非常相似。
- 特点:频谱与语音高度重叠,非平稳性强,包含大量瞬态成分。
- 应用:会议系统、智能音箱、助听器。
- 难点:传统降噪方法很难区分目标语音和背景语音,容易把目标语音也一起滤掉。
我记得有一次在咖啡馆测试降噪算法,背景里有人聊天。我的算法把背景人声当成了噪声,结果把目标说话人的声音也削掉了一部分。嗯,这就是人群噪声的“狡猾”之处。
3.3 噪声特性分析框架
说了这么多,我们来画一张图,把整个知识体系串起来。这张图是我做项目时经常参考的框架,它能帮你快速定位噪声类型,并选择合适的降噪策略。
3.4 实战中的噪声分析流程
理论框架有了,模型也认识了。那在实际项目中,拿到一段带噪语音,该怎么分析它的噪声特性呢?我一般按下面几步走:
- 听:先戴上耳机听一遍。凭经验判断噪声类型——是平稳的嗡嗡声,还是突发的撞击声?
- 看时域波形:观察幅度的变化。平稳噪声的幅度包络比较稳定,非平稳噪声会有明显的起伏。
- 看频谱图:用短时傅里叶变换画出语谱图。白噪声的频谱是均匀的,粉红噪声低频能量大,汽车噪声有明显的低频条带,人群噪声则像“散落的星星”。
- 计算统计量:计算噪声段的均值、方差、功率谱密度。如果统计量随时间变化不大,就是平稳噪声。
- 做VAD:用语音活动检测把语音段和噪声段分开,单独分析噪声段的特性。