www.pudn.com > dspproject.rar > WienerScalart96m_2.m, change:2016-05-15,size:3368b


function output=WienerScalart96m_2(signal,fs,IS,T1) 
% output=WIENERSCALART96(signal,fs,IS) 
% Wiener filter based on tracking a priori SNR usingDecision-Directed  
% method, proposed by Scalart et al 96. In this method it is assumed that 
% SNRpost=SNRprior +1. based on this the Wiener Filter can be adapted to a 
% model like Ephraims model in which we have a gain function which is a 
% function of a priori SNR and a priori SNR is being tracked using Decision 
% Directed method.  
% Author: Esfandiar Zavarehei 
% Created: MAR-05 
 
 
if (nargin<3 | isstruct(IS))                % 如果输入参数小于3个或IS是结构数据 
   IS=.25;  
end 
W=fix(.025*fs);                             % 帧长为25ms 
SP=.4;                                      % 帧移比例取40%(10ms)  
wnd=hamming(W);                             % 设置窗函数 
% 如果输入参数大于或等于3个并IS是结构数据(为了兼容其他程序) 
if (nargin>=3 & isstruct(IS)) 
    SP=IS.shiftsize/W; 
    nfft=IS.nfft; 
    wnd=IS.window; 
    if isfield(IS,'IS') 
        IS=IS.IS; 
    else 
        IS=.25; 
    end 
end 
pre_emph=0; 
signal=filter([1 -pre_emph],1,signal);      % 预加重 
NIS=fix((IS*fs-W)/(SP*W) +1);               % 计算无话段帧数 
y=segment(signal,W,SP,wnd);                 % 分帧  
Y=fft(y);                                   % FFT 
YPhase=angle(Y(1:fix(end/2)+1,:));          % 带噪语音的相位角  
Y=abs(Y(1:fix(end/2)+1,:));                 % 取正频率谱值 
numberOfFrames=size(Y,2);                   % 计算总帧数 
FreqResol=size(Y,1);                        % 计算频谱中的谱线数 
N=mean(Y(:,1:NIS)')';                       % 计算无话段噪声平均谱值  
LambdaD=mean((Y(:,1:NIS)').^2)';            % 初始噪声功率谱方差 
alpha=.99;                                  % 设置平滑系数 
fn=numberOfFrames; 
miniL=5;                                    % 设置miniL 
[voiceseg,vosl,SF,Ef]=pitch_vad1(y,fn,T1,miniL); %端点检测 
 
NoiseCounter=0;                             % 初始化NoiseCounter 
NoiseLength=9;                              % 设置噪声平滑区间长度 
G=ones(size(N));                            % 初始化谱估计器 
Gamma=G; 
X=zeros(size(Y));                           % 初始化X 
h=waitbar(0,'Wait...');                     % 设置运行进度条图  
for i=1:numberOfFrames 
    SpeechFlag=SF(i); 
    if i<=NIS                               % 若i<=NIS在前导无声(噪声)段 
        SpeechFlag=0; 
        NoiseCounter=100; 
    %else                                   % i>NIS判断是否为有话帧 
        %[NoiseFlag, SpeechFlag, NoiseCounter, Dist]=vad(Y(:,i),N,NoiseCounter);  
    end 
    if SpeechFlag==0                         % 在无话段中平滑更新噪声谱值 
        N=(NoiseLength*N+Y(:,i))/(NoiseLength+1);  
        LambdaD=(NoiseLength*LambdaD+(Y(:,i).^2))./(1+NoiseLength);%更新和平滑噪声方差 
    end 
 
    gammaNew=(Y(:,i).^2)./LambdaD;          % 计算后验信噪比 
    xi=alpha*(G.^2).*Gamma+(1-alpha).*max(gammaNew-1,0); % 计算先验信噪比 
    Gamma=gammaNew; 
    G=(xi./(xi+1));                         % 计算维纳滤波器的谱估计器 
    X(:,i)=G.*Y(:,i);                       % 维纳滤波后的幅值 
%显示运行进度条图 
    waitbar(i/numberOfFrames,h,num2str(fix(100*i/numberOfFrames))); 
end 
close(h);                                   % 关闭运行进度条图 
output=OverlapAdd2(X,YPhase,W,SP*W);        % 语音合成 
output=filter(1,[1 -pre_emph],output);      % 消除预加重影响 
output=output/max(abs(output));