OpenShot Audio Library | OpenShotAudio  0.6.0
juce_LookupTable.h
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 
49 template <typename FloatType>
51 {
52 public:
60  LookupTable();
61 
68  LookupTable (const std::function<FloatType (size_t)>& functionToApproximate, size_t numPointsToUse);
69 
80  void initialise (const std::function<FloatType (size_t)>& functionToApproximate, size_t numPointsToUse);
81 
82  //==============================================================================
93  FloatType getUnchecked (FloatType index) const noexcept
94  {
95  jassert (isInitialised()); // Use the non-default constructor or call initialise() before first use
96  jassert (isPositiveAndBelow (index, FloatType (getNumPoints())));
97 
98  auto i = truncatePositiveToUnsignedInt (index);
99  auto f = index - FloatType (i);
100  jassert (isPositiveAndBelow (f, FloatType (1)));
101 
102  auto x0 = data.getUnchecked (static_cast<int> (i));
103  auto x1 = data.getUnchecked (static_cast<int> (i + 1));
104 
105  return jmap (f, x0, x1);
106  }
107 
108  //==============================================================================
121  FloatType get (FloatType index) const noexcept
122  {
123  if (index >= (FloatType) getNumPoints())
124  index = static_cast<FloatType> (getGuardIndex());
125  else if (index < 0)
126  index = {};
127 
128  return getUnchecked (index);
129  }
130 
131  //==============================================================================
133  FloatType operator[] (FloatType index) const noexcept { return getUnchecked (index); }
134 
136  size_t getNumPoints() const noexcept { return static_cast<size_t> (data.size()) - 1; }
137 
139  bool isInitialised() const noexcept { return data.size() > 1; }
140 
141 private:
142  //==============================================================================
143  Array<FloatType> data;
144 
145  void prepare() noexcept;
146  static size_t getRequiredBufferSize (size_t numPointsToUse) noexcept { return numPointsToUse + 1; }
147  size_t getGuardIndex() const noexcept { return getRequiredBufferSize (getNumPoints()) - 1; }
148 
149  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookupTable)
150 };
151 
152 
153 //==============================================================================
171 template <typename FloatType>
173 {
174 public:
175  //==============================================================================
183  LookupTableTransform() = default;
184 
185  //==============================================================================
196  LookupTableTransform (const std::function<FloatType (FloatType)>& functionToApproximate,
197  FloatType minInputValueToUse,
198  FloatType maxInputValueToUse,
199  size_t numPoints)
200  {
201  initialise (functionToApproximate, minInputValueToUse, maxInputValueToUse, numPoints);
202  }
203 
204  //==============================================================================
215  void initialise (const std::function<FloatType (FloatType)>& functionToApproximate,
216  FloatType minInputValueToUse,
217  FloatType maxInputValueToUse,
218  size_t numPoints);
219 
220  //==============================================================================
231  FloatType processSampleUnchecked (FloatType value) const noexcept
232  {
233  jassert (value >= minInputValue && value <= maxInputValue);
234  return lookupTable[scaler * value + offset];
235  }
236 
237  //==============================================================================
251  FloatType processSample (FloatType value) const noexcept
252  {
253  auto index = scaler * jlimit (minInputValue, maxInputValue, value) + offset;
254  jassert (isPositiveAndBelow (index, FloatType (lookupTable.getNumPoints())));
255 
256  return lookupTable[index];
257  }
258 
259  //==============================================================================
261  FloatType operator[] (FloatType index) const noexcept { return processSampleUnchecked (index); }
262 
264  FloatType operator() (FloatType index) const noexcept { return processSample (index); }
265 
266  //==============================================================================
270  void processUnchecked (const FloatType* input, FloatType* output, size_t numSamples) const noexcept
271  {
272  for (size_t i = 0; i < numSamples; ++i)
273  output[i] = processSampleUnchecked (input[i]);
274  }
275 
276  //==============================================================================
280  void process (const FloatType* input, FloatType* output, size_t numSamples) const noexcept
281  {
282  for (size_t i = 0; i < numSamples; ++i)
283  output[i] = processSample (input[i]);
284  }
285 
286  //==============================================================================
309  static double calculateMaxRelativeError (const std::function<FloatType (FloatType)>& functionToApproximate,
310  FloatType minInputValue,
311  FloatType maxInputValue,
312  size_t numPoints,
313  size_t numTestPoints = 0);
314 private:
315  //==============================================================================
316  static double calculateRelativeDifference (double, double) noexcept;
317 
318  //==============================================================================
319  LookupTable<FloatType> lookupTable;
320 
321  FloatType minInputValue, maxInputValue;
322  FloatType scaler, offset;
323 
324  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookupTableTransform)
325 };
326 
327 } // namespace juce::dsp
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)