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
));
85 //-----------------------------------------------------------------------------
88 //-----------------------------------------------------------------------------
89 void blackman( FLOAT
* window
, unsigned long length
)
92 double pi
, phase
= 0, delta
;
95 delta
= 2 * pi
/ (double) length
;
97 for( i
= 0; i
< length
; i
++ )
99 window
[i
] = (FLOAT
)(0.42 - .5*cos(phase
) + .08*cos(2*phase
));
107 //-----------------------------------------------------------------------------
110 //-----------------------------------------------------------------------------
111 void bartlett( FLOAT
* window
, unsigned long length
)
114 FLOAT half
= (FLOAT
)length
/ 2;
116 for( i
= 0; i
< length
; i
++ )
118 if( i
< half
) window
[i
] = i
/ half
;
119 else window
[i
] = (length
- i
) / half
;
126 //-----------------------------------------------------------------------------
127 // name: apply_window()
128 // desc: apply a window to data
129 //-----------------------------------------------------------------------------
130 void apply_window( FLOAT
* data
, FLOAT
* window
, unsigned long length
)
134 for( i
= 0; i
< length
; i
++ )
135 data
[i
] *= window
[i
];
140 void bit_reverse( FLOAT
* x
, long N
);
142 //-----------------------------------------------------------------------------
144 // desc: real value fft
146 // these routines from the CARL software, spect.c
147 // check out the CARL CMusic distribution for more source code
149 // if forward is true, rfft replaces 2*N real data points in x with N complex
150 // values representing the positive frequency half of their Fourier spectrum,
151 // with x[1] replaced with the real part of the Nyquist frequency value.
153 // if forward is false, rfft expects x to contain a positive frequency
154 // spectrum arranged as before, and replaces it with 2*N real values.
156 // N MUST be a power of 2.
158 //-----------------------------------------------------------------------------
159 void rfft( FLOAT
* x
, long N
, unsigned int forward
)
161 static int first
= 1 ;
162 FLOAT c1
, c2
, h1r
, h1i
, h2r
, h2i
, wr
, wi
, wpr
, wpi
, temp
, theta
;
164 long i
, i1
, i2
, i3
, i4
, N2p1
;
168 PI
= (FLOAT
) (4.*atan( 1. )) ;
169 TWOPI
= (FLOAT
) (8.*atan( 1. )) ;
181 cfft( x
, N
, forward
) ;
194 wpr
= (FLOAT
) (-2.*pow( sin( 0.5*theta
), 2. )) ;
195 wpi
= (FLOAT
) sin( theta
) ;
198 for( i
= 0 ; i
<= N
>>1 ; i
++ )
206 h1r
= c1
*(x
[i1
] + xr
) ;
207 h1i
= c1
*(x
[i2
] - xi
) ;
208 h2r
= -c2
*(x
[i2
] + xi
) ;
209 h2i
= c2
*(x
[i1
] - xr
) ;
210 x
[i1
] = h1r
+ wr
*h2r
- wi
*h2i
;
211 x
[i2
] = h1i
+ wr
*h2i
+ wi
*h2r
;
212 xr
= h1r
- wr
*h2r
+ wi
*h2i
;
213 xi
= -h1i
+ wr
*h2i
+ wi
*h2r
;
217 h1r
= c1
*(x
[i1
] + x
[i3
] ) ;
218 h1i
= c1
*(x
[i2
] - x
[i4
] ) ;
219 h2r
= -c2
*(x
[i2
] + x
[i4
] ) ;
220 h2i
= c2
*(x
[i1
] - x
[i3
] ) ;
221 x
[i1
] = h1r
+ wr
*h2r
- wi
*h2i
;
222 x
[i2
] = h1i
+ wr
*h2i
+ wi
*h2r
;
223 x
[i3
] = h1r
- wr
*h2r
+ wi
*h2i
;
224 x
[i4
] = -h1i
+ wr
*h2i
+ wi
*h2r
;
227 wr
= (temp
= wr
)*wpr
- wi
*wpi
+ wr
;
228 wi
= wi
*wpr
+ temp
*wpi
+ wi
;
234 cfft( x
, N
, forward
) ;
240 //-----------------------------------------------------------------------------
242 // desc: complex value fft
244 // these routines from CARL software, spect.c
245 // check out the CARL CMusic distribution for more software
247 // cfft replaces FLOAT array x containing NC complex values (2*NC FLOAT
248 // values alternating real, imagininary, etc.) by its Fourier transform
249 // if forward is true, or by its inverse Fourier transform ifforward is
250 // false, using a recursive Fast Fourier transform method due to
251 // Danielson and Lanczos.
253 // NC MUST be a power of 2.
255 //-----------------------------------------------------------------------------
256 void cfft( FLOAT
* x
, long NC
, unsigned int forward
)
258 FLOAT wr
, wi
, wpr
, wpi
, theta
, scale
;
259 long mmax
, ND
, m
, i
, j
, delta
;
261 bit_reverse( x
, ND
) ;
263 for( mmax
= 2 ; mmax
< ND
; mmax
= delta
)
266 theta
= TWOPI
/( forward
? mmax
: -mmax
) ;
267 wpr
= (FLOAT
) (-2.*pow( sin( 0.5*theta
), 2. )) ;
268 wpi
= (FLOAT
) sin( theta
) ;
272 for( m
= 0 ; m
< mmax
; m
+= 2 )
274 register FLOAT rtemp
, itemp
;
275 for( i
= m
; i
< ND
; i
+= delta
)
278 rtemp
= wr
*x
[j
] - wi
*x
[j
+1] ;
279 itemp
= wr
*x
[j
+1] + wi
*x
[j
] ;
280 x
[j
] = x
[i
] - rtemp
;
281 x
[j
+1] = x
[i
+1] - itemp
;
286 wr
= (rtemp
= wr
)*wpr
- wi
*wpi
+ wr
;
287 wi
= wi
*wpr
+ rtemp
*wpi
+ wi
;
292 scale
= (FLOAT
)(forward
? 1./ND
: 2.) ;
294 register FLOAT
*xi
=x
, *xe
=x
+ND
;
303 //-----------------------------------------------------------------------------
304 // name: bit_reverse()
305 // desc: bitreverse places FLOAT array x containing N/2 complex values
306 // into bit-reversed order
307 //-----------------------------------------------------------------------------
308 void bit_reverse( FLOAT
* x
, long N
)
312 for( i
= j
= 0 ; i
< N
; i
+= 2, j
+= m
)
316 rtemp
= x
[j
] ; itemp
= x
[j
+1] ; /* complex exchange */
317 x
[j
] = x
[i
] ; x
[j
+1] = x
[i
+1] ;
318 x
[i
] = rtemp
; x
[i
+1] = itemp
;
321 for( m
= N
>>1 ; m
>= 2 && j
>= m
; m
>>= 1 )
329 //-----------------------------------------------------------------------------
331 // desc: type ii dct on N reals
332 //-----------------------------------------------------------------------------
333 void the_dct( FLOAT
* x
, unsigned long N
, FLOAT
* out
, unsigned long Nout
)
340 memset( out
, 0, sizeof(FLOAT
)*Nout
);
343 for( k
= 0; k
< Nout
; k
++ )
345 for( n
= 0; n
< N
; n
++ )
347 out
[k
] += x
[n
] * cos( ONE_PI
/ N
* k
* (n
+ .5) );
356 //-----------------------------------------------------------------------------
357 // name: the_dct_matrix()
358 // desc: type ii dct matrx on N reals
359 //-----------------------------------------------------------------------------
360 void the_dct_matrix( FLOAT
** out
, unsigned long N
)
365 for( k
= 0; k
< N
; k
++ )
367 for( n
= 0; n
< N
; n
++ )
369 out
[k
][n
] = cos( ONE_PI
/ N
* k
* (n
+ .5) );
375 //-----------------------------------------------------------------------------
376 // name: the_dct_now()
377 // desc: apply dct matrx on N reals
378 //-----------------------------------------------------------------------------
379 void the_dct_now( FLOAT
* x
, FLOAT
** matrix
, unsigned long N
,
380 FLOAT
* out
, unsigned long Nout
)
387 memset( out
, 0, sizeof(FLOAT
)*Nout
);
390 for( k
= 0; k
< Nout
; k
++ )
392 for( n
= 0; n
< N
; n
++ )
394 out
[k
] = x
[n
] * matrix
[k
][n
];
402 //-----------------------------------------------------------------------------
403 // name: the_inverse_dct()
404 // desc: type iii dct, or inverse dct
405 //-----------------------------------------------------------------------------
406 void the_inverse_dct( FLOAT
* x
, unsigned long N
, FLOAT
* out
, unsigned long Nout
)
411 //-----------------------------------------------------------------------------
412 // name: the_inverse_dct_matrix()
413 // desc: generates the NxN DCT matrix
414 //-----------------------------------------------------------------------------
415 void the_inverse_dct_matrix( FLOAT
** out
, unsigned long N
)
420 for( k
= 0; k
< N
; k
++ )
422 for( n
= 0; n
< N
; n
++ )
424 out
[k
][n
] = cos( ONE_PI
/ N
* n
* (k
+ .5) );
432 //-----------------------------------------------------------------------------
433 // name: the_inverse_dct_now()
434 // desc: apply inverse dct matrx on N reals
435 //-----------------------------------------------------------------------------
436 void the_inverse_dct_now( FLOAT
* x
, FLOAT
** matrix
, unsigned long N
,
437 FLOAT
* out
, unsigned long Nout
)
444 memset( out
, 0, sizeof(FLOAT
)*Nout
);
447 for( k
= 0; k
< Nout
; k
++ )
449 for( n
= 0; n
< N
; n
++ )
451 out
[k
] = x
[0] / 2 + x
[n
] * matrix
[k
][n
];