You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
4.9KB

  1. /* Some misc util functions for audio DSP work, written by Steve Harris,
  2. * December 2000
  3. *
  4. * steve@plugin.org.uk
  5. */
  6. #ifndef LADSPA_UTIL_H
  7. #define LADSPA_UTIL_H
  8. #include <math.h>
  9. #include <stdint.h>
  10. #include <string.h>
  11. #define buffer_write(a, b) a=(b)
  12. // 16.16 fixpoint
  13. typedef union {
  14. int32_t all;
  15. struct {
  16. #ifdef WORDS_BIGENDIAN
  17. int16_t in;
  18. uint16_t fr;
  19. #else
  20. uint16_t fr;
  21. int16_t in;
  22. #endif
  23. } part;
  24. } fixp16;
  25. // 32.32 fixpoint
  26. typedef union {
  27. int64_t all;
  28. struct {
  29. #ifdef WORDS_BIGENDIAN
  30. int32_t in;
  31. uint32_t fr;
  32. #else
  33. uint32_t fr;
  34. int32_t in;
  35. #endif
  36. } part;
  37. } fixp32;
  38. /* 32 bit "pointer cast" union */
  39. typedef union {
  40. float f;
  41. int32_t i;
  42. } ls_pcast32;
  43. // Sometimes it doesn't get defined, even though it eists and C99 is declared
  44. long int lrintf (float x);
  45. // 1.0 / ln(2)
  46. #define LN2R 1.442695041f
  47. /* detet floating point denormal numbers by comparing them to the smallest
  48. * normal, crap, but reliable */
  49. #define DN_CHECK(x, l) if (fabs(x) < 1e-38) printf("DN: " l"\n")
  50. // Denormalise floats, only actually needed for PIII and recent PowerPC
  51. //#define FLUSH_TO_ZERO(fv) (((*(unsigned int*)&(fv))&0x7f800000)==0)?0.0f:(fv)
  52. static __inline float flush_to_zero(float f)
  53. {
  54. ls_pcast32 v;
  55. v.f = f;
  56. // original: return (v.i & 0x7f800000) == 0 ? 0.0f : f;
  57. // version from Tim Blechmann
  58. return (v.i & 0x7f800000) < 0x08000000 ? 0.0f : f;
  59. }
  60. static __inline void round_to_zero(volatile float *f)
  61. {
  62. *f += 1e-18;
  63. *f -= 1e-18;
  64. }
  65. /* A set of branchless clipping operations from Laurent de Soras */
  66. static __inline float f_max(float x, float a)
  67. {
  68. x -= a;
  69. x += fabs(x);
  70. x *= 0.5;
  71. x += a;
  72. return x;
  73. }
  74. static __inline float f_min(float x, float b)
  75. {
  76. x = b - x;
  77. x += fabs(x);
  78. x *= 0.5;
  79. x = b - x;
  80. return x;
  81. }
  82. static __inline float f_clamp(float x, float a, float b)
  83. {
  84. const float x1 = fabs(x - a);
  85. const float x2 = fabs(x - b);
  86. x = x1 + a + b;
  87. x -= x2;
  88. x *= 0.5;
  89. return x;
  90. }
  91. // Limit a value to be l<=v<=u
  92. #define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v)))
  93. // Truncate-to-zero modulo (ANSI C doesn't specify) will only work
  94. // if -m < v < 2m
  95. #define MOD(v,m) (v<0?v+m:(v>=m?v-m:v))
  96. // Truncate-to-zero modulo (ANSI C doesn't specify) will only work
  97. // if v > -m and v < m
  98. #define NEG_MOD(v,m) ((v)<0?((v)+(m)):(v))
  99. // Convert a value in dB's to a coefficent
  100. #define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f)
  101. #define CO_DB(v) (20.0f * log10f(v))
  102. // Linearly interpolate [ = a * (1 - f) + b * f]
  103. #define LIN_INTERP(f,a,b) ((a) + (f) * ((b) - (a)))
  104. // Cubic interpolation function
  105. static __inline float cube_interp(const float fr, const float inm1, const float
  106. in, const float inp1, const float inp2)
  107. {
  108. return in + 0.5f * fr * (inp1 - inm1 +
  109. fr * (4.0f * inp1 + 2.0f * inm1 - 5.0f * in - inp2 +
  110. fr * (3.0f * (in - inp1) - inm1 + inp2)));
  111. }
  112. /* fast sin^2 aproxiamtion, adapted from jan AT rpgfan's posting to the
  113. * music-dsp list */
  114. static __inline float f_sin_sq(float angle)
  115. {
  116. const float asqr = angle * angle;
  117. float result = -2.39e-08f;
  118. result *= asqr;
  119. result += 2.7526e-06f;
  120. result *= asqr;
  121. result -= 1.98409e-04f;
  122. result *= asqr;
  123. result += 8.3333315e-03f;
  124. result *= asqr;
  125. result -= 1.666666664e-01f;
  126. result *= asqr;
  127. result += 1.0f;
  128. result *= angle;
  129. return result * result;
  130. }
  131. #ifdef HAVE_LRINTF
  132. #define f_round(f) lrintf(f)
  133. #else
  134. // Round float to int using IEEE int* hack
  135. static __inline int f_round(float f)
  136. {
  137. ls_pcast32 p;
  138. p.f = f;
  139. p.f += (3<<22);
  140. return p.i - 0x4b400000;
  141. }
  142. #endif
  143. // Truncate float to int
  144. static __inline int f_trunc(float f)
  145. {
  146. return f_round(floorf(f));
  147. }
  148. /* Andrew Simper's pow(2, x) aproximation from the music-dsp list */
  149. #if 0
  150. /* original */
  151. static __inline float f_pow2(float x)
  152. {
  153. long *px = (long*)(&x); // store address of float as long pointer
  154. const float tx = (x-0.5f) + (3<<22); // temporary value for truncation
  155. const long lx = *((long*)&tx) - 0x4b400000; // integer power of 2
  156. const float dx = x-(float)(lx); // float remainder of power of 2
  157. x = 1.0f + dx*(0.6960656421638072f + // cubic apporoximation of 2^x
  158. dx*(0.224494337302845f + // for x in the range [0, 1]
  159. dx*(0.07944023841053369f)));
  160. *px += (lx<<23); // add integer power of 2 to exponent
  161. return x;
  162. }
  163. #else
  164. /* union version */
  165. static __inline float f_pow2(float x)
  166. {
  167. ls_pcast32 *px, tx, lx;
  168. float dx;
  169. px = (ls_pcast32 *)&x; // store address of float as long pointer
  170. tx.f = (x-0.5f) + (3<<22); // temporary value for truncation
  171. lx.i = tx.i - 0x4b400000; // integer power of 2
  172. dx = x - (float)lx.i; // float remainder of power of 2
  173. x = 1.0f + dx * (0.6960656421638072f + // cubic apporoximation of 2^x
  174. dx * (0.224494337302845f + // for x in the range [0, 1]
  175. dx * (0.07944023841053369f)));
  176. (*px).i += (lx.i << 23); // add integer power of 2 to exponent
  177. return (*px).f;
  178. }
  179. #endif
  180. /* Fast exponentiation function, y = e^x */
  181. #define f_exp(x) f_pow2(x * LN2R)
  182. #endif