1 #include "Geometry.hpp"
2 
3 START_NAMESPACE_DISTRHO
4 
5 namespace wolf
6 {
7 template <typename T,
8           typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
9 T clamp(const T &value, const T &min, const T &max)
10 {
11     return std::max(min, std::min(value, max));
12 }
13 
14 template <typename T>
mirror(const T & value,const T & max)15 T mirror(const T &value, const T &max)
16 {
17     return max - value;
18 }
19 
20 template <typename T>
mirror(const T & value,const T & min,const T & max)21 T mirror(const T &value, const T &min, const T &max)
22 {
23     return max - value + min;
24 }
25 
normalize(const float & value,const float & max)26 float normalize(const float &value, const float &max)
27 {
28     return value / max;
29 }
30 
logScale(const float value,const float min,const float max)31 float logScale(const float value, const float min, const float max)
32 {
33     if (value < min)
34         return min;
35     if (value > max)
36         return max;
37 
38     const float b = std::log(max / min) / (max - min);
39     const float a = max / std::exp(max * b);
40 
41     return a * std::exp(b * value);
42 }
43 
invLogScale(const float value,const float min,const float max)44 float invLogScale(const float value, const float min, const float max)
45 {
46     if (value < min)
47         return min;
48     if (value > max)
49         return max;
50 
51     const float b = std::log(max / min) / (max - min);
52     const float a = max / std::exp(max * b);
53 
54     return std::log(value / a) / b;
55 }
56 
randomNumber(const float min,const float max)57 float randomNumber(const float min, const float max)
58 {
59     return ((float)std::rand() / (float)RAND_MAX * (max - min)) + min;
60 }
61 
lerp(float a,float b,float f)62 float lerp(float a, float b, float f)
63 {
64     f = clamp(f, 0.0f, 1.0f);
65 
66     return a * (1.0 - f) + (b * f);
67 }
68 
69 /* Hexfloat stuff------------------------------------- */
70 
71 // Adapted from https://cs.chromium.org/chromium/src/v8/src/conversions.cc
72 // Copyright 2015 The Chromium Authors. All rights reserved.
73 //
74 // Redistribution and use in source and binary forms, with or without
75 // modification, are permitted provided that the following conditions are
76 // met:
77 //
78 //    * Redistributions of source code must retain the above copyright
79 // notice, this list of conditions and the following disclaimer.
80 //    * Redistributions in binary form must reproduce the above
81 // copyright notice, this list of conditions and the following disclaimer
82 // in the documentation and/or other materials provided with the
83 // distribution.
84 //    * Neither the name of Google Inc. nor the names of its
85 // contributors may be used to endorse or promote products derived from
86 // this software without specific prior written permission.
87 //
88 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
89 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
90 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
91 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
92 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
93 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
94 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
95 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
96 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
98 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99 
doubleToRadixCString(char * buf,double value,int radix)100 int doubleToRadixCString(char *buf, double value, int radix)
101 {
102     const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz";
103 
104     // Temporary buffer for the result. We start with the decimal point in the
105     // middle and write to the left for the integer part and to the right for the
106     // fractional part. 1024 characters for the exponent and 52 for the mantissa
107     // either way, with additional space for sign, decimal point and string
108     // termination should be sufficient.
109     const int kBufferSize = 2200;
110     char buffer[kBufferSize];
111 
112     int integer_cursor = kBufferSize / 2;
113     int fraction_cursor = integer_cursor;
114 
115     bool negative = value < 0;
116 
117     if (negative)
118         value = -value;
119 
120     // Split the value into an integer part and a fractional part.
121     double integer = std::floor(value);
122     double fraction = value - integer;
123 
124     // We only compute fractional digits up to the input double's precision.
125     double delta = 0.0;
126 
127     if (fraction > delta)
128     {
129         // Insert decimal point.
130         buffer[fraction_cursor++] = '.';
131         do
132         {
133             // Shift up by one digit.
134             fraction *= radix;
135             delta *= radix;
136 
137             // Write digit.
138             int digit = static_cast<int>(fraction);
139             buffer[fraction_cursor++] = chars[digit];
140 
141             // Calculate remainder.
142             fraction -= digit;
143 
144             // Round to even.
145             if (fraction > 0.5 || (fraction == 0.5 && (digit & 1)))
146             {
147                 if (fraction + delta > 1)
148                 {
149                     // We need to back trace already written digits in case of carry-over.
150                     while (true)
151                     {
152                         fraction_cursor--;
153                         if (fraction_cursor == kBufferSize / 2)
154                         {
155                             // Carry over to the integer part.
156                             integer += 1;
157                             break;
158                         }
159                         char c = buffer[fraction_cursor];
160 
161                         // Reconstruct digit.
162                         int digit = c > '9' ? (c - 'a' + 10) : (c - '0');
163 
164                         if (digit + 1 < radix)
165                         {
166                             buffer[fraction_cursor++] = chars[digit + 1];
167                             break;
168                         }
169                     }
170                     break;
171                 }
172             }
173         } while (fraction > delta);
174     }
175 
176     int exponent;
177     std::frexp(integer / radix, &exponent);
178 
179     // Compute integer digits. Fill unrepresented digits with zero.
180     while (exponent > 0)
181     {
182         integer /= radix;
183         buffer[--integer_cursor] = '0';
184         std::frexp(integer / radix, &exponent);
185     }
186 
187     do
188     {
189         const double rem = std::fmod(integer, radix);
190         buffer[--integer_cursor] = chars[static_cast<int>(rem)];
191         integer = (integer - rem) / radix;
192     } while (integer > 0);
193 
194     // Add sign and terminate string.
195     if (negative)
196         buffer[--integer_cursor] = '-';
197 
198     buffer[fraction_cursor++] = '\0';
199 
200     const int len = fraction_cursor - integer_cursor;
201 
202     memcpy(buf, buffer + integer_cursor, len * sizeof(char) + 1);
203 
204     return len - 1;
205 }
206 
207 //Adapted from https://github.com/dankogai/js-hexfloat
208 /*Copyright (c) 2016 Dan Kogai
209 
210 Permission is hereby granted, free of charge, to any person obtaining a copy
211 of this software and associated documentation files (the "Software"), to deal
212 in the Software without restriction, including without limitation the rights
213 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
214 copies of the Software, and to permit persons to whom the Software is
215 furnished to do so, subject to the following conditions:
216 
217 The above copyright notice and this permission notice shall be included in all
218 copies or substantial portions of the Software.
219 
220 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
221 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
222 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
223 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
224 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
225 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
226 SOFTWARE.*/
227 
toHexFloat(char * buffer,const double value)228 int toHexFloat(char *buffer, const double value)
229 {
230     if (value == +0.0)
231     {
232         return std::sprintf(buffer, "0x0p+0");
233     }
234     else if (value == -0.0)
235     {
236         return std::sprintf(buffer, "-0x0p+0");
237     }
238 
239     const char sign = value < 0 ? '-' : '\0';
240 
241     double hexDigits = std::abs(value);
242     int exponent = 0;
243 
244     if (hexDigits < 1)
245     {
246         while (hexDigits < 1)
247         {
248             hexDigits *= 2;
249             --exponent;
250         }
251     }
252     else
253     {
254         while (hexDigits >= 2)
255         {
256             hexDigits /= 2;
257             ++exponent;
258         }
259     }
260 
261     const char exponentSign = exponent < 0 ? '\0' : '+';
262 
263     int length;
264 
265     if (sign)
266         length = std::sprintf(buffer, "%c0x", sign);
267     else
268         length = std::sprintf(buffer, "0x");
269 
270     length += doubleToRadixCString(buffer + length, hexDigits, 16);
271 
272     if (exponentSign)
273         return length + std::sprintf(buffer + length, "p%c%d", exponentSign, exponent);
274     else
275         return length + std::sprintf(buffer + length, "p%d", exponent);
276 }
277 
278 //following functions adapted from ispc
279 /*
280   Copyright (c) 2010-2011, Intel Corporation
281   All rights reserved.
282 
283   Redistribution and use in source and binary forms, with or without
284   modification, are permitted provided that the following conditions are
285   met:
286 
287     * Redistributions of source code must retain the above copyright
288       notice, this list of conditions and the following disclaimer.
289 
290     * Redistributions in binary form must reproduce the above copyright
291       notice, this list of conditions and the following disclaimer in the
292       documentation and/or other materials provided with the distribution.
293 
294     * Neither the name of Intel Corporation nor the names of its
295       contributors may be used to endorse or promote products derived from
296       this software without specific prior written permission.
297 
298 
299    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
300    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
301    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
302    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
303    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
304    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
305    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
306    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
307    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
308    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
309    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
310 */
311 
312 /*
313  * Compute the value 2^n, where the exponent is given as an integer.
314  */
ipow2(int exponent)315 double ipow2(int exponent)
316 {
317     if (exponent < 0)
318         return 1.0 / ipow2(-exponent);
319 
320     double ret = 1.0;
321 
322     while (exponent > 16)
323     {
324         ret *= 65536.0;
325         exponent -= 16;
326     }
327 
328     while (exponent-- > 0)
329         ret *= 2.0;
330 
331     return ret;
332 }
333 
334 /*
335  * Parse a hexadecimal-formatted floating-point number (C99 hex float constant-style).
336  */
parseHexFloat(char const * ptr,char ** endPointer)337 double parseHexFloat(char const *ptr, char **endPointer)
338 {
339     DISTRHO_SAFE_ASSERT_RETURN(ptr != NULL, 0);
340     DISTRHO_SAFE_ASSERT_RETURN((ptr[0] == '0' && ptr[1] == 'x') || (ptr[0] == '-' && ptr[1] == '0' && ptr[2] == 'x'), 0);
341 
342     double sign;
343 
344     if (ptr[0] == '-')
345     {
346         sign = -1.0;
347         ptr += 3;
348     }
349     else
350     {
351         sign = 1.0;
352         ptr += 2;
353     }
354 
355     // Start initializing the mantissa
356     DISTRHO_SAFE_ASSERT_RETURN(*ptr == '0' || *ptr == '1', 0);
357     double mantissa = (*ptr == '1') ? 1.0 : 0.0;
358 
359     ++ptr;
360 
361     if (*ptr == '.')
362     {
363         // Is there a fraction part?  If so, the i'th digit we encounter
364         // gives the 1/(16^i) component of the mantissa.
365         ++ptr;
366 
367         double scale = 1.0 / 16.0;
368 
369         // Keep going until we come to the 'p', which indicates that we've
370         // come to the exponent
371         while (*ptr != 'p')
372         {
373             // Figure out the raw value from 0-15
374 
375             int digit;
376 
377             if (*ptr >= '0' && *ptr <= '9')
378             {
379                 digit = *ptr - '0';
380             }
381             else if (*ptr >= 'a' && *ptr <= 'f')
382             {
383                 digit = 10 + *ptr - 'a';
384             }
385             else
386             {
387                 fprintf(stderr, "Error while parsing hexfloat: invalid digit");
388                 return 0;
389             }
390 
391             // And add its contribution to the mantissa
392             mantissa += scale * digit;
393             scale /= 16.0;
394             ++ptr;
395         }
396     }
397     else
398     {
399         // If there's not a '.', then we better be going straight to the
400         // exponent
401         DISTRHO_SAFE_ASSERT_RETURN(*ptr == 'p', 0);
402     }
403 
404     ++ptr; // skip the 'p'
405 
406     // interestingly enough, the exponent is provided base 10..
407     int exponent = (int)std::strtol(ptr, endPointer, 10);
408 
409     // Does stdlib exp2() guarantee exact results for integer n where can
410     // be represented exactly as doubles?  I would hope so but am not sure,
411     // so let's be sure.
412     return sign * (mantissa * ipow2(exponent));
413 }
414 } // namespace wolf
415 
416 END_NAMESPACE_DISTRHO
417