// Fast Fourier Transform (FFT) Code
// Java implementation by: Craig A. Lindley
// Last Update: 02/27/99
/* libfft.c - fast Fourier transform library
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
package jass.generators;
public class FFT {
public static void main(String[] argv) {
int n = 4096;
int b=12;
FFT fft = new FFT(b);
double fs=44100;
double f = 292,d = 100,f2=600;
double[] y = new double[n];
double[] yim = new double[n];
double[] yf = new double[n];
for(int i=0;i<n;i++) {
y[i] = Math.sin(TWOPI*f*i/fs) * Math.exp(-d*i/fs);
yim[i] = 0;
yf[i]=0;
}
for(int i=0;i<n;i++) {
y[i] += Math.sin(TWOPI*f2*i/fs) * Math.exp(-d*i/fs);
}
fft.doFFT(y,yim,false);
for(int i=0;i<n/2;i++) {
yf[i] = 10*Math.log10(y[i]*y[i]+yim[i]*yim[i]);
double freq=i*fs/n;
System.out.println(yf[i]+" "+freq);
}
}
/**
* This is a Java implementation of the fast Fourier transform
* written by Jef Poskanzer. The copyright appears above.
*/
private static final double TWOPI = 2.0 * Math.PI;
// Limits on the number of bits this algorithm can utilize
private static final int LOG2_MAXFFTSIZE = 15;
private static final int MAXFFTSIZE = 1 << LOG2_MAXFFTSIZE;
/**
* FFT class constructor
* Initializes code for doing a fast Fourier transform
*
* @param int bits is a power of two such that 2^b is the number
* of samples.
*/
public FFT(int bits) {
this.bits = bits;
if (bits > LOG2_MAXFFTSIZE) {
System.out.println("" + bits + " is too big");
System.exit(1);
}
for (int i = (1 << bits) - 1; i >= 0; --i) {
int k = 0;
for (int j = 0; j < bits; ++j) {
k *= 2;
if ((i & (1 << j)) != 0)
k++;
}
bitreverse[i] = k;
}
}
/**
* A fast Fourier transform routine
*
* @param double [] xr is the real part of the data to be transformed
* @param double [] xi is the imaginary part of the data to be transformed
* (normally zero unless inverse transofrm is effect).
* @param boolean invFlag which is true if inverse transform is being
* applied. false for a forward transform.
*/
public void doFFT(double [] xr, double [] xi, boolean invFlag) {
int n, n2, i, k, kn2, l, p;
double ang, s, c, tr, ti;
n2 = (n = (1 << bits)) / 2;
for (l = 0; l < bits; ++l) {
for (k = 0; k < n; k += n2) {
for (i = 0; i < n2; ++i, ++k) {
p = bitreverse[k / n2];
ang = TWOPI * p / n;
c = Math.cos(ang);
s = Math.sin(ang);
kn2 = k + n2;
if (invFlag)
s = -s;
tr = xr[kn2] * c + xi[kn2] * s;
ti = xi[kn2] * c - xr[kn2] * s;
xr[kn2] = xr[k] - tr;
xi[kn2] = xi[k] - ti;
xr[k] += tr;
xi[k] += ti;
}
}
n2 /= 2;
}
for (k = 0; k < n; k++) {
if ((i = bitreverse[k]) <= k)
continue;
tr = xr[k];
ti = xi[k];
xr[k] = xr[i];
xi[k] = xi[i];
xr[i] = tr;
xi[i] = ti;
}
// Finally, multiply each value by 1/n, if this is the forward
// transform.
if (!invFlag) {
double f = 1.0 / n;
for (i = 0; i < n ; i++) {
xr[i] *= f;
xi[i] *= f;
}
}
}
// Private class data
public int bits;
private int [] bitreverse = new int[MAXFFTSIZE];
}