-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFft.cpp
160 lines (147 loc) · 4.12 KB
/
Fft.cpp
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
158
159
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include "fft.h"
float PI ;
float TWOPI ;
/*
* 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 rfft( float *x, long N, int forward )
{
float c1, c2, h1r, h1i, h2r, h2i, wr, wi, wpr, wpi, temp, theta ;
float xr, xi ;
long i, i1, i2, i3, i4, N2p1 ;
static int first = 1 ;
if ( first )
{
PI = (float) (4.*atan( 1. )) ;
TWOPI = (float) (8.*atan( 1. )) ;
first = 0 ;
}
theta = PI/N ;
wr = 1. ;
wi = 0. ;
c1 = 0.5 ;
if ( forward )
{
c2 = -0.5 ;
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 = (float) (-2.*pow( sin( 0.5*theta ), 2. )) ;
wpi = (float) 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
cfft( x, N, forward ) ;
}
/*
* cfft replaces float array x containing NC complex values
* (2*NC 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 cfft( float *x, long NC, int forward )
{
float wr, wi, wpr, wpi, theta, scale ;
long mmax, ND, m, i, j, delta ;
ND = NC<<1 ;
bitreverse( x, ND ) ;
for ( mmax = 2 ; mmax < ND ; mmax = delta )
{
delta = mmax<<1 ;
theta = TWOPI/( forward? mmax : -mmax ) ;
wpr = (float) (-2.*pow( sin( 0.5*theta ), 2. )) ;
wpi = (float) sin( theta ) ;
wr = 1. ;
wi = 0. ;
for ( m = 0 ; m < mmax ; m += 2 )
{
register 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 ? 6./ND : 2. ; // scale = forward ? 1./ND : 2. ;
{ //6.0 is the optimized value fot Cool Edit FFT view
register float *xi=x, *xe=x+ND ;
while ( xi < xe )
*xi++ *= scale ;
}
}
/*
* bitreverse places float array x containing N/2 complex values
* into bit-reversed order
*/
void bitreverse( float *x, long N )
{
float rtemp, itemp ;
long 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 ;
}
}