+ Filter: move implementation of get_changed_offsets to .cpp file
[calf.git] / src / calf / fft.h
blob5cb50d53c668e029daf5e4850e222f0676b42147
1 /* Calf DSP Library
2 * FFT class
4 * Copyright (C) 2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #ifndef __CALF_FFT_H
23 #define __CALF_FFT_H
25 #include <complex>
27 namespace dsp {
29 /// FFT routine copied from my old OneSignal library, modified to
30 /// match Calf's style. It's not fast at all, just a straightforward
31 /// implementation.
32 template<class T, int O>
33 class fft
35 typedef typename std::complex<T> complex;
36 int scramble[1<<O];
37 complex sines[1<<O];
38 public:
39 fft()
41 int N=1<<O;
42 assert(N >= 4);
43 for (int i=0; i<N; i++)
45 int v=0;
46 for (int j=0; j<O; j++)
47 if (i&(1<<j))
48 v+=(N>>(j+1));
49 scramble[i]=v;
51 int N90 = N >> 2;
52 T divN = 2 * M_PI / N;
53 // use symmetry
54 for (int i=0; i<N90; i++)
56 T angle = divN * i;
57 T c = cos(angle), s = sin(angle);
58 sines[i + 3 * N90] = -(sines[i + N90] = complex(-s, c));
59 sines[i + 2 * N90] = -(sines[i] = complex(c, s));
62 void calculate(complex *input, complex *output, bool inverse)
64 int N=1<<O;
65 int N1=N-1;
66 int i;
67 // Scramble the input data
68 if (inverse)
70 float mf=1.0/N;
71 for (i=0; i<N; i++)
73 complex &c=input[scramble[i]];
74 output[i]=mf*complex(c.imag(),c.real());
77 else
78 for (i=0; i<N; i++)
79 output[i]=input[scramble[i]];
81 // O butterfiles
82 for (i=0; i<O; i++)
84 int PO=1<<i, PNO=1<<(O-i-1);
85 int j,k;
86 for (j=0; j<PNO; j++)
88 int base=j<<(i+1);
89 for (k=0; k<PO; k++)
91 int B1=base+k;
92 int B2=base+k+(1<<i);
93 complex r1=output[B1];
94 complex r2=output[B2];
95 output[B1]=r1+r2*sines[(B1<<(O-i-1))&N1];
96 output[B2]=r1+r2*sines[(B2<<(O-i-1))&N1];
100 if (inverse)
102 for (i=0; i<N; i++)
104 const complex &c=output[i];
105 output[i]=complex(c.imag(),c.real());
113 #endif