fft.c 5.4 KB

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