comparison fft.cpp @ 9:a1539d4e3b08

* Tidy code, start doc
author Chris Cannam
date Sat, 12 Jun 2010 13:08:33 +0100
parents
children 1e6360396b6c
comparison
equal deleted inserted replaced
8:e15ebd222c63 9:a1539d4e3b08
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 #ifdef VST
4 #include "devuvuzelator-vst.h"
5 #else
6 #ifdef LADSPA
7 #include "devuvuzelator-ladspa.h"
8 #else
9 #error Need to define either VST or LADSPA
10 #endif
11 #endif
12
13 // FFT implementation by Don Cross, public domain.
14 // This version scales the forward transform.
15
16 void Devuvuzelator::fft(unsigned int n, bool inverse,
17 double *ri, double *ii, double *ro, double *io)
18 {
19 if (!ri || !ro || !io) return;
20
21 unsigned int bits;
22 unsigned int i, j, k, m;
23 unsigned int blockSize, blockEnd;
24
25 double tr, ti;
26
27 if (n < 2) return;
28 if (n & (n-1)) return;
29
30 double angle = 2.0 * M_PI;
31 if (inverse) angle = -angle;
32
33 for (i = 0; ; ++i) {
34 if (n & (1 << i)) {
35 bits = i;
36 break;
37 }
38 }
39
40 static unsigned int tableSize = 0;
41 static int *table = 0;
42
43 if (tableSize != n) {
44
45 delete[] table;
46
47 table = new int[n];
48
49 for (i = 0; i < n; ++i) {
50
51 m = i;
52
53 for (j = k = 0; j < bits; ++j) {
54 k = (k << 1) | (m & 1);
55 m >>= 1;
56 }
57
58 table[i] = k;
59 }
60
61 tableSize = n;
62 }
63
64 if (ii) {
65 for (i = 0; i < n; ++i) {
66 ro[table[i]] = ri[i];
67 io[table[i]] = ii[i];
68 }
69 } else {
70 for (i = 0; i < n; ++i) {
71 ro[table[i]] = ri[i];
72 io[table[i]] = 0.0;
73 }
74 }
75
76 blockEnd = 1;
77
78 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
79
80 double delta = angle / (double)blockSize;
81 double sm2 = -sin(-2 * delta);
82 double sm1 = -sin(-delta);
83 double cm2 = cos(-2 * delta);
84 double cm1 = cos(-delta);
85 double w = 2 * cm1;
86 double ar[3], ai[3];
87
88 for (i = 0; i < n; i += blockSize) {
89
90 ar[2] = cm2;
91 ar[1] = cm1;
92
93 ai[2] = sm2;
94 ai[1] = sm1;
95
96 for (j = i, m = 0; m < blockEnd; j++, m++) {
97
98 ar[0] = w * ar[1] - ar[2];
99 ar[2] = ar[1];
100 ar[1] = ar[0];
101
102 ai[0] = w * ai[1] - ai[2];
103 ai[2] = ai[1];
104 ai[1] = ai[0];
105
106 k = j + blockEnd;
107 tr = ar[0] * ro[k] - ai[0] * io[k];
108 ti = ar[0] * io[k] + ai[0] * ro[k];
109
110 ro[k] = ro[j] - tr;
111 io[k] = io[j] - ti;
112
113 ro[j] += tr;
114 io[j] += ti;
115 }
116 }
117
118 blockEnd = blockSize;
119 }
120
121 if (!inverse) {
122
123 double denom = (double)n;
124
125 for (i = 0; i < n; i++) {
126 ro[i] /= denom;
127 io[i] /= denom;
128 }
129 }
130 }
131