title:Naive FFT implementation in C keywords:c,linux,fir,dsp,octave,fft # Naive FFT implementation in C ## Intro Time to implement DFT/FFT by myself. Just followed Ifeachor book on theory part and IOWA FFT source on implementation side. ## Implementation ### DFT Formula for most simple Discreate Fourier Transformation. Also most slowest one. Official DFT formula $$X(k) = F_{D}[x(nT)] = $$ $$ \sum_{n=0}^{N-1} x(nT) e^{-jk\omega nT} , k=0,1,...,N-1 $$ My wording of DFT algorithm: Go over data array and sumup multiplication of each "frequency" $$e^{-jk\omega nT}$$ over data array $$x(nT)$$ ```c void dft(double *x_i, double *x_q, int n, int inv) { double Wn,Wk; double *Xi, *Xq; double c,s; int i,j; Xi = malloc(n*sizeof(double)); Xq = malloc(n*sizeof(double)); Wn = 2*M_PI/n; if (inv==1) { Wn=-Wn; } for (i=0;i>1; int Nm1 = n-1; int i,j; for (i = 0, j = 0; i < n; i++) { if (j > i) { double tmp_r = x_i[i]; double tmp_i = x_q[i]; //data[i] = data[j]; x_i[i] = x_q[j]; x_q[i] = x_q[j]; //data[j] = tmp; x_i[j] = tmp_r; x_q[j] = tmp_i; } /* * Find least significant zero bit */ unsigned lszb = ~i & (i + 1); /* * Use division to bit-reverse the single bit so that we now have * the most significant zero bit * * N = 2^r = 2^(m+1) * Nd2 = N/2 = 2^m * if lszb = 2^k, where k is within the range of 0...m, then * mszb = Nd2 / lszb * = 2^m / 2^k * = 2^(m-k) * = bit-reversed value of lszb */ unsigned mszb = Nd2 / lszb; /* * Toggle bits with bit-reverse mask */ unsigned bits = Nm1 & ~(mszb - 1); j ^= bits; } } ``` #### FFT Implementation ```c void fft_1(double *x_i, double *x_q, uint64_t n, uint64_t inv) { uint64_t n_log2; uint64_t r; uint64_t m, md2; uint64_t i,j,k; uint64_t i_e, i_o; double theta_2pi; double theta; double Wm_r, Wm_i, Wmk_r, Wmk_i; double u_r, u_i, t_r, t_i; //find log of n i=n; n_log2 = 0; while (i>1) { i=i/2; n_log2+=1; } if (inv==1) { theta_2pi = -2*M_PI; } else { theta_2pi = 2*M_PI; } for (i=1; i<= n_log2; i++) { m = 1 << i; md2 = m >> 1; theta = theta_2pi / m; Wm_r = cos(theta); Wm_i = sin(theta); for (j=0; j1 1 0 Input Q: Output I: Output Q: ### Source Source located in main branch of git repo Browse source http://git.main.lv/cgit.cgi/NaiveFFT.git ``` git clone http://git.main.lv/cgit.cgi/NaiveFFT.git git checkout main ``` ### Build #### Linux ``` cd NaiveFFT/Build make ``` #### Macos Open with Xcode and build ## Thx [Aleksejs](https://github.com/ivanovsaleksejs) - gave tips about js [Dzuris]() - freedback on code [#developers.lv](https://developers.lv) - having patiens for listening to js nonsence from js-newbie ## Links [01] https://rosettacode.org/wiki/Fast_Fourier_transform#C [02] https://www.math.wustl.edu/~victor/mfmm/fourier/fft.c [03] https://www.strauss-engineering.ch/libdsp.html [04] http://www.iowahills.com/FFTCode.html [05] https://github.com/rshuston/FFT-C/blob/master/libfft/fft.c [06] http://www.guitarscience.net/papers/fftalg.pdf [07] https://root.cern/doc/master/FFT_8C_source.html [08] https://lloydrochester.com/post/c/example-fft/ [09] https://github.com/mborgerding/kissfft/blob/master/kiss_fft.c [10] https://community.vcvrack.com/t/complete-list-of-c-c-fft-libraries/9153 [11] https://octave.org/doc/v4.2.1/Signal-Processing.html [12] https://en.wikipedia.org/wiki/Fast_Fourier_transform [13] http://www.iowahills.com/FFTCode.html [14] Digital Signal Processing: A Practical Approach by (Emmanuel Ifeachor, Barrie Jervis)