2 (c) Copyright 1998-2001 - Tord Jansson
3 ======================================
5 This file is part of the BladeEnc MP3 Encoder, based on
6 ISO's reference code for MPEG Layer 3 compression, and might
7 contain smaller or larger sections that are directly taken
8 from ISO's reference code.
10 All changes to the ISO reference code herein are either
11 copyrighted by Tord Jansson (tord.jansson@swipnet.se)
12 or sublicensed to Tord Jansson by a third party.
14 BladeEnc is free software; you can redistribute this file
15 and/or modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 2.1 of the License, or (at your option) any later version.
21 ------------ Changes ------------
23 2000-11-04 Andre Piotrowski
25 - speed up: don«t calculate the unneeded phi values!
29 - speed up: slightly improved way to handle the 'special case'
33 - speed up: implemented prepacking
37 - speed up: avoid data reordering
41 - moved fft configuration switches to "l3psy.h"
45 - use some explicit type casting to avoid compiler warnings
48 /*****************************************************************************
49 * FFT computes fast fourier transform of BLKSIZE samples of data *
50 * based on the decimation-in-frequency algorithm described in "Digital *
51 * Signal Processing" by Oppenheim and Schafer, refer to pages 304 *
52 * (flow graph) and 330-332 (Fortran program in problem 5). *
54 * required constants: *
55 * PI 3.14159265358979 *
56 * BLKSIZE should be 2^^M for a positive integer M *
58 *****************************************************************************/
68 /* The switches have been moved to "l3psy.h" */
80 void fft (FLOAT x_real[], FLOAT x_imag[], FLOAT energy[], FLOAT phi[], int N)
87 static double w_real[BLKSIZE/2], w_imag[BLKSIZE/2];
88 double t_real, t_imag, u_real, u_imag;
92 static int swap_l[BLKSIZE/2+1];
93 static int swap_s[BLKSIZE_s/2+1];
97 double t1, t2, t3, t4, t5, t6;
101 for (i = 0; i < BLKSIZE/2; i++)
103 w_real[i] = cos(PI*i/(BLKSIZE/2));
105 w_imag[i] = -sin(PI*i/(BLKSIZE/2));
107 w_imag[i] = sin(PI*i/(BLKSIZE/2));
113 for (i = 0; i < BLKSIZE/2-1; i++)
115 swap_l[i] = j; k = BLKSIZE/4; while (k <= j) {j -= k; k >>= 1;} j += k;
117 swap_l[i] = i; swap_l[i+1] = i+1;
120 for (i = 0; i < BLKSIZE_s/2-1; i++)
122 swap_s[i] = j; k = BLKSIZE_s/4; while (k <= j) {j -= k; k >>= 1;} j += k;
124 swap_s[i] = i; swap_s[i+1] = i+1;
135 /* packing the sequence to the half length */
136 for (i = 0; i < N; i++)
138 x_real[i] = x_real[2*i];
139 x_imag[i] = x_real[2*i+1];
146 for (le = N; le > 1; le = le1)
150 /* special case: k=0; u_real=1.0; u_imag=0.0; j=0 */
151 for (i = 0; i < N; i += le)
154 t_real = x_real[i] - x_real[ip];
155 t_imag = x_imag[i] - x_imag[ip];
156 x_real[i] += x_real[ip];
157 x_imag[i] += x_imag[ip];
158 x_real[ip] = (FLOAT) t_real;
159 x_imag[ip] = (FLOAT) t_imag;
163 for (j = 1; j < le1; j++)
167 for (i = j; i < N; i += le)
170 t_real = x_real[i] - x_real[ip];
171 t_imag = x_imag[i] - x_imag[ip];
172 x_real[i] += x_real[ip];
173 x_imag[i] += x_imag[ip];
174 x_real[ip] = (FLOAT) (t_real*u_real - t_imag*u_imag);
175 x_imag[ip] = (FLOAT) (t_imag*u_real + t_real*u_imag);
185 /* this section reorders the data to the correct ordering */
187 for (i = 0; i < N-1; i++)
193 x_real[j] = x_real[i];
194 x_imag[j] = x_imag[i];
195 x_real[i] = (FLOAT) t_real;
196 x_imag[i] = (FLOAT) t_imag;
208 We don«t reorder the data to the correct ordering,
209 but access the data by the bit reverse order index array.
211 pSwap = (N_ORG == BLKSIZE) ? swap_l : swap_s;
216 /* unpacking the sequence */
219 x_real[0] = (FLOAT) (t_real+t_imag);
221 x_real[N] = (FLOAT) (t_real-t_imag);
224 k = off = BLKSIZE/N_ORG;
225 for (i = 1; i < N/2; i++)
234 t1 = x_real[a] + x_real[b];
235 t2 = x_real[a] - x_real[b];
236 t3 = x_imag[a] + x_imag[b];
237 t4 = x_imag[a] - x_imag[b];
238 t5 = t2*w_imag[k] + t3*w_real[k];
239 t6 = t3*w_imag[k] - t2*w_real[k];
241 x_real[a] = (FLOAT) (t1+t5) / 2.0;
242 x_imag[a] = (FLOAT) (t6+t4) / 2.0;
243 x_real[b] = (FLOAT) (t1-t5) / 2.0;
244 x_imag[b] = (FLOAT) (t6-t4) / 2.0;
248 /* x_real[N/2] doesn«t change */
249 /* x_real[N/2] changes the sign in case of a normal fft */
252 x_imag[i] = -x_imag[i];
254 x_imag[pSwap[i]] *= -1.0;
255 #endif /* REORDER_DATA */
256 #endif /* NORMAL_FFT */
258 #endif /* REAL_SEQUENCE */
261 /* calculating the energy and phase, phi */
265 min_i = LONG_FFT_MIN_IDX;
266 max_i = LONG_FFT_MAX_IDX;
270 min_i = SHORT_FFT_MIN_IDX;
271 max_i = SHORT_FFT_MAX_IDX;
275 for (i = 0; i <= N/2; i++)
277 for (i = 0; i < N; i++)
285 energy[i] = x_real[a]*x_real[a] + x_imag[a]*x_imag[a];
286 if(energy[i] <= 0.0005)
288 energy[i] = (FLOAT) 0.0005; /* keep the identity */
289 x_real[a] = (FLOAT) sqrt(0.0005); /* energy[i] * cos(phi[i]) == x_real[i] */
290 x_imag[a] = 0.0; /* energy[i] * sin(phi[i]) == x_imag[i] */
293 if (i >= min_i && i <= max_i)
295 phi[i] = (FLOAT) atan2((double) x_imag[a], (double) x_real[a]);