DISTRHO Plugin Framework
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.

296 lines
7.8KB

  1. /*
  2. * DISTRHO Plugin Framework (DPF)
  3. * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any purpose with
  6. * or without fee is hereby granted, provided that the above copyright notice and this
  7. * permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
  10. * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
  11. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
  13. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifndef DISTRHO_UTILS_HPP_INCLUDED
  17. #define DISTRHO_UTILS_HPP_INCLUDED
  18. #include "src/DistrhoDefines.h"
  19. #include <cstdarg>
  20. #include <cstdio>
  21. #include <cstdlib>
  22. #include <cstring>
  23. #include <cmath>
  24. #include <limits>
  25. #ifdef DISTRHO_PROPER_CPP11_SUPPORT
  26. # include <cstdint>
  27. #else
  28. # include <stdint.h>
  29. #endif
  30. #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT)
  31. namespace std {
  32. inline float fmin(float __x, float __y)
  33. { return __builtin_fminf(__x, __y); }
  34. inline float fmax(float __x, float __y)
  35. { return __builtin_fmaxf(__x, __y); }
  36. inline float rint(float __x)
  37. { return __builtin_rintf(__x); }
  38. inline float round(float __x)
  39. { return __builtin_roundf(__x); }
  40. }
  41. #endif
  42. #ifndef M_PI
  43. # define M_PI 3.14159265358979323846
  44. #endif
  45. #define DISTRHO_MACRO_AS_STRING_VALUE(MACRO) #MACRO
  46. #define DISTRHO_MACRO_AS_STRING(MACRO) DISTRHO_MACRO_AS_STRING_VALUE(MACRO)
  47. // -----------------------------------------------------------------------
  48. // misc functions
  49. /*
  50. * Return a 64-bit number from 4 8-bit numbers.
  51. */
  52. static inline
  53. int64_t d_cconst(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d) noexcept
  54. {
  55. return (a << 24) | (b << 16) | (c << 8) | (d << 0);
  56. }
  57. /*
  58. * Return an hexadecimal representation of a MAJ.MIN.MICRO version number.
  59. */
  60. static inline
  61. uint32_t d_version(const uint8_t major, const uint8_t minor, const uint8_t micro) noexcept
  62. {
  63. return uint32_t(major << 16) | uint32_t(minor << 8) | (micro << 0);
  64. }
  65. /*
  66. * Dummy function.
  67. */
  68. static inline
  69. void d_pass() noexcept {}
  70. // -----------------------------------------------------------------------
  71. // string print functions
  72. /*
  73. * Print a string to stdout with newline (gray color).
  74. * Does nothing if DEBUG is not defined.
  75. */
  76. #ifndef DEBUG
  77. # define d_debug(...)
  78. #else
  79. static inline
  80. void d_debug(const char* const fmt, ...) noexcept
  81. {
  82. try {
  83. ::va_list args;
  84. ::va_start(args, fmt);
  85. std::fprintf(stdout, "\x1b[30;1m");
  86. std::vfprintf(stdout, fmt, args);
  87. std::fprintf(stdout, "\x1b[0m\n");
  88. ::va_end(args);
  89. } catch (...) {}
  90. }
  91. #endif
  92. /*
  93. * Print a string to stdout with newline.
  94. */
  95. static inline
  96. void d_stdout(const char* const fmt, ...) noexcept
  97. {
  98. try {
  99. ::va_list args;
  100. ::va_start(args, fmt);
  101. std::vfprintf(stdout, fmt, args);
  102. std::fprintf(stdout, "\n");
  103. ::va_end(args);
  104. } catch (...) {}
  105. }
  106. /*
  107. * Print a string to stderr with newline.
  108. */
  109. static inline
  110. void d_stderr(const char* const fmt, ...) noexcept
  111. {
  112. try {
  113. ::va_list args;
  114. ::va_start(args, fmt);
  115. std::vfprintf(stderr, fmt, args);
  116. std::fprintf(stderr, "\n");
  117. ::va_end(args);
  118. } catch (...) {}
  119. }
  120. /*
  121. * Print a string to stderr with newline (red color).
  122. */
  123. static inline
  124. void d_stderr2(const char* const fmt, ...) noexcept
  125. {
  126. try {
  127. ::va_list args;
  128. ::va_start(args, fmt);
  129. std::fprintf(stderr, "\x1b[31m");
  130. std::vfprintf(stderr, fmt, args);
  131. std::fprintf(stderr, "\x1b[0m\n");
  132. ::va_end(args);
  133. } catch (...) {}
  134. }
  135. /*
  136. * Print a safe assertion error message.
  137. */
  138. static inline
  139. void d_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
  140. {
  141. d_stderr2("assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  142. }
  143. /*
  144. * Print a safe assertion error message, with 1 extra signed integer value.
  145. */
  146. static inline
  147. void d_safe_assert_int(const char* const assertion, const char* const file,
  148. const int line, const int value) noexcept
  149. {
  150. d_stderr2("assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  151. }
  152. /*
  153. * Print a safe assertion error message, with 1 extra unsigned integer value.
  154. */
  155. static inline
  156. void d_safe_assert_uint(const char* const assertion, const char* const file,
  157. const int line, const uint value) noexcept
  158. {
  159. d_stderr2("assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value);
  160. }
  161. /*
  162. * Print a safe assertion error message, with 2 extra signed integer values.
  163. */
  164. static inline
  165. void d_safe_assert_int2(const char* const assertion, const char* const file,
  166. const int line, const int v1, const int v2) noexcept
  167. {
  168. d_stderr2("assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  169. }
  170. /*
  171. * Print a safe assertion error message, with 2 extra unsigned integer values.
  172. */
  173. static inline
  174. void d_safe_assert_uint2(const char* const assertion, const char* const file,
  175. const int line, const uint v1, const uint v2) noexcept
  176. {
  177. d_stderr2("assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2);
  178. }
  179. /*
  180. * Print a safe assertion error message, with a custom error message.
  181. */
  182. static inline
  183. void d_custom_safe_assert(const char* const message, const char* const assertion, const char* const file,
  184. const int line) noexcept
  185. {
  186. d_stderr2("assertion failure: %s, condition \"%s\" in file %s, line %i", message, assertion, file, line);
  187. }
  188. /*
  189. * Print a safe exception error message.
  190. */
  191. static inline
  192. void d_safe_exception(const char* const exception, const char* const file, const int line) noexcept
  193. {
  194. d_stderr2("exception caught: \"%s\" in file %s, line %i", exception, file, line);
  195. }
  196. // -----------------------------------------------------------------------
  197. // math functions
  198. /*
  199. * Safely compare two floating point numbers.
  200. * Returns true if they match.
  201. */
  202. template<typename T>
  203. static inline
  204. bool d_isEqual(const T& v1, const T& v2)
  205. {
  206. return std::abs(v1-v2) < std::numeric_limits<T>::epsilon();
  207. }
  208. /*
  209. * Safely compare two floating point numbers.
  210. * Returns true if they don't match.
  211. */
  212. template<typename T>
  213. static inline
  214. bool d_isNotEqual(const T& v1, const T& v2)
  215. {
  216. return std::abs(v1-v2) >= std::numeric_limits<T>::epsilon();
  217. }
  218. /*
  219. * Safely check if a floating point number is zero.
  220. */
  221. template<typename T>
  222. static inline
  223. bool d_isZero(const T& value)
  224. {
  225. return std::abs(value) < std::numeric_limits<T>::epsilon();
  226. }
  227. /*
  228. * Safely check if a floating point number is not zero.
  229. */
  230. template<typename T>
  231. static inline
  232. bool d_isNotZero(const T& value)
  233. {
  234. return std::abs(value) >= std::numeric_limits<T>::epsilon();
  235. }
  236. /*
  237. * Get next power of 2.
  238. */
  239. static inline
  240. uint32_t d_nextPowerOf2(uint32_t size) noexcept
  241. {
  242. DISTRHO_SAFE_ASSERT_RETURN(size > 0, 0);
  243. // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
  244. --size;
  245. size |= size >> 1;
  246. size |= size >> 2;
  247. size |= size >> 4;
  248. size |= size >> 8;
  249. size |= size >> 16;
  250. return ++size;
  251. }
  252. // -----------------------------------------------------------------------
  253. #ifndef DONT_SET_USING_DISTRHO_NAMESPACE
  254. // If your code uses a lot of DISTRHO classes, then this will obviously save you
  255. // a lot of typing, but can be disabled by setting DONT_SET_USING_DISTRHO_NAMESPACE.
  256. namespace DISTRHO_NAMESPACE {}
  257. using namespace DISTRHO_NAMESPACE;
  258. #endif
  259. // -----------------------------------------------------------------------
  260. #endif // DISTRHO_UTILS_HPP_INCLUDED