DISTRHO Plugin Framework
DistrhoUtils.hpp
1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2018 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 
17 #ifndef DISTRHO_UTILS_HPP_INCLUDED
18 #define DISTRHO_UTILS_HPP_INCLUDED
19 
20 #include "src/DistrhoDefines.h"
21 
22 #include <cstdarg>
23 #include <cstdio>
24 #include <cstdlib>
25 #include <cstring>
26 
27 #include <cmath>
28 #include <limits>
29 
30 #ifdef DISTRHO_PROPER_CPP11_SUPPORT
31 # include <cstdint>
32 #else
33 # include <stdint.h>
34 #endif
35 
36 #if defined(DISTRHO_OS_MAC) && ! defined(CARLA_OS_MAC) && ! defined(DISTRHO_PROPER_CPP11_SUPPORT)
37 namespace std {
38 inline float fmin(float __x, float __y)
39  { return __builtin_fminf(__x, __y); }
40 inline float fmax(float __x, float __y)
41  { return __builtin_fmaxf(__x, __y); }
42 inline float rint(float __x)
43  { return __builtin_rintf(__x); }
44 inline float round(float __x)
45  { return __builtin_roundf(__x); }
46 }
47 #endif
48 
49 #ifndef M_PI
50 # define M_PI 3.14159265358979323846
51 #endif
52 
53 // -----------------------------------------------------------------------
54 // misc functions
55 
56 /*
57  * Return a 64-bit number from 4 8-bit numbers.
58  */
59 static inline
60 int64_t d_cconst(const uint8_t a, const uint8_t b, const uint8_t c, const uint8_t d) noexcept
61 {
62  return (a << 24) | (b << 16) | (c << 8) | (d << 0);
63 }
64 
65 /*
66  * Return an hexadecimal representation of a MAJ.MIN.MICRO version number.
67  */
68 static inline
69 uint32_t d_version(const uint8_t major, const uint8_t minor, const uint8_t micro) noexcept
70 {
71  return uint32_t(major << 16) | uint32_t(minor << 8) | (micro << 0);
72 }
73 
74 /*
75  * Dummy function.
76  */
77 static inline
78 void d_pass() noexcept {}
79 
80 // -----------------------------------------------------------------------
81 // string print functions
82 
83 /*
84  * Print a string to stdout with newline (gray color).
85  * Does nothing if DEBUG is not defined.
86  */
87 #ifndef DEBUG
88 # define d_debug(...)
89 #else
90 static inline
91 void d_debug(const char* const fmt, ...) noexcept
92 {
93  try {
94  ::va_list args;
95  ::va_start(args, fmt);
96  std::fprintf(stdout, "\x1b[30;1m");
97  std::vfprintf(stdout, fmt, args);
98  std::fprintf(stdout, "\x1b[0m\n");
99  ::va_end(args);
100  } catch (...) {}
101 }
102 #endif
103 
104 /*
105  * Print a string to stdout with newline.
106  */
107 static inline
108 void d_stdout(const char* const fmt, ...) noexcept
109 {
110  try {
111  ::va_list args;
112  ::va_start(args, fmt);
113  std::vfprintf(stdout, fmt, args);
114  std::fprintf(stdout, "\n");
115  ::va_end(args);
116  } catch (...) {}
117 }
118 
119 /*
120  * Print a string to stderr with newline.
121  */
122 static inline
123 void d_stderr(const char* const fmt, ...) noexcept
124 {
125  try {
126  ::va_list args;
127  ::va_start(args, fmt);
128  std::vfprintf(stderr, fmt, args);
129  std::fprintf(stderr, "\n");
130  ::va_end(args);
131  } catch (...) {}
132 }
133 
134 /*
135  * Print a string to stderr with newline (red color).
136  */
137 static inline
138 void d_stderr2(const char* const fmt, ...) noexcept
139 {
140  try {
141  ::va_list args;
142  ::va_start(args, fmt);
143  std::fprintf(stderr, "\x1b[31m");
144  std::vfprintf(stderr, fmt, args);
145  std::fprintf(stderr, "\x1b[0m\n");
146  ::va_end(args);
147  } catch (...) {}
148 }
149 
150 /*
151  * Print a safe assertion error message.
152  */
153 static inline
154 void d_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
155 {
156  d_stderr2("assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
157 }
158 
159 /*
160  * Print a safe exception error message.
161  */
162 static inline
163 void d_safe_exception(const char* const exception, const char* const file, const int line) noexcept
164 {
165  d_stderr2("exception caught: \"%s\" in file %s, line %i", exception, file, line);
166 }
167 
168 // -----------------------------------------------------------------------
169 // math functions
170 
171 /*
172  * Safely compare two floating point numbers.
173  * Returns true if they match.
174  */
175 template<typename T>
176 static inline
177 bool d_isEqual(const T& v1, const T& v2)
178 {
179  return std::abs(v1-v2) < std::numeric_limits<T>::epsilon();
180 }
181 
182 /*
183  * Safely compare two floating point numbers.
184  * Returns true if they don't match.
185  */
186 template<typename T>
187 static inline
188 bool d_isNotEqual(const T& v1, const T& v2)
189 {
190  return std::abs(v1-v2) >= std::numeric_limits<T>::epsilon();
191 }
192 
193 /*
194  * Safely check if a floating point number is zero.
195  */
196 template<typename T>
197 static inline
198 bool d_isZero(const T& value)
199 {
200  return std::abs(value) < std::numeric_limits<T>::epsilon();
201 }
202 
203 /*
204  * Safely check if a floating point number is not zero.
205  */
206 template<typename T>
207 static inline
208 bool d_isNotZero(const T& value)
209 {
210  return std::abs(value) >= std::numeric_limits<T>::epsilon();
211 }
212 
213 /*
214  * Get next power of 2.
215  */
216 static inline
217 uint32_t d_nextPowerOf2(uint32_t size) noexcept
218 {
219  DISTRHO_SAFE_ASSERT_RETURN(size > 0, 0);
220 
221  // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
222  --size;
223  size |= size >> 1;
224  size |= size >> 2;
225  size |= size >> 4;
226  size |= size >> 8;
227  size |= size >> 16;
228  return ++size;
229 }
230 
231 // -----------------------------------------------------------------------
232 
233 #ifndef DONT_SET_USING_DISTRHO_NAMESPACE
234  // If your code uses a lot of DISTRHO classes, then this will obviously save you
235  // a lot of typing, but can be disabled by setting DONT_SET_USING_DISTRHO_NAMESPACE.
236  namespace DISTRHO_NAMESPACE {}
237  using namespace DISTRHO_NAMESPACE;
238 #endif
239 
240 // -----------------------------------------------------------------------
241 
242 #endif // DISTRHO_UTILS_HPP_INCLUDED
Definition: DistrhoUtils.hpp:236