【语音去噪】基于matlab谱减法去噪【含Matlab源码 429期】

411 阅读3分钟

一、简介

在语音去噪中最常用的方法是谱减法,谱减法是一种发展较早且应用较为成熟的语音去噪算法,该算法利用加性噪声与语音不相关的特点,在假设噪声是统计平稳的前提下,用无语音间隙测算到的噪声频谱估计值取代有语音期间噪声的频谱,与含噪语音频谱相减,从而获得语音频谱的估计值。谱减法具有算法简单、运算量小的特点,便于实现快速处理,往往能够获得较高的输出信噪比,所以被广泛采用。该算法经典形式的不足之处是处理后会产生具有一定节奏性起伏、听上去类似音乐的“音乐噪声”。

转换到频域后,这些峰值听起来就像帧与帧之间频率随机变化的多频音,这种情况在清音段尤其明显,这种由于半波整流引起的“噪声”被称为“音乐噪声”。从根本上,通常导致音乐噪声的原因主要有:
(1)对谱减算法中的负数部分进行了非线性处理
(2)对噪声谱的估计不准
(3)抑制函数(增益函数)具有较大的可变性
1 原理
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2 流程图
在这里插入图片描述
3 谱减法的缺点
1)由于对负值进行半波整流,导致帧频谱的随机频率上出现小的、独立的峰值,变换到时域上面,这些峰值听起来就像帧与帧之间频率随机变化的多颤音,也就是通常所说的“音乐噪声”(Musical Noise)
2)另外,谱减法还存在一个小缺点就是使用带噪语音的相位作为增强后语音的相位,因此产生语音的质量可能比较粗糙,尤其是在低信噪比的条件下,可能会达到被听觉感知的程度,降低语音的质量。
为了更好的理解谱减法语音增强,这里对该算法进行简单仿真,仿真参数设置如下
在这里插入图片描述

二、源代码

winsize=256;%窗长
n=0.23;%噪声水平
a=4;b=6;
[speech,fs,nbits]=wavread('speech_dft.wav');%读入wav文件
speech=speech(:,1);
size=length(speech);%语音长度
numofwin=floor(size/winsize);%窗数
%定义汉明窗
ham=hamming(winsize)';
hamwin=zeros(1,size);
enhanced=zeros(1,size);
improved=zeros(1,size);
%生成噪声信号
noise=n*randn(1,size);
y=speech'+noise;
%噪声处理
noisy=n*randn(1,winsize);
N=fft(noisy);
npow=abs(N);
for q=1:2*numofwin-1
    yframe=y(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2);%分帧
    hamwin(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2)=hamwin(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2)+ham;
    %加噪信号FFT
    y1=fft(yframe.*ham);
    ypow=abs(y1);%加噪信号幅度
    yangle=angle(y1);%相位
    %计算功率谱密度
    Py=ypow.^2;
    Pn=npow.^2;
    Pyy=ypow.^a;
    Pnn=npow.^a;
    %基本谱减
    for i=1:winsize
        if Py(i)-Pn(i)>0
            Ps(i)=Py(i)-Pn(i);
        else
            Ps(i)=0;
        end
    end
    s=sqrt(Ps).*exp(1i*yangle);
            for i=1:winsize
                if Pyy(i)-b*Pnn(i)>0
                    Pss(i)=Pyy(i)-b*Pnn(i);
                else
                    Pss(i)=0;
                end
            end
            ss=Pss.^(1/a).*exp(1i*yangle);
            %去噪语音IFFT
            enhanced(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2)=enhanced(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2)+real(ifft(s));
            improved(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2)=improved(1+(q-1)*winsize/2:winsize+(q-1)*winsize/2)+real(ifft(ss));
end
%去除汉明窗引起的增益
for i=1:size
    if hamwin(i)==0
        enhanced(i)=0;
        improved(i)=0;
    else
        enhanced(i)=enhanced(i)/hamwin(i);
        improved(i)=improved(i)/hamwin(i);
    end
end

三、运行结果

在这里插入图片描述

四、备注

版本:2014a