赞
踩
一、基于先验信噪比的维纳滤波语音降噪算法的基本概念
改进的维纳滤波器为基于先验信噪比的维纳滤波器,其原理框图下图所示。
对于第m帧带噪语音信号ym(n)=sm(n)+nm(n)
式中,sm(n)是第m帧纯净语音信号;nm(n)为第m帧噪声信号。维纳滤波器就是在最小方均误差准则(MSE)下实现对语音信号sm(n)的估计。在sm(n)与nm(n)不相关且均为平稳随机过程条件下,对上式进行离散傅里叶变换,得Y(m,k)=S(m,k)+N(m,k)
谱增益函数为
式中,ζ(m,k)(SNRpo)为先验信噪比;m为帧号;k为频点。
则第m帧增强语音可表示为
采用直接判决(Decision-Directed)法来估计先验信噪比SNRprio,即
SNRprio(m,k)=a・ SNRprio(m-1,k)+(1-a) ・max(SNRpost(m,k) -1,0)
式中,SNRpost表示后验信噪比;Y(m,k)表示估计的第m帧信号的功率谱;(m,k)表示估
计的第m帧噪声功率谱。
二、先验信噪比的维纳滤波语音增强实验
先验信噪比的维纳滤波函数Weina_Im
名称:Weina_Im
功能:基于先验信噪比的维纳滤波算法。
调用格式:
enhanced = Weina_Im(x,wind,inc,NIS,alpha)
说明:输入参数x是输入的含噪语音信号;wlen为窗函数或窗长;inc是帧移;NIS是前导无话段帧数;alpha是信噪比平滑参数。enhanced是降噪后的信号。
函数代码如下:
- % 维纳滤波enhancement=Weina_Im(y_fft,framesize,framenum,length);
- % MS估计噪声功率谱, D-D法估计先验概率, 不需要估计纯净信号功率
- % y_fft:分帧语音的FFT变换,
- % framesize:帧长
- % framenum:总帧数,
- % length:语音长度
- % enhancement:增强后的语音
- % --------------------------------------------------------------------------------------------------------------
-
- function enhancement=Weina_Im(x,wind,inc,NIS,alpha)
- Length=length(x);
- nwin=length(wind); % 取窗长
- if (nwin == 1) % 判断窗长是否为1,若为1,即表示没有设窗函数
- framesize= wind; % 是,帧长=win
- wnd=hamming(framesize); % 设置窗函数
- else
- framesize = nwin; % 否,帧长=窗长
- wnd=wind;
- end
- y=enframe(x,wnd,inc)'; % 分帧
- framenum=size(y,2); % 求帧数
- y_fft = fft(y); % FFT
- y_a = abs(y_fft); % 求取幅值
- y_phase=angle(y_fft); % 求取相位角
- y_fft2=y_a.^2; % 求能量
- noise=mean(y_fft2(:,1:NIS),2); % 计算噪声段平均能量
-
- snr_x_q=0.96; %前一帧先验信噪比,初始值设为0.96
- for i=1:framenum
- Mag_y=y_a(:,i);
- snr_h=y_fft2(:,i)./noise;%(:,i); %计算后验信噪比
- snr_x=alpha.*snr_x_q+(1-alpha).*max(snr_h-1,0); %先验信噪比,利用"D-D"法 ,framesize*1
- Hw=snr_x./(1+snr_x); %维纳滤波
- M=Mag_y.*Hw; %维纳后的幅度值
- Mn=M.*exp(1i.*y_phase(:,i)); %插入相位
- snr_x_q=M.^2./noise;%(:,i); %更新估计的前一帧先验信噪比
- signal(:,i)=real(ifft(Mn));
- end
- enhancement=filpframe(signal',wnd,inc);
信噪比计算函数SNR_Calc
名称:SNR_Calc
功能:计算信噪比。
调用格式:
snr=SNR_Calc(x,xn)
说明:输入信号x是输入的纯净语音信号;xn是输入的含噪信号。输出参数snr是计算的信噪比。
函数程序如下:
- function snr=SNR_Calc(I,In)
- % 计算带噪语音信号的信噪比
- % I 是纯语音信号
- % In 是带噪的语音信号
- % 信噪比计算公式是
- % snr=10*log10(Esignal/Enoise)
- I=I(:)'; % 把数据转为一列
- In=In(:)';
- Ps=sum((I-mean(I)).^2); % 信号的能量
- Pn=sum((I-In).^2); % 噪声的能量
- snr=10*log10(Ps/Pn); % 信号的能量与噪声的能量之比,再求分贝值
案例、用先验信噪比的维纳滤波算法给语音减噪
程序如下:
- clear all; clc; close all;
-
- [xx, fs] = wavread('C5_3_y.wav'); % 读入数据文件
- xx=xx-mean(xx); % 消除直流分量
- x=xx/max(abs(xx)); % 幅值归一化
- IS=0.25; % 设置前导无话段长度
- wlen=200; % 设置帧长为25ms
- inc=80; % 设置帧移为10ms
- SNR=5; % 设置信噪比SNR
- NIS=fix((IS*fs-wlen)/inc +1); % 求前导无话段帧数
- alpha=0.95;
-
- signal=awgn(x,SNR,'measured','db'); % 叠加噪声
- output=Weina_Im(x,wlen,inc,NIS,alpha) ;
- output=output/max(abs(output));
- len=min(length(output),length(x));
- x=x(1:len);
- signal=signal(1:len);
- output=output(1:len);
-
- snr1=SNR_Calc(x,signal); % 计算初始信噪比
- snr2=SNR_Calc(x,output); % 计算降噪后的信噪比
- snr=snr2-snr1;
- fprintf('snr1=%5.4f snr2=%5.4f snr=%5.4f\n',snr1,snr2,snr);
-
- % 作图
- time=(0:len-1)/fs; % 设置时间
- subplot 311; plot(time,x,'k'); grid; axis tight;
- title('纯语音波形'); ylabel('幅值')
- subplot 312; plot(time,signal,'k'); grid; axis tight;
- title(['带噪语音 信噪比=' num2str(SNR) 'dB']); ylabel('幅值')
- subplot 313; plot(time,output,'k');grid;%hold on;
- title('滤波后波形'); ylabel('幅值'); xlabel('时间/s');
运行结果如下:
实验使用到的语音数据下载链接如下:
传统语音增强——最小方均(LMS)自适应滤波算法-数据集文档类资源-CSDN下载
参考文献:语音信号处理实验教程;梁瑞宇、赵力、魏昕(编著)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。