miszczo

FFT

Mar 11th, 2022
724
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.33 KB | None | 0 0
  1. /******************************************************************************
  2.  
  3.                             Online C Compiler.
  4.                 Code, Compile, Run and Debug C program online.
  5. Write your code in this editor and press "Run" button to compile and execute it.
  6.  
  7. *******************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11.  
  12.  
  13. #define SAMPLES 256
  14. float input_signal[SAMPLES];
  15.  
  16. #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
  17. void four1(float data[], unsigned long nn, int isign)
  18. /*Replaces data[1..2*nn] by its discrete Fourier transform, if isign is input as 1; or replaces
  19.  data[1..2*nn] by nn times its inverse discrete Fourier transform, if isign is input as −1.
  20.  data is a complex array of length nn or, equivalently, a real array of length 2*nn. nn MUST
  21.  be an integer power of 2 (this is not checked for!).*/
  22. {
  23.   unsigned long n, mmax, m, j, istep, i;
  24.   double wtemp, wr, wpr, wpi, wi, theta; /*Double precision for the trigonomet-
  25.    ric recurrences.*/
  26.   float tempr,tempi;
  27.   n = nn << 1;
  28.   j = 1;
  29.   for (i = 1; i < n; i += 2) { /*This is the bit-reversal section of the
  30.    routine.*/
  31.     if (j > i) {
  32.       SWAP(data[j], data[i]); /*Exchange the two complex numbers.*/
  33.       SWAP(data[j + 1], data[i + 1]);
  34.     }
  35.     m = nn;
  36.     while (m >= 2 && j > m) {
  37.       j -= m;
  38.       m >>= 1;
  39.     }
  40.     j += m;
  41.   }
  42.   /*Here begins the Danielson-Lanczos section of the routine.*/
  43.   mmax = 2;
  44.   while (n > mmax) {
  45.     /*    Outer loop
  46.      executed log2
  47.      nn times
  48.      .*/
  49.     istep = mmax << 1;
  50.     theta = isign * (6.28318530717959 / mmax); /*Initialize the trigonometric recurrence.*/
  51.     wtemp = sin(0.5 * theta);
  52.     wpr = -2.0 * wtemp * wtemp;
  53.     wpi = sin(theta);
  54.     wr = 1.0;
  55.     wi = 0.0;
  56.     for (m = 1; m < mmax; m += 2) { /*Here are the two nested inner loops.*/
  57.       for (i = m; i <= n; i += istep) {
  58.         j = i + mmax; /*This is the Danielson-Lanczos for-
  59.          mula:*/
  60.         tempr = wr * data[j] - wi * data[j + 1];
  61.         tempi = wr * data[j + 1] + wi * data[j];
  62.         data[j] = data[i] - tempr;
  63.         data[j + 1] = data[i + 1] - tempi;
  64.         data[i] += tempr;
  65.         data[i + 1] += tempi;
  66.       }
  67.       wr = (wtemp = wr) * wpr - wi * wpi + wr;
  68.       /*Trigonometric recurrence.*/
  69.       wi = wi * wpr + wtemp * wpi + wi;
  70.     }
  71.     mmax = istep;
  72.   }
  73. }
  74.  
  75.  
  76. /*Calculates the Fourier transform of a set of n real-valued data points. Replaces this data (which
  77.  is stored in array data[1..n]) by the positive frequency half of its complex Fourier transform.
  78.  The real-valued first and last components of the complex transform are returned as elements
  79.  data[1] and data[2], respectively. n must be a power of 2. This routine also calculates the
  80.  inverse transform of a complex data array if it is the transform of real data. (Result in this case
  81.  must be multiplied by 2/n.)*/
  82. void realft(float data[], unsigned long n, int isign) {
  83.   void four1(float data[], unsigned long nn, int isign);
  84.   unsigned long i, i1, i2, i3, i4, np3;
  85.   float c1 = 0.5, c2, h1r, h1i, h2r, h2i;
  86.   float wr, wi, wpr, wpi, wtemp, theta; /*Double precision for the trigonometric recurrences.*/
  87.   theta = 3.141592653589793 / (double) (n >> 1); /*Initialize the recurrence.*/
  88.   if (isign == 1) {
  89.     c2 = -0.5;
  90.     four1(data, n >> 1, 1); /*The forward transform is here.*/
  91.   } else {
  92.     c2 = 0.5;/* Otherwise set up for an inverse trans-form.*/
  93.     theta = -theta;
  94.   }
  95.   wtemp = sin(0.5 * theta);
  96.   wpr = -2.0 * wtemp * wtemp;
  97.   wpi = sin(theta);
  98.   wr = 1.0 + wpr;
  99.   wi = wpi;
  100.   np3 = n + 3;
  101.   for (i = 2; i <= (n >> 2); i++) { /*Case i=1 done separately below.*/
  102.     i4 = 1 + (i3 = np3 - (i2 = 1 + (i1 = i + i - 1)));
  103.     h1r = c1 * (data[i1] + data[i3]);
  104.     /*The two separate transforms are separated out of data.*/h1i = c1
  105.         * (data[i2] - data[i4]);
  106.     h2r = -c2 * (data[i2] + data[i4]);
  107.     h2i = c2 * (data[i1] - data[i3]);
  108.     data[i1] = h1r + wr * h2r - wi * h2i;/* Here they are recombined to form
  109.      the true transform of the origi-
  110.      nal real data.*/
  111.     data[i2] = h1i + wr * h2i + wi * h2r;
  112.     data[i3] = h1r - wr * h2r + wi * h2i;
  113.     data[i4] = -h1i + wr * h2i + wi * h2r;
  114.     wr = (wtemp = wr) * wpr - wi * wpi + wr; /*The recurrence.*/
  115.     wi = wi * wpr + wtemp * wpi + wi;
  116.   }
  117.   if (isign == 1) {
  118.     data[1] = (h1r = data[1]) + data[2]; /*Squeeze the first and last data together to get them all within the original array.*/
  119.     data[2] = h1r - data[2];
  120.   } else {
  121.     data[1] = c1 * ((h1r = data[1]) + data[2]);
  122.     data[2] = c1 * (h1r - data[2]);
  123.     four1(data, n >> 1, -1); /*This is the inverse transform for the case isign=-1.*/
  124.   }
  125. }
  126.  
  127. int main()
  128. {
  129.     printf("Program start!\n\r");
  130.     for (int i = 0; i < (SAMPLES); i++) {
  131.         input_signal[i] =1024 * sin(60*2 * M_PI * i / SAMPLES);
  132.         printf("[%d]%f\n\r",i, input_signal[i]);
  133.     }
  134.     printf("*************************************************************************************************!\n\r");
  135.     realft(input_signal,SAMPLES,1);
  136.    
  137.    
  138.     for(int i =0;i<(SAMPLES);i++){
  139.         input_signal[i]=sqrt(input_signal[2*i+1]*input_signal[2*i+1]+input_signal[2*i+1+1]*input_signal[2*i+1+1])/(SAMPLES/2);
  140.     }
  141.    
  142.     for (int i = 0; i < (SAMPLES); i++) {
  143.         printf("[%d]%f\n\r",i, input_signal[i]);
  144.     }
  145.    
  146.  
  147.     return 0;
  148. }
  149.  
Advertisement
Add Comment
Please, Sign In to add comment