1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfunction [emicrophone,aaa]=compsup(microphone,TheFarEnd,avtime,samplingfreq);
2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% microphone = microphone signal
3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% aaa = nonlinearity input variable
4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% TheFarEnd = far end signal
5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% avtime = interval to compute suppression from (seconds)
6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% samplingfreq = sampling frequency
7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent%if(nargin==6)
9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent%    fprintf(1,'suppress has received a delay sequence\n');
10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent%end
11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentAp500=[  1.00, -4.95, 9.801, -9.70299, 4.80298005, -0.9509900499];
14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentBp500=[  0.662743088639636, -2.5841655608125, 3.77668102146288, -2.45182477425154, 0.596566274575251, 0.0];
15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentAp200=[ 1.00, -4.875, 9.50625, -9.26859375, 4.518439453125, -0.881095693359375];
18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentBp200=[ 0.862545460994275, -3.2832804496114, 4.67892032308828, -2.95798023879133, 0.699796870041299, 0.0];
19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentmaxDelay=0.4; %[s]
21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurenthistLen=1; %[s]
22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
23e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% CONSTANTS THAT YOU CAN EXPERIMENT WITH
25e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentA_GAIN=10.0;	 	% for the suppress case
26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentoversampling = 2;	% must be power of 2; minimum is 2; 4 works
27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% fine for support=64, but for support=128,
28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% 8 gives better results.
29e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentsupport=64; %512	% fft support (frequency resolution; at low
30e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% settings you can hear more distortion
31e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% (e.g. pitch that is left-over from far-end))
32e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% 128 works well, 64 is ok)
33e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
34e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentlowlevel = mean(abs(microphone))*0.0001;
35e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
36e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentG_ol = 0;  % Use overlapping sets of estimates
37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
38e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% ECHO SUPPRESSION SPECIFIC PARAMETERS
39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentsuppress_overdrive=1.0;   % overdrive factor for suppression 1.4 is good
40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentgamma_echo=1.0;           % same as suppress_overdrive but at different place
41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentde_echo_bound=0.0;
42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentmLim=10;                  % rank of matrix G
43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent%limBW = 1;		  % use bandwidth-limited response for G
44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentif mLim > (support/2+1)
45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    error('mLim in suppress.m too large\n');
46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentend
47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentdynrange=1.0000e-004;
50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% other, constants
52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenthsupport = support/2;
53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenthsupport1 = hsupport+1;
54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfactor =  2 / oversampling;
55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentupdatel = support/oversampling;
56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentwin=sqrt(designwindow(0,support));
57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentestLen = round(avtime * samplingfreq/updatel)
58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentrunningfmean =0.0;
60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentmLim = floor(hsupport1/2);
62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentV = sqrt(2/hsupport1)*cos(pi/hsupport1*(repmat((0:hsupport1-1) + 0.5, mLim, 1).* ...
63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    repmat((0:mLim-1)' + 0.5, 1, hsupport1)));
64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfprintf(1,'updatel is %5.3f s\n', updatel/samplingfreq);
66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
69e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbandfirst=8; bandlast=25;
70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentdosmooth=0;  % to get rid of wavy bin counts (can be worse or better)
71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% compute some constants
73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentblockLen = support/oversampling;
74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentmaxDelayb = floor(samplingfreq*maxDelay/updatel); % in blocks
75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurenthistLenb = floor(samplingfreq*histLen/updatel); % in blocks
76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentx0=TheFarEnd;
78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenty0=microphone;
79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent%input
82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenttlength=min([length(microphone),length(TheFarEnd)]);
83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentupdateno=floor(tlength/updatel);
84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenttlength=updatel*updateno;
85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentupdateno = updateno - oversampling + 1;
86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentTheFarEnd =TheFarEnd(1:tlength);
88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentmicrophone =microphone(1:tlength);
89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentTheFarEnd =[zeros(hsupport,1);TheFarEnd(1:tlength)];
91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentmicrophone =[zeros(hsupport,1);microphone(1:tlength)];
92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% signal length
95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentn = min([floor(length(x0)/support)*support,floor(length(y0)/support)*support]);
96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnb = n/blockLen - oversampling + 1; % in blocks
97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% initialize space
99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentwin = sqrt([0 ; hanning(support-1)]);
100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentsxAll2 = zeros(hsupport1,nb);
101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentsyAll2 = zeros(hsupport1,nb);
102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentz500=zeros(5,maxDelayb+1);
104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentz200=zeros(5,hsupport1);
105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbxspectrum=uint32(zeros(nb,1));
107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbxhist=uint32(zeros(maxDelayb+1,1));
108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbyspectrum=uint32(zeros(nb,1));
109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbcount=zeros(1+maxDelayb,nb);
110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfcount=zeros(1+maxDelayb,nb);
111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfout=zeros(1+maxDelayb,nb);
112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentdelay=zeros(nb,1);
113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenttdelay=zeros(nb,1);
114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnlgains=zeros(nb,1);
115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% create space (mainly for debugging)
117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentemicrophone=zeros(tlength,1);
118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfemicrophone=complex(zeros(hsupport1,updateno));
119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentthefilter=zeros(hsupport1,updateno);
120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentthelimiter=ones(hsupport1,updateno);
121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentfTheFarEnd=complex(zeros(hsupport1,updateno));
122e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentafTheFarEnd=zeros(hsupport1,updateno);
123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfmicrophone=complex(zeros(hsupport1,updateno));
124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentafmicrophone=zeros(hsupport1,updateno);
125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
126e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentG = zeros(hsupport1, hsupport1);
127e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentzerovec = zeros(hsupport1,1);
128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentzeromat = zeros(hsupport1);
129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% Reset sums
131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentmmxs_a = zerovec;
132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentmmys_a = zerovec;
133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurents2xs_a = zerovec;
134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurents2ys_a = zerovec;
135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentRxxs_a = zeromat;
136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentRyxs_a = zeromat;
137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentcount_a = 1;
138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentmmxs_b = zerovec;
140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentmmys_b = zerovec;
141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurents2xs_b = zerovec;
142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurents2ys_b = zerovec;
143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentRxxs_b = zeromat;
144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentRyxs_b = zeromat;
145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentcount_b = 1;
146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnog=0;
148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentaaa=zeros(size(TheFarEnd));
150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent% loop over signal blocks
152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfprintf(1,'.. Suppression; averaging G over %5.1f seconds; file length %5.1f seconds ..\n',avtime, length(microphone)/samplingfreq);
153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfprintf(1,'.. SUPPRESSING ONLY AFTER %5.1f SECONDS! ..\n',avtime);
154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfprintf(1,'.. 20 seconds is good ..\n');
155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurenthh = waitbar_j(0,'Please wait...');
156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
157e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfor i=1:updateno
159e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    sb = (i-1)*updatel + 1;
161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    se=sb+support-1;
162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % analysis FFTs
164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    temp=fft(win .* TheFarEnd(sb:se));
165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    fTheFarEnd(:,i)=temp(1:hsupport1);
166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    xf=fTheFarEnd(:,i);
167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    afTheFarEnd(:,i)= abs(fTheFarEnd(:,i));
168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    temp=win .* microphone(sb:se);
170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    temp=fft(win .* microphone(sb:se));
172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    fmicrophone(:,i)=temp(1:hsupport1);
173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    yf=fmicrophone(:,i);
174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    afmicrophone(:,i)= abs(fmicrophone(:,i));
175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ener_orig = afmicrophone(:,i)'*afmicrophone(:,i);
178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if( ener_orig == 0)
179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        afmicrophone(:,i)=lowlevel*ones(size(afmicrophone(:,i)));
180e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
181e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
182e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
183e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    	% use log domain (showed improved performance)
184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentxxf= sqrt(real(xf.*conj(xf))+1e-20);
185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentyyf= sqrt(real(yf.*conj(yf))+1e-20);
186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        sxAll2(:,i) = 20*log10(xxf);
187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent	syAll2(:,i) = 20*log10(yyf);
188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent       mD=min(i-1,maxDelayb);
190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      xthreshold = sum(sxAll2(:,i-mD:i),2)/(maxDelayb+1);
191e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
192e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      [yout, z200] = filter(Bp200,Ap200,syAll2(:,i),z200,2);
193e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      yout=yout/(maxDelayb+1);
194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      ythreshold = mean(syAll2(:,i-mD:i),2);
195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent      
196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  bxspectrum(i)=getBspectrum(sxAll2(:,i),xthreshold,bandfirst,bandlast);
198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  byspectrum(i)=getBspectrum(syAll2(:,i),yout,bandfirst,bandlast);
199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  bxhist(end-mD:end)=bxspectrum(i-mD:i);
201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  
202e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  bcount(:,i)=hisser2( ...
203e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent     byspectrum(i),flipud(bxhist),bandfirst,bandlast);
204e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 
205e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 
206e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  [fout(:,i), z500] = filter(Bp500,Ap500,bcount(:,i),z500,2);
207e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  fcount(:,i)=sum(bcount(:,max(1,i-histLenb+1):i),2); % using the history range
208e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fout(:,i)=round(fout(:,i)); 
209e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  [value,delay(i)]=min(fout(:,i),[],1);
210e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  tdelay(i)=(delay(i)-1)*support/(samplingfreq*oversampling);
211e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
212e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % compensate
213e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
214e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    idel =  max(i - delay(i) + 1,1);
215e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
216e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent  
217e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % echo suppression
218e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
219e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    noisyspec = afmicrophone(:,i);
220e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
221e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Estimate G using covariance matrices
222e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
223e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Cumulative estimates    
224e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    xx = afTheFarEnd(:,idel);
225e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    yy = afmicrophone(:,i);
226e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
227e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Means
228e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    mmxs_a = mmxs_a + xx;
229e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    mmys_a = mmys_a + yy;
230e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (G_ol)
231e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmxs_b = mmxs_b + xx;  
232e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmys_b = mmys_b + yy;
233e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmy = mean([mmys_a/count_a mmys_b/count_b],2);
234e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmx = mean([mmxs_a/count_a mmxs_b/count_b],2);
235e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    else
236e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmx = mmxs_a/count_a;   
237e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmy = mmys_a/count_a;   
238e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
239e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    count_a = count_a + 1;
240e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    count_b = count_b + 1;
241e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
242e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Mean removal
243e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    xxm = xx - mmx;
244e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    yym = yy - mmy;
245e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
246e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Variances
247e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    s2xs_a = s2xs_a +  xxm .* xxm;
248e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    s2ys_a = s2ys_a +  yym .* yym;
249e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    s2xs_b = s2xs_b +  xxm .* xxm;
250e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    s2ys_b = s2ys_b +  yym .* yym;
251e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
252e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Correlation matrices  
253e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Rxxs_a = Rxxs_a + xxm * xxm';
254e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Ryxs_a = Ryxs_a + yym * xxm';
255e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Rxxs_b = Rxxs_b + xxm * xxm';
256e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    Ryxs_b = Ryxs_b + yym * xxm';
257e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
258e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
259e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Gain matrix A
260e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
261e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if mod(i, estLen) == 0
262e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
263e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
264e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % Cumulative based estimates
265e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Rxxf = Rxxs_a / (estLen - 1);
266e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Ryxf = Ryxs_a / (estLen - 1);
267e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
268e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % Variance normalization
269e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        s2x2 = s2xs_a / (estLen - 1);
270e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        s2x2 = sqrt(s2x2);
271e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent       % Sx = diag(max(s2x2,dynrange*max(s2x2)));
272e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Sx = diag(s2x2);
273e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if (sum(s2x2) > 0)
274e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent          iSx = inv(Sx);
275e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent         else
276e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                 iSx= Sx + 0.01;
277e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent         end
278e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent             
279e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        s2y2 = s2ys_a / (estLen - 1);
280e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        s2y2 = sqrt(s2y2);
281e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent       % Sy = diag(max(s2y2,dynrange*max(s2y2)));
282e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Sy = diag(s2y2);
283e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        iSy = inv(Sy);        
284e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        rx = iSx * Rxxf * iSx;
285e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        ryx = iSy * Ryxf * iSx;
286e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
287e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent     
288e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
289e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        dbd= 7; % Us less than the full matrix
290e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
291e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % k x m
292e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % Bandlimited structure on G
293e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        LSEon = 0; % Default is using MMSE
294e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if (LSEon)
295e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            ryx = ryx*rx;
296e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            rx = rx*rx;
297e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        end
298e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        p = dbd-1;
299e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        gaj = min(min(hsupport1,2*p+1),min([p+(1:hsupport1); hsupport1+p+1-(1:hsupport1)]));
300e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        cgaj = [0 cumsum(gaj)];
301e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
302e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        G3 = zeros(hsupport1);
303e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        for kk=1:hsupport1
304e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            ki = max(0,kk-p-1);
305e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            if (sum(sum(rx(ki+1:ki+gaj(kk),ki+1:ki+gaj(kk))))>0)
306e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent               G3(kk,ki+1:ki+gaj(kk)) = ryx(kk,ki+1:ki+gaj(kk))/rx(ki+1:ki+gaj(kk),ki+1:ki+gaj(kk));
307e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent           else
308e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent               G3(kk,ki+1:ki+gaj(kk)) = ryx(kk,ki+1:ki+gaj(kk));
309e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent           end
310e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        end
311e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % End Bandlimited structure
312e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
313e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        G = G3;
314e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        G(abs(G)<0.01)=0;
315e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        G = suppress_overdrive * Sy * G * iSx;
316e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
317e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if 1
318e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            figure(32); mi=2;
319e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            surf(max(min(G,mi),-mi)); view(2)
320e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            title('Unscaled Masked Limited-bandwidth G');
321e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        end
322e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        pause(0.05);
323e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
324e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % Reset sums
325e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmxs_a = zerovec;
326e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        mmys_a = zerovec;
327e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        s2xs_a = zerovec;
328e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        s2ys_a = zerovec;
329e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Rxxs_a = zeromat;
330e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        Ryxs_a = zeromat;
331e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        count_a = 1;
332e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
333e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
334e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
335e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (G_ol)    
336e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        % Gain matrix B
337e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
338e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        if ((mod((i-estLen/2), estLen) == 0) & i>estLen)
339e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
340e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
341e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            % Cumulative based estimates
342e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            Rxxf = Rxxs_b / (estLen - 1);
343e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            Ryxf = Ryxs_b / (estLen - 1);
344e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
345e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            % Variance normalization
346e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            s2x2 = s2xs_b / (estLen - 1);
347e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            s2x2 = sqrt(s2x2);
348e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            Sx = diag(max(s2x2,dynrange*max(s2x2)));
349e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            iSx = inv(Sx);
350e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            s2y2 = s2ys_b / (estLen - 1);
351e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            s2y2 = sqrt(s2y2);
352e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            Sy = diag(max(s2y2,dynrange*max(s2y2)));
353e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            iSy = inv(Sy);        
354e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            rx = iSx * Rxxf * iSx;
355e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            ryx = iSy * Ryxf * iSx;
356e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
357e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
358e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            % Bandlimited structure on G
359e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            LSEon = 0; % Default is using MMSE
360e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            if (LSEon)
361e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                ryx = ryx*rx;
362e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                rx = rx*rx;
363e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            end
364e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            p = dbd-1;
365e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            gaj = min(min(hsupport1,2*p+1),min([p+(1:hsupport1); hsupport1+p+1-(1:hsupport1)]));
366e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            cgaj = [0 cumsum(gaj)];
367e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
368e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            G3 = zeros(hsupport1);
369e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            for kk=1:hsupport1
370e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                ki = max(0,kk-p-1);
371e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                G3(kk,ki+1:ki+gaj(kk)) = ryx(kk,ki+1:ki+gaj(kk))/rx(ki+1:ki+gaj(kk),ki+1:ki+gaj(kk));
372e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            end
373e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            % End Bandlimited structure
374e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
375e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            G = G3;
376e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            G(abs(G)<0.01)=0;
377e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            G = suppress_overdrive * Sy * G * iSx;
378e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
379e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            if 1
380e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                figure(32); mi=2;
381e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                surf(max(min(G,mi),-mi)); view(2)
382e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent                title('Unscaled Masked Limited-bandwidth G');
383e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            end
384e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            pause(0.05);
385e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
386e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
387e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            % Reset sums
388e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            mmxs_b = zerovec;
389e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            mmys_b = zerovec;
390e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            s2xs_b = zerovec;
391e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            s2ys_b = zerovec;
392e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            Rxxs_b = zeromat;
393e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            Ryxs_b = zeromat;
394e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            count_b = 1;
395e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent            
396e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        end
397e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        
398e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
399e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
400e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    FECestimate2 = G*afTheFarEnd(:,idel);
401e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
402e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % compute Wiener filter and suppressor function
403e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thefilter(:,i) = (noisyspec - gamma_echo*FECestimate2) ./ noisyspec;
404e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ix0 = find(thefilter(:,i)<de_echo_bound);   % bounding trick 1
405e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thefilter(ix0,i) = de_echo_bound;     % bounding trick 2
406e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    ix0 = find(thefilter(:,i)>1);   % bounding in reasonable range
407e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thefilter(ix0,i) = 1;
408e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
409e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % NONLINEARITY
410e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    nl_alpha=0.8;    % memory; seems not very critical
411e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    nlSeverity=0.3;  % nonlinearity severity: 0 does nothing; 1 suppresses all
412e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thefmean=mean(thefilter(8:16,i));
413e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (thefmean<1)
414e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        disp('');
415e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
416e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    runningfmean = nl_alpha*runningfmean + (1-nl_alpha)*thefmean;
417e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    aaa(sb+20+1:sb+20+updatel)=10000*runningfmean* ones(updatel,1); % debug
418e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    slope0=1.0/(1.0-nlSeverity); %
419e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thegain = max(0.0,min(1.0,slope0*(runningfmean-nlSeverity)));
420e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % END NONLINEARITY
421e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thefilter(:,i) = thegain*thefilter(:,i);
422e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
423e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
424e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % Wiener filtering
425e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    femicrophone(:,i) = fmicrophone(:,i) .* thefilter(:,i);
426e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thelimiter(:,i) = (noisyspec - A_GAIN*FECestimate2) ./ noisyspec;
427e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    index = find(thelimiter(:,i)>1.0);
428e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thelimiter(index,i) = 1.0;
429e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    index = find(thelimiter(:,i)<0.0);
430e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    thelimiter(index,i) = 0.0;
431e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
432e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if (rem(i,floor(updateno/20))==0)
433e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        fprintf(1,'.');
434e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
435e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    if mod(i,50)==0
436e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent        waitbar_j(i/updateno,hh); 
437e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    end
438e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
439e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    
440e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    % reconstruction; first make spectrum odd
441e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    temp=[femicrophone(:,i);flipud(conj(femicrophone(2:hsupport,i)))];
442e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent    emicrophone(sb:se) = emicrophone(sb:se) + factor * win .* real(ifft(temp));
443e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
444e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentend
445e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentfprintf(1,'\n');
446e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent
447e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentclose(hh);