fft.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include "fourier.h"
  5. #include "ddcmath.h"
  6. #include "fft.h"
  7. #include "cmsis_os.h"
  8. #define CHECKPOINTER(p) CheckPointer(p, #p)
  9. static void CheckPointer(void *p, char *name)
  10. {
  11. if (p == NULL)
  12. {
  13. // fprintf(stderr, "Error in fft_float(): %s == NULL\n", name);
  14. printf("Error in fft_float(): %s == NULL\n", name);
  15. exit(1);
  16. }
  17. }
  18. void vFFT()
  19. {
  20. unsigned MAXSIZE;
  21. unsigned MAXWAVES;
  22. unsigned i, j;
  23. int invfft = 0;
  24. MAXSIZE = 128;
  25. MAXWAVES = 4;
  26. int IMC_REPEAT = 10;
  27. // IMC_REPEAT = 100;
  28. // srand(1);
  29. float RealIn[MAXSIZE];
  30. float ImagIn[MAXSIZE];
  31. float RealOut[MAXSIZE];
  32. float ImagOut[MAXSIZE];
  33. float coeff[MAXWAVES];
  34. float amp[MAXWAVES];
  35. for (int imc_repeat=0; imc_repeat < IMC_REPEAT; imc_repeat++) {
  36. /* Makes MAXWAVES waves of random amplitude and period */
  37. for (i = 0; i < MAXWAVES; i++)
  38. {
  39. // coeff[i] = rand() % 1000;
  40. // amp[i] = rand() % 1000;
  41. coeff[i] = 123;
  42. amp[i] = 456;
  43. }
  44. for (i = 0; i < MAXSIZE; i++)
  45. {
  46. /* RealIn[i]=rand();*/
  47. RealIn[i] = 0;
  48. ImagIn[i] = 0;
  49. float sum = 0;
  50. for (j = 0; j < MAXWAVES; j++)
  51. {
  52. /* randomly select sin or cos */
  53. if (i % 2)
  54. {
  55. sum += coeff[j] * cos(amp[j] * i);
  56. // RealIn[i] += coeff[j] * cos(amp[j] * i);
  57. }
  58. else
  59. {
  60. // RealIn[i] += coeff[j] * sin(amp[j] * i);
  61. sum += coeff[j] * sin(amp[j] * i);
  62. }
  63. }
  64. RealIn[i] = sum;
  65. }
  66. /* regular*/
  67. {
  68. unsigned NumBits; /* Number of bits needed to store indices */
  69. unsigned i, j, k, n;
  70. unsigned BlockSize, BlockEnd;
  71. double angle_numerator = 2.0 * DDC_PI;
  72. double tr, ti; /* temp real, temp imaginary */
  73. unsigned NumSamples = MAXSIZE;
  74. int InverseTransform = invfft;
  75. if (!IsPowerOfTwo(NumSamples))
  76. {
  77. // fprintf(
  78. // stderr,
  79. // "Error in fft(): NumSamples=%u is not power of two\n",
  80. // NumSamples);
  81. printf(
  82. "Error in fft(): NumSamples=%u is not power of two\n",
  83. NumSamples);
  84. exit(1);
  85. }
  86. if (InverseTransform)
  87. angle_numerator = -angle_numerator;
  88. NumBits = NumberOfBitsNeeded(NumSamples);
  89. /*
  90. ** Do simultaneous data copy and bit-reversal ordering into outputs...
  91. */
  92. for (i = 0; i < NumSamples; i++)
  93. {
  94. j = ReverseBits(i, NumBits);
  95. RealOut[j] = RealIn[i];
  96. // ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
  97. ImagOut[j] = ImagIn[i];
  98. }
  99. /*
  100. ** Do the FFT itself...
  101. */
  102. BlockEnd = 1;
  103. for (BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1)
  104. {
  105. double delta_angle = angle_numerator / (double)BlockSize;
  106. double sm2 = sin(-2 * delta_angle);
  107. double sm1 = sin(-delta_angle);
  108. double cm2 = cos(-2 * delta_angle);
  109. double cm1 = cos(-delta_angle);
  110. double w = 2 * cm1;
  111. double ar[3], ai[3];
  112. double temp;
  113. for (i = 0; i < NumSamples; i += BlockSize)
  114. {
  115. ar[2] = cm2;
  116. ar[1] = cm1;
  117. ai[2] = sm2;
  118. ai[1] = sm1;
  119. for (j = i, n = 0; n < BlockEnd; j++, n++)
  120. {
  121. ar[0] = w * ar[1] - ar[2];
  122. ar[2] = ar[1];
  123. ar[1] = ar[0];
  124. ai[0] = w * ai[1] - ai[2];
  125. ai[2] = ai[1];
  126. ai[1] = ai[0];
  127. k = j + BlockEnd;
  128. tr = ar[0] * RealOut[k] - ai[0] * ImagOut[k];
  129. ti = ar[0] * ImagOut[k] + ai[0] * RealOut[k];
  130. RealOut[k] = RealOut[j] - tr;
  131. ImagOut[k] = ImagOut[j] - ti;
  132. RealOut[j] += tr;
  133. ImagOut[j] += ti;
  134. }
  135. }
  136. BlockEnd = BlockSize;
  137. }
  138. /*
  139. ** Need to normalize if inverse transform...
  140. */
  141. if (InverseTransform)
  142. {
  143. double denom = (double)NumSamples;
  144. for (i = 0; i < NumSamples; i++)
  145. {
  146. RealOut[i] /= denom;
  147. ImagOut[i] /= denom;
  148. }
  149. }
  150. }
  151. } //imc_repeat
  152. /*
  153. portDISABLE_INTERRUPTS();
  154. printf("RealOut:\r\n");
  155. portENABLE_INTERRUPTS();
  156. for (i = 0; i < MAXSIZE; i++)
  157. printf("%f \t", RealOut[i]);
  158. printf("\r\n");
  159. printf("ImagOut:\r\n");
  160. for (i = 0; i < MAXSIZE; i++)
  161. printf("%f \t", ImagOut[i]);
  162. printf("\r\n");
  163. */
  164. float real_sum = 0;
  165. float imag_sum = 0;
  166. for (i = 0; i < MAXSIZE; i++) {
  167. real_sum += RealOut[i];
  168. imag_sum += ImagOut[i];
  169. }
  170. portDISABLE_INTERRUPTS();
  171. printf("%d, %d\r\n", (int)(real_sum*1000000), (int)(imag_sum*1000000));
  172. portENABLE_INTERRUPTS();
  173. // printf("RealOut: ");
  174. // for (i = 0; i < 3; i++)
  175. // printf("%f\t", RealOut[i]);
  176. // printf("\r\n");
  177. // printf("ImagOut: ");
  178. // for (i = 0; i < 3; i++)
  179. // printf("%f\t", ImagOut[i]);
  180. // printf("\r\n");
  181. }