OpenShot Audio Library | OpenShotAudio  0.3.1
juce_LookupTable.h
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 
52 template <typename FloatType>
54 {
55 public:
63  LookupTable();
64 
71  LookupTable (const std::function<FloatType(size_t)>& functionToApproximate, size_t numPointsToUse);
72 
83  void initialise (const std::function<FloatType(size_t)>& functionToApproximate, size_t numPointsToUse);
84 
85  //==============================================================================
96  FloatType getUnchecked (FloatType index) const noexcept
97  {
98  jassert (isInitialised()); // Use the non-default constructor or call initialise() before first use
99  jassert (isPositiveAndBelow (index, FloatType (getNumPoints())));
100 
101  auto i = truncatePositiveToUnsignedInt (index);
102  auto f = index - FloatType (i);
103  jassert (isPositiveAndBelow (f, FloatType (1)));
104 
105  auto x0 = data.getUnchecked (static_cast<int> (i));
106  auto x1 = data.getUnchecked (static_cast<int> (i + 1));
107 
108  return jmap (f, x0, x1);
109  }
110 
111  //==============================================================================
124  FloatType get (FloatType index) const noexcept
125  {
126  if (index >= getNumPoints())
127  index = static_cast<FloatType> (getGuardIndex());
128  else if (index < 0)
129  index = {};
130 
131  return getUnchecked (index);
132  }
133 
134  //==============================================================================
136  FloatType operator[] (FloatType index) const noexcept { return getUnchecked (index); }
137 
139  size_t getNumPoints() const noexcept { return static_cast<size_t> (data.size()) - 1; }
140 
142  bool isInitialised() const noexcept { return data.size() > 1; }
143 
144 private:
145  //==============================================================================
146  Array<FloatType> data;
147 
148  void prepare() noexcept;
149  static size_t getRequiredBufferSize (size_t numPointsToUse) noexcept { return numPointsToUse + 1; }
150  size_t getGuardIndex() const noexcept { return getRequiredBufferSize (getNumPoints()) - 1; }
151 
152  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookupTable)
153 };
154 
155 
156 //==============================================================================
174 template <typename FloatType>
176 {
177 public:
178  //==============================================================================
186  LookupTableTransform() = default;
187 
188  //==============================================================================
199  LookupTableTransform (const std::function<FloatType(FloatType)>& functionToApproximate,
200  FloatType minInputValueToUse,
201  FloatType maxInputValueToUse,
202  size_t numPoints)
203  {
204  initialise (functionToApproximate, minInputValueToUse, maxInputValueToUse, numPoints);
205  }
206 
207  //==============================================================================
218  void initialise (const std::function<FloatType(FloatType)>& functionToApproximate,
219  FloatType minInputValueToUse,
220  FloatType maxInputValueToUse,
221  size_t numPoints);
222 
223  //==============================================================================
234  FloatType processSampleUnchecked (FloatType value) const noexcept
235  {
236  jassert (value >= minInputValue && value <= maxInputValue);
237  return lookupTable[scaler * value + offset];
238  }
239 
240  //==============================================================================
254  FloatType processSample (FloatType value) const noexcept
255  {
256  auto index = scaler * jlimit (minInputValue, maxInputValue, value) + offset;
257  jassert (isPositiveAndBelow (index, FloatType (lookupTable.getNumPoints())));
258 
259  return lookupTable[index];
260  }
261 
262  //==============================================================================
264  FloatType operator[] (FloatType index) const noexcept { return processSampleUnchecked (index); }
265 
267  FloatType operator() (FloatType index) const noexcept { return processSample (index); }
268 
269  //==============================================================================
273  void processUnchecked (const FloatType* input, FloatType* output, size_t numSamples) const noexcept
274  {
275  for (size_t i = 0; i < numSamples; ++i)
276  output[i] = processSampleUnchecked (input[i]);
277  }
278 
279  //==============================================================================
283  void process (const FloatType* input, FloatType* output, size_t numSamples) const noexcept
284  {
285  for (size_t i = 0; i < numSamples; ++i)
286  output[i] = processSample (input[i]);
287  }
288 
289  //==============================================================================
312  static double calculateMaxRelativeError (const std::function<FloatType(FloatType)>& functionToApproximate,
313  FloatType minInputValue,
314  FloatType maxInputValue,
315  size_t numPoints,
316  size_t numTestPoints = 0);
317 private:
318  //==============================================================================
319  static double calculateRelativeDifference (double, double) noexcept;
320 
321  //==============================================================================
322  LookupTable<FloatType> lookupTable;
323 
324  FloatType minInputValue, maxInputValue;
325  FloatType scaler, offset;
326 
327  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookupTableTransform)
328 };
329 
330 } // namespace dsp
331 } // namespace juce
ElementType getUnchecked(int index) const
Definition: juce_Array.h:252
int size() const noexcept
Definition: juce_Array.h:215
LookupTableTransform(const std::function< FloatType(FloatType)> &functionToApproximate, FloatType minInputValueToUse, FloatType maxInputValueToUse, size_t numPoints)
FloatType operator[](FloatType index) const noexcept
FloatType processSampleUnchecked(FloatType value) const noexcept
void initialise(const std::function< FloatType(FloatType)> &functionToApproximate, FloatType minInputValueToUse, FloatType maxInputValueToUse, size_t numPoints)
void process(const FloatType *input, FloatType *output, size_t numSamples) const noexcept
void processUnchecked(const FloatType *input, FloatType *output, size_t numSamples) const noexcept
FloatType processSample(FloatType value) const noexcept
FloatType operator()(FloatType index) const noexcept
static double calculateMaxRelativeError(const std::function< FloatType(FloatType)> &functionToApproximate, FloatType minInputValue, FloatType maxInputValue, size_t numPoints, size_t numTestPoints=0)
FloatType get(FloatType index) const noexcept
FloatType operator[](FloatType index) const noexcept
FloatType getUnchecked(FloatType index) const noexcept
bool isInitialised() const noexcept
size_t getNumPoints() const noexcept
void initialise(const std::function< FloatType(size_t)> &functionToApproximate, size_t numPointsToUse)