OpenShot Library | OpenShotAudio 0.2.2
juce_LookupTable.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
27namespace juce
28{
29namespace dsp
30{
31
32template <typename FloatType>
34{
35 data.resize (1);
36}
37
38template <typename FloatType>
39LookupTable<FloatType>::LookupTable (const std::function<FloatType(size_t)>& functionToApproximate,
40 size_t numPointsToUse)
41{
42 initialise (functionToApproximate, numPointsToUse);
43}
44
45//==============================================================================
46template <typename FloatType>
47void LookupTable<FloatType>::initialise (const std::function<FloatType(size_t)>& functionToApproximate,
48 size_t numPointsToUse)
49{
50 data.resize (static_cast<int> (getRequiredBufferSize (numPointsToUse)));
51
52 for (size_t i = 0; i < numPointsToUse; ++i)
53 {
54 auto value = functionToApproximate (i);
55
56 jassert (! std::isnan (value));
57 jassert (! std::isinf (value));
58 // Make sure functionToApproximate returns a sensible value for the entire specified range.
59 // E.g., this won't work for zero: [] (size_t i) { return 1.0f / i; }
60
61 data.getReference (static_cast<int> (i)) = value;
62 }
63
64 prepare();
65}
66
67template <typename FloatType>
69{
70 auto guardIndex = static_cast<int> (getGuardIndex());
71 data.getReference (guardIndex) = data.getUnchecked (guardIndex - 1);
72}
73
74template <typename FloatType>
75void LookupTableTransform<FloatType>::initialise (const std::function<FloatType(FloatType)>& functionToApproximate,
76 FloatType minInputValueToUse,
77 FloatType maxInputValueToUse,
78 size_t numPoints)
79{
80 jassert (maxInputValueToUse > minInputValueToUse);
81
82 minInputValue = minInputValueToUse;
83 maxInputValue = maxInputValueToUse;
84 scaler = FloatType (numPoints - 1) / (maxInputValueToUse - minInputValueToUse);
85 offset = -minInputValueToUse * scaler;
86
87 const auto initFn = [functionToApproximate, minInputValueToUse, maxInputValueToUse, numPoints] (size_t i)
88 {
89 return functionToApproximate (
90 jlimit (
91 minInputValueToUse, maxInputValueToUse,
92 jmap (FloatType (i), FloatType (0), FloatType (numPoints - 1), minInputValueToUse, maxInputValueToUse))
93 );
94 };
95
96 lookupTable.initialise (initFn, numPoints);
97}
98
99//==============================================================================
100template <typename FloatType>
101double LookupTableTransform<FloatType>::calculateMaxRelativeError (const std::function<FloatType(FloatType)>& functionToApproximate,
102 FloatType minInputValue,
103 FloatType maxInputValue,
104 size_t numPoints,
105 size_t numTestPoints)
106{
107 jassert (maxInputValue > minInputValue);
108
109 if (numTestPoints == 0)
110 numTestPoints = 100 * numPoints; // use default
111
112 LookupTableTransform transform (functionToApproximate, minInputValue, maxInputValue, numPoints);
113
114 double maxError = 0;
115
116 for (size_t i = 0; i < numTestPoints; ++i)
117 {
118 auto inputValue = jmap (FloatType (i), FloatType (0), FloatType (numTestPoints - 1), minInputValue, maxInputValue);
119 auto approximatedOutputValue = transform.processSample (inputValue);
120 auto referenceOutputValue = functionToApproximate (inputValue);
121
122 maxError = jmax (maxError, calculateRelativeDifference ((double) referenceOutputValue, (double) approximatedOutputValue));
123 }
124
125 return maxError;
126}
127
128//==============================================================================
129template <typename FloatType>
130double LookupTableTransform<FloatType>::calculateRelativeDifference (double x, double y) noexcept
131{
132 static const auto eps = std::numeric_limits<double>::min();
133
134 auto absX = std::abs (x);
135 auto absY = std::abs (y);
136 auto absDiff = std::abs (x - y);
137
138 if (absX < eps)
139 {
140 if (absY >= eps)
141 return absDiff / absY;
142
143 return absDiff; // return the absolute error if both numbers are too close to zero
144 }
145
146 return absDiff / std::min (absX, absY);
147}
148
149//==============================================================================
150template class LookupTable<float>;
151template class LookupTable<double>;
152
153template class LookupTableTransform<float>;
154template class LookupTableTransform<double>;
155
156} // namespace dsp
157} // namespace juce
Class for approximating expensive arithmetic operations.
void initialise(const std::function< FloatType(FloatType)> &functionToApproximate, FloatType minInputValueToUse, FloatType maxInputValueToUse, size_t numPoints)
Initialises or changes the parameters of a LookupTableTransform object.
FloatType processSample(FloatType value) const noexcept
Calculates the approximated value for the given input value with range checking.
static double calculateMaxRelativeError(const std::function< FloatType(FloatType)> &functionToApproximate, FloatType minInputValue, FloatType maxInputValue, size_t numPoints, size_t numTestPoints=0)
Calculates the maximum relative error of the approximation for the specified parameter set.
Class for efficiently approximating expensive arithmetic operations.
FloatType getUnchecked(FloatType index) const noexcept
Calculates the approximated value for the given index without range checking.
void initialise(const std::function< FloatType(size_t)> &functionToApproximate, size_t numPointsToUse)
Initialises or changes the parameters of a LookupTable object.
LookupTable()
Creates an uninitialised LookupTable object.