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
25 #include "SC_Constants.h"
30 #include <xmmintrin.h>
34 #include <smmintrin.h>
37 #if _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE /* c99 compliant compiler */
42 /* needed for msvc compiler at least */
43 template <typename float_type
>
44 inline float_type
trunc(float_type arg
)
46 if(arg
> float_type(0))
47 return std::floor(arg
);
49 return std::ceil(arg
);
53 ///////////////////////////////////////////////////////////////////////////////////////
55 inline bool sc_isnan(float x
)
57 #if defined(__cplusplus) && defined(__GNUC__) && _GLIBCXX_HAVE_ISNAN
60 return (!(x
>= 0.f
|| x
<= 0.f
));
64 ///////////////////////////////////////////////////////////////////////////////////////
66 // versions provided for float32 and float64
67 // did not supply template because do not want to instantiate for integers.
68 // all constants explicitly cast to prevent PowerPC frsp instruction generation.
70 ///////////////////////////////////////////////////////////////////////////////////////
72 // this is a function for preventing pathological math operations in ugens.
73 // can be used at the end of a block to fix any recirculating filter values.
74 inline float32
zapgremlins(float32 x
)
76 float32 absx
= std::abs(x
);
77 // very small numbers fail the first test, eliminating denormalized numbers
78 // (zero also fails the first test, but that is OK since it returns zero.)
79 // very large numbers fail the second test, eliminating infinities
80 // Not-a-Numbers fail both tests and are eliminated.
81 return (absx
> (float32
)1e-15 && absx
< (float32
)1e15
) ? x
: (float32
)0.;
84 inline float32
sc_log2(float32 x
)
87 return ::log2f(std::abs(x
));
89 return static_cast<float32
>(std::log(std::abs(x
)) * (float32
)rlog2
);
93 inline float32
sc_log10(float32 x
)
95 return std::log10(std::abs(x
));
98 inline float32
sc_midicps(float32 note
)
100 return (float32
)440. * std::pow((float32
)2., (note
- (float32
)69.) * (float32
)0.083333333333);
103 inline float32
sc_cpsmidi(float32 freq
)
105 return sc_log2(freq
* (float32
)0.0022727272727) * (float32
)12. + (float32
)69.;
108 inline float32
sc_midiratio(float32 midi
)
110 return std::pow((float32
)2. , midi
* (float32
)0.083333333333);
113 inline float32
sc_ratiomidi(float32 ratio
)
115 return (float32
)12. * sc_log2(ratio
);
118 inline float32
sc_octcps(float32 note
)
120 return (float32
)440. * std::pow((float32
)2., note
- (float32
)4.75);
123 inline float32
sc_cpsoct(float32 freq
)
125 return sc_log2(freq
* (float32
)0.0022727272727) + (float32
)4.75;
128 inline float32
sc_ampdb(float32 amp
)
130 return std::log10(amp
) * (float32
)20.;
133 inline float32
sc_dbamp(float32 db
)
135 return std::pow((float32
)10., db
* (float32
).05);
138 inline float32
sc_squared(float32 x
)
143 inline float32
sc_cubed(float32 x
)
148 inline float32
sc_sqrt(float32 x
)
150 return x
< (float32
)0. ? -sqrt(-x
) : sqrt(x
);
154 inline float32
sc_hanwindow(float32 x
)
156 if (x
< (float32
)0. || x
> (float32
)1.) return (float32
)0.;
157 return (float32
)0.5 - (float32
)0.5 * static_cast<float32
>(cos(x
* (float32
)twopi
));
160 inline float32
sc_welwindow(float32 x
)
162 if (x
< (float32
)0. || x
> (float32
)1.) return (float32
)0.;
163 return static_cast<float32
>(sin(x
* pi
));
166 inline float32
sc_triwindow(float32 x
)
168 if (x
< (float32
)0. || x
> (float32
)1.) return (float32
)0.;
169 if (x
< (float32
)0.5) return (float32
)2. * x
;
170 else return (float32
)-2. * x
+ (float32
)2.;
173 inline float32
sc_bitriwindow(float32 x
)
175 float32 ax
= (float32
)1. - std::abs(x
);
176 if (ax
<= (float32
)0.) return (float32
)0.;
180 inline float32
sc_rectwindow(float32 x
)
182 if (x
< (float32
)0. || x
> (float32
)1.) return (float32
)0.;
186 inline float32
sc_scurve(float32 x
)
188 if (x
<= (float32
)0.) return (float32
)0.;
189 if (x
>= (float32
)1.) return (float32
)1.;
190 return x
* x
* ((float32
)3. - (float32
)2. * x
);
193 inline float32
sc_scurve0(float32 x
)
195 // assumes that x is in range
196 return x
* x
* ((float32
)3. - (float32
)2. * x
);
199 inline float32
sc_ramp(float32 x
)
201 if (x
<= (float32
)0.) return (float32
)0.;
202 if (x
>= (float32
)1.) return (float32
)1.;
206 inline float32
sc_sign(float32 x
)
208 return x
< (float32
)0. ? (float32
)-1. : (x
> (float32
)0. ? (float32
)1.f
: (float32
)0.f
);
211 inline float32
sc_distort(float32 x
)
213 return x
/ ((float32
)1. + std::abs(x
));
216 inline float32
sc_distortneg(float32 x
)
219 return x
/((float32
)1. - x
);
224 inline float32
sc_softclip(float32 x
)
226 float32 absx
= std::abs(x
);
227 if (absx
<= (float32
)0.5) return x
;
228 else return (absx
- (float32
)0.25) / x
;
231 // Taylor expansion out to x**9/9! factored into multiply-adds
233 inline float32
taylorsin(float32 x
)
235 // valid range from -pi/2 to +3pi/2
236 x
= static_cast<float32
>((float32
)pi2
- std::abs(pi2
- x
));
238 return static_cast<float32
>(x
*(x2
*(x2
*(x2
*(x2
*(1.0/362880.0)
245 inline float32
sc_trunc(float32 x
)
258 inline float32
sc_ceil(float32 x
)
261 __m128 a
= _mm_set_ss(x
);
262 const int cntrl
= _MM_FROUND_TO_POS_INF
;
263 __m128 b
= _mm_round_ss(a
, a
, cntrl
);
264 return _mm_cvtss_f32(b
);
270 inline float32
sc_floor(float32 x
)
273 __m128 a
= _mm_set_ss(x
);
274 const int cntrl
= _MM_FROUND_TO_NEG_INF
;
275 __m128 b
= _mm_round_ss(a
, a
, cntrl
);
276 return _mm_cvtss_f32(b
);
278 return std::floor(x
);
282 inline float32
sc_reciprocal(float32 x
)
285 // adapted from AP-803 Newton-Raphson Method with Streaming SIMD Extensions
286 // 23 bit accuracy (out of 24bit)
287 const __m128 arg
= _mm_set_ss(x
);
288 const __m128 approx
= _mm_rcp_ss(arg
);
289 const __m128 muls
= _mm_mul_ss(_mm_mul_ss(arg
, approx
), approx
);
290 const __m128 doubleApprox
= _mm_add_ss(approx
, approx
);
291 const __m128 result
= _mm_sub_ss(doubleApprox
, muls
);
292 return _mm_cvtss_f32(result
);
298 inline float32
sc_frac(float32 x
)
300 return x
- sc_floor(x
);
304 inline float32
sc_lg3interp(float32 x1
, float32 a
, float32 b
, float32 c
, float32 d
)
306 // cubic lagrange interpolator
307 float32 x0
= x1
+ 1.f
;
308 float32 x2
= x1
- 1.f
;
309 float32 x3
= x1
- 2.f
;
311 float32 x03
= x0
* x3
* 0.5f
;
312 float32 x12
= x1
* x2
* 0.16666666666666667f
;
314 return x12
* (d
* x0
- a
* x3
) + x03
* (b
* x2
- c
* x1
);
317 inline float32
sc_CalcFeedback(float32 delaytime
, float32 decaytime
)
319 if (delaytime
== 0.f
|| decaytime
== 0.f
)
323 float32 absret
= static_cast<float32
>(exp(log001
* delaytime
/ sc_abs(decaytime
)));
324 float32 ret
= copysignf(absret
, decaytime
);
328 return static_cast<float32
>(exp(log001
* delaytime
/ decaytime
));
330 return static_cast<float32
>(-exp(log001
* delaytime
/ -decaytime
));
335 inline float32
sc_wrap1(float32 x
)
337 if (x
>= (float32
) 1.) return x
+ (float32
)-2.;
338 if (x
< (float32
)-1.) return x
+ (float32
) 2.;
342 inline float32
sc_fold1(float32 x
)
344 if (x
>= (float32
) 1.) return (float32
) 2. - x
;
345 if (x
< (float32
)-1.) return (float32
)-2. - x
;
350 ///////////////////////////////////////////////////////////////////////////////////////
352 inline float64
zapgremlins(float64 x
)
354 float64 absx
= std::abs(x
);
355 // very small numbers fail the first test, eliminating denormalized numbers
356 // (zero also fails the first test, but that is OK since it returns zero.)
357 // very large numbers fail the second test, eliminating infinities
358 // Not-a-Numbers fail both tests and are eliminated.
359 return (absx
> (float64
)1e-15 && absx
< (float64
)1e15
) ? x
: (float64
)0.;
362 inline float64
sc_log2(float64 x
)
365 return ::log2(std::abs(x
));
367 return std::log(std::abs(x
)) * rlog2
;
371 inline float64
sc_log10(float64 x
)
373 return std::log10(std::abs(x
));
376 inline float64
sc_midicps(float64 note
)
378 return (float64
)440. * std::pow((float64
)2., (note
- (float64
)69.) * (float64
)0.08333333333333333333333333);
381 inline float64
sc_cpsmidi(float64 freq
)
383 return sc_log2(freq
* (float64
)0.002272727272727272727272727) * (float64
)12. + (float64
)69.;
386 inline float64
sc_midiratio(float64 midi
)
388 return std::pow((float64
)2. , midi
* (float64
)0.083333333333);
391 inline float64
sc_ratiomidi(float64 ratio
)
393 return (float64
)12. * sc_log2(ratio
);
396 inline float64
sc_octcps(float64 note
)
398 return (float64
)440. * std::pow((float64
)2., note
- (float64
)4.75);
401 inline float64
sc_cpsoct(float64 freq
)
403 return sc_log2(freq
* (float64
)0.0022727272727) + (float64
)4.75;
406 inline float64
sc_ampdb(float64 amp
)
408 return std::log10(amp
) * (float64
)20.;
411 inline float64
sc_dbamp(float64 db
)
413 return std::pow((float64
)10., db
* (float64
).05);
416 inline float64
sc_squared(float64 x
)
421 inline float64
sc_cubed(float64 x
)
426 inline float64
sc_sqrt(float64 x
)
428 return x
< (float64
)0. ? -sqrt(-x
) : sqrt(x
);
431 inline float64
sc_hanwindow(float64 x
)
433 if (x
< (float64
)0. || x
> (float64
)1.) return (float64
)0.;
434 return (float64
)0.5 - (float64
)0.5 * cos(x
* twopi
);
437 inline float64
sc_welwindow(float64 x
)
439 if (x
< (float64
)0. || x
> (float64
)1.) return (float64
)0.;
443 inline float64
sc_triwindow(float64 x
)
445 if (x
< (float64
)0. || x
> (float64
)1.) return (float64
)0.;
446 if (x
< (float64
)0.5) return (float64
)2. * x
;
447 else return (float64
)-2. * x
+ (float64
)2.;
450 inline float64
sc_bitriwindow(float64 x
)
452 float64 ax
= std::abs(x
);
453 if (ax
> (float64
)1.) return (float64
)0.;
454 return (float64
)1. - ax
;
457 inline float64
sc_rectwindow(float64 x
)
459 if (x
< (float64
)0. || x
> (float64
)1.) return (float64
)0.;
463 inline float64
sc_scurve(float64 x
)
465 if (x
<= (float64
)0.) return (float64
)0.;
466 if (x
>= (float64
)1.) return (float64
)1.;
467 return x
* x
* ((float64
)3. - (float64
)2. * x
);
470 inline float64
sc_scurve0(float64 x
)
472 // assumes that x is in range
473 return x
* x
* ((float64
)3. - (float64
)2. * x
);
476 inline float64
sc_ramp(float64 x
)
478 if (x
<= (float64
)0.) return (float64
)0.;
479 if (x
>= (float64
)1.) return (float64
)1.;
483 inline float64
sc_sign(float64 x
)
485 return x
< (float64
)0. ? (float64
)-1. : (x
> (float64
)0. ? (float64
)1.f
: (float64
)0.f
);
488 inline float64
sc_distort(float64 x
)
490 return x
/ ((float64
)1. + std::abs(x
));
493 inline float64
sc_distortneg(float64 x
)
496 return x
/((float64
)1. - x
);
502 inline float64
sc_softclip(float64 x
)
504 float64 absx
= std::abs(x
);
505 if (absx
<= (float64
)0.5) return x
;
506 else return (absx
- (float64
)0.25) / x
;
509 // Taylor expansion out to x**9/9! factored into multiply-adds
511 inline float64
taylorsin(float64 x
)
513 x
= pi2
- std::abs(pi2
- x
);
515 return x
*(x2
*(x2
*(x2
*(x2
*(1.0/362880.0)
522 inline float64
sc_trunc(float64 x
)
530 inline float64
sc_ceil(float64 x
)
533 __m128d a
= _mm_set_sd(x
);
534 const int cntrl
= _MM_FROUND_TO_POS_INF
;
535 __m128d b
= _mm_round_sd(a
, a
, cntrl
);
536 return _mm_cvtsd_f64(b
);
542 inline float64
sc_floor(float64 x
)
545 __m128d a
= _mm_set_sd(x
);
546 const int cntrl
= _MM_FROUND_TO_NEG_INF
;
547 __m128d b
= _mm_round_sd(a
, a
, cntrl
);
548 return _mm_cvtsd_f64(b
);
550 return std::floor(x
);
554 inline float64
sc_reciprocal(float64 x
)
560 inline float64
sc_frac(float64 x
)
562 return x
- sc_floor(x
);
565 inline float64
sc_wrap1(float64 x
)
567 if (x
>= (float64
) 1.) return x
+ (float64
)-2.;
568 if (x
< (float64
)-1.) return x
+ (float64
) 2.;
572 inline float64
sc_fold1(float64 x
)
574 if (x
>= (float64
) 1.) return (float64
) 2. - x
;
575 if (x
< (float64
)-1.) return (float64
)-2. - x
;
579 inline int32
sc_grayCode(int32 x
)
586 ///////////////////////////////////////////////////////////////////////////////////////