10725
|
1 /*
|
|
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
|
|
3 ** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
|
|
4 **
|
|
5 ** This program is free software; you can redistribute it and/or modify
|
|
6 ** it under the terms of the GNU General Public License as published by
|
|
7 ** the Free Software Foundation; either version 2 of the License, or
|
|
8 ** (at your option) any later version.
|
|
9 **
|
|
10 ** This program is distributed in the hope that it will be useful,
|
|
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 ** GNU General Public License for more details.
|
|
14 **
|
|
15 ** You should have received a copy of the GNU General Public License
|
|
16 ** along with this program; if not, write to the Free Software
|
|
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
18 **
|
|
19 ** Any non-GPL usage of this software or parts of this software is strictly
|
|
20 ** forbidden.
|
|
21 **
|
|
22 ** Commercial non-GPL licensing of this software is possible.
|
|
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
|
|
24 **
|
10989
|
25 ** $Id: cfft.c,v 1.1 2003/08/30 22:30:21 arpi Exp $
|
10725
|
26 **/
|
|
27
|
|
28 /*
|
|
29 * Algorithmically based on Fortran-77 FFTPACK
|
|
30 * by Paul N. Swarztrauber(Version 4, 1985).
|
|
31 *
|
|
32 * Does even sized fft only
|
|
33 */
|
|
34
|
|
35 /* isign is +1 for backward and -1 for forward transforms */
|
|
36
|
|
37 #include "common.h"
|
|
38 #include "structs.h"
|
|
39
|
|
40 #include <stdlib.h>
|
|
41 #ifdef _WIN32_WCE
|
|
42 #define assert(x)
|
|
43 #else
|
|
44 #include <assert.h>
|
|
45 #endif
|
|
46
|
|
47 #include "cfft.h"
|
|
48 #include "cfft_tab.h"
|
|
49
|
|
50
|
|
51 /*----------------------------------------------------------------------
|
|
52 passf2, passf3, passf4, passf5. Complex FFT passes fwd and bwd.
|
|
53 ----------------------------------------------------------------------*/
|
|
54
|
|
55 static void passf2(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
56 complex_t *wa, int8_t isign)
|
|
57 {
|
|
58 uint16_t i, k, ah, ac;
|
|
59
|
|
60 if (ido == 1)
|
|
61 {
|
|
62 for (k = 0; k < l1; k++)
|
|
63 {
|
|
64 ah = 2*k;
|
|
65 ac = 4*k;
|
|
66
|
|
67 RE(ch[ah]) = RE(cc[ac]) + RE(cc[ac+1]);
|
|
68 RE(ch[ah+l1]) = RE(cc[ac]) - RE(cc[ac+1]);
|
10989
|
69 IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+1]);
|
10725
|
70 IM(ch[ah+l1]) = IM(cc[ac]) - IM(cc[ac+1]);
|
|
71 }
|
|
72 } else {
|
|
73 for (k = 0; k < l1; k++)
|
|
74 {
|
|
75 ah = k*ido;
|
|
76 ac = 2*k*ido;
|
|
77
|
|
78 for (i = 0; i < ido; i++)
|
|
79 {
|
|
80 complex_t t2;
|
|
81
|
10989
|
82 RE(ch[ah+i]) = RE(cc[ac+i]) + RE(cc[ac+i+ido]);
|
|
83 RE(t2) = RE(cc[ac+i]) - RE(cc[ac+i+ido]);
|
10725
|
84
|
10989
|
85 IM(ch[ah+i]) = IM(cc[ac+i]) + IM(cc[ac+i+ido]);
|
|
86 IM(t2) = IM(cc[ac+i]) - IM(cc[ac+i+ido]);
|
10725
|
87
|
10989
|
88 RE(ch[ah+i+l1*ido]) = MUL_R_C(RE(t2),RE(wa[i])) - MUL_R_C(IM(t2),IM(wa[i]))*isign;
|
|
89 IM(ch[ah+i+l1*ido]) = MUL_R_C(IM(t2),RE(wa[i])) + MUL_R_C(RE(t2),IM(wa[i]))*isign;
|
10725
|
90 }
|
|
91 }
|
|
92 }
|
|
93 }
|
|
94
|
|
95
|
|
96 static void passf3(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
97 complex_t *wa1, complex_t *wa2, int8_t isign)
|
|
98 {
|
|
99 static real_t taur = COEF_CONST(-0.5);
|
|
100 static real_t taui = COEF_CONST(0.866025403784439);
|
|
101 uint16_t i, k, ac, ah;
|
|
102 complex_t c2, c3, d2, d3, t2;
|
|
103
|
|
104 if (ido == 1)
|
|
105 {
|
|
106 for (k = 0; k < l1; k++)
|
|
107 {
|
|
108 ac = 3*k+1;
|
|
109 ah = k;
|
|
110
|
|
111 RE(t2) = RE(cc[ac]) + RE(cc[ac+1]);
|
|
112 IM(t2) = IM(cc[ac]) + IM(cc[ac+1]);
|
|
113 RE(c2) = RE(cc[ac-1]) + MUL_R_C(RE(t2),taur);
|
|
114 IM(c2) = IM(cc[ac-1]) + MUL_R_C(IM(t2),taur);
|
|
115
|
|
116 RE(ch[ah]) = RE(cc[ac-1]) + RE(t2);
|
|
117 IM(ch[ah]) = IM(cc[ac-1]) + IM(t2);
|
|
118
|
|
119 RE(c3) = MUL_R_C((RE(cc[ac]) - RE(cc[ac+1])), taui)*isign;
|
|
120 IM(c3) = MUL_R_C((IM(cc[ac]) - IM(cc[ac+1])), taui)*isign;
|
|
121
|
|
122 RE(ch[ah+l1]) = RE(c2) - IM(c3);
|
|
123 IM(ch[ah+l1]) = IM(c2) + RE(c3);
|
|
124 RE(ch[ah+2*l1]) = RE(c2) + IM(c3);
|
|
125 IM(ch[ah+2*l1]) = IM(c2) - RE(c3);
|
|
126 }
|
|
127 } else {
|
|
128 for (k = 0; k < l1; k++)
|
|
129 {
|
|
130 for (i = 0; i < ido; i++)
|
|
131 {
|
|
132 ac = i + (3*k+1)*ido;
|
|
133 ah = i + k * ido;
|
|
134
|
|
135 RE(t2) = RE(cc[ac]) + RE(cc[ac+ido]);
|
|
136 RE(c2) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),taur);
|
|
137 IM(t2) = IM(cc[ac]) + IM(cc[ac+ido]);
|
|
138 IM(c2) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),taur);
|
|
139
|
|
140 RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2);
|
|
141 IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2);
|
|
142
|
|
143 RE(c3) = MUL_R_C((RE(cc[ac]) - RE(cc[ac+ido])), taui)*isign;
|
|
144 IM(c3) = MUL_R_C((IM(cc[ac]) - IM(cc[ac+ido])), taui)*isign;
|
|
145
|
|
146 RE(d2) = RE(c2) - IM(c3);
|
|
147 IM(d3) = IM(c2) - RE(c3);
|
|
148 RE(d3) = RE(c2) + IM(c3);
|
|
149 IM(d2) = IM(c2) + RE(c3);
|
|
150
|
|
151 RE(ch[ah+l1*ido]) = MUL_R_C(RE(d2),RE(wa1[i])) - MUL_R_C(IM(d2),IM(wa1[i]))*isign;
|
|
152 IM(ch[ah+l1*ido]) = MUL_R_C(IM(d2),RE(wa1[i])) + MUL_R_C(RE(d2),IM(wa1[i]))*isign;
|
|
153 RE(ch[ah+l1*2*ido]) = MUL_R_C(RE(d3),RE(wa2[i])) - MUL_R_C(IM(d3),IM(wa2[i]))*isign;
|
|
154 IM(ch[ah+l1*2*ido]) = MUL_R_C(IM(d3),RE(wa2[i])) + MUL_R_C(RE(d3),IM(wa2[i]))*isign;
|
|
155 }
|
|
156 }
|
|
157 }
|
|
158 }
|
|
159
|
|
160
|
|
161 static void passf4(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
162 complex_t *wa1, complex_t *wa2, complex_t *wa3, int8_t isign)
|
|
163 {
|
|
164 uint16_t i, k, ac, ah;
|
|
165
|
|
166 if (ido == 1)
|
|
167 {
|
|
168 for (k = 0; k < l1; k++)
|
|
169 {
|
10989
|
170 complex_t t1, t2, t3, t4;
|
|
171
|
10725
|
172 ac = 4*k;
|
|
173 ah = k;
|
|
174
|
|
175 RE(t2) = RE(cc[ac]) + RE(cc[ac+2]);
|
10989
|
176 RE(t1) = RE(cc[ac]) - RE(cc[ac+2]);
|
|
177 IM(t2) = IM(cc[ac]) + IM(cc[ac+2]);
|
|
178 IM(t1) = IM(cc[ac]) - IM(cc[ac+2]);
|
10725
|
179 RE(t3) = RE(cc[ac+1]) + RE(cc[ac+3]);
|
10989
|
180 IM(t4) = RE(cc[ac+1]) - RE(cc[ac+3]);
|
|
181 IM(t3) = IM(cc[ac+3]) + IM(cc[ac+1]);
|
10725
|
182 RE(t4) = IM(cc[ac+3]) - IM(cc[ac+1]);
|
|
183
|
|
184 RE(ch[ah]) = RE(t2) + RE(t3);
|
|
185 RE(ch[ah+2*l1]) = RE(t2) - RE(t3);
|
10989
|
186
|
|
187 IM(ch[ah]) = IM(t2) + IM(t3);
|
10725
|
188 IM(ch[ah+2*l1]) = IM(t2) - IM(t3);
|
10989
|
189
|
|
190 RE(ch[ah+l1]) = RE(t1) + RE(t4)*isign;
|
10725
|
191 RE(ch[ah+3*l1]) = RE(t1) - RE(t4)*isign;
|
10989
|
192
|
|
193 IM(ch[ah+l1]) = IM(t1) + IM(t4)*isign;
|
10725
|
194 IM(ch[ah+3*l1]) = IM(t1) - IM(t4)*isign;
|
|
195 }
|
|
196 } else {
|
|
197 for (k = 0; k < l1; k++)
|
|
198 {
|
10989
|
199 ac = 4*k*ido;
|
|
200 ah = k*ido;
|
|
201
|
10725
|
202 for (i = 0; i < ido; i++)
|
|
203 {
|
10989
|
204 complex_t c2, c3, c4, t1, t2, t3, t4;
|
10725
|
205
|
10989
|
206 RE(t2) = RE(cc[ac+i]) + RE(cc[ac+i+2*ido]);
|
|
207 RE(t1) = RE(cc[ac+i]) - RE(cc[ac+i+2*ido]);
|
|
208 IM(t2) = IM(cc[ac+i]) + IM(cc[ac+i+2*ido]);
|
|
209 IM(t1) = IM(cc[ac+i]) - IM(cc[ac+i+2*ido]);
|
|
210 RE(t3) = RE(cc[ac+i+ido]) + RE(cc[ac+i+3*ido]);
|
|
211 IM(t4) = RE(cc[ac+i+ido]) - RE(cc[ac+i+3*ido]);
|
|
212 IM(t3) = IM(cc[ac+i+3*ido]) + IM(cc[ac+i+ido]);
|
|
213 RE(t4) = IM(cc[ac+i+3*ido]) - IM(cc[ac+i+ido]);
|
10725
|
214
|
|
215 RE(c2) = RE(t1) + RE(t4)*isign;
|
10989
|
216 RE(c4) = RE(t1) - RE(t4)*isign;
|
|
217
|
10725
|
218 IM(c2) = IM(t1) + IM(t4)*isign;
|
|
219 IM(c4) = IM(t1) - IM(t4)*isign;
|
|
220
|
10989
|
221 RE(ch[ah+i]) = RE(t2) + RE(t3);
|
|
222 RE(c3) = RE(t2) - RE(t3);
|
|
223
|
|
224 IM(ch[ah+i]) = IM(t2) + IM(t3);
|
|
225 IM(c3) = IM(t2) - IM(t3);
|
|
226
|
|
227 IM(ch[ah+i+l1*ido]) = MUL_R_C(IM(c2),RE(wa1[i])) + MUL_R_C(RE(c2),IM(wa1[i]))*isign;
|
|
228 RE(ch[ah+i+l1*ido]) = MUL_R_C(RE(c2),RE(wa1[i])) - MUL_R_C(IM(c2),IM(wa1[i]))*isign;
|
|
229 IM(ch[ah+i+2*l1*ido]) = MUL_R_C(IM(c3),RE(wa2[i])) + MUL_R_C(RE(c3),IM(wa2[i]))*isign;
|
|
230 RE(ch[ah+i+2*l1*ido]) = MUL_R_C(RE(c3),RE(wa2[i])) - MUL_R_C(IM(c3),IM(wa2[i]))*isign;
|
|
231 IM(ch[ah+i+3*l1*ido]) = MUL_R_C(IM(c4),RE(wa3[i])) + MUL_R_C(RE(c4),IM(wa3[i]))*isign;
|
|
232 RE(ch[ah+i+3*l1*ido]) = MUL_R_C(RE(c4),RE(wa3[i])) - MUL_R_C(IM(c4),IM(wa3[i]))*isign;
|
10725
|
233 }
|
|
234 }
|
|
235 }
|
|
236 }
|
|
237
|
|
238
|
|
239 static void passf5(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
240 complex_t *wa1, complex_t *wa2, complex_t *wa3, complex_t *wa4,
|
|
241 int8_t isign)
|
|
242 {
|
|
243 static real_t tr11 = COEF_CONST(0.309016994374947);
|
|
244 static real_t ti11 = COEF_CONST(0.951056516295154);
|
|
245 static real_t tr12 = COEF_CONST(-0.809016994374947);
|
|
246 static real_t ti12 = COEF_CONST(0.587785252292473);
|
|
247 uint16_t i, k, ac, ah;
|
|
248 complex_t c2, c3, c4, c5, d3, d4, d5, d2, t2, t3, t4, t5;
|
|
249
|
|
250 if (ido == 1)
|
|
251 {
|
|
252 for (k = 0; k < l1; k++)
|
|
253 {
|
|
254 ac = 5*k + 1;
|
|
255 ah = k;
|
|
256
|
|
257 RE(t2) = RE(cc[ac]) + RE(cc[ac+3]);
|
|
258 IM(t2) = IM(cc[ac]) + IM(cc[ac+3]);
|
|
259 RE(t3) = RE(cc[ac+1]) + RE(cc[ac+2]);
|
|
260 IM(t3) = IM(cc[ac+1]) + IM(cc[ac+2]);
|
|
261 RE(t4) = RE(cc[ac+1]) - RE(cc[ac+2]);
|
|
262 IM(t4) = IM(cc[ac+1]) - IM(cc[ac+2]);
|
|
263 RE(t5) = RE(cc[ac]) - RE(cc[ac+3]);
|
|
264 IM(t5) = IM(cc[ac]) - IM(cc[ac+3]);
|
|
265
|
|
266 RE(ch[ah]) = RE(cc[ac-1]) + RE(t2) + RE(t3);
|
|
267 IM(ch[ah]) = IM(cc[ac-1]) + IM(t2) + IM(t3);
|
|
268
|
|
269 RE(c2) = RE(cc[ac-1]) + MUL_R_C(RE(t2),tr11) + MUL_R_C(RE(t3),tr12);
|
|
270 IM(c2) = IM(cc[ac-1]) + MUL_R_C(IM(t2),tr11) + MUL_R_C(IM(t3),tr12);
|
|
271 RE(c3) = RE(cc[ac-1]) + MUL_R_C(RE(t2),tr12) + MUL_R_C(RE(t3),tr11);
|
|
272 IM(c3) = IM(cc[ac-1]) + MUL_R_C(IM(t2),tr12) + MUL_R_C(IM(t3),tr11);
|
|
273 RE(c4) = (MUL_R_C(RE(t5),ti12)*isign - MUL_R_C(RE(t4),ti11));
|
|
274 IM(c4) = (MUL_R_C(IM(t5),ti12)*isign - MUL_R_C(IM(t4),ti11));
|
|
275 RE(c5) = (MUL_R_C(RE(t5),ti11)*isign + MUL_R_C(RE(t4),ti12));
|
|
276 IM(c5) = (MUL_R_C(IM(t5),ti11)*isign + MUL_R_C(IM(t4),ti12));
|
|
277
|
|
278 RE(ch[ah+l1]) = RE(c2) - IM(c5);
|
|
279 IM(ch[ah+l1]) = IM(c2) + RE(c5);
|
|
280 RE(ch[ah+2*l1]) = RE(c3) - IM(c4);
|
|
281 IM(ch[ah+2*l1]) = IM(c3) + RE(c4);
|
|
282 RE(ch[ah+3*l1]) = RE(c3) + IM(c4);
|
|
283 IM(ch[ah+3*l1]) = IM(c3) - RE(c4);
|
|
284 RE(ch[ah+4*l1]) = RE(c2) + IM(c5);
|
|
285 IM(ch[ah+4*l1]) = IM(c2) - RE(c5);
|
|
286 }
|
|
287 } else {
|
|
288 for (k = 0; k < l1; k++)
|
|
289 {
|
|
290 for (i = 0; i < ido; i++)
|
|
291 {
|
|
292 ac = i + (k*5 + 1) * ido;
|
|
293 ah = i + k * ido;
|
|
294
|
|
295 RE(t2) = RE(cc[ac]) + RE(cc[ac+3*ido]);
|
|
296 IM(t2) = IM(cc[ac]) + IM(cc[ac+3*ido]);
|
|
297 RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+2*ido]);
|
|
298 IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+2*ido]);
|
|
299 RE(t4) = RE(cc[ac+ido]) - RE(cc[ac+2*ido]);
|
|
300 IM(t4) = IM(cc[ac+ido]) - IM(cc[ac+2*ido]);
|
|
301 RE(t5) = RE(cc[ac]) - RE(cc[ac+3*ido]);
|
|
302 IM(t5) = IM(cc[ac]) - IM(cc[ac+3*ido]);
|
|
303
|
|
304 RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2) + RE(t3);
|
|
305 IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2) + IM(t3);
|
|
306
|
|
307 RE(c2) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),tr11) + MUL_R_C(RE(t3),tr12);
|
|
308 IM(c2) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),tr11) + MUL_R_C(IM(t3),tr12);
|
|
309 RE(c3) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),tr12) + MUL_R_C(RE(t3),tr11);
|
|
310 IM(c3) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),tr12) + MUL_R_C(IM(t3),tr11);
|
|
311 RE(c4) = (MUL_R_C(RE(t5),ti12)*isign - MUL_R_C(RE(t4),ti11));
|
|
312 IM(c4) = (MUL_R_C(IM(t5),ti12)*isign - MUL_R_C(IM(t4),ti11));
|
|
313 RE(c5) = (MUL_R_C(RE(t5),ti11)*isign + MUL_R_C(RE(t4),ti12));
|
|
314 IM(c5) = (MUL_R_C(IM(t5),ti11)*isign + MUL_R_C(IM(t4),ti12));
|
|
315
|
|
316 IM(d2) = IM(c2) + RE(c5);
|
|
317 IM(d3) = IM(c3) + RE(c4);
|
|
318 RE(d4) = RE(c3) + IM(c4);
|
|
319 RE(d5) = RE(c2) + IM(c5);
|
|
320 RE(d2) = RE(c2) - IM(c5);
|
|
321 IM(d5) = IM(c2) - RE(c5);
|
|
322 RE(d3) = RE(c3) - IM(c4);
|
|
323 IM(d4) = IM(c3) - RE(c4);
|
|
324
|
|
325 RE(ch[ah+l1*ido]) = MUL_R_C(RE(d2),RE(wa1[i])) - MUL_R_C(IM(d2),IM(wa1[i]))*isign;
|
|
326 IM(ch[ah+l1*ido]) = MUL_R_C(IM(d2),RE(wa1[i])) + MUL_R_C(RE(d2),IM(wa1[i]))*isign;
|
|
327 RE(ch[ah+2*l1*ido]) = MUL_R_C(RE(d3),RE(wa2[i])) - MUL_R_C(IM(d3),IM(wa2[i]))*isign;
|
|
328 IM(ch[ah+2*l1*ido]) = MUL_R_C(IM(d3),RE(wa2[i])) + MUL_R_C(RE(d3),IM(wa2[i]))*isign;
|
|
329 RE(ch[ah+3*l1*ido]) = MUL_R_C(RE(d4),RE(wa3[i])) - MUL_R_C(IM(d4),IM(wa3[i]))*isign;
|
|
330 IM(ch[ah+3*l1*ido]) = MUL_R_C(IM(d4),RE(wa3[i])) + MUL_R_C(RE(d4),IM(wa3[i]))*isign;
|
|
331 RE(ch[ah+4*l1*ido]) = MUL_R_C(RE(d5),RE(wa4[i])) - MUL_R_C(IM(d5),IM(wa4[i]))*isign;
|
|
332 IM(ch[ah+4*l1*ido]) = MUL_R_C(IM(d5),RE(wa4[i])) + MUL_R_C(RE(d5),IM(wa4[i]))*isign;
|
|
333 }
|
|
334 }
|
|
335 }
|
|
336 }
|
|
337
|
|
338
|
|
339 /*----------------------------------------------------------------------
|
|
340 cfftf1, cfftf, cfftb, cffti1, cffti. Complex FFTs.
|
|
341 ----------------------------------------------------------------------*/
|
|
342
|
|
343 INLINE void cfftf1(uint16_t n, complex_t *c, complex_t *ch,
|
|
344 uint16_t *ifac, complex_t *wa, int8_t isign)
|
|
345 {
|
|
346 uint16_t i;
|
|
347 uint16_t k1, l1, l2;
|
|
348 uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido, idl1;
|
|
349
|
|
350 nf = ifac[1];
|
|
351 na = 0;
|
|
352 l1 = 1;
|
|
353 iw = 0;
|
|
354
|
|
355 for (k1 = 2; k1 <= nf+1; k1++)
|
|
356 {
|
|
357 ip = ifac[k1];
|
|
358 l2 = ip*l1;
|
|
359 ido = n / l2;
|
|
360 idl1 = ido*l1;
|
|
361
|
|
362 switch (ip)
|
|
363 {
|
10989
|
364 case 4:
|
|
365 ix2 = iw + ido;
|
|
366 ix3 = ix2 + ido;
|
|
367
|
|
368 if (na == 0)
|
|
369 passf4(ido, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], isign);
|
|
370 else
|
|
371 passf4(ido, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], isign);
|
|
372
|
|
373 na = 1 - na;
|
|
374 break;
|
10725
|
375 case 2:
|
|
376 if (na == 0)
|
|
377 passf2(ido, l1, c, ch, &wa[iw], isign);
|
|
378 else
|
|
379 passf2(ido, l1, ch, c, &wa[iw], isign);
|
|
380
|
|
381 na = 1 - na;
|
|
382 break;
|
|
383 case 3:
|
|
384 ix2 = iw + ido;
|
|
385
|
|
386 if (na == 0)
|
|
387 passf3(ido, l1, c, ch, &wa[iw], &wa[ix2], isign);
|
|
388 else
|
|
389 passf3(ido, l1, ch, c, &wa[iw], &wa[ix2], isign);
|
|
390
|
|
391 na = 1 - na;
|
|
392 break;
|
|
393 case 5:
|
|
394 ix2 = iw + ido;
|
|
395 ix3 = ix2 + ido;
|
|
396 ix4 = ix3 + ido;
|
|
397
|
|
398 if (na == 0)
|
|
399 passf5(ido, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign);
|
|
400 else
|
|
401 passf5(ido, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign);
|
|
402
|
|
403 na = 1 - na;
|
|
404 break;
|
|
405 }
|
|
406
|
|
407 l1 = l2;
|
|
408 iw += (ip-1) * ido;
|
|
409 }
|
|
410
|
|
411 if (na == 0)
|
|
412 return;
|
|
413
|
|
414 for (i = 0; i < n; i++)
|
|
415 {
|
|
416 RE(c[i]) = RE(ch[i]);
|
|
417 IM(c[i]) = IM(ch[i]);
|
|
418 }
|
|
419 }
|
|
420
|
|
421 void cfftf(cfft_info *cfft, complex_t *c)
|
|
422 {
|
|
423 cfftf1(cfft->n, c, cfft->work, cfft->ifac, cfft->tab, -1);
|
|
424 }
|
|
425
|
|
426 void cfftb(cfft_info *cfft, complex_t *c)
|
|
427 {
|
|
428 cfftf1(cfft->n, c, cfft->work, cfft->ifac, cfft->tab, +1);
|
|
429 }
|
|
430
|
|
431 static void cffti1(uint16_t n, complex_t *wa, uint16_t *ifac)
|
|
432 {
|
|
433 static uint16_t ntryh[4] = {3, 4, 2, 5};
|
|
434 #ifndef FIXED_POINT
|
|
435 real_t arg, argh, argld, fi;
|
|
436 uint16_t ido, ipm;
|
|
437 uint16_t i1, k1, l1, l2;
|
|
438 uint16_t ld, ii, ip;
|
|
439 #endif
|
|
440 uint16_t ntry, i, j;
|
|
441 uint16_t ib;
|
|
442 uint16_t nf, nl, nq, nr;
|
|
443
|
|
444 nl = n;
|
|
445 nf = 0;
|
|
446 j = 0;
|
|
447
|
|
448 startloop:
|
|
449 j++;
|
|
450
|
|
451 if (j <= 4)
|
|
452 ntry = ntryh[j-1];
|
|
453 else
|
|
454 ntry += 2;
|
|
455
|
|
456 do
|
|
457 {
|
|
458 nq = nl / ntry;
|
|
459 nr = nl - ntry*nq;
|
|
460
|
|
461 if (nr != 0)
|
|
462 goto startloop;
|
|
463
|
|
464 nf++;
|
|
465 ifac[nf+1] = ntry;
|
|
466 nl = nq;
|
|
467
|
|
468 if (ntry == 2 && nf != 1)
|
|
469 {
|
|
470 for (i = 2; i <= nf; i++)
|
|
471 {
|
|
472 ib = nf - i + 2;
|
|
473 ifac[ib+1] = ifac[ib];
|
|
474 }
|
|
475 ifac[2] = 2;
|
|
476 }
|
|
477 } while (nl != 1);
|
|
478
|
|
479 ifac[0] = n;
|
|
480 ifac[1] = nf;
|
|
481
|
|
482 #ifndef FIXED_POINT
|
10989
|
483 argh = (real_t)2.0*M_PI / (real_t)n;
|
10725
|
484 i = 0;
|
|
485 l1 = 1;
|
|
486
|
|
487 for (k1 = 1; k1 <= nf; k1++)
|
|
488 {
|
|
489 ip = ifac[k1+1];
|
|
490 ld = 0;
|
|
491 l2 = l1*ip;
|
|
492 ido = n / l2;
|
|
493 ipm = ip - 1;
|
|
494
|
|
495 for (j = 0; j < ipm; j++)
|
|
496 {
|
|
497 i1 = i;
|
|
498 RE(wa[i]) = 1.0;
|
|
499 IM(wa[i]) = 0.0;
|
|
500 ld += l1;
|
|
501 fi = 0;
|
|
502 argld = ld*argh;
|
|
503
|
|
504 for (ii = 0; ii < ido; ii++)
|
|
505 {
|
|
506 i++;
|
|
507 fi++;
|
|
508 arg = fi * argld;
|
10989
|
509 RE(wa[i]) = (real_t)cos(arg);
|
|
510 IM(wa[i]) = (real_t)sin(arg);
|
10725
|
511 }
|
|
512
|
|
513 if (ip > 5)
|
|
514 {
|
|
515 RE(wa[i1]) = RE(wa[i]);
|
|
516 IM(wa[i1]) = IM(wa[i]);
|
|
517 }
|
|
518 }
|
|
519 l1 = l2;
|
|
520 }
|
|
521 #endif
|
|
522 }
|
|
523
|
|
524 cfft_info *cffti(uint16_t n)
|
|
525 {
|
|
526 cfft_info *cfft = (cfft_info*)malloc(sizeof(cfft_info));
|
|
527
|
|
528 cfft->n = n;
|
|
529 cfft->work = (complex_t*)malloc(n*sizeof(complex_t));
|
|
530
|
|
531 #ifndef FIXED_POINT
|
|
532 cfft->tab = (complex_t*)malloc(n*sizeof(complex_t));
|
|
533
|
|
534 cffti1(n, cfft->tab, cfft->ifac);
|
|
535 #else
|
|
536 cffti1(n, NULL, cfft->ifac);
|
|
537
|
|
538 switch (n)
|
|
539 {
|
|
540 case 60: cfft->tab = cfft_tab_60; break;
|
|
541 case 64: cfft->tab = cfft_tab_64; break;
|
|
542 case 480: cfft->tab = cfft_tab_480; break;
|
|
543 case 512: cfft->tab = cfft_tab_512; break;
|
|
544 #ifdef LD_DEC
|
|
545 case 240: cfft->tab = cfft_tab_240; break;
|
|
546 case 256: cfft->tab = cfft_tab_256; break;
|
|
547 #endif
|
|
548 }
|
|
549 #endif
|
|
550
|
|
551 return cfft;
|
|
552 }
|
|
553
|
|
554 void cfftu(cfft_info *cfft)
|
|
555 {
|
|
556 if (cfft->work) free(cfft->work);
|
|
557 #ifndef FIXED_POINT
|
|
558 if (cfft->tab) free(cfft->tab);
|
|
559 #endif
|
|
560
|
|
561 if (cfft) free(cfft);
|
10989
|
562 }
|