NAP
rampedvalue.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 // Std includes
8 #include <atomic>
9 #include <iostream>
10 #include <assert.h>
11 
12 // Nap includes
13 #include <nap/signalslot.h>
14 #include <nap/logger.h>
15 
16 // Audo includes
17 #include <audio/utility/audiotypes.h>
18 #include <audio/utility/dirtyflag.h>
19 #include <cmath>
20 
21 namespace nap
22 {
23  namespace audio
24  {
25 
30  template<typename T>
32  {
33  public:
34  inline static constexpr T smallestFactor = 0.0001f;
35 
36  public:
37  RampedValue(const T& initValue) : mValue(initValue) { }
38 
39 
43  void setValue(const T& value)
44  {
45  stop();
46  mValue = value;
47  }
48 
55  void ramp(const T& destination, int stepCount, RampMode mode = RampMode::Linear)
56  {
57  assert(stepCount >= 0);
58 
59  mDestination.store(destination);
60  mStepCount.store(stepCount);
61  mRampMode.store(mode);
62 
63  updateRamp();
64  }
65 
69  void stop() { mStepCounter = 0; }
70 
76  {
77  RampMode rampMode = mRampMode.load();
78 
79  if (mStepCounter > 0) {
80  switch (rampMode) {
81  case RampMode::Linear:
82  mValue = mValue + mIncrement;
83  break;
84  case RampMode::Exponential:
85  mValue = mValue * mFactor;
86  break;
87  }
88  mStepCounter--;
89  if (mStepCounter == 0) {
90  if (rampMode == RampMode::Exponential && mDestinationZero)
91  mValue = 0;
92  else
93  mValue = mDestination.load();
95  }
96  }
97 
98  return mValue;
99  }
100 
105  T getValue() const { return mValue; }
106 
111  bool isRamping() const { return mStepCounter > 0; }
112 
117 
118  private:
119  void updateRamp()
120  {
121  T destination = mDestination.load();
122  int stepCount = mStepCount.load();
123 
124  // if there are zero steps we reach the destination of the ramp immediately
125  if (stepCount <= 0)
126  {
127  mStepCounter = 0;
128  mValue = destination;
129  destinationReachedSignal(mValue);
130  return;
131  }
132 
133  mStepCounter = mStepCount;
134 
135  switch (mRampMode.load())
136  {
137  case RampMode::Linear:
138  mIncrement = (destination - mValue) / T(stepCount);
139  break;
140 
141  case RampMode::Exponential:
142  // avoid divisions by zero by avoiding mValue = 0
143  if (mValue == 0)
144  mValue = destination * smallestFactor; // this is a 140dB ramp up from mValue to mDestination
145 
146  // avoid divisions by zero by avoiding mDestination = 0
147  if (destination == 0)
148  {
149  destination = mValue * smallestFactor; // this is a 140 dB ramp down from mValue to mDestination
150  mDestinationZero = true;
151  }
152  else
153  mDestinationZero = false;
154 
155  // calculate the increment factor
156  mFactor = pow(double(destination / mValue), double(1.0 / stepCount));
157  break;
158  }
159  }
160 
161  private:
162  T mValue; // Value that is being controlled by this object.
163 
164  union
165  {
166  T mIncrement; // Increment value per step of the current ramp when mode is linear.
167  T mFactor; // Factor value per step of the current ramp when mode is exponential.
168  };
169  std::atomic<T> mDestination = { 0 }; // Destination value of the current ramp.
170  std::atomic<int> mStepCount = { 0 }; // Number of steps in the ramp.
171  int mStepCounter = 0; // Current step index, 0 means at destination
172  std::atomic<RampMode> mRampMode = {RampMode::Linear}; // The mode of the current ramp
173  bool mDestinationZero = false; // In case of a linear ramp this indicates wether the destination value needs to be rounded to zero.
174  };
175 
176 
177  }
178 }
nap::audio::RampMode
RampMode
Definition: audiotypes.h:131
nap::audio::RampedValue::mIncrement
T mIncrement
Definition: rampedvalue.h:166
nap::audio::RampedValue::getValue
T getValue() const
Definition: rampedvalue.h:105
nap::audio::RampedValue::stop
void stop()
Definition: rampedvalue.h:69
nap::audio::RampedValue::destinationReachedSignal
nap::Signal< T > destinationReachedSignal
Definition: rampedvalue.h:116
nap::Signal< T >
nap::audio::RampedValue::smallestFactor
static constexpr T smallestFactor
Definition: rampedvalue.h:34
nap::audio::RampedValue::isRamping
bool isRamping() const
Definition: rampedvalue.h:111
nap::audio::RampedValue::RampedValue
RampedValue(const T &initValue)
Definition: rampedvalue.h:37
nap
Definition: templateapp.h:17
nap::audio::RampedValue::ramp
void ramp(const T &destination, int stepCount, RampMode mode=RampMode::Linear)
Definition: rampedvalue.h:55
nap::audio::RampedValue::mFactor
T mFactor
Definition: rampedvalue.h:167
nap::audio::RampedValue::getNextValue
T getNextValue()
Definition: rampedvalue.h:75
nap::audio::RampedValue
Definition: rampedvalue.h:31
nap::audio::RampedValue::setValue
void setValue(const T &value)
Definition: rampedvalue.h:43