Rowan-Classes/6th-Semester-Spring-2024/DSP/Labs/FinalProject/statistical_based/stsa_weuclid.m
2024-04-25 18:38:09 -04:00

146 lines
3.6 KiB
Matlab

function stsa_weuclid(filename,outfile,p)
%
% Implements the Bayesian estimator based on the weighted-Euclidean
% distortion measure [1, Eq. 18].
%
% Usage: stsa_weuclid(noisyFile, outputFile, p)
%
% infile - noisy speech file in .wav format
% outputFile - enhanced output file in .wav format
% p - power exponent used in the weighted-Euclidean measure.
% Valid values for p: p>-2
%
%
% Example call: stsa_weuclid('sp04_babble_sn10.wav','out_weuclid.wav',-1);
%
% References:
% [1] Loizou, P. (2005). Speech enhancement based on perceptually motivated
% Bayesian estimators of the speech magnitude spectrum. IEEE Trans. on Speech
% and Audio Processing, 13(5), 857-869.
%
% Author: Philipos C. Loizou
%
% Copyright (c) 2006 by Philipos C. Loizou
% $Revision: 0.0 $ $Date: 10/09/2006 $
%-------------------------------------------------------------------------
if nargin<3
fprintf('Usage: stsa_weuclid(infile.wav,outfile.wav,p) \n');
fprintf(' where p>-2 \n\n');
return;
end;
if p<-2,
error('ERROR! p needs to be larger than -2.\n\n');
end
[x, Srate, bits]= wavread( filename);
% =============== Initialize variables ===============
len=floor(20*Srate/1000); % Frame size in samples
if rem(len,2)==1, len=len+1; end;
PERC=50; % window overlap in percent of frame size
len1=floor(len*PERC/100);
len2=len-len1;
win=hamming(len); %tukey(len,PERC); % define window
% Noise magnitude calculations - assuming that the first 6 frames is noise/silence
%
nFFT=2*len;
nFFT2=len/2;
noise_mean=zeros(nFFT,1);
j=1;
for k=1:6
noise_mean=noise_mean+abs(fft(win.*x(j:j+len-1),nFFT));
j=j+len;
end
noise_mu=noise_mean/6;
noise_mu2=noise_mu.^2;
%--- allocate memory and initialize various variables
k=1;
img=sqrt(-1);
x_old=zeros(len1,1);
Nframes=floor(length(x)/len2)-1;
xfinal=zeros(Nframes*len2,1);
%=============================== Start Processing =======================================================
%
k=1;
aa=0.98;
mu=0.98;
eta=0.15;
c=sqrt(pi)/2;
C2=gamma(0.5);
%p=-1;
CC=gamma((p+3)/2)/gamma(p/2+1);
ksi_min=10^(-25/10);
for n=1:Nframes
insign=win.*x(k:k+len-1);
%--- Take fourier transform of frame
spec=fft(insign,nFFT);
sig=abs(spec); % compute the magnitude
sig2=sig.^2;
gammak=min(sig2./noise_mu2,40); % post SNR
if n==1
ksi=aa+(1-aa)*max(gammak-1,0);
else
ksi=aa*Xk_prev./noise_mu2 + (1-aa)*max(gammak-1,0); % a priori SNR
ksi=max(ksi_min,ksi); % limit ksi to -25 dB
end
log_sigma_k= gammak.* ksi./ (1+ ksi)- log(1+ ksi);
vad_decision= sum( log_sigma_k)/ len;
if (vad_decision< eta)
% noise only frame found
noise_mu2= mu* noise_mu2+ (1- mu)* sig2;
end
% ===end of vad===
vk=ksi.*gammak./(1+ksi);
%----- weighted Euclidean distance ------------------------
if p==-1
hw=CC*sqrt(vk)./(gammak.*exp(-vk/2).*besseli(0,vk/2)); % if p=-1 use this equation as it's faster
else
numer=CC*sqrt(vk).*confhyperg(-(p+1)/2,1,-vk,100);
denom=gammak.*confhyperg(-p/2,1,-vk,100);
hw=numer./denom;
end
%
sig=sig.*hw;
Xk_prev=sig.^2;
xi_w= ifft( hw .* spec, nFFT);
xi_w= real( xi_w);
% --- Overlap and add ---------------
%
xfinal(k:k+ len2-1)= x_old+ xi_w(1:len1);
x_old= xi_w(len1+ 1: len);
k=k+len2;
end
%========================================================================================
wavwrite(xfinal,Srate,16,outfile);