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