annotate fft.cpp @ 19:0cdedb2fab81 tip

* OS/X build fixes
author Chris Cannam
date Fri, 18 Jun 2010 11:18:49 +0100
parents 1e6360396b6c
children
rev   line source
Chris@9 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@9 2
Chris@13 3 #define _USE_MATH_DEFINES
Chris@13 4 #include <cmath>
Chris@13 5
Chris@9 6 #ifdef VST
Chris@9 7 #include "devuvuzelator-vst.h"
Chris@9 8 #else
Chris@9 9 #ifdef LADSPA
Chris@9 10 #include "devuvuzelator-ladspa.h"
Chris@9 11 #else
Chris@9 12 #error Need to define either VST or LADSPA
Chris@9 13 #endif
Chris@9 14 #endif
Chris@9 15
Chris@9 16 // FFT implementation by Don Cross, public domain.
Chris@9 17 // This version scales the forward transform.
Chris@9 18
Chris@9 19 void Devuvuzelator::fft(unsigned int n, bool inverse,
Chris@9 20 double *ri, double *ii, double *ro, double *io)
Chris@9 21 {
Chris@9 22 if (!ri || !ro || !io) return;
Chris@9 23
Chris@9 24 unsigned int bits;
Chris@9 25 unsigned int i, j, k, m;
Chris@9 26 unsigned int blockSize, blockEnd;
Chris@9 27
Chris@9 28 double tr, ti;
Chris@9 29
Chris@9 30 if (n < 2) return;
Chris@9 31 if (n & (n-1)) return;
Chris@9 32
Chris@9 33 double angle = 2.0 * M_PI;
Chris@9 34 if (inverse) angle = -angle;
Chris@9 35
Chris@9 36 for (i = 0; ; ++i) {
Chris@9 37 if (n & (1 << i)) {
Chris@9 38 bits = i;
Chris@9 39 break;
Chris@9 40 }
Chris@9 41 }
Chris@9 42
Chris@9 43 static unsigned int tableSize = 0;
Chris@9 44 static int *table = 0;
Chris@9 45
Chris@9 46 if (tableSize != n) {
Chris@9 47
Chris@9 48 delete[] table;
Chris@9 49
Chris@9 50 table = new int[n];
Chris@9 51
Chris@9 52 for (i = 0; i < n; ++i) {
Chris@9 53
Chris@9 54 m = i;
Chris@9 55
Chris@9 56 for (j = k = 0; j < bits; ++j) {
Chris@9 57 k = (k << 1) | (m & 1);
Chris@9 58 m >>= 1;
Chris@9 59 }
Chris@9 60
Chris@9 61 table[i] = k;
Chris@9 62 }
Chris@9 63
Chris@9 64 tableSize = n;
Chris@9 65 }
Chris@9 66
Chris@9 67 if (ii) {
Chris@9 68 for (i = 0; i < n; ++i) {
Chris@9 69 ro[table[i]] = ri[i];
Chris@9 70 io[table[i]] = ii[i];
Chris@9 71 }
Chris@9 72 } else {
Chris@9 73 for (i = 0; i < n; ++i) {
Chris@9 74 ro[table[i]] = ri[i];
Chris@9 75 io[table[i]] = 0.0;
Chris@9 76 }
Chris@9 77 }
Chris@9 78
Chris@9 79 blockEnd = 1;
Chris@9 80
Chris@9 81 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
Chris@9 82
Chris@9 83 double delta = angle / (double)blockSize;
Chris@9 84 double sm2 = -sin(-2 * delta);
Chris@9 85 double sm1 = -sin(-delta);
Chris@9 86 double cm2 = cos(-2 * delta);
Chris@9 87 double cm1 = cos(-delta);
Chris@9 88 double w = 2 * cm1;
Chris@9 89 double ar[3], ai[3];
Chris@9 90
Chris@9 91 for (i = 0; i < n; i += blockSize) {
Chris@9 92
Chris@9 93 ar[2] = cm2;
Chris@9 94 ar[1] = cm1;
Chris@9 95
Chris@9 96 ai[2] = sm2;
Chris@9 97 ai[1] = sm1;
Chris@9 98
Chris@9 99 for (j = i, m = 0; m < blockEnd; j++, m++) {
Chris@9 100
Chris@9 101 ar[0] = w * ar[1] - ar[2];
Chris@9 102 ar[2] = ar[1];
Chris@9 103 ar[1] = ar[0];
Chris@9 104
Chris@9 105 ai[0] = w * ai[1] - ai[2];
Chris@9 106 ai[2] = ai[1];
Chris@9 107 ai[1] = ai[0];
Chris@9 108
Chris@9 109 k = j + blockEnd;
Chris@9 110 tr = ar[0] * ro[k] - ai[0] * io[k];
Chris@9 111 ti = ar[0] * io[k] + ai[0] * ro[k];
Chris@9 112
Chris@9 113 ro[k] = ro[j] - tr;
Chris@9 114 io[k] = io[j] - ti;
Chris@9 115
Chris@9 116 ro[j] += tr;
Chris@9 117 io[j] += ti;
Chris@9 118 }
Chris@9 119 }
Chris@9 120
Chris@9 121 blockEnd = blockSize;
Chris@9 122 }
Chris@9 123
Chris@9 124 if (!inverse) {
Chris@9 125
Chris@9 126 double denom = (double)n;
Chris@9 127
Chris@9 128 for (i = 0; i < n; i++) {
Chris@9 129 ro[i] /= denom;
Chris@9 130 io[i] /= denom;
Chris@9 131 }
Chris@9 132 }
Chris@9 133 }
Chris@9 134