2
* fft.c: fft and frequency calculation.
3
* Copyright (C) 1999 Richard Boulton <richard@tartarus.org>
4
* Convolution stuff by Ralph Loader <suckfish@ihug.co.nz>
6
* August 2000: almost completely rewritten by Fabio Checconi <fchecconi@libero.it>
7
* ( see src/fft.old.c for the original one, used by xmms-0.9.5.1 ).
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
39
#define PI 3.14159265358979323846
43
double *window = NULL;
45
int _fft_init ( unsigned long points );
49
int _fft_reverse_bits ( unsigned int initial );
50
void _fft_calculate ( void );
52
double *rout = NULL, *iout = NULL, *costable = NULL, *sintable = NULL;
55
int *bit_reverse = NULL;
60
fftw_real *rin = NULL, *rout = NULL;
68
_fft_reverse_bits( unsigned int initial )
70
unsigned int reversed = 0, loop;
72
for( loop = 0; loop < lognn; loop++) {
74
reversed += (initial & 1);
82
_fft_calculate( void )
85
unsigned int exchanges;
86
float fact_real, fact_imag;
87
float tmp_real, tmp_imag;
88
unsigned int factfact;
93
for( i = lognn; i != 0; i-- ) {
94
for( j = 0; j != exchanges; j++ ) {
95
fact_real = costable[j * factfact];
96
fact_imag = sintable[j * factfact];
98
for( k = j; k < nn; k += exchanges << 1) {
99
int k1 = k + exchanges;
100
tmp_real = fact_real * rout[k1] - fact_imag * iout[k1];
101
tmp_imag = fact_real * iout[k1] + fact_imag * rout[k1];
102
rout[k1] = rout[k] - tmp_real;
103
iout[k1] = iout[k] - tmp_imag;
113
#define __fft_calculate _fft_calculate();
117
#define __fft_calculate rfftw_one( p, rin, rout );
122
_fft_init( unsigned long points )
127
unsigned int i = points, k = 1;
144
if( sintable != NULL )
146
if( costable != NULL )
148
if( bit_reverse != NULL )
151
bit_reverse = (int*) xmalloc( sizeof( int ) * nn );
152
costable = (double*) xmalloc( sizeof( double ) * nn / 2 );
153
sintable = (double*) xmalloc( sizeof( double ) * nn / 2 );
155
rout = (double*) xmalloc ( sizeof( double ) * nn );
156
iout = (double*) xmalloc ( sizeof( double ) * nn );
158
for( i = 0; i < nn; i++ ) {
159
bit_reverse[i] = _fft_reverse_bits( i );
162
for( i = 0; i < nn / 2; i++ ) {
164
costable[i] = cos( j );
165
sintable[i] = sin( j );
177
rfftw_destroy_plan( p );
179
rin = (fftw_real*) xmalloc( sizeof( fftw_real ) * nn );
180
rout = (fftw_real*) xmalloc( sizeof( fftw_real ) * nn );
182
p = rfftw_create_plan( nn, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE );
190
window = (double*) xmalloc( sizeof( double ) * nn );
191
for ( c = 0; c < nn / 2; c++ )
192
window[c] = window[nn - c - 1] = 0.54 - 0.46 * cos( 2 * PI * c / nn );
198
fft( void *snd_sample, unsigned long size, double *outbuf, int typ )
203
if( _fft_init( size ) != 0 )
208
for( n = 0; n < nn; n++ ) {
210
rout[bit_reverse[n]] = (((unsigned char*)snd_sample)[n] - 128) * window[n];
211
iout[bit_reverse[n]] = 0;
213
rin[n] = (((unsigned char*)snd_sample)[n] - 128) * window[n];
217
for( n = 0; n < nn; n++ ) {
219
rout[bit_reverse[n]] = ((unsigned int*)snd_sample)[n];
220
iout[bit_reverse[n]] = 0;
222
rin[n] = ((int*)snd_sample)[n];
229
for( n = 0; n < size / 2; n ++ )
231
outbuf[n] = rout[n] * rout[n] + iout[n] * iout[n];
233
outbuf[n] = rout[n] * rout[n] + rout[size - n] * rout[size - n];