| 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.