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