Mercurial > hg > vamp-plugin-sdk
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 |