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 #include "function_attributes.h"
35 using nova::wrap_argument
;
37 #define NOVA_WRAPPER(NAME, NOVANAME) \
38 FLATTEN void NAME##_nova(UnaryOpUGen *unit, int inNumSamples) \
40 nova::NOVANAME##_vec_simd(OUT(0), IN(0), inNumSamples); \
43 #define NOVA_WRAPPER_CT_UNROLL(NAME, NOVANAME) \
44 FLATTEN void NAME##_nova(UnaryOpUGen *unit, int inNumSamples) \
46 nova::NOVANAME##_vec_simd(OUT(0), IN(0), inNumSamples); \
49 FLATTEN void NAME##_nova_64(UnaryOpUGen *unit, int inNumSamples) \
51 nova::NOVANAME##_vec_simd<64>(OUT(0), IN(0)); \
56 using namespace std
; // for math functions
58 static InterfaceTable
*ft
;
60 //////////////////////////////////////////////////////////////////////////////////////////////////
63 /* special unary math operators */
129 struct UnaryOpUGen
: public Unit
133 typedef void (*UnaryOpFunc
)(UnaryOpUGen
*unit
, int inNumSamples
);
138 void UnaryOpUGen_Ctor(UnaryOpUGen
*unit
);
141 bool ChooseOperatorFunc(UnaryOpUGen
*unit
);
143 void UnaryOpUGen_Ctor(UnaryOpUGen
*unit
)
145 bool initialized
= ChooseOperatorFunc(unit
);
147 (unit
->mCalcFunc
)(unit
, 1);
150 ////////////////////////////////////////////////////////////////////////////////////////////////////////
152 #define DEFINE_UNARY_OP_FUNCS(name, function) \
153 extern "C" void name##_a(UnaryOpUGen *unit, int inNumSamples) \
155 float *out = ZOUT(0); \
158 LOOP1(inNumSamples, \
159 ZXP(out) = function(ZXP(a)); \
163 extern "C" void name##_1(UnaryOpUGen *unit, int inNumSamples) \
165 ZOUT0(0) = function(ZIN0(0)); \
168 extern "C" void name##_d(UnaryOpUGen *unit, int inNumSamples) \
170 if (inNumSamples) { \
171 float x = DEMANDINPUT_A(0, inNumSamples); \
172 OUT0(0) = sc_isnan(x) ? NAN : function(x); \
178 template <typename F
>
179 inline F
sc_invert(F x
)
184 DEFINE_UNARY_OP_FUNCS(invert
, sc_invert
)
187 FLATTEN
void invert_nova(UnaryOpUGen
*unit
, int inNumSamples
)
189 nova::minus_vec_simd(OUT(0), 0.f
, IN(0), inNumSamples
);
192 FLATTEN
void invert_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
194 nova::minus_vec_simd
<64>(OUT(0), 0.f
, IN(0));
200 template <typename F
>
203 return x
> 0.f
? 0.f
: 1.f
;
206 DEFINE_UNARY_OP_FUNCS(not, sc_not
)
208 void zero_a(UnaryOpUGen
*unit
, int inNumSamples
)
210 float *out
= ZOUT(0);
212 ZClear(inNumSamples
, out
);
215 void thru_a(UnaryOpUGen
*unit
, int inNumSamples
)
217 float *out
= ZOUT(0);
220 ZCopy(inNumSamples
, out
, a
);
223 DEFINE_UNARY_OP_FUNCS(abs
, std::abs
)
226 FLATTEN
void zero_nova(UnaryOpUGen
*unit
, int inNumSamples
)
228 nova::zerovec_simd(OUT(0), inNumSamples
);
231 FLATTEN
void zero_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
233 nova::zerovec_simd
<64>(OUT(0));
236 FLATTEN
void thru_nova(UnaryOpUGen
*unit
, int inNumSamples
)
238 nova::copyvec_simd(OUT(0), IN(0), inNumSamples
);
241 FLATTEN
void thru_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
243 nova::copyvec_simd
<64>(OUT(0), IN(0));
246 FLATTEN
void abs_nova(UnaryOpUGen
*unit
, int inNumSamples
)
248 nova::abs_vec_simd(OUT(0), IN(0), inNumSamples
);
251 FLATTEN
void abs_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
253 nova::abs_vec_simd
<64>(OUT(0), IN(0));
257 template <typename F
>
258 inline F
sc_recip(F x
)
263 DEFINE_UNARY_OP_FUNCS(recip
, sc_recip
)
266 FLATTEN
void recip_nova(UnaryOpUGen
*unit
, int inNumSamples
)
268 nova::over_vec_simd(OUT(0), 1.f
, IN(0), inNumSamples
);
271 FLATTEN
void recip_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
273 nova::over_vec_simd
<64>(OUT(0), 1.f
, IN(0));
278 DEFINE_UNARY_OP_FUNCS(floor
, floor
)
279 DEFINE_UNARY_OP_FUNCS(ceil
, ceil
)
282 NOVA_WRAPPER_CT_UNROLL(floor
, floor
)
283 NOVA_WRAPPER_CT_UNROLL(ceil
, ceil
)
286 DEFINE_UNARY_OP_FUNCS(sin
, sin
)
287 DEFINE_UNARY_OP_FUNCS(cos
, cos
)
288 DEFINE_UNARY_OP_FUNCS(tan
, tan
)
290 DEFINE_UNARY_OP_FUNCS(asin
, asin
)
291 DEFINE_UNARY_OP_FUNCS(acos
, acos
)
292 DEFINE_UNARY_OP_FUNCS(atan
, atan
)
294 DEFINE_UNARY_OP_FUNCS(sinh
, sinh
)
295 DEFINE_UNARY_OP_FUNCS(cosh
, cosh
)
296 DEFINE_UNARY_OP_FUNCS(tanh
, tanh
)
300 NOVA_WRAPPER(sin
, sin
)
301 NOVA_WRAPPER(cos
, cos
)
302 NOVA_WRAPPER(tan
, tan
)
303 NOVA_WRAPPER(asin
, asin
)
304 NOVA_WRAPPER(acos
, acos
)
305 NOVA_WRAPPER(atan
, atan
)
306 NOVA_WRAPPER(tanh
, tanh
)
310 DEFINE_UNARY_OP_FUNCS(log
, std::log
)
311 DEFINE_UNARY_OP_FUNCS(log2
, sc_log2
)
312 DEFINE_UNARY_OP_FUNCS(log10
, sc_log10
)
313 DEFINE_UNARY_OP_FUNCS(exp
, exp
)
316 NOVA_WRAPPER(log
, log
)
317 NOVA_WRAPPER(log2
, log2
)
318 NOVA_WRAPPER(log10
, log10
)
319 NOVA_WRAPPER(exp
, exp
)
322 DEFINE_UNARY_OP_FUNCS(sqrt
, sc_sqrt
)
325 NOVA_WRAPPER_CT_UNROLL(sqrt
, signed_sqrt
)
328 DEFINE_UNARY_OP_FUNCS(ampdb
, sc_ampdb
)
329 DEFINE_UNARY_OP_FUNCS(dbamp
, sc_dbamp
)
330 DEFINE_UNARY_OP_FUNCS(midicps
, sc_midicps
)
331 DEFINE_UNARY_OP_FUNCS(cpsmidi
, sc_cpsmidi
)
332 DEFINE_UNARY_OP_FUNCS(midiratio
, sc_midiratio
)
333 DEFINE_UNARY_OP_FUNCS(ratiomidi
, sc_ratiomidi
)
334 DEFINE_UNARY_OP_FUNCS(cpsoct
, sc_cpsoct
)
335 DEFINE_UNARY_OP_FUNCS(octcps
, sc_octcps
)
338 NOVA_WRAPPER(ampdb
, amp2db
)
339 NOVA_WRAPPER(dbamp
, db2amp
)
340 NOVA_WRAPPER(midicps
, midi2freq
)
341 NOVA_WRAPPER(cpsmidi
, freq2midi
)
342 NOVA_WRAPPER(midiratio
, midi2ratio
)
343 NOVA_WRAPPER(ratiomidi
, ratio2midi
)
344 NOVA_WRAPPER(cpsoct
, freq2oct
)
345 NOVA_WRAPPER(octcps
, oct2freq
)
349 DEFINE_UNARY_OP_FUNCS(frac
, sc_frac
)
351 NOVA_WRAPPER_CT_UNROLL(frac
, frac
)
355 DEFINE_UNARY_OP_FUNCS(squared
, sc_squared
)
357 NOVA_WRAPPER_CT_UNROLL(squared
, square
)
361 DEFINE_UNARY_OP_FUNCS(cubed
, sc_cubed
)
363 NOVA_WRAPPER_CT_UNROLL(cubed
, cube
)
366 DEFINE_UNARY_OP_FUNCS(sign
, sc_sign
)
369 NOVA_WRAPPER_CT_UNROLL(sign
, sgn
)
372 DEFINE_UNARY_OP_FUNCS(distort
, sc_distort
)
375 void distort_a_nova(UnaryOpUGen
*unit
, int inNumSamples
)
379 using namespace nova
;
381 int vs
= vec
<float>::size
;
382 int len
= inNumSamples
/ vs
;
385 for (int i
=0; i
<len
; ++i
) {
386 vec
<float> arg
; arg
.load_aligned(a
);
387 vec
<float> result
= arg
/ (one
+ abs(arg
));
388 result
.store_aligned(out
);
394 DEFINE_UNARY_OP_FUNCS(distortneg
, sc_distortneg
)
395 DEFINE_UNARY_OP_FUNCS(softclip
, sc_softclip
)
398 NOVA_WRAPPER_CT_UNROLL(softclip
, softclip
)
401 DEFINE_UNARY_OP_FUNCS(rectwindow
, sc_rectwindow
)
402 DEFINE_UNARY_OP_FUNCS(hanwindow
, sc_hanwindow
)
403 DEFINE_UNARY_OP_FUNCS(welwindow
, sc_welwindow
)
404 DEFINE_UNARY_OP_FUNCS(triwindow
, sc_triwindow
)
406 DEFINE_UNARY_OP_FUNCS(scurve
, sc_scurve
)
407 DEFINE_UNARY_OP_FUNCS(ramp
, sc_ramp
)
411 FLATTEN
void ramp_nova(UnaryOpUGen
*unit
, int inNumSamples
)
413 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(0.f
), wrap_argument(1.f
), inNumSamples
);
416 FLATTEN
void ramp_nova_64(UnaryOpUGen
*unit
, int inNumSamples
)
418 nova::clip_vec_simd
<64>(OUT(0), wrap_argument(IN(0)), wrap_argument(0.f
), wrap_argument(1.f
));
422 ////////////////////////////////////////////////////////////////////////////////////////////////////////
424 void zero_d(UnaryOpUGen
*unit
, int inNumSamples
)
427 float x
= DEMANDINPUT_A(0, inNumSamples
);
428 OUT0(0) = sc_isnan(x
) ? NAN
: 0.f
;
434 void thru_d(UnaryOpUGen
*unit
, int inNumSamples
)
437 float x
= DEMANDINPUT_A(0, inNumSamples
);
438 OUT0(0) = sc_isnan(x
) ? NAN
: (x
);
444 ////////////////////////////////////////////////////////////////////////////////////////////////////////
446 static UnaryOpFunc
ChooseNormalFunc(UnaryOpUGen
*unit
)
448 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
450 switch (unit
->mSpecialIndex
) {
451 case opSilence
: func
= &zero_a
; break;
452 case opThru
: func
= &thru_a
; break;
453 case opNeg
: func
= &invert_a
; break;
454 case opNot
: func
= ¬_a
; break;
455 case opAbs
: func
= &abs_a
; break;
456 case opCeil
: func
= &ceil_a
; break;
457 case opFloor
: func
= &floor_a
; break;
458 case opFrac
: func
= &frac_a
; break;
459 case opSign
: func
= &sign_a
; break;
460 case opSquared
: func
= &squared_a
; break;
461 case opCubed
: func
= &cubed_a
; break;
462 case opSqrt
: func
= &sqrt_a
; break;
463 case opExp
: func
= &exp_a
; break;
464 case opRecip
: func
= &recip_a
; break;
465 case opMIDICPS
: func
= &midicps_a
; break;
466 case opCPSMIDI
: func
= &cpsmidi_a
; break;
468 case opMIDIRatio
: func
= &midiratio_a
; break;
469 case opRatioMIDI
: func
= &ratiomidi_a
; break;
470 case opDbAmp
: func
= &dbamp_a
; break;
471 case opAmpDb
: func
= &db_a
; break;
472 case opOctCPS
: func
= &octcps_a
; break;
473 case opCPSOct
: func
= &cpsoct_a
; break;
474 case opLog
: func
= &log_a
; break;
475 case opLog2
: func
= &log2_a
; break;
476 case opLog10
: func
= &log10_a
; break;
477 case opSin
: func
= &sin_a
; break;
478 case opCos
: func
= &cos_a
; break;
479 case opTan
: func
= &tan_a
; break;
480 case opArcSin
: func
= &asin_a
; break;
481 case opArcCos
: func
= &acos_a
; break;
482 case opArcTan
: func
= &atan_a
; break;
483 case opSinH
: func
= &sinh_a
; break;
484 case opCosH
: func
= &cosh_a
; break;
485 case opTanH
: func
= &tanh_a
; break;
487 case opDistort
: func
= &distort_a
; break;
488 case opSoftClip
: func
= &softclip_a
; break;
490 case opRectWindow
: func
= &rectwindow_a
; break;
491 case opHanWindow
: func
= &hanwindow_a
; break;
492 case opWelchWindow
: func
= &welwindow_a
; break;
493 case opTriWindow
: func
= &triwindow_a
; break;
495 case opSCurve
: func
= &scurve_a
; break;
496 case opRamp
: func
= &ramp_a
; break;
498 default : func
= &thru_a
; break;
503 static UnaryOpFunc
ChooseOneFunc(UnaryOpUGen
*unit
)
505 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
507 switch (unit
->mSpecialIndex
) {
508 case opSilence
: func
= &zero_a
; break;
509 case opThru
: func
= &thru_a
; break;
510 case opNeg
: func
= &invert_1
; break;
511 case opNot
: func
= ¬_1
; break;
512 case opAbs
: func
= &abs_1
; break;
513 case opCeil
: func
= &ceil_1
; break;
514 case opFloor
: func
= &floor_1
; break;
515 case opFrac
: func
= &frac_1
; break;
516 case opSign
: func
= &sign_1
; break;
517 case opSquared
: func
= &squared_1
; break;
518 case opCubed
: func
= &cubed_1
; break;
519 case opSqrt
: func
= &sqrt_1
; break;
520 case opExp
: func
= &exp_1
; break;
521 case opRecip
: func
= &recip_1
; break;
522 case opMIDICPS
: func
= &midicps_1
; break;
523 case opCPSMIDI
: func
= &cpsmidi_1
; break;
525 case opMIDIRatio
: func
= &midiratio_1
; break;
526 case opRatioMIDI
: func
= &ratiomidi_1
; break;
527 case opDbAmp
: func
= &dbamp_1
; break;
528 case opAmpDb
: func
= &db_1
; break;
529 case opOctCPS
: func
= &octcps_1
; break;
530 case opCPSOct
: func
= &cpsoct_1
; break;
531 case opLog
: func
= &log_1
; break;
532 case opLog2
: func
= &log2_1
; break;
533 case opLog10
: func
= &log10_1
; break;
534 case opSin
: func
= &sin_1
; break;
535 case opCos
: func
= &cos_1
; break;
536 case opTan
: func
= &tan_1
; break;
537 case opArcSin
: func
= &asin_1
; break;
538 case opArcCos
: func
= &acos_1
; break;
539 case opArcTan
: func
= &atan_1
; break;
540 case opSinH
: func
= &sinh_1
; break;
541 case opCosH
: func
= &cosh_1
; break;
542 case opTanH
: func
= &tanh_1
; break;
544 case opDistort
: func
= &distort_1
; break;
545 case opSoftClip
: func
= &softclip_1
; break;
547 case opRectWindow
: func
= &rectwindow_1
; break;
548 case opHanWindow
: func
= &hanwindow_1
; break;
549 case opWelchWindow
: func
= &welwindow_1
; break;
550 case opTriWindow
: func
= &triwindow_1
; break;
552 case opSCurve
: func
= &scurve_1
; break;
553 case opRamp
: func
= &ramp_1
; break;
555 default : func
= &thru_a
; break;
561 static UnaryOpFunc
ChooseDemandFunc(UnaryOpUGen
*unit
)
563 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
565 switch (unit
->mSpecialIndex
) {
566 case opSilence
: func
= &zero_d
; break;
567 case opThru
: func
= &thru_d
; break;
568 case opNeg
: func
= &invert_d
; break;
569 case opNot
: func
= ¬_d
; break;
570 case opAbs
: func
= &abs_d
; break;
571 case opCeil
: func
= &ceil_d
; break;
572 case opFloor
: func
= &floor_d
; break;
573 case opFrac
: func
= &frac_d
; break;
574 case opSign
: func
= &sign_d
; break;
575 case opSquared
: func
= &squared_d
; break;
576 case opCubed
: func
= &cubed_d
; break;
577 case opSqrt
: func
= &sqrt_d
; break;
578 case opExp
: func
= &exp_d
; break;
579 case opRecip
: func
= &recip_d
; break;
580 case opMIDICPS
: func
= &midicps_d
; break;
581 case opCPSMIDI
: func
= &cpsmidi_d
; break;
583 case opMIDIRatio
: func
= &midiratio_d
; break;
584 case opRatioMIDI
: func
= &ratiomidi_d
; break;
585 case opDbAmp
: func
= &dbamp_d
; break;
586 case opAmpDb
: func
= &db_d
; break;
587 case opOctCPS
: func
= &octcps_d
; break;
588 case opCPSOct
: func
= &cpsoct_d
; break;
589 case opLog
: func
= &log_d
; break;
590 case opLog2
: func
= &log2_d
; break;
591 case opLog10
: func
= &log10_d
; break;
592 case opSin
: func
= &sin_d
; break;
593 case opCos
: func
= &cos_d
; break;
594 case opTan
: func
= &tan_d
; break;
595 case opArcSin
: func
= &asin_d
; break;
596 case opArcCos
: func
= &acos_d
; break;
597 case opArcTan
: func
= &atan_d
; break;
598 case opSinH
: func
= &sinh_d
; break;
599 case opCosH
: func
= &cosh_d
; break;
600 case opTanH
: func
= &tanh_d
; break;
602 case opDistort
: func
= &distort_d
; break;
603 case opSoftClip
: func
= &softclip_d
; break;
605 case opRectWindow
: func
= &rectwindow_d
; break;
606 case opHanWindow
: func
= &hanwindow_d
; break;
607 case opWelchWindow
: func
= &welwindow_d
; break;
608 case opTriWindow
: func
= &triwindow_d
; break;
610 case opSCurve
: func
= &scurve_d
; break;
611 case opRamp
: func
= &ramp_d
; break;
613 default : func
= &thru_d
; break;
620 static UnaryOpFunc
ChooseNovaSimdFunc(UnaryOpUGen
*unit
)
622 void (*func
)(UnaryOpUGen
*unit
, int inNumSamples
);
624 if (BUFLENGTH
== 64) {
625 switch (unit
->mSpecialIndex
) {
626 case opSilence
: return &zero_nova_64
;
627 case opThru
: func
= &thru_nova
; break;
628 case opNeg
: return &invert_nova_64
;
629 case opNot
: func
= ¬_a
; break;
630 case opAbs
: return &abs_nova_64
;
631 case opCeil
: func
= &ceil_nova_64
; break;
632 case opFloor
: func
= &floor_nova_64
; break;
633 case opFrac
: func
= &frac_nova_64
; break;
634 case opSign
: return &sign_nova_64
;
635 case opSquared
: return &squared_nova_64
;
636 case opCubed
: return &cubed_nova_64
;
637 case opSqrt
: func
= &sqrt_nova_64
; break;
638 case opExp
: func
= &exp_nova
; break;
639 case opRecip
: return &recip_nova_64
;
640 case opMIDICPS
: func
= &midicps_nova
; break;
641 case opCPSMIDI
: func
= &cpsmidi_nova
; break;
642 case opMIDIRatio
: func
= &midiratio_nova
; break;
643 case opRatioMIDI
: func
= &ratiomidi_nova
; break;
644 case opDbAmp
: func
= &dbamp_nova
; break;
645 case opAmpDb
: func
= &db_nova
; break;
646 case opOctCPS
: func
= &octcps_nova
; break;
647 case opCPSOct
: func
= &cpsoct_nova
; break;
648 case opLog
: func
= &log_nova
; break;
649 case opLog2
: func
= &log2_nova
; break;
650 case opLog10
: func
= &log10_nova
; break;
651 case opSin
: func
= &sin_nova
; break;
652 case opCos
: func
= &cos_nova
; break;
653 case opTan
: func
= &tan_nova
; break;
654 case opArcSin
: func
= &asin_nova
; break;
655 case opArcCos
: func
= &acos_nova
; break;
656 case opArcTan
: func
= &atan_nova
; break;
657 case opSinH
: func
= &sinh_a
; break;
658 case opCosH
: func
= &cosh_a
; break;
659 case opTanH
: func
= &tanh_nova
; break;
661 case opDistort
: func
= &distort_a_nova
; break;
662 case opSoftClip
: func
= &softclip_nova_64
; break;
664 case opRectWindow
: func
= &rectwindow_a
; break;
665 case opHanWindow
: func
= &hanwindow_a
; break;
666 case opWelchWindow
: func
= &welwindow_a
; break;
667 case opTriWindow
: func
= &triwindow_a
; break;
669 case opSCurve
: func
= &scurve_a
; break;
670 case opRamp
: return &ramp_nova_64
;
672 default : return &thru_nova_64
;
675 switch (unit
->mSpecialIndex
) {
676 case opSilence
: func
= &zero_nova
; break;
677 case opThru
: func
= &thru_nova
; break;
678 case opNeg
: func
= &invert_nova
; break;
679 case opNot
: func
= ¬_a
; break;
680 case opAbs
: func
= &abs_nova
; break;
681 case opCeil
: func
= &ceil_nova
; break;
682 case opFloor
: func
= &floor_nova
; break;
683 case opFrac
: func
= &frac_nova
; break;
684 case opSign
: func
= &sign_nova
; break;
685 case opSquared
: func
= &squared_nova
; break;
686 case opCubed
: func
= &cubed_nova
; break;
687 case opSqrt
: func
= &sqrt_nova
; break;
688 case opExp
: func
= &exp_nova
; break;
689 case opRecip
: func
= &recip_nova
; break;
690 case opMIDICPS
: func
= &midicps_nova
; break;
691 case opCPSMIDI
: func
= &cpsmidi_nova
; break;
692 case opMIDIRatio
: func
= &midiratio_nova
; break;
693 case opRatioMIDI
: func
= &ratiomidi_nova
; break;
694 case opDbAmp
: func
= &dbamp_nova
; break;
695 case opAmpDb
: func
= &db_nova
; break;
696 case opOctCPS
: func
= &octcps_nova
; break;
697 case opCPSOct
: func
= &cpsoct_nova
; break;
698 case opLog
: func
= &log_nova
; break;
699 case opLog2
: func
= &log2_nova
; break;
700 case opLog10
: func
= &log10_nova
; break;
701 case opSin
: func
= &sin_nova
; break;
702 case opCos
: func
= &cos_nova
; break;
703 case opTan
: func
= &tan_nova
; break;
704 case opArcSin
: func
= &asin_nova
; break;
705 case opArcCos
: func
= &acos_nova
; break;
706 case opArcTan
: func
= &atan_nova
; break;
707 case opSinH
: func
= &sinh_a
; break;
708 case opCosH
: func
= &cosh_a
; break;
709 case opTanH
: func
= &tanh_nova
; break;
711 case opDistort
: func
= &distort_a_nova
; break;
712 case opSoftClip
: func
= &softclip_nova
; break;
714 case opRectWindow
: func
= &rectwindow_a
; break;
715 case opHanWindow
: func
= &hanwindow_a
; break;
716 case opWelchWindow
: func
= &welwindow_a
; break;
717 case opTriWindow
: func
= &triwindow_a
; break;
719 case opSCurve
: func
= &scurve_a
; break;
720 case opRamp
: func
= &ramp_nova
; break;
722 default : func
= &thru_nova
; break;
728 bool ChooseOperatorFunc(UnaryOpUGen
*unit
)
730 //Print("->ChooseOperatorFunc %d\n", unit->mSpecialIndex);
733 if (unit
->mCalcRate
== calc_DemandRate
) {
734 func
= ChooseDemandFunc(unit
);
735 } else if (BUFLENGTH
== 1) {
736 func
= ChooseOneFunc(unit
);
737 #if defined(NOVA_SIMD)
738 } else if (!(BUFLENGTH
& 15)) {
739 /* select normal function for initialization */
740 func
= ChooseNormalFunc(unit
);
743 /* select simd function */
744 func
= ChooseNovaSimdFunc(unit
);
748 func
= ChooseNormalFunc(unit
);
750 unit
->mCalcFunc
= (UnitCalcFunc
)func
;
751 //Print("<-ChooseOperatorFunc %p\n", func);
752 //Print("calc %d\n", unit->mCalcRate);
757 ////////////////////////////////////////////////////////////////////////////////////////////////////////
763 DefineSimpleUnit(UnaryOpUGen
);