Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/distrho/extra/ValueSmoother.hpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2021 Jean Pierre Cimalando <jp-dev@inbox.ru> | |
4 * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any purpose with | |
7 * or without fee is hereby granted, provided that the above copyright notice and this | |
8 * permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |
11 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |
12 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
14 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
16 */ | |
17 | |
18 #ifndef DISTRHO_VALUE_SMOOTHER_HPP_INCLUDED | |
19 #define DISTRHO_VALUE_SMOOTHER_HPP_INCLUDED | |
20 | |
21 #include "../DistrhoUtils.hpp" | |
22 | |
23 START_NAMESPACE_DISTRHO | |
24 | |
25 // -------------------------------------------------------------------------------------------------------------------- | |
26 | |
27 /** | |
28 * @brief An exponential smoother for control values | |
29 * | |
30 * This continually smooths a value towards a defined target, | |
31 * using a low-pass filter of the 1st order, which creates an exponential curve. | |
32 * | |
33 * The length of the curve is defined by a T60 constant, | |
34 * which is the time it takes for a 1-to-0 smoothing to fall to -60dB. | |
35 * | |
36 * Note that this smoother has asymptotical behavior, | |
37 * and it must not be assumed that the final target is ever reached. | |
38 */ | |
39 class ExponentialValueSmoother { | |
40 float coef; | |
41 float target; | |
42 float mem; | |
43 float tau; | |
44 float sampleRate; | |
45 | |
46 public: | |
47 ExponentialValueSmoother() | |
48 : coef(0.f), | |
49 target(0.f), | |
50 mem(0.f), | |
51 tau(0.f), | |
52 sampleRate(0.f) {} | |
53 | |
54 void setSampleRate(const float newSampleRate) noexcept | |
55 { | |
56 if (d_isNotEqual(sampleRate, newSampleRate)) | |
57 { | |
58 sampleRate = newSampleRate; | |
59 updateCoef(); | |
60 } | |
61 } | |
62 | |
63 void setTimeConstant(const float newT60) noexcept | |
64 { | |
65 const float newTau = newT60 * (float)(1.0 / 6.91); | |
66 | |
67 if (d_isNotEqual(tau, newTau)) | |
68 { | |
69 tau = newTau; | |
70 updateCoef(); | |
71 } | |
72 } | |
73 | |
74 float getCurrentValue() const noexcept | |
75 { | |
76 return mem; | |
77 } | |
78 | |
79 float getTargetValue() const noexcept | |
80 { | |
81 return target; | |
82 } | |
83 | |
84 void setTargetValue(const float newTarget) noexcept | |
85 { | |
86 target = newTarget; | |
87 } | |
88 | |
89 void clearToTargetValue() noexcept | |
90 { | |
91 mem = target; | |
92 } | |
93 | |
94 inline float peek() const noexcept | |
95 { | |
96 return mem * coef + target * (1.f - coef); | |
97 } | |
98 | |
99 inline float next() noexcept | |
100 { | |
101 return (mem = mem * coef + target * (1.f - coef)); | |
102 } | |
103 | |
104 private: | |
105 void updateCoef() noexcept | |
106 { | |
107 coef = std::exp(-1.f / (tau * sampleRate)); | |
108 } | |
109 }; | |
110 | |
111 // -------------------------------------------------------------------------------------------------------------------- | |
112 | |
113 /** | |
114 * @brief A linear smoother for control values | |
115 * | |
116 * This continually smooths a value towards a defined target, using linear segments. | |
117 * | |
118 * The duration of the smoothing segment is defined by the given time constant. | |
119 * Every time the target changes, a new segment restarts for the whole duration of the time constant. | |
120 * | |
121 * Note that this smoother, unlike an exponential smoother, eventually should converge to its target value. | |
122 */ | |
123 class LinearValueSmoother { | |
124 float step; | |
125 float target; | |
126 float mem; | |
127 float tau; | |
128 float sampleRate; | |
129 | |
130 public: | |
131 LinearValueSmoother() | |
132 : step(0.f), | |
133 target(0.f), | |
134 mem(0.f), | |
135 tau(0.f), | |
136 sampleRate(0.f) {} | |
137 | |
138 void setSampleRate(const float newSampleRate) noexcept | |
139 { | |
140 if (d_isNotEqual(sampleRate, newSampleRate)) | |
141 { | |
142 sampleRate = newSampleRate; | |
143 updateStep(); | |
144 } | |
145 } | |
146 | |
147 void setTimeConstant(const float newTau) noexcept | |
148 { | |
149 if (d_isNotEqual(tau, newTau)) | |
150 { | |
151 tau = newTau; | |
152 updateStep(); | |
153 } | |
154 } | |
155 | |
156 float getCurrentValue() const noexcept | |
157 { | |
158 return mem; | |
159 } | |
160 | |
161 float getTargetValue() const noexcept | |
162 { | |
163 return target; | |
164 } | |
165 | |
166 void setTargetValue(const float newTarget) noexcept | |
167 { | |
168 if (d_isNotEqual(target, newTarget)) | |
169 { | |
170 target = newTarget; | |
171 updateStep(); | |
172 } | |
173 } | |
174 | |
175 void clearToTargetValue() noexcept | |
176 { | |
177 mem = target; | |
178 } | |
179 | |
180 inline float peek() const noexcept | |
181 { | |
182 const float dy = target - mem; | |
183 return mem + std::copysign(std::fmin(std::abs(dy), std::abs(step)), dy); | |
184 } | |
185 | |
186 inline float next() noexcept | |
187 { | |
188 const float y0 = mem; | |
189 const float dy = target - y0; | |
190 return (mem = y0 + std::copysign(std::fmin(std::abs(dy), std::abs(step)), dy)); | |
191 } | |
192 | |
193 private: | |
194 void updateStep() noexcept | |
195 { | |
196 step = (target - mem) / (tau * sampleRate); | |
197 } | |
198 }; | |
199 | |
200 // -------------------------------------------------------------------------------------------------------------------- | |
201 | |
202 END_NAMESPACE_DISTRHO | |
203 | |
204 #endif // DISTRHO_VALUE_SMOOTHER_HPP_INCLUDED |