OpenWareLaboratory
custom_dsp.h
Go to the documentation of this file.
1 
3 #if !defined(DSY_CUSTOM_DSP_H) && defined __cplusplus
4 #define DSY_CUSTOM_DSP_H
5 #include <math.h>
6 
7 #include "basicmaths.h"
8 #undef min
9 #undef max
10 #undef abs
11 #undef exp
12 #undef sqrt
13 #undef pow
14 #undef log
15 #undef rand
16 #undef clamp
17 
20 #define PI_F 3.1415927410125732421875f
21 #define TWOPI_F (2.0f * PI_F)
22 #define HALFPI_F (PI_F * 0.5f)
23 #define DSY_MIN(in, mn) (in < mn ? in : mn)
24 #define DSY_MAX(in, mx) (in > mx ? in : mx)
25 #define DSY_CLAMP(in, mn, mx) (DSY_MIN(DSY_MAX(in, mn), mx))
26 
27 namespace daisysp
28 {
29 //Avoids division for random floats. e.g. rand() * kRandFrac
30 static constexpr float kRandFrac = 1.f / (float)RAND_MAX;
31 
32 //Convert from semitones to other units. e.g. 2 ^ (kOneTwelfth * x)
33 static constexpr float kOneTwelfth = 1.f / 12.f;
34 
38 inline float fmax(float a, float b)
39 {
40  float r;
41 #ifdef ARM_MATH_CM7
42  asm("vmaxnm.f32 %[d], %[n], %[m]" : [d] "=t"(r) : [n] "t"(a), [m] "t"(b) :);
43 #else
44  r = (a > b) ? a : b;
45 #endif // ARM_MATH_CM7
46  return r;
47 }
48 
49 inline float fmin(float a, float b)
50 {
51  float r;
52 #ifdef ARM_MATH_CM7
53  asm("vminnm.f32 %[d], %[n], %[m]" : [d] "=t"(r) : [n] "t"(a), [m] "t"(b) :);
54 #else
55  r = (a < b) ? a : b;
56 #endif // ARM_MATH_CM7
57  return r;
58 }
59 
62 inline float fclamp(float in, float min, float max)
63 {
64  return fmin(fmax(in, min), max);
65 }
66 
71 #if 0
72 inline float fastpower(float f, int n)
73 {
74  long *lp, l;
75  lp = (long *)(&f);
76  l = *lp;
77  l -= 0x3F800000;
78  l <<= (n - 1);
79  l += 0x3F800000;
80  *lp = l;
81  return f;
82 }
83 #else
84 #define fastpower(f, n) (fast_powf(f, n))
85 #endif
86 
87 inline float fastroot(float f, int n)
88 {
89  long *lp, l;
90  lp = (long *)(&f);
91  l = *lp;
92  l -= 0x3F800000;
93  l >>= (n = 1);
94  l += 0x3F800000;
95  *lp = l;
96  return f;
97 }
98 
102 #if 0
103 inline float pow10f(float f)
104 {
105  return expf(2.302585092994046f * f);
106 }
107 #else
108 #define pow10f(x) (fast_powf(10.f, x))
109 #endif
110 
111 /* Original code for fastlog2f by Dr. Paul Beckmann from the ARM community forum, adapted from the CMSIS-DSP library
112 About 25% performance increase over std::log10f
113 */
114 #if 0
115 inline float fastlog2f(float f)
116 {
117  float frac;
118  int exp;
119  frac = frexpf(fabsf(f), &exp);
120  f = 1.23149591368684f;
121  f *= frac;
122  f += -4.11852516267426f;
123  f *= frac;
124  f += 6.02197014179219f;
125  f *= frac;
126  f += -3.13396450166353f;
127  f += exp;
128  return (f);
129 }
130 #else
131 #define fastlog2f(x) fast_log2f(x)
132 #endif
133 
134 #if 0
135 inline float fastlog10f(float f)
136 {
137  return fastlog2f(f) * 0.3010299956639812f;
138 }
139 #else
140 #define fastlog10f(x) fast_log10f(x)
141 #endif
142 
145 inline float mtof(float m)
146 {
147  return powf(2, (m - 69.0f) / 12.0f) * 440.0f;
148 }
149 
150 
157 inline void fonepole(float &out, float in, float coeff)
158 {
159  out += coeff * (in - out);
160 }
161 
165 template <typename T>
166 T median(T a, T b, T c)
167 {
168  return (b < a) ? (b < c) ? (c < a) ? c : a : b
169  : (a < c) ? (c < b) ? c : b : a;
170 }
171 
174 inline float ThisBlepSample(float t)
175 {
176  return 0.5f * t * t;
177 }
178 
181 inline float NextBlepSample(float t)
182 {
183  t = 1.0f - t;
184  return -0.5f * t * t;
185 }
186 
189 inline float NextIntegratedBlepSample(float t)
190 {
191  const float t1 = 0.5f * t;
192  const float t2 = t1 * t1;
193  const float t4 = t2 * t2;
194  return 0.1875f - t1 + 1.5f * t2 - t4;
195 }
196 
199 inline float ThisIntegratedBlepSample(float t)
200 {
201  return NextIntegratedBlepSample(1.0f - t);
202 }
203 
205 inline float SoftLimit(float x)
206 {
207  return x * (27.f + x * x) / (27.f + 9.f * x * x);
208 }
209 
211 inline float SoftClip(float x)
212 {
213  if(x < -3.0f)
214  return -1.0f;
215  else if(x > 3.0f)
216  return 1.0f;
217  else
218  return SoftLimit(x);
219 }
220 
227 inline void TestFloat(float &x, float y = 0.f)
228 {
229  if(!isnormal(x) && x != 0)
230  {
231 #ifdef DEBUG
232  asm("bkpt 255");
233 #else
234  x = y;
235 #endif
236  }
237 }
238 
251 inline float soft_saturate(float in, float thresh)
252 {
253  bool flip;
254  float val, out;
255  //val = fabsf(in);
256  flip = val < 0.0f;
257  val = flip ? -in : in;
258  if(val < thresh)
259  {
260  out = in;
261  }
262  else if(val > 1.0f)
263  {
264  out = (thresh + 1.0f) / 2.0f;
265  if(flip)
266  out *= -1.0f;
267  }
268  else if(val > thresh)
269  {
270  float temp;
271  temp = (val - thresh) / (1 - thresh);
272  out = thresh + (val - thresh) / (1.0f + (temp * temp));
273  if(flip)
274  out *= -1.0f;
275  }
276  return out;
277  // return val < thresh
278  // ? val
279  // : val > 1.0f
280  // ? (thresh + 1.0f) / 2.0f
281  // : thresh
282  // + (val - thresh)
283  // / (1.0f
284  // + (((val - thresh) / (1.0f - thresh))
285  // * ((val - thresh) / (1.0f - thresh))));
286 }
287 } // namespace daisysp
288 #endif
#define min(a, b)
Definition: basicmaths.h:38
#define max(a, b)
Definition: basicmaths.h:41