annotate src/vamp-sdk/FFTimpl.cpp @ 357:ef49ec7b71be

Added tag vamp-plugin-sdk-v2.5 for changeset 92b1fbb1cc87
author Chris Cannam
date Wed, 08 May 2013 10:48:43 +0100
parents ab8e761f3ee9
children b409560a805b
rev   line source
Chris@337 1
Chris@337 2 /* Public domain FFT implementation from Don Cross. */
Chris@337 3
Chris@337 4 static void
Chris@337 5 fft(unsigned int n, bool inverse,
Chris@337 6 const double *ri, const double *ii,
Chris@337 7 double *ro, double *io)
Chris@337 8 {
Chris@337 9 if (!ri || !ro || !io) return;
Chris@337 10
Chris@337 11 unsigned int bits;
Chris@337 12 unsigned int i, j, k, m;
Chris@337 13 unsigned int blockSize, blockEnd;
Chris@337 14
Chris@337 15 double tr, ti;
Chris@337 16
Chris@337 17 if (n < 2) return;
Chris@337 18 if (n & (n-1)) return;
Chris@337 19
Chris@337 20 double angle = 2.0 * M_PI;
Chris@337 21 if (inverse) angle = -angle;
Chris@337 22
Chris@337 23 for (i = 0; ; ++i) {
Chris@337 24 if (n & (1 << i)) {
Chris@337 25 bits = i;
Chris@337 26 break;
Chris@337 27 }
Chris@337 28 }
Chris@337 29
chris@340 30 #ifdef _MSC_VER
chris@340 31 int *table = (int *)_malloca(n * sizeof(int));
chris@340 32 #else
Chris@337 33 int table[n];
chris@340 34 #endif
Chris@337 35
Chris@337 36 for (i = 0; i < n; ++i) {
Chris@337 37 m = i;
Chris@337 38 for (j = k = 0; j < bits; ++j) {
Chris@337 39 k = (k << 1) | (m & 1);
Chris@337 40 m >>= 1;
Chris@337 41 }
Chris@337 42 table[i] = k;
Chris@337 43 }
Chris@337 44
Chris@337 45 if (ii) {
Chris@337 46 for (i = 0; i < n; ++i) {
Chris@337 47 ro[table[i]] = ri[i];
Chris@337 48 io[table[i]] = ii[i];
Chris@337 49 }
Chris@337 50 } else {
Chris@337 51 for (i = 0; i < n; ++i) {
Chris@337 52 ro[table[i]] = ri[i];
Chris@337 53 io[table[i]] = 0.0;
Chris@337 54 }
Chris@337 55 }
Chris@337 56
Chris@337 57 blockEnd = 1;
Chris@337 58
Chris@337 59 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
Chris@337 60
Chris@337 61 double delta = angle / (double)blockSize;
Chris@337 62 double sm2 = -sin(-2 * delta);
Chris@337 63 double sm1 = -sin(-delta);
Chris@337 64 double cm2 = cos(-2 * delta);
Chris@337 65 double cm1 = cos(-delta);
Chris@337 66 double w = 2 * cm1;
Chris@337 67 double ar[3], ai[3];
Chris@337 68
Chris@337 69 for (i = 0; i < n; i += blockSize) {
Chris@337 70
Chris@337 71 ar[2] = cm2;
Chris@337 72 ar[1] = cm1;
Chris@337 73
Chris@337 74 ai[2] = sm2;
Chris@337 75 ai[1] = sm1;
Chris@337 76
Chris@337 77 for (j = i, m = 0; m < blockEnd; j++, m++) {
Chris@337 78
Chris@337 79 ar[0] = w * ar[1] - ar[2];
Chris@337 80 ar[2] = ar[1];
Chris@337 81 ar[1] = ar[0];
Chris@337 82
Chris@337 83 ai[0] = w * ai[1] - ai[2];
Chris@337 84 ai[2] = ai[1];
Chris@337 85 ai[1] = ai[0];
Chris@337 86
Chris@337 87 k = j + blockEnd;
Chris@337 88 tr = ar[0] * ro[k] - ai[0] * io[k];
Chris@337 89 ti = ar[0] * io[k] + ai[0] * ro[k];
Chris@337 90
Chris@337 91 ro[k] = ro[j] - tr;
Chris@337 92 io[k] = io[j] - ti;
Chris@337 93
Chris@337 94 ro[j] += tr;
Chris@337 95 io[j] += ti;
Chris@337 96 }
Chris@337 97 }
Chris@337 98
Chris@337 99 blockEnd = blockSize;
Chris@337 100 }
Chris@337 101
Chris@337 102 if (inverse) {
Chris@337 103
Chris@337 104 double denom = (double)n;
Chris@337 105
Chris@337 106 for (i = 0; i < n; i++) {
Chris@337 107 ro[i] /= denom;
Chris@337 108 io[i] /= denom;
Chris@337 109 }
Chris@337 110 }
chris@340 111
chris@340 112 #ifdef _MSC_VER
chris@340 113 _freea(table);
chris@340 114 #endif
Chris@337 115 }
Chris@337 116