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 | 
