comparison src/vamp-sdk/FFTimpl.cpp @ 460:b409560a805b

Merge from branch vampipe
author Chris Cannam
date Mon, 10 Oct 2016 15:48:35 +0100
parents ab8e761f3ee9 b89653767a60
children 25e023bad200
comparison
equal deleted inserted replaced
442:4101e3f80aa0 460:b409560a805b
1 1
2 /* Public domain FFT implementation from Don Cross. */ 2 // Override C linkage for KissFFT headers. So long as we have already
3 // included all of the other (system etc) headers KissFFT depends on,
4 // this should work out OK
5 #undef __cplusplus
3 6
4 static void 7 namespace Kiss {
5 fft(unsigned int n, bool inverse,
6 const double *ri, const double *ii,
7 double *ro, double *io)
8 {
9 if (!ri || !ro || !io) return;
10 8
11 unsigned int bits; 9 #undef KISS_FFT_H
12 unsigned int i, j, k, m; 10 #undef KISS_FTR_H
13 unsigned int blockSize, blockEnd; 11 #undef KISS_FFT__GUTS_H
12 #undef FIXED_POINT
13 #undef USE_SIMD
14 #undef kiss_fft_scalar
14 15
15 double tr, ti; 16 #ifdef SINGLE_PRECISION_FFT
16 17 #pragma message("Using single-precision FFTs")
17 if (n < 2) return; 18 typedef float kiss_fft_scalar;
18 if (n & (n-1)) return; 19 #define kiss_fft_scalar float
19
20 double angle = 2.0 * M_PI;
21 if (inverse) angle = -angle;
22
23 for (i = 0; ; ++i) {
24 if (n & (1 << i)) {
25 bits = i;
26 break;
27 }
28 }
29
30 #ifdef _MSC_VER
31 int *table = (int *)_malloca(n * sizeof(int));
32 #else 20 #else
33 int table[n]; 21 typedef double kiss_fft_scalar;
22 #define kiss_fft_scalar double
34 #endif 23 #endif
35 24
36 for (i = 0; i < n; ++i) { 25 inline void free(void *ptr) { ::free(ptr); }
37 m = i; 26 #include "ext/kiss_fft.c"
38 for (j = k = 0; j < bits; ++j) { 27 #include "ext/kiss_fftr.c"
39 k = (k << 1) | (m & 1);
40 m >>= 1;
41 }
42 table[i] = k;
43 }
44 28
45 if (ii) { 29 #undef kiss_fft_scalar // leaving only the namespaced typedef
46 for (i = 0; i < n; ++i) {
47 ro[table[i]] = ri[i];
48 io[table[i]] = ii[i];
49 }
50 } else {
51 for (i = 0; i < n; ++i) {
52 ro[table[i]] = ri[i];
53 io[table[i]] = 0.0;
54 }
55 }
56 30
57 blockEnd = 1;
58
59 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
60
61 double delta = angle / (double)blockSize;
62 double sm2 = -sin(-2 * delta);
63 double sm1 = -sin(-delta);
64 double cm2 = cos(-2 * delta);
65 double cm1 = cos(-delta);
66 double w = 2 * cm1;
67 double ar[3], ai[3];
68
69 for (i = 0; i < n; i += blockSize) {
70
71 ar[2] = cm2;
72 ar[1] = cm1;
73
74 ai[2] = sm2;
75 ai[1] = sm1;
76
77 for (j = i, m = 0; m < blockEnd; j++, m++) {
78
79 ar[0] = w * ar[1] - ar[2];
80 ar[2] = ar[1];
81 ar[1] = ar[0];
82
83 ai[0] = w * ai[1] - ai[2];
84 ai[2] = ai[1];
85 ai[1] = ai[0];
86
87 k = j + blockEnd;
88 tr = ar[0] * ro[k] - ai[0] * io[k];
89 ti = ar[0] * io[k] + ai[0] * ro[k];
90
91 ro[k] = ro[j] - tr;
92 io[k] = io[j] - ti;
93
94 ro[j] += tr;
95 io[j] += ti;
96 }
97 }
98
99 blockEnd = blockSize;
100 }
101
102 if (inverse) {
103
104 double denom = (double)n;
105
106 for (i = 0; i < n; i++) {
107 ro[i] /= denom;
108 io[i] /= denom;
109 }
110 }
111
112 #ifdef _MSC_VER
113 _freea(table);
114 #endif
115 } 31 }
116 32