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.

195 lines
6.4KB

  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. namespace juce
  20. {
  21. namespace dsp
  22. {
  23. template <typename FloatType>
  24. static inline FloatType ncos (size_t order, size_t i, size_t size) noexcept
  25. {
  26. return std::cos (static_cast<FloatType> (order * i)
  27. * MathConstants<FloatType>::pi / static_cast<FloatType> (size - 1));
  28. }
  29. template <typename FloatType>
  30. WindowingFunction<FloatType>::WindowingFunction (size_t size, WindowingMethod type, bool normalise, FloatType beta)
  31. {
  32. fillWindowingTables (size, type, normalise, beta);
  33. }
  34. template <typename FloatType>
  35. void WindowingFunction<FloatType>::fillWindowingTables (size_t size, WindowingMethod type,
  36. bool normalise, FloatType beta) noexcept
  37. {
  38. windowTable.resize (static_cast<int> (size));
  39. fillWindowingTables (windowTable.getRawDataPointer(), size, type, normalise, beta);
  40. }
  41. template <typename FloatType>
  42. void WindowingFunction<FloatType>::fillWindowingTables (FloatType* samples, size_t size,
  43. WindowingMethod type, bool normalise,
  44. FloatType beta) noexcept
  45. {
  46. switch (type)
  47. {
  48. case rectangular:
  49. {
  50. for (size_t i = 0; i < size; ++i)
  51. samples[i] = static_cast<FloatType> (1);
  52. }
  53. break;
  54. case triangular:
  55. {
  56. auto halfSlots = static_cast<FloatType> (0.5) * static_cast<FloatType> (size - 1);
  57. for (size_t i = 0; i < size; ++i)
  58. samples[i] = static_cast<FloatType> (1.0) - std::abs ((static_cast<FloatType> (i) - halfSlots) / halfSlots);
  59. }
  60. break;
  61. case hann:
  62. {
  63. for (size_t i = 0; i < size; ++i)
  64. {
  65. auto cos2 = ncos<FloatType> (2, i, size);
  66. samples[i] = static_cast<FloatType> (0.5 - 0.5 * cos2);
  67. }
  68. }
  69. break;
  70. case hamming:
  71. {
  72. for (size_t i = 0; i < size; ++i)
  73. {
  74. auto cos2 = ncos<FloatType> (2, i, size);
  75. samples[i] = static_cast<FloatType> (0.54 - 0.46 * cos2);
  76. }
  77. }
  78. break;
  79. case blackman:
  80. {
  81. constexpr FloatType alpha = 0.16f;
  82. for (size_t i = 0; i < size; ++i)
  83. {
  84. auto cos2 = ncos<FloatType> (2, i, size);
  85. auto cos4 = ncos<FloatType> (4, i, size);
  86. samples[i] = static_cast<FloatType> (0.5 * (1 - alpha) - 0.5 * cos2 + 0.5 * alpha * cos4);
  87. }
  88. }
  89. break;
  90. case blackmanHarris:
  91. {
  92. for (size_t i = 0; i < size; ++i)
  93. {
  94. auto cos2 = ncos<FloatType> (2, i, size);
  95. auto cos4 = ncos<FloatType> (4, i, size);
  96. auto cos6 = ncos<FloatType> (6, i, size);
  97. samples[i] = static_cast<FloatType> (0.35875 - 0.48829 * cos2 + 0.14128 * cos4 - 0.01168 * cos6);
  98. }
  99. }
  100. break;
  101. case flatTop:
  102. {
  103. for (size_t i = 0; i < size; ++i)
  104. {
  105. auto cos2 = ncos<FloatType> (2, i, size);
  106. auto cos4 = ncos<FloatType> (4, i, size);
  107. auto cos6 = ncos<FloatType> (6, i, size);
  108. auto cos8 = ncos<FloatType> (8, i, size);
  109. samples[i] = static_cast<FloatType> (1.0 - 1.93 * cos2 + 1.29 * cos4 - 0.388 * cos6 + 0.028 * cos8);
  110. }
  111. }
  112. break;
  113. case kaiser:
  114. {
  115. const double factor = 1.0 / SpecialFunctions::besselI0 (beta);
  116. for (size_t i = 0; i < size; ++i)
  117. samples[i] = static_cast<FloatType> (SpecialFunctions::besselI0 (beta * std::sqrt (1.0 - std::pow ((i - 0.5 * (size - 1.0))
  118. / ( 0.5 * (size - 1.0)), 2.0)))
  119. * factor);
  120. }
  121. break;
  122. default:
  123. jassertfalse;
  124. break;
  125. }
  126. // DC frequency amplitude must be one
  127. if (normalise)
  128. {
  129. FloatType sum (0);
  130. for (size_t i = 0; i < size; ++i)
  131. sum += samples[i];
  132. auto factor = static_cast<FloatType> (size) / sum;
  133. FloatVectorOperations::multiply (samples, factor, static_cast<int> (size));
  134. }
  135. }
  136. template <typename FloatType>
  137. void WindowingFunction<FloatType>::multiplyWithWindowingTable (FloatType* samples, size_t size) noexcept
  138. {
  139. FloatVectorOperations::multiply (samples, windowTable.getRawDataPointer(), jmin (static_cast<int> (size), windowTable.size()));
  140. }
  141. template <typename FloatType>
  142. const char* WindowingFunction<FloatType>::getWindowingMethodName (WindowingMethod type) noexcept
  143. {
  144. switch (type)
  145. {
  146. case rectangular: return "Rectangular";
  147. case triangular: return "Triangular";
  148. case hann: return "Hann";
  149. case hamming: return "Hamming";
  150. case blackman: return "Blackman";
  151. case blackmanHarris: return "Blackman-Harris";
  152. case flatTop: return "Flat Top";
  153. case kaiser: return "Kaiser";
  154. default: jassertfalse; return "";
  155. }
  156. }
  157. template class WindowingFunction<float>;
  158. template class WindowingFunction<double>;
  159. } // namespace dsp
  160. } // namespace juce