RDsp.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (C) 2018 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef RDSP_H
  17. #define RDSP_H
  18. #include <complex>
  19. #include <log/log.h>
  20. #include <vector>
  21. #include <map>
  22. using FloatVec = std::vector<float>;
  23. using IntVec = std::vector<int>;
  24. using ComplexVec = std::vector<std::complex<float>>;
  25. // =======
  26. // Helper Functions
  27. // =======
  28. template <class T>
  29. static T dBtoLinear(T valueDb) {
  30. return pow (10, valueDb / 20.0);
  31. }
  32. template <class T>
  33. static T linearToDb(T value) {
  34. return 20 * log10(value);
  35. }
  36. // =======
  37. // DSP window creation
  38. // =======
  39. #define TWOPI (M_PI * 2)
  40. enum rdsp_window_type {
  41. RDSP_WINDOW_RECTANGULAR,
  42. RDSP_WINDOW_TRIANGULAR,
  43. RDSP_WINDOW_TRIANGULAR_FLAT_TOP,
  44. RDSP_WINDOW_HAMMING,
  45. RDSP_WINDOW_HAMMING_FLAT_TOP,
  46. RDSP_WINDOW_HANNING,
  47. RDSP_WINDOW_HANNING_FLAT_TOP,
  48. };
  49. template <typename T>
  50. static void fillRectangular(T &v) {
  51. const size_t size = v.size();
  52. for (size_t i = 0; i < size; i++) {
  53. v[i] = 1.0;
  54. }
  55. } //rectangular
  56. template <typename T>
  57. static void fillTriangular(T &v, size_t overlap) {
  58. const size_t size = v.size();
  59. //ramp up
  60. size_t i = 0;
  61. if (overlap > 0) {
  62. for (; i < overlap; i++) {
  63. v[i] = (2.0 * i + 1) / (2 * overlap);
  64. }
  65. }
  66. //flat top
  67. for (; i < size - overlap; i++) {
  68. v[i] = 1.0;
  69. }
  70. //ramp down
  71. if (overlap > 0) {
  72. for (; i < size; i++) {
  73. v[i] = (2.0 * (size - i) - 1) / (2 * overlap);
  74. }
  75. }
  76. } //triangular
  77. template <typename T>
  78. static void fillHamming(T &v, size_t overlap) {
  79. const size_t size = v.size();
  80. const size_t twoOverlap = 2 * overlap;
  81. size_t i = 0;
  82. if (overlap > 0) {
  83. for (; i < overlap; i++) {
  84. v[i] = 0.54 - 0.46 * cos(TWOPI * i /(twoOverlap - 1));
  85. }
  86. }
  87. //flat top
  88. for (; i < size - overlap; i++) {
  89. v[i] = 1.0;
  90. }
  91. //ramp down
  92. if (overlap > 0) {
  93. for (; i < size; i++) {
  94. int k = i - ((int)size - 2 * overlap);
  95. v[i] = 0.54 - 0.46 * cos(TWOPI * k / (twoOverlap - 1));
  96. }
  97. }
  98. } //hamming
  99. template <typename T>
  100. static void fillHanning(T &v, size_t overlap) {
  101. const size_t size = v.size();
  102. const size_t twoOverlap = 2 * overlap;
  103. //ramp up
  104. size_t i = 0;
  105. if (overlap > 0) {
  106. for (; i < overlap; i++) {
  107. v[i] = 0.5 * (1.0 - cos(TWOPI * i / (twoOverlap - 1)));
  108. }
  109. }
  110. //flat top
  111. for (; i < size - overlap; i++) {
  112. v[i] = 1.0;
  113. }
  114. //ramp down
  115. if (overlap > 0) {
  116. for (; i < size; i++) {
  117. int k = i - ((int)size - 2 * overlap);
  118. v[i] = 0.5 * (1.0 - cos(TWOPI * k / (twoOverlap - 1)));
  119. }
  120. }
  121. }
  122. template <typename T>
  123. static void fill_window(T &v, int type, size_t size, size_t overlap) {
  124. if (overlap > size / 2) {
  125. overlap = size / 2;
  126. }
  127. v.resize(size);
  128. switch (type) {
  129. case RDSP_WINDOW_RECTANGULAR:
  130. fillRectangular(v);
  131. break;
  132. case RDSP_WINDOW_TRIANGULAR:
  133. fillTriangular(v, size / 2);
  134. break;
  135. case RDSP_WINDOW_TRIANGULAR_FLAT_TOP:
  136. fillTriangular(v, overlap);
  137. break;
  138. case RDSP_WINDOW_HAMMING:
  139. fillHamming(v, size / 2);
  140. break;
  141. case RDSP_WINDOW_HAMMING_FLAT_TOP:
  142. fillHamming(v, overlap);
  143. break;
  144. case RDSP_WINDOW_HANNING:
  145. fillHanning(v, size / 2);
  146. break;
  147. case RDSP_WINDOW_HANNING_FLAT_TOP:
  148. fillHanning(v, overlap);
  149. break;
  150. default:
  151. ALOGE("Error: unknown window type %d", type);
  152. }
  153. }
  154. //};
  155. #endif //RDSP_H