The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

187 lines
6.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. template <typename FloatType>
  20. static inline FloatType ncos (size_t order, size_t i, size_t size) noexcept
  21. {
  22. return std::cos (static_cast<FloatType> (order * i)
  23. * MathConstants<FloatType>::pi / static_cast<FloatType> (size - 1));
  24. }
  25. template <typename FloatType>
  26. WindowingFunction<FloatType>::WindowingFunction (size_t size, WindowingMethod type, bool normalize, FloatType beta)
  27. {
  28. fillWindowingTables (size, type, normalize, beta);
  29. }
  30. template <typename FloatType>
  31. void WindowingFunction<FloatType>::fillWindowingTables (size_t size, WindowingMethod type,
  32. bool normalize, FloatType beta) noexcept
  33. {
  34. windowTable.resize (static_cast<int> (size));
  35. fillWindowingTables (windowTable.getRawDataPointer(), size, type, normalize, beta);
  36. }
  37. template <typename FloatType>
  38. void WindowingFunction<FloatType>::fillWindowingTables (FloatType* samples, size_t size,
  39. WindowingMethod type, bool normalize,
  40. FloatType beta) noexcept
  41. {
  42. switch (type)
  43. {
  44. case rectangular:
  45. {
  46. for (size_t i = 0; i < size; ++i)
  47. samples[i] = static_cast<FloatType> (1);
  48. }
  49. break;
  50. case triangular:
  51. {
  52. auto halfSlots = static_cast<FloatType> (0.5) * static_cast<FloatType> (size - 1);
  53. for (size_t i = 0; i < size; ++i)
  54. samples[i] = static_cast<FloatType> (1.0) - std::fabs ((static_cast<FloatType> (i) - halfSlots) / halfSlots);
  55. }
  56. break;
  57. case hann:
  58. {
  59. for (size_t i = 0; i < size; ++i)
  60. {
  61. auto cos2 = ncos<FloatType> (2, i, size);
  62. samples[i] = static_cast<FloatType> (0.5 - 0.5 * cos2);
  63. }
  64. }
  65. break;
  66. case hamming:
  67. {
  68. for (size_t i = 0; i < size; ++i)
  69. {
  70. auto cos2 = ncos<FloatType> (2, i, size);
  71. samples[i] = static_cast<FloatType> (0.54 - 0.46 * cos2);
  72. }
  73. }
  74. break;
  75. case blackman:
  76. {
  77. constexpr FloatType alpha = 0.16f;
  78. for (size_t i = 0; i < size; ++i)
  79. {
  80. auto cos2 = ncos<FloatType> (2, i, size);
  81. auto cos4 = ncos<FloatType> (4, i, size);
  82. samples[i] = static_cast<FloatType> (0.5 * (1 - alpha) - 0.5 * cos2 + 0.5 * alpha * cos4);
  83. }
  84. }
  85. break;
  86. case blackmanHarris:
  87. {
  88. for (size_t i = 0; i < size; ++i)
  89. {
  90. auto cos2 = ncos<FloatType> (2, i, size);
  91. auto cos4 = ncos<FloatType> (4, i, size);
  92. auto cos6 = ncos<FloatType> (6, i, size);
  93. samples[i] = static_cast<FloatType> (0.35875 - 0.48829 * cos2 + 0.14128 * cos4 - 0.01168 * cos6);
  94. }
  95. }
  96. break;
  97. case flatTop:
  98. {
  99. for (size_t i = 0; i < size; ++i)
  100. {
  101. auto cos2 = ncos<FloatType> (2, i, size);
  102. auto cos4 = ncos<FloatType> (4, i, size);
  103. auto cos6 = ncos<FloatType> (6, i, size);
  104. auto cos8 = ncos<FloatType> (8, i, size);
  105. samples[i] = static_cast<FloatType> (1.0 - 1.93 * cos2 + 1.29 * cos4 - 0.388 * cos6 + 0.028 * cos8);
  106. }
  107. }
  108. break;
  109. case kaiser:
  110. {
  111. const double factor = 1.0 / SpecialFunctions::besselI0 (beta);
  112. for (size_t i = 0; i < size; ++i)
  113. samples[i] = static_cast<FloatType> (SpecialFunctions::besselI0 (beta * std::sqrt (1.0 - std::pow ((i - 0.5 * (size - 1.0))
  114. / ( 0.5 * (size - 1.0)), 2.0)))
  115. * factor);
  116. }
  117. break;
  118. default:
  119. jassertfalse;
  120. break;
  121. }
  122. // DC frequency amplitude must be one
  123. if (normalize)
  124. {
  125. FloatType sum = {};
  126. for (size_t i = 0; i < size; ++i)
  127. sum += samples[i];
  128. auto factor = static_cast<FloatType> (size) / sum;
  129. FloatVectorOperations::multiply (samples, factor, static_cast<int> (size));
  130. }
  131. }
  132. template <typename FloatType>
  133. void WindowingFunction<FloatType>::multiplyWithWindowingTable (FloatType* samples, size_t size) noexcept
  134. {
  135. FloatVectorOperations::multiply (samples, windowTable.getRawDataPointer(), jmin (static_cast<int> (size), windowTable.size()));
  136. }
  137. template <typename FloatType>
  138. const char* WindowingFunction<FloatType>::getWindowingMethodName (WindowingMethod type) noexcept
  139. {
  140. switch (type)
  141. {
  142. case rectangular: return "Rectangular";
  143. case triangular: return "Triangular";
  144. case hann: return "Hann";
  145. case hamming: return "Hamming";
  146. case blackman: return "Blackman";
  147. case blackmanHarris: return "Blackman-Harris";
  148. case flatTop: return "FlatTop";
  149. case kaiser: return "Kaiser";
  150. default: jassertfalse; return "";
  151. }
  152. }
  153. template struct WindowingFunction<float>;
  154. template struct WindowingFunction<double>;