Nu:Tekt NTS-1 digital SDK
v1.1-0
|
Go to the documentation of this file.
47 #ifndef __float_math_h
48 #define __float_math_h
63 #define M_E 2.718281828459045f
67 #define M_LOG2E 1.44269504088896f
71 #define M_LOG10E 0.4342944819032518f
75 #define M_LN2 0.6931471805599453094f
79 #define M_LN10 2.30258509299404568402f
83 #define M_PI 3.141592653589793f
87 #define M_TWOPI 6.283185307179586f
91 #define M_PI_2 1.5707963267948966f
95 #define M_PI_4 0.7853981633974483f
99 #define M_1_PI 0.3183098861837907f
103 #define M_2_PI 0.6366197723675814f
107 #define M_4_PI 1.2732395447351627f
111 #define M_1_TWOPI 0.15915494309189534f
115 #define M_2_SQRTPI 1.1283791670955126f
119 #define M_4_PI2 0.40528473456935109f
123 #define M_SQRT2 1.41421356237309504880f
127 #define M_1_SQRT2 0.7071067811865475f
141 #define F32_FRAC_MASK ((1L<<23)-1)
142 #define F32_EXP_MASK (((1L<<9)-1)<<23)
143 #define F32_SIGN_MASK (0x80000000)
146 #define f32_frac_bits(f) ((f) & F32_FRAC_MASK)
147 #define f32_exp_bits(f) ((f) & F32_EXP_MASK)
148 #define f32_sign_bit(f) ((f) & F32_SIGN_MASK)
173 static inline __attribute__((optimize(
"Ofast"),always_inline))
191 static inline __attribute__((optimize(
"Ofast"),always_inline))
192 float
fsel(const
float a, const
float b, const
float c) {
193 return (a >= 0) ? b : c;
198 static inline __attribute__((optimize(
"Ofast"),always_inline))
200 return (a >= 0) ? 1 : 0;
205 static inline __attribute__((always_inline))
207 return (f.i >> 31) != 0;
212 static inline __attribute__((always_inline))
214 return f.i & ((1 << 23) - 1);
219 static inline __attribute__((always_inline))
221 return (f.i >> 23) & 0xFF;
226 static inline __attribute__((optimize(
"Ofast"),always_inline))
228 return (
f32pair_t){p0.a + p1.a, p0.b + p1.b};
233 static inline __attribute__((optimize(
"Ofast"),always_inline))
235 return (
f32pair_t){p0.a - p1.a, p0.b - p1.b};
240 static inline __attribute__((optimize(
"Ofast"),always_inline))
242 return (
f32pair_t){p.a + scl, p.b + scl};
247 static inline __attribute__((optimize(
"Ofast"),always_inline))
249 return (
f32pair_t){p0.a * p1.a, p0.b * p1.b};
254 static inline __attribute__((optimize(
"Ofast"),always_inline))
256 return (
f32pair_t){p.a * scl, p.b * scl};
261 static inline __attribute__((optimize(
"Ofast"),always_inline))
263 const float frinv = 1.f - fr;
264 return (
f32pair_t){ frinv * p0.a + fr * p1.a, frinv * p0.b + fr * p1.b };
269 static inline __attribute__((optimize(
"Ofast"),always_inline))
276 xs.i |= ys.i & 0x80000000;
283 static inline __attribute__((optimize(
"Ofast"),always_inline))
293 static inline __attribute__((optimize(
"Ofast"),always_inline))
296 return (
float)((uint32_t)x);
301 static inline __attribute__((optimize(
"Ofast"),always_inline))
304 return (
float)((uint32_t)x + 1);
309 static inline __attribute__((optimize(
"Ofast"),always_inline))
315 static inline __attribute__((optimize(
"Ofast"), always_inline))
316 float clampfsel(
const float min,
float x,
const float max)
318 x =
fsel(x - min, x, min);
319 return fsel(x - max, max, x);
322 static inline __attribute__((optimize(
"Ofast"), always_inline))
323 float clampminfsel(
const float min,
const float x)
325 return fsel(x - min, x, min);
328 static inline __attribute__((optimize(
"Ofast"), always_inline))
329 float clampmaxfsel(
const float x,
const float max)
331 return fsel(x - max, max, x);
334 #if defined(FLOAT_CLIP_NOFSEL)
338 static inline __attribute__((optimize(
"Ofast"), always_inline))
339 float clipmaxf(
const float x,
const float m)
340 {
return (((x)>=m)?m:(x)); }
344 static inline __attribute__((optimize(
"Ofast"), always_inline))
345 float clipminf(
const float m,
const float x)
346 {
return (((x)<=m)?m:(x)); }
350 static inline __attribute__((optimize(
"Ofast"), always_inline))
351 float clipminmaxf(
const float min,
const float x,
const float max)
352 {
return (((x)>=max)?max:((x)<=min)?min:(x)); }
356 static inline __attribute__((optimize(
"Ofast"), always_inline))
357 float clip0f(
const float x)
358 {
return (((x)<0.f)?0.f:(x)); }
362 static inline __attribute__((optimize(
"Ofast"), always_inline))
363 float clip1f(
const float x)
364 {
return (((x)>1.f)?1.f:(x)); }
368 static inline __attribute__((optimize(
"Ofast"), always_inline))
370 {
return (((x)>1.f)?1.f:((x)<0.f)?0.f:(x)); }
374 static inline __attribute__((optimize(
"Ofast"), always_inline))
376 {
return (((x)<-1.f)?-1.f:(x)); }
380 static inline __attribute__((optimize(
"Ofast"), always_inline))
382 {
return (((x)>1.f)?1.f:((x)<-1.f)?-1.f:(x)); }
388 static inline __attribute__((optimize(
"Ofast"), always_inline))
390 {
return clampmaxfsel(x, m); }
394 static inline __attribute__((optimize(
"Ofast"), always_inline))
396 {
return clampminfsel(m, x); }
400 static inline __attribute__((optimize(
"Ofast"), always_inline))
401 float
clipminmaxf(const
float min, const
float x, const
float max)
402 {
return clampfsel(min, x, max); }
406 static inline __attribute__((optimize(
"Ofast"), always_inline))
408 {
return clampminfsel(0, x); }
412 static inline __attribute__((optimize(
"Ofast"), always_inline))
414 {
return clampmaxfsel(x, 1); }
418 static inline __attribute__((optimize(
"Ofast"), always_inline))
420 {
return clampfsel(0, x, 1); }
424 static inline __attribute__((optimize(
"Ofast"), always_inline))
426 {
return clampminfsel(-1, x); }
430 static inline __attribute__((optimize(
"Ofast"), always_inline))
432 {
return clampfsel(-1, x, 1); }
498 static inline __attribute__((optimize(
"Ofast"), always_inline))
500 static const float q = 0.78444488374548933f;
501 union {
float f; uint32_t i; } p = { 0.20363937680730309f };
502 union {
float f; uint32_t i; } r = { 0.015124940802184233f };
503 union {
float f; uint32_t i; } s = { -0.0032225901625579573f };
505 union {
float f; uint32_t i; } vx = { x };
506 uint32_t sign = vx.i & 0x80000000;
507 vx.i = vx.i & 0x7FFFFFFF;
509 float qpprox = M_4_PI * x - M_4_PI2 * x * vx.f;
510 float qpproxsq = qpprox * qpprox;
516 return q * qpprox + qpproxsq * (p.f + qpproxsq * (r.f + qpproxsq * s.f));
523 static inline __attribute__((optimize(
"Ofast"), always_inline))
525 static const float q = 0.77633023248007499f;
526 union {
float f; uint32_t i; } p = { 0.22308510060189463f };
527 union {
float f; uint32_t i; } vx = { x };
528 const uint32_t sign = vx.i & 0x80000000;
530 const float qpprox = M_4_PI * x - M_4_PI2 * x * vx.f;
532 return qpprox * (q + p.f * qpprox);
538 static inline __attribute__((optimize(
"Ofast"), always_inline))
540 const int32_t k = (int32_t)(x * M_1_TWOPI);
541 const float half = (x < 0) ? -0.5f : 0.5f;
542 return fastsinf((half + k) * M_TWOPI - x);
548 static inline __attribute__((optimize(
"Ofast"), always_inline))
550 const int32_t k = (int32_t)(x * M_1_TWOPI);
551 const float half = (x < 0) ? -0.5f : 0.5f;
558 static inline __attribute__((optimize(
"Ofast"), always_inline))
560 const float halfpiminustwopi = -4.7123889803846899f;
561 float offset = (x > M_PI_2) ? halfpiminustwopi : M_PI_2;
568 static inline __attribute__((optimize(
"Ofast"), always_inline))
570 static const float p = 0.54641335845679634f;
571 union {
float f; uint32_t i; } vx = { x };
573 const float qpprox = 1.0f - M_2_PI * vx.f;
574 return qpprox + p * qpprox * (1.0f - qpprox * qpprox);
581 static inline __attribute__((optimize(
"Ofast"), always_inline))
589 static inline __attribute__((optimize(
"Ofast"), always_inline))
597 static inline __attribute__((optimize(
"Ofast"), always_inline))
605 static inline __attribute__((optimize(
"Ofast"), always_inline))
614 static inline __attribute__((optimize(
"Ofast"), always_inline))
616 const int32_t k = (int32_t)(x * M_1_TWOPI);
617 const float half = (x < 0) ? -0.5f : 0.5f;
618 const float xnew = x - (half + k) * M_TWOPI;
625 static inline __attribute__((optimize(
"Ofast"), always_inline))
627 const int32_t k = (int32_t)(x * M_1_TWOPI);
628 const float half = (x < 0) ? -0.5f : 0.5f;
629 const float xnew = x - (half + k) * M_TWOPI;
636 static inline __attribute__((optimize(
"Ofast"), always_inline))
638 union {
float f; uint32_t i; } vx = { x };
639 union { uint32_t i;
float f; } mx = { (vx.i & 0x007FFFFF) | 0x3f000000 };
641 y *= 1.1920928955078125e-7f;
643 return y - 124.22551499f
644 - 1.498030302f * mx.f
645 - 1.72587999f / (0.3520887068f + mx.f);
651 static inline __attribute__((optimize(
"Ofast"), always_inline))
653 union {
float f; uint32_t i; } vx = { x };
654 float y = (float)(vx.i);
655 y *= 1.1920928955078125e-7f;
656 return y - 126.94269504f;
662 static inline __attribute__((optimize(
"Ofast"), always_inline))
670 static inline __attribute__((optimize(
"Ofast"), always_inline))
678 static inline __attribute__((optimize(
"Ofast"), always_inline))
680 float clipp = (p < -126) ? -126.0f : p;
682 float z = clipp - w + 1.f;
683 union { uint32_t i;
float f; } v = { (uint32_t) ( (1 << 23) *
684 (clipp + 121.2740575f + 27.7280233f / (4.84252568f - z) - 1.49012907f * z)
693 static inline __attribute__((optimize(
"Ofast"), always_inline))
695 float clipp = (p < -126) ? -126.0f : p;
696 union { uint32_t i;
float f; } v = { (uint32_t)( (1 << 23) * (clipp + 126.94269504f) ) };
704 static inline __attribute__((optimize(
"Ofast"), always_inline))
712 static inline __attribute__((optimize(
"Ofast"), always_inline))
720 static inline __attribute__((optimize(
"Ofast"), always_inline))
728 static inline __attribute__((optimize(
"Ofast"), always_inline))
738 static inline __attribute__((optimize(
"Ofast"), always_inline))
740 const float coeff_1 = M_PI_4;
741 const float coeff_2 = 3 * coeff_1;
745 r = (x - abs_y) / (x + abs_y);
746 angle = coeff_1 - coeff_1 * r;
749 r = (x + abs_y) / (abs_y - x);
750 angle = coeff_2 - coeff_1 * r;
752 return (y < 0) ? -angle : angle;
758 static inline __attribute__((optimize(
"Ofast"), always_inline))
760 return (-0.67436811832e-5f +
761 (0.2468149110712040f +
762 (0.583691066395175e-1f + 0.3357335044280075e-1f * x) * x) * x) /
763 (0.2464845986383725f +
764 (0.609347197060491e-1f +
765 (0.1086202599228572f + 0.2874707922475963e-1f * x) * x) * x);
783 static inline __attribute__((optimize(
"Ofast"), always_inline))
785 return (amp < 0.f) ? -999.f : 20.f*log10f(amp);
790 static inline __attribute__((optimize(
"Ofast"), always_inline))
797 static inline __attribute__((optimize(
"Ofast"), always_inline))
799 return powf(10.f,0.05f*db);
804 static inline __attribute__((optimize(
"Ofast"), always_inline))
823 static inline __attribute__((optimize(
"Ofast"), always_inline))
824 float
linintf(const
float fr, const
float x0, const
float x1) {
825 return x0 + fr * (x1 - x0);
830 static inline __attribute__((optimize(
"Ofast"), always_inline))
831 float
cosintf(const
float fr, const
float x0, const
float x1) {
833 return x0 + tmp * (x1 - x0);
838 #endif // __float_math_h
static float si_ceilf(float x)
Ceiling function.
static f32pair_t f32pair_linint(const float fr, const f32pair_t p0, const f32pair_t p1)
Pair-wise linear interpolation.
static float fastersinfullf(float x)
"Faster" sine approximation, valid on full x domain
static float fasterexpf(float p)
"Faster" exponential approximation, valid for x in [ ~ -87, ...
static float fastsinf(float x)
"Fast" sine approximation, valid for x in [-M_PI, M_PI]
static float fasttanfullf(float x)
"Fast" tangent approximation, valid on full x domain, except where tangent diverges.
static f32pair_t f32pair_mul(const f32pair_t p0, const f32pair_t p1)
Pair-wise product.
static f32pair_t f32pair_sub(const f32pair_t p0, const f32pair_t p1)
Pair-wise subtraction.
static float fastexpf(float p)
"Fast" exponential approximation, valid for x in [ ~ -87, ...
static int32_t float_mantissa(f32_t f)
Obtain mantissa.
static f32pair_t f32pair_add(const f32pair_t p0, const f32pair_t p1)
Pair-wise addition.
static float fasteratan2f(float y, float x)
atan2 approximation
static float clipm1f(const float x)
Clip lower bound of x to -1.f (inclusive)
static float dbampf(const float db)
dB to ampltitude
static float fastercosf(float x)
"Faster" cosine approximation, valid for x in [-M_PI, M_PI]
static float clipminmaxf(const float min, const float x, const float max)
Clip x to min and max (inclusive)
static float si_roundf(float x)
Round to nearest integer.
static float clipmaxf(const float x, const float m)
Clip upper bound of x to m (inclusive)
static float fastertanf(float x)
"Faster" tangent approximation, valid for x in [-M_PI_2, M_PI_2]
static float fastsinfullf(float x)
"Fast" sine approximation, valid on full x domain
static float clip0f(const float x)
Clip lower bound of x to 0.f (inclusive)
static uint8_t float_is_neg(const f32_t f)
Sign bit check.
static uint8_t fselb(const float a)
FSEL boolean construct.
static float clipminf(const float m, const float x)
Clip lower bound of x to m (inclusive)
static float fasterampdbf(const float amp)
"Faster" Amplitude to dB
static float si_copysignf(const float x, const float y)
Return x with sign of y applied.
static float fastcosfullf(float x)
"Fast" cosine approximation, valid on full x domain
static float fastercosfullf(float x)
"Faster" cosine approximation, valid on full x domain
static f32pair_t f32pair_addscal(const f32pair_t p, const float scl)
Pair-wise scalar addition.
static float si_floorf(float x)
Floor function.
static float fasterlogf(float x)
"Fast" natural logarithm approximation, valid for positive x as precision allows.
static float fasterpow2f(float p)
"Faster" power of 2 approximation, valid for x in [ -126, ...
static float fastertanhf(float x)
Hyperbolic tangent approximation.
static float fastpow2f(float p)
"Fast" power of 2 approximation, valid for x in [ -126, ...
static float fasterdbampf(const float db)
"Faster" dB to ampltitude
static f32pair_t f32pair(const float a, const float b)
Make a float pair.
static float fastlog2f(float x)
"Fast" log base 2 approximation, valid for positive x as precision allows.
static float fastpowf(float x, float p)
"Fast" x to the power of p approximation
static float fasterpowf(float x, float p)
"Faster" x to the power of p approximation
static float clip01f(const float x)
Clip x to [0.f, 1.f] (inclusive)
static float fsel(const float a, const float b, const float c)
FSEL construct.
static float fastcosf(float x)
"Fast" cosine approximation, valid for x in [-M_PI, M_PI]
static float clip1f(const float x)
Clip upper bound of x to 1.f (inclusive)
static float ampdbf(const float amp)
Amplitude to dB.
static int32_t float_exponent(f32_t f)
Obtain exponent.
static float fastertanfullf(float x)
"Faster" tangent approximation, valid on full x domain, except where tangent diverges.
static float clip1m1f(const float x)
Clip x to [-1.f, 1.f] (inclusive)
static float fastersinf(float x)
"Faster" sine approximation, valid for x in [-M_PI, M_PI]
static float fasttanf(float x)
"Fast" tangent approximation, valid for x in [-M_PI_2, M_PI_2]
static float linintf(const float fr, const float x0, const float x1)
Linear interpolation.
static float si_fabsf(float x)
Absolute value.
static float cosintf(const float fr, const float x0, const float x1)
Cosine interpolation.
static float fasterlog2f(float x)
"Faster" log base 2 approximation, valid for positive x as precision allows.
static float fastlogf(float x)
"Fast" natural logarithm approximation, valid for positive x as precision allows.
static f32pair_t f32pair_mulscal(const f32pair_t p, const float scl)
Pair-wise scalar product.