r_fft_ex.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. *****************************************************************************
  3. *
  4. * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
  5. * R99 Version 3.3.0
  6. * REL-4 Version 4.1.0
  7. *
  8. *****************************************************************************
  9. *
  10. * File : r_fft.c
  11. * Purpose : Fast Fourier Transform (FFT) algorithm
  12. *
  13. *****************************************************************************
  14. */
  15. /*****************************************************************
  16. *
  17. * This is an implementation of decimation-in-time FFT algorithm for
  18. * real sequences. The techniques used here can be found in several
  19. * books, e.g., i) Proakis and Manolakis, "Digital Signal Processing",
  20. * 2nd Edition, Chapter 9, and ii) W.H. Press et. al., "Numerical
  21. * Recipes in C", 2nd Ediiton, Chapter 12.
  22. *
  23. * Input - There is one input to this function:
  24. *
  25. * 1) An integer pointer to the input data array
  26. *
  27. * Output - There is no return value.
  28. * The input data are replaced with transformed data. If the
  29. * input is a real time domain sequence, it is replaced with
  30. * the complex FFT for positive frequencies. The FFT value
  31. * for DC and the foldover frequency are combined to form the
  32. * first complex number in the array. The remaining complex
  33. * numbers correspond to increasing frequencies. If the input
  34. * is a complex frequency domain sequence arranged as above,
  35. * it is replaced with the corresponding time domain sequence.
  36. *
  37. * Notes:
  38. *
  39. * 1) This function is designed to be a part of a VAD
  40. * algorithm that requires 128-point FFT of real
  41. * sequences. This is achieved here through a 64-point
  42. * complex FFT. Consequently, the FFT size information is
  43. * not transmitted explicitly. However, some flexibility
  44. * is provided in the function to change the size of the
  45. * FFT by specifying the size information through "define"
  46. * statements.
  47. *
  48. * 2) The values of the complex sinusoids used in the FFT
  49. * algorithm are stored in a ROM table.
  50. *
  51. * 3) In the c_fft function, the FFT values are divided by
  52. * 2 after each stage of computation thus dividing the
  53. * final FFT values by 64. This is somewhat different
  54. * from the usual definition of FFT where the factor 1/N,
  55. * i.e., 1/64, used for the IFFT and not the FFT. No factor
  56. * is used in the r_fft function.
  57. *
  58. *****************************************************************/
  59. const char r_fft_id[] = "@(#)$Id $";
  60. #include "typedef.h"
  61. #include "cnst.h"
  62. #include "basic_op.h"
  63. #include "oper_32b.h"
  64. #include "count.h"
  65. #include "vad2.h"
  66. #define SIZE 128
  67. #define SIZE_BY_TWO 64
  68. #define NUM_STAGE 6
  69. #define TRUE 1
  70. #define FALSE 0
  71. static Word16 phs_tbl[] =
  72. {
  73. 32767, 0, 32729, -1608, 32610, -3212, 32413, -4808,
  74. 32138, -6393, 31786, -7962, 31357, -9512, 30853, -11039,
  75. 30274, -12540, 29622, -14010, 28899, -15447, 28106, -16846,
  76. 27246, -18205, 26320, -19520, 25330, -20788, 24279, -22006,
  77. 23170, -23170, 22006, -24279, 20788, -25330, 19520, -26320,
  78. 18205, -27246, 16846, -28106, 15447, -28899, 14010, -29622,
  79. 12540, -30274, 11039, -30853, 9512, -31357, 7962, -31786,
  80. 6393, -32138, 4808, -32413, 3212, -32610, 1608, -32729,
  81. 0, -32768, -1608, -32729, -3212, -32610, -4808, -32413,
  82. -6393, -32138, -7962, -31786, -9512, -31357, -11039, -30853,
  83. -12540, -30274, -14010, -29622, -15447, -28899, -16846, -28106,
  84. -18205, -27246, -19520, -26320, -20788, -25330, -22006, -24279,
  85. -23170, -23170, -24279, -22006, -25330, -20788, -26320, -19520,
  86. -27246, -18205, -28106, -16846, -28899, -15447, -29622, -14010,
  87. -30274, -12540, -30853, -11039, -31357, -9512, -31786, -7962,
  88. -32138, -6393, -32413, -4808, -32610, -3212, -32729, -1608
  89. };
  90. static Word16 ii_table[] =
  91. {SIZE / 2, SIZE / 4, SIZE / 8, SIZE / 16, SIZE / 32, SIZE / 64};
  92. /* FFT function for complex sequences */
  93. /*
  94. * The decimation-in-time complex FFT is implemented below.
  95. * The input complex numbers are presented as real part followed by
  96. * imaginary part for each sample. The counters are therefore
  97. * incremented by two to access the complex valued samples.
  98. */
  99. void c_fft_ex(Word16 * farray_ptr)
  100. {
  101. Word16 i, j, k, ii, jj, kk, ji, kj, ii2;
  102. Word32 ftmp, ftmp_real, ftmp_imag;
  103. Word16 tmp, tmp1, tmp2;
  104. /* Rearrange the input array in bit reversed order */
  105. for (i = 0, j = 0; i < SIZE - 2; i = i + 2)
  106. { test();
  107. if (sub_ex(j, i) > 0)
  108. {
  109. ftmp = *(farray_ptr + i); move16();
  110. *(farray_ptr + i) = *(farray_ptr + j); move16();
  111. *(farray_ptr + j) = ftmp; move16();
  112. ftmp = *(farray_ptr + i + 1); move16();
  113. *(farray_ptr + i + 1) = *(farray_ptr + j + 1); move16();
  114. *(farray_ptr + j + 1) = ftmp; move16();
  115. }
  116. k = SIZE_BY_TWO; move16();
  117. test();
  118. while (sub_ex(j, k) >= 0)
  119. {
  120. j = sub_ex(j, k);
  121. k = shr_ex(k, 1);
  122. }
  123. j = add_ex(j, k);
  124. }
  125. /* The FFT part */
  126. for (i = 0; i < NUM_STAGE; i++)
  127. { /* i is stage counter */
  128. jj = shl_ex(2, i); /* FFT size */
  129. kk = shl_ex(jj, 1); /* 2 * FFT size */
  130. ii = ii_table[i]; /* 2 * number of FFT's */ move16();
  131. ii2 = shl_ex(ii, 1);
  132. ji = 0; /* ji is phase table index */ move16();
  133. for (j = 0; j < jj; j = j + 2)
  134. { /* j is sample counter */
  135. for (k = j; k < SIZE; k = k + kk)
  136. { /* k is butterfly top */
  137. kj = add_ex(k, jj); /* kj is butterfly bottom */
  138. /* Butterfly computations */
  139. ftmp_real = L_mult_ex(*(farray_ptr + kj), phs_tbl[ji]);
  140. ftmp_real = L_msu_ex(ftmp_real, *(farray_ptr + kj + 1), phs_tbl[ji + 1]);
  141. ftmp_imag = L_mult_ex(*(farray_ptr + kj + 1), phs_tbl[ji]);
  142. ftmp_imag = L_mac_ex(ftmp_imag, *(farray_ptr + kj), phs_tbl[ji + 1]);
  143. tmp1 = round_ex(ftmp_real);
  144. tmp2 = round_ex(ftmp_imag);
  145. tmp = sub_ex(*(farray_ptr + k), tmp1);
  146. *(farray_ptr + kj) = shr_ex(tmp, 1); move16();
  147. tmp = sub_ex(*(farray_ptr + k + 1), tmp2);
  148. *(farray_ptr + kj + 1) = shr_ex(tmp, 1); move16();
  149. tmp = add_ex(*(farray_ptr + k), tmp1);
  150. *(farray_ptr + k) = shr_ex(tmp, 1); move16();
  151. tmp = add_ex(*(farray_ptr + k + 1), tmp2);
  152. *(farray_ptr + k + 1) = shr_ex(tmp, 1); move16();
  153. }
  154. ji = add_ex(ji, ii2);
  155. }
  156. }
  157. } /* end of c_fft () */
  158. void r_fft_ex(Word16 * farray_ptr)
  159. {
  160. Word16 ftmp1_real, ftmp1_imag, ftmp2_real, ftmp2_imag;
  161. Word32 Lftmp1_real, Lftmp1_imag;
  162. Word16 i, j;
  163. Word32 Ltmp1;
  164. /* Perform the complex FFT */
  165. c_fft_ex(farray_ptr);
  166. /* First, handle the DC and foldover frequencies */
  167. ftmp1_real = *farray_ptr; move16();
  168. ftmp2_real = *(farray_ptr + 1); move16();
  169. *farray_ptr = add_ex(ftmp1_real, ftmp2_real); move16();
  170. *(farray_ptr + 1) = sub_ex(ftmp1_real, ftmp2_real); move16();
  171. /* Now, handle the remaining positive frequencies */
  172. for (i = 2, j = SIZE - i; i <= SIZE_BY_TWO; i = i + 2, j = SIZE - i)
  173. {
  174. ftmp1_real = add_ex(*(farray_ptr + i), *(farray_ptr + j));
  175. ftmp1_imag = sub_ex(*(farray_ptr + i + 1), *(farray_ptr + j + 1));
  176. ftmp2_real = add_ex(*(farray_ptr + i + 1), *(farray_ptr + j + 1));
  177. ftmp2_imag = sub_ex(*(farray_ptr + j), *(farray_ptr + i));
  178. Lftmp1_real = L_deposit_h_ex(ftmp1_real);
  179. Lftmp1_imag = L_deposit_h_ex(ftmp1_imag);
  180. Ltmp1 = L_mac_ex(Lftmp1_real, ftmp2_real, phs_tbl[i]);
  181. Ltmp1 = L_msu_ex(Ltmp1, ftmp2_imag, phs_tbl[i + 1]);
  182. *(farray_ptr + i) = round_ex(L_shr_ex(Ltmp1, 1)); move16();
  183. Ltmp1 = L_mac_ex(Lftmp1_imag, ftmp2_imag, phs_tbl[i]);
  184. Ltmp1 = L_mac_ex(Ltmp1, ftmp2_real, phs_tbl[i + 1]);
  185. *(farray_ptr + i + 1) = round_ex(L_shr_ex(Ltmp1, 1)); move16();
  186. Ltmp1 = L_mac_ex(Lftmp1_real, ftmp2_real, phs_tbl[j]);
  187. Ltmp1 = L_mac_ex(Ltmp1, ftmp2_imag, phs_tbl[j + 1]);
  188. *(farray_ptr + j) = round_ex(L_shr_ex(Ltmp1, 1)); move16();
  189. Ltmp1 = L_negate_ex(Lftmp1_imag);
  190. Ltmp1 = L_msu_ex(Ltmp1, ftmp2_imag, phs_tbl[j]);
  191. Ltmp1 = L_mac_ex(Ltmp1, ftmp2_real, phs_tbl[j + 1]);
  192. *(farray_ptr + j + 1) = round_ex(L_shr_ex(Ltmp1, 1)); move16();
  193. }
  194. } /* end r_fft () */