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