
一句话介绍: 这套程序把带噪语音分成短时帧,在频域中估计并扣除噪声谱,再利用原始相位重建语音;同时实现基础谱减法和带过减系数的改进谱减法,可以直接比较两种方法对语音信噪比的提升效果。
真实语音中经常会混入持续背景噪声。
如果直接观察带噪语音,语音波形和噪声会叠加在一起;如果简单降低整体幅值,语音和噪声又会一起变小,并不能真正把两者分开。
这套程序利用一个很直观的思路:先估计噪声在各个频率上的强度,再从带噪语音的频谱中把这部分噪声减掉。
整个处理流程是:
干净语音 / 带噪语音 → 256 点分帧 → Hamming 加窗 → FFT → 噪声谱估计 → 谱减 → 保留带噪相位 → IFFT → 50% 重叠相加 → 降噪语音
程序还同时计算降噪前后的 SNR,用数值判断降噪是否真正有效。
1. 工程里真正有哪些内容?
文件 | 作用 |
|---|---|
| 随机生成白噪声,比较基础谱减和改进谱减 |
| 读取已有带噪语音和噪声文件进行谱减 |
| 干净参考语音 |
| 已加入噪声的语音 |
| 单独噪声信号 |
程序实际提供了两种实验方式:
方式一:自动给干净语音加随机白噪声,使用 pjf.m。
方式二:直接读取已经准备好的带噪语音和噪声,使用 pjf000.m。
2. 当前语音数据是什么规模?
工程中的 WAV 文件采样率都是:44.1 kHz
speech_dft.wav 为双声道语音,程序只取:第 1 个通道
干净语音长度约:5.15 s
因此后续谱减实际上处理的是一条单通道语音序列。
pjf.m 会在这条干净语音上直接叠加随机高斯白噪声。
当前噪声幅度参数为:n = 0.23
所以每次重新运行时,由于随机噪声不同,最终 SNR 也会有一定变化。
3. 为什么不能直接对整段语音做一次 FFT?
语音不是一个完全稳定不变的信号。
几秒钟内:
不同音节会不断变化;能量会变化;频率结构也会变化。
如果把整段语音只做一次 FFT,相当于把几秒钟的信息全部混在一起。
程序采用短时处理:窗长 = 256 点
在 44.1 kHz 采样率下,一帧只有约:256 / 44100 ≈ 5.8 ms
这样可以把一小段语音近似看成短时平稳信号,再逐帧进行频谱降噪。
4. 为什么相邻帧要重叠一半?
程序每次向前移动:128 点
而每帧长度为:256 点
因此相邻两帧有:50% 重叠
这样做能够减轻直接切帧造成的不连续。
处理结束以后,各帧再重新叠加回完整语音。
因此流程并不是:
切成很多互不相关的小段 → 独立处理 → 硬拼接
而是:
重叠分析 → 频域处理 → 重叠相加重建
这样能让帧与帧之间的过渡更加连续。
5. Hamming 窗在这里做什么?
每一帧在 FFT 前都会乘 Hamming 窗。
简单来说,直接截取 256 点相当于突然把信号两端切断,这会让频谱出现额外泄漏。
Hamming 窗会让帧两端逐渐衰减,从而减弱截断带来的频谱扩散。
程序处理完所有帧以后,还会累计每个位置上的 Hamming 窗权重,再把重建信号除以这个累计值。
所以:加窗用于改善频谱分析,最后的增益补偿则用于恢复重叠加窗造成的幅度变化。
6. 基础谱减法到底减的是什么?
设一帧带噪语音为:
y(n) = s(n) + n(n)
其中:
s(n):真实语音;
n(n):噪声;
y(n):实际观测到的带噪语音。
FFT 后可以写成:
Y(k) = S(k) + N(k)
程序首先计算带噪语音和噪声的幅度:
|Y(k)|、|N(k)|
基础谱减使用的是功率谱:
P_s(k) = max[|Y(k)|² - |N(k)|², 0]
然后恢复语音幅度:
|Ŝ(k)| = √P_s(k)
这里最关键的是:
如果某个频率上的带噪功率明显高于噪声功率,就保留扣除噪声以后剩余的部分。
如果相减结果小于 0,程序直接设为 0,因为功率不应该出现负值。
7. 为什么谱减以后还要保留原来的相位?
谱减主要修改的是:频谱幅度
程序没有重新估计语音相位,而是直接使用带噪语音的相位:
Ŝ(k) = |Ŝ(k)| · exp[j·angle(Y(k))]
这是一种经典的谱减处理方式。
原因可以简单理解为:
在很多语音增强场景中,幅度谱对听感和噪声强度影响非常明显,而直接保留观测信号相位可以避免额外进行复杂相位估计。
得到新的复频谱以后,再通过 IFFT 回到时域。
8. “改进谱减法”改在哪里?
pjf.m 和 pjf000.m 除了基础谱减,还计算另一条增强语音 improved。
当前设置:a = 4、b = 6
它的频域处理可以写成:
P_improved(k) = max[|Y(k)|ᵃ - b·|N(k)|ᵃ, 0]
当前就是:
P_improved(k) = max[|Y(k)|⁴ - 6|N(k)|⁴, 0]
再得到新的幅度:
|Ŝ_improved(k)| = P_improved(k)^(1/4)
这里有两个变化。
基础谱减处理的是:|Y|²
改进版本使用:|Y|⁴
相当于改变了频谱差异的非线性表达方式。
不再只减:1 × 噪声谱
而是减去:6 × 噪声谱项
因此对残余噪声的抑制更强。
9. 为什么“多减一点噪声”可能有效?
基础谱减存在一个常见现象:实际噪声谱和估计噪声谱不可能每个时刻、每个频点都完全相同。
如果只按照估计值精确减一次,某些频率上仍可能残留较明显的噪声。
过减的思路是:估计噪声以后,再额外多减一部分
从而进一步压低残余噪声。
当前程序用:b = 6增加谱减强度。
所以它的目标是:
牺牲一部分频谱保真度,换取更明显的背景噪声抑制。
这也是为什么程序同时保留基础版和改进版,便于比较不同降噪强度。
10. 每一帧处理后怎样重新变成完整语音?
单帧处理完成后,程序执行 IFFT:
ŝ(n) = IFFT[Ŝ(k)]
然后按照原来的 50% 重叠位置,把每个时域帧累加到完整输出中。
最后再除以累计 Hamming 窗:
最终语音 = 重叠累加结果 / 窗函数累计增益
因此完整恢复过程是:
FFT → 修改幅度谱 → 保留相位 → IFFT → Overlap-Add
这一步把频域降噪重新变成可以播放和分析的时域语音信号。
11. 程序怎样判断降噪有没有效果?
工程使用信噪比 SNR 评价结果。
计算思想是:
SNR = 10log₁₀[语音方差 / 噪声或误差方差]
对于增强后的语音,误差定义为:
e = 增强语音 - 干净参考语音
所以:
SNR_enhanced = 10log₁₀[var(speech) / var(e)]
SNR 越高,说明:
恢复语音与干净参考语音之间的误差相对越小。
因为这是一个仿真实验,工程保留了原始干净语音,所以可以直接计算这种客观 SNR。
12. 工程自带音频的实际降噪效果
pjf000.m 使用:
speech_dft.wav:干净参考语音;
output.wav:带噪语音;
noise.wav:噪声。
按照源码中的谱减逻辑,对提供音频重新计算后得到:
状态 | SNR |
带噪语音 | 约 -4.20 dB |
基础谱减后 | 约 5.12 dB |
改进谱减后 | 约 5.79 dB |
因此:
基础谱减提升约 9.32 dB
改进谱减提升约 9.99 dB
而改进方法相对于基础谱减又提高约:0.67 dB
从这组数据可以看到:
谱减已经能够明显降低噪声误差,而当前 a=4、b=6 的改进版本在该样本上还取得了进一步的 SNR 提升。
13. 为什么不直接用普通低通滤波器?
如果噪声只集中在高频,而语音只集中在低频,低通滤波确实可以有效降噪。
但宽带白噪声会覆盖很宽的频率范围,并且和语音频谱大量重叠。
这时低通滤波面临一个问题:
把噪声切掉的同时,也可能把语音高频信息一起切掉。
谱减法的思路不同:
不是规定“某个频率以上全部删除”,而是逐频点比较当前频谱与噪声谱。
所以它更适合处理:
频率范围与语音发生重叠、但能够估计其统计频谱的背景噪声。
14. 这种方法理论上为什么适合语音降噪?
程序不是只降低整体音量,而是先估计噪声在不同频率上的能量,再针对这些频率进行扣除。
因此它真正利用了:
语音谱与噪声谱之间的差异。
整段语音不断变化,但短时间内频谱变化相对有限。
256 点短帧使程序能够逐段估计频谱,而不是假设几秒钟语音始终不变。
FFT 和 IFFT 构成可逆变换。
程序只修改频谱幅度,再利用原相位和 IFFT 恢复时域语音,因此能够形成完整的:
分析 → 降噪 → 重建流程。
通过 b 改变噪声扣除量,可以在:
残余噪声 ↔ 语音失真之间进行调整。
这比固定低通截止频率更加直接地针对噪声谱进行控制。
15. 程序最终能得到什么?
运行以后主要得到:
原始干净语音;带噪语音;基础谱减后的语音;
改进谱减后的语音;降噪前 SNR;基础谱减 SNR;改进谱减 SNR。
所以这个工程既能够用于:听感 / 波形观察
也能够用于:SNR 数值比较
如果希望试听处理结果,可以再使用 sound 或 audiowrite 对这两个变量进行播放或保存。
16. 它适合用在哪里?
可以完整理解:
分帧 → 加窗 → FFT → 噪声谱估计 → 谱减 → IFFT → 重叠相加
这一经典语音增强流程。
程序同时提供基础谱减和过减版本,可以直接研究提高噪声扣除强度以后 SNR 怎样变化。
pjf.m 可以直接生成高斯白噪声,用于研究稳定宽带噪声环境中的语音增强效果。
这套代码结构简单,很适合进一步扩展到噪声跟踪、谱底约束、维纳滤波等方法进行对比。
17. 怎么运行?
如果直接做随机白噪声实验,运行:pjf.m
它会读取 speech_dft.wav,自动生成噪声,并计算基础谱减和改进谱减结果。
最值得调整的是 窗长、噪声水平和过减系数 b:它们分别影响短时频谱分辨率、输入噪声强度和谱减抑制力度。
18. 一句话看懂这个项目
这是一个语音谱减降噪程序:它把 44.1 kHz 语音按 256 点分帧并采用 50% 重叠和 Hamming 窗,在每帧 FFT 后估计噪声幅度谱,基础方法使用 |Ŝ|²=max(|Y|²-|N|²,0),改进方法进一步使用 a=4、b=6 的过减策略,再保留带噪语音相位进行 IFFT 和重叠相加恢复。按工程提供的固定音频复算,SNR 可由约 -4.20 dB 提升到基础谱减约 5.12 dB,改进谱减约 5.79 dB。