File: fft.c

package info (click to toggle)
pd-fftease 3.0.1-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,112 kB
  • sloc: ansic: 14,552; makefile: 208; sh: 93; cpp: 19; perl: 9
file content (157 lines) | stat: -rw-r--r-- 3,848 bytes parent folder | download
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;
    }
}