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.

194 lines
6.5KB

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