VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_dsp / maths / juce_LogRampedValue.h
blob998e2494138febe3f35149301f63b3915331eab3
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
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.
23 ==============================================================================
26 namespace juce
28 namespace dsp
31 //==============================================================================
32 /**
33 Utility class for logarithmically smoothed linear values.
35 Logarithmically smoothed values can be more relevant than linear ones for
36 specific cases such as algorithm change smoothing, using two of them in
37 opposite directions.
39 The gradient of the logarithmic/exponential slope can be configured by
40 calling LogRampedValue::setLogParameters.
42 @see SmoothedValue
44 @tags{DSP}
46 template <typename FloatType>
47 class LogRampedValue : public SmoothedValueBase <LogRampedValue <FloatType>>
49 public:
50 //==============================================================================
51 /** Constructor. */
52 LogRampedValue() = default;
54 /** Constructor. */
55 LogRampedValue (FloatType initialValue) noexcept
57 // Visual Studio can't handle base class initialisation with CRTP
58 this->currentValue = initialValue;
59 this->target = initialValue;
62 //==============================================================================
63 /** Sets the behaviour of the log ramp.
64 @param midPointAmplitudedB Sets the amplitude of the mid point in
65 decibels, with the target value at 0 dB
66 and the initial value at -inf dB
67 @param rateOfChangeShouldIncrease If true then the ramp starts shallow
68 and gets progressively steeper, if false
69 then the ramp is initially steep and
70 flattens out as you approach the target
71 value
73 void setLogParameters (FloatType midPointAmplitudedB, bool rateOfChangeShouldIncrease) noexcept
75 jassert (midPointAmplitudedB < (FloatType) 0.0);
76 B = Decibels::decibelsToGain (midPointAmplitudedB);
78 increasingRateOfChange = rateOfChangeShouldIncrease;
81 //==============================================================================
82 /** Reset to a new sample rate and ramp length.
83 @param sampleRate The sample rate
84 @param rampLengthInSeconds The duration of the ramp in seconds
86 void reset (double sampleRate, double rampLengthInSeconds) noexcept
88 jassert (sampleRate > 0 && rampLengthInSeconds >= 0);
89 reset ((int) std::floor (rampLengthInSeconds * sampleRate));
92 /** Set a new ramp length directly in samples.
93 @param numSteps The number of samples over which the ramp should be active
95 void reset (int numSteps) noexcept
97 stepsToTarget = numSteps;
99 this->setCurrentAndTargetValue (this->target);
101 updateRampParameters();
104 //==============================================================================
105 /** Set a new target value.
107 @param newValue The new target value
109 void setTargetValue (FloatType newValue) noexcept
111 if (newValue == this->target)
112 return;
114 if (stepsToTarget <= 0)
116 this->setCurrentAndTargetValue (newValue);
117 return;
120 this->target = newValue;
121 this->countdown = stepsToTarget;
122 source = this->currentValue;
124 updateRampParameters();
127 //==============================================================================
128 /** Compute the next value.
129 @returns Smoothed value
131 FloatType getNextValue() noexcept
133 if (! this->isSmoothing())
134 return this->target;
136 --(this->countdown);
138 temp *= r; temp += d;
139 this->currentValue = jmap (temp, source, this->target);
141 return this->currentValue;
144 //==============================================================================
145 /** Skip the next numSamples samples.
147 This is identical to calling getNextValue numSamples times.
148 @see getNextValue
150 FloatType skip (int numSamples) noexcept
152 if (numSamples >= this->countdown)
154 this->setCurrentAndTargetValue (this->target);
155 return this->target;
158 this->countdown -= numSamples;
160 auto rN = (FloatType) std::pow (r, numSamples);
161 temp *= rN;
162 temp += d * (rN - (FloatType) 1) / (r - (FloatType) 1);
164 this->currentValue = jmap (temp, source, this->target);
165 return this->currentValue;
168 private:
169 //==============================================================================
170 void updateRampParameters()
172 auto D = increasingRateOfChange ? B : (FloatType) 1 - B;
173 auto base = ((FloatType) 1 / D) - (FloatType) 1;
174 r = std::pow (base, (FloatType) 2 / (FloatType) stepsToTarget);
175 auto rN = std::pow (r, (FloatType) stepsToTarget);
176 d = (r - (FloatType) 1) / (rN - (FloatType) 1);
177 temp = 0;
180 //==============================================================================
181 bool increasingRateOfChange = true;
182 FloatType B = Decibels::decibelsToGain ((FloatType) -40);
184 int stepsToTarget = 0;
185 FloatType temp = 0, source = 0, r = 0, d = 1;
188 } // namespace dsp
189 } // namespace juce