41

I was looking for a FFT implementation in C. However, I am not looking for a huge library (like FFTW) but for a easy to use single C-file implementation. Unfortunately I haven't been able to find anything like this.

Can someone recommend a simple implementation?

Chris
  • 44,602
  • 16
  • 137
  • 156
mijc
  • 1,189
  • 3
  • 9
  • 16
  • Try [searching for 'fft' on github](https://github.com/search?langOverride=c&q=fft&repo=&start_value=1&type=Repositories). But what's not easy to use about FFTW? Do you mean easy to understand the source? – Rup Jan 10 '12 at 09:48
  • 11
    Write your own. It'll be a good exercise. The internet is full of explanations of how to calculate DFT and FFT. Use that. – Alexey Frunze Jan 10 '12 at 09:54
  • 2
    The FFT routines [here](http://www.fit.vutbr.cz/research/prod/?id=510) have less than a hundred lines of code. The library implements forward and inverse fast Fourier transform (FFT) algorithms using both decimation in time (DIT) and decimation in frequency (DIF). – DaBler Feb 03 '17 at 11:19
  • @DaBler That's exactly what I was searching for! thank you! – gkpln3 Oct 28 '19 at 14:04

4 Answers4

35

Your best bet is KissFFT - as its name implies it's simple, but it's still quite respectably fast, and a lot more lightweight than FFTW. It's also free, wheras FFTW requires a hefty licence fee if you want to include it in a commercial product.

Paul R
  • 208,748
  • 37
  • 389
  • 560
29

This file works properly as it is: just copy and paste in your computer. Surfing on the web I have found this easy implementation on wikipedia page here. The page is in italian, so I re-wrote the code with some translations. Here there are almost the same informations but in english. ENJOY!

#include <iostream>
#include <complex>
#define MAX 200

using namespace std;

#define M_PI 3.1415926535897932384

int log2(int N)    /*function to calculate the log2(.) of int numbers*/
{
  int k = N, i = 0;
  while(k) {
    k >>= 1;
    i++;
  }
  return i - 1;
}

int check(int n)    //checking if the number of element is a power of 2
{
  return n > 0 && (n & (n - 1)) == 0;
}

int reverse(int N, int n)    //calculating revers number
{
  int j, p = 0;
  for(j = 1; j <= log2(N); j++) {
    if(n & (1 << (log2(N) - j)))
      p |= 1 << (j - 1);
  }
  return p;
}

void ordina(complex<double>* f1, int N) //using the reverse order in the array
{
  complex<double> f2[MAX];
  for(int i = 0; i < N; i++)
    f2[i] = f1[reverse(N, i)];
  for(int j = 0; j < N; j++)
    f1[j] = f2[j];
}

void transform(complex<double>* f, int N) //
{
  ordina(f, N);    //first: reverse order
  complex<double> *W;
  W = (complex<double> *)malloc(N / 2 * sizeof(complex<double>));
  W[1] = polar(1., -2. * M_PI / N);
  W[0] = 1;
  for(int i = 2; i < N / 2; i++)
    W[i] = pow(W[1], i);
  int n = 1;
  int a = N / 2;
  for(int j = 0; j < log2(N); j++) {
    for(int i = 0; i < N; i++) {
      if(!(i & n)) {
        complex<double> temp = f[i];
        complex<double> Temp = W[(i * a) % (n * a)] * f[i + n];
        f[i] = temp + Temp;
        f[i + n] = temp - Temp;
      }
    }
    n *= 2;
    a = a / 2;
  }
  free(W);
}

void FFT(complex<double>* f, int N, double d)
{
  transform(f, N);
  for(int i = 0; i < N; i++)
    f[i] *= d; //multiplying by step
}

int main()
{
  int n;
  do {
    cout << "specify array dimension (MUST be power of 2)" << endl;
    cin >> n;
  } while(!check(n));
  double d;
  cout << "specify sampling step" << endl; //just write 1 in order to have the same results of matlab fft(.)
  cin >> d;
  complex<double> vec[MAX];
  cout << "specify the array" << endl;
  for(int i = 0; i < n; i++) {
    cout << "specify element number: " << i << endl;
    cin >> vec[i];
  }
  FFT(vec, n, d);
  cout << "...printing the FFT of the array specified" << endl;
  for(int j = 0; j < n; j++)
    cout << vec[j] << endl;
  return 0;
}
Leos313
  • 5,152
  • 6
  • 40
  • 69
  • 4
    This works surprisingly well. Not the most efficient code in the world, but it definitely does work! – Andy Piper Sep 27 '19 at 09:27
  • 1
    could you please explain your code a bit? especially the `reverse()` function. i am trying to implement a fourier transform in C for my arduino project. – hammi Sep 29 '21 at 18:38
8

Here is a permissively-licensed C library with a variety of different FFT implementations, each of which is in its own self-contained C-file.

Connor McKay
  • 580
  • 7
  • 13
7

You could start converting this java snippet to C the author states he has converted it from C based on the book numerical recipies which you find online! here

stacker
  • 68,052
  • 28
  • 140
  • 210
  • Not sure about copyrights but you can find C code in github. e.g. https://github.com/honzatomek/numerical_recipes_3_py/tree/master/res – alex Sep 14 '21 at 14:32