xref: /aosp_15_r20/external/speex/tmv/fftwrap_tm.h (revision 28e138c64d234588b5cd2a8a403b584bd3036e4e)
1 /* Copyright (C) 2007 Hong Zhiqian */
2 /**
3    @file fftwrap_tm.h
4    @author Hong Zhiqian
5    @brief Various compatibility routines for Speex (TriMedia version)
6 */
7 /*
8    Redistribution and use in source and binary forms, with or without
9    modification, are permitted provided that the following conditions
10    are met:
11 
12    - Redistributions of source code must retain the above copyright
13    notice, this list of conditions and the following disclaimer.
14 
15    - Redistributions in binary form must reproduce the above copyright
16    notice, this list of conditions and the following disclaimer in the
17    documentation and/or other materials provided with the distribution.
18 
19    - Neither the name of the Xiph.org Foundation nor the names of its
20    contributors may be used to endorse or promote products derived from
21    this software without specific prior written permission.
22 
23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 #include <ops/custom_defs.h>
36 #include "profile_tm.h"
37 
38 #ifdef FIXED_POINT
39 
40 #define OVERRIDE_MAXIMIZE_RANGE
maximize_range(Int16 * in,Int16 * out,int bound,int len)41 static int maximize_range(Int16 *in, Int16 *out, int bound, int len)
42 {
43    	register int max_val=0;
44 	register int shift=0;
45 	register int i, j;
46 
47 	TMDEBUG_ALIGNMEM(in);
48 	TMDEBUG_ALIGNMEM(out);
49 
50 	MAXIMIZERANGE_START();
51 
52 	len >>= 1;
53 
54 	for ( i=0 ; i<len ; i+=4 )
55 	{
56 		register int x10, x32, x54, x76;
57 
58 		x10 = ld32x(in,i);
59 		x32 = ld32x(in,i+1);
60 		x54 = ld32x(in,i+2);
61 		x76 = ld32x(in,i+3);
62 
63 		x10 = dspidualabs(x10);
64 		x32 = dspidualabs(x32);
65 		x54 = dspidualabs(x54);
66 		x76 = dspidualabs(x76);
67 
68 		x10 = imax(sex16(x10), asri(16,x10));
69 		x32 = imax(sex16(x32), asri(16,x32));
70 		x54 = imax(sex16(x54), asri(16,x54));
71 		x76 = imax(sex16(x76), asri(16,x76));
72 
73 		max_val = imax(max_val,x10);
74 		max_val = imax(max_val,x32);
75 		max_val = imax(max_val,x54);
76 		max_val = imax(max_val,x76);
77 	}
78 
79 	while ( max_val <= (bound>>1) && max_val != 0 )
80 	{	max_val <<= 1;
81 		shift++;
82 	}
83 
84 	if ( shift != 0 )
85 	{
86 		for ( i=0,j=0 ; i<len ; i+=4,j+=16 )
87 		{
88 			register int x10, x32, x54, x76;
89 
90 			x10 = ld32x(in,i);
91 			x32 = ld32x(in,i+1);
92 			x54 = ld32x(in,i+2);
93 			x76 = ld32x(in,i+3);
94 
95 			x10 = dualasl(x10, shift);
96 			x32 = dualasl(x32, shift);
97 			x54 = dualasl(x54, shift);
98 			x76 = dualasl(x76, shift);
99 
100 			st32d(j,out,x10);
101 			st32d(j+4,out,x32);
102 			st32d(j+8,out,x54);
103 			st32d(j+12,out,x76);
104 		}
105 	}
106 
107 	MAXIMIZERANGE_STOP();
108 
109 	return shift;
110 }
111 
112 #define OVERRIDE_RENORM_RANGE
renorm_range(Int16 * in,Int16 * out,int shift,int len)113 static void renorm_range(Int16 *in, Int16 *out, int shift, int len)
114 {
115 	register int i, j, s, l;
116 
117 	TMDEBUG_ALIGNMEM(in);
118 	TMDEBUG_ALIGNMEM(out);
119 
120 	RENORMRANGE_START();
121 
122 	s = (1<<((shift))>>1);
123 	s = pack16lsb(s,s);
124 
125 	len >>= 1;
126 	l = len & (int)0xFFFFFFFE;
127 
128    	for ( i=0,j=0 ; i<l; i+=2,j+=8 )
129 	{
130 		register int x10, x32;
131 
132 		x10 = ld32x(in,i);
133 		x32 = ld32x(in,i+1);
134 
135 		x10 = dspidualadd(x10, s);
136 		x32 = dspidualadd(x32, s);
137 
138 		x10 = dualasr(x10, shift);
139 		x32 = dualasr(x32, shift);
140 
141 		st32d(j,out,x10);
142 		st32d(j+4,out,x32);
143 	}
144 
145 	if ( len & (int)0x01 )
146 	{
147 		register int x10;
148 
149 		x10 = ld32x(in,i);
150 		x10 = dspidualadd(x10, s);
151 		x10 = dualasr(x10, shift);
152 		st32d(j,out,x10);
153 	}
154 
155 	RENORMRANGE_STOP();
156 }
157 
158 #endif
159 
160 #ifdef USE_COMPACT_KISS_FFT
161 #ifdef FIXED_POINT
162 
163 #define OVERRIDE_POWER_SPECTRUM
power_spectrum(const spx_word16_t * X,spx_word32_t * ps,int N)164 void power_spectrum(const spx_word16_t *X, spx_word32_t *ps, int N)
165 {
166 	register int x10, x32, x54, x76, *x;
167 	register int i;
168 
169 	x = (int*)(X-1);
170 
171 	TMDEBUG_ALIGNMEM(x);
172 
173 	POWERSPECTRUM_START();
174 
175 	x76 = 0;
176 	ps[0] = MULT16_16(X[0],X[0]);
177 	N >>= 1;
178 
179 	for( i=1 ; i<N ; i+=4 )
180 	{
181 		x10 = ld32x(x, i);
182 		x32 = ld32x(x, i+1);
183 		x54 = ld32x(x, i+2);
184 		x76 = ld32x(x, i+3);
185 
186 		ps[i]	= ifir16(x10,x10);
187 		ps[i+1] = ifir16(x32,x32);
188 		ps[i+2] = ifir16(x54,x54);
189 		ps[i+3] = ifir16(x76,x76);
190 	}
191 
192 	x76 = sex16(x76);
193 	ps[N] = x76 * x76;
194 
195 	POWERSPECTRUM_STOP();
196 }
197 
198 #else
199 
200 #define OVERRIDE_POWER_SPECTRUM
power_spectrum(const float * restrict X,float * restrict ps,int N)201 void power_spectrum(const float * restrict X, float * restrict ps, int N)
202 {
203 	register int i, j;
204 	register float xx;
205 
206 	POWERSPECTRUM_START();
207 
208 	xx = X[0];
209 
210 	ps[0]=MULT16_16(xx,xx);
211 
212 #pragma TCS_unroll=4
213 #pragma TCS_unrollexact=1
214    for (i=1,j=1;i<N-1;i+=2,j++)
215    {	register float xi, xii;
216 
217 		xi = X[i];
218 		xii = X[i+1];
219 
220 		ps[j] =  MULT16_16(xi,xi) + MULT16_16(xii,xii);
221    }
222 #pragma TCS_unrollexact=0
223 #pragma TCS_unroll=0
224 
225    xx = X[i];
226    ps[j]=MULT16_16(xx,xx);
227 
228    POWERSPECTRUM_STOP();
229 }
230 
231 #endif
232 #endif
233 
234