1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
29 // authors: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // FFT: CARL music distribution
33 //-----------------------------------------------------------------------------
34 #include "util_xforms.h"
41 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
45 void hanning( float * window
, unsigned long length
)
48 double pi
, phase
= 0, delta
;
51 delta
= 2 * pi
/ (double) length
;
53 for( i
= 0; i
< length
; i
++ )
55 window
[i
] = (float)(0.5 * (1.0 - cos(phase
)));
63 //-----------------------------------------------------------------------------
66 //-----------------------------------------------------------------------------
67 void hamming( float * window
, unsigned long length
)
70 double pi
, phase
= 0, delta
;
73 delta
= 2 * pi
/ (double) length
;
75 for( i
= 0; i
< length
; i
++ )
77 window
[i
] = (float)(0.54 - .46*cos(phase
));
84 //-----------------------------------------------------------------------------
87 //-----------------------------------------------------------------------------
88 void blackman( float * window
, unsigned long length
)
91 double pi
, phase
= 0, delta
;
94 delta
= 2 * pi
/ (double) length
;
96 for( i
= 0; i
< length
; i
++ )
98 window
[i
] = (float)(0.42 - .5*cos(phase
) + .08*cos(2*phase
));
106 //-----------------------------------------------------------------------------
107 // name: apply_window()
108 // desc: apply a window to data
109 //-----------------------------------------------------------------------------
110 void apply_window( float * data
, float * window
, unsigned long length
)
114 for( i
= 0; i
< length
; i
++ )
115 data
[i
] *= window
[i
];
120 void bit_reverse( float * x
, long N
);
122 //-----------------------------------------------------------------------------
124 // desc: real value fft
126 // these routines from the CARL software, spect.c
127 // check out the CARL CMusic distribution for more source code
129 // if forward is true, rfft replaces 2*N real data points in x with N complex
130 // values representing the positive frequency half of their Fourier spectrum,
131 // with x[1] replaced with the real part of the Nyquist frequency value.
133 // if forward is false, rfft expects x to contain a positive frequency
134 // spectrum arranged as before, and replaces it with 2*N real values.
136 // N MUST be a power of 2.
138 //-----------------------------------------------------------------------------
139 void rfft( float * x
, long N
, unsigned int forward
)
141 static int first
= 1 ;
142 float c1
, c2
, h1r
, h1i
, h2r
, h2i
, wr
, wi
, wpr
, wpi
, temp
, theta
;
144 long i
, i1
, i2
, i3
, i4
, N2p1
;
148 PI
= (float) (4.*atan( 1. )) ;
149 TWOPI
= (float) (8.*atan( 1. )) ;
161 cfft( x
, N
, forward
) ;
174 wpr
= (float) (-2.*pow( sin( 0.5*theta
), 2. )) ;
175 wpi
= (float) sin( theta
) ;
178 for( i
= 0 ; i
<= N
>>1 ; i
++ )
186 h1r
= c1
*(x
[i1
] + xr
) ;
187 h1i
= c1
*(x
[i2
] - xi
) ;
188 h2r
= -c2
*(x
[i2
] + xi
) ;
189 h2i
= c2
*(x
[i1
] - xr
) ;
190 x
[i1
] = h1r
+ wr
*h2r
- wi
*h2i
;
191 x
[i2
] = h1i
+ wr
*h2i
+ wi
*h2r
;
192 xr
= h1r
- wr
*h2r
+ wi
*h2i
;
193 xi
= -h1i
+ wr
*h2i
+ wi
*h2r
;
197 h1r
= c1
*(x
[i1
] + x
[i3
] ) ;
198 h1i
= c1
*(x
[i2
] - x
[i4
] ) ;
199 h2r
= -c2
*(x
[i2
] + x
[i4
] ) ;
200 h2i
= c2
*(x
[i1
] - x
[i3
] ) ;
201 x
[i1
] = h1r
+ wr
*h2r
- wi
*h2i
;
202 x
[i2
] = h1i
+ wr
*h2i
+ wi
*h2r
;
203 x
[i3
] = h1r
- wr
*h2r
+ wi
*h2i
;
204 x
[i4
] = -h1i
+ wr
*h2i
+ wi
*h2r
;
207 wr
= (temp
= wr
)*wpr
- wi
*wpi
+ wr
;
208 wi
= wi
*wpr
+ temp
*wpi
+ wi
;
214 cfft( x
, N
, forward
) ;
220 //-----------------------------------------------------------------------------
222 // desc: complex value fft
224 // these routines from CARL software, spect.c
225 // check out the CARL CMusic distribution for more software
227 // cfft replaces float array x containing NC complex values (2*NC float
228 // values alternating real, imagininary, etc.) by its Fourier transform
229 // if forward is true, or by its inverse Fourier transform ifforward is
230 // false, using a recursive Fast Fourier transform method due to
231 // Danielson and Lanczos.
233 // NC MUST be a power of 2.
235 //-----------------------------------------------------------------------------
236 void cfft( float * x
, long NC
, unsigned int forward
)
238 float wr
, wi
, wpr
, wpi
, theta
, scale
;
239 long mmax
, ND
, m
, i
, j
, delta
;
241 bit_reverse( x
, ND
) ;
243 for( mmax
= 2 ; mmax
< ND
; mmax
= delta
)
246 theta
= TWOPI
/( forward
? mmax
: -mmax
) ;
247 wpr
= (float) (-2.*pow( sin( 0.5*theta
), 2. )) ;
248 wpi
= (float) sin( theta
) ;
252 for( m
= 0 ; m
< mmax
; m
+= 2 )
254 register float rtemp
, itemp
;
255 for( i
= m
; i
< ND
; i
+= delta
)
258 rtemp
= wr
*x
[j
] - wi
*x
[j
+1] ;
259 itemp
= wr
*x
[j
+1] + wi
*x
[j
] ;
260 x
[j
] = x
[i
] - rtemp
;
261 x
[j
+1] = x
[i
+1] - itemp
;
266 wr
= (rtemp
= wr
)*wpr
- wi
*wpi
+ wr
;
267 wi
= wi
*wpr
+ rtemp
*wpi
+ wi
;
272 scale
= (float)(forward
? 1./ND
: 2.) ;
274 register float *xi
=x
, *xe
=x
+ND
;
283 //-----------------------------------------------------------------------------
284 // name: bit_reverse()
285 // desc: bitreverse places float array x containing N/2 complex values
286 // into bit-reversed order
287 //-----------------------------------------------------------------------------
288 void bit_reverse( float * x
, long N
)
292 for( i
= j
= 0 ; i
< N
; i
+= 2, j
+= m
)
296 rtemp
= x
[j
] ; itemp
= x
[j
+1] ; /* complex exchange */
297 x
[j
] = x
[i
] ; x
[j
+1] = x
[i
+1] ;
298 x
[i
] = rtemp
; x
[i
+1] = itemp
;
301 for( m
= N
>>1 ; m
>= 2 && j
>= m
; m
>>= 1 )