annotate src/vamp-sdk/FFTimpl.cpp @ 354:e85513153c71

Initialise rate to 0. Otherwise there's a danger plugins will change the SampleType (e.g. to VariableSampleRate) but not set the rate because they don't think they need it (when in fact it needs to be set to 0)
author Chris Cannam
date Thu, 28 Mar 2013 15:49:17 +0000
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