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 **
|
|
25 ** $Id: cfft.c,v 1.11 2003/07/29 08:20:12 menno Exp $
|
|
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 IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+1]);
|
|
69 RE(ch[ah+l1]) = RE(cc[ac]) - RE(cc[ac+1]);
|
|
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
|
|
82 RE(ch[ah]) = RE(cc[ac]) + RE(cc[ac+ido]);
|
|
83 IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+ido]);
|
|
84
|
|
85 RE(t2) = RE(cc[ac]) - RE(cc[ac+ido]);
|
|
86 IM(t2) = IM(cc[ac]) - IM(cc[ac+ido]);
|
|
87
|
|
88 RE(ch[ah+l1*ido]) = MUL_R_C(RE(t2),RE(wa[i])) - MUL_R_C(IM(t2),IM(wa[i]))*isign;
|
|
89 IM(ch[ah+l1*ido]) = MUL_R_C(IM(t2),RE(wa[i])) + MUL_R_C(RE(t2),IM(wa[i]))*isign;
|
|
90 ah++;
|
|
91 ac++;
|
|
92 }
|
|
93 }
|
|
94 }
|
|
95 }
|
|
96
|
|
97
|
|
98 static void passf3(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
99 complex_t *wa1, complex_t *wa2, int8_t isign)
|
|
100 {
|
|
101 static real_t taur = COEF_CONST(-0.5);
|
|
102 static real_t taui = COEF_CONST(0.866025403784439);
|
|
103 uint16_t i, k, ac, ah;
|
|
104 complex_t c2, c3, d2, d3, t2;
|
|
105
|
|
106 if (ido == 1)
|
|
107 {
|
|
108 for (k = 0; k < l1; k++)
|
|
109 {
|
|
110 ac = 3*k+1;
|
|
111 ah = k;
|
|
112
|
|
113 RE(t2) = RE(cc[ac]) + RE(cc[ac+1]);
|
|
114 IM(t2) = IM(cc[ac]) + IM(cc[ac+1]);
|
|
115 RE(c2) = RE(cc[ac-1]) + MUL_R_C(RE(t2),taur);
|
|
116 IM(c2) = IM(cc[ac-1]) + MUL_R_C(IM(t2),taur);
|
|
117
|
|
118 RE(ch[ah]) = RE(cc[ac-1]) + RE(t2);
|
|
119 IM(ch[ah]) = IM(cc[ac-1]) + IM(t2);
|
|
120
|
|
121 RE(c3) = MUL_R_C((RE(cc[ac]) - RE(cc[ac+1])), taui)*isign;
|
|
122 IM(c3) = MUL_R_C((IM(cc[ac]) - IM(cc[ac+1])), taui)*isign;
|
|
123
|
|
124 RE(ch[ah+l1]) = RE(c2) - IM(c3);
|
|
125 IM(ch[ah+l1]) = IM(c2) + RE(c3);
|
|
126 RE(ch[ah+2*l1]) = RE(c2) + IM(c3);
|
|
127 IM(ch[ah+2*l1]) = IM(c2) - RE(c3);
|
|
128 }
|
|
129 } else {
|
|
130 for (k = 0; k < l1; k++)
|
|
131 {
|
|
132 for (i = 0; i < ido; i++)
|
|
133 {
|
|
134 ac = i + (3*k+1)*ido;
|
|
135 ah = i + k * ido;
|
|
136
|
|
137 RE(t2) = RE(cc[ac]) + RE(cc[ac+ido]);
|
|
138 RE(c2) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),taur);
|
|
139 IM(t2) = IM(cc[ac]) + IM(cc[ac+ido]);
|
|
140 IM(c2) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),taur);
|
|
141
|
|
142 RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2);
|
|
143 IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2);
|
|
144
|
|
145 RE(c3) = MUL_R_C((RE(cc[ac]) - RE(cc[ac+ido])), taui)*isign;
|
|
146 IM(c3) = MUL_R_C((IM(cc[ac]) - IM(cc[ac+ido])), taui)*isign;
|
|
147
|
|
148 RE(d2) = RE(c2) - IM(c3);
|
|
149 IM(d3) = IM(c2) - RE(c3);
|
|
150 RE(d3) = RE(c2) + IM(c3);
|
|
151 IM(d2) = IM(c2) + RE(c3);
|
|
152
|
|
153 RE(ch[ah+l1*ido]) = MUL_R_C(RE(d2),RE(wa1[i])) - MUL_R_C(IM(d2),IM(wa1[i]))*isign;
|
|
154 IM(ch[ah+l1*ido]) = MUL_R_C(IM(d2),RE(wa1[i])) + MUL_R_C(RE(d2),IM(wa1[i]))*isign;
|
|
155 RE(ch[ah+l1*2*ido]) = MUL_R_C(RE(d3),RE(wa2[i])) - MUL_R_C(IM(d3),IM(wa2[i]))*isign;
|
|
156 IM(ch[ah+l1*2*ido]) = MUL_R_C(IM(d3),RE(wa2[i])) + MUL_R_C(RE(d3),IM(wa2[i]))*isign;
|
|
157 }
|
|
158 }
|
|
159 }
|
|
160 }
|
|
161
|
|
162
|
|
163 static void passf4(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
164 complex_t *wa1, complex_t *wa2, complex_t *wa3, int8_t isign)
|
|
165 {
|
|
166 uint16_t i, k, ac, ah;
|
|
167 complex_t c2, c3, c4, t1, t2, t3, t4;
|
|
168
|
|
169 if (ido == 1)
|
|
170 {
|
|
171 for (k = 0; k < l1; k++)
|
|
172 {
|
|
173 ac = 4*k;
|
|
174 ah = k;
|
|
175
|
|
176 RE(t2) = RE(cc[ac]) + RE(cc[ac+2]);
|
|
177 IM(t2) = IM(cc[ac]) + IM(cc[ac+2]);
|
|
178 RE(t3) = RE(cc[ac+1]) + RE(cc[ac+3]);
|
|
179 IM(t3) = IM(cc[ac+1]) + IM(cc[ac+3]);
|
|
180 RE(t1) = RE(cc[ac]) - RE(cc[ac+2]);
|
|
181 IM(t1) = IM(cc[ac]) - IM(cc[ac+2]);
|
|
182 RE(t4) = IM(cc[ac+3]) - IM(cc[ac+1]);
|
|
183 IM(t4) = RE(cc[ac+1]) - RE(cc[ac+3]);
|
|
184
|
|
185 RE(ch[ah]) = RE(t2) + RE(t3);
|
|
186 IM(ch[ah]) = IM(t2) + IM(t3);
|
|
187 RE(ch[ah+l1]) = RE(t1) + RE(t4)*isign;
|
|
188 IM(ch[ah+l1]) = IM(t1) + IM(t4)*isign;
|
|
189 RE(ch[ah+2*l1]) = RE(t2) - RE(t3);
|
|
190 IM(ch[ah+2*l1]) = IM(t2) - IM(t3);
|
|
191 RE(ch[ah+3*l1]) = RE(t1) - RE(t4)*isign;
|
|
192 IM(ch[ah+3*l1]) = IM(t1) - IM(t4)*isign;
|
|
193 }
|
|
194 } else {
|
|
195 for (k = 0; k < l1; k++)
|
|
196 {
|
|
197 for (i = 0; i < ido; i++)
|
|
198 {
|
|
199 ac = i + 4*k*ido;
|
|
200 ah = i + k*ido;
|
|
201
|
|
202 RE(t2) = RE(cc[ac]) + RE(cc[ac+2*ido]);
|
|
203 IM(t2) = IM(cc[ac]) + IM(cc[ac+2*ido]);
|
|
204 RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+3*ido]);
|
|
205 IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+3*ido]);
|
|
206 RE(t1) = RE(cc[ac]) - RE(cc[ac+2*ido]);
|
|
207 IM(t1) = IM(cc[ac]) - IM(cc[ac+2*ido]);
|
|
208 RE(t4) = IM(cc[ac+3*ido]) - IM(cc[ac+ido]);
|
|
209 IM(t4) = RE(cc[ac+ido]) - RE(cc[ac+3*ido]);
|
|
210
|
|
211 RE(ch[ah]) = RE(t2) + RE(t3);
|
|
212 IM(ch[ah]) = IM(t2) + IM(t3);
|
|
213
|
|
214 RE(c2) = RE(t1) + RE(t4)*isign;
|
|
215 IM(c2) = IM(t1) + IM(t4)*isign;
|
|
216 RE(c3) = RE(t2) - RE(t3);
|
|
217 IM(c3) = IM(t2) - IM(t3);
|
|
218 RE(c4) = RE(t1) - RE(t4)*isign;
|
|
219 IM(c4) = IM(t1) - IM(t4)*isign;
|
|
220
|
|
221 RE(ch[ah+l1*ido]) = MUL_R_C(RE(c2),RE(wa1[i])) - MUL_R_C(IM(c2),IM(wa1[i]))*isign;
|
|
222 IM(ch[ah+l1*ido]) = MUL_R_C(IM(c2),RE(wa1[i])) + MUL_R_C(RE(c2),IM(wa1[i]))*isign;
|
|
223 RE(ch[ah+2*l1*ido]) = MUL_R_C(RE(c3),RE(wa2[i])) - MUL_R_C(IM(c3),IM(wa2[i]))*isign;
|
|
224 IM(ch[ah+2*l1*ido]) = MUL_R_C(IM(c3),RE(wa2[i])) + MUL_R_C(RE(c3),IM(wa2[i]))*isign;
|
|
225 RE(ch[ah+3*l1*ido]) = MUL_R_C(RE(c4),RE(wa3[i])) - MUL_R_C(IM(c4),IM(wa3[i]))*isign;
|
|
226 IM(ch[ah+3*l1*ido]) = MUL_R_C(IM(c4),RE(wa3[i])) + MUL_R_C(RE(c4),IM(wa3[i]))*isign;
|
|
227 }
|
|
228 }
|
|
229 }
|
|
230 }
|
|
231
|
|
232
|
|
233 static void passf5(uint16_t ido, uint16_t l1, complex_t *cc, complex_t *ch,
|
|
234 complex_t *wa1, complex_t *wa2, complex_t *wa3, complex_t *wa4,
|
|
235 int8_t isign)
|
|
236 {
|
|
237 static real_t tr11 = COEF_CONST(0.309016994374947);
|
|
238 static real_t ti11 = COEF_CONST(0.951056516295154);
|
|
239 static real_t tr12 = COEF_CONST(-0.809016994374947);
|
|
240 static real_t ti12 = COEF_CONST(0.587785252292473);
|
|
241 uint16_t i, k, ac, ah;
|
|
242 complex_t c2, c3, c4, c5, d3, d4, d5, d2, t2, t3, t4, t5;
|
|
243
|
|
244 if (ido == 1)
|
|
245 {
|
|
246 for (k = 0; k < l1; k++)
|
|
247 {
|
|
248 ac = 5*k + 1;
|
|
249 ah = k;
|
|
250
|
|
251 RE(t2) = RE(cc[ac]) + RE(cc[ac+3]);
|
|
252 IM(t2) = IM(cc[ac]) + IM(cc[ac+3]);
|
|
253 RE(t3) = RE(cc[ac+1]) + RE(cc[ac+2]);
|
|
254 IM(t3) = IM(cc[ac+1]) + IM(cc[ac+2]);
|
|
255 RE(t4) = RE(cc[ac+1]) - RE(cc[ac+2]);
|
|
256 IM(t4) = IM(cc[ac+1]) - IM(cc[ac+2]);
|
|
257 RE(t5) = RE(cc[ac]) - RE(cc[ac+3]);
|
|
258 IM(t5) = IM(cc[ac]) - IM(cc[ac+3]);
|
|
259
|
|
260 RE(ch[ah]) = RE(cc[ac-1]) + RE(t2) + RE(t3);
|
|
261 IM(ch[ah]) = IM(cc[ac-1]) + IM(t2) + IM(t3);
|
|
262
|
|
263 RE(c2) = RE(cc[ac-1]) + MUL_R_C(RE(t2),tr11) + MUL_R_C(RE(t3),tr12);
|
|
264 IM(c2) = IM(cc[ac-1]) + MUL_R_C(IM(t2),tr11) + MUL_R_C(IM(t3),tr12);
|
|
265 RE(c3) = RE(cc[ac-1]) + MUL_R_C(RE(t2),tr12) + MUL_R_C(RE(t3),tr11);
|
|
266 IM(c3) = IM(cc[ac-1]) + MUL_R_C(IM(t2),tr12) + MUL_R_C(IM(t3),tr11);
|
|
267 RE(c4) = (MUL_R_C(RE(t5),ti12)*isign - MUL_R_C(RE(t4),ti11));
|
|
268 IM(c4) = (MUL_R_C(IM(t5),ti12)*isign - MUL_R_C(IM(t4),ti11));
|
|
269 RE(c5) = (MUL_R_C(RE(t5),ti11)*isign + MUL_R_C(RE(t4),ti12));
|
|
270 IM(c5) = (MUL_R_C(IM(t5),ti11)*isign + MUL_R_C(IM(t4),ti12));
|
|
271
|
|
272 RE(ch[ah+l1]) = RE(c2) - IM(c5);
|
|
273 IM(ch[ah+l1]) = IM(c2) + RE(c5);
|
|
274 RE(ch[ah+2*l1]) = RE(c3) - IM(c4);
|
|
275 IM(ch[ah+2*l1]) = IM(c3) + RE(c4);
|
|
276 RE(ch[ah+3*l1]) = RE(c3) + IM(c4);
|
|
277 IM(ch[ah+3*l1]) = IM(c3) - RE(c4);
|
|
278 RE(ch[ah+4*l1]) = RE(c2) + IM(c5);
|
|
279 IM(ch[ah+4*l1]) = IM(c2) - RE(c5);
|
|
280 }
|
|
281 } else {
|
|
282 for (k = 0; k < l1; k++)
|
|
283 {
|
|
284 for (i = 0; i < ido; i++)
|
|
285 {
|
|
286 ac = i + (k*5 + 1) * ido;
|
|
287 ah = i + k * ido;
|
|
288
|
|
289 RE(t2) = RE(cc[ac]) + RE(cc[ac+3*ido]);
|
|
290 IM(t2) = IM(cc[ac]) + IM(cc[ac+3*ido]);
|
|
291 RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+2*ido]);
|
|
292 IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+2*ido]);
|
|
293 RE(t4) = RE(cc[ac+ido]) - RE(cc[ac+2*ido]);
|
|
294 IM(t4) = IM(cc[ac+ido]) - IM(cc[ac+2*ido]);
|
|
295 RE(t5) = RE(cc[ac]) - RE(cc[ac+3*ido]);
|
|
296 IM(t5) = IM(cc[ac]) - IM(cc[ac+3*ido]);
|
|
297
|
|
298 RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2) + RE(t3);
|
|
299 IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2) + IM(t3);
|
|
300
|
|
301 RE(c2) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),tr11) + MUL_R_C(RE(t3),tr12);
|
|
302 IM(c2) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),tr11) + MUL_R_C(IM(t3),tr12);
|
|
303 RE(c3) = RE(cc[ac-ido]) + MUL_R_C(RE(t2),tr12) + MUL_R_C(RE(t3),tr11);
|
|
304 IM(c3) = IM(cc[ac-ido]) + MUL_R_C(IM(t2),tr12) + MUL_R_C(IM(t3),tr11);
|
|
305 RE(c4) = (MUL_R_C(RE(t5),ti12)*isign - MUL_R_C(RE(t4),ti11));
|
|
306 IM(c4) = (MUL_R_C(IM(t5),ti12)*isign - MUL_R_C(IM(t4),ti11));
|
|
307 RE(c5) = (MUL_R_C(RE(t5),ti11)*isign + MUL_R_C(RE(t4),ti12));
|
|
308 IM(c5) = (MUL_R_C(IM(t5),ti11)*isign + MUL_R_C(IM(t4),ti12));
|
|
309
|
|
310 IM(d2) = IM(c2) + RE(c5);
|
|
311 IM(d3) = IM(c3) + RE(c4);
|
|
312 RE(d4) = RE(c3) + IM(c4);
|
|
313 RE(d5) = RE(c2) + IM(c5);
|
|
314 RE(d2) = RE(c2) - IM(c5);
|
|
315 IM(d5) = IM(c2) - RE(c5);
|
|
316 RE(d3) = RE(c3) - IM(c4);
|
|
317 IM(d4) = IM(c3) - RE(c4);
|
|
318
|
|
319 RE(ch[ah+l1*ido]) = MUL_R_C(RE(d2),RE(wa1[i])) - MUL_R_C(IM(d2),IM(wa1[i]))*isign;
|
|
320 IM(ch[ah+l1*ido]) = MUL_R_C(IM(d2),RE(wa1[i])) + MUL_R_C(RE(d2),IM(wa1[i]))*isign;
|
|
321 RE(ch[ah+2*l1*ido]) = MUL_R_C(RE(d3),RE(wa2[i])) - MUL_R_C(IM(d3),IM(wa2[i]))*isign;
|
|
322 IM(ch[ah+2*l1*ido]) = MUL_R_C(IM(d3),RE(wa2[i])) + MUL_R_C(RE(d3),IM(wa2[i]))*isign;
|
|
323 RE(ch[ah+3*l1*ido]) = MUL_R_C(RE(d4),RE(wa3[i])) - MUL_R_C(IM(d4),IM(wa3[i]))*isign;
|
|
324 IM(ch[ah+3*l1*ido]) = MUL_R_C(IM(d4),RE(wa3[i])) + MUL_R_C(RE(d4),IM(wa3[i]))*isign;
|
|
325 RE(ch[ah+4*l1*ido]) = MUL_R_C(RE(d5),RE(wa4[i])) - MUL_R_C(IM(d5),IM(wa4[i]))*isign;
|
|
326 IM(ch[ah+4*l1*ido]) = MUL_R_C(IM(d5),RE(wa4[i])) + MUL_R_C(RE(d5),IM(wa4[i]))*isign;
|
|
327 }
|
|
328 }
|
|
329 }
|
|
330 }
|
|
331
|
|
332
|
|
333 /*----------------------------------------------------------------------
|
|
334 cfftf1, cfftf, cfftb, cffti1, cffti. Complex FFTs.
|
|
335 ----------------------------------------------------------------------*/
|
|
336
|
|
337 INLINE void cfftf1(uint16_t n, complex_t *c, complex_t *ch,
|
|
338 uint16_t *ifac, complex_t *wa, int8_t isign)
|
|
339 {
|
|
340 uint16_t i;
|
|
341 uint16_t k1, l1, l2;
|
|
342 uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido, idl1;
|
|
343
|
|
344 nf = ifac[1];
|
|
345 na = 0;
|
|
346 l1 = 1;
|
|
347 iw = 0;
|
|
348
|
|
349 for (k1 = 2; k1 <= nf+1; k1++)
|
|
350 {
|
|
351 ip = ifac[k1];
|
|
352 l2 = ip*l1;
|
|
353 ido = n / l2;
|
|
354 idl1 = ido*l1;
|
|
355
|
|
356 switch (ip)
|
|
357 {
|
|
358 case 2:
|
|
359 if (na == 0)
|
|
360 passf2(ido, l1, c, ch, &wa[iw], isign);
|
|
361 else
|
|
362 passf2(ido, l1, ch, c, &wa[iw], isign);
|
|
363
|
|
364 na = 1 - na;
|
|
365 break;
|
|
366 case 3:
|
|
367 ix2 = iw + ido;
|
|
368
|
|
369 if (na == 0)
|
|
370 passf3(ido, l1, c, ch, &wa[iw], &wa[ix2], isign);
|
|
371 else
|
|
372 passf3(ido, l1, ch, c, &wa[iw], &wa[ix2], isign);
|
|
373
|
|
374 na = 1 - na;
|
|
375 break;
|
|
376 case 4:
|
|
377 ix2 = iw + ido;
|
|
378 ix3 = ix2 + ido;
|
|
379
|
|
380 if (na == 0)
|
|
381 passf4(ido, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], isign);
|
|
382 else
|
|
383 passf4(ido, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], isign);
|
|
384
|
|
385 na = 1 - na;
|
|
386 break;
|
|
387 case 5:
|
|
388 ix2 = iw + ido;
|
|
389 ix3 = ix2 + ido;
|
|
390 ix4 = ix3 + ido;
|
|
391
|
|
392 if (na == 0)
|
|
393 passf5(ido, l1, c, ch, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign);
|
|
394 else
|
|
395 passf5(ido, l1, ch, c, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign);
|
|
396
|
|
397 na = 1 - na;
|
|
398 break;
|
|
399 }
|
|
400
|
|
401 l1 = l2;
|
|
402 iw += (ip-1) * ido;
|
|
403 }
|
|
404
|
|
405 if (na == 0)
|
|
406 return;
|
|
407
|
|
408 for (i = 0; i < n; i++)
|
|
409 {
|
|
410 RE(c[i]) = RE(ch[i]);
|
|
411 IM(c[i]) = IM(ch[i]);
|
|
412 }
|
|
413 }
|
|
414
|
|
415 void cfftf(cfft_info *cfft, complex_t *c)
|
|
416 {
|
|
417 cfftf1(cfft->n, c, cfft->work, cfft->ifac, cfft->tab, -1);
|
|
418 }
|
|
419
|
|
420 void cfftb(cfft_info *cfft, complex_t *c)
|
|
421 {
|
|
422 cfftf1(cfft->n, c, cfft->work, cfft->ifac, cfft->tab, +1);
|
|
423 }
|
|
424
|
|
425 static void cffti1(uint16_t n, complex_t *wa, uint16_t *ifac)
|
|
426 {
|
|
427 static uint16_t ntryh[4] = {3, 4, 2, 5};
|
|
428 #ifndef FIXED_POINT
|
|
429 real_t arg, argh, argld, fi;
|
|
430 uint16_t ido, ipm;
|
|
431 uint16_t i1, k1, l1, l2;
|
|
432 uint16_t ld, ii, ip;
|
|
433 #endif
|
|
434 uint16_t ntry, i, j;
|
|
435 uint16_t ib;
|
|
436 uint16_t nf, nl, nq, nr;
|
|
437
|
|
438 nl = n;
|
|
439 nf = 0;
|
|
440 j = 0;
|
|
441
|
|
442 startloop:
|
|
443 j++;
|
|
444
|
|
445 if (j <= 4)
|
|
446 ntry = ntryh[j-1];
|
|
447 else
|
|
448 ntry += 2;
|
|
449
|
|
450 do
|
|
451 {
|
|
452 nq = nl / ntry;
|
|
453 nr = nl - ntry*nq;
|
|
454
|
|
455 if (nr != 0)
|
|
456 goto startloop;
|
|
457
|
|
458 nf++;
|
|
459 ifac[nf+1] = ntry;
|
|
460 nl = nq;
|
|
461
|
|
462 if (ntry == 2 && nf != 1)
|
|
463 {
|
|
464 for (i = 2; i <= nf; i++)
|
|
465 {
|
|
466 ib = nf - i + 2;
|
|
467 ifac[ib+1] = ifac[ib];
|
|
468 }
|
|
469 ifac[2] = 2;
|
|
470 }
|
|
471 } while (nl != 1);
|
|
472
|
|
473 ifac[0] = n;
|
|
474 ifac[1] = nf;
|
|
475
|
|
476 #ifndef FIXED_POINT
|
|
477 argh = 2.0*M_PI / (real_t)n;
|
|
478 i = 0;
|
|
479 l1 = 1;
|
|
480
|
|
481 for (k1 = 1; k1 <= nf; k1++)
|
|
482 {
|
|
483 ip = ifac[k1+1];
|
|
484 ld = 0;
|
|
485 l2 = l1*ip;
|
|
486 ido = n / l2;
|
|
487 ipm = ip - 1;
|
|
488
|
|
489 for (j = 0; j < ipm; j++)
|
|
490 {
|
|
491 i1 = i;
|
|
492 RE(wa[i]) = 1.0;
|
|
493 IM(wa[i]) = 0.0;
|
|
494 ld += l1;
|
|
495 fi = 0;
|
|
496 argld = ld*argh;
|
|
497
|
|
498 for (ii = 0; ii < ido; ii++)
|
|
499 {
|
|
500 i++;
|
|
501 fi++;
|
|
502 arg = fi * argld;
|
|
503 RE(wa[i]) = cos(arg);
|
|
504 IM(wa[i]) = sin(arg);
|
|
505 }
|
|
506
|
|
507 if (ip > 5)
|
|
508 {
|
|
509 RE(wa[i1]) = RE(wa[i]);
|
|
510 IM(wa[i1]) = IM(wa[i]);
|
|
511 }
|
|
512 }
|
|
513 l1 = l2;
|
|
514 }
|
|
515 #endif
|
|
516 }
|
|
517
|
|
518 cfft_info *cffti(uint16_t n)
|
|
519 {
|
|
520 cfft_info *cfft = (cfft_info*)malloc(sizeof(cfft_info));
|
|
521
|
|
522 cfft->n = n;
|
|
523 cfft->work = (complex_t*)malloc(n*sizeof(complex_t));
|
|
524
|
|
525 #ifndef FIXED_POINT
|
|
526 cfft->tab = (complex_t*)malloc(n*sizeof(complex_t));
|
|
527
|
|
528 cffti1(n, cfft->tab, cfft->ifac);
|
|
529 #else
|
|
530 cffti1(n, NULL, cfft->ifac);
|
|
531
|
|
532 switch (n)
|
|
533 {
|
|
534 case 60: cfft->tab = cfft_tab_60; break;
|
|
535 case 64: cfft->tab = cfft_tab_64; break;
|
|
536 case 480: cfft->tab = cfft_tab_480; break;
|
|
537 case 512: cfft->tab = cfft_tab_512; break;
|
|
538 #ifdef LD_DEC
|
|
539 case 240: cfft->tab = cfft_tab_240; break;
|
|
540 case 256: cfft->tab = cfft_tab_256; break;
|
|
541 #endif
|
|
542 }
|
|
543 #endif
|
|
544
|
|
545 return cfft;
|
|
546 }
|
|
547
|
|
548 void cfftu(cfft_info *cfft)
|
|
549 {
|
|
550 if (cfft->work) free(cfft->work);
|
|
551 #ifndef FIXED_POINT
|
|
552 if (cfft->tab) free(cfft->tab);
|
|
553 #endif
|
|
554
|
|
555 if (cfft) free(cfft);
|
|
556 } |