From db01e1264a89e5a40f1e730d9d80679faf6943f8 Mon Sep 17 00:00:00 2001 From: Arturs Artamonovs Date: Thu, 19 Aug 2021 08:00:30 +0100 Subject: workinf dft and fft. Octave test file --- NaiveFFT/main.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++------ Test/test_fft.m | 12 ++++ 2 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 Test/test_fft.m diff --git a/NaiveFFT/main.c b/NaiveFFT/main.c index fec893b..f8b56cd 100644 --- a/NaiveFFT/main.c +++ b/NaiveFFT/main.c @@ -11,28 +11,31 @@ #include #include #include +#include //data array #define DATA_SIZE (8) -double data_i[DATA_SIZE] = {1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; +//double data_i[DATA_SIZE] = {0.0f,1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f}; +//double data_q[DATA_SIZE] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; +double data_i[DATA_SIZE] = {1.0f,1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; double data_q[DATA_SIZE] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f}; + //calc the fft void fft_if(double *x_i, double *x_q, int n, int inv) { int i=0,j=0,k=0,m=0, irem=0, sign; double tq,ti; - printf("FFT\n"); k=n/2; - for (j=1,i=1;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; + } +} +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; j