Audio plugin host https://kx.studio/carla
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.

CarlaMathUtils.hpp 8.0KB

10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Carla math utils
  3. * Copyright (C) 2011-2022 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_MATH_UTILS_HPP_INCLUDED
  18. #define CARLA_MATH_UTILS_HPP_INCLUDED
  19. #include "CarlaUtils.hpp"
  20. #include <cmath>
  21. #include <limits>
  22. // --------------------------------------------------------------------------------------------------------------------
  23. // math functions (base)
  24. /*
  25. * Return the lower of 2 values, with 'min' as the minimum possible value (ie, constrain).
  26. */
  27. template<typename T>
  28. static inline
  29. const T& carla_minConstrained(const T& v1, const T& v2, const T& min) noexcept
  30. {
  31. return (v1 <= min || v2 <= min) ? min : (v1 < v2 ? v1 : v2);
  32. }
  33. /*
  34. * Return the lower positive of 2 values.
  35. * If one of the values is zero, returns zero.
  36. * If one value is negative but the other positive, returns the positive.
  37. * Returned value is guaranteed to be >= 0.
  38. */
  39. template<typename T>
  40. static inline
  41. T carla_minPositive(const T& v1, const T& v2) noexcept
  42. {
  43. if (v1 == 0 || v2 == 0)
  44. return 0;
  45. if (v1 < 0)
  46. return (v2 > 0) ? v2 : 0;
  47. if (v2 < 0)
  48. return (v1 > 0) ? v1 : 0;
  49. return (v1 < v2) ? v1 : v2;
  50. }
  51. /*
  52. * Return the higher of 2 values, with 'max' as the maximum possible value (ie, limit).
  53. */
  54. template<typename T>
  55. static inline
  56. const T& carla_maxLimited(const T& v1, const T& v2, const T& max) noexcept
  57. {
  58. return (v1 >= max || v2 >= max) ? max : (v1 > v2 ? v1 : v2);
  59. }
  60. /*
  61. * Return the higher negative of 2 values.
  62. * If one of the values is zero, returns zero.
  63. * If one value is positive but the other negative, returns the negative.
  64. * Returned value is guaranteed to be <= 0.
  65. */
  66. template<typename T>
  67. static inline
  68. T carla_maxNegative(const T& v1, const T& v2) noexcept
  69. {
  70. if (v1 == 0 || v2 == 0)
  71. return 0;
  72. if (v1 > 0)
  73. return (v2 < 0) ? v2 : 0;
  74. if (v2 > 0)
  75. return (v1 < 0) ? v1 : 0;
  76. return (v1 > v2) ? v1 : v2;
  77. }
  78. /*
  79. * Return a value between 'min' and 'max'.
  80. */
  81. template<typename T>
  82. static inline
  83. const T& carla_fixedValue(const T& min, const T& max, const T& value) noexcept
  84. {
  85. CARLA_SAFE_ASSERT_RETURN(max > min, min);
  86. if (value <= min)
  87. return min;
  88. if (value >= max)
  89. return max;
  90. return value;
  91. }
  92. /*
  93. * Get next power of 2.
  94. */
  95. static inline
  96. uint32_t carla_nextPowerOf2(uint32_t size) noexcept
  97. {
  98. CARLA_SAFE_ASSERT_RETURN(size > 0, 0);
  99. // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
  100. --size;
  101. size |= size >> 1;
  102. size |= size >> 2;
  103. size |= size >> 4;
  104. size |= size >> 8;
  105. size |= size >> 16;
  106. return ++size;
  107. }
  108. /*
  109. * Safely check if 2 numbers are equal.
  110. */
  111. template<typename T>
  112. static inline
  113. bool carla_isEqual(const T& v1, const T& v2)
  114. {
  115. return std::abs(v1-v2) < std::numeric_limits<T>::epsilon();
  116. }
  117. /*
  118. * Safely check if 2 numbers are not equal.
  119. */
  120. template<typename T>
  121. static inline
  122. bool carla_isNotEqual(const T& v1, const T& v2)
  123. {
  124. return std::abs(v1-v2) >= std::numeric_limits<T>::epsilon();
  125. }
  126. /*
  127. * Safely check if a number is zero.
  128. */
  129. template<typename T>
  130. static inline
  131. bool carla_isZero(const T& value)
  132. {
  133. return std::abs(value) < std::numeric_limits<T>::epsilon();
  134. }
  135. /*
  136. * Safely check if a number is not zero.
  137. */
  138. template<typename T>
  139. static inline
  140. bool carla_isNotZero(const T& value)
  141. {
  142. return std::abs(value) >= std::numeric_limits<T>::epsilon();
  143. }
  144. // --------------------------------------------------------------------------------------------------------------------
  145. // math functions (extended)
  146. /*
  147. * Add float array values to another float array.
  148. */
  149. static inline
  150. void carla_addFloats(float dest[], const float src[], const std::size_t count) noexcept
  151. {
  152. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  153. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  154. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  155. for (std::size_t i=0; i<count; ++i)
  156. {
  157. if (!std::isfinite(dest[i]))
  158. __builtin_unreachable();
  159. if (!std::isfinite(src[i]))
  160. __builtin_unreachable();
  161. *dest++ += *src++;
  162. }
  163. }
  164. /*
  165. * Copy float array values to another float array.
  166. */
  167. static inline
  168. void carla_copyFloats(float dest[], const float src[], const std::size_t count) noexcept
  169. {
  170. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  171. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  172. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  173. std::memcpy(dest, src, count*sizeof(float));
  174. }
  175. /*
  176. * Fill a float array with a single float value.
  177. */
  178. static inline
  179. void carla_fillFloatsWithSingleValue(float data[], const float& value, const std::size_t count) noexcept
  180. {
  181. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  182. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  183. if (carla_isZero(value))
  184. {
  185. std::memset(data, 0, count*sizeof(float));
  186. }
  187. else
  188. {
  189. for (std::size_t i=0; i<count; ++i)
  190. {
  191. if (!std::isfinite(data[i]))
  192. __builtin_unreachable();
  193. *data++ = value;
  194. }
  195. }
  196. }
  197. /*
  198. * Clear a float array.
  199. */
  200. static inline
  201. void carla_zeroFloats(float floats[], const std::size_t count) noexcept
  202. {
  203. CARLA_SAFE_ASSERT_RETURN(floats != nullptr,);
  204. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  205. std::memset(floats, 0, count*sizeof(float));
  206. }
  207. // --------------------------------------------------------------------------------------------------------------------
  208. /*
  209. * Fill an array with a fixed value, floating-point version.
  210. */
  211. template <>
  212. inline
  213. void carla_fill<float>(float data[], const float& value, const std::size_t count) noexcept
  214. {
  215. carla_fillFloatsWithSingleValue(data, value, count);
  216. }
  217. /*
  218. * Find the highest absolute and normalized value within a float array.
  219. */
  220. static inline
  221. float carla_findMaxNormalizedFloat(const float floats[], const std::size_t count)
  222. {
  223. CARLA_SAFE_ASSERT_RETURN(floats != nullptr, 0.0f);
  224. CARLA_SAFE_ASSERT_RETURN(count > 0, 0.0f);
  225. static constexpr const float kEmptyFloats[8192] = {};
  226. if (count <= 8192 && std::memcmp(floats, kEmptyFloats, count) == 0)
  227. return 0.0f;
  228. float tmp, maxf2 = std::abs(floats[0]);
  229. for (std::size_t i=1; i<count; ++i)
  230. {
  231. if (!std::isfinite(floats[i]))
  232. __builtin_unreachable();
  233. tmp = std::abs(*floats++);
  234. if (tmp > maxf2)
  235. maxf2 = tmp;
  236. }
  237. if (maxf2 > 1.0f)
  238. maxf2 = 1.0f;
  239. return maxf2;
  240. }
  241. /*
  242. * Multiply an array with a fixed value, float-specific version.
  243. */
  244. static inline
  245. void carla_multiply(float data[], const float& multiplier, const std::size_t count) noexcept
  246. {
  247. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  248. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  249. if (carla_isZero(multiplier))
  250. {
  251. std::memset(data, 0, count*sizeof(float));
  252. }
  253. else
  254. {
  255. for (std::size_t i=0; i<count; ++i)
  256. {
  257. if (!std::isfinite(data[i]))
  258. __builtin_unreachable();
  259. *data++ *= multiplier;
  260. }
  261. }
  262. }
  263. // --------------------------------------------------------------------------------------------------------------------
  264. // Missing functions in old OSX versions.
  265. #if ! defined(DISTRHO_UTILS_HPP_INCLUDED) && ! defined(CARLA_PROPER_CPP11_SUPPORT)
  266. namespace std {
  267. inline float fmin(float __x, float __y)
  268. { return __builtin_fminf(__x, __y); }
  269. inline float fmax(float __x, float __y)
  270. { return __builtin_fmaxf(__x, __y); }
  271. inline float rint(float __x)
  272. { return __builtin_rintf(__x); }
  273. inline float round(float __x)
  274. { return __builtin_roundf(__x); }
  275. }
  276. #endif
  277. // --------------------------------------------------------------------------------------------------------------------
  278. #endif // CARLA_MATH_UTILS_HPP_INCLUDED