OpenShot Library | OpenShotAudio  0.2.2
juce_LogRampedValue.h
1 
2 /** @weakgroup juce_dsp-maths
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  By using JUCE, you agree to the terms of both the JUCE 5 End-User License
15  Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
16  27th April 2017).
17 
18  End User License Agreement: www.juce.com/juce-5-licence
19  Privacy Policy: www.juce.com/juce-5-privacy-policy
20 
21  Or: You may also use this code under the terms of the GPL v3 (see
22  www.gnu.org/licenses).
23 
24  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
25  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
26  DISCLAIMED.
27 
28  ==============================================================================
29 */
30 
31 namespace juce
32 {
33 namespace dsp
34 {
35 
36 //==============================================================================
37 /**
38  Utility class for logarithmically smoothed linear values.
39 
40  Logarithmically smoothed values can be more relevant than linear ones for
41  specific cases such as algorithm change smoothing, using two of them in
42  opposite directions.
43 
44  The gradient of the logarithmic/exponential slope can be configured by
45  calling LogRampedValue::setLogParameters.
46 
47  @see SmoothedValue
48 
49  @tags{DSP}
50 */
51 template <typename FloatType>
52 class LogRampedValue : public SmoothedValueBase <LogRampedValue <FloatType>>
53 {
54 public:
55  //==============================================================================
56  /** Constructor. */
57  LogRampedValue() = default;
58 
59  /** Constructor. */
60  LogRampedValue (FloatType initialValue) noexcept
61  {
62  // Visual Studio can't handle base class initialisation with CRTP
63  this->currentValue = initialValue;
64  this->target = initialValue;
65  }
66 
67  //==============================================================================
68  /** Sets the behaviour of the log ramp.
69  @param midPointAmplitudedB Sets the amplitude of the mid point in
70  decibels, with the target value at 0 dB
71  and the initial value at -inf dB
72  @param rateOfChangeShouldIncrease If true then the ramp starts shallow
73  and gets progressively steeper, if false
74  then the ramp is initially steep and
75  flattens out as you approach the target
76  value
77  */
78  void setLogParameters (FloatType midPointAmplitudedB, bool rateOfChangeShouldIncrease) noexcept
79  {
80  jassert (midPointAmplitudedB < (FloatType) 0.0);
81  B = Decibels::decibelsToGain (midPointAmplitudedB);
82 
83  increasingRateOfChange = rateOfChangeShouldIncrease;
84  }
85 
86  //==============================================================================
87  /** Reset to a new sample rate and ramp length.
88  @param sampleRate The sample rate
89  @param rampLengthInSeconds The duration of the ramp in seconds
90  */
91  void reset (double sampleRate, double rampLengthInSeconds) noexcept
92  {
93  jassert (sampleRate > 0 && rampLengthInSeconds >= 0);
94  reset ((int) std::floor (rampLengthInSeconds * sampleRate));
95  }
96 
97  /** Set a new ramp length directly in samples.
98  @param numSteps The number of samples over which the ramp should be active
99  */
100  void reset (int numSteps) noexcept
101  {
102  stepsToTarget = numSteps;
103 
104  this->setCurrentAndTargetValue (this->target);
105 
106  updateRampParameters();
107  }
108 
109  //==============================================================================
110  /** Set a new target value.
111 
112  @param newValue The new target value
113  */
114  void setTargetValue (FloatType newValue) noexcept
115  {
116  if (newValue == this->target)
117  return;
118 
119  if (stepsToTarget <= 0)
120  {
121  this->setCurrentAndTargetValue (newValue);
122  return;
123  }
124 
125  this->target = newValue;
126  this->countdown = stepsToTarget;
127  source = this->currentValue;
128 
129  updateRampParameters();
130  }
131 
132  //==============================================================================
133  /** Compute the next value.
134  @returns Smoothed value
135  */
136  FloatType getNextValue() noexcept
137  {
138  if (! this->isSmoothing())
139  return this->target;
140 
141  --(this->countdown);
142 
143  temp *= r; temp += d;
144  this->currentValue = jmap (temp, source, this->target);
145 
146  return this->currentValue;
147  }
148 
149  //==============================================================================
150  /** Skip the next numSamples samples.
151 
152  This is identical to calling getNextValue numSamples times.
153  @see getNextValue
154  */
155  FloatType skip (int numSamples) noexcept
156  {
157  if (numSamples >= this->countdown)
158  {
159  this->setCurrentAndTargetValue (this->target);
160  return this->target;
161  }
162 
163  this->countdown -= numSamples;
164 
165  auto rN = (FloatType) std::pow (r, numSamples);
166  temp *= rN;
167  temp += d * (rN - (FloatType) 1) / (r - (FloatType) 1);
168 
169  this->currentValue = jmap (temp, source, this->target);
170  return this->currentValue;
171  }
172 
173 private:
174  //==============================================================================
175  void updateRampParameters()
176  {
177  auto D = increasingRateOfChange ? B : (FloatType) 1 - B;
178  auto base = ((FloatType) 1 / D) - (FloatType) 1;
179  r = std::pow (base, (FloatType) 2 / (FloatType) stepsToTarget);
180  auto rN = std::pow (r, (FloatType) stepsToTarget);
181  d = (r - (FloatType) 1) / (rN - (FloatType) 1);
182  temp = 0;
183  }
184 
185  //==============================================================================
186  bool increasingRateOfChange = true;
187  FloatType B = Decibels::decibelsToGain ((FloatType) -40);
188 
189  int stepsToTarget = 0;
190  FloatType temp = 0, source = 0, r = 0, d = 1;
191 };
192 
193 } // namespace dsp
194 } // namespace juce
195 
196 /** @}*/
static Type decibelsToGain(Type decibels, Type minusInfinityDb=Type(defaultMinusInfinitydB))
Converts a dBFS value to its equivalent gain level.
Definition: juce_Decibels.h:46
A base class for the smoothed value classes.
bool isSmoothing() const noexcept
Returns true if the current value is currently being interpolated.
void setCurrentAndTargetValue(FloatType newValue)
Sets the current value and the target value.
Utility class for logarithmically smoothed linear values.
LogRampedValue()=default
Constructor.
FloatType getNextValue() noexcept
Compute the next value.
void reset(double sampleRate, double rampLengthInSeconds) noexcept
Reset to a new sample rate and ramp length.
void setLogParameters(FloatType midPointAmplitudedB, bool rateOfChangeShouldIncrease) noexcept
Sets the behaviour of the log ramp.
FloatType skip(int numSamples) noexcept
Skip the next numSamples samples.
LogRampedValue(FloatType initialValue) noexcept
Constructor.
void reset(int numSteps) noexcept
Set a new ramp length directly in samples.
void setTargetValue(FloatType newValue) noexcept
Set a new target value.