1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#include "fftease.h"
/* If forward is true, rfft replaces 2*N real data points in x with
N complex values representing the positive frequency half of their
Fourier spectrum, with x[1] replaced with the real part of the Nyquist
frequency value. If forward is false, rfft expects x to contain a
positive frequency spectrum arranged as before, and replaces it with
2*N real values. N MUST be a power of 2. */
void fftease_rfft( t_float *x, int N, int forward )
{
t_float c1,c2,
h1r,h1i,
h2r,h2i,
wr,wi,
wpr,wpi,
temp,
theta;
t_float xr,xi;
int i,
i1,i2,i3,i4,
N2p1;
static int first = 1;
/*t_float PI, TWOPI;*/
if ( first ) {
first = 0;
}
theta = PI/N;
wr = 1.;
wi = 0.;
c1 = 0.5;
if ( forward ) {
c2 = -0.5;
fftease_cfft( x, N, forward );
xr = x[0];
xi = x[1];
} else {
c2 = 0.5;
theta = -theta;
xr = x[1];
xi = 0.;
x[1] = 0.;
}
wpr = -2.*pow( sin( 0.5*theta ), 2. );
wpi = sin( theta );
N2p1 = (N<<1) + 1;
for ( i = 0; i <= N>>1; i++ ) {
i1 = i<<1;
i2 = i1 + 1;
i3 = N2p1 - i2;
i4 = i3 + 1;
if ( i == 0 ) {
h1r = c1*(x[i1] + xr );
h1i = c1*(x[i2] - xi );
h2r = -c2*(x[i2] + xi );
h2i = c2*(x[i1] - xr );
x[i1] = h1r + wr*h2r - wi*h2i;
x[i2] = h1i + wr*h2i + wi*h2r;
xr = h1r - wr*h2r + wi*h2i;
xi = -h1i + wr*h2i + wi*h2r;
} else {
h1r = c1*(x[i1] + x[i3] );
h1i = c1*(x[i2] - x[i4] );
h2r = -c2*(x[i2] + x[i4] );
h2i = c2*(x[i1] - x[i3] );
x[i1] = h1r + wr*h2r - wi*h2i;
x[i2] = h1i + wr*h2i + wi*h2r;
x[i3] = h1r - wr*h2r + wi*h2i;
x[i4] = -h1i + wr*h2i + wi*h2r;
}
wr = (temp = wr)*wpr - wi*wpi + wr;
wi = wi*wpr + temp*wpi + wi;
}
if ( forward )
x[1] = xr;
else
fftease_cfft( x, N, forward );
}
/* cfft replaces t_float array x containing NC complex values
(2*NC t_float values alternating real, imagininary, etc.)
by its Fourier transform if forward is true, or by its
inverse Fourier transform if forward is false, using a
recursive Fast Fourier transform method due to Danielson
and Lanczos. NC MUST be a power of 2. */
void fftease_cfft( t_float *x, int NC, int forward )
{
t_float wr,wi,
wpr,wpi,
theta,
scale;
int mmax,
ND,
m,
i,j,
delta;
ND = NC<<1;
fftease_bitreverse( x, ND );
for ( mmax = 2; mmax < ND; mmax = delta ) {
delta = mmax<<1;
theta = TWOPI/( forward? mmax : -mmax );
wpr = -2.*pow( sin( 0.5*theta ), 2. );
wpi = sin( theta );
wr = 1.;
wi = 0.;
for ( m = 0; m < mmax; m += 2 ) {
register t_float rtemp, itemp;
for ( i = m; i < ND; i += delta ) {
j = i + mmax;
rtemp = wr*x[j] - wi*x[j+1];
itemp = wr*x[j+1] + wi*x[j];
x[j] = x[i] - rtemp;
x[j+1] = x[i+1] - itemp;
x[i] += rtemp;
x[i+1] += itemp;
}
wr = (rtemp = wr)*wpr - wi*wpi + wr;
wi = wi*wpr + rtemp*wpi + wi;
}
}
/* scale output */
scale = forward ? 1./ND : 2.;
{ register t_float *xi=x, *xe=x+ND;
while ( xi < xe )
*xi++ *= scale;
}
}
/* bitreverse places t_float array x containing N/2 complex values
into bit-reversed order */
void fftease_bitreverse( t_float *x, int N )
{
t_float rtemp,itemp;
int i,j,
m;
for ( i = j = 0; i < N; i += 2, j += m ) {
if ( j > i ) {
rtemp = x[j]; itemp = x[j+1]; /* complex exchange */
x[j] = x[i]; x[j+1] = x[i+1];
x[i] = rtemp; x[i+1] = itemp;
}
for ( m = N>>1; m >= 2 && j >= m; m >>= 1 )
j -= m;
}
}
|