AME
ame_Util.hpp
Go to the documentation of this file.
1
10#pragma once
11
12#include "ame_Math.hpp"
13
14#include <array>
15#include <atomic>
16#include <cassert>
17#include <concepts>
18#include <cstddef>
19#include <type_traits>
20
21namespace ame
22{
27template <typename T>
28struct Range
29{
30 T min;
31 T Max;
32 T init;
33 T step;
34};
35
42template <std::floating_point FloatType>
43constexpr FloatType addModulo2Pi (FloatType phase, FloatType increment) noexcept
44{
45 phase += increment;
46 while (phase > twoPi<FloatType>)
47 {
48 phase -= twoPi<FloatType>;
49 }
50 return phase;
51}
52
62template <std::floating_point FloatType>
63constexpr FloatType scale (FloatType sourceValue,
64 FloatType sourceRangeMin,
65 FloatType sourceRangeMax,
66 FloatType targetRangeMin,
67 FloatType targetRangeMax)
68{
69 return targetRangeMin
70 + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin);
71}
72
76template <std::floating_point FloatType>
78{
79 static_assert (! std::is_const<FloatType>::value, "FloatType is must NOT be const.");
80
81public:
82 LinearSmoothedValue (FloatType initialValue, const int rampSteps)
83 {
84 reset (initialValue);
85 setRampLength (rampSteps);
86 }
87 ~LinearSmoothedValue() = default;
88
90 bool isSmoothing() const noexcept
91 {
92 return countdown > 0;
93 }
94
96 FloatType getCurrentValue() const noexcept
97 {
98 return currentValue;
99 }
100
102 FloatType getTargetValue() const noexcept
103 {
104 return target;
105 }
106
110 void reset (FloatType newValue) noexcept
111 {
112 target = newValue;
113 currentValue = newValue;
114 countdown = 0;
115 }
116
120 void setRampLength (const int numSteps) noexcept
121 {
122 stepsToTarget = numSteps;
123 }
124
128 void setTargetValue (FloatType newValue) noexcept
129 {
130 if (newValue == target)
131 {
132 return;
133 }
134
135 if (stepsToTarget <= 0)
136 {
137 reset (newValue);
138 return;
139 }
140
141 target = newValue;
142 countdown = stepsToTarget;
143 setStepSize();
144 }
145
149 FloatType getNextValue() noexcept
150 {
151 if (! isSmoothing())
152 {
153 return target;
154 }
155
156 --countdown;
157 if (isSmoothing())
158 {
159 currentValue += step;
160 }
161 else
162 {
163 currentValue = target;
164 }
165 return currentValue;
166 }
167
168private:
169 void setStepSize()
170 {
171 step = (target - currentValue) / stepsToTarget;
172 }
173
174 FloatType currentValue {};
175 FloatType target {};
176 FloatType step {};
177 int countdown {};
178 int stepsToTarget {};
179};
180
186template <std::floating_point FloatType>
187class Slide
188{
189 static_assert (! std::is_const<FloatType>::value, "FloatType is must NOT be const.");
190
191public:
192 Slide() {}
198 Slide (FloatType slownessOfIncrease, FloatType slownessOfDecrease) noexcept
199 {
200 slideUp.store (slownessOfIncrease);
201 slideDown.store (slownessOfDecrease);
202 }
203 ~Slide() = default;
204
209 void setSlownessOfIncrease (FloatType slownessIncrease)
210 {
211 assert (slownessIncrease >= 1.0f);
212 slideUp.store (slownessIncrease);
213 }
214
219 void setSlownessOfDecrease (FloatType slownessDecrease)
220 {
221 assert (slownessDecrease >= 1.0f);
222 slideDown.store (slownessDecrease);
223 }
224
229 FloatType process (FloatType input) noexcept
230 {
231 const auto dt = input - lastOutput;
232 const auto s = dt > FloatType (0.0) ? slideUp.load() : slideDown.load();
233 lastOutput = lastOutput + dt / s;
234 return lastOutput;
235 }
236
237private:
238 FloatType lastOutput {};
239 std::atomic<FloatType> slideUp { 1.0 };
240 std::atomic<FloatType> slideDown { 1.0 };
241};
242
243namespace
244{
245 template <typename T>
246 concept signed_number = std::signed_integral<T> || std::floating_point<T>;
247}
248
252template <signed_number T>
253class Wrap
254{
255public:
259 explicit Wrap (T length) : length (length)
260 {
261 assert (length > 0); //length is must greater than 0
262 }
263
264 Wrap() = default;
265 ~Wrap() = default;
266
271 void set (T n)
272 {
273 while (n >= length)
274 {
275 n -= length;
276 }
277
278 while (n < 0)
279 {
280 n += length;
281 }
282
283 num = n;
284 }
285
290 [[nodiscard]] T get (T offset = 0) const noexcept
291 {
292 auto n = num + offset;
293 while (n >= length)
294 {
295 n -= length;
296 }
297
298 while (n < 0)
299 {
300 n += length;
301 }
302 return n;
303 }
304
308 void changeLength (T newLength) noexcept
309 {
310 length = newLength;
311 }
312
313 [[nodiscard]] T getLength() const noexcept
314 {
315 return length;
316 }
317
321 T operator++() noexcept
322 {
323 ++num;
324 if (num >= length)
325 {
326 num = 0;
327 }
328 return num;
329 }
330
334 T operator++ (int) noexcept
335 {
336 num++;
337 if (num >= length)
338 {
339 num = 0;
340 }
341 return num;
342 }
343
349 T operator+= (T add) noexcept
350 {
351 num += add;
352 while (num >= length)
353 {
354 num -= length;
355 }
356 return num;
357 }
358
359private:
360 T num {};
361 T length {};
362};
363
379template <typename... Ts>
380constexpr std::array<std::byte, sizeof...(Ts)> makeBytes (Ts&&... args) noexcept
381{
382 return { std::byte (std::forward<Ts> (args))... };
383}
384} // namespace ame
Math functions.
constexpr FloatType addModulo2Pi(FloatType phase, FloatType increment) noexcept
Increment the phase and returns in the range of 0~2pi.
Definition: ame_Util.hpp:43
constexpr FloatType scale(FloatType sourceValue, FloatType sourceRangeMin, FloatType sourceRangeMax, FloatType targetRangeMin, FloatType targetRangeMax)
Map values to an output range.
Definition: ame_Util.hpp:63
Smooth values linearly.
Definition: ame_Util.hpp:78
void setRampLength(const int numSteps) noexcept
Set a new ramp length in samples.
Definition: ame_Util.hpp:120
void reset(FloatType newValue) noexcept
Reset the currentValue, targetValue and ramp count.
Definition: ame_Util.hpp:110
void setTargetValue(FloatType newValue) noexcept
Set the next value to ramp towards.
Definition: ame_Util.hpp:128
FloatType getNextValue() noexcept
Compute the smoothed value.
Definition: ame_Util.hpp:149
FloatType getTargetValue() const noexcept
Returns the target value towards which the smoothed value is currently moving.
Definition: ame_Util.hpp:102
FloatType getCurrentValue() const noexcept
Returns the current value to the ramp.
Definition: ame_Util.hpp:96
bool isSmoothing() const noexcept
Returns true if the current value is currently being interpolated.
Definition: ame_Util.hpp:90
Smooth values logarithmically.
Definition: ame_Util.hpp:188
void setSlownessOfIncrease(FloatType slownessIncrease)
Set the slowness of the increase.
Definition: ame_Util.hpp:209
Slide(FloatType slownessOfIncrease, FloatType slownessOfDecrease) noexcept
Create an Slide object.
Definition: ame_Util.hpp:198
FloatType process(FloatType input) noexcept
Filter an input value
Definition: ame_Util.hpp:229
void setSlownessOfDecrease(FloatType slownessDecrease)
Set the slowness of the decrease.
Definition: ame_Util.hpp:219
A number to wrap between 0~length.
Definition: ame_Util.hpp:254
T operator+=(T add) noexcept
+= operator.
Definition: ame_Util.hpp:349
Wrap(T length)
Definition: ame_Util.hpp:259
void changeLength(T newLength) noexcept
The number to automatically wrap in the range [0, length-1].
Definition: ame_Util.hpp:308
T get(T offset=0) const noexcept
Get the current value or the number of the current value plus an offset.
Definition: ame_Util.hpp:290
T operator++() noexcept
Prefix increment.
Definition: ame_Util.hpp:321
void set(T n)
Sets the current value to an arbitrary number.
Definition: ame_Util.hpp:271
範囲を表す構造体.
Definition: ame_Util.hpp:29