| 
							- #pragma once
 - 
 - #include <complex>
 - 
 - 
 - namespace rack {
 - 
 - /** Simple FFT implementation
 - If you need something fast, use pffft, KissFFT, etc instead.
 - The size N must be a power of 2
 - */
 - struct SimpleFFT {
 - 	int N;
 - 	/** Twiddle factors e^(2pi k/N), interleaved complex numbers */
 - 	std::complex<float> *tw;
 - 	SimpleFFT(int N, bool inverse) : N(N) {
 - 		tw = new std::complex<float>[N];
 - 		for (int i = 0; i < N; i++) {
 - 			float phase = 2*M_PI * (float)i / N;
 - 			if (inverse)
 - 				phase *= -1.0;
 - 			tw[i] = std::exp(std::complex<float>(0.0, phase));
 - 		}
 - 	}
 - 	~SimpleFFT() {
 - 		delete[] tw;
 - 	}
 - 	/** Reference naive implementation
 - 	x and y are arrays of interleaved complex numbers
 - 	y must be size N/s
 - 	s is the stride factor for the x array which divides the size N
 - 	*/
 - 	void dft(const std::complex<float> *x, std::complex<float> *y, int s=1) {
 - 		for (int k = 0; k < N/s; k++) {
 - 			std::complex<float> yk = 0.0;
 - 			for (int n = 0; n < N; n += s) {
 - 				int m = (n*k) % N;
 - 				yk += x[n] * tw[m];
 - 			}
 - 			y[k] = yk;
 - 		}
 - 	}
 - 	void fft(const std::complex<float> *x, std::complex<float> *y, int s=1) {
 - 		if (N/s <= 2) {
 - 			// Naive DFT is faster than further FFT recursions at this point
 - 			dft(x, y, s);
 - 			return;
 - 		}
 - 		std::complex<float> *e = new std::complex<float>[N/(2*s)]; // Even inputs
 - 		std::complex<float> *o = new std::complex<float>[N/(2*s)]; // Odd inputs
 - 		fft(x, e, 2*s);
 - 		fft(x + s, o, 2*s);
 - 		for (int k = 0; k < N/(2*s); k++) {
 - 			int m = (k*s) % N;
 - 			y[k] = e[k] + tw[m] * o[k];
 - 			y[k + N/(2*s)] = e[k] - tw[m] * o[k];
 - 		}
 - 		delete[] e;
 - 		delete[] o;
 - 	}
 - };
 - 
 - } // namespace rack
 
 
  |