xref: /aosp_15_r20/external/speex/tmv/preprocess_tm.h (revision 28e138c64d234588b5cd2a8a403b584bd3036e4e)
1*28e138c6SAndroid Build Coastguard Worker /* Copyright (C) 2007 Hong Zhiqian */
2*28e138c6SAndroid Build Coastguard Worker /**
3*28e138c6SAndroid Build Coastguard Worker    @file preprocess_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 #ifdef FIXED_POINT
39*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_PREPROCESS_ANALYSIS
preprocess_analysis(SpeexPreprocessState * restrict st,spx_int16_t * restrict x)40*28e138c6SAndroid Build Coastguard Worker static void preprocess_analysis(SpeexPreprocessState * restrict st, spx_int16_t * restrict x)
41*28e138c6SAndroid Build Coastguard Worker {
42*28e138c6SAndroid Build Coastguard Worker 	register int i, j, framesize = st->frame_size;
43*28e138c6SAndroid Build Coastguard Worker 	register int N = st->ps_size;
44*28e138c6SAndroid Build Coastguard Worker 	register int N3 = 2*N - framesize;
45*28e138c6SAndroid Build Coastguard Worker 	register int N4 = framesize - N3;
46*28e138c6SAndroid Build Coastguard Worker 	register int * restrict ps = st->ps;
47*28e138c6SAndroid Build Coastguard Worker 	register int * restrict frame;
48*28e138c6SAndroid Build Coastguard Worker 	register int * restrict inbuf;
49*28e138c6SAndroid Build Coastguard Worker 	register int * restrict ptr;
50*28e138c6SAndroid Build Coastguard Worker 	register int max_val;
51*28e138c6SAndroid Build Coastguard Worker 
52*28e138c6SAndroid Build Coastguard Worker 	frame = (int*)(st->frame);
53*28e138c6SAndroid Build Coastguard Worker 	inbuf = (int*)(st->inbuf);
54*28e138c6SAndroid Build Coastguard Worker 	ptr = (int*)(st->frame+N3);
55*28e138c6SAndroid Build Coastguard Worker 
56*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(x);
57*28e138c6SAndroid Build Coastguard Worker    	TMDEBUG_ALIGNMEM(frame);
58*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(inbuf);
59*28e138c6SAndroid Build Coastguard Worker 
60*28e138c6SAndroid Build Coastguard Worker 	PREPROCESSANAYLSIS_START();
61*28e138c6SAndroid Build Coastguard Worker 
62*28e138c6SAndroid Build Coastguard Worker 	N3 >>= 1;
63*28e138c6SAndroid Build Coastguard Worker 	framesize >>= 1;
64*28e138c6SAndroid Build Coastguard Worker 	max_val = 0;
65*28e138c6SAndroid Build Coastguard Worker 
66*28e138c6SAndroid Build Coastguard Worker 	for ( i=0,j=0 ; i<N3 ; i+=2,j+=8 )
67*28e138c6SAndroid Build Coastguard Worker 	{	register int r1, r2;
68*28e138c6SAndroid Build Coastguard Worker 
69*28e138c6SAndroid Build Coastguard Worker 		r1 = ld32x(inbuf,i);
70*28e138c6SAndroid Build Coastguard Worker 		r2 = ld32x(inbuf,i+1);
71*28e138c6SAndroid Build Coastguard Worker 
72*28e138c6SAndroid Build Coastguard Worker 		st32d(j,   frame, r1);
73*28e138c6SAndroid Build Coastguard Worker 		st32d(j+4, frame, r2);
74*28e138c6SAndroid Build Coastguard Worker 	}
75*28e138c6SAndroid Build Coastguard Worker 
76*28e138c6SAndroid Build Coastguard Worker 	for ( i=0,j=0 ; i<framesize ; i+=2,j+=8 )
77*28e138c6SAndroid Build Coastguard Worker 	{	register int r1, r2;
78*28e138c6SAndroid Build Coastguard Worker 
79*28e138c6SAndroid Build Coastguard Worker 		r1 = ld32x(x, i);
80*28e138c6SAndroid Build Coastguard Worker 		r2 = ld32x(x, i+1);
81*28e138c6SAndroid Build Coastguard Worker 
82*28e138c6SAndroid Build Coastguard Worker 		st32d(j,  ptr, r1);
83*28e138c6SAndroid Build Coastguard Worker 		st32d(j+4,ptr, r2);
84*28e138c6SAndroid Build Coastguard Worker 	}
85*28e138c6SAndroid Build Coastguard Worker 
86*28e138c6SAndroid Build Coastguard Worker 	for ( i=0,j=0,ptr=(int*)(x+N4) ; i<N3 ; i+=2,j+=8 )
87*28e138c6SAndroid Build Coastguard Worker 	{	register int r1, r2;
88*28e138c6SAndroid Build Coastguard Worker 
89*28e138c6SAndroid Build Coastguard Worker 		r1 = ld32x(ptr, i);
90*28e138c6SAndroid Build Coastguard Worker 		r2 = ld32x(ptr, i+1);
91*28e138c6SAndroid Build Coastguard Worker 
92*28e138c6SAndroid Build Coastguard Worker 		st32d(j,  inbuf, r1);
93*28e138c6SAndroid Build Coastguard Worker 		st32d(j+4,inbuf, r2);
94*28e138c6SAndroid Build Coastguard Worker 	}
95*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
96*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=2
97*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
98*28e138c6SAndroid Build Coastguard Worker #endif
99*28e138c6SAndroid Build Coastguard Worker    for ( i=0,j=0,ptr=(int*)st->window ; i<N ; ++i,j+=4 )
100*28e138c6SAndroid Build Coastguard Worker    {	register int f10, w10, r0, r1;
101*28e138c6SAndroid Build Coastguard Worker 
102*28e138c6SAndroid Build Coastguard Worker 		f10 = ld32x(frame, i);
103*28e138c6SAndroid Build Coastguard Worker 		w10 = ld32x(ptr,   i);
104*28e138c6SAndroid Build Coastguard Worker 
105*28e138c6SAndroid Build Coastguard Worker 		r0  = (sex16(f10) * sex16(w10)) >> 15;
106*28e138c6SAndroid Build Coastguard Worker 		r1	= (asri(16,f10) * asri(16,w10)) >> 15;
107*28e138c6SAndroid Build Coastguard Worker 
108*28e138c6SAndroid Build Coastguard Worker 		max_val = imax(iabs(sex16(r0)), max_val);
109*28e138c6SAndroid Build Coastguard Worker 		max_val = imax(iabs(sex16(r1)), max_val);
110*28e138c6SAndroid Build Coastguard Worker 
111*28e138c6SAndroid Build Coastguard Worker 		r0	= pack16lsb(r1, r0);
112*28e138c6SAndroid Build Coastguard Worker 		st32d(j, frame, r0);
113*28e138c6SAndroid Build Coastguard Worker 	}
114*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
115*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
116*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
117*28e138c6SAndroid Build Coastguard Worker #endif
118*28e138c6SAndroid Build Coastguard Worker 
119*28e138c6SAndroid Build Coastguard Worker 	max_val = 14 - spx_ilog2(max_val);
120*28e138c6SAndroid Build Coastguard Worker 	st->frame_shift = max_val;
121*28e138c6SAndroid Build Coastguard Worker 
122*28e138c6SAndroid Build Coastguard Worker 	if ( max_val != 0 )
123*28e138c6SAndroid Build Coastguard Worker 	{
124*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
125*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
126*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
127*28e138c6SAndroid Build Coastguard Worker #endif
128*28e138c6SAndroid Build Coastguard Worker 		for ( i=0,j=0 ; i<N ; ++i,j+=4 )
129*28e138c6SAndroid Build Coastguard Worker 		{	register int f10;
130*28e138c6SAndroid Build Coastguard Worker 
131*28e138c6SAndroid Build Coastguard Worker 			f10 = ld32x(frame, i);
132*28e138c6SAndroid Build Coastguard Worker 			f10 = dualasl(f10, max_val);
133*28e138c6SAndroid Build Coastguard Worker 			st32d(j, frame, f10);
134*28e138c6SAndroid Build Coastguard Worker 
135*28e138c6SAndroid Build Coastguard Worker 		}
136*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
137*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
138*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
139*28e138c6SAndroid Build Coastguard Worker #endif
140*28e138c6SAndroid Build Coastguard Worker 	}
141*28e138c6SAndroid Build Coastguard Worker 
142*28e138c6SAndroid Build Coastguard Worker 	spx_fft(st->fft_lookup, st->frame, st->ft);
143*28e138c6SAndroid Build Coastguard Worker 	power_spectrum(st->ft, ps, N << 1);
144*28e138c6SAndroid Build Coastguard Worker 
145*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
146*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
147*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
148*28e138c6SAndroid Build Coastguard Worker #endif
149*28e138c6SAndroid Build Coastguard Worker 	for ( i=0,ptr=(int*)st->ps,max_val<<=1,j=((1<<((max_val))>>1)) ;i<N ; ++i )
150*28e138c6SAndroid Build Coastguard Worker 	{
151*28e138c6SAndroid Build Coastguard Worker 		ps[i] = (ps[i] + j) >> max_val;
152*28e138c6SAndroid Build Coastguard Worker 	}
153*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
154*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
155*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
156*28e138c6SAndroid Build Coastguard Worker #endif
157*28e138c6SAndroid Build Coastguard Worker 
158*28e138c6SAndroid Build Coastguard Worker 	filterbank_compute_bank32(st->bank, ps, ps+N);
159*28e138c6SAndroid Build Coastguard Worker 
160*28e138c6SAndroid Build Coastguard Worker 	PREPROCESSANAYLSIS_STOP();
161*28e138c6SAndroid Build Coastguard Worker }
162*28e138c6SAndroid Build Coastguard Worker 
163*28e138c6SAndroid Build Coastguard Worker #define _MULT16_32_Q15(a,b,c) ADD32(MULT16_16((a),(b)), SHR(MULT16_16((a),(c)),15))
164*28e138c6SAndroid Build Coastguard Worker 
165*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_UPDATE_NOISE_PROB
update_noise_prob(SpeexPreprocessState * restrict st)166*28e138c6SAndroid Build Coastguard Worker static void update_noise_prob(SpeexPreprocessState * restrict st)
167*28e138c6SAndroid Build Coastguard Worker {
168*28e138c6SAndroid Build Coastguard Worker 	register int i;
169*28e138c6SAndroid Build Coastguard Worker 	register int min_range, nb_adapt;
170*28e138c6SAndroid Build Coastguard Worker 	register int N = st->ps_size;
171*28e138c6SAndroid Build Coastguard Worker 	register int * restrict Smin = (int*)st->Smin;
172*28e138c6SAndroid Build Coastguard Worker 	register int * restrict Stmp = (int*)st->Stmp;
173*28e138c6SAndroid Build Coastguard Worker 	register int * restrict S = (int*)st->S;
174*28e138c6SAndroid Build Coastguard Worker 
175*28e138c6SAndroid Build Coastguard Worker 	UPDATENOISEPROB_START();
176*28e138c6SAndroid Build Coastguard Worker 
177*28e138c6SAndroid Build Coastguard Worker 	{
178*28e138c6SAndroid Build Coastguard Worker 		register int psi_lsb, psi_msb, ips_lsb, ips_msb, psii_lsb, psii_msb;
179*28e138c6SAndroid Build Coastguard Worker 		register int psiii_lsb, psiii_msb;
180*28e138c6SAndroid Build Coastguard Worker 		register int q8, q05, q2, q1;
181*28e138c6SAndroid Build Coastguard Worker 		register int *ps = (int*)st->ps;
182*28e138c6SAndroid Build Coastguard Worker 		register int si_lsb, si_msb, sii_lsb, sii_msb;
183*28e138c6SAndroid Build Coastguard Worker 
184*28e138c6SAndroid Build Coastguard Worker 		q8	= QCONST16(.8f,15);
185*28e138c6SAndroid Build Coastguard Worker 		q05 = QCONST16(.05f,15);
186*28e138c6SAndroid Build Coastguard Worker 		q2	= QCONST16(.2f,15);
187*28e138c6SAndroid Build Coastguard Worker 		q1	= QCONST16(.1f,15);
188*28e138c6SAndroid Build Coastguard Worker 
189*28e138c6SAndroid Build Coastguard Worker 		ips_lsb	 = ps[0];
190*28e138c6SAndroid Build Coastguard Worker 		psi_lsb	 = ps[1];
191*28e138c6SAndroid Build Coastguard Worker 		si_lsb	 = S[0];
192*28e138c6SAndroid Build Coastguard Worker 		ips_msb	 = ips_lsb >> 15;
193*28e138c6SAndroid Build Coastguard Worker 		psi_msb	 = psi_lsb >> 15;
194*28e138c6SAndroid Build Coastguard Worker 		si_msb	 = si_lsb >> 15;
195*28e138c6SAndroid Build Coastguard Worker 
196*28e138c6SAndroid Build Coastguard Worker 		ips_lsb	 &= 0x00007fff;
197*28e138c6SAndroid Build Coastguard Worker 		psi_lsb	 &= 0x00007fff;
198*28e138c6SAndroid Build Coastguard Worker 		si_lsb	 &= 0x00007fff;
199*28e138c6SAndroid Build Coastguard Worker 
200*28e138c6SAndroid Build Coastguard Worker 		S[0] = _MULT16_32_Q15(q8,si_msb,si_lsb) +  _MULT16_32_Q15(q2,ips_msb,ips_lsb);
201*28e138c6SAndroid Build Coastguard Worker 
202*28e138c6SAndroid Build Coastguard Worker 		for ( i=1 ; i<N-1 ; i+=2 )
203*28e138c6SAndroid Build Coastguard Worker 		{
204*28e138c6SAndroid Build Coastguard Worker 			psii_lsb = ps[i+1];
205*28e138c6SAndroid Build Coastguard Worker 			si_lsb	 = S[i];
206*28e138c6SAndroid Build Coastguard Worker 
207*28e138c6SAndroid Build Coastguard Worker 			psii_msb = psii_lsb >> 15;
208*28e138c6SAndroid Build Coastguard Worker 			si_msb	 = si_lsb >> 15;
209*28e138c6SAndroid Build Coastguard Worker 			si_lsb	 &= 0x00007fff;
210*28e138c6SAndroid Build Coastguard Worker 			psii_lsb &= 0x00007fff;
211*28e138c6SAndroid Build Coastguard Worker 
212*28e138c6SAndroid Build Coastguard Worker 			S[i]= _MULT16_32_Q15(q8,si_msb,si_lsb) +
213*28e138c6SAndroid Build Coastguard Worker 				  _MULT16_32_Q15(q05,ips_msb,ips_lsb) +
214*28e138c6SAndroid Build Coastguard Worker 				  _MULT16_32_Q15(q1,psi_msb,psi_lsb) +
215*28e138c6SAndroid Build Coastguard Worker 				  _MULT16_32_Q15(q05,psii_msb,psii_lsb);
216*28e138c6SAndroid Build Coastguard Worker 
217*28e138c6SAndroid Build Coastguard Worker 			psiii_lsb = ps[i+2];
218*28e138c6SAndroid Build Coastguard Worker 			sii_lsb	 = S[i+1];
219*28e138c6SAndroid Build Coastguard Worker 
220*28e138c6SAndroid Build Coastguard Worker 			sii_msb	 =  sii_lsb >> 15;
221*28e138c6SAndroid Build Coastguard Worker 			psiii_msb=  psiii_lsb >> 15;
222*28e138c6SAndroid Build Coastguard Worker 			sii_lsb	 &= 0x00007fff;
223*28e138c6SAndroid Build Coastguard Worker 			psiii_lsb&= 0x00007fff;
224*28e138c6SAndroid Build Coastguard Worker 
225*28e138c6SAndroid Build Coastguard Worker 			S[i+1]= _MULT16_32_Q15(q8,sii_msb,sii_lsb) +
226*28e138c6SAndroid Build Coastguard Worker 					_MULT16_32_Q15(q05,psi_msb,psi_lsb) +
227*28e138c6SAndroid Build Coastguard Worker 					_MULT16_32_Q15(q1,psii_msb,psii_lsb) +
228*28e138c6SAndroid Build Coastguard Worker 					_MULT16_32_Q15(q05,psiii_msb,psiii_lsb);
229*28e138c6SAndroid Build Coastguard Worker 
230*28e138c6SAndroid Build Coastguard Worker 			ips_lsb = psii_lsb;
231*28e138c6SAndroid Build Coastguard Worker 			ips_msb = psii_msb;
232*28e138c6SAndroid Build Coastguard Worker 			psi_lsb = psiii_lsb;
233*28e138c6SAndroid Build Coastguard Worker 			psi_msb = psiii_msb;
234*28e138c6SAndroid Build Coastguard Worker 		}
235*28e138c6SAndroid Build Coastguard Worker 
236*28e138c6SAndroid Build Coastguard Worker 		S[N-1] = MULT16_32_Q15(q8,S[N-1]) + MULT16_32_Q15(q2,ps[N-1]);
237*28e138c6SAndroid Build Coastguard Worker 	}
238*28e138c6SAndroid Build Coastguard Worker 
239*28e138c6SAndroid Build Coastguard Worker 	nb_adapt = st->nb_adapt;
240*28e138c6SAndroid Build Coastguard Worker 
241*28e138c6SAndroid Build Coastguard Worker 	if ( nb_adapt==1 )
242*28e138c6SAndroid Build Coastguard Worker 	{	for ( i=0 ; i<N ; ++i )
243*28e138c6SAndroid Build Coastguard Worker 			Smin[i] = Stmp[i] = 0;
244*28e138c6SAndroid Build Coastguard Worker 
245*28e138c6SAndroid Build Coastguard Worker 	}
246*28e138c6SAndroid Build Coastguard Worker 
247*28e138c6SAndroid Build Coastguard Worker 	min_range = mux(nb_adapt < 100,		15,
248*28e138c6SAndroid Build Coastguard Worker 				mux(nb_adapt < 1000,	50,
249*28e138c6SAndroid Build Coastguard Worker 				mux(nb_adapt < 10000,	150, 300)));
250*28e138c6SAndroid Build Coastguard Worker 
251*28e138c6SAndroid Build Coastguard Worker 	if ( st->min_count > min_range )
252*28e138c6SAndroid Build Coastguard Worker 	{
253*28e138c6SAndroid Build Coastguard Worker 		st->min_count = 0;
254*28e138c6SAndroid Build Coastguard Worker 
255*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
256*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=2
257*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
258*28e138c6SAndroid Build Coastguard Worker #endif
259*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i<N ; ++i )
260*28e138c6SAndroid Build Coastguard Worker 		{	register int si, stmpi;
261*28e138c6SAndroid Build Coastguard Worker 
262*28e138c6SAndroid Build Coastguard Worker 			si		= S[i];
263*28e138c6SAndroid Build Coastguard Worker 			stmpi	= Stmp[i];
264*28e138c6SAndroid Build Coastguard Worker 
265*28e138c6SAndroid Build Coastguard Worker 			Smin[i] = imin(stmpi,si);
266*28e138c6SAndroid Build Coastguard Worker 			Stmp[i] = si;
267*28e138c6SAndroid Build Coastguard Worker 		}
268*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
269*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
270*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
271*28e138c6SAndroid Build Coastguard Worker #endif
272*28e138c6SAndroid Build Coastguard Worker 	} else
273*28e138c6SAndroid Build Coastguard Worker 	{
274*28e138c6SAndroid Build Coastguard Worker 
275*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
276*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=2
277*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
278*28e138c6SAndroid Build Coastguard Worker #endif
279*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i<N ; ++i )
280*28e138c6SAndroid Build Coastguard Worker 		{	register int si, stmpi, smini;
281*28e138c6SAndroid Build Coastguard Worker 
282*28e138c6SAndroid Build Coastguard Worker 			si		= S[i];
283*28e138c6SAndroid Build Coastguard Worker 			stmpi	= Stmp[i];
284*28e138c6SAndroid Build Coastguard Worker 			smini	= Smin[i];
285*28e138c6SAndroid Build Coastguard Worker 
286*28e138c6SAndroid Build Coastguard Worker 			Smin[i] = imin(smini,si);
287*28e138c6SAndroid Build Coastguard Worker 			Stmp[i] = imin(stmpi,si);
288*28e138c6SAndroid Build Coastguard Worker 		}
289*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
290*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
291*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
292*28e138c6SAndroid Build Coastguard Worker #endif
293*28e138c6SAndroid Build Coastguard Worker 	}
294*28e138c6SAndroid Build Coastguard Worker 
295*28e138c6SAndroid Build Coastguard Worker 
296*28e138c6SAndroid Build Coastguard Worker 	{
297*28e138c6SAndroid Build Coastguard Worker 		register int q4;
298*28e138c6SAndroid Build Coastguard Worker 		register int * restrict update_prob = (int*)st->update_prob;
299*28e138c6SAndroid Build Coastguard Worker 
300*28e138c6SAndroid Build Coastguard Worker 		q4 = QCONST16(.4f,15);
301*28e138c6SAndroid Build Coastguard Worker 
302*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
303*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
304*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
305*28e138c6SAndroid Build Coastguard Worker #endif
306*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i<N ; ++i )
307*28e138c6SAndroid Build Coastguard Worker 		{	register int si;
308*28e138c6SAndroid Build Coastguard Worker 			register int smini;
309*28e138c6SAndroid Build Coastguard Worker 
310*28e138c6SAndroid Build Coastguard Worker 			si = S[i];
311*28e138c6SAndroid Build Coastguard Worker 			smini = Smin[i];
312*28e138c6SAndroid Build Coastguard Worker 			update_prob[i] = mux(MULT16_32_Q15(q4,si) > ADD32(smini,20), 1, 0);
313*28e138c6SAndroid Build Coastguard Worker 		}
314*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
315*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
316*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
317*28e138c6SAndroid Build Coastguard Worker #endif
318*28e138c6SAndroid Build Coastguard Worker 	}
319*28e138c6SAndroid Build Coastguard Worker 
320*28e138c6SAndroid Build Coastguard Worker 	UPDATENOISEPROB_STOP();
321*28e138c6SAndroid Build Coastguard Worker }
322*28e138c6SAndroid Build Coastguard Worker 
323*28e138c6SAndroid Build Coastguard Worker #else
324*28e138c6SAndroid Build Coastguard Worker 
325*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_PREPROCESS_ANALYSIS
preprocess_analysis(SpeexPreprocessState * restrict st,spx_int16_t * restrict x)326*28e138c6SAndroid Build Coastguard Worker static void preprocess_analysis(SpeexPreprocessState * restrict st, spx_int16_t * restrict x)
327*28e138c6SAndroid Build Coastguard Worker {
328*28e138c6SAndroid Build Coastguard Worker 	register int i;
329*28e138c6SAndroid Build Coastguard Worker 	register int framesize = st->frame_size;
330*28e138c6SAndroid Build Coastguard Worker 	register int N = st->ps_size;
331*28e138c6SAndroid Build Coastguard Worker 	register int N3 = 2*N - framesize;
332*28e138c6SAndroid Build Coastguard Worker 	register int N4 = framesize - N3;
333*28e138c6SAndroid Build Coastguard Worker 	register float * restrict ps = st->ps;
334*28e138c6SAndroid Build Coastguard Worker 	register float * restrict frame = st->frame;
335*28e138c6SAndroid Build Coastguard Worker 	register float * restrict inbuf = st->inbuf;
336*28e138c6SAndroid Build Coastguard Worker 
337*28e138c6SAndroid Build Coastguard Worker 	PREPROCESSANAYLSIS_START();
338*28e138c6SAndroid Build Coastguard Worker 
339*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
340*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
341*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
342*28e138c6SAndroid Build Coastguard Worker #endif
343*28e138c6SAndroid Build Coastguard Worker 	for ( i=0 ; i<N3 ; ++i )
344*28e138c6SAndroid Build Coastguard Worker 	{
345*28e138c6SAndroid Build Coastguard Worker 		frame[i] = inbuf[i];
346*28e138c6SAndroid Build Coastguard Worker 	}
347*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
348*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
349*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
350*28e138c6SAndroid Build Coastguard Worker #endif
351*28e138c6SAndroid Build Coastguard Worker 
352*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
353*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
354*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
355*28e138c6SAndroid Build Coastguard Worker #endif
356*28e138c6SAndroid Build Coastguard Worker    	for ( i=0 ; i<framesize ; ++i )
357*28e138c6SAndroid Build Coastguard Worker 	{	frame[N3+i] = x[i];
358*28e138c6SAndroid Build Coastguard Worker 	}
359*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
360*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
361*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
362*28e138c6SAndroid Build Coastguard Worker #endif
363*28e138c6SAndroid Build Coastguard Worker 
364*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
365*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
366*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
367*28e138c6SAndroid Build Coastguard Worker #endif
368*28e138c6SAndroid Build Coastguard Worker 	for ( i=0,x+=N4 ; i<N3 ; ++i )
369*28e138c6SAndroid Build Coastguard Worker 	{	inbuf[i]  = x[i];
370*28e138c6SAndroid Build Coastguard Worker 	}
371*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
372*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
373*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
374*28e138c6SAndroid Build Coastguard Worker #endif
375*28e138c6SAndroid Build Coastguard Worker 
376*28e138c6SAndroid Build Coastguard Worker 	inbuf = st->window;
377*28e138c6SAndroid Build Coastguard Worker 
378*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
379*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
380*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
381*28e138c6SAndroid Build Coastguard Worker #endif
382*28e138c6SAndroid Build Coastguard Worker 	for ( i=0 ; i<2*N ; ++i )
383*28e138c6SAndroid Build Coastguard Worker 	{
384*28e138c6SAndroid Build Coastguard Worker 		frame[i] = frame[i] * inbuf[i];
385*28e138c6SAndroid Build Coastguard Worker 	}
386*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_PREPROCESSANALYSIS)
387*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
388*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
389*28e138c6SAndroid Build Coastguard Worker #endif
390*28e138c6SAndroid Build Coastguard Worker 
391*28e138c6SAndroid Build Coastguard Worker 	spx_fft(st->fft_lookup, frame, st->ft);
392*28e138c6SAndroid Build Coastguard Worker 	power_spectrum(st->ft, ps, N << 1);
393*28e138c6SAndroid Build Coastguard Worker 	filterbank_compute_bank32(st->bank, ps, ps+N);
394*28e138c6SAndroid Build Coastguard Worker 
395*28e138c6SAndroid Build Coastguard Worker 	PREPROCESSANAYLSIS_STOP();
396*28e138c6SAndroid Build Coastguard Worker }
397*28e138c6SAndroid Build Coastguard Worker 
398*28e138c6SAndroid Build Coastguard Worker 
399*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_UPDATE_NOISE_PROB
update_noise_prob(SpeexPreprocessState * restrict st)400*28e138c6SAndroid Build Coastguard Worker static void update_noise_prob(SpeexPreprocessState * restrict st)
401*28e138c6SAndroid Build Coastguard Worker {
402*28e138c6SAndroid Build Coastguard Worker 
403*28e138c6SAndroid Build Coastguard Worker 	register float * restrict S = st->S;
404*28e138c6SAndroid Build Coastguard Worker    	register float * restrict ps = st->ps;
405*28e138c6SAndroid Build Coastguard Worker 	register int N = st->ps_size;
406*28e138c6SAndroid Build Coastguard Worker     register int min_range;
407*28e138c6SAndroid Build Coastguard Worker 	register int i;
408*28e138c6SAndroid Build Coastguard Worker 	register int nb_adapt;
409*28e138c6SAndroid Build Coastguard Worker 	register float * restrict Smin = st->Smin;
410*28e138c6SAndroid Build Coastguard Worker 	register float * restrict Stmp = st->Stmp;
411*28e138c6SAndroid Build Coastguard Worker 
412*28e138c6SAndroid Build Coastguard Worker 	UPDATENOISEPROB_START();
413*28e138c6SAndroid Build Coastguard Worker 
414*28e138c6SAndroid Build Coastguard Worker 	{
415*28e138c6SAndroid Build Coastguard Worker 		register float ips, psi;
416*28e138c6SAndroid Build Coastguard Worker 
417*28e138c6SAndroid Build Coastguard Worker 		ips  = ps[0];
418*28e138c6SAndroid Build Coastguard Worker 		psi  = ps[1];
419*28e138c6SAndroid Build Coastguard Worker 
420*28e138c6SAndroid Build Coastguard Worker 		S[0] = .8f * S[0] + .2f * ips;
421*28e138c6SAndroid Build Coastguard Worker 
422*28e138c6SAndroid Build Coastguard Worker 		for ( i=1 ; i<N-1 ; i+=2 )
423*28e138c6SAndroid Build Coastguard Worker 		{
424*28e138c6SAndroid Build Coastguard Worker 			register float psii, psiii;
425*28e138c6SAndroid Build Coastguard Worker 
426*28e138c6SAndroid Build Coastguard Worker 			psii	= ps[i+1];
427*28e138c6SAndroid Build Coastguard Worker 			psiii	= ps[i+2];
428*28e138c6SAndroid Build Coastguard Worker 			S[i]	= .8f * S[i]	+ .05f * ips + .1f * psi  + .05f * psii;
429*28e138c6SAndroid Build Coastguard Worker 			S[i+1]	= .8f * S[i+1]	+ .05f * psi + .1f * psii + .05f * psiii;
430*28e138c6SAndroid Build Coastguard Worker 			ips		= psii;
431*28e138c6SAndroid Build Coastguard Worker 			psi		= psiii;
432*28e138c6SAndroid Build Coastguard Worker 		}
433*28e138c6SAndroid Build Coastguard Worker 
434*28e138c6SAndroid Build Coastguard Worker 		S[N-1] = .8f * S[N-1] + .2f * ps[N-1];
435*28e138c6SAndroid Build Coastguard Worker 	}
436*28e138c6SAndroid Build Coastguard Worker 
437*28e138c6SAndroid Build Coastguard Worker 	nb_adapt = st->nb_adapt;
438*28e138c6SAndroid Build Coastguard Worker 
439*28e138c6SAndroid Build Coastguard Worker    	if ( nb_adapt==1 )
440*28e138c6SAndroid Build Coastguard Worker 	{
441*28e138c6SAndroid Build Coastguard Worker 		for (i=0;i<N;i++)
442*28e138c6SAndroid Build Coastguard Worker 			Smin[i] = st->Stmp[i] = 0;
443*28e138c6SAndroid Build Coastguard Worker 	}
444*28e138c6SAndroid Build Coastguard Worker 
445*28e138c6SAndroid Build Coastguard Worker 	min_range = mux(nb_adapt < 100,		15,
446*28e138c6SAndroid Build Coastguard Worker 				mux(nb_adapt < 1000,	50,
447*28e138c6SAndroid Build Coastguard Worker 				mux(nb_adapt < 10000,	150, 300)));
448*28e138c6SAndroid Build Coastguard Worker 
449*28e138c6SAndroid Build Coastguard Worker 
450*28e138c6SAndroid Build Coastguard Worker 	if ( st->min_count > min_range )
451*28e138c6SAndroid Build Coastguard Worker 	{
452*28e138c6SAndroid Build Coastguard Worker 		st->min_count = 0;
453*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
454*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
455*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
456*28e138c6SAndroid Build Coastguard Worker #endif
457*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i<N ; ++i )
458*28e138c6SAndroid Build Coastguard Worker 		{
459*28e138c6SAndroid Build Coastguard Worker 			register float stmpi, si;
460*28e138c6SAndroid Build Coastguard Worker 
461*28e138c6SAndroid Build Coastguard Worker 			stmpi	= Stmp[i];
462*28e138c6SAndroid Build Coastguard Worker 			si		= S[i];
463*28e138c6SAndroid Build Coastguard Worker 
464*28e138c6SAndroid Build Coastguard Worker 			Smin[i] = fmin(stmpi,si);
465*28e138c6SAndroid Build Coastguard Worker 			Stmp[i] = si;
466*28e138c6SAndroid Build Coastguard Worker 		}
467*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
468*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
469*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
470*28e138c6SAndroid Build Coastguard Worker #endif
471*28e138c6SAndroid Build Coastguard Worker 
472*28e138c6SAndroid Build Coastguard Worker 	} else
473*28e138c6SAndroid Build Coastguard Worker 	{
474*28e138c6SAndroid Build Coastguard Worker 		register float * restrict Smin = st->Smin;
475*28e138c6SAndroid Build Coastguard Worker 
476*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
477*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
478*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
479*28e138c6SAndroid Build Coastguard Worker #endif
480*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i<N ; ++i )
481*28e138c6SAndroid Build Coastguard Worker 		{
482*28e138c6SAndroid Build Coastguard Worker 			register float stmpi, si, smini;
483*28e138c6SAndroid Build Coastguard Worker 
484*28e138c6SAndroid Build Coastguard Worker 			stmpi	= Stmp[i];
485*28e138c6SAndroid Build Coastguard Worker 			si		= S[i];
486*28e138c6SAndroid Build Coastguard Worker 			smini	= Smin[i];
487*28e138c6SAndroid Build Coastguard Worker 
488*28e138c6SAndroid Build Coastguard Worker 			Smin[i] = fmin(smini,si);
489*28e138c6SAndroid Build Coastguard Worker 			Stmp[i] = fmin(stmpi,si);
490*28e138c6SAndroid Build Coastguard Worker 		}
491*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
492*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
493*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
494*28e138c6SAndroid Build Coastguard Worker #endif
495*28e138c6SAndroid Build Coastguard Worker 	}
496*28e138c6SAndroid Build Coastguard Worker 
497*28e138c6SAndroid Build Coastguard Worker 	{
498*28e138c6SAndroid Build Coastguard Worker 		register int * restrict update_prob = (int*)st->update_prob;
499*28e138c6SAndroid Build Coastguard Worker 
500*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
501*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
502*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
503*28e138c6SAndroid Build Coastguard Worker #endif
504*28e138c6SAndroid Build Coastguard Worker 		for (i=0;i<N;i++)
505*28e138c6SAndroid Build Coastguard Worker 		{	register float si;
506*28e138c6SAndroid Build Coastguard Worker 			register float smini;
507*28e138c6SAndroid Build Coastguard Worker 
508*28e138c6SAndroid Build Coastguard Worker 			si		= S[i];
509*28e138c6SAndroid Build Coastguard Worker 			smini	= Smin[i];
510*28e138c6SAndroid Build Coastguard Worker 			update_prob[i] = mux( (.4 * si) > (smini + 20.f), 1, 0);
511*28e138c6SAndroid Build Coastguard Worker 
512*28e138c6SAndroid Build Coastguard Worker 		}
513*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_UPDATENOISEPROB)
514*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
515*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
516*28e138c6SAndroid Build Coastguard Worker #endif
517*28e138c6SAndroid Build Coastguard Worker 	}
518*28e138c6SAndroid Build Coastguard Worker 
519*28e138c6SAndroid Build Coastguard Worker 	UPDATENOISEPROB_STOP();
520*28e138c6SAndroid Build Coastguard Worker }
521*28e138c6SAndroid Build Coastguard Worker 
522*28e138c6SAndroid Build Coastguard Worker 
523*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_COMPUTE_GAIN_FLOOR
compute_gain_floor(int noise_suppress,int effective_echo_suppress,float * restrict noise,float * restrict echo,float * gain_floor,int len)524*28e138c6SAndroid Build Coastguard Worker static void compute_gain_floor(
525*28e138c6SAndroid Build Coastguard Worker 	int noise_suppress,
526*28e138c6SAndroid Build Coastguard Worker 	int effective_echo_suppress,
527*28e138c6SAndroid Build Coastguard Worker 	float * restrict noise,
528*28e138c6SAndroid Build Coastguard Worker 	float * restrict echo,
529*28e138c6SAndroid Build Coastguard Worker 	float * gain_floor,
530*28e138c6SAndroid Build Coastguard Worker 	int len
531*28e138c6SAndroid Build Coastguard Worker )
532*28e138c6SAndroid Build Coastguard Worker {
533*28e138c6SAndroid Build Coastguard Worker 	register int i;
534*28e138c6SAndroid Build Coastguard Worker 	register float echo_floor;
535*28e138c6SAndroid Build Coastguard Worker 	register float noise_floor;
536*28e138c6SAndroid Build Coastguard Worker 
537*28e138c6SAndroid Build Coastguard Worker 	COMPUTEGAINFLOOR_START();
538*28e138c6SAndroid Build Coastguard Worker 
539*28e138c6SAndroid Build Coastguard Worker 	noise_floor = exp(.2302585f*noise_suppress);
540*28e138c6SAndroid Build Coastguard Worker 	echo_floor = exp(.2302585f*effective_echo_suppress);
541*28e138c6SAndroid Build Coastguard Worker 
542*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_COMPUTEGAINFLOOR)
543*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
544*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
545*28e138c6SAndroid Build Coastguard Worker #endif
546*28e138c6SAndroid Build Coastguard Worker 	for (i=0;i<len;i++)
547*28e138c6SAndroid Build Coastguard Worker 	{	register float noisei, echoi;
548*28e138c6SAndroid Build Coastguard Worker 
549*28e138c6SAndroid Build Coastguard Worker 		noisei = noise[i];
550*28e138c6SAndroid Build Coastguard Worker 		echoi  = echo[i];
551*28e138c6SAndroid Build Coastguard Worker 
552*28e138c6SAndroid Build Coastguard Worker 		gain_floor[i] = FRAC_SCALING * sqrt(noise_floor * noisei +	echo_floor * echoi) / sqrt(1+noisei+echoi);
553*28e138c6SAndroid Build Coastguard Worker 
554*28e138c6SAndroid Build Coastguard Worker 	}
555*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_COMPUTEGAINFLOOR)
556*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
557*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
558*28e138c6SAndroid Build Coastguard Worker #endif
559*28e138c6SAndroid Build Coastguard Worker 
560*28e138c6SAndroid Build Coastguard Worker 	COMPUTEGAINFLOOR_STOP();
561*28e138c6SAndroid Build Coastguard Worker }
562*28e138c6SAndroid Build Coastguard Worker 
563*28e138c6SAndroid Build Coastguard Worker #endif
564*28e138c6SAndroid Build Coastguard Worker 
565*28e138c6SAndroid Build Coastguard Worker static inline spx_word32_t hypergeom_gain(spx_word32_t xx);
566*28e138c6SAndroid Build Coastguard Worker static inline spx_word16_t qcurve(spx_word16_t x);
567*28e138c6SAndroid Build Coastguard Worker static void compute_gain_floor(int noise_suppress, int effective_echo_suppress, spx_word32_t *noise, spx_word32_t *echo, spx_word16_t *gain_floor, int len);
568*28e138c6SAndroid Build Coastguard Worker void speex_echo_get_residual(SpeexEchoState *st, spx_word32_t *Yout, int len);
569*28e138c6SAndroid Build Coastguard Worker 
570*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
571*28e138c6SAndroid Build Coastguard Worker static void speex_compute_agc(SpeexPreprocessState *st, spx_word16_t Pframe, spx_word16_t *ft);
572*28e138c6SAndroid Build Coastguard Worker #endif
573*28e138c6SAndroid Build Coastguard Worker 
preprocess_residue_echo(SpeexPreprocessState * restrict st,int N,int NM)574*28e138c6SAndroid Build Coastguard Worker void preprocess_residue_echo(
575*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
576*28e138c6SAndroid Build Coastguard Worker 	int N,
577*28e138c6SAndroid Build Coastguard Worker 	int NM
578*28e138c6SAndroid Build Coastguard Worker )
579*28e138c6SAndroid Build Coastguard Worker {
580*28e138c6SAndroid Build Coastguard Worker 	if (st->echo_state)
581*28e138c6SAndroid Build Coastguard Worker 	{
582*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t * restrict r_echo = st->residual_echo;
583*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t * restrict e_noise = st->echo_noise;
584*28e138c6SAndroid Build Coastguard Worker 		register int i;
585*28e138c6SAndroid Build Coastguard Worker 
586*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
587*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t r;
588*28e138c6SAndroid Build Coastguard Worker #endif
589*28e138c6SAndroid Build Coastguard Worker 
590*28e138c6SAndroid Build Coastguard Worker 		speex_echo_get_residual(st->echo_state, r_echo, N);
591*28e138c6SAndroid Build Coastguard Worker 
592*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
593*28e138c6SAndroid Build Coastguard Worker 		r = r_echo[0];
594*28e138c6SAndroid Build Coastguard Worker 		if (!(r >=0 && r < N*1e9f) )
595*28e138c6SAndroid Build Coastguard Worker 		{
596*28e138c6SAndroid Build Coastguard Worker 			memset(r_echo, 0, N * sizeof(spx_word32_t));
597*28e138c6SAndroid Build Coastguard Worker 		}
598*28e138c6SAndroid Build Coastguard Worker #endif
599*28e138c6SAndroid Build Coastguard Worker 
600*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
601*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
602*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
603*28e138c6SAndroid Build Coastguard Worker #endif
604*28e138c6SAndroid Build Coastguard Worker 		for (i=0;i<N;i++)
605*28e138c6SAndroid Build Coastguard Worker 		{	register spx_word32_t eni = e_noise[i];
606*28e138c6SAndroid Build Coastguard Worker 			e_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),eni), r_echo[i]);
607*28e138c6SAndroid Build Coastguard Worker 		}
608*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
609*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
610*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
611*28e138c6SAndroid Build Coastguard Worker #endif
612*28e138c6SAndroid Build Coastguard Worker 		filterbank_compute_bank32(st->bank, e_noise, e_noise+N);
613*28e138c6SAndroid Build Coastguard Worker 
614*28e138c6SAndroid Build Coastguard Worker 	} else
615*28e138c6SAndroid Build Coastguard Worker 	{	memset(st->echo_noise, 0, (NM) * sizeof(spx_word32_t));
616*28e138c6SAndroid Build Coastguard Worker 	}
617*28e138c6SAndroid Build Coastguard Worker }
618*28e138c6SAndroid Build Coastguard Worker 
preprocess_update_noise(SpeexPreprocessState * restrict st,spx_word32_t * restrict ps,int N)619*28e138c6SAndroid Build Coastguard Worker void preprocess_update_noise(
620*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
621*28e138c6SAndroid Build Coastguard Worker 	spx_word32_t * restrict ps,
622*28e138c6SAndroid Build Coastguard Worker 	int N
623*28e138c6SAndroid Build Coastguard Worker )
624*28e138c6SAndroid Build Coastguard Worker {
625*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t beta, beta_1;
626*28e138c6SAndroid Build Coastguard Worker 	register int * restrict up = st->update_prob;
627*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict noise = st->noise;
628*28e138c6SAndroid Build Coastguard Worker 	register int i;
629*28e138c6SAndroid Build Coastguard Worker 
630*28e138c6SAndroid Build Coastguard Worker 	beta = MAX16(QCONST16(.03,15),DIV32_16(Q15_ONE,st->nb_adapt));
631*28e138c6SAndroid Build Coastguard Worker 	beta_1 = Q15_ONE-beta;
632*28e138c6SAndroid Build Coastguard Worker 
633*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
634*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
635*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
636*28e138c6SAndroid Build Coastguard Worker #endif
637*28e138c6SAndroid Build Coastguard Worker 	for (i=0;i<N;i++)
638*28e138c6SAndroid Build Coastguard Worker 	{	register spx_word32_t ni = noise[i];
639*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t psi = ps[i];
640*28e138c6SAndroid Build Coastguard Worker 
641*28e138c6SAndroid Build Coastguard Worker 		if ( !up[i] || psi < PSHR32(ni, NOISE_SHIFT) )
642*28e138c6SAndroid Build Coastguard Worker 		{	noise[i] =	MAX32(EXTEND32(0),MULT16_32_Q15(beta_1,ni) +
643*28e138c6SAndroid Build Coastguard Worker 						MULT16_32_Q15(beta,SHL32(psi,NOISE_SHIFT)));
644*28e138c6SAndroid Build Coastguard Worker 		}
645*28e138c6SAndroid Build Coastguard Worker 	}
646*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
647*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
648*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
649*28e138c6SAndroid Build Coastguard Worker #endif
650*28e138c6SAndroid Build Coastguard Worker 	filterbank_compute_bank32(st->bank, noise, noise+N);
651*28e138c6SAndroid Build Coastguard Worker }
652*28e138c6SAndroid Build Coastguard Worker 
preprocess_compute_SNR(SpeexPreprocessState * restrict st,spx_word32_t * restrict ps,int NM)653*28e138c6SAndroid Build Coastguard Worker void preprocess_compute_SNR(
654*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
655*28e138c6SAndroid Build Coastguard Worker 	spx_word32_t * restrict ps,
656*28e138c6SAndroid Build Coastguard Worker 	int NM
657*28e138c6SAndroid Build Coastguard Worker )
658*28e138c6SAndroid Build Coastguard Worker {
659*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict noise = st->noise;
660*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict echo = st->echo_noise;
661*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict reverb = st->reverb_estimate;
662*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict post = st->post;
663*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict old_ps = st->old_ps;
664*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict prior = st->prior;
665*28e138c6SAndroid Build Coastguard Worker 	register int i;
666*28e138c6SAndroid Build Coastguard Worker 
667*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
668*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
669*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
670*28e138c6SAndroid Build Coastguard Worker #endif
671*28e138c6SAndroid Build Coastguard Worker 	for ( i=0 ; i<NM ; i++)
672*28e138c6SAndroid Build Coastguard Worker 	{
673*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t gamma;
674*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t tot_noise;
675*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t posti;
676*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t opsi;
677*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t priori;
678*28e138c6SAndroid Build Coastguard Worker 
679*28e138c6SAndroid Build Coastguard Worker 		tot_noise = ADD32(ADD32(ADD32(EXTEND32(1), PSHR32(noise[i],NOISE_SHIFT)), echo[i]) , reverb[i]);
680*28e138c6SAndroid Build Coastguard Worker 
681*28e138c6SAndroid Build Coastguard Worker 		posti = SUB16(DIV32_16_Q8(ps[i],tot_noise), QCONST16(1.f,SNR_SHIFT));
682*28e138c6SAndroid Build Coastguard Worker 		posti = MIN16(posti, QCONST16(100.f,SNR_SHIFT));
683*28e138c6SAndroid Build Coastguard Worker 		post[i] = posti;
684*28e138c6SAndroid Build Coastguard Worker 
685*28e138c6SAndroid Build Coastguard Worker 		opsi = old_ps[i];
686*28e138c6SAndroid Build Coastguard Worker 
687*28e138c6SAndroid Build Coastguard Worker 		gamma = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.89f,15),SQR16_Q15(DIV32_16_Q15(opsi,ADD32(opsi,tot_noise))));
688*28e138c6SAndroid Build Coastguard Worker 
689*28e138c6SAndroid Build Coastguard Worker 		priori = EXTRACT16(PSHR32(ADD32(MULT16_16(gamma,MAX16(0,posti)), MULT16_16(Q15_ONE-gamma,DIV32_16_Q8(opsi,tot_noise))), 15));
690*28e138c6SAndroid Build Coastguard Worker 		prior[i]=MIN16(priori, QCONST16(100.f,SNR_SHIFT));
691*28e138c6SAndroid Build Coastguard Worker 	}
692*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
693*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
694*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
695*28e138c6SAndroid Build Coastguard Worker #endif
696*28e138c6SAndroid Build Coastguard Worker }
697*28e138c6SAndroid Build Coastguard Worker 
preprocess_smooth_SNR(SpeexPreprocessState * restrict st,int N,int NM)698*28e138c6SAndroid Build Coastguard Worker spx_word32_t preprocess_smooth_SNR(
699*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
700*28e138c6SAndroid Build Coastguard Worker 	int N,
701*28e138c6SAndroid Build Coastguard Worker 	int NM
702*28e138c6SAndroid Build Coastguard Worker )
703*28e138c6SAndroid Build Coastguard Worker {
704*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict zeta = st->zeta;
705*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict prior = st->prior;
706*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t Zframe;
707*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t iprior, priori;
708*28e138c6SAndroid Build Coastguard Worker 	register int _N = N-1;
709*28e138c6SAndroid Build Coastguard Worker 	register int i;
710*28e138c6SAndroid Build Coastguard Worker 
711*28e138c6SAndroid Build Coastguard Worker 	iprior = prior[0];
712*28e138c6SAndroid Build Coastguard Worker 	priori = prior[1];
713*28e138c6SAndroid Build Coastguard Worker 	zeta[0] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),zeta[0]), MULT16_16(QCONST16(.3f,15),iprior)),15);
714*28e138c6SAndroid Build Coastguard Worker 
715*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
716*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=2
717*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
718*28e138c6SAndroid Build Coastguard Worker #endif
719*28e138c6SAndroid Build Coastguard Worker 	for ( i=1 ; i<_N ; i++)
720*28e138c6SAndroid Build Coastguard Worker 	{	register spx_word16_t zetai = zeta[i];
721*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t priorii = prior[i+1];
722*28e138c6SAndroid Build Coastguard Worker 
723*28e138c6SAndroid Build Coastguard Worker 		zeta[i] = PSHR32(ADD32(ADD32(ADD32(MULT16_16(QCONST16(.7f,15),zetai), MULT16_16(QCONST16(.15f,15),priori)),
724*28e138c6SAndroid Build Coastguard Worker                   MULT16_16(QCONST16(.075f,15),iprior)), MULT16_16(QCONST16(.075f,15),priorii)),15);
725*28e138c6SAndroid Build Coastguard Worker 
726*28e138c6SAndroid Build Coastguard Worker 		iprior = priori;
727*28e138c6SAndroid Build Coastguard Worker 		priori = priorii;
728*28e138c6SAndroid Build Coastguard Worker 	}
729*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
730*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
731*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
732*28e138c6SAndroid Build Coastguard Worker #endif
733*28e138c6SAndroid Build Coastguard Worker 
734*28e138c6SAndroid Build Coastguard Worker 	for (i=_N; i<NM ; i++)
735*28e138c6SAndroid Build Coastguard Worker 	{	register spx_word16_t zetai = zeta[i];
736*28e138c6SAndroid Build Coastguard Worker 
737*28e138c6SAndroid Build Coastguard Worker 		priori = prior[i];
738*28e138c6SAndroid Build Coastguard Worker 		zeta[i] = PSHR32(ADD32(MULT16_16(QCONST16(.7f,15),zetai), MULT16_16(QCONST16(.3f,15),priori)),15);
739*28e138c6SAndroid Build Coastguard Worker 	}
740*28e138c6SAndroid Build Coastguard Worker 
741*28e138c6SAndroid Build Coastguard Worker 	Zframe = 0;
742*28e138c6SAndroid Build Coastguard Worker 
743*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
744*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
745*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
746*28e138c6SAndroid Build Coastguard Worker #endif
747*28e138c6SAndroid Build Coastguard Worker 	for ( i=N ; i<NM ; i++ )
748*28e138c6SAndroid Build Coastguard Worker 	{	Zframe = ADD32(Zframe, EXTEND32(zeta[i]));
749*28e138c6SAndroid Build Coastguard Worker 	}
750*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
751*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
752*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
753*28e138c6SAndroid Build Coastguard Worker #endif
754*28e138c6SAndroid Build Coastguard Worker 
755*28e138c6SAndroid Build Coastguard Worker 	return Zframe;
756*28e138c6SAndroid Build Coastguard Worker }
757*28e138c6SAndroid Build Coastguard Worker 
preprocess_compute_emgain(SpeexPreprocessState * restrict st,spx_word32_t * restrict ps,spx_word16_t Pframe,int NM)758*28e138c6SAndroid Build Coastguard Worker void preprocess_compute_emgain(
759*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
760*28e138c6SAndroid Build Coastguard Worker 	spx_word32_t * restrict ps,
761*28e138c6SAndroid Build Coastguard Worker 	spx_word16_t Pframe,
762*28e138c6SAndroid Build Coastguard Worker 	int NM
763*28e138c6SAndroid Build Coastguard Worker )
764*28e138c6SAndroid Build Coastguard Worker {
765*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict zeta = st->zeta;
766*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict prior = st->prior;
767*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain = st->gain;
768*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict old_ps = st->old_ps;
769*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict post = st->post;
770*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain2 = st->gain2;
771*28e138c6SAndroid Build Coastguard Worker 	register int i;
772*28e138c6SAndroid Build Coastguard Worker 	register int N=st->ps_size;
773*28e138c6SAndroid Build Coastguard Worker 
774*28e138c6SAndroid Build Coastguard Worker 	for ( i=N ; i<NM ; ++i )
775*28e138c6SAndroid Build Coastguard Worker 	{
776*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t theta;
777*28e138c6SAndroid Build Coastguard Worker 		register spx_word32_t MM;
778*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t prior_ratio;
779*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t P1;
780*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t q;
781*28e138c6SAndroid Build Coastguard Worker 
782*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
783*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t tmp;
784*28e138c6SAndroid Build Coastguard Worker #endif
785*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t priori = prior[i];
786*28e138c6SAndroid Build Coastguard Worker 
787*28e138c6SAndroid Build Coastguard Worker 		prior_ratio = PDIV32_16(SHL32(EXTEND32(priori), 15), ADD16(priori, SHL32(1,SNR_SHIFT)));
788*28e138c6SAndroid Build Coastguard Worker 		theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(post[i]),EXPIN_SHIFT-SNR_SHIFT));
789*28e138c6SAndroid Build Coastguard Worker 
790*28e138c6SAndroid Build Coastguard Worker 		MM = hypergeom_gain(theta);
791*28e138c6SAndroid Build Coastguard Worker 		gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
792*28e138c6SAndroid Build Coastguard Worker 		old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(gain[i])),ps[i]);
793*28e138c6SAndroid Build Coastguard Worker 
794*28e138c6SAndroid Build Coastguard Worker 		P1 = QCONST16(.199f,15)+MULT16_16_Q15(QCONST16(.8f,15),qcurve (zeta[i]));
795*28e138c6SAndroid Build Coastguard Worker 		q = Q15_ONE-MULT16_16_Q15(Pframe,P1);
796*28e138c6SAndroid Build Coastguard Worker 
797*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
798*28e138c6SAndroid Build Coastguard Worker 		theta = MIN32(theta, EXTEND32(32767));
799*28e138c6SAndroid Build Coastguard Worker 		tmp = MULT16_16_Q15((SHL32(1,SNR_SHIFT)+priori),EXTRACT16(MIN32(Q15ONE,SHR32(spx_exp(-EXTRACT16(theta)),1))));
800*28e138c6SAndroid Build Coastguard Worker 		tmp = MIN16(QCONST16(3.,SNR_SHIFT), tmp);
801*28e138c6SAndroid Build Coastguard Worker 		tmp = EXTRACT16(PSHR32(MULT16_16(PDIV32_16(SHL32(EXTEND32(q),8),(Q15_ONE-q)),tmp),8));
802*28e138c6SAndroid Build Coastguard Worker 		gain2[i]=DIV32_16(SHL32(EXTEND32(32767),SNR_SHIFT), ADD16(256,tmp));
803*28e138c6SAndroid Build Coastguard Worker #else
804*28e138c6SAndroid Build Coastguard Worker 		gain2[i]=1/(1.f + (q/(1.f-q))*(1+priori)*exp(-theta));
805*28e138c6SAndroid Build Coastguard Worker #endif
806*28e138c6SAndroid Build Coastguard Worker 	}
807*28e138c6SAndroid Build Coastguard Worker 
808*28e138c6SAndroid Build Coastguard Worker 	filterbank_compute_psd16(st->bank,gain2+N, gain2);
809*28e138c6SAndroid Build Coastguard Worker 	filterbank_compute_psd16(st->bank,gain+N, gain);
810*28e138c6SAndroid Build Coastguard Worker }
811*28e138c6SAndroid Build Coastguard Worker 
preprocess_compute_linear_gain(SpeexPreprocessState * restrict st,spx_word32_t * restrict ps,int N)812*28e138c6SAndroid Build Coastguard Worker void preprocess_compute_linear_gain(
813*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
814*28e138c6SAndroid Build Coastguard Worker 	spx_word32_t * restrict ps,
815*28e138c6SAndroid Build Coastguard Worker 	int N
816*28e138c6SAndroid Build Coastguard Worker )
817*28e138c6SAndroid Build Coastguard Worker {
818*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain_floor = st->gain_floor;
819*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict prior = st->prior;
820*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain = st->gain;
821*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict old_ps = st->old_ps;
822*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict post = st->post;
823*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain2 = st->gain2;
824*28e138c6SAndroid Build Coastguard Worker 	register int i;
825*28e138c6SAndroid Build Coastguard Worker 
826*28e138c6SAndroid Build Coastguard Worker 	filterbank_compute_psd16(st->bank,gain_floor+N,gain_floor);
827*28e138c6SAndroid Build Coastguard Worker 
828*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
829*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
830*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
831*28e138c6SAndroid Build Coastguard Worker #endif
832*28e138c6SAndroid Build Coastguard Worker 	for (i=0;i<N;i++)
833*28e138c6SAndroid Build Coastguard Worker     {
834*28e138c6SAndroid Build Coastguard Worker          register spx_word32_t MM;
835*28e138c6SAndroid Build Coastguard Worker          register spx_word32_t theta;
836*28e138c6SAndroid Build Coastguard Worker          register spx_word16_t prior_ratio;
837*28e138c6SAndroid Build Coastguard Worker          register spx_word16_t tmp;
838*28e138c6SAndroid Build Coastguard Worker          register spx_word16_t p;
839*28e138c6SAndroid Build Coastguard Worker          register spx_word16_t g;
840*28e138c6SAndroid Build Coastguard Worker 		 register spx_word16_t gfi = gain_floor[i];
841*28e138c6SAndroid Build Coastguard Worker 
842*28e138c6SAndroid Build Coastguard Worker 		 prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(prior[i], SHL32(1,SNR_SHIFT)));
843*28e138c6SAndroid Build Coastguard Worker          theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(post[i]),EXPIN_SHIFT-SNR_SHIFT));
844*28e138c6SAndroid Build Coastguard Worker 		 MM = hypergeom_gain(theta);
845*28e138c6SAndroid Build Coastguard Worker 
846*28e138c6SAndroid Build Coastguard Worker 		 g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
847*28e138c6SAndroid Build Coastguard Worker 		 p = gain2[i];
848*28e138c6SAndroid Build Coastguard Worker 
849*28e138c6SAndroid Build Coastguard Worker 		 g = VMUX( MULT16_16_Q15(QCONST16(.333f,15),g) > gain[i], MULT16_16(3,gain[i]), g);
850*28e138c6SAndroid Build Coastguard Worker 
851*28e138c6SAndroid Build Coastguard Worker          old_ps[i]= MULT16_32_P15(QCONST16(.2f,15),old_ps[i]) +
852*28e138c6SAndroid Build Coastguard Worker 					MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(g)),ps[i]);
853*28e138c6SAndroid Build Coastguard Worker 
854*28e138c6SAndroid Build Coastguard Worker 		 g = VMUX( g < gfi, gfi, g );
855*28e138c6SAndroid Build Coastguard Worker          gain[i] = g;
856*28e138c6SAndroid Build Coastguard Worker 
857*28e138c6SAndroid Build Coastguard Worker          tmp =	MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(g),15))) +
858*28e138c6SAndroid Build Coastguard Worker 				MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(gfi),15)));
859*28e138c6SAndroid Build Coastguard Worker 
860*28e138c6SAndroid Build Coastguard Worker          gain2[i]=SQR16_Q15(tmp);
861*28e138c6SAndroid Build Coastguard Worker 
862*28e138c6SAndroid Build Coastguard Worker          /* Use this if you want a log-domain MMSE estimator instead */
863*28e138c6SAndroid Build Coastguard Worker          /* gain2[i] = pow(g, p) * pow(gfi,1.f-p);*/
864*28e138c6SAndroid Build Coastguard Worker     }
865*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
866*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
867*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
868*28e138c6SAndroid Build Coastguard Worker #endif
869*28e138c6SAndroid Build Coastguard Worker }
870*28e138c6SAndroid Build Coastguard Worker 
871*28e138c6SAndroid Build Coastguard Worker 
872*28e138c6SAndroid Build Coastguard Worker #if 0
873*28e138c6SAndroid Build Coastguard Worker void preprocess_compute_bark_gain(
874*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
875*28e138c6SAndroid Build Coastguard Worker 	int N,
876*28e138c6SAndroid Build Coastguard Worker 	int NM
877*28e138c6SAndroid Build Coastguard Worker )
878*28e138c6SAndroid Build Coastguard Worker {
879*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain_floor = st->gain_floor;
880*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain = st->gain;
881*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain2 = st->gain2;
882*28e138c6SAndroid Build Coastguard Worker 	register int i;
883*28e138c6SAndroid Build Coastguard Worker 
884*28e138c6SAndroid Build Coastguard Worker     for (i=N;i<NM;i++)
885*28e138c6SAndroid Build Coastguard Worker     {
886*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t tmp;
887*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t p = gain2[i];
888*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t gaini;
889*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t gfi = gain_floor[i];
890*28e138c6SAndroid Build Coastguard Worker 
891*28e138c6SAndroid Build Coastguard Worker 		gaini = MAX16(gain[i], gfi);
892*28e138c6SAndroid Build Coastguard Worker 
893*28e138c6SAndroid Build Coastguard Worker 		gain[i] = gaini;
894*28e138c6SAndroid Build Coastguard Worker 
895*28e138c6SAndroid Build Coastguard Worker 		tmp =	MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(gaini),15))) +
896*28e138c6SAndroid Build Coastguard Worker 			MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(gfi),15)));
897*28e138c6SAndroid Build Coastguard Worker 
898*28e138c6SAndroid Build Coastguard Worker 		gain2[i]=SQR16_Q15(tmp);
899*28e138c6SAndroid Build Coastguard Worker     }
900*28e138c6SAndroid Build Coastguard Worker 
901*28e138c6SAndroid Build Coastguard Worker     filterbank_compute_psd16(st->bank,gain2+N, gain2);
902*28e138c6SAndroid Build Coastguard Worker }
903*28e138c6SAndroid Build Coastguard Worker #endif
904*28e138c6SAndroid Build Coastguard Worker 
preprocess_apply_gain(SpeexPreprocessState * restrict st,int N)905*28e138c6SAndroid Build Coastguard Worker void preprocess_apply_gain(
906*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
907*28e138c6SAndroid Build Coastguard Worker 	int N
908*28e138c6SAndroid Build Coastguard Worker )
909*28e138c6SAndroid Build Coastguard Worker {
910*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict ft = st->ft;
911*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict gain2 = st->gain2;
912*28e138c6SAndroid Build Coastguard Worker 	register int j, i;
913*28e138c6SAndroid Build Coastguard Worker 
914*28e138c6SAndroid Build Coastguard Worker 	ft[0] = MULT16_16_P15(gain2[0],ft[0]);
915*28e138c6SAndroid Build Coastguard Worker 
916*28e138c6SAndroid Build Coastguard Worker 	for (i=1,j=1; i<N ; i++,j+=2)
917*28e138c6SAndroid Build Coastguard Worker 	{
918*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t gain2i = gain2[i];
919*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t ftj = ft[j];
920*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t ftjj = ft[j+1];
921*28e138c6SAndroid Build Coastguard Worker 
922*28e138c6SAndroid Build Coastguard Worker 		ft[j] = MULT16_16_P15(gain2i,ftj);
923*28e138c6SAndroid Build Coastguard Worker 		ft[j+1] = MULT16_16_P15(gain2i,ftjj);
924*28e138c6SAndroid Build Coastguard Worker 	}
925*28e138c6SAndroid Build Coastguard Worker 
926*28e138c6SAndroid Build Coastguard Worker 	ft[(N<<1)-1] = MULT16_16_P15(gain2[N-1],ft[(N<<1)-1]);
927*28e138c6SAndroid Build Coastguard Worker }
928*28e138c6SAndroid Build Coastguard Worker 
929*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
preprocess_scale(SpeexPreprocessState * restrict st,int N)930*28e138c6SAndroid Build Coastguard Worker void preprocess_scale(
931*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
932*28e138c6SAndroid Build Coastguard Worker 	int N
933*28e138c6SAndroid Build Coastguard Worker )
934*28e138c6SAndroid Build Coastguard Worker {
935*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict frame = st->frame;
936*28e138c6SAndroid Build Coastguard Worker 	register int shift = st->frame_shift;
937*28e138c6SAndroid Build Coastguard Worker 	register int i;
938*28e138c6SAndroid Build Coastguard Worker 	register int N2 = N << 1;
939*28e138c6SAndroid Build Coastguard Worker 
940*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
941*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
942*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
943*28e138c6SAndroid Build Coastguard Worker #endif
944*28e138c6SAndroid Build Coastguard Worker 	for ( i=0 ; i<N2 ;i++)
945*28e138c6SAndroid Build Coastguard Worker 	{	register spx_word16_t framei = frame[i];
946*28e138c6SAndroid Build Coastguard Worker 
947*28e138c6SAndroid Build Coastguard Worker 		frame[i] = PSHR16(framei,shift);
948*28e138c6SAndroid Build Coastguard Worker 	}
949*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
950*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
951*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
952*28e138c6SAndroid Build Coastguard Worker #endif
953*28e138c6SAndroid Build Coastguard Worker }
954*28e138c6SAndroid Build Coastguard Worker 
955*28e138c6SAndroid Build Coastguard Worker #else
956*28e138c6SAndroid Build Coastguard Worker 
preprocess_apply_agc(SpeexPreprocessState * restrict st,int N)957*28e138c6SAndroid Build Coastguard Worker void preprocess_apply_agc(
958*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
959*28e138c6SAndroid Build Coastguard Worker 	int N
960*28e138c6SAndroid Build Coastguard Worker )
961*28e138c6SAndroid Build Coastguard Worker {
962*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t max_sample=0;
963*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict frame = st->frame;
964*28e138c6SAndroid Build Coastguard Worker 	register int i;
965*28e138c6SAndroid Build Coastguard Worker 	register int N2 = N << 1;
966*28e138c6SAndroid Build Coastguard Worker 
967*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
968*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
969*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
970*28e138c6SAndroid Build Coastguard Worker #endif
971*28e138c6SAndroid Build Coastguard Worker 	for (i=0;i<N2;i++)
972*28e138c6SAndroid Build Coastguard Worker 	{	register spx_word16_t framei = VABS(frame[i]);
973*28e138c6SAndroid Build Coastguard Worker 
974*28e138c6SAndroid Build Coastguard Worker 		max_sample = VMUX( framei > max_sample, framei, max_sample);
975*28e138c6SAndroid Build Coastguard Worker 	}
976*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
977*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
978*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
979*28e138c6SAndroid Build Coastguard Worker #endif
980*28e138c6SAndroid Build Coastguard Worker 
981*28e138c6SAndroid Build Coastguard Worker 	if ( max_sample > 28000.f )
982*28e138c6SAndroid Build Coastguard Worker 	{
983*28e138c6SAndroid Build Coastguard Worker 		float damp = 28000.f/max_sample;
984*28e138c6SAndroid Build Coastguard Worker 
985*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
986*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
987*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
988*28e138c6SAndroid Build Coastguard Worker #endif
989*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i< N2 ; i++ )
990*28e138c6SAndroid Build Coastguard Worker 		{	frame[i] *= damp;
991*28e138c6SAndroid Build Coastguard Worker 		}
992*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
993*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
994*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
995*28e138c6SAndroid Build Coastguard Worker #endif
996*28e138c6SAndroid Build Coastguard Worker 	}
997*28e138c6SAndroid Build Coastguard Worker }
998*28e138c6SAndroid Build Coastguard Worker #endif
999*28e138c6SAndroid Build Coastguard Worker 
1000*28e138c6SAndroid Build Coastguard Worker 
preprocess_update(SpeexPreprocessState * restrict st,spx_int16_t * restrict x,int N)1001*28e138c6SAndroid Build Coastguard Worker void preprocess_update(
1002*28e138c6SAndroid Build Coastguard Worker 	SpeexPreprocessState * restrict st,
1003*28e138c6SAndroid Build Coastguard Worker 	spx_int16_t * restrict x,
1004*28e138c6SAndroid Build Coastguard Worker 	int N
1005*28e138c6SAndroid Build Coastguard Worker )
1006*28e138c6SAndroid Build Coastguard Worker {
1007*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict frame = st->frame;
1008*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict window = st->window;
1009*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t * restrict outbuf = st->outbuf;
1010*28e138c6SAndroid Build Coastguard Worker 	register int framesize = st->frame_size;
1011*28e138c6SAndroid Build Coastguard Worker 	register int N2 = N << 1;
1012*28e138c6SAndroid Build Coastguard Worker 	register int N3 = N2 - framesize;
1013*28e138c6SAndroid Build Coastguard Worker 	register int N4 = (framesize) - N3;
1014*28e138c6SAndroid Build Coastguard Worker 	register int i;
1015*28e138c6SAndroid Build Coastguard Worker 
1016*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
1017*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
1018*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
1019*28e138c6SAndroid Build Coastguard Worker #endif
1020*28e138c6SAndroid Build Coastguard Worker 	for ( i=0 ; i<N2 ; i++)
1021*28e138c6SAndroid Build Coastguard Worker 	{	register spx_word16_t fi = frame[i];
1022*28e138c6SAndroid Build Coastguard Worker 		register spx_word16_t wi = window[i];
1023*28e138c6SAndroid Build Coastguard Worker 
1024*28e138c6SAndroid Build Coastguard Worker 		frame[i] = MULT16_16_Q15(fi, wi);
1025*28e138c6SAndroid Build Coastguard Worker 	}
1026*28e138c6SAndroid Build Coastguard Worker 	for (i=0;i<N3;i++)
1027*28e138c6SAndroid Build Coastguard Worker 	{	x[i] = outbuf[i] + frame[i];
1028*28e138c6SAndroid Build Coastguard Worker 	}
1029*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
1030*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
1031*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
1032*28e138c6SAndroid Build Coastguard Worker #endif
1033*28e138c6SAndroid Build Coastguard Worker 
1034*28e138c6SAndroid Build Coastguard Worker 	for ( i=0;i<N4;i++)
1035*28e138c6SAndroid Build Coastguard Worker 	{	x[N3+i] = frame[N3+i];
1036*28e138c6SAndroid Build Coastguard Worker 	}
1037*28e138c6SAndroid Build Coastguard Worker 
1038*28e138c6SAndroid Build Coastguard Worker 	memcpy(outbuf, frame+framesize, (N3) * sizeof(spx_word16_t));
1039*28e138c6SAndroid Build Coastguard Worker }
1040*28e138c6SAndroid Build Coastguard Worker 
1041*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_SPEEX_PREPROCESS_RUN
speex_preprocess_run(SpeexPreprocessState * restrict st,spx_int16_t * restrict x)1042*28e138c6SAndroid Build Coastguard Worker int speex_preprocess_run(SpeexPreprocessState * restrict st, spx_int16_t * restrict x)
1043*28e138c6SAndroid Build Coastguard Worker {
1044*28e138c6SAndroid Build Coastguard Worker 	register int i, N, M, NM;
1045*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t * restrict ps=st->ps;
1046*28e138c6SAndroid Build Coastguard Worker 	register spx_word32_t Zframe;
1047*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t Pframe;
1048*28e138c6SAndroid Build Coastguard Worker 
1049*28e138c6SAndroid Build Coastguard Worker 	st->nb_adapt++;
1050*28e138c6SAndroid Build Coastguard Worker 	st->min_count++;
1051*28e138c6SAndroid Build Coastguard Worker 	N = st->ps_size;
1052*28e138c6SAndroid Build Coastguard Worker 	M = st->nbands;
1053*28e138c6SAndroid Build Coastguard Worker 	NM = N + M;
1054*28e138c6SAndroid Build Coastguard Worker 
1055*28e138c6SAndroid Build Coastguard Worker 	preprocess_residue_echo(st, N, NM);
1056*28e138c6SAndroid Build Coastguard Worker 	preprocess_analysis(st, x);
1057*28e138c6SAndroid Build Coastguard Worker 	update_noise_prob(st);
1058*28e138c6SAndroid Build Coastguard Worker 	preprocess_update_noise(st, ps, N);
1059*28e138c6SAndroid Build Coastguard Worker 
1060*28e138c6SAndroid Build Coastguard Worker 	if ( st->nb_adapt == 1 )
1061*28e138c6SAndroid Build Coastguard Worker 	{	memcpy(st->old_ps, ps, (NM) * sizeof(spx_word32_t));
1062*28e138c6SAndroid Build Coastguard Worker 	}
1063*28e138c6SAndroid Build Coastguard Worker 
1064*28e138c6SAndroid Build Coastguard Worker 	preprocess_compute_SNR(st, ps, NM);
1065*28e138c6SAndroid Build Coastguard Worker 	Zframe = preprocess_smooth_SNR(st, N, NM);
1066*28e138c6SAndroid Build Coastguard Worker 
1067*28e138c6SAndroid Build Coastguard Worker 
1068*28e138c6SAndroid Build Coastguard Worker 	{
1069*28e138c6SAndroid Build Coastguard Worker 	register spx_word16_t effective_echo_suppress;
1070*28e138c6SAndroid Build Coastguard Worker 
1071*28e138c6SAndroid Build Coastguard Worker 	Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,M)));
1072*28e138c6SAndroid Build Coastguard Worker 	effective_echo_suppress =	EXTRACT16(PSHR32(ADD32(MULT16_16(SUB16(Q15_ONE,Pframe), st->echo_suppress),
1073*28e138c6SAndroid Build Coastguard Worker 								MULT16_16(Pframe, st->echo_suppress_active)),15));
1074*28e138c6SAndroid Build Coastguard Worker 	compute_gain_floor(st->noise_suppress, effective_echo_suppress, st->noise+N, st->echo_noise+N, st->gain_floor+N, M);
1075*28e138c6SAndroid Build Coastguard Worker 
1076*28e138c6SAndroid Build Coastguard Worker 	}
1077*28e138c6SAndroid Build Coastguard Worker 
1078*28e138c6SAndroid Build Coastguard Worker 	preprocess_compute_emgain(st, ps, Pframe, NM);
1079*28e138c6SAndroid Build Coastguard Worker 	preprocess_compute_linear_gain(st, ps, N);
1080*28e138c6SAndroid Build Coastguard Worker 
1081*28e138c6SAndroid Build Coastguard Worker 
1082*28e138c6SAndroid Build Coastguard Worker 	if (!st->denoise_enabled)
1083*28e138c6SAndroid Build Coastguard Worker 	{
1084*28e138c6SAndroid Build Coastguard Worker 	   register spx_word16_t * restrict gain2 = st->gain2;
1085*28e138c6SAndroid Build Coastguard Worker 
1086*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
1087*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
1088*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
1089*28e138c6SAndroid Build Coastguard Worker #endif
1090*28e138c6SAndroid Build Coastguard Worker 		for ( i=0 ; i<NM ; i++ )
1091*28e138c6SAndroid Build Coastguard Worker 		{   gain2[i] = Q15_ONE;
1092*28e138c6SAndroid Build Coastguard Worker 		}
1093*28e138c6SAndroid Build Coastguard Worker #if (TM_UNROLL && TM_UNROLL_SPEEXPREPROCESSRUN)
1094*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
1095*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
1096*28e138c6SAndroid Build Coastguard Worker #endif
1097*28e138c6SAndroid Build Coastguard Worker 	}
1098*28e138c6SAndroid Build Coastguard Worker 
1099*28e138c6SAndroid Build Coastguard Worker 	preprocess_apply_gain(st, N);
1100*28e138c6SAndroid Build Coastguard Worker 
1101*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
1102*28e138c6SAndroid Build Coastguard Worker 	if (st->agc_enabled)
1103*28e138c6SAndroid Build Coastguard Worker 	{	speex_compute_agc(st, Pframe, st->ft);
1104*28e138c6SAndroid Build Coastguard Worker 	}
1105*28e138c6SAndroid Build Coastguard Worker #endif
1106*28e138c6SAndroid Build Coastguard Worker 
1107*28e138c6SAndroid Build Coastguard Worker 
1108*28e138c6SAndroid Build Coastguard Worker    spx_ifft(st->fft_lookup, st->ft, st->frame);
1109*28e138c6SAndroid Build Coastguard Worker 
1110*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
1111*28e138c6SAndroid Build Coastguard Worker 	preprocess_scale(st, N);
1112*28e138c6SAndroid Build Coastguard Worker #endif
1113*28e138c6SAndroid Build Coastguard Worker 
1114*28e138c6SAndroid Build Coastguard Worker #ifndef FIXED_POINT
1115*28e138c6SAndroid Build Coastguard Worker 	if ( st->agc_enabled )
1116*28e138c6SAndroid Build Coastguard Worker 	{	preprocess_apply_agc(st, N);
1117*28e138c6SAndroid Build Coastguard Worker 	}
1118*28e138c6SAndroid Build Coastguard Worker #endif
1119*28e138c6SAndroid Build Coastguard Worker 
1120*28e138c6SAndroid Build Coastguard Worker 	preprocess_update(st, x, N);
1121*28e138c6SAndroid Build Coastguard Worker 
1122*28e138c6SAndroid Build Coastguard Worker 	if ( st->vad_enabled )
1123*28e138c6SAndroid Build Coastguard Worker 	{
1124*28e138c6SAndroid Build Coastguard Worker 		if (Pframe > st->speech_prob_start || (st->was_speech && Pframe > st->speech_prob_continue))
1125*28e138c6SAndroid Build Coastguard Worker 		{	st->was_speech=1;
1126*28e138c6SAndroid Build Coastguard Worker 			return 1;
1127*28e138c6SAndroid Build Coastguard Worker 
1128*28e138c6SAndroid Build Coastguard Worker 		} else
1129*28e138c6SAndroid Build Coastguard Worker 		{	st->was_speech=0;
1130*28e138c6SAndroid Build Coastguard Worker 			return 0;
1131*28e138c6SAndroid Build Coastguard Worker 		}
1132*28e138c6SAndroid Build Coastguard Worker 	} else
1133*28e138c6SAndroid Build Coastguard Worker 	{	return 1;
1134*28e138c6SAndroid Build Coastguard Worker 	}
1135*28e138c6SAndroid Build Coastguard Worker }
1136