-
Notifications
You must be signed in to change notification settings - Fork 42
/
logmmse.m
120 lines (89 loc) · 2.79 KB
/
logmmse.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
function logmmse(filename,outfile)
%
% Implements the logMMSE algorithm [1].
%
% Usage: logmmse(noisyFile, outputFile)
%
% infile - noisy speech file in .wav format
% outputFile - enhanced output file in .wav format
%
%
% Example call: logmmse('sp04_babble_sn10.wav','out_log.wav');
%
% References:
% [1] Ephraim, Y. and Malah, D. (1985). Speech enhancement using a minimum
% mean-square error log-spectral amplitude estimator. IEEE Trans. Acoust.,
% Speech, Signal Process., ASSP-23(2), 443-445.
%
% Authors: Philipos C. Loizou
%
% Copyright (c) 2006 by Philipos C. Loizou
% $Revision: 0.0 $ $Date: 10/09/2006 $
%-------------------------------------------------------------------------
if nargin<2
fprintf('Usage: logmmse(noisyfile.wav,outFile.wav) \n\n');
return;
end
[x, Srate, bits]= wavread( filename); %nsdata is a column vector
% =============== 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; % update rate in samples
win=hanning(len); % define window
win = win*len2/sum(win); % normalize window for equal level output
% Noise magnitude calculations - assuming that the first 6 frames is
% noise/silence
nFFT=2*len;
noise_mean=zeros(nFFT,1);
j=1;
for m=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
x_old=zeros(len1,1);
Nframes=floor(length(x)/len2)-floor(len/len2);
xfinal=zeros(Nframes*len2,1);
%=============================== Start Processing =======================================================
%
k=1;
aa=0.98;
mu=0.98;
eta=0.15;
ksi_min=10^(-25/10);
for n=1:Nframes
insign=win.*x(k:k+len-1);
spec=fft(insign,nFFT);
sig=abs(spec); % compute the magnitude
sig2=sig.^2;
gammak=min(sig2./noise_mu2,40); % limit post SNR to avoid overflows
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===
A=ksi./(1+ksi); % Log-MMSE estimator
vk=A.*gammak;
ei_vk=0.5*expint(vk);
hw=A.*exp(ei_vk);
sig=sig.*hw;
Xk_prev=sig.^2;
xi_w= ifft( hw .* spec,nFFT);
xi_w= real( xi_w);
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);