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
22 #include "SC_PlugIn.h"
25 #include "simd_unary_arithmetic.hpp"
26 #include "simd_binary_arithmetic.hpp"
27 #include "simd_ternary_arithmetic.hpp"
28 #include "simd_math.hpp"
29 #include "simd_memory.hpp"
30 #include "softclip.hpp"
31 #include "simd_unit_conversion.hpp"
33 #if defined(__GNUC__) && !defined(__clang__)
34 #define inline_functions __attribute__ ((flatten))
36 #define inline_functions
39 using nova::wrap_argument
;
41 #define NOVA_WRAPPER(NAME, NOVANAME) \
42 inline_functions void NAME##_nova(UnaryOpUGen *unit, int inNumSamples) \
44 nova::NOVANAME##_vec_simd(OUT(0), IN(0), inNumSamples); \
47 #define NOVA_WRAPPER_CT_UNROLL(NAME, NOVANAME) \
48 inline_functions void NAME##_nova(UnaryOpUGen *unit, int inNumSamples) \
50 nova::NOVANAME##_vec_simd(OUT(0), IN(0), inNumSamples); \
53 inline_functions void NAME##_nova_64(UnaryOpUGen *unit, int inNumSamples) \
55 nova::NOVANAME##_vec_simd<64>(OUT(0), IN(0)); \
60 using namespace std
; // for math functions
62 static InterfaceTable
*ft
;
64 //////////////////////////////////////////////////////////////////////////////////////////////////
67 /* special unary math operators */
133 struct UnaryOpUGen
: public Unit
137 typedef void (*UnaryOpFunc
)(UnaryOpUGen
*unit
, int inNumSamples
);
142 void UnaryOpUGen_Ctor(UnaryOpUGen
*unit
);
145 bool ChooseOperatorFunc(UnaryOpUGen
*unit
);
147 void UnaryOpUGen_Ctor(UnaryOpUGen
*unit
)
149 bool initialized
= ChooseOperatorFunc(unit
);
151 (unit
->mCalcFunc
)(unit
, 1);
154 ////////////////////////////////////////////////////////////////////////////////////////////////////////
156 #define DEFINE_UNARY_OP_FUNCS(name, function) \
157 extern "C" void name##_a(UnaryOpUGen *unit, int inNumSamples) \
159 float *out = ZOUT(0); \
162 LOOP1(inNumSamples, \
163 ZXP(out) = function(ZXP(a)); \
167 extern "C" void name##_1(UnaryOpUGen *unit, int inNumSamples) \
169 ZOUT0(0) = function(ZIN0(0)); \
172 extern "C" void name##_d(UnaryOpUGen *unit, int inNumSamples) \
174 if (inNumSamples) { \
175 float x = DEMANDINPUT_A(0, inNumSamples); \
176 OUT0(0) = sc_isnan(x) ? NAN : function(x); \
182 template <typename F
>
183 inline F
sc_invert(F x
)
188 DEFINE_UNARY_OP_FUNCS(invert
, sc_invert
)
191 inline_functions
void invert_nova(UnaryOpUGen
*unit
, int inNumSamples
)
193 nova::minus_vec_simd(OUT(0), 0.f
, IN(0), inNumSamples
);
196 inline_functions
void invert_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
198 nova::minus_vec_simd
<64>(OUT(0), 0.f
, IN(0));
204 template <typename F
>
207 return x
> 0.f
? 0.f
: 1.f
;
210 DEFINE_UNARY_OP_FUNCS(not, sc_not
)
212 void zero_a(UnaryOpUGen
*unit
, int inNumSamples
)
214 float *out
= ZOUT(0);
216 ZClear(inNumSamples
, out
);
219 void thru_a(UnaryOpUGen
*unit
, int inNumSamples
)
221 float *out
= ZOUT(0);
224 ZCopy(inNumSamples
, out
, a
);
227 DEFINE_UNARY_OP_FUNCS(abs
, std::abs
)
230 inline_functions
void zero_nova(UnaryOpUGen
*unit
, int inNumSamples
)
232 nova::zerovec_simd(OUT(0), inNumSamples
);
235 inline_functions
void zero_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
237 nova::zerovec_simd
<64>(OUT(0));
240 inline_functions
void thru_nova(UnaryOpUGen
*unit
, int inNumSamples
)
242 nova::copyvec_simd(OUT(0), IN(0), inNumSamples
);
245 inline_functions
void thru_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
247 nova::copyvec_simd
<64>(OUT(0), IN(0));
250 inline_functions
void abs_nova(UnaryOpUGen
*unit
, int inNumSamples
)
252 nova::abs_vec_simd(OUT(0), IN(0), inNumSamples
);
255 inline_functions
void abs_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
257 nova::abs_vec_simd
<64>(OUT(0), IN(0));
261 template <typename F
>
262 inline F
sc_recip(F x
)
267 DEFINE_UNARY_OP_FUNCS(recip
, sc_recip
)
270 inline_functions
void recip_nova(UnaryOpUGen
*unit
, int inNumSamples
)
272 nova::over_vec_simd(OUT(0), 1.f
, IN(0), inNumSamples
);
275 inline_functions
void recip_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
277 nova::over_vec_simd
<64>(OUT(0), 1.f
, IN(0));
282 DEFINE_UNARY_OP_FUNCS(floor
, floor
)
283 DEFINE_UNARY_OP_FUNCS(ceil
, ceil
)
286 NOVA_WRAPPER_CT_UNROLL(floor
, floor
)
287 NOVA_WRAPPER_CT_UNROLL(ceil
, ceil
)
290 DEFINE_UNARY_OP_FUNCS(sin
, sin
)
291 DEFINE_UNARY_OP_FUNCS(cos
, cos
)
292 DEFINE_UNARY_OP_FUNCS(tan
, tan
)
294 DEFINE_UNARY_OP_FUNCS(asin
, asin
)
295 DEFINE_UNARY_OP_FUNCS(acos
, acos
)
296 DEFINE_UNARY_OP_FUNCS(atan
, atan
)
298 DEFINE_UNARY_OP_FUNCS(sinh
, sinh
)
299 DEFINE_UNARY_OP_FUNCS(cosh
, cosh
)
300 DEFINE_UNARY_OP_FUNCS(tanh
, tanh
)
304 NOVA_WRAPPER(sin
, sin
)
305 NOVA_WRAPPER(cos
, cos
)
306 NOVA_WRAPPER(tan
, tan
)
307 NOVA_WRAPPER(asin
, asin
)
308 NOVA_WRAPPER(acos
, acos
)
309 NOVA_WRAPPER(atan
, atan
)
310 NOVA_WRAPPER(tanh
, tanh
)
314 DEFINE_UNARY_OP_FUNCS(log
, std::log
)
315 DEFINE_UNARY_OP_FUNCS(log2
, sc_log2
)
316 DEFINE_UNARY_OP_FUNCS(log10
, sc_log10
)
317 DEFINE_UNARY_OP_FUNCS(exp
, exp
)
320 NOVA_WRAPPER(log
, log
)
321 NOVA_WRAPPER(log2
, log2
)
322 NOVA_WRAPPER(log10
, log10
)
323 NOVA_WRAPPER(exp
, exp
)
326 DEFINE_UNARY_OP_FUNCS(sqrt
, sc_sqrt
)
329 NOVA_WRAPPER_CT_UNROLL(sqrt
, signed_sqrt
)
332 DEFINE_UNARY_OP_FUNCS(ampdb
, sc_ampdb
)
333 DEFINE_UNARY_OP_FUNCS(dbamp
, sc_dbamp
)
334 DEFINE_UNARY_OP_FUNCS(midicps
, sc_midicps
)
335 DEFINE_UNARY_OP_FUNCS(cpsmidi
, sc_cpsmidi
)
336 DEFINE_UNARY_OP_FUNCS(midiratio
, sc_midiratio
)
337 DEFINE_UNARY_OP_FUNCS(ratiomidi
, sc_ratiomidi
)
338 DEFINE_UNARY_OP_FUNCS(cpsoct
, sc_cpsoct
)
339 DEFINE_UNARY_OP_FUNCS(octcps
, sc_octcps
)
342 NOVA_WRAPPER(ampdb
, amp2db
)
343 NOVA_WRAPPER(dbamp
, db2amp
)
344 NOVA_WRAPPER(midicps
, midi2freq
)
345 NOVA_WRAPPER(cpsmidi
, freq2midi
)
346 NOVA_WRAPPER(midiratio
, midi2ratio
)
347 NOVA_WRAPPER(ratiomidi
, ratio2midi
)
348 NOVA_WRAPPER(cpsoct
, freq2oct
)
349 NOVA_WRAPPER(octcps
, oct2freq
)
353 DEFINE_UNARY_OP_FUNCS(frac
, sc_frac
)
355 NOVA_WRAPPER_CT_UNROLL(frac
, frac
)
359 DEFINE_UNARY_OP_FUNCS(squared
, sc_squared
)
361 NOVA_WRAPPER_CT_UNROLL(squared
, square
)
365 DEFINE_UNARY_OP_FUNCS(cubed
, sc_cubed
)
367 NOVA_WRAPPER_CT_UNROLL(cubed
, cube
)
370 DEFINE_UNARY_OP_FUNCS(sign
, sc_sign
)
373 NOVA_WRAPPER_CT_UNROLL(sign
, sgn
)
376 DEFINE_UNARY_OP_FUNCS(distort
, sc_distort
)
379 void distort_a_nova(UnaryOpUGen
*unit
, int inNumSamples
)
383 using namespace nova
;
385 int vs
= vec
<float>::size
;
386 int len
= inNumSamples
/ vs
;
389 for (int i
=0; i
<len
; ++i
) {
390 vec
<float> arg
; arg
.load_aligned(a
);
391 vec
<float> result
= arg
/ (one
+ abs(arg
));
392 result
.store_aligned(out
);
398 DEFINE_UNARY_OP_FUNCS(distortneg
, sc_distortneg
)
399 DEFINE_UNARY_OP_FUNCS(softclip
, sc_softclip
)
402 NOVA_WRAPPER_CT_UNROLL(softclip
, softclip
)
405 DEFINE_UNARY_OP_FUNCS(rectwindow
, sc_rectwindow
)
406 DEFINE_UNARY_OP_FUNCS(hanwindow
, sc_hanwindow
)
407 DEFINE_UNARY_OP_FUNCS(welwindow
, sc_welwindow
)
408 DEFINE_UNARY_OP_FUNCS(triwindow
, sc_triwindow
)
410 DEFINE_UNARY_OP_FUNCS(scurve
, sc_scurve
)
411 DEFINE_UNARY_OP_FUNCS(ramp
, sc_ramp
)
415 inline_functions
void ramp_nova(UnaryOpUGen
*unit
, int inNumSamples
)
417 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(0.f
), wrap_argument(1.f
), inNumSamples
);
420 inline_functions
void ramp_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
422 nova::clip_vec_simd
<64>(OUT(0), wrap_argument(IN(0)), wrap_argument(0.f
), wrap_argument(1.f
));
426 ////////////////////////////////////////////////////////////////////////////////////////////////////////
428 void zero_d(UnaryOpUGen
*unit
, int inNumSamples
)
431 float x
= DEMANDINPUT_A(0, inNumSamples
);
432 OUT0(0) = sc_isnan(x
) ? NAN
: 0.f
;
438 void thru_d(UnaryOpUGen
*unit
, int inNumSamples
)
441 float x
= DEMANDINPUT_A(0, inNumSamples
);
442 OUT0(0) = sc_isnan(x
) ? NAN
: (x
);
448 ////////////////////////////////////////////////////////////////////////////////////////////////////////
450 static UnaryOpFunc
ChooseNormalFunc(UnaryOpUGen
*unit
)
452 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
454 switch (unit
->mSpecialIndex
) {
455 case opSilence
: func
= &zero_a
; break;
456 case opThru
: func
= &thru_a
; break;
457 case opNeg
: func
= &invert_a
; break;
458 case opNot
: func
= ¬_a
; break;
459 case opAbs
: func
= &abs_a
; break;
460 case opCeil
: func
= &ceil_a
; break;
461 case opFloor
: func
= &floor_a
; break;
462 case opFrac
: func
= &frac_a
; break;
463 case opSign
: func
= &sign_a
; break;
464 case opSquared
: func
= &squared_a
; break;
465 case opCubed
: func
= &cubed_a
; break;
466 case opSqrt
: func
= &sqrt_a
; break;
467 case opExp
: func
= &exp_a
; break;
468 case opRecip
: func
= &recip_a
; break;
469 case opMIDICPS
: func
= &midicps_a
; break;
470 case opCPSMIDI
: func
= &cpsmidi_a
; break;
472 case opMIDIRatio
: func
= &midiratio_a
; break;
473 case opRatioMIDI
: func
= &ratiomidi_a
; break;
474 case opDbAmp
: func
= &dbamp_a
; break;
475 case opAmpDb
: func
= &db_a
; break;
476 case opOctCPS
: func
= &octcps_a
; break;
477 case opCPSOct
: func
= &cpsoct_a
; break;
478 case opLog
: func
= &log_a
; break;
479 case opLog2
: func
= &log2_a
; break;
480 case opLog10
: func
= &log10_a
; break;
481 case opSin
: func
= &sin_a
; break;
482 case opCos
: func
= &cos_a
; break;
483 case opTan
: func
= &tan_a
; break;
484 case opArcSin
: func
= &asin_a
; break;
485 case opArcCos
: func
= &acos_a
; break;
486 case opArcTan
: func
= &atan_a
; break;
487 case opSinH
: func
= &sinh_a
; break;
488 case opCosH
: func
= &cosh_a
; break;
489 case opTanH
: func
= &tanh_a
; break;
491 case opDistort
: func
= &distort_a
; break;
492 case opSoftClip
: func
= &softclip_a
; break;
494 case opRectWindow
: func
= &rectwindow_a
; break;
495 case opHanWindow
: func
= &hanwindow_a
; break;
496 case opWelchWindow
: func
= &welwindow_a
; break;
497 case opTriWindow
: func
= &triwindow_a
; break;
499 case opSCurve
: func
= &scurve_a
; break;
500 case opRamp
: func
= &ramp_a
; break;
502 default : func
= &thru_a
; break;
507 static UnaryOpFunc
ChooseOneFunc(UnaryOpUGen
*unit
)
509 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
511 switch (unit
->mSpecialIndex
) {
512 case opSilence
: func
= &zero_a
; break;
513 case opThru
: func
= &thru_a
; break;
514 case opNeg
: func
= &invert_1
; break;
515 case opNot
: func
= ¬_1
; break;
516 case opAbs
: func
= &abs_1
; break;
517 case opCeil
: func
= &ceil_1
; break;
518 case opFloor
: func
= &floor_1
; break;
519 case opFrac
: func
= &frac_1
; break;
520 case opSign
: func
= &sign_1
; break;
521 case opSquared
: func
= &squared_1
; break;
522 case opCubed
: func
= &cubed_1
; break;
523 case opSqrt
: func
= &sqrt_1
; break;
524 case opExp
: func
= &exp_1
; break;
525 case opRecip
: func
= &recip_1
; break;
526 case opMIDICPS
: func
= &midicps_1
; break;
527 case opCPSMIDI
: func
= &cpsmidi_1
; break;
529 case opMIDIRatio
: func
= &midiratio_1
; break;
530 case opRatioMIDI
: func
= &ratiomidi_1
; break;
531 case opDbAmp
: func
= &dbamp_1
; break;
532 case opAmpDb
: func
= &db_1
; break;
533 case opOctCPS
: func
= &octcps_1
; break;
534 case opCPSOct
: func
= &cpsoct_1
; break;
535 case opLog
: func
= &log_1
; break;
536 case opLog2
: func
= &log2_1
; break;
537 case opLog10
: func
= &log10_1
; break;
538 case opSin
: func
= &sin_1
; break;
539 case opCos
: func
= &cos_1
; break;
540 case opTan
: func
= &tan_1
; break;
541 case opArcSin
: func
= &asin_1
; break;
542 case opArcCos
: func
= &acos_1
; break;
543 case opArcTan
: func
= &atan_1
; break;
544 case opSinH
: func
= &sinh_1
; break;
545 case opCosH
: func
= &cosh_1
; break;
546 case opTanH
: func
= &tanh_1
; break;
548 case opDistort
: func
= &distort_1
; break;
549 case opSoftClip
: func
= &softclip_1
; break;
551 case opRectWindow
: func
= &rectwindow_1
; break;
552 case opHanWindow
: func
= &hanwindow_1
; break;
553 case opWelchWindow
: func
= &welwindow_1
; break;
554 case opTriWindow
: func
= &triwindow_1
; break;
556 case opSCurve
: func
= &scurve_1
; break;
557 case opRamp
: func
= &ramp_1
; break;
559 default : func
= &thru_a
; break;
565 static UnaryOpFunc
ChooseDemandFunc(UnaryOpUGen
*unit
)
567 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
569 switch (unit
->mSpecialIndex
) {
570 case opSilence
: func
= &zero_d
; break;
571 case opThru
: func
= &thru_d
; break;
572 case opNeg
: func
= &invert_d
; break;
573 case opNot
: func
= ¬_d
; break;
574 case opAbs
: func
= &abs_d
; break;
575 case opCeil
: func
= &ceil_d
; break;
576 case opFloor
: func
= &floor_d
; break;
577 case opFrac
: func
= &frac_d
; break;
578 case opSign
: func
= &sign_d
; break;
579 case opSquared
: func
= &squared_d
; break;
580 case opCubed
: func
= &cubed_d
; break;
581 case opSqrt
: func
= &sqrt_d
; break;
582 case opExp
: func
= &exp_d
; break;
583 case opRecip
: func
= &recip_d
; break;
584 case opMIDICPS
: func
= &midicps_d
; break;
585 case opCPSMIDI
: func
= &cpsmidi_d
; break;
587 case opMIDIRatio
: func
= &midiratio_d
; break;
588 case opRatioMIDI
: func
= &ratiomidi_d
; break;
589 case opDbAmp
: func
= &dbamp_d
; break;
590 case opAmpDb
: func
= &db_d
; break;
591 case opOctCPS
: func
= &octcps_d
; break;
592 case opCPSOct
: func
= &cpsoct_d
; break;
593 case opLog
: func
= &log_d
; break;
594 case opLog2
: func
= &log2_d
; break;
595 case opLog10
: func
= &log10_d
; break;
596 case opSin
: func
= &sin_d
; break;
597 case opCos
: func
= &cos_d
; break;
598 case opTan
: func
= &tan_d
; break;
599 case opArcSin
: func
= &asin_d
; break;
600 case opArcCos
: func
= &acos_d
; break;
601 case opArcTan
: func
= &atan_d
; break;
602 case opSinH
: func
= &sinh_d
; break;
603 case opCosH
: func
= &cosh_d
; break;
604 case opTanH
: func
= &tanh_d
; break;
606 case opDistort
: func
= &distort_d
; break;
607 case opSoftClip
: func
= &softclip_d
; break;
609 case opRectWindow
: func
= &rectwindow_d
; break;
610 case opHanWindow
: func
= &hanwindow_d
; break;
611 case opWelchWindow
: func
= &welwindow_d
; break;
612 case opTriWindow
: func
= &triwindow_d
; break;
614 case opSCurve
: func
= &scurve_d
; break;
615 case opRamp
: func
= &ramp_d
; break;
617 default : func
= &thru_d
; break;
624 static UnaryOpFunc
ChooseNovaSimdFunc(UnaryOpUGen
*unit
)
626 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
628 if (BUFLENGTH
== 64) {
629 switch (unit
->mSpecialIndex
) {
630 case opSilence
: return &zero_nova_64
;
631 case opThru
: func
= &thru_nova
; break;
632 case opNeg
: return &invert_nova_64
;
633 case opNot
: func
= ¬_a
; break;
634 case opAbs
: return &abs_nova_64
;
635 case opCeil
: func
= &ceil_nova_64
; break;
636 case opFloor
: func
= &floor_nova_64
; break;
637 case opFrac
: func
= &frac_nova_64
; break;
638 case opSign
: return &sign_nova_64
;
639 case opSquared
: return &squared_nova_64
;
640 case opCubed
: return &cubed_nova_64
;
641 case opSqrt
: func
= &sqrt_nova_64
; break;
642 case opExp
: func
= &exp_nova
; break;
643 case opRecip
: return &recip_nova_64
;
644 case opMIDICPS
: func
= &midicps_nova
; break;
645 case opCPSMIDI
: func
= &cpsmidi_nova
; break;
646 case opMIDIRatio
: func
= &midiratio_nova
; break;
647 case opRatioMIDI
: func
= &ratiomidi_nova
; break;
648 case opDbAmp
: func
= &dbamp_nova
; break;
649 case opAmpDb
: func
= &db_nova
; break;
650 case opOctCPS
: func
= &octcps_nova
; break;
651 case opCPSOct
: func
= &cpsoct_nova
; break;
652 case opLog
: func
= &log_nova
; break;
653 case opLog2
: func
= &log2_nova
; break;
654 case opLog10
: func
= &log10_nova
; break;
655 case opSin
: func
= &sin_nova
; break;
656 case opCos
: func
= &cos_nova
; break;
657 case opTan
: func
= &tan_nova
; break;
658 case opArcSin
: func
= &asin_nova
; break;
659 case opArcCos
: func
= &acos_nova
; break;
660 case opArcTan
: func
= &atan_nova
; break;
661 case opSinH
: func
= &sinh_a
; break;
662 case opCosH
: func
= &cosh_a
; break;
663 case opTanH
: func
= &tanh_nova
; break;
665 case opDistort
: func
= &distort_a_nova
; break;
666 case opSoftClip
: func
= &softclip_nova_64
; break;
668 case opRectWindow
: func
= &rectwindow_a
; break;
669 case opHanWindow
: func
= &hanwindow_a
; break;
670 case opWelchWindow
: func
= &welwindow_a
; break;
671 case opTriWindow
: func
= &triwindow_a
; break;
673 case opSCurve
: func
= &scurve_a
; break;
674 case opRamp
: return &ramp_nova_64
;
676 default : return &thru_nova_64
;
679 switch (unit
->mSpecialIndex
) {
680 case opSilence
: func
= &zero_nova
; break;
681 case opThru
: func
= &thru_nova
; break;
682 case opNeg
: func
= &invert_nova
; break;
683 case opNot
: func
= ¬_a
; break;
684 case opAbs
: func
= &abs_nova
; break;
685 case opCeil
: func
= &ceil_nova
; break;
686 case opFloor
: func
= &floor_nova
; break;
687 case opFrac
: func
= &frac_nova
; break;
688 case opSign
: func
= &sign_nova
; break;
689 case opSquared
: func
= &squared_nova
; break;
690 case opCubed
: func
= &cubed_nova
; break;
691 case opSqrt
: func
= &sqrt_nova
; break;
692 case opExp
: func
= &exp_nova
; break;
693 case opRecip
: func
= &recip_nova
; break;
694 case opMIDICPS
: func
= &midicps_nova
; break;
695 case opCPSMIDI
: func
= &cpsmidi_nova
; break;
696 case opMIDIRatio
: func
= &midiratio_nova
; break;
697 case opRatioMIDI
: func
= &ratiomidi_nova
; break;
698 case opDbAmp
: func
= &dbamp_nova
; break;
699 case opAmpDb
: func
= &db_nova
; break;
700 case opOctCPS
: func
= &octcps_nova
; break;
701 case opCPSOct
: func
= &cpsoct_nova
; break;
702 case opLog
: func
= &log_nova
; break;
703 case opLog2
: func
= &log2_nova
; break;
704 case opLog10
: func
= &log10_nova
; break;
705 case opSin
: func
= &sin_nova
; break;
706 case opCos
: func
= &cos_nova
; break;
707 case opTan
: func
= &tan_nova
; break;
708 case opArcSin
: func
= &asin_nova
; break;
709 case opArcCos
: func
= &acos_nova
; break;
710 case opArcTan
: func
= &atan_nova
; break;
711 case opSinH
: func
= &sinh_a
; break;
712 case opCosH
: func
= &cosh_a
; break;
713 case opTanH
: func
= &tanh_nova
; break;
715 case opDistort
: func
= &distort_a_nova
; break;
716 case opSoftClip
: func
= &softclip_nova
; break;
718 case opRectWindow
: func
= &rectwindow_a
; break;
719 case opHanWindow
: func
= &hanwindow_a
; break;
720 case opWelchWindow
: func
= &welwindow_a
; break;
721 case opTriWindow
: func
= &triwindow_a
; break;
723 case opSCurve
: func
= &scurve_a
; break;
724 case opRamp
: func
= &ramp_nova
; break;
726 default : func
= &thru_nova
; break;
732 bool ChooseOperatorFunc(UnaryOpUGen
*unit
)
734 //Print("->ChooseOperatorFunc %d\n", unit->mSpecialIndex);
737 if (unit
->mCalcRate
== calc_DemandRate
) {
738 func
= ChooseDemandFunc(unit
);
739 } else if (BUFLENGTH
== 1) {
740 func
= ChooseOneFunc(unit
);
741 #if defined(NOVA_SIMD)
742 } else if (!(BUFLENGTH
& 15)) {
743 /* select normal function for initialization */
744 func
= ChooseNormalFunc(unit
);
747 /* select simd function */
748 func
= ChooseNovaSimdFunc(unit
);
752 func
= ChooseNormalFunc(unit
);
754 unit
->mCalcFunc
= (UnitCalcFunc
)func
;
755 //Print("<-ChooseOperatorFunc %p\n", func);
756 //Print("calc %d\n", unit->mCalcRate);
761 ////////////////////////////////////////////////////////////////////////////////////////////////////////
767 DefineSimpleUnit(UnaryOpUGen
);