1*28e138c6SAndroid Build Coastguard Worker /* Copyright (C) 2007 Hong Zhiqian */
2*28e138c6SAndroid Build Coastguard Worker /**
3*28e138c6SAndroid Build Coastguard Worker @file mdf_tm.h
4*28e138c6SAndroid Build Coastguard Worker @author Hong Zhiqian
5*28e138c6SAndroid Build Coastguard Worker @brief Various compatibility routines for Speex (TriMedia version)
6*28e138c6SAndroid Build Coastguard Worker */
7*28e138c6SAndroid Build Coastguard Worker /*
8*28e138c6SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without
9*28e138c6SAndroid Build Coastguard Worker modification, are permitted provided that the following conditions
10*28e138c6SAndroid Build Coastguard Worker are met:
11*28e138c6SAndroid Build Coastguard Worker
12*28e138c6SAndroid Build Coastguard Worker - Redistributions of source code must retain the above copyright
13*28e138c6SAndroid Build Coastguard Worker notice, this list of conditions and the following disclaimer.
14*28e138c6SAndroid Build Coastguard Worker
15*28e138c6SAndroid Build Coastguard Worker - Redistributions in binary form must reproduce the above copyright
16*28e138c6SAndroid Build Coastguard Worker notice, this list of conditions and the following disclaimer in the
17*28e138c6SAndroid Build Coastguard Worker documentation and/or other materials provided with the distribution.
18*28e138c6SAndroid Build Coastguard Worker
19*28e138c6SAndroid Build Coastguard Worker - Neither the name of the Xiph.org Foundation nor the names of its
20*28e138c6SAndroid Build Coastguard Worker contributors may be used to endorse or promote products derived from
21*28e138c6SAndroid Build Coastguard Worker this software without specific prior written permission.
22*28e138c6SAndroid Build Coastguard Worker
23*28e138c6SAndroid Build Coastguard Worker THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24*28e138c6SAndroid Build Coastguard Worker ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25*28e138c6SAndroid Build Coastguard Worker LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26*28e138c6SAndroid Build Coastguard Worker A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
27*28e138c6SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28*28e138c6SAndroid Build Coastguard Worker EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29*28e138c6SAndroid Build Coastguard Worker PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30*28e138c6SAndroid Build Coastguard Worker PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31*28e138c6SAndroid Build Coastguard Worker LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32*28e138c6SAndroid Build Coastguard Worker NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33*28e138c6SAndroid Build Coastguard Worker SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*28e138c6SAndroid Build Coastguard Worker */
35*28e138c6SAndroid Build Coastguard Worker #include <ops/custom_defs.h>
36*28e138c6SAndroid Build Coastguard Worker #include "profile_tm.h"
37*28e138c6SAndroid Build Coastguard Worker
38*28e138c6SAndroid Build Coastguard Worker // shifted power spectrum to fftwrap.c so that optimisation can be shared between mdf.c and preprocess.c
39*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_POWER_SPECTRUM
40*28e138c6SAndroid Build Coastguard Worker
41*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
42*28e138c6SAndroid Build Coastguard Worker
43*28e138c6SAndroid Build Coastguard Worker #else
44*28e138c6SAndroid Build Coastguard Worker
45*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_FILTER_DC_NOTCH16
filter_dc_notch16(const spx_int16_t * restrict in,float radius,float * restrict out,int len,float * restrict mem)46*28e138c6SAndroid Build Coastguard Worker void filter_dc_notch16(
47*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict in,
48*28e138c6SAndroid Build Coastguard Worker float radius,
49*28e138c6SAndroid Build Coastguard Worker float * restrict out,
50*28e138c6SAndroid Build Coastguard Worker int len,
51*28e138c6SAndroid Build Coastguard Worker float * restrict mem
52*28e138c6SAndroid Build Coastguard Worker )
53*28e138c6SAndroid Build Coastguard Worker {
54*28e138c6SAndroid Build Coastguard Worker register int i;
55*28e138c6SAndroid Build Coastguard Worker register float den2, r1;
56*28e138c6SAndroid Build Coastguard Worker register float mem0, mem1;
57*28e138c6SAndroid Build Coastguard Worker
58*28e138c6SAndroid Build Coastguard Worker FILTERDCNOTCH16_START();
59*28e138c6SAndroid Build Coastguard Worker
60*28e138c6SAndroid Build Coastguard Worker r1 = 1 - radius;
61*28e138c6SAndroid Build Coastguard Worker den2 = (radius * radius) + (0.7 * r1 * r1);
62*28e138c6SAndroid Build Coastguard Worker mem0 = mem[0];
63*28e138c6SAndroid Build Coastguard Worker mem1 = mem[1];
64*28e138c6SAndroid Build Coastguard Worker
65*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_FILTERDCNOTCH16)
66*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
67*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
68*28e138c6SAndroid Build Coastguard Worker #endif
69*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<len ; ++i )
70*28e138c6SAndroid Build Coastguard Worker {
71*28e138c6SAndroid Build Coastguard Worker register float vin = in[i];
72*28e138c6SAndroid Build Coastguard Worker register float vout = mem0 + vin;
73*28e138c6SAndroid Build Coastguard Worker register float rvout = radius * vout;
74*28e138c6SAndroid Build Coastguard Worker
75*28e138c6SAndroid Build Coastguard Worker mem0 = mem1 + 2 * (-vin + rvout);
76*28e138c6SAndroid Build Coastguard Worker mem1 = vin - (den2 * vout);
77*28e138c6SAndroid Build Coastguard Worker
78*28e138c6SAndroid Build Coastguard Worker out[i] = rvout;
79*28e138c6SAndroid Build Coastguard Worker }
80*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_FILTERDCNOTCH16)
81*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
82*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
83*28e138c6SAndroid Build Coastguard Worker #endif
84*28e138c6SAndroid Build Coastguard Worker
85*28e138c6SAndroid Build Coastguard Worker mem[0] = mem0;
86*28e138c6SAndroid Build Coastguard Worker mem[1] = mem1;
87*28e138c6SAndroid Build Coastguard Worker
88*28e138c6SAndroid Build Coastguard Worker FILTERDCNOTCH16_STOP();
89*28e138c6SAndroid Build Coastguard Worker }
90*28e138c6SAndroid Build Coastguard Worker
91*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_MDF_INNER_PROD
mdf_inner_prod(const float * restrict x,const float * restrict y,int len)92*28e138c6SAndroid Build Coastguard Worker float mdf_inner_prod(
93*28e138c6SAndroid Build Coastguard Worker const float * restrict x,
94*28e138c6SAndroid Build Coastguard Worker const float * restrict y,
95*28e138c6SAndroid Build Coastguard Worker int len
96*28e138c6SAndroid Build Coastguard Worker )
97*28e138c6SAndroid Build Coastguard Worker {
98*28e138c6SAndroid Build Coastguard Worker register float sum = 0;
99*28e138c6SAndroid Build Coastguard Worker
100*28e138c6SAndroid Build Coastguard Worker MDFINNERPROD_START();
101*28e138c6SAndroid Build Coastguard Worker
102*28e138c6SAndroid Build Coastguard Worker len >>= 1;
103*28e138c6SAndroid Build Coastguard Worker
104*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_MDFINNERPRODUCT)
105*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
106*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
107*28e138c6SAndroid Build Coastguard Worker #endif
108*28e138c6SAndroid Build Coastguard Worker while(len--)
109*28e138c6SAndroid Build Coastguard Worker {
110*28e138c6SAndroid Build Coastguard Worker register float acc0, acc1;
111*28e138c6SAndroid Build Coastguard Worker
112*28e138c6SAndroid Build Coastguard Worker acc0 = (*x++) * (*y++);
113*28e138c6SAndroid Build Coastguard Worker acc1 = (*x++) * (*y++);
114*28e138c6SAndroid Build Coastguard Worker
115*28e138c6SAndroid Build Coastguard Worker sum += acc0 + acc1;
116*28e138c6SAndroid Build Coastguard Worker }
117*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_MDFINNERPRODUCT)
118*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
119*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
120*28e138c6SAndroid Build Coastguard Worker #endif
121*28e138c6SAndroid Build Coastguard Worker
122*28e138c6SAndroid Build Coastguard Worker MDFINNERPROD_STOP();
123*28e138c6SAndroid Build Coastguard Worker
124*28e138c6SAndroid Build Coastguard Worker return sum;
125*28e138c6SAndroid Build Coastguard Worker }
126*28e138c6SAndroid Build Coastguard Worker
127*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_SPECTRAL_MUL_ACCUM
spectral_mul_accum(const float * restrict X,const float * restrict Y,float * restrict acc,int N,int M)128*28e138c6SAndroid Build Coastguard Worker void spectral_mul_accum(
129*28e138c6SAndroid Build Coastguard Worker const float * restrict X,
130*28e138c6SAndroid Build Coastguard Worker const float * restrict Y,
131*28e138c6SAndroid Build Coastguard Worker float * restrict acc,
132*28e138c6SAndroid Build Coastguard Worker int N, int M
133*28e138c6SAndroid Build Coastguard Worker )
134*28e138c6SAndroid Build Coastguard Worker {
135*28e138c6SAndroid Build Coastguard Worker register int i, j;
136*28e138c6SAndroid Build Coastguard Worker register float Xi, Yi, Xii, Yii;
137*28e138c6SAndroid Build Coastguard Worker register int _N;
138*28e138c6SAndroid Build Coastguard Worker
139*28e138c6SAndroid Build Coastguard Worker SPECTRALMULACCUM_START();
140*28e138c6SAndroid Build Coastguard Worker
141*28e138c6SAndroid Build Coastguard Worker acc[0] = X[0] * Y[0];
142*28e138c6SAndroid Build Coastguard Worker _N = N-1;
143*28e138c6SAndroid Build Coastguard Worker
144*28e138c6SAndroid Build Coastguard Worker for ( i=1 ; i<_N ; i+=2 )
145*28e138c6SAndroid Build Coastguard Worker {
146*28e138c6SAndroid Build Coastguard Worker Xi = X[i];
147*28e138c6SAndroid Build Coastguard Worker Yi = Y[i];
148*28e138c6SAndroid Build Coastguard Worker Xii = X[i+1];
149*28e138c6SAndroid Build Coastguard Worker Yii = Y[i+1];
150*28e138c6SAndroid Build Coastguard Worker
151*28e138c6SAndroid Build Coastguard Worker acc[i] = (Xi * Yi - Xii * Yii);
152*28e138c6SAndroid Build Coastguard Worker acc[i+1]= (Xii * Yi + Xi * Yii);
153*28e138c6SAndroid Build Coastguard Worker }
154*28e138c6SAndroid Build Coastguard Worker
155*28e138c6SAndroid Build Coastguard Worker acc[_N] = X[_N] * Y[_N];
156*28e138c6SAndroid Build Coastguard Worker
157*28e138c6SAndroid Build Coastguard Worker for ( j=1,X+=N,Y+=N ; j<M ; j++ )
158*28e138c6SAndroid Build Coastguard Worker {
159*28e138c6SAndroid Build Coastguard Worker acc[0] += X[0] * Y[0];
160*28e138c6SAndroid Build Coastguard Worker
161*28e138c6SAndroid Build Coastguard Worker for ( i=1 ; i<N-1 ; i+=2 )
162*28e138c6SAndroid Build Coastguard Worker {
163*28e138c6SAndroid Build Coastguard Worker Xi = X[i];
164*28e138c6SAndroid Build Coastguard Worker Yi = Y[i];
165*28e138c6SAndroid Build Coastguard Worker Xii = X[i+1];
166*28e138c6SAndroid Build Coastguard Worker Yii = Y[i+1];
167*28e138c6SAndroid Build Coastguard Worker
168*28e138c6SAndroid Build Coastguard Worker acc[i] += (Xi * Yi - Xii * Yii);
169*28e138c6SAndroid Build Coastguard Worker acc[i+1]+= (Xii * Yi + Xi * Yii);
170*28e138c6SAndroid Build Coastguard Worker }
171*28e138c6SAndroid Build Coastguard Worker
172*28e138c6SAndroid Build Coastguard Worker acc[_N] += X[_N] * Y[_N];
173*28e138c6SAndroid Build Coastguard Worker X += N;
174*28e138c6SAndroid Build Coastguard Worker Y += N;
175*28e138c6SAndroid Build Coastguard Worker }
176*28e138c6SAndroid Build Coastguard Worker
177*28e138c6SAndroid Build Coastguard Worker SPECTRALMULACCUM_STOP();
178*28e138c6SAndroid Build Coastguard Worker }
179*28e138c6SAndroid Build Coastguard Worker
180*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_WEIGHTED_SPECTRAL_MUL_CONJ
weighted_spectral_mul_conj(const float * restrict w,const float p,const float * restrict X,const float * restrict Y,float * restrict prod,int N)181*28e138c6SAndroid Build Coastguard Worker void weighted_spectral_mul_conj(
182*28e138c6SAndroid Build Coastguard Worker const float * restrict w,
183*28e138c6SAndroid Build Coastguard Worker const float p,
184*28e138c6SAndroid Build Coastguard Worker const float * restrict X,
185*28e138c6SAndroid Build Coastguard Worker const float * restrict Y,
186*28e138c6SAndroid Build Coastguard Worker float * restrict prod,
187*28e138c6SAndroid Build Coastguard Worker int N
188*28e138c6SAndroid Build Coastguard Worker )
189*28e138c6SAndroid Build Coastguard Worker {
190*28e138c6SAndroid Build Coastguard Worker register int i, j;
191*28e138c6SAndroid Build Coastguard Worker register int _N;
192*28e138c6SAndroid Build Coastguard Worker
193*28e138c6SAndroid Build Coastguard Worker WEIGHTEDSPECTRALMULCONJ_START();
194*28e138c6SAndroid Build Coastguard Worker
195*28e138c6SAndroid Build Coastguard Worker prod[0] = p * w[0] * X[0] * Y[0];
196*28e138c6SAndroid Build Coastguard Worker _N = N-1;
197*28e138c6SAndroid Build Coastguard Worker
198*28e138c6SAndroid Build Coastguard Worker for (i=1,j=1;i<_N;i+=2,j++)
199*28e138c6SAndroid Build Coastguard Worker {
200*28e138c6SAndroid Build Coastguard Worker register float W;
201*28e138c6SAndroid Build Coastguard Worker register float Xi, Yi, Xii, Yii;
202*28e138c6SAndroid Build Coastguard Worker
203*28e138c6SAndroid Build Coastguard Worker Xi = X[i];
204*28e138c6SAndroid Build Coastguard Worker Yi = Y[i];
205*28e138c6SAndroid Build Coastguard Worker Xii = X[i+1];
206*28e138c6SAndroid Build Coastguard Worker Yii = Y[i+1];
207*28e138c6SAndroid Build Coastguard Worker W = p * w[j];
208*28e138c6SAndroid Build Coastguard Worker
209*28e138c6SAndroid Build Coastguard Worker
210*28e138c6SAndroid Build Coastguard Worker prod[i] = W * (Xi * Yi + Xii * Yii);
211*28e138c6SAndroid Build Coastguard Worker prod[i+1]= W * (Xi * Yii - Xii * Yi);
212*28e138c6SAndroid Build Coastguard Worker }
213*28e138c6SAndroid Build Coastguard Worker
214*28e138c6SAndroid Build Coastguard Worker prod[_N] = p * w[j] * X[_N] * Y[_N];
215*28e138c6SAndroid Build Coastguard Worker
216*28e138c6SAndroid Build Coastguard Worker WEIGHTEDSPECTRALMULCONJ_STOP();
217*28e138c6SAndroid Build Coastguard Worker }
218*28e138c6SAndroid Build Coastguard Worker
219*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_MDF_ADJUST_PROP
mdf_adjust_prop(const float * restrict W,int N,int M,float * restrict prop)220*28e138c6SAndroid Build Coastguard Worker void mdf_adjust_prop(
221*28e138c6SAndroid Build Coastguard Worker const float * restrict W,
222*28e138c6SAndroid Build Coastguard Worker int N,
223*28e138c6SAndroid Build Coastguard Worker int M,
224*28e138c6SAndroid Build Coastguard Worker float * restrict prop
225*28e138c6SAndroid Build Coastguard Worker )
226*28e138c6SAndroid Build Coastguard Worker {
227*28e138c6SAndroid Build Coastguard Worker register int i, j;
228*28e138c6SAndroid Build Coastguard Worker register float max_sum = 1;
229*28e138c6SAndroid Build Coastguard Worker register float prop_sum = 1;
230*28e138c6SAndroid Build Coastguard Worker
231*28e138c6SAndroid Build Coastguard Worker MDFADJUSTPROP_START();
232*28e138c6SAndroid Build Coastguard Worker
233*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<M ; ++i )
234*28e138c6SAndroid Build Coastguard Worker {
235*28e138c6SAndroid Build Coastguard Worker register float tmp = 1;
236*28e138c6SAndroid Build Coastguard Worker register int k = i * N;
237*28e138c6SAndroid Build Coastguard Worker register int l = k + N;
238*28e138c6SAndroid Build Coastguard Worker register float propi;
239*28e138c6SAndroid Build Coastguard Worker
240*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_MDFADJUSTPROP)
241*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
242*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
243*28e138c6SAndroid Build Coastguard Worker #endif
244*28e138c6SAndroid Build Coastguard Worker for ( j=k ; j<l ; ++j )
245*28e138c6SAndroid Build Coastguard Worker {
246*28e138c6SAndroid Build Coastguard Worker register float wi = W[j];
247*28e138c6SAndroid Build Coastguard Worker
248*28e138c6SAndroid Build Coastguard Worker tmp += wi * wi;
249*28e138c6SAndroid Build Coastguard Worker }
250*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_MDFADJUSTPROP)
251*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
252*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
253*28e138c6SAndroid Build Coastguard Worker #endif
254*28e138c6SAndroid Build Coastguard Worker
255*28e138c6SAndroid Build Coastguard Worker propi = spx_sqrt(tmp);
256*28e138c6SAndroid Build Coastguard Worker prop[i]= propi;
257*28e138c6SAndroid Build Coastguard Worker max_sum= fmux(propi > max_sum, propi, max_sum);
258*28e138c6SAndroid Build Coastguard Worker }
259*28e138c6SAndroid Build Coastguard Worker
260*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<M ; ++i )
261*28e138c6SAndroid Build Coastguard Worker {
262*28e138c6SAndroid Build Coastguard Worker register float propi = prop[i];
263*28e138c6SAndroid Build Coastguard Worker
264*28e138c6SAndroid Build Coastguard Worker propi += .1f * max_sum;
265*28e138c6SAndroid Build Coastguard Worker prop_sum += propi;
266*28e138c6SAndroid Build Coastguard Worker prop[i] = propi;
267*28e138c6SAndroid Build Coastguard Worker }
268*28e138c6SAndroid Build Coastguard Worker
269*28e138c6SAndroid Build Coastguard Worker prop_sum = 0.99f / prop_sum;
270*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<M ; ++i )
271*28e138c6SAndroid Build Coastguard Worker { prop[i] = prop_sum * prop[i];
272*28e138c6SAndroid Build Coastguard Worker }
273*28e138c6SAndroid Build Coastguard Worker
274*28e138c6SAndroid Build Coastguard Worker MDFADJUSTPROP_STOP();
275*28e138c6SAndroid Build Coastguard Worker }
276*28e138c6SAndroid Build Coastguard Worker
277*28e138c6SAndroid Build Coastguard Worker
278*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_SPEEX_ECHO_GET_RESIDUAL
speex_echo_get_residual(SpeexEchoState * restrict st,float * restrict residual_echo,int len)279*28e138c6SAndroid Build Coastguard Worker void speex_echo_get_residual(
280*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
281*28e138c6SAndroid Build Coastguard Worker float * restrict residual_echo,
282*28e138c6SAndroid Build Coastguard Worker int len
283*28e138c6SAndroid Build Coastguard Worker )
284*28e138c6SAndroid Build Coastguard Worker {
285*28e138c6SAndroid Build Coastguard Worker register int i;
286*28e138c6SAndroid Build Coastguard Worker register float leak2, leake;
287*28e138c6SAndroid Build Coastguard Worker register int N;
288*28e138c6SAndroid Build Coastguard Worker register float * restrict window;
289*28e138c6SAndroid Build Coastguard Worker register float * restrict last_y;
290*28e138c6SAndroid Build Coastguard Worker register float * restrict y;
291*28e138c6SAndroid Build Coastguard Worker
292*28e138c6SAndroid Build Coastguard Worker SPEEXECHOGETRESIDUAL_START();
293*28e138c6SAndroid Build Coastguard Worker
294*28e138c6SAndroid Build Coastguard Worker window = st->window;
295*28e138c6SAndroid Build Coastguard Worker last_y = st->last_y;
296*28e138c6SAndroid Build Coastguard Worker y = st->y;
297*28e138c6SAndroid Build Coastguard Worker N = st->window_size;
298*28e138c6SAndroid Build Coastguard Worker
299*28e138c6SAndroid Build Coastguard Worker
300*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL)
301*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
302*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
303*28e138c6SAndroid Build Coastguard Worker #endif
304*28e138c6SAndroid Build Coastguard Worker for (i=0;i<N;i++)
305*28e138c6SAndroid Build Coastguard Worker { y[i] = window[i] * last_y[i];
306*28e138c6SAndroid Build Coastguard Worker }
307*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL)
308*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
309*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
310*28e138c6SAndroid Build Coastguard Worker #endif
311*28e138c6SAndroid Build Coastguard Worker
312*28e138c6SAndroid Build Coastguard Worker spx_fft(st->fft_table, st->y, st->Y);
313*28e138c6SAndroid Build Coastguard Worker power_spectrum(st->Y, residual_echo, N);
314*28e138c6SAndroid Build Coastguard Worker
315*28e138c6SAndroid Build Coastguard Worker leake = st->leak_estimate;
316*28e138c6SAndroid Build Coastguard Worker leak2 = fmux(leake > .5, 1, 2 * leake);
317*28e138c6SAndroid Build Coastguard Worker N = st->frame_size;
318*28e138c6SAndroid Build Coastguard Worker
319*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL)
320*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
321*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
322*28e138c6SAndroid Build Coastguard Worker #endif
323*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<N ; ++i )
324*28e138c6SAndroid Build Coastguard Worker { residual_echo[i] *= leak2;
325*28e138c6SAndroid Build Coastguard Worker }
326*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOGETRESIDUAL)
327*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
328*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
329*28e138c6SAndroid Build Coastguard Worker #endif
330*28e138c6SAndroid Build Coastguard Worker
331*28e138c6SAndroid Build Coastguard Worker residual_echo[N] *= leak2;
332*28e138c6SAndroid Build Coastguard Worker
333*28e138c6SAndroid Build Coastguard Worker #ifndef NO_REMARK
334*28e138c6SAndroid Build Coastguard Worker (void)len;
335*28e138c6SAndroid Build Coastguard Worker #endif
336*28e138c6SAndroid Build Coastguard Worker
337*28e138c6SAndroid Build Coastguard Worker SPEEXECHOGETRESIDUAL_STOP();
338*28e138c6SAndroid Build Coastguard Worker }
339*28e138c6SAndroid Build Coastguard Worker #endif
340*28e138c6SAndroid Build Coastguard Worker
341*28e138c6SAndroid Build Coastguard Worker
mdf_preemph(SpeexEchoState * restrict st,spx_word16_t * restrict x,const spx_int16_t * restrict far_end,int framesize)342*28e138c6SAndroid Build Coastguard Worker void mdf_preemph(
343*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
344*28e138c6SAndroid Build Coastguard Worker spx_word16_t * restrict x,
345*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict far_end,
346*28e138c6SAndroid Build Coastguard Worker int framesize
347*28e138c6SAndroid Build Coastguard Worker )
348*28e138c6SAndroid Build Coastguard Worker {
349*28e138c6SAndroid Build Coastguard Worker register spx_word16_t preemph = st->preemph;
350*28e138c6SAndroid Build Coastguard Worker register spx_word16_t memX = st->memX;
351*28e138c6SAndroid Build Coastguard Worker register spx_word16_t memD = st->memD;
352*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict input = st->input;
353*28e138c6SAndroid Build Coastguard Worker register int i;
354*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
355*28e138c6SAndroid Build Coastguard Worker register int saturated = st->saturated;
356*28e138c6SAndroid Build Coastguard Worker #endif
357*28e138c6SAndroid Build Coastguard Worker
358*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
359*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
360*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
361*28e138c6SAndroid Build Coastguard Worker #endif
362*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<framesize ; ++i )
363*28e138c6SAndroid Build Coastguard Worker {
364*28e138c6SAndroid Build Coastguard Worker register spx_int16_t far_endi = far_end[i];
365*28e138c6SAndroid Build Coastguard Worker register spx_word32_t tmp32;
366*28e138c6SAndroid Build Coastguard Worker register spx_word16_t inputi = input[i];
367*28e138c6SAndroid Build Coastguard Worker
368*28e138c6SAndroid Build Coastguard Worker tmp32 = SUB32(EXTEND32(far_endi), EXTEND32(MULT16_16_P15(preemph,memX)));
369*28e138c6SAndroid Build Coastguard Worker
370*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
371*28e138c6SAndroid Build Coastguard Worker saturated = mux(iabs(tmp32) > 32767, M+1, saturated);
372*28e138c6SAndroid Build Coastguard Worker tmp32 = iclipi(tmp32,32767);
373*28e138c6SAndroid Build Coastguard Worker #endif
374*28e138c6SAndroid Build Coastguard Worker
375*28e138c6SAndroid Build Coastguard Worker x[i] = EXTRACT16(tmp32);
376*28e138c6SAndroid Build Coastguard Worker memX = far_endi;
377*28e138c6SAndroid Build Coastguard Worker tmp32 = SUB32(EXTEND32(inputi), EXTEND32(MULT16_16_P15(preemph, memD)));
378*28e138c6SAndroid Build Coastguard Worker
379*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
380*28e138c6SAndroid Build Coastguard Worker saturated = mux( ((tmp32 > 32767) && (saturated == 0)), 1,
381*28e138c6SAndroid Build Coastguard Worker mux( ((tmp32 <-32767) && (saturated == 0)), 1, saturated ));
382*28e138c6SAndroid Build Coastguard Worker tmp32 = iclipi(tmp32,32767);
383*28e138c6SAndroid Build Coastguard Worker #endif
384*28e138c6SAndroid Build Coastguard Worker memD = inputi;
385*28e138c6SAndroid Build Coastguard Worker input[i] = tmp32;
386*28e138c6SAndroid Build Coastguard Worker }
387*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
388*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
389*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
390*28e138c6SAndroid Build Coastguard Worker #endif
391*28e138c6SAndroid Build Coastguard Worker
392*28e138c6SAndroid Build Coastguard Worker st->memD = memD;
393*28e138c6SAndroid Build Coastguard Worker st->memX = memX;
394*28e138c6SAndroid Build Coastguard Worker
395*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
396*28e138c6SAndroid Build Coastguard Worker st->saturated = saturated;
397*28e138c6SAndroid Build Coastguard Worker #endif
398*28e138c6SAndroid Build Coastguard Worker }
399*28e138c6SAndroid Build Coastguard Worker
mdf_sub(spx_word16_t * restrict dest,const spx_word16_t * restrict src1,const spx_word16_t * restrict src2,int framesize)400*28e138c6SAndroid Build Coastguard Worker void mdf_sub(
401*28e138c6SAndroid Build Coastguard Worker spx_word16_t * restrict dest,
402*28e138c6SAndroid Build Coastguard Worker const spx_word16_t * restrict src1,
403*28e138c6SAndroid Build Coastguard Worker const spx_word16_t * restrict src2,
404*28e138c6SAndroid Build Coastguard Worker int framesize
405*28e138c6SAndroid Build Coastguard Worker )
406*28e138c6SAndroid Build Coastguard Worker {
407*28e138c6SAndroid Build Coastguard Worker register int i;
408*28e138c6SAndroid Build Coastguard Worker
409*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
410*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
411*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
412*28e138c6SAndroid Build Coastguard Worker #endif
413*28e138c6SAndroid Build Coastguard Worker
414*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
415*28e138c6SAndroid Build Coastguard Worker for ( i=0,framesize<<=1 ; i<framesize ; i+=4 )
416*28e138c6SAndroid Build Coastguard Worker { register int src1i, src2i, desti;
417*28e138c6SAndroid Build Coastguard Worker
418*28e138c6SAndroid Build Coastguard Worker src1i = ld32d(src1,i);
419*28e138c6SAndroid Build Coastguard Worker src2i = ld32d(src2,i);
420*28e138c6SAndroid Build Coastguard Worker desti = dspidualsub(src1i,src2i);
421*28e138c6SAndroid Build Coastguard Worker st32d(i, dest, desti);
422*28e138c6SAndroid Build Coastguard Worker }
423*28e138c6SAndroid Build Coastguard Worker #else
424*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<framesize ; ++i )
425*28e138c6SAndroid Build Coastguard Worker { dest[i] = src1[i] - src2[i];
426*28e138c6SAndroid Build Coastguard Worker }
427*28e138c6SAndroid Build Coastguard Worker #endif
428*28e138c6SAndroid Build Coastguard Worker
429*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
430*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
431*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
432*28e138c6SAndroid Build Coastguard Worker #endif
433*28e138c6SAndroid Build Coastguard Worker }
434*28e138c6SAndroid Build Coastguard Worker
mdf_sub_int(spx_word16_t * restrict dest,const spx_int16_t * restrict src1,const spx_int16_t * restrict src2,int framesize)435*28e138c6SAndroid Build Coastguard Worker void mdf_sub_int(
436*28e138c6SAndroid Build Coastguard Worker spx_word16_t * restrict dest,
437*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict src1,
438*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict src2,
439*28e138c6SAndroid Build Coastguard Worker int framesize
440*28e138c6SAndroid Build Coastguard Worker )
441*28e138c6SAndroid Build Coastguard Worker {
442*28e138c6SAndroid Build Coastguard Worker register int i, j;
443*28e138c6SAndroid Build Coastguard Worker
444*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
445*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
446*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
447*28e138c6SAndroid Build Coastguard Worker #endif
448*28e138c6SAndroid Build Coastguard Worker
449*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
450*28e138c6SAndroid Build Coastguard Worker for ( i=0,framesize<<=1 ; i<framesize ; i+=4 )
451*28e138c6SAndroid Build Coastguard Worker { register int src1i, src2i, desti;
452*28e138c6SAndroid Build Coastguard Worker
453*28e138c6SAndroid Build Coastguard Worker src1i = ld32d(src1,i);
454*28e138c6SAndroid Build Coastguard Worker src2i = ld32d(src2,i);
455*28e138c6SAndroid Build Coastguard Worker desti = dspidualsub(src1i,src2i);
456*28e138c6SAndroid Build Coastguard Worker st32d(i, dest, desti);
457*28e138c6SAndroid Build Coastguard Worker }
458*28e138c6SAndroid Build Coastguard Worker #else
459*28e138c6SAndroid Build Coastguard Worker for ( i=0,j=0 ; i<framesize ; i+=2,++j )
460*28e138c6SAndroid Build Coastguard Worker { register int src1i, src2i, desti;
461*28e138c6SAndroid Build Coastguard Worker
462*28e138c6SAndroid Build Coastguard Worker
463*28e138c6SAndroid Build Coastguard Worker src1i = ld32d(src1,j);
464*28e138c6SAndroid Build Coastguard Worker src2i = ld32d(src2,j);
465*28e138c6SAndroid Build Coastguard Worker desti = dspidualsub(src1i,src2i);
466*28e138c6SAndroid Build Coastguard Worker
467*28e138c6SAndroid Build Coastguard Worker dest[i] = sex16(desti);
468*28e138c6SAndroid Build Coastguard Worker dest[i+1] = asri(16,desti);
469*28e138c6SAndroid Build Coastguard Worker }
470*28e138c6SAndroid Build Coastguard Worker #endif
471*28e138c6SAndroid Build Coastguard Worker
472*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
473*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
474*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
475*28e138c6SAndroid Build Coastguard Worker #endif
476*28e138c6SAndroid Build Coastguard Worker }
477*28e138c6SAndroid Build Coastguard Worker
mdf_compute_weight_gradient(SpeexEchoState * restrict st,spx_word16_t * restrict X,int N,int M)478*28e138c6SAndroid Build Coastguard Worker void mdf_compute_weight_gradient(
479*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
480*28e138c6SAndroid Build Coastguard Worker spx_word16_t * restrict X,
481*28e138c6SAndroid Build Coastguard Worker int N,
482*28e138c6SAndroid Build Coastguard Worker int M
483*28e138c6SAndroid Build Coastguard Worker )
484*28e138c6SAndroid Build Coastguard Worker {
485*28e138c6SAndroid Build Coastguard Worker register int i, j;
486*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict PHI = st->PHI;
487*28e138c6SAndroid Build Coastguard Worker
488*28e138c6SAndroid Build Coastguard Worker for (j=M-1;j>=0;j--)
489*28e138c6SAndroid Build Coastguard Worker {
490*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict W = &(st->W[j*N]);
491*28e138c6SAndroid Build Coastguard Worker
492*28e138c6SAndroid Build Coastguard Worker weighted_spectral_mul_conj(
493*28e138c6SAndroid Build Coastguard Worker st->power_1,
494*28e138c6SAndroid Build Coastguard Worker FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15),
495*28e138c6SAndroid Build Coastguard Worker &X[(j+1)*N],
496*28e138c6SAndroid Build Coastguard Worker st->E,
497*28e138c6SAndroid Build Coastguard Worker st->PHI,
498*28e138c6SAndroid Build Coastguard Worker N);
499*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
500*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
501*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
502*28e138c6SAndroid Build Coastguard Worker #endif
503*28e138c6SAndroid Build Coastguard Worker for (i=0;i<N;i++)
504*28e138c6SAndroid Build Coastguard Worker { W[i] = ADD32(W[i],PHI[i]);
505*28e138c6SAndroid Build Coastguard Worker }
506*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
507*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
508*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
509*28e138c6SAndroid Build Coastguard Worker #endif
510*28e138c6SAndroid Build Coastguard Worker }
511*28e138c6SAndroid Build Coastguard Worker }
512*28e138c6SAndroid Build Coastguard Worker
mdf_update_weight(SpeexEchoState * restrict st,int N,int M,int framesize)513*28e138c6SAndroid Build Coastguard Worker void mdf_update_weight(
514*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
515*28e138c6SAndroid Build Coastguard Worker int N,
516*28e138c6SAndroid Build Coastguard Worker int M,
517*28e138c6SAndroid Build Coastguard Worker int framesize
518*28e138c6SAndroid Build Coastguard Worker )
519*28e138c6SAndroid Build Coastguard Worker {
520*28e138c6SAndroid Build Coastguard Worker register int j;
521*28e138c6SAndroid Build Coastguard Worker register int cancel_count = st->cancel_count;
522*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict wtmp = st->wtmp;
523*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
524*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict wtmp2 = st->wtmp2;
525*28e138c6SAndroid Build Coastguard Worker register int i;
526*28e138c6SAndroid Build Coastguard Worker #endif
527*28e138c6SAndroid Build Coastguard Worker
528*28e138c6SAndroid Build Coastguard Worker for ( j=0 ; j<M ; j++ )
529*28e138c6SAndroid Build Coastguard Worker {
530*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict W = &(st->W[j*N]);
531*28e138c6SAndroid Build Coastguard Worker
532*28e138c6SAndroid Build Coastguard Worker if (j==0 || cancel_count%(M-1) == j-1)
533*28e138c6SAndroid Build Coastguard Worker {
534*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
535*28e138c6SAndroid Build Coastguard Worker
536*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
537*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
538*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
539*28e138c6SAndroid Build Coastguard Worker #endif
540*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<N ; i++ )
541*28e138c6SAndroid Build Coastguard Worker wtmp2[i] = EXTRACT16(PSHR32(W[i],NORMALIZE_SCALEDOWN+16));
542*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
543*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
544*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
545*28e138c6SAndroid Build Coastguard Worker #endif
546*28e138c6SAndroid Build Coastguard Worker spx_ifft(st->fft_table, wtmp2, wtmp);
547*28e138c6SAndroid Build Coastguard Worker memset(wtmp, 0, framesize * sizeof(spx_word16_t));
548*28e138c6SAndroid Build Coastguard Worker
549*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
550*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
551*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
552*28e138c6SAndroid Build Coastguard Worker #endif
553*28e138c6SAndroid Build Coastguard Worker for (j=framesize; j<N ; ++j)
554*28e138c6SAndroid Build Coastguard Worker { wtmp[j]=SHL16(wtmp[j],NORMALIZE_SCALEUP);
555*28e138c6SAndroid Build Coastguard Worker }
556*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
557*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
558*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
559*28e138c6SAndroid Build Coastguard Worker #endif
560*28e138c6SAndroid Build Coastguard Worker
561*28e138c6SAndroid Build Coastguard Worker spx_fft(st->fft_table, wtmp, wtmp2);
562*28e138c6SAndroid Build Coastguard Worker
563*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
564*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
565*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
566*28e138c6SAndroid Build Coastguard Worker #endif
567*28e138c6SAndroid Build Coastguard Worker for (i=0;i<N;i++)
568*28e138c6SAndroid Build Coastguard Worker { W[i] -= SHL32(EXTEND32(wtmp2[i]),16+NORMALIZE_SCALEDOWN-NORMALIZE_SCALEUP-1);
569*28e138c6SAndroid Build Coastguard Worker }
570*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
571*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
572*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
573*28e138c6SAndroid Build Coastguard Worker #endif
574*28e138c6SAndroid Build Coastguard Worker
575*28e138c6SAndroid Build Coastguard Worker #else
576*28e138c6SAndroid Build Coastguard Worker spx_ifft(st->fft_table, W, wtmp);
577*28e138c6SAndroid Build Coastguard Worker memset(&wtmp[framesize], 0, (N-framesize) * sizeof(spx_word16_t));
578*28e138c6SAndroid Build Coastguard Worker spx_fft(st->fft_table, wtmp, W);
579*28e138c6SAndroid Build Coastguard Worker #endif
580*28e138c6SAndroid Build Coastguard Worker }
581*28e138c6SAndroid Build Coastguard Worker }
582*28e138c6SAndroid Build Coastguard Worker }
583*28e138c6SAndroid Build Coastguard Worker
584*28e138c6SAndroid Build Coastguard Worker #ifdef TWO_PATH
585*28e138c6SAndroid Build Coastguard Worker // first four parameters is passed by registers
586*28e138c6SAndroid Build Coastguard Worker // generate faster performance with 4 parameters functions
mdf_update_foreground(SpeexEchoState * restrict st,spx_word32_t Dbf,spx_word32_t Sff,spx_word32_t See)587*28e138c6SAndroid Build Coastguard Worker spx_word32_t mdf_update_foreground(
588*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
589*28e138c6SAndroid Build Coastguard Worker spx_word32_t Dbf,
590*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sff,
591*28e138c6SAndroid Build Coastguard Worker spx_word32_t See
592*28e138c6SAndroid Build Coastguard Worker )
593*28e138c6SAndroid Build Coastguard Worker {
594*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Davg1 = st->Davg1;
595*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Davg2 = st->Davg2;
596*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Dvar1 = st->Dvar1;
597*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Dvar2 = st->Dvar2;
598*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict input = st->input;
599*28e138c6SAndroid Build Coastguard Worker register int framesize = st->frame_size;
600*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict xx = st->x + framesize;
601*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict y = st->y + framesize;
602*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict ee = st->e + framesize;
603*28e138c6SAndroid Build Coastguard Worker register int update_foreground;
604*28e138c6SAndroid Build Coastguard Worker register int i;
605*28e138c6SAndroid Build Coastguard Worker register int N = st->window_size;
606*28e138c6SAndroid Build Coastguard Worker register int M = st->M;
607*28e138c6SAndroid Build Coastguard Worker
608*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
609*28e138c6SAndroid Build Coastguard Worker register spx_word32_t sc0 = SUB32(Sff,See);
610*28e138c6SAndroid Build Coastguard Worker register spx_float_t sc1 = FLOAT_MUL32U(Sff,Dbf);
611*28e138c6SAndroid Build Coastguard Worker
612*28e138c6SAndroid Build Coastguard Worker Davg1 = ADD32(MULT16_32_Q15(QCONST16(.6f,15),Davg1), MULT16_32_Q15(QCONST16(.4f,15),sc0));
613*28e138c6SAndroid Build Coastguard Worker Davg2 = ADD32(MULT16_32_Q15(QCONST16(.85f,15),Davg2), MULT16_32_Q15(QCONST16(.15f,15),sc0));
614*28e138c6SAndroid Build Coastguard Worker Dvar1 = FLOAT_ADD(
615*28e138c6SAndroid Build Coastguard Worker FLOAT_MULT(VAR1_SMOOTH,Dvar1),
616*28e138c6SAndroid Build Coastguard Worker FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.4f,15),Sff),
617*28e138c6SAndroid Build Coastguard Worker MULT16_32_Q15(QCONST16(.4f,15),Dbf)));
618*28e138c6SAndroid Build Coastguard Worker Dvar2 = FLOAT_ADD(
619*28e138c6SAndroid Build Coastguard Worker FLOAT_MULT(VAR2_SMOOTH,Dvar2),
620*28e138c6SAndroid Build Coastguard Worker FLOAT_MUL32U(MULT16_32_Q15(QCONST16(.15f,15),Sff),
621*28e138c6SAndroid Build Coastguard Worker MULT16_32_Q15(QCONST16(.15f,15),Dbf)));
622*28e138c6SAndroid Build Coastguard Worker #else
623*28e138c6SAndroid Build Coastguard Worker register spx_word32_t sc0 = Sff - See;
624*28e138c6SAndroid Build Coastguard Worker register spx_word32_t sc1 = Sff * Dbf;
625*28e138c6SAndroid Build Coastguard Worker
626*28e138c6SAndroid Build Coastguard Worker Davg1 = .6*Davg1 + .4*sc0;
627*28e138c6SAndroid Build Coastguard Worker Davg2 = .85*Davg2 + .15*sc0;
628*28e138c6SAndroid Build Coastguard Worker Dvar1 = VAR1_SMOOTH*Dvar1 + .16*sc1;
629*28e138c6SAndroid Build Coastguard Worker Dvar2 = VAR2_SMOOTH*Dvar2 + .0225*sc1;
630*28e138c6SAndroid Build Coastguard Worker #endif
631*28e138c6SAndroid Build Coastguard Worker
632*28e138c6SAndroid Build Coastguard Worker update_foreground =
633*28e138c6SAndroid Build Coastguard Worker mux( FLOAT_GT(FLOAT_MUL32U(sc0, VABS(sc0)), sc1), 1,
634*28e138c6SAndroid Build Coastguard Worker mux( FLOAT_GT(FLOAT_MUL32U(Davg1, VABS(Davg1)), FLOAT_MULT(VAR1_UPDATE,(Dvar1))), 1,
635*28e138c6SAndroid Build Coastguard Worker mux( FLOAT_GT(FLOAT_MUL32U(Davg2, VABS(Davg2)), FLOAT_MULT(VAR2_UPDATE,(Dvar2))), 1, 0)));
636*28e138c6SAndroid Build Coastguard Worker
637*28e138c6SAndroid Build Coastguard Worker if ( update_foreground )
638*28e138c6SAndroid Build Coastguard Worker {
639*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict windowf = st->window + framesize;
640*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict window = st->window;
641*28e138c6SAndroid Build Coastguard Worker
642*28e138c6SAndroid Build Coastguard Worker st->Davg1 = st->Davg2 = 0;
643*28e138c6SAndroid Build Coastguard Worker st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
644*28e138c6SAndroid Build Coastguard Worker
645*28e138c6SAndroid Build Coastguard Worker memcpy(st->foreground, st->W, N*M*sizeof(spx_word32_t));
646*28e138c6SAndroid Build Coastguard Worker
647*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
648*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
649*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
650*28e138c6SAndroid Build Coastguard Worker #endif
651*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<framesize ; ++i)
652*28e138c6SAndroid Build Coastguard Worker { register spx_word16_t wi = window[i];
653*28e138c6SAndroid Build Coastguard Worker register spx_word16_t wfi = windowf[i];
654*28e138c6SAndroid Build Coastguard Worker register spx_word16_t ei = ee[i];
655*28e138c6SAndroid Build Coastguard Worker register spx_word16_t yi = y[i];
656*28e138c6SAndroid Build Coastguard Worker
657*28e138c6SAndroid Build Coastguard Worker ee[i] = MULT16_16_Q15(wfi,ei) + MULT16_16_Q15(wi,yi);
658*28e138c6SAndroid Build Coastguard Worker }
659*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
660*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
661*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
662*28e138c6SAndroid Build Coastguard Worker #endif
663*28e138c6SAndroid Build Coastguard Worker
664*28e138c6SAndroid Build Coastguard Worker } else
665*28e138c6SAndroid Build Coastguard Worker {
666*28e138c6SAndroid Build Coastguard Worker register int reset_background;
667*28e138c6SAndroid Build Coastguard Worker
668*28e138c6SAndroid Build Coastguard Worker reset_background =
669*28e138c6SAndroid Build Coastguard Worker mux( FLOAT_GT(FLOAT_MUL32U(-(sc0),VABS(sc0)), FLOAT_MULT(VAR_BACKTRACK,sc1)), 1,
670*28e138c6SAndroid Build Coastguard Worker mux( FLOAT_GT(FLOAT_MUL32U(-(Davg1), VABS(Davg1)), FLOAT_MULT(VAR_BACKTRACK,Dvar1)), 1,
671*28e138c6SAndroid Build Coastguard Worker mux( FLOAT_GT(FLOAT_MUL32U(-(Davg2), VABS(Davg2)), FLOAT_MULT(VAR_BACKTRACK,Dvar2)), 1, 0)));
672*28e138c6SAndroid Build Coastguard Worker
673*28e138c6SAndroid Build Coastguard Worker if ( reset_background )
674*28e138c6SAndroid Build Coastguard Worker {
675*28e138c6SAndroid Build Coastguard Worker memcpy(st->W, st->foreground, N*M*sizeof(spx_word32_t));
676*28e138c6SAndroid Build Coastguard Worker memcpy(y, ee, framesize * sizeof(spx_word16_t));
677*28e138c6SAndroid Build Coastguard Worker mdf_sub(xx,input,y,framesize);
678*28e138c6SAndroid Build Coastguard Worker See = Sff;
679*28e138c6SAndroid Build Coastguard Worker st->Davg1 = st->Davg2 = 0;
680*28e138c6SAndroid Build Coastguard Worker st->Dvar1 = st->Dvar2 = FLOAT_ZERO;
681*28e138c6SAndroid Build Coastguard Worker } else
682*28e138c6SAndroid Build Coastguard Worker {
683*28e138c6SAndroid Build Coastguard Worker st->Davg1 = Davg1;
684*28e138c6SAndroid Build Coastguard Worker st->Davg2 = Davg2;
685*28e138c6SAndroid Build Coastguard Worker st->Dvar1 = Dvar1;
686*28e138c6SAndroid Build Coastguard Worker st->Dvar2 = Dvar2;
687*28e138c6SAndroid Build Coastguard Worker }
688*28e138c6SAndroid Build Coastguard Worker }
689*28e138c6SAndroid Build Coastguard Worker
690*28e138c6SAndroid Build Coastguard Worker return See;
691*28e138c6SAndroid Build Coastguard Worker }
692*28e138c6SAndroid Build Coastguard Worker #endif
693*28e138c6SAndroid Build Coastguard Worker
mdf_compute_error_signal(SpeexEchoState * restrict st,const spx_int16_t * restrict in,spx_int16_t * restrict out,int framesize)694*28e138c6SAndroid Build Coastguard Worker void mdf_compute_error_signal(
695*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
696*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict in,
697*28e138c6SAndroid Build Coastguard Worker spx_int16_t * restrict out,
698*28e138c6SAndroid Build Coastguard Worker int framesize
699*28e138c6SAndroid Build Coastguard Worker )
700*28e138c6SAndroid Build Coastguard Worker {
701*28e138c6SAndroid Build Coastguard Worker register spx_word16_t preemph = st->preemph;
702*28e138c6SAndroid Build Coastguard Worker register spx_word16_t memE = st->memE;
703*28e138c6SAndroid Build Coastguard Worker register int saturated = st->saturated;
704*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict e = st->e;
705*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict ee = st->e + framesize;
706*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict input = st->input;
707*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict xx = st->x + framesize;
708*28e138c6SAndroid Build Coastguard Worker register int i;
709*28e138c6SAndroid Build Coastguard Worker
710*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
711*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
712*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
713*28e138c6SAndroid Build Coastguard Worker #endif
714*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<framesize ; ++i )
715*28e138c6SAndroid Build Coastguard Worker {
716*28e138c6SAndroid Build Coastguard Worker register spx_word32_t tmp_out;
717*28e138c6SAndroid Build Coastguard Worker register spx_int16_t ini = in[i];
718*28e138c6SAndroid Build Coastguard Worker register int flg;
719*28e138c6SAndroid Build Coastguard Worker
720*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
721*28e138c6SAndroid Build Coastguard Worker
722*28e138c6SAndroid Build Coastguard Worker #ifdef TWO_PATH
723*28e138c6SAndroid Build Coastguard Worker tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(ee[i]));
724*28e138c6SAndroid Build Coastguard Worker tmp_out = iclipi(tmp_out,32767);
725*28e138c6SAndroid Build Coastguard Worker #else
726*28e138c6SAndroid Build Coastguard Worker tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(y[i]));
727*28e138c6SAndroid Build Coastguard Worker tmp_out = iclipi(tmp_out,32767);
728*28e138c6SAndroid Build Coastguard Worker #endif
729*28e138c6SAndroid Build Coastguard Worker
730*28e138c6SAndroid Build Coastguard Worker #else
731*28e138c6SAndroid Build Coastguard Worker #ifdef TWO_PATH
732*28e138c6SAndroid Build Coastguard Worker tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(ee[i]));
733*28e138c6SAndroid Build Coastguard Worker #else
734*28e138c6SAndroid Build Coastguard Worker tmp_out = SUB32(EXTEND32(input[i]), EXTEND32(y[i]));
735*28e138c6SAndroid Build Coastguard Worker #endif
736*28e138c6SAndroid Build Coastguard Worker tmp_out =
737*28e138c6SAndroid Build Coastguard Worker fmux( tmp_out > 32767, 32767,
738*28e138c6SAndroid Build Coastguard Worker fmux( tmp_out < -32768, -32768, tmp_out));
739*28e138c6SAndroid Build Coastguard Worker #endif
740*28e138c6SAndroid Build Coastguard Worker
741*28e138c6SAndroid Build Coastguard Worker tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(preemph,memE)));
742*28e138c6SAndroid Build Coastguard Worker flg = iabs(ini) >= 32000;
743*28e138c6SAndroid Build Coastguard Worker tmp_out = VMUX( flg, 0, tmp_out);
744*28e138c6SAndroid Build Coastguard Worker saturated = mux( flg && (saturated == 0), 1, saturated);
745*28e138c6SAndroid Build Coastguard Worker
746*28e138c6SAndroid Build Coastguard Worker out[i] = (spx_int16_t)tmp_out;
747*28e138c6SAndroid Build Coastguard Worker memE = tmp_out;
748*28e138c6SAndroid Build Coastguard Worker }
749*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
750*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
751*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
752*28e138c6SAndroid Build Coastguard Worker #endif
753*28e138c6SAndroid Build Coastguard Worker
754*28e138c6SAndroid Build Coastguard Worker st->memE = memE;
755*28e138c6SAndroid Build Coastguard Worker st->saturated = saturated;
756*28e138c6SAndroid Build Coastguard Worker memset(e, 0, framesize * sizeof(spx_word16_t));
757*28e138c6SAndroid Build Coastguard Worker memcpy(ee, xx, framesize * sizeof(spx_word16_t));
758*28e138c6SAndroid Build Coastguard Worker }
759*28e138c6SAndroid Build Coastguard Worker
mdf_check(SpeexEchoState * restrict st,spx_int16_t * out,spx_word32_t Syy,spx_word32_t Sxx,spx_word32_t See,spx_word32_t Sff,spx_word32_t Sdd)760*28e138c6SAndroid Build Coastguard Worker inline int mdf_check(
761*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
762*28e138c6SAndroid Build Coastguard Worker spx_int16_t * out,
763*28e138c6SAndroid Build Coastguard Worker spx_word32_t Syy,
764*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sxx,
765*28e138c6SAndroid Build Coastguard Worker spx_word32_t See,
766*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sff,
767*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sdd
768*28e138c6SAndroid Build Coastguard Worker )
769*28e138c6SAndroid Build Coastguard Worker {
770*28e138c6SAndroid Build Coastguard Worker register int N = st->window_size;
771*28e138c6SAndroid Build Coastguard Worker register spx_word32_t N1e9 = N * 1e9;
772*28e138c6SAndroid Build Coastguard Worker register int screwed_up = st->screwed_up;
773*28e138c6SAndroid Build Coastguard Worker register int framesize = st->frame_size;
774*28e138c6SAndroid Build Coastguard Worker
775*28e138c6SAndroid Build Coastguard Worker if (!(Syy>=0 && Sxx>=0 && See >= 0)
776*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
777*28e138c6SAndroid Build Coastguard Worker || !(Sff < N1e9 && Syy < N1e9 && Sxx < N1e9 )
778*28e138c6SAndroid Build Coastguard Worker #endif
779*28e138c6SAndroid Build Coastguard Worker )
780*28e138c6SAndroid Build Coastguard Worker {
781*28e138c6SAndroid Build Coastguard Worker screwed_up += 50;
782*28e138c6SAndroid Build Coastguard Worker memset(out, 0, framesize * sizeof(spx_int16_t));
783*28e138c6SAndroid Build Coastguard Worker
784*28e138c6SAndroid Build Coastguard Worker } else
785*28e138c6SAndroid Build Coastguard Worker { screwed_up = mux( SHR32(Sff, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 10000),6)), screwed_up+1, 0);
786*28e138c6SAndroid Build Coastguard Worker }
787*28e138c6SAndroid Build Coastguard Worker
788*28e138c6SAndroid Build Coastguard Worker st->screwed_up = screwed_up;
789*28e138c6SAndroid Build Coastguard Worker
790*28e138c6SAndroid Build Coastguard Worker return screwed_up;
791*28e138c6SAndroid Build Coastguard Worker }
792*28e138c6SAndroid Build Coastguard Worker
mdf_smooth(spx_word32_t * restrict power,spx_word32_t * restrict Xf,int framesize,int M)793*28e138c6SAndroid Build Coastguard Worker void mdf_smooth(
794*28e138c6SAndroid Build Coastguard Worker spx_word32_t * restrict power,
795*28e138c6SAndroid Build Coastguard Worker spx_word32_t * restrict Xf,
796*28e138c6SAndroid Build Coastguard Worker int framesize,
797*28e138c6SAndroid Build Coastguard Worker int M
798*28e138c6SAndroid Build Coastguard Worker )
799*28e138c6SAndroid Build Coastguard Worker {
800*28e138c6SAndroid Build Coastguard Worker register spx_word16_t ss, ss_1, pf, xff;
801*28e138c6SAndroid Build Coastguard Worker register int j;
802*28e138c6SAndroid Build Coastguard Worker
803*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
804*28e138c6SAndroid Build Coastguard Worker ss=DIV32_16(11469,M);
805*28e138c6SAndroid Build Coastguard Worker ss_1 = SUB16(32767,ss);
806*28e138c6SAndroid Build Coastguard Worker #else
807*28e138c6SAndroid Build Coastguard Worker ss=.35/M;
808*28e138c6SAndroid Build Coastguard Worker ss_1 = 1-ss;
809*28e138c6SAndroid Build Coastguard Worker #endif
810*28e138c6SAndroid Build Coastguard Worker
811*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
812*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
813*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
814*28e138c6SAndroid Build Coastguard Worker #endif
815*28e138c6SAndroid Build Coastguard Worker for ( j=0 ; j<framesize ; ++j )
816*28e138c6SAndroid Build Coastguard Worker { register spx_word32_t pi = power[j];
817*28e138c6SAndroid Build Coastguard Worker register spx_word32_t xfi = Xf[j];
818*28e138c6SAndroid Build Coastguard Worker
819*28e138c6SAndroid Build Coastguard Worker power[j] = MULT16_32_Q15(ss_1,pi) + 1 + MULT16_32_Q15(ss,xfi);
820*28e138c6SAndroid Build Coastguard Worker }
821*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
822*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
823*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
824*28e138c6SAndroid Build Coastguard Worker #endif
825*28e138c6SAndroid Build Coastguard Worker
826*28e138c6SAndroid Build Coastguard Worker pf = power[framesize];
827*28e138c6SAndroid Build Coastguard Worker xff = Xf[framesize];
828*28e138c6SAndroid Build Coastguard Worker power[framesize] = MULT16_32_Q15(ss_1,pf) + 1 + MULT16_32_Q15(ss,xff);
829*28e138c6SAndroid Build Coastguard Worker }
830*28e138c6SAndroid Build Coastguard Worker
mdf_compute_filtered_spectra_crosscorrelations(SpeexEchoState * restrict st,spx_word32_t Syy,spx_word32_t See,int framesize)831*28e138c6SAndroid Build Coastguard Worker void mdf_compute_filtered_spectra_crosscorrelations(
832*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
833*28e138c6SAndroid Build Coastguard Worker spx_word32_t Syy,
834*28e138c6SAndroid Build Coastguard Worker spx_word32_t See,
835*28e138c6SAndroid Build Coastguard Worker int framesize
836*28e138c6SAndroid Build Coastguard Worker )
837*28e138c6SAndroid Build Coastguard Worker {
838*28e138c6SAndroid Build Coastguard Worker register spx_float_t Pey = FLOAT_ONE;
839*28e138c6SAndroid Build Coastguard Worker register spx_float_t Pyy = FLOAT_ONE;
840*28e138c6SAndroid Build Coastguard Worker register spx_word16_t spec_average = st->spec_average;
841*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict pRf = st->Rf;
842*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict pYf = st->Yf;
843*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict pEh = st->Eh;
844*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict pYh = st->Yh;
845*28e138c6SAndroid Build Coastguard Worker register spx_word16_t beta0 = st->beta0;
846*28e138c6SAndroid Build Coastguard Worker register spx_word16_t beta_max = st->beta_max;
847*28e138c6SAndroid Build Coastguard Worker register spx_float_t alpha, alpha_1;
848*28e138c6SAndroid Build Coastguard Worker register spx_word32_t tmp32, tmpx;
849*28e138c6SAndroid Build Coastguard Worker register spx_float_t sPey = st->Pey;
850*28e138c6SAndroid Build Coastguard Worker register spx_float_t sPyy = st->Pyy;
851*28e138c6SAndroid Build Coastguard Worker register spx_float_t tmp;
852*28e138c6SAndroid Build Coastguard Worker register spx_word16_t leak_estimate;
853*28e138c6SAndroid Build Coastguard Worker register int j;
854*28e138c6SAndroid Build Coastguard Worker register spx_float_t Eh, Yh;
855*28e138c6SAndroid Build Coastguard Worker register spx_word32_t _Ehj, _Rfj, _Yfj, _Yhj;
856*28e138c6SAndroid Build Coastguard Worker
857*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
858*28e138c6SAndroid Build Coastguard Worker register spx_word16_t spec_average1 = SUB16(32767,spec_average);
859*28e138c6SAndroid Build Coastguard Worker #else
860*28e138c6SAndroid Build Coastguard Worker register spx_word16_t spec_average1 = 1 - spec_average;
861*28e138c6SAndroid Build Coastguard Worker #endif
862*28e138c6SAndroid Build Coastguard Worker
863*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
864*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
865*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
866*28e138c6SAndroid Build Coastguard Worker #endif
867*28e138c6SAndroid Build Coastguard Worker for (j=framesize; j>0 ; --j)
868*28e138c6SAndroid Build Coastguard Worker {
869*28e138c6SAndroid Build Coastguard Worker _Ehj = pEh[j];
870*28e138c6SAndroid Build Coastguard Worker _Rfj = pRf[j];
871*28e138c6SAndroid Build Coastguard Worker _Yfj = pYf[j];
872*28e138c6SAndroid Build Coastguard Worker _Yhj = pYh[j];
873*28e138c6SAndroid Build Coastguard Worker
874*28e138c6SAndroid Build Coastguard Worker Eh = PSEUDOFLOAT(_Rfj - _Ehj);
875*28e138c6SAndroid Build Coastguard Worker Yh = PSEUDOFLOAT(_Yfj - _Yhj);
876*28e138c6SAndroid Build Coastguard Worker
877*28e138c6SAndroid Build Coastguard Worker Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh));
878*28e138c6SAndroid Build Coastguard Worker Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh));
879*28e138c6SAndroid Build Coastguard Worker
880*28e138c6SAndroid Build Coastguard Worker pEh[j] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Ehj), spec_average, _Rfj);
881*28e138c6SAndroid Build Coastguard Worker pYh[j] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Yhj), spec_average, _Yfj);
882*28e138c6SAndroid Build Coastguard Worker }
883*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
884*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
885*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
886*28e138c6SAndroid Build Coastguard Worker #endif
887*28e138c6SAndroid Build Coastguard Worker _Ehj = pEh[0];
888*28e138c6SAndroid Build Coastguard Worker _Rfj = pRf[0];
889*28e138c6SAndroid Build Coastguard Worker _Yfj = pYf[0];
890*28e138c6SAndroid Build Coastguard Worker _Yhj = pYh[0];
891*28e138c6SAndroid Build Coastguard Worker
892*28e138c6SAndroid Build Coastguard Worker Eh = PSEUDOFLOAT(_Rfj - _Ehj);
893*28e138c6SAndroid Build Coastguard Worker Yh = PSEUDOFLOAT(_Yfj - _Yhj);
894*28e138c6SAndroid Build Coastguard Worker
895*28e138c6SAndroid Build Coastguard Worker Pey = FLOAT_ADD(Pey,FLOAT_MULT(Eh,Yh));
896*28e138c6SAndroid Build Coastguard Worker Pyy = FLOAT_ADD(Pyy,FLOAT_MULT(Yh,Yh));
897*28e138c6SAndroid Build Coastguard Worker
898*28e138c6SAndroid Build Coastguard Worker pEh[0] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Ehj), spec_average, _Rfj);
899*28e138c6SAndroid Build Coastguard Worker pYh[0] = MAC16_32_Q15(MULT16_32_Q15(spec_average1, _Yhj), spec_average, _Yfj);
900*28e138c6SAndroid Build Coastguard Worker
901*28e138c6SAndroid Build Coastguard Worker Pyy = FLOAT_SQRT(Pyy);
902*28e138c6SAndroid Build Coastguard Worker Pey = FLOAT_DIVU(Pey,Pyy);
903*28e138c6SAndroid Build Coastguard Worker
904*28e138c6SAndroid Build Coastguard Worker tmp32 = MULT16_32_Q15(beta0,Syy);
905*28e138c6SAndroid Build Coastguard Worker tmpx = MULT16_32_Q15(beta_max,See);
906*28e138c6SAndroid Build Coastguard Worker tmp32 = VMUX(tmp32 > tmpx, tmpx, tmp32);
907*28e138c6SAndroid Build Coastguard Worker alpha = FLOAT_DIV32(tmp32, See);
908*28e138c6SAndroid Build Coastguard Worker alpha_1 = FLOAT_SUB(FLOAT_ONE, alpha);
909*28e138c6SAndroid Build Coastguard Worker
910*28e138c6SAndroid Build Coastguard Worker sPey = FLOAT_ADD(FLOAT_MULT(alpha_1,sPey) , FLOAT_MULT(alpha,Pey));
911*28e138c6SAndroid Build Coastguard Worker sPyy = FLOAT_ADD(FLOAT_MULT(alpha_1,sPyy) , FLOAT_MULT(alpha,Pyy));
912*28e138c6SAndroid Build Coastguard Worker tmp = FLOAT_MULT(MIN_LEAK,sPyy);
913*28e138c6SAndroid Build Coastguard Worker
914*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
915*28e138c6SAndroid Build Coastguard Worker sPyy = VMUX(FLOAT_LT(sPyy, FLOAT_ONE), FLOAT_ONE, sPyy);
916*28e138c6SAndroid Build Coastguard Worker sPey = VMUX(FLOAT_LT(sPey, tmp), tmp, sPey);
917*28e138c6SAndroid Build Coastguard Worker sPey = VMUX(FLOAT_LT(sPey, sPyy), sPey, sPyy);
918*28e138c6SAndroid Build Coastguard Worker #else
919*28e138c6SAndroid Build Coastguard Worker sPyy = FLOAT_LT(sPyy, FLOAT_ONE) ? FLOAT_ONE : sPyy;
920*28e138c6SAndroid Build Coastguard Worker sPey = FLOAT_LT(sPey, tmp) ? tmp : sPey;
921*28e138c6SAndroid Build Coastguard Worker sPey = FLOAT_LT(sPey, sPyy) ? sPey : sPyy;
922*28e138c6SAndroid Build Coastguard Worker #endif
923*28e138c6SAndroid Build Coastguard Worker
924*28e138c6SAndroid Build Coastguard Worker leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(sPey, sPyy),14));
925*28e138c6SAndroid Build Coastguard Worker
926*28e138c6SAndroid Build Coastguard Worker leak_estimate = VMUX( leak_estimate > 16383, 32767, SHL16(leak_estimate,1));
927*28e138c6SAndroid Build Coastguard Worker st->Pey = sPey;
928*28e138c6SAndroid Build Coastguard Worker st->Pyy = sPyy;
929*28e138c6SAndroid Build Coastguard Worker st->leak_estimate = leak_estimate;
930*28e138c6SAndroid Build Coastguard Worker }
931*28e138c6SAndroid Build Coastguard Worker
mdf_compute_RER(spx_word32_t See,spx_word32_t Syy,spx_word32_t Sey,spx_word32_t Sxx,spx_word16_t leake)932*28e138c6SAndroid Build Coastguard Worker inline spx_word16_t mdf_compute_RER(
933*28e138c6SAndroid Build Coastguard Worker spx_word32_t See,
934*28e138c6SAndroid Build Coastguard Worker spx_word32_t Syy,
935*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sey,
936*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sxx,
937*28e138c6SAndroid Build Coastguard Worker spx_word16_t leake
938*28e138c6SAndroid Build Coastguard Worker )
939*28e138c6SAndroid Build Coastguard Worker {
940*28e138c6SAndroid Build Coastguard Worker register spx_word16_t RER;
941*28e138c6SAndroid Build Coastguard Worker
942*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
943*28e138c6SAndroid Build Coastguard Worker register spx_word32_t tmp32;
944*28e138c6SAndroid Build Coastguard Worker register spx_word32_t tmp;
945*28e138c6SAndroid Build Coastguard Worker spx_float_t bound = PSEUDOFLOAT(Sey);
946*28e138c6SAndroid Build Coastguard Worker
947*28e138c6SAndroid Build Coastguard Worker tmp32 = MULT16_32_Q15(leake,Syy);
948*28e138c6SAndroid Build Coastguard Worker tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1)));
949*28e138c6SAndroid Build Coastguard Worker
950*28e138c6SAndroid Build Coastguard Worker bound = FLOAT_DIVU(FLOAT_MULT(bound, bound), PSEUDOFLOAT(ADD32(1,Syy)));
951*28e138c6SAndroid Build Coastguard Worker tmp = FLOAT_EXTRACT32(bound);
952*28e138c6SAndroid Build Coastguard Worker tmp32 = imux( FLOAT_GT(bound, PSEUDOFLOAT(See)), See,
953*28e138c6SAndroid Build Coastguard Worker imux( tmp32 < tmp, tmp, tmp32));
954*28e138c6SAndroid Build Coastguard Worker
955*28e138c6SAndroid Build Coastguard Worker tmp = SHR32(See,1);
956*28e138c6SAndroid Build Coastguard Worker tmp32 = imux(tmp32 > tmp, tmp, tmp32);
957*28e138c6SAndroid Build Coastguard Worker RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15));
958*28e138c6SAndroid Build Coastguard Worker #else
959*28e138c6SAndroid Build Coastguard Worker register spx_word32_t r0;
960*28e138c6SAndroid Build Coastguard Worker
961*28e138c6SAndroid Build Coastguard Worker r0 = (Sey * Sey)/(1 + See * Syy);
962*28e138c6SAndroid Build Coastguard Worker
963*28e138c6SAndroid Build Coastguard Worker RER = (.0001*Sxx + 3.* MULT16_32_Q15(leake,Syy)) / See;
964*28e138c6SAndroid Build Coastguard Worker RER = fmux( RER < r0, r0, RER);
965*28e138c6SAndroid Build Coastguard Worker RER = fmux( RER > .5, .5, RER);
966*28e138c6SAndroid Build Coastguard Worker #endif
967*28e138c6SAndroid Build Coastguard Worker
968*28e138c6SAndroid Build Coastguard Worker return RER;
969*28e138c6SAndroid Build Coastguard Worker }
970*28e138c6SAndroid Build Coastguard Worker
mdf_adapt(SpeexEchoState * restrict st,spx_word16_t RER,spx_word32_t Syy,spx_word32_t See,spx_word32_t Sxx)971*28e138c6SAndroid Build Coastguard Worker void mdf_adapt(
972*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
973*28e138c6SAndroid Build Coastguard Worker spx_word16_t RER,
974*28e138c6SAndroid Build Coastguard Worker spx_word32_t Syy,
975*28e138c6SAndroid Build Coastguard Worker spx_word32_t See,
976*28e138c6SAndroid Build Coastguard Worker spx_word32_t Sxx
977*28e138c6SAndroid Build Coastguard Worker )
978*28e138c6SAndroid Build Coastguard Worker {
979*28e138c6SAndroid Build Coastguard Worker register spx_float_t * restrict power_1 = st->power_1;
980*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict power = st->power;
981*28e138c6SAndroid Build Coastguard Worker register int adapted = st->adapted;
982*28e138c6SAndroid Build Coastguard Worker register spx_word32_t sum_adapt = st->sum_adapt;
983*28e138c6SAndroid Build Coastguard Worker register spx_word16_t leake = st->leak_estimate;
984*28e138c6SAndroid Build Coastguard Worker register int framesize = st->frame_size;
985*28e138c6SAndroid Build Coastguard Worker register int i;
986*28e138c6SAndroid Build Coastguard Worker register int M = st->M;
987*28e138c6SAndroid Build Coastguard Worker
988*28e138c6SAndroid Build Coastguard Worker adapted = mux( !adapted && sum_adapt > QCONST32(M,15) &&
989*28e138c6SAndroid Build Coastguard Worker MULT16_32_Q15(leake,Syy) > MULT16_32_Q15(QCONST16(.03f,15),Syy), 1, adapted);
990*28e138c6SAndroid Build Coastguard Worker
991*28e138c6SAndroid Build Coastguard Worker if ( adapted )
992*28e138c6SAndroid Build Coastguard Worker { register spx_word32_t * restrict Yf = st->Yf;
993*28e138c6SAndroid Build Coastguard Worker register spx_word32_t * restrict Rf = st->Rf;
994*28e138c6SAndroid Build Coastguard Worker register spx_word32_t r, e, e2;
995*28e138c6SAndroid Build Coastguard Worker
996*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
997*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
998*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
999*28e138c6SAndroid Build Coastguard Worker #endif
1000*28e138c6SAndroid Build Coastguard Worker for ( i=0 ; i<framesize ; ++i )
1001*28e138c6SAndroid Build Coastguard Worker {
1002*28e138c6SAndroid Build Coastguard Worker r = SHL32(Yf[i],3);
1003*28e138c6SAndroid Build Coastguard Worker r = MULT16_32_Q15(leake,r);
1004*28e138c6SAndroid Build Coastguard Worker e = SHL32(Rf[i],3)+1;
1005*28e138c6SAndroid Build Coastguard Worker
1006*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
1007*28e138c6SAndroid Build Coastguard Worker e2 = SHR32(e,1);
1008*28e138c6SAndroid Build Coastguard Worker r = mux( r > e2, e2, r);
1009*28e138c6SAndroid Build Coastguard Worker #else
1010*28e138c6SAndroid Build Coastguard Worker e2 = e * .5;
1011*28e138c6SAndroid Build Coastguard Worker r = fmux( r > e2, e2, r);
1012*28e138c6SAndroid Build Coastguard Worker #endif
1013*28e138c6SAndroid Build Coastguard Worker
1014*28e138c6SAndroid Build Coastguard Worker r = MULT16_32_Q15(QCONST16(.7,15),r) +
1015*28e138c6SAndroid Build Coastguard Worker MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e)));
1016*28e138c6SAndroid Build Coastguard Worker
1017*28e138c6SAndroid Build Coastguard Worker power_1[i] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,power[i]+10)),WEIGHT_SHIFT+16);
1018*28e138c6SAndroid Build Coastguard Worker }
1019*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
1020*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
1021*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
1022*28e138c6SAndroid Build Coastguard Worker #endif
1023*28e138c6SAndroid Build Coastguard Worker
1024*28e138c6SAndroid Build Coastguard Worker r = SHL32(Yf[framesize],3);
1025*28e138c6SAndroid Build Coastguard Worker r = MULT16_32_Q15(leake,r);
1026*28e138c6SAndroid Build Coastguard Worker e = SHL32(Rf[framesize],3)+1;
1027*28e138c6SAndroid Build Coastguard Worker
1028*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
1029*28e138c6SAndroid Build Coastguard Worker e2 = SHR32(e,1);
1030*28e138c6SAndroid Build Coastguard Worker r = mux( r > e2, e2, r);
1031*28e138c6SAndroid Build Coastguard Worker #else
1032*28e138c6SAndroid Build Coastguard Worker e2 = e * .5;
1033*28e138c6SAndroid Build Coastguard Worker r = fmux( r > e2, e2, r);
1034*28e138c6SAndroid Build Coastguard Worker #endif
1035*28e138c6SAndroid Build Coastguard Worker
1036*28e138c6SAndroid Build Coastguard Worker r = MULT16_32_Q15(QCONST16(.7,15),r) +
1037*28e138c6SAndroid Build Coastguard Worker MULT16_32_Q15(QCONST16(.3,15),(spx_word32_t)(MULT16_32_Q15(RER,e)));
1038*28e138c6SAndroid Build Coastguard Worker
1039*28e138c6SAndroid Build Coastguard Worker power_1[framesize] = FLOAT_SHL(FLOAT_DIV32_FLOAT(r,FLOAT_MUL32U(e,power[framesize]+10)),WEIGHT_SHIFT+16);
1040*28e138c6SAndroid Build Coastguard Worker
1041*28e138c6SAndroid Build Coastguard Worker } else
1042*28e138c6SAndroid Build Coastguard Worker {
1043*28e138c6SAndroid Build Coastguard Worker register spx_word16_t adapt_rate=0;
1044*28e138c6SAndroid Build Coastguard Worker register int N = st->window_size;
1045*28e138c6SAndroid Build Coastguard Worker
1046*28e138c6SAndroid Build Coastguard Worker if ( Sxx > SHR32(MULT16_16(N, 1000),6) )
1047*28e138c6SAndroid Build Coastguard Worker { register spx_word32_t tmp32, tmp32q;
1048*28e138c6SAndroid Build Coastguard Worker
1049*28e138c6SAndroid Build Coastguard Worker tmp32 = MULT16_32_Q15(QCONST16(.25f, 15), Sxx);
1050*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
1051*28e138c6SAndroid Build Coastguard Worker tmp32q = SHR32(See,2);
1052*28e138c6SAndroid Build Coastguard Worker tmp32 = mux(tmp32 > tmp32q, tmp32q, tmp32);
1053*28e138c6SAndroid Build Coastguard Worker #else
1054*28e138c6SAndroid Build Coastguard Worker tmp32q = 0.25 * See;
1055*28e138c6SAndroid Build Coastguard Worker tmp32 = fmux(tmp32 > tmp32q, tmp32q, tmp32);
1056*28e138c6SAndroid Build Coastguard Worker #endif
1057*28e138c6SAndroid Build Coastguard Worker adapt_rate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32, See),15));
1058*28e138c6SAndroid Build Coastguard Worker }
1059*28e138c6SAndroid Build Coastguard Worker
1060*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
1061*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
1062*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
1063*28e138c6SAndroid Build Coastguard Worker #endif
1064*28e138c6SAndroid Build Coastguard Worker for (i=0;i<framesize;i++)
1065*28e138c6SAndroid Build Coastguard Worker power_1[i] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(power[i],10)),WEIGHT_SHIFT+1);
1066*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXECHOCANCELLATION)
1067*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
1068*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
1069*28e138c6SAndroid Build Coastguard Worker #endif
1070*28e138c6SAndroid Build Coastguard Worker power_1[framesize] = FLOAT_SHL(FLOAT_DIV32(EXTEND32(adapt_rate),ADD32(power[framesize],10)),WEIGHT_SHIFT+1);
1071*28e138c6SAndroid Build Coastguard Worker sum_adapt = ADD32(sum_adapt,adapt_rate);
1072*28e138c6SAndroid Build Coastguard Worker }
1073*28e138c6SAndroid Build Coastguard Worker
1074*28e138c6SAndroid Build Coastguard Worker st->sum_adapt = sum_adapt;
1075*28e138c6SAndroid Build Coastguard Worker st->adapted = adapted;
1076*28e138c6SAndroid Build Coastguard Worker }
1077*28e138c6SAndroid Build Coastguard Worker
1078*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_ECHO_CANCELLATION
speex_echo_cancellation(SpeexEchoState * restrict st,const spx_int16_t * restrict in,const spx_int16_t * restrict far_end,spx_int16_t * restrict out)1079*28e138c6SAndroid Build Coastguard Worker void speex_echo_cancellation(
1080*28e138c6SAndroid Build Coastguard Worker SpeexEchoState * restrict st,
1081*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict in,
1082*28e138c6SAndroid Build Coastguard Worker const spx_int16_t * restrict far_end,
1083*28e138c6SAndroid Build Coastguard Worker spx_int16_t * restrict out
1084*28e138c6SAndroid Build Coastguard Worker )
1085*28e138c6SAndroid Build Coastguard Worker {
1086*28e138c6SAndroid Build Coastguard Worker register int framesize = st->frame_size;
1087*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict x = st->x;
1088*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict xx = st->x + framesize;
1089*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict yy = st->y + framesize;
1090*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict ee = st->e + framesize;
1091*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Syy, See, Sxx, Sdd, Sff;
1092*28e138c6SAndroid Build Coastguard Worker register spx_word16_t RER;
1093*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Sey;
1094*28e138c6SAndroid Build Coastguard Worker register int j;
1095*28e138c6SAndroid Build Coastguard Worker register int N,M;
1096*28e138c6SAndroid Build Coastguard Worker #ifdef TWO_PATH
1097*28e138c6SAndroid Build Coastguard Worker register spx_word32_t Dbf;
1098*28e138c6SAndroid Build Coastguard Worker #endif
1099*28e138c6SAndroid Build Coastguard Worker
1100*28e138c6SAndroid Build Coastguard Worker N = st->window_size;
1101*28e138c6SAndroid Build Coastguard Worker M = st->M;
1102*28e138c6SAndroid Build Coastguard Worker st->cancel_count++;
1103*28e138c6SAndroid Build Coastguard Worker
1104*28e138c6SAndroid Build Coastguard Worker filter_dc_notch16(in, st->notch_radius, st->input, framesize, st->notch_mem);
1105*28e138c6SAndroid Build Coastguard Worker mdf_preemph(st, xx, far_end, framesize);
1106*28e138c6SAndroid Build Coastguard Worker
1107*28e138c6SAndroid Build Coastguard Worker {
1108*28e138c6SAndroid Build Coastguard Worker
1109*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict X = st->X;
1110*28e138c6SAndroid Build Coastguard Worker
1111*28e138c6SAndroid Build Coastguard Worker for ( j=M-1 ; j>=0 ; j-- )
1112*28e138c6SAndroid Build Coastguard Worker { register spx_word16_t * restrict Xdes = &(X[(j+1)*N]);
1113*28e138c6SAndroid Build Coastguard Worker register spx_word16_t * restrict Xsrc = &(X[j*N]);
1114*28e138c6SAndroid Build Coastguard Worker
1115*28e138c6SAndroid Build Coastguard Worker memcpy(Xdes, Xsrc, N * sizeof(spx_word16_t));
1116*28e138c6SAndroid Build Coastguard Worker }
1117*28e138c6SAndroid Build Coastguard Worker
1118*28e138c6SAndroid Build Coastguard Worker spx_fft(st->fft_table, x, X);
1119*28e138c6SAndroid Build Coastguard Worker memcpy(st->last_y, st->x, N * sizeof(spx_word16_t));
1120*28e138c6SAndroid Build Coastguard Worker Sxx = mdf_inner_prod(xx, xx, framesize);
1121*28e138c6SAndroid Build Coastguard Worker memcpy(x, xx, framesize * sizeof(spx_word16_t));
1122*28e138c6SAndroid Build Coastguard Worker
1123*28e138c6SAndroid Build Coastguard Worker #ifdef TWO_PATH
1124*28e138c6SAndroid Build Coastguard Worker spectral_mul_accum(st->X, st->foreground, st->Y, N, M);
1125*28e138c6SAndroid Build Coastguard Worker spx_ifft(st->fft_table, st->Y, st->e);
1126*28e138c6SAndroid Build Coastguard Worker mdf_sub(xx, st->input, ee, framesize);
1127*28e138c6SAndroid Build Coastguard Worker Sff = mdf_inner_prod(xx, xx, framesize);
1128*28e138c6SAndroid Build Coastguard Worker #endif
1129*28e138c6SAndroid Build Coastguard Worker
1130*28e138c6SAndroid Build Coastguard Worker mdf_adjust_prop (st->W, N, M, st->prop);
1131*28e138c6SAndroid Build Coastguard Worker
1132*28e138c6SAndroid Build Coastguard Worker if (st->saturated == 0)
1133*28e138c6SAndroid Build Coastguard Worker { mdf_compute_weight_gradient(st, X, N, M);
1134*28e138c6SAndroid Build Coastguard Worker } else
1135*28e138c6SAndroid Build Coastguard Worker { st->saturated--;
1136*28e138c6SAndroid Build Coastguard Worker }
1137*28e138c6SAndroid Build Coastguard Worker }
1138*28e138c6SAndroid Build Coastguard Worker
1139*28e138c6SAndroid Build Coastguard Worker mdf_update_weight(st, N, M, framesize);
1140*28e138c6SAndroid Build Coastguard Worker spectral_mul_accum(st->X, st->W, st->Y, N, M);
1141*28e138c6SAndroid Build Coastguard Worker spx_ifft(st->fft_table, st->Y, st->y);
1142*28e138c6SAndroid Build Coastguard Worker
1143*28e138c6SAndroid Build Coastguard Worker #ifdef TWO_PATH
1144*28e138c6SAndroid Build Coastguard Worker mdf_sub(xx, ee, yy, framesize);
1145*28e138c6SAndroid Build Coastguard Worker Dbf = 10+mdf_inner_prod(xx, xx, framesize);
1146*28e138c6SAndroid Build Coastguard Worker #endif
1147*28e138c6SAndroid Build Coastguard Worker
1148*28e138c6SAndroid Build Coastguard Worker mdf_sub(xx, st->input, yy, framesize);
1149*28e138c6SAndroid Build Coastguard Worker See = mdf_inner_prod(xx, xx, framesize);
1150*28e138c6SAndroid Build Coastguard Worker
1151*28e138c6SAndroid Build Coastguard Worker #ifndef TWO_PATH
1152*28e138c6SAndroid Build Coastguard Worker Sff = See;
1153*28e138c6SAndroid Build Coastguard Worker #else
1154*28e138c6SAndroid Build Coastguard Worker See = mdf_update_foreground(st,Dbf,Sff,See);
1155*28e138c6SAndroid Build Coastguard Worker #endif
1156*28e138c6SAndroid Build Coastguard Worker
1157*28e138c6SAndroid Build Coastguard Worker
1158*28e138c6SAndroid Build Coastguard Worker mdf_compute_error_signal(st, in, out, framesize);
1159*28e138c6SAndroid Build Coastguard Worker Sey = mdf_inner_prod(ee, yy, framesize);
1160*28e138c6SAndroid Build Coastguard Worker Syy = mdf_inner_prod(yy, yy, framesize);
1161*28e138c6SAndroid Build Coastguard Worker Sdd = mdf_inner_prod(st->input, st->input, framesize);
1162*28e138c6SAndroid Build Coastguard Worker
1163*28e138c6SAndroid Build Coastguard Worker if ( mdf_check(st,out,Syy,Sxx,See,Sff,Sdd) >= 50 )
1164*28e138c6SAndroid Build Coastguard Worker { speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now.");
1165*28e138c6SAndroid Build Coastguard Worker speex_echo_state_reset(st);
1166*28e138c6SAndroid Build Coastguard Worker return;
1167*28e138c6SAndroid Build Coastguard Worker }
1168*28e138c6SAndroid Build Coastguard Worker
1169*28e138c6SAndroid Build Coastguard Worker See = MAX32(See, SHR32(MULT16_16(N, 100),6));
1170*28e138c6SAndroid Build Coastguard Worker spx_fft(st->fft_table, st->e, st->E);
1171*28e138c6SAndroid Build Coastguard Worker memset(st->y, 0, framesize * sizeof(spx_word16_t));
1172*28e138c6SAndroid Build Coastguard Worker spx_fft(st->fft_table, st->y, st->Y);
1173*28e138c6SAndroid Build Coastguard Worker power_spectrum(st->E, st->Rf, N);
1174*28e138c6SAndroid Build Coastguard Worker power_spectrum(st->Y, st->Yf, N);
1175*28e138c6SAndroid Build Coastguard Worker power_spectrum(st->X, st->Xf, N);
1176*28e138c6SAndroid Build Coastguard Worker
1177*28e138c6SAndroid Build Coastguard Worker mdf_smooth(st->power,st->Xf,framesize, M);
1178*28e138c6SAndroid Build Coastguard Worker mdf_compute_filtered_spectra_crosscorrelations(st,Syy,See,framesize);
1179*28e138c6SAndroid Build Coastguard Worker RER = mdf_compute_RER(See,Syy,Sey,Sxx,st->leak_estimate);
1180*28e138c6SAndroid Build Coastguard Worker mdf_adapt(st, RER, Syy, See, Sxx);
1181*28e138c6SAndroid Build Coastguard Worker
1182*28e138c6SAndroid Build Coastguard Worker if ( st->adapted )
1183*28e138c6SAndroid Build Coastguard Worker { register spx_word16_t * restrict last_yy = st->last_y + framesize;
1184*28e138c6SAndroid Build Coastguard Worker
1185*28e138c6SAndroid Build Coastguard Worker memcpy(st->last_y, last_yy, framesize * sizeof(spx_word16_t));
1186*28e138c6SAndroid Build Coastguard Worker mdf_sub_int(last_yy, in, out, framesize);
1187*28e138c6SAndroid Build Coastguard Worker
1188*28e138c6SAndroid Build Coastguard Worker }
1189*28e138c6SAndroid Build Coastguard Worker }
1190*28e138c6SAndroid Build Coastguard Worker
1191*28e138c6SAndroid Build Coastguard Worker
1192*28e138c6SAndroid Build Coastguard Worker
1193