fourierf.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*============================================================================
  2. fourierf.c - Don Cross <dcross@intersrv.com>
  3. http://www.intersrv.com/~dcross/fft.html
  4. Contains definitions for doing Fourier transforms
  5. and inverse Fourier transforms.
  6. This module performs operations on arrays of 'float'.
  7. Revision history:
  8. 1998 September 19 [Don Cross]
  9. Updated coding standards.
  10. Improved efficiency of trig calculations.
  11. ============================================================================*/
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include "fourier.h"
  16. #include "ddcmath.h"
  17. #define CHECKPOINTER(p) CheckPointer(p,#p)
  18. static void CheckPointer ( void *p, char *name )
  19. {
  20. if ( p == NULL )
  21. {
  22. // fprintf ( stderr, "Error in fft_float(): %s == NULL\n", name );
  23. printf ( "Error in fft_float(): %s == NULL\n", name );
  24. exit(1);
  25. }
  26. }
  27. void fft_float (
  28. unsigned NumSamples,
  29. int InverseTransform,
  30. float *RealIn,
  31. float *ImagIn,
  32. float *RealOut,
  33. float *ImagOut )
  34. {
  35. unsigned NumBits; /* Number of bits needed to store indices */
  36. unsigned i, j, k, n;
  37. unsigned BlockSize, BlockEnd;
  38. double angle_numerator = 2.0 * DDC_PI;
  39. double tr, ti; /* temp real, temp imaginary */
  40. if ( !IsPowerOfTwo(NumSamples) )
  41. {
  42. // fprintf (
  43. // stderr,
  44. // "Error in fft(): NumSamples=%u is not power of two\n",
  45. // NumSamples );
  46. printf (
  47. "Error in fft(): NumSamples=%u is not power of two\n",
  48. NumSamples );
  49. exit(1);
  50. }
  51. if ( InverseTransform )
  52. angle_numerator = -angle_numerator;
  53. CHECKPOINTER ( RealIn );
  54. CHECKPOINTER ( RealOut );
  55. CHECKPOINTER ( ImagOut );
  56. NumBits = NumberOfBitsNeeded ( NumSamples );
  57. /*
  58. ** Do simultaneous data copy and bit-reversal ordering into outputs...
  59. */
  60. for ( i=0; i < NumSamples; i++ )
  61. {
  62. j = ReverseBits ( i, NumBits );
  63. RealOut[j] = RealIn[i];
  64. ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
  65. }
  66. /*
  67. ** Do the FFT itself...
  68. */
  69. BlockEnd = 1;
  70. for ( BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1 )
  71. {
  72. double delta_angle = angle_numerator / (double)BlockSize;
  73. double sm2 = sin ( -2 * delta_angle );
  74. double sm1 = sin ( -delta_angle );
  75. double cm2 = cos ( -2 * delta_angle );
  76. double cm1 = cos ( -delta_angle );
  77. double w = 2 * cm1;
  78. double ar[3], ai[3];
  79. double temp;
  80. for ( i=0; i < NumSamples; i += BlockSize )
  81. {
  82. ar[2] = cm2;
  83. ar[1] = cm1;
  84. ai[2] = sm2;
  85. ai[1] = sm1;
  86. for ( j=i, n=0; n < BlockEnd; j++, n++ )
  87. {
  88. ar[0] = w*ar[1] - ar[2];
  89. ar[2] = ar[1];
  90. ar[1] = ar[0];
  91. ai[0] = w*ai[1] - ai[2];
  92. ai[2] = ai[1];
  93. ai[1] = ai[0];
  94. k = j + BlockEnd;
  95. tr = ar[0]*RealOut[k] - ai[0]*ImagOut[k];
  96. ti = ar[0]*ImagOut[k] + ai[0]*RealOut[k];
  97. RealOut[k] = RealOut[j] - tr;
  98. ImagOut[k] = ImagOut[j] - ti;
  99. RealOut[j] += tr;
  100. ImagOut[j] += ti;
  101. }
  102. }
  103. BlockEnd = BlockSize;
  104. }
  105. /*
  106. ** Need to normalize if inverse transform...
  107. */
  108. if ( InverseTransform )
  109. {
  110. double denom = (double)NumSamples;
  111. for ( i=0; i < NumSamples; i++ )
  112. {
  113. RealOut[i] /= denom;
  114. ImagOut[i] /= denom;
  115. }
  116. }
  117. }
  118. /*--- end of file fourierf.c ---*/