xref: /aosp_15_r20/external/speex/tmv/fftwrap_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 fftwrap_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 
40*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_MAXIMIZE_RANGE
maximize_range(Int16 * in,Int16 * out,int bound,int len)41*28e138c6SAndroid Build Coastguard Worker static int maximize_range(Int16 *in, Int16 *out, int bound, int len)
42*28e138c6SAndroid Build Coastguard Worker {
43*28e138c6SAndroid Build Coastguard Worker    	register int max_val=0;
44*28e138c6SAndroid Build Coastguard Worker 	register int shift=0;
45*28e138c6SAndroid Build Coastguard Worker 	register int i, j;
46*28e138c6SAndroid Build Coastguard Worker 
47*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(in);
48*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(out);
49*28e138c6SAndroid Build Coastguard Worker 
50*28e138c6SAndroid Build Coastguard Worker 	MAXIMIZERANGE_START();
51*28e138c6SAndroid Build Coastguard Worker 
52*28e138c6SAndroid Build Coastguard Worker 	len >>= 1;
53*28e138c6SAndroid Build Coastguard Worker 
54*28e138c6SAndroid Build Coastguard Worker 	for ( i=0 ; i<len ; i+=4 )
55*28e138c6SAndroid Build Coastguard Worker 	{
56*28e138c6SAndroid Build Coastguard Worker 		register int x10, x32, x54, x76;
57*28e138c6SAndroid Build Coastguard Worker 
58*28e138c6SAndroid Build Coastguard Worker 		x10 = ld32x(in,i);
59*28e138c6SAndroid Build Coastguard Worker 		x32 = ld32x(in,i+1);
60*28e138c6SAndroid Build Coastguard Worker 		x54 = ld32x(in,i+2);
61*28e138c6SAndroid Build Coastguard Worker 		x76 = ld32x(in,i+3);
62*28e138c6SAndroid Build Coastguard Worker 
63*28e138c6SAndroid Build Coastguard Worker 		x10 = dspidualabs(x10);
64*28e138c6SAndroid Build Coastguard Worker 		x32 = dspidualabs(x32);
65*28e138c6SAndroid Build Coastguard Worker 		x54 = dspidualabs(x54);
66*28e138c6SAndroid Build Coastguard Worker 		x76 = dspidualabs(x76);
67*28e138c6SAndroid Build Coastguard Worker 
68*28e138c6SAndroid Build Coastguard Worker 		x10 = imax(sex16(x10), asri(16,x10));
69*28e138c6SAndroid Build Coastguard Worker 		x32 = imax(sex16(x32), asri(16,x32));
70*28e138c6SAndroid Build Coastguard Worker 		x54 = imax(sex16(x54), asri(16,x54));
71*28e138c6SAndroid Build Coastguard Worker 		x76 = imax(sex16(x76), asri(16,x76));
72*28e138c6SAndroid Build Coastguard Worker 
73*28e138c6SAndroid Build Coastguard Worker 		max_val = imax(max_val,x10);
74*28e138c6SAndroid Build Coastguard Worker 		max_val = imax(max_val,x32);
75*28e138c6SAndroid Build Coastguard Worker 		max_val = imax(max_val,x54);
76*28e138c6SAndroid Build Coastguard Worker 		max_val = imax(max_val,x76);
77*28e138c6SAndroid Build Coastguard Worker 	}
78*28e138c6SAndroid Build Coastguard Worker 
79*28e138c6SAndroid Build Coastguard Worker 	while ( max_val <= (bound>>1) && max_val != 0 )
80*28e138c6SAndroid Build Coastguard Worker 	{	max_val <<= 1;
81*28e138c6SAndroid Build Coastguard Worker 		shift++;
82*28e138c6SAndroid Build Coastguard Worker 	}
83*28e138c6SAndroid Build Coastguard Worker 
84*28e138c6SAndroid Build Coastguard Worker 	if ( shift != 0 )
85*28e138c6SAndroid Build Coastguard Worker 	{
86*28e138c6SAndroid Build Coastguard Worker 		for ( i=0,j=0 ; i<len ; i+=4,j+=16 )
87*28e138c6SAndroid Build Coastguard Worker 		{
88*28e138c6SAndroid Build Coastguard Worker 			register int x10, x32, x54, x76;
89*28e138c6SAndroid Build Coastguard Worker 
90*28e138c6SAndroid Build Coastguard Worker 			x10 = ld32x(in,i);
91*28e138c6SAndroid Build Coastguard Worker 			x32 = ld32x(in,i+1);
92*28e138c6SAndroid Build Coastguard Worker 			x54 = ld32x(in,i+2);
93*28e138c6SAndroid Build Coastguard Worker 			x76 = ld32x(in,i+3);
94*28e138c6SAndroid Build Coastguard Worker 
95*28e138c6SAndroid Build Coastguard Worker 			x10 = dualasl(x10, shift);
96*28e138c6SAndroid Build Coastguard Worker 			x32 = dualasl(x32, shift);
97*28e138c6SAndroid Build Coastguard Worker 			x54 = dualasl(x54, shift);
98*28e138c6SAndroid Build Coastguard Worker 			x76 = dualasl(x76, shift);
99*28e138c6SAndroid Build Coastguard Worker 
100*28e138c6SAndroid Build Coastguard Worker 			st32d(j,out,x10);
101*28e138c6SAndroid Build Coastguard Worker 			st32d(j+4,out,x32);
102*28e138c6SAndroid Build Coastguard Worker 			st32d(j+8,out,x54);
103*28e138c6SAndroid Build Coastguard Worker 			st32d(j+12,out,x76);
104*28e138c6SAndroid Build Coastguard Worker 		}
105*28e138c6SAndroid Build Coastguard Worker 	}
106*28e138c6SAndroid Build Coastguard Worker 
107*28e138c6SAndroid Build Coastguard Worker 	MAXIMIZERANGE_STOP();
108*28e138c6SAndroid Build Coastguard Worker 
109*28e138c6SAndroid Build Coastguard Worker 	return shift;
110*28e138c6SAndroid Build Coastguard Worker }
111*28e138c6SAndroid Build Coastguard Worker 
112*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_RENORM_RANGE
renorm_range(Int16 * in,Int16 * out,int shift,int len)113*28e138c6SAndroid Build Coastguard Worker static void renorm_range(Int16 *in, Int16 *out, int shift, int len)
114*28e138c6SAndroid Build Coastguard Worker {
115*28e138c6SAndroid Build Coastguard Worker 	register int i, j, s, l;
116*28e138c6SAndroid Build Coastguard Worker 
117*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(in);
118*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(out);
119*28e138c6SAndroid Build Coastguard Worker 
120*28e138c6SAndroid Build Coastguard Worker 	RENORMRANGE_START();
121*28e138c6SAndroid Build Coastguard Worker 
122*28e138c6SAndroid Build Coastguard Worker 	s = (1<<((shift))>>1);
123*28e138c6SAndroid Build Coastguard Worker 	s = pack16lsb(s,s);
124*28e138c6SAndroid Build Coastguard Worker 
125*28e138c6SAndroid Build Coastguard Worker 	len >>= 1;
126*28e138c6SAndroid Build Coastguard Worker 	l = len & (int)0xFFFFFFFE;
127*28e138c6SAndroid Build Coastguard Worker 
128*28e138c6SAndroid Build Coastguard Worker    	for ( i=0,j=0 ; i<l; i+=2,j+=8 )
129*28e138c6SAndroid Build Coastguard Worker 	{
130*28e138c6SAndroid Build Coastguard Worker 		register int x10, x32;
131*28e138c6SAndroid Build Coastguard Worker 
132*28e138c6SAndroid Build Coastguard Worker 		x10 = ld32x(in,i);
133*28e138c6SAndroid Build Coastguard Worker 		x32 = ld32x(in,i+1);
134*28e138c6SAndroid Build Coastguard Worker 
135*28e138c6SAndroid Build Coastguard Worker 		x10 = dspidualadd(x10, s);
136*28e138c6SAndroid Build Coastguard Worker 		x32 = dspidualadd(x32, s);
137*28e138c6SAndroid Build Coastguard Worker 
138*28e138c6SAndroid Build Coastguard Worker 		x10 = dualasr(x10, shift);
139*28e138c6SAndroid Build Coastguard Worker 		x32 = dualasr(x32, shift);
140*28e138c6SAndroid Build Coastguard Worker 
141*28e138c6SAndroid Build Coastguard Worker 		st32d(j,out,x10);
142*28e138c6SAndroid Build Coastguard Worker 		st32d(j+4,out,x32);
143*28e138c6SAndroid Build Coastguard Worker 	}
144*28e138c6SAndroid Build Coastguard Worker 
145*28e138c6SAndroid Build Coastguard Worker 	if ( len & (int)0x01 )
146*28e138c6SAndroid Build Coastguard Worker 	{
147*28e138c6SAndroid Build Coastguard Worker 		register int x10;
148*28e138c6SAndroid Build Coastguard Worker 
149*28e138c6SAndroid Build Coastguard Worker 		x10 = ld32x(in,i);
150*28e138c6SAndroid Build Coastguard Worker 		x10 = dspidualadd(x10, s);
151*28e138c6SAndroid Build Coastguard Worker 		x10 = dualasr(x10, shift);
152*28e138c6SAndroid Build Coastguard Worker 		st32d(j,out,x10);
153*28e138c6SAndroid Build Coastguard Worker 	}
154*28e138c6SAndroid Build Coastguard Worker 
155*28e138c6SAndroid Build Coastguard Worker 	RENORMRANGE_STOP();
156*28e138c6SAndroid Build Coastguard Worker }
157*28e138c6SAndroid Build Coastguard Worker 
158*28e138c6SAndroid Build Coastguard Worker #endif
159*28e138c6SAndroid Build Coastguard Worker 
160*28e138c6SAndroid Build Coastguard Worker #ifdef USE_COMPACT_KISS_FFT
161*28e138c6SAndroid Build Coastguard Worker #ifdef FIXED_POINT
162*28e138c6SAndroid Build Coastguard Worker 
163*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_POWER_SPECTRUM
power_spectrum(const spx_word16_t * X,spx_word32_t * ps,int N)164*28e138c6SAndroid Build Coastguard Worker void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N)
165*28e138c6SAndroid Build Coastguard Worker {
166*28e138c6SAndroid Build Coastguard Worker 	register int x10, x32, x54, x76, *x;
167*28e138c6SAndroid Build Coastguard Worker 	register int i;
168*28e138c6SAndroid Build Coastguard Worker 
169*28e138c6SAndroid Build Coastguard Worker 	x = (int*)(X-1);
170*28e138c6SAndroid Build Coastguard Worker 
171*28e138c6SAndroid Build Coastguard Worker 	TMDEBUG_ALIGNMEM(x);
172*28e138c6SAndroid Build Coastguard Worker 
173*28e138c6SAndroid Build Coastguard Worker 	POWERSPECTRUM_START();
174*28e138c6SAndroid Build Coastguard Worker 
175*28e138c6SAndroid Build Coastguard Worker 	x76 = 0;
176*28e138c6SAndroid Build Coastguard Worker 	ps[0] = MULT16_16(X[0],X[0]);
177*28e138c6SAndroid Build Coastguard Worker 	N >>= 1;
178*28e138c6SAndroid Build Coastguard Worker 
179*28e138c6SAndroid Build Coastguard Worker 	for( i=1 ; i<N ; i+=4 )
180*28e138c6SAndroid Build Coastguard Worker 	{
181*28e138c6SAndroid Build Coastguard Worker 		x10 = ld32x(x, i);
182*28e138c6SAndroid Build Coastguard Worker 		x32 = ld32x(x, i+1);
183*28e138c6SAndroid Build Coastguard Worker 		x54 = ld32x(x, i+2);
184*28e138c6SAndroid Build Coastguard Worker 		x76 = ld32x(x, i+3);
185*28e138c6SAndroid Build Coastguard Worker 
186*28e138c6SAndroid Build Coastguard Worker 		ps[i]	= ifir16(x10,x10);
187*28e138c6SAndroid Build Coastguard Worker 		ps[i+1] = ifir16(x32,x32);
188*28e138c6SAndroid Build Coastguard Worker 		ps[i+2] = ifir16(x54,x54);
189*28e138c6SAndroid Build Coastguard Worker 		ps[i+3] = ifir16(x76,x76);
190*28e138c6SAndroid Build Coastguard Worker 	}
191*28e138c6SAndroid Build Coastguard Worker 
192*28e138c6SAndroid Build Coastguard Worker 	x76 = sex16(x76);
193*28e138c6SAndroid Build Coastguard Worker 	ps[N] = x76 * x76;
194*28e138c6SAndroid Build Coastguard Worker 
195*28e138c6SAndroid Build Coastguard Worker 	POWERSPECTRUM_STOP();
196*28e138c6SAndroid Build Coastguard Worker }
197*28e138c6SAndroid Build Coastguard Worker 
198*28e138c6SAndroid Build Coastguard Worker #else
199*28e138c6SAndroid Build Coastguard Worker 
200*28e138c6SAndroid Build Coastguard Worker #define OVERRIDE_POWER_SPECTRUM
power_spectrum(const float * restrict X,float * restrict ps,int N)201*28e138c6SAndroid Build Coastguard Worker void power_spectrum(const float * restrict X, float * restrict ps, int N)
202*28e138c6SAndroid Build Coastguard Worker {
203*28e138c6SAndroid Build Coastguard Worker 	register int i, j;
204*28e138c6SAndroid Build Coastguard Worker 	register float xx;
205*28e138c6SAndroid Build Coastguard Worker 
206*28e138c6SAndroid Build Coastguard Worker 	POWERSPECTRUM_START();
207*28e138c6SAndroid Build Coastguard Worker 
208*28e138c6SAndroid Build Coastguard Worker 	xx = X[0];
209*28e138c6SAndroid Build Coastguard Worker 
210*28e138c6SAndroid Build Coastguard Worker 	ps[0]=MULT16_16(xx,xx);
211*28e138c6SAndroid Build Coastguard Worker 
212*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=4
213*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=1
214*28e138c6SAndroid Build Coastguard Worker    for (i=1,j=1;i<N-1;i+=2,j++)
215*28e138c6SAndroid Build Coastguard Worker    {	register float xi, xii;
216*28e138c6SAndroid Build Coastguard Worker 
217*28e138c6SAndroid Build Coastguard Worker 		xi = X[i];
218*28e138c6SAndroid Build Coastguard Worker 		xii = X[i+1];
219*28e138c6SAndroid Build Coastguard Worker 
220*28e138c6SAndroid Build Coastguard Worker 		ps[j] =  MULT16_16(xi,xi) + MULT16_16(xii,xii);
221*28e138c6SAndroid Build Coastguard Worker    }
222*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unrollexact=0
223*28e138c6SAndroid Build Coastguard Worker #pragma TCS_unroll=0
224*28e138c6SAndroid Build Coastguard Worker 
225*28e138c6SAndroid Build Coastguard Worker    xx = X[i];
226*28e138c6SAndroid Build Coastguard Worker    ps[j]=MULT16_16(xx,xx);
227*28e138c6SAndroid Build Coastguard Worker 
228*28e138c6SAndroid Build Coastguard Worker    POWERSPECTRUM_STOP();
229*28e138c6SAndroid Build Coastguard Worker }
230*28e138c6SAndroid Build Coastguard Worker 
231*28e138c6SAndroid Build Coastguard Worker #endif
232*28e138c6SAndroid Build Coastguard Worker #endif
233*28e138c6SAndroid Build Coastguard Worker 
234