DaisySP
Loading...
Searching...
No Matches
dsp.h
1/*
2Copyright (c) 2020 Electrosmith, Corp, Emilie Gillet
3
4Use of this source code is governed by an MIT-style
5license that can be found in the LICENSE file or at
6https://opensource.org/licenses/MIT.
7*/
8
11#pragma once
12#ifndef DSY_CORE_DSP
13#define DSY_CORE_DSP
14#include <cassert>
15#include <cstdint>
16#include <random>
17#include <cmath>
18
21#define PI_F 3.1415927410125732421875f
22#define TWOPI_F (2.0f * PI_F)
23#define HALFPI_F (PI_F * 0.5f)
24#define DSY_MIN(in, mn) (in < mn ? in : mn)
25#define DSY_MAX(in, mx) (in > mx ? in : mx)
26#define DSY_CLAMP(in, mn, mx) (DSY_MIN(DSY_MAX(in, mn), mx))
27#define DSY_COUNTOF(_arr) (sizeof(_arr) / sizeof(_arr[0]))
28
29namespace daisysp
30{
31//Avoids division for random floats. e.g. rand() * kRandFrac
32static constexpr float kRandFrac = 1.f / (float)RAND_MAX;
33
34//Convert from semitones to other units. e.g. 2 ^ (kOneTwelfth * x)
35static constexpr float kOneTwelfth = 1.f / 12.f;
36
40inline float fmax(float a, float b)
41{
42 float r;
43#ifdef __arm__
44 asm("vmaxnm.f32 %[d], %[n], %[m]" : [d] "=t"(r) : [n] "t"(a), [m] "t"(b) :);
45#else
46 r = (a > b) ? a : b;
47#endif // __arm__
48 return r;
49}
50
51inline float fmin(float a, float b)
52{
53 float r;
54#ifdef __arm__
55 asm("vminnm.f32 %[d], %[n], %[m]" : [d] "=t"(r) : [n] "t"(a), [m] "t"(b) :);
56#else
57 r = (a < b) ? a : b;
58#endif // __arm__
59 return r;
60}
61
64inline float fclamp(float in, float min, float max)
65{
66 return fmin(fmax(in, min), max);
67}
68
73inline float fastpower(float f, int n)
74{
75 long *lp, l;
76 lp = (long *)(&f);
77 l = *lp;
78 l -= 0x3F800000;
79 l <<= (n - 1);
80 l += 0x3F800000;
81 *lp = l;
82 return f;
83}
84
85inline float fastroot(float f, int n)
86{
87 long *lp, l;
88 lp = (long *)(&f);
89 l = *lp;
90 l -= 0x3F800000;
91 l >>= (n - 1);
92 l += 0x3F800000;
93 *lp = l;
94 return f;
95}
96
100inline float fastmod1f(float x)
101{
102 return x - static_cast<int>(x);
103}
104
108inline float pow10f(float f)
109{
110 return expf(2.302585092994046f * f);
111}
112
113/* Original code for fastlog2f by Dr. Paul Beckmann from the ARM community forum, adapted from the CMSIS-DSP library
114About 25% performance increase over std::log10f
115*/
116inline float fastlog2f(float f)
117{
118 float frac;
119 int exp;
120 frac = frexpf(fabsf(f), &exp);
121 f = 1.23149591368684f;
122 f *= frac;
123 f += -4.11852516267426f;
124 f *= frac;
125 f += 6.02197014179219f;
126 f *= frac;
127 f += -3.13396450166353f;
128 f += exp;
129 return (f);
130}
131
132inline float fastlog10f(float f)
133{
134 return fastlog2f(f) * 0.3010299956639812f;
135}
136
139inline float mtof(float m)
140{
141 return powf(2, (m - 69.0f) / 12.0f) * 440.0f;
142}
143
144
151inline void fonepole(float &out, float in, float coeff)
152{
153 out += coeff * (in - out);
154}
155
157enum class Mapping
158{
159 LINEAR,
160 EXP,
161 LOG,
162};
163
176inline float
177fmap(float in, float min, float max, Mapping curve = Mapping::LINEAR)
178{
179 switch(curve)
180 {
181 case Mapping::EXP:
182 return fclamp(min + (in * in) * (max - min), min, max);
183 case Mapping::LOG:
184 {
185 const float a = 1.f / log10f(max / min);
186 return fclamp(min * powf(10, in / a), min, max);
187 }
188 case Mapping::LINEAR:
189 default: return fclamp(min + in * (max - min), min, max);
190 }
191}
192
196template <typename T>
197T median(T a, T b, T c)
198{
199 return (b < a) ? (b < c) ? (c < a) ? c : a : b
200 : (a < c) ? (c < b) ? c : b : a;
201}
202
205inline float ThisBlepSample(float t)
206{
207 return 0.5f * t * t;
208}
209
212inline float NextBlepSample(float t)
213{
214 t = 1.0f - t;
215 return -0.5f * t * t;
216}
217
220inline float NextIntegratedBlepSample(float t)
221{
222 const float t1 = 0.5f * t;
223 const float t2 = t1 * t1;
224 const float t4 = t2 * t2;
225 return 0.1875f - t1 + 1.5f * t2 - t4;
226}
227
230inline float ThisIntegratedBlepSample(float t)
231{
232 return NextIntegratedBlepSample(1.0f - t);
233}
234
236inline float SoftLimit(float x)
237{
238 return x * (27.f + x * x) / (27.f + 9.f * x * x);
239}
240
242inline float SoftClip(float x)
243{
244 if(x < -3.0f)
245 return -1.0f;
246 else if(x > 3.0f)
247 return 1.0f;
248 else
249 return SoftLimit(x);
250}
251
258inline void TestFloat(float &x, float y = 0.f)
259{
260 if(!std::isnormal(x) && x != 0)
261 {
262#if defined(__arm__) && defined(DEBUG)
263 asm("bkpt 255");
264#else
265 x = y;
266#endif
267 }
268}
269
282inline float soft_saturate(float in, float thresh)
283{
284 bool flip;
285 float val, out;
286 //val = fabsf(in);
287 out = 0.f;
288 flip = in < 0.0f;
289 val = flip ? -in : in;
290 if(val < thresh)
291 {
292 out = in;
293 }
294 else if(val > 1.0f)
295 {
296 out = (thresh + 1.0f) / 2.0f;
297 if(flip)
298 out *= -1.0f;
299 }
300 else if(val > thresh)
301 {
302 float temp;
303 temp = (val - thresh) / (1 - thresh);
304 out = thresh + (val - thresh) / (1.0f + (temp * temp));
305 if(flip)
306 out *= -1.0f;
307 }
308 return out;
309 // return val < thresh
310 // ? val
311 // : val > 1.0f
312 // ? (thresh + 1.0f) / 2.0f
313 // : thresh
314 // + (val - thresh)
315 // / (1.0f
316 // + (((val - thresh) / (1.0f - thresh))
317 // * ((val - thresh) / (1.0f - thresh))));
318}
319constexpr bool is_power2(uint32_t x)
320{
321 return ((x - 1) & x) == 0;
322}
323
329#if __cplusplus <= 201103L
330inline uint32_t get_next_power2(uint32_t x)
331#else
332constexpr uint32_t get_next_power2(uint32_t x)
333#endif
334{
335 x--;
336 x |= x >> 1;
337 x |= x >> 2;
338 x |= x >> 4;
339 x |= x >> 8;
340 x |= x >> 16;
341 x++;
342
343 assert(is_power2(x));
344 return x;
345}
346
347} // namespace daisysp
348#endif
349
350#ifdef DSY_CUSTOM_DSP
351#include "custom_dsp.h"
352#endif
FIR Filter implementation, generic and ARM CMSIS DSP based.
Definition adenv.h:16
uint32_t get_next_power2(uint32_t x)
Definition dsp.h:330
float fastpower(float f, int n)
Definition dsp.h:73
Mapping
Definition dsp.h:158
float mtof(float m)
Definition dsp.h:139
float ThisBlepSample(float t)
Definition dsp.h:205
float fastmod1f(float x)
Definition dsp.h:100
float pow10f(float f)
Definition dsp.h:108
T median(T a, T b, T c)
Definition dsp.h:197
float fclamp(float in, float min, float max)
Definition dsp.h:64
float NextIntegratedBlepSample(float t)
Definition dsp.h:220
float soft_saturate(float in, float thresh)
Definition dsp.h:282
float fmax(float a, float b)
Definition dsp.h:40
float SoftLimit(float x)
Definition dsp.h:236
float NextBlepSample(float t)
Definition dsp.h:212
float fmap(float in, float min, float max, Mapping curve=Mapping::LINEAR)
Definition dsp.h:177
void TestFloat(float &x, float y=0.f)
Definition dsp.h:258
float ThisIntegratedBlepSample(float t)
Definition dsp.h:230
float SoftClip(float x)
Definition dsp.h:242
void fonepole(float &out, float in, float coeff)
Definition dsp.h:151