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