common: prevent buffer overflow
[supercollider.git] / include / plugin_interface / SC_InlineUnaryOp.h
blob8581d8c1225097f91f5ed3bde02d85bcffb3a156
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef _UnaryOpUGen_
22 #define _UnaryOpUGen_
24 #include "SC_Types.h"
25 #include "SC_Constants.h"
27 #include <cmath>
29 #if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE /* c99 compliant compiler */
30 #define HAVE_C99
31 #endif
33 #ifndef HAVE_C99
34 /* needed for msvc compiler at least */
35 template <typename float_type>
36 inline float_type trunc(float_type arg)
38 if(arg > float_type(0))
39 return std::floor(arg);
40 else
41 return std::ceil(arg);
43 #endif
45 ///////////////////////////////////////////////////////////////////////////////////////
47 inline bool sc_isnan(float x)
49 #if defined(__cplusplus) && defined(__GNUC__) && _GLIBCXX_HAVE_ISNAN
50 return std::isnan(x);
51 #else
52 return (!(x >= 0.f || x <= 0.f));
53 #endif
56 ///////////////////////////////////////////////////////////////////////////////////////
58 // versions provided for float32 and float64
59 // did not supply template because do not want to instantiate for integers.
60 // all constants explicitly cast to prevent PowerPC frsp instruction generation.
62 ///////////////////////////////////////////////////////////////////////////////////////
64 // this is a function for preventing pathological math operations in ugens.
65 // can be used at the end of a block to fix any recirculating filter values.
66 inline float32 zapgremlins(float32 x)
68 float32 absx = std::abs(x);
69 // very small numbers fail the first test, eliminating denormalized numbers
70 // (zero also fails the first test, but that is OK since it returns zero.)
71 // very large numbers fail the second test, eliminating infinities
72 // Not-a-Numbers fail both tests and are eliminated.
73 return (absx > (float32)1e-15 && absx < (float32)1e15) ? x : (float32)0.;
76 inline float32 sc_log2(float32 x)
78 #ifdef HAVE_C99
79 return ::log2f(std::abs(x));
80 #else
81 return static_cast<float32>(std::log(std::abs(x)) * (float32)rlog2);
82 #endif
85 inline float32 sc_log10(float32 x)
87 return std::log10(std::abs(x));
90 inline float32 sc_midicps(float32 note)
92 return (float32)440. * std::pow((float32)2., (note - (float32)69.) * (float32)0.083333333333);
95 inline float32 sc_cpsmidi(float32 freq)
97 return sc_log2(freq * (float32)0.0022727272727) * (float32)12. + (float32)69.;
100 inline float32 sc_midiratio(float32 midi)
102 return std::pow((float32)2. , midi * (float32)0.083333333333);
105 inline float32 sc_ratiomidi(float32 ratio)
107 return (float32)12. * sc_log2(ratio);
110 inline float32 sc_octcps(float32 note)
112 return (float32)440. * std::pow((float32)2., note - (float32)4.75);
115 inline float32 sc_cpsoct(float32 freq)
117 return sc_log2(freq * (float32)0.0022727272727) + (float32)4.75;
120 inline float32 sc_ampdb(float32 amp)
122 return std::log10(amp) * (float32)20.;
125 inline float32 sc_dbamp(float32 db)
127 return std::pow((float32)10., db * (float32).05);
130 inline float32 sc_squared(float32 x)
132 return x * x;
135 inline float32 sc_cubed(float32 x)
137 return x * x * x;
140 inline float32 sc_sqrt(float32 x)
142 return x < (float32)0. ? -sqrt(-x) : sqrt(x);
146 inline float32 sc_hanwindow(float32 x)
148 if (x < (float32)0. || x > (float32)1.) return (float32)0.;
149 return (float32)0.5 - (float32)0.5 * static_cast<float32>(cos(x * (float32)twopi));
152 inline float32 sc_welwindow(float32 x)
154 if (x < (float32)0. || x > (float32)1.) return (float32)0.;
155 return static_cast<float32>(sin(x * pi));
158 inline float32 sc_triwindow(float32 x)
160 if (x < (float32)0. || x > (float32)1.) return (float32)0.;
161 if (x < (float32)0.5) return (float32)2. * x;
162 else return (float32)-2. * x + (float32)2.;
165 inline float32 sc_bitriwindow(float32 x)
167 float32 ax = (float32)1. - std::abs(x);
168 if (ax <= (float32)0.) return (float32)0.;
169 return ax;
172 inline float32 sc_rectwindow(float32 x)
174 if (x < (float32)0. || x > (float32)1.) return (float32)0.;
175 return (float32)1.;
178 inline float32 sc_scurve(float32 x)
180 if (x <= (float32)0.) return (float32)0.;
181 if (x >= (float32)1.) return (float32)1.;
182 return x * x * ((float32)3. - (float32)2. * x);
185 inline float32 sc_scurve0(float32 x)
187 // assumes that x is in range
188 return x * x * ((float32)3. - (float32)2. * x);
191 inline float32 sc_ramp(float32 x)
193 if (x <= (float32)0.) return (float32)0.;
194 if (x >= (float32)1.) return (float32)1.;
195 return x;
198 inline float32 sc_sign(float32 x)
200 return x < (float32)0. ? (float32)-1. : (x > (float32)0. ? (float32)1.f : (float32)0.f);
203 inline float32 sc_distort(float32 x)
205 return x / ((float32)1. + std::abs(x));
208 inline float32 sc_distortneg(float32 x)
210 if (x < (float32)0.)
211 return x/((float32)1. - x);
212 else
213 return x;
216 inline float32 sc_softclip(float32 x)
218 float32 absx = std::abs(x);
219 if (absx <= (float32)0.5) return x;
220 else return (absx - (float32)0.25) / x;
223 // Taylor expansion out to x**9/9! factored into multiply-adds
224 // from Phil Burk.
225 inline float32 taylorsin(float32 x)
227 // valid range from -pi/2 to +3pi/2
228 x = static_cast<float32>((float32)pi2 - std::abs(pi2 - x));
229 float32 x2 = x * x;
230 return static_cast<float32>(x*(x2*(x2*(x2*(x2*(1.0/362880.0)
231 - (1.0/5040.0))
232 + (1.0/120.0))
233 - (1.0/6.0))
234 + 1.0));
237 inline float32 sc_trunc(float32 x)
239 #ifdef HAVE_C99
240 return truncf(x);
241 #else
242 return trunc(x);
243 #endif
246 inline float32 sc_frac(float32 x)
248 return x - std::floor(x);
251 inline float32 sc_lg3interp(float32 x1, float32 a, float32 b, float32 c, float32 d)
253 // cubic lagrange interpolator
254 float32 x0 = x1 + 1.f;
255 float32 x2 = x1 - 1.f;
256 float32 x3 = x1 - 2.f;
258 float32 x03 = x0 * x3 * 0.5f;
259 float32 x12 = x1 * x2 * 0.16666666666666667f;
261 return x12 * (d * x0 - a * x3) + x03 * (b * x2 - c * x1);
264 inline float32 sc_CalcFeedback(float32 delaytime, float32 decaytime)
266 if (delaytime == 0.f || decaytime == 0.f)
267 return 0.f;
269 #ifdef HAVE_C99
270 float32 absret = static_cast<float32>(exp(log001 * delaytime / sc_abs(decaytime)));
271 float32 ret = copysignf(absret, decaytime);
272 return ret;
273 #else
274 if (decaytime > 0.f)
275 return static_cast<float32>(exp(log001 * delaytime / decaytime));
276 else
277 return static_cast<float32>(-exp(log001 * delaytime / -decaytime));
278 #endif
282 inline float32 sc_wrap1(float32 x)
284 if (x >= (float32) 1.) return x + (float32)-2.;
285 if (x < (float32)-1.) return x + (float32) 2.;
286 return x;
289 inline float32 sc_fold1(float32 x)
291 if (x >= (float32) 1.) return (float32) 2. - x;
292 if (x < (float32)-1.) return (float32)-2. - x;
293 return x;
297 ///////////////////////////////////////////////////////////////////////////////////////
299 inline float64 zapgremlins(float64 x)
301 float64 absx = std::abs(x);
302 // very small numbers fail the first test, eliminating denormalized numbers
303 // (zero also fails the first test, but that is OK since it returns zero.)
304 // very large numbers fail the second test, eliminating infinities
305 // Not-a-Numbers fail both tests and are eliminated.
306 return (absx > (float64)1e-15 && absx < (float64)1e15) ? x : (float64)0.;
309 inline float64 sc_log2(float64 x)
311 #ifdef HAVE_C99
312 return ::log2(std::abs(x));
313 #else
314 return std::log(std::abs(x)) * rlog2;
315 #endif
318 inline float64 sc_log10(float64 x)
320 return std::log10(std::abs(x));
323 inline float64 sc_midicps(float64 note)
325 return (float64)440. * std::pow((float64)2., (note - (float64)69.) * (float64)0.08333333333333333333333333);
328 inline float64 sc_cpsmidi(float64 freq)
330 return sc_log2(freq * (float64)0.002272727272727272727272727) * (float64)12. + (float64)69.;
333 inline float64 sc_midiratio(float64 midi)
335 return std::pow((float64)2. , midi * (float64)0.083333333333);
338 inline float64 sc_ratiomidi(float64 ratio)
340 return (float64)12. * sc_log2(ratio);
343 inline float64 sc_octcps(float64 note)
345 return (float64)440. * std::pow((float64)2., note - (float64)4.75);
348 inline float64 sc_cpsoct(float64 freq)
350 return sc_log2(freq * (float64)0.0022727272727) + (float64)4.75;
353 inline float64 sc_ampdb(float64 amp)
355 return std::log10(amp) * (float64)20.;
358 inline float64 sc_dbamp(float64 db)
360 return std::pow((float64)10., db * (float64).05);
363 inline float64 sc_squared(float64 x)
365 return x * x;
368 inline float64 sc_cubed(float64 x)
370 return x * x * x;
373 inline float64 sc_sqrt(float64 x)
375 return x < (float64)0. ? -sqrt(-x) : sqrt(x);
378 inline float64 sc_hanwindow(float64 x)
380 if (x < (float64)0. || x > (float64)1.) return (float64)0.;
381 return (float64)0.5 - (float64)0.5 * cos(x * twopi);
384 inline float64 sc_welwindow(float64 x)
386 if (x < (float64)0. || x > (float64)1.) return (float64)0.;
387 return sin(x * pi);
390 inline float64 sc_triwindow(float64 x)
392 if (x < (float64)0. || x > (float64)1.) return (float64)0.;
393 if (x < (float64)0.5) return (float64)2. * x;
394 else return (float64)-2. * x + (float64)2.;
397 inline float64 sc_bitriwindow(float64 x)
399 float64 ax = std::abs(x);
400 if (ax > (float64)1.) return (float64)0.;
401 return (float64)1. - ax;
404 inline float64 sc_rectwindow(float64 x)
406 if (x < (float64)0. || x > (float64)1.) return (float64)0.;
407 return (float64)1.;
410 inline float64 sc_scurve(float64 x)
412 if (x <= (float64)0.) return (float64)0.;
413 if (x >= (float64)1.) return (float64)1.;
414 return x * x * ((float64)3. - (float64)2. * x);
417 inline float64 sc_scurve0(float64 x)
419 // assumes that x is in range
420 return x * x * ((float64)3. - (float64)2. * x);
423 inline float64 sc_ramp(float64 x)
425 if (x <= (float64)0.) return (float64)0.;
426 if (x >= (float64)1.) return (float64)1.;
427 return x;
430 inline float64 sc_sign(float64 x)
432 return x < (float64)0. ? (float64)-1. : (x > (float64)0. ? (float64)1.f : (float64)0.f);
435 inline float64 sc_distort(float64 x)
437 return x / ((float64)1. + std::abs(x));
440 inline float64 sc_distortneg(float64 x)
442 if (x < (float64)0.)
443 return x/((float64)1. - x);
444 else
445 return x;
449 inline float64 sc_softclip(float64 x)
451 float64 absx = std::abs(x);
452 if (absx <= (float64)0.5) return x;
453 else return (absx - (float64)0.25) / x;
456 // Taylor expansion out to x**9/9! factored into multiply-adds
457 // from Phil Burk.
458 inline float64 taylorsin(float64 x)
460 x = pi2 - std::abs(pi2 - x);
461 float64 x2 = x * x;
462 return x*(x2*(x2*(x2*(x2*(1.0/362880.0)
463 - (1.0/5040.0))
464 + (1.0/120.0))
465 - (1.0/6.0))
466 + 1.0);
469 inline float64 sc_trunc(float64 x)
471 return trunc(x);
474 inline float64 sc_frac(float64 x)
476 return x - std::floor(x);
479 inline float64 sc_wrap1(float64 x)
481 if (x >= (float64) 1.) return x + (float64)-2.;
482 if (x < (float64)-1.) return x + (float64) 2.;
483 return x;
486 inline float64 sc_fold1(float64 x)
488 if (x >= (float64) 1.) return (float64) 2. - x;
489 if (x < (float64)-1.) return (float64)-2. - x;
490 return x;
493 inline int32 sc_grayCode(int32 x)
495 return x ^ (x >> 1);
500 ///////////////////////////////////////////////////////////////////////////////////////
502 #endif