谱减法去噪基础版

谱减法原理

谱减算法为最早的语音降噪算法之一,它的提出,基于一个简单的原理:假设语音中的噪声只有加性噪声,并且噪声信号是平稳的或者缓慢变化的,那么只要将带噪语音谱减去噪声谱,就可以得到纯净语音幅度。

流程图

谱减法的基本流程如下:
谱减法去噪基础版_第1张图片

图1.谱减法框图示意

谱减法去噪基础版_第2张图片

图2.谱减法波形示意

实现代码

依照上述原理,粗糙的实现了谱减法去噪,但是效果不是很好,谱减法有很多改进的方法,欢迎大家探索。
matlab代码如下:

clear all;
[signal,fs]=audioread('six.wav');
len=length(signal);
time=(1:len)/fs;
subplot(311);
plot(time,signal);
xlabel('时间/s');title('原始信号时域图');grid on;

% 加噪声
snr=25; % 信噪比
nsignal=awgn(signal,snr); % 使用matlab自带函数添加高斯白噪声
subplot(312);
plot(time,nsignal);
xlabel('时间/s');title('加噪信号时域图');grid on;
% sound(nsignal,fs);

% 对加噪信号分帧加窗
frame_len=256; % 帧长
step_len=0.5*frame_len; % 步长
frame=fix((len-step_len)/(frame_len-step_len)); % 帧数
fsignal=zeros(frame_len,frame);
windows=hamming(frame_len);
index=1;
for i=1:frame
    wsignal=nsignal(index:index+frame_len-1).*windows;
    fsignal(:,i)=wsignal;
    index=index+step_len;
end

% 假设前k帧为噪声帧
index=1;
nfft=2^nextpow2(frame_len); % 最靠近的2的幂次
sumnoise=zeros(nfft,1);
k=10;
for i=1:k
    iframe=fsignal(:,i);
    N=(abs(fft(iframe,nfft))).^2;
    sumnoise=sumnoise+N;
    index=index+step_len;
end
meannoise=sumnoise/k;

% 对每帧进行谱减
index=1;
subsignal=zeros(frame_len,frame);
SUB=zeros(nfft,1);
for i=1:frame
    iframe=fsignal(:,i);
    S=(abs(fft(iframe,nfft))).^2;
    theta=angle((fft(iframe,nfft)));
    SUB=S-meannoise;
    Sub=sqrt(SUB);
    sub=Sub.*(cos(theta)+sqrt(-1)*(sin(theta)));
    s=ifft(sub,nfft);
    subsignal(:,i)=real(s(1:frame_len));
    index=index+step_len;
end

% 拼接谱减之后的信号
index=1;
newsignal=zeros(len,1);
for i=1:frame
    sframe=subsignal(:,i);
    newsignal(index:index+step_len-1)=sframe(1:step_len);
    index=index+step_len;
end
subplot(313);
plot(time,newsignal);
xlabel('时间/s');title('去噪信号时域图');grid on;
sound(newsignal,fs);

处理结果如图:
谱减法去噪基础版_第3张图片
推荐的博客:https://blog.csdn.net/leixiaohua1020/article/details/47276353

你可能感兴趣的:(MATLAB)