You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
2.7 KiB

  1. // Copyright (c) 2016 Network
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <math.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "frontend/fft.h"
  18. namespace wenet {
  19. void make_sintbl(int n, float* sintbl) {
  20. int i, n2, n4, n8;
  21. float c, s, dc, ds, t;
  22. n2 = n / 2;
  23. n4 = n / 4;
  24. n8 = n / 8;
  25. t = sin(M_PI / n);
  26. dc = 2 * t * t;
  27. ds = sqrt(dc * (2 - dc));
  28. t = 2 * dc;
  29. c = sintbl[n4] = 1;
  30. s = sintbl[0] = 0;
  31. for (i = 1; i < n8; ++i) {
  32. c -= dc;
  33. dc += t * c;
  34. s += ds;
  35. ds -= t * s;
  36. sintbl[i] = s;
  37. sintbl[n4 - i] = c;
  38. }
  39. if (n8 != 0) sintbl[n8] = sqrt(0.5);
  40. for (i = 0; i < n4; ++i) sintbl[n2 - i] = sintbl[i];
  41. for (i = 0; i < n2 + n4; ++i) sintbl[i + n2] = -sintbl[i];
  42. }
  43. void make_bitrev(int n, int* bitrev) {
  44. int i, j, k, n2;
  45. n2 = n / 2;
  46. i = j = 0;
  47. for (;;) {
  48. bitrev[i] = j;
  49. if (++i >= n) break;
  50. k = n2;
  51. while (k <= j) {
  52. j -= k;
  53. k /= 2;
  54. }
  55. j += k;
  56. }
  57. }
  58. // bitrev: bit reversal table
  59. // sintbl: trigonometric function table
  60. // x:real part
  61. // y:image part
  62. // n: fft length
  63. int fft(const int* bitrev, const float* sintbl, float* x, float* y, int n) {
  64. int i, j, k, ik, h, d, k2, n4, inverse;
  65. float t, s, c, dx, dy;
  66. /* preparation */
  67. if (n < 0) {
  68. n = -n;
  69. inverse = 1; /* inverse transform */
  70. } else {
  71. inverse = 0;
  72. }
  73. n4 = n / 4;
  74. if (n == 0) {
  75. return 0;
  76. }
  77. /* bit reversal */
  78. for (i = 0; i < n; ++i) {
  79. j = bitrev[i];
  80. if (i < j) {
  81. t = x[i];
  82. x[i] = x[j];
  83. x[j] = t;
  84. t = y[i];
  85. y[i] = y[j];
  86. y[j] = t;
  87. }
  88. }
  89. /* transformation */
  90. for (k = 1; k < n; k = k2) {
  91. h = 0;
  92. k2 = k + k;
  93. d = n / k2;
  94. for (j = 0; j < k; ++j) {
  95. c = sintbl[h + n4];
  96. if (inverse)
  97. s = -sintbl[h];
  98. else
  99. s = sintbl[h];
  100. for (i = j; i < n; i += k2) {
  101. ik = i + k;
  102. dx = s * y[ik] + c * x[ik];
  103. dy = c * y[ik] - s * x[ik];
  104. x[ik] = x[i] - dx;
  105. x[i] += dx;
  106. y[ik] = y[i] - dy;
  107. y[i] += dy;
  108. }
  109. h += d;
  110. }
  111. }
  112. if (inverse) {
  113. /* divide by n in case of the inverse transformation */
  114. for (i = 0; i < n; ++i) {
  115. x[i] /= n;
  116. y[i] /= n;
  117. }
  118. }
  119. return 0; /* finished successfully */
  120. }
  121. } // namespace wenet