annotate fft.cpp @ 9:a1539d4e3b08

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