首页/文章/ 详情

2-25把强噪声里的语音重新“捞”出来:谱减法与改进谱减法语音降噪

40分钟前浏览52
一句话介绍: 这套程序把带噪语音分成短时帧,在频域中估计并扣除噪声谱,再利用原始相位重建语音;同时实现基础谱减法和带过减系数的改进谱减法,可以直接比较两种方法对语音信噪比的提升效果。

先看它解决什么问题

真实语音中经常会混入持续背景噪声。

如果直接观察带噪语音,语音波形和噪声会叠加在一起;如果简单降低整体幅值,语音和噪声又会一起变小,并不能真正把两者分开。

这套程序利用一个很直观的思路:先估计噪声在各个频率上的强度,再从带噪语音的频谱中把这部分噪声减掉。

整个处理流程是:

干净语音 / 带噪语音 → 256 点分帧 → Hamming 加窗 → FFT → 噪声谱估计 → 谱减 → 保留带噪相位 → IFFT → 50% 重叠相加 → 降噪语音

程序还同时计算降噪前后的 SNR,用数值判断降噪是否真正有效。

1. 工程里真正有哪些内容?

文件

作用

pjf.m

随机生成白噪声,比较基础谱减和改进谱减

pjf000.m

读取已有带噪语音和噪声文件进行谱减

speech_dft.wav

干净参考语音

output.wav

已加入噪声的语音

noise.wav

单独噪声信号

程序实际提供了两种实验方式:

方式一:自动给干净语音加随机白噪声,使用 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)

这里有两个变化。

使用 4 次幅度谱

基础谱减处理的是:|Y|²

改进版本使用:|Y|⁴

相当于改变了频谱差异的非线性表达方式。

加入过减系数 b = 6

不再只减: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。


来源:MATLAB学习与应用
非线性二次开发理论控制
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2026-09-09
最近编辑:40分钟前
explicit-z
硕士 工种号:MATLAB学习与应用
获赞 212粉丝 78文章 311课程 5
点赞
收藏
作者推荐
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈