/* 
 * fft.c -- Fast Fourier Transform code
 * 
 */


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "fft.h"

#define PI 3.141592653589793
#define XCHG(a,b) wtemp=(a);(a)=(b);(b)=wtemp

void fft(struct cnum data[], int nn, int isign) {
  int n, mmax = 0, m, j, istep, i, mtmp;
  double wtemp, theta;
  double br;
  struct cnum twiddle;
  struct cnum phase;
  struct cnum temp;	 /*temporary value*/

	/*bit reversal*/
	n = nn;
	mtmp = nn>>1;
	j=0;
	for (i=0;i<n;i++) {
	   if (j > i) {		  /*swap the complex numbers*/
			wtemp=data[j].real;
			data[j].real=data[i].real;
			data[i].real=wtemp;
			wtemp=data[j].imag;
			data[j].imag=data[i].imag;
			data[i].imag=wtemp;
	   }
  		m=mtmp;
		while (j >= m && m > 0) {
			j -= m;
			m >>= 1;
	   		}
		j += m;
	}

	/*butterflies*/
	mmax = 1;
	while (n > mmax) {
	   istep=2*mmax;
	   theta=6.28318530717959/(isign*istep);  /*isign determines forward*/
	   phase.real = cos(theta);
	   phase.imag = sin(theta);
	   twiddle.real=1.0;
	   twiddle.imag=0.0;
	   for (m=0;m<mmax;m++) {
		  for (i=m;i<n;i+=istep) {
			 j=i+mmax;								/*actual butterfly*/
			 temp.real=twiddle.real*data[j].real-twiddle.imag*data[j].imag;
			 temp.imag=twiddle.real*data[j].imag+twiddle.imag*data[j].real;
			 data[j].real=data[i].real-temp.real;
			 data[j].imag=data[i].imag-temp.imag;
			 data[i].real += temp.real;
			 data[i].imag += temp.imag;
		  }											/*calculate new twiddle*/
		  twiddle.real=(wtemp=twiddle.real)*phase.real-twiddle.imag*phase.imag;
		  twiddle.imag=twiddle.imag*phase.real+wtemp*phase.imag;
	   }
		mmax = istep;
	}

	if (isign < 0) 
          return;	

	br = 1.0/n;	/*Bracewell scaling factor*/
	for (i = 0; i < n; i++) {
		data[i].real *= br;
		data[i].imag *= br;
	}
}


