annotate fft/cross/Cross.c @ 40:223f770b5341 kissfft-double tip

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