1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5.  
  6. #define logb(v, b) (log(v)/log(b))
  7. #define SAMPLES 8
  8. #define PI 3.1415926535897932
  9.  
  10. // complex datatype
  11. typedef struct complex_t {
  12. double re; // Real part
  13. double im; // Imag part
  14. } complex;
  15.  
  16. // function headers
  17. complex c_from_polar(double r, double radians);
  18. complex c_add(complex left, complex right);
  19. complex c_sub(complex left, complex right);
  20. complex c_mult(complex left, complex right);
  21. double c_magnitude(complex c);
  22.  
  23.  
  24. int* twiddleIndexGen(int* twindex, int log2N);
  25. complex* twiddleGen(complex* twiddles, int* twindex, int log2N);
  26. complex* DFT_naive(complex* x, int N);
  27.  
  28. // definitions
  29.  
  30. // convert polar value to complex
  31. complex c_from_polar(double r, double radians){
  32. complex result;
  33. result.re = r * cos(radians);
  34. result.im = r * sin(radians);
  35. return result;
  36. }
  37.  
  38. // add two complex numbers
  39. complex c_add(complex left, complex right){
  40. complex result;
  41. result.re = left.re + right.re;
  42. result.im = left.re + right.re;
  43. return result;
  44. }
  45.  
  46. // subtract two complex numbers
  47. complex c_sub(complex left, complex right){
  48. complex result;
  49. result.re = left.re - right.re;
  50. result.im = left.re - right.re;
  51. return result;
  52. }
  53.  
  54. // multiply two complex numbers
  55. complex c_mult(complex left, complex right){
  56. complex result;
  57. result.re = left.re * right.re - left.im * right.im;
  58. result.im = left.re * right.im - left.im * right.re;
  59. return result;
  60. }
  61.  
  62. // compute magnitude of complex number
  63. double c_magnitude(complex c){
  64. return sqrt(c.re * c.re + c.im * c.im);
  65. }
  66.  
  67. // compute DFT for input x
  68. complex* DFT_naive(complex* x, int N){
  69. complex* X = (complex*) malloc(sizeof(struct complex_t) * N);
  70. complex* w = (complex*) malloc(sizeof(struct complex_t) * N);
  71. int k, n;
  72. for (k = 0; k < N; k++){
  73. w[k] = c_from_polar(1, -2*PI*k/N);
  74. }
  75. for (k = 0; k < N; k++){
  76. X[k].re = X[k].im = 0.0;
  77. for (n = 0; n < N; n++){
  78. //X[k] = c_add(X[k[, c_mult(x[n], w[(n*k)%N]));
  79. }
  80. }
  81. free(w);
  82. return X;
  83. }
  84.  
  85. /* twiddleIndexGen:
  86.  * Precalculates the final index order
  87.  * of the twiddle factors based on
  88.  * the number of samples.
  89.  * Uses the bit reversal method
  90.  */
  91. int* twiddleIndexGen(int* twindex, int log2N){
  92. int i, j;
  93. for (j = 0; j < (1<<log2N); j++){ // Index value
  94. int this_num = j;
  95. for (i = 0; i < log2N; i++){ // Bit
  96. twindex[j] <<= 1;
  97. twindex[j] += this_num & 1; // is this bit 1?
  98. this_num >>= 1;
  99. }
  100. printf("%d ", twindex[j]);
  101. }
  102. printf("\n");
  103. return twindex;
  104. }
  105.  
  106. complex* twiddleGen(complex* twiddles, int* twindex, int log2N){
  107. twindex = twiddleIndexGen(twindex, log2N);
  108. int i, j;
  109. int N = (1<<log2N);
  110. for (i = 0; i < N; i++){
  111. j = twindex[i];
  112. twiddles[j] = c_from_polar(1, -2*PI*j/N);
  113. printf("%f, %f\n", twiddles[j].re, twiddles[j].im);
  114. }
  115. return twiddles;
  116. }
  117.  
  118. /* RFFT:
  119.  * Recursive algorithm. Traverses through the array
  120.  * of sample values in a predefined order before
  121.  * traversing back and computing FFTs using twiddle
  122.  * factors.
  123.  */
  124. complex* RFFT(complex* top, complex* out, complex** left, complex** right, int l){
  125. int i;
  126. printf("\nL= %i\n", l);
  127. for (i = 0; i < SAMPLES/(1<<l); i++){
  128. left[l][i] = top[2*i]; // Fill LHS
  129. printf("%.0f ", left[l][i].re);
  130. right[l][i] = top[2*i+1]; // Fill RHS
  131. printf("%.0f\n", right[l][i].re);
  132. }
  133. if (1<<l>=SAMPLES){
  134.  
  135. } else {
  136. RFFT(left[l], out, left, right, l+1); // Traverse left
  137. RFFT(right[l], out, left, right, l+1); // Traverse right
  138. }
  139. return top;
  140. }
  141.  
  142. int main(int argc, char **argv) {
  143. int i;
  144. int ls = logb(SAMPLES, 2); // # levels
  145. complex *main = (complex *)malloc(sizeof(complex)*SAMPLES); // main array
  146. complex *out = (complex *)malloc(sizeof(complex)*SAMPLES); // output array
  147. complex **left = (complex **)malloc(sizeof(complex)*SAMPLES); // array of left traverse arrays
  148. complex **right = (complex **)malloc(sizeof(complex)*SAMPLES); // array of right traverse arrays
  149. /* (only need one for each per level since only working with a single pair at one time)
  150. * each level down the tree requires only half the number of values as the previous
  151. * so array size is halved. Total array size is roughly 4x sample size
  152. */
  153.  
  154. // Populate MAIN array
  155. for (i = 0; i < SAMPLES; i++) {
  156. main[i] = (complex){i,0};
  157. //printf("%.0f,%.0f\n\n", main[i].re, main[i].im);
  158. }
  159.  
  160. // Generate twiddle indexes and twiddle factors
  161. int *twindex = (int*)malloc(sizeof(int)*SAMPLES);
  162. complex *twiddles = (complex*)malloc(sizeof(complex)*SAMPLES);
  163. twiddles = twiddleGen(twiddles, twindex, ls);
  164.  
  165. // Define LEFT/RIGHT array sizes, each is 1/2
  166. // as long as the previous array
  167. for (i = ls; i >= 0; i--){
  168. left[ls-i+1] = (complex*)malloc(sizeof(complex)*(1<<i));
  169. right[ls-i+1] = (complex*)malloc(sizeof(complex)*(1<<i));
  170. }
  171.  
  172. //Begin Recursion
  173. int level = 1;
  174. RFFT(main, out, left, right, level);
  175.  
  176. // Cleanup
  177. for (i = ls; i >= 0; i--){
  178. free(left[ls-i+1]);
  179. free(right[ls-i+1]);
  180. }
  181. free(left);
  182. free(right);
  183. free(twiddles);
  184. free(twindex);
  185. free(out);
  186. free(main);
  187. return 0;
  188. }
  189.