Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / plugins / UnaryOpUGens.cpp
blob45d04a01f16c8988f781058e3e50af1faf4e73ad
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
22 #include "SC_PlugIn.h"
24 #ifdef NOVA_SIMD
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) \
39 { \
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) \
45 { \
46 nova::NOVANAME##_vec_simd(OUT(0), IN(0), inNumSamples); \
47 } \
49 FLATTEN void NAME##_nova_64(UnaryOpUGen *unit, int inNumSamples) \
50 { \
51 nova::NOVANAME##_vec_simd<64>(OUT(0), IN(0)); \
54 struct sc_distort_functor
56 template <typename FloatType>
57 inline FloatType operator()(FloatType arg) const
59 return sc_distort(arg);
62 template <typename FloatType>
63 inline nova::vec<FloatType> operator()(nova::vec<FloatType> arg) const
65 nova::vec<FloatType> one (1.f);
66 return arg * reciprocal(one + abs(arg));
70 namespace nova {
71 NOVA_SIMD_DEFINE_UNARY_WRAPPER (distort, sc_distort_functor)
73 #endif
75 using namespace std; // for math functions
77 static InterfaceTable *ft;
79 //////////////////////////////////////////////////////////////////////////////////////////////////
82 /* special unary math operators */
83 enum {
84 opNeg,
85 opNot,
86 opIsNil,
87 opNotNil,
88 opBitNot,
89 opAbs,
90 opAsFloat,
91 opAsInt,
92 opCeil,
93 opFloor,
94 opFrac,
95 opSign,
96 opSquared,
97 opCubed,
98 opSqrt,
99 opExp,
100 opRecip,
101 opMIDICPS,
102 opCPSMIDI,
104 opMIDIRatio,
105 opRatioMIDI,
106 opDbAmp,
107 opAmpDb,
108 opOctCPS,
109 opCPSOct,
110 opLog,
111 opLog2,
112 opLog10,
113 opSin,
114 opCos,
115 opTan,
116 opArcSin,
117 opArcCos,
118 opArcTan,
119 opSinH,
120 opCosH,
121 opTanH,
122 opRand,
123 opRand2,
124 opLinRand,
125 opBiLinRand,
127 opSum3Rand,
129 opDistort,
130 opSoftClip,
131 opCoin,
133 opDigitValue,
134 opSilence,
135 opThru,
136 opRectWindow,
137 opHanWindow,
138 opWelchWindow,
139 opTriWindow,
141 opRamp,
142 opSCurve,
144 opNumUnarySelectors
148 struct UnaryOpUGen : public Unit
152 typedef void (*UnaryOpFunc)(UnaryOpUGen *unit, int inNumSamples);
154 extern "C"
157 void UnaryOpUGen_Ctor(UnaryOpUGen *unit);
160 bool ChooseOperatorFunc(UnaryOpUGen *unit);
162 void UnaryOpUGen_Ctor(UnaryOpUGen *unit)
164 bool initialized = ChooseOperatorFunc(unit);
165 if (!initialized)
166 (unit->mCalcFunc)(unit, 1);
169 ////////////////////////////////////////////////////////////////////////////////////////////////////////
171 #define DEFINE_UNARY_OP_FUNCS(name, function) \
172 extern "C" void name##_a(UnaryOpUGen *unit, int inNumSamples) \
174 float *out = ZOUT(0); \
175 float *a = ZIN(0); \
177 LOOP1(inNumSamples, \
178 ZXP(out) = function(ZXP(a)); \
179 ); \
182 extern "C" void name##_1(UnaryOpUGen *unit, int inNumSamples) \
184 ZOUT0(0) = function(ZIN0(0)); \
187 extern "C" void name##_d(UnaryOpUGen *unit, int inNumSamples) \
189 if (inNumSamples) { \
190 float x = DEMANDINPUT_A(0, inNumSamples); \
191 OUT0(0) = sc_isnan(x) ? NAN : function(x); \
192 } else { \
193 RESETINPUT(0); \
197 template <typename F>
198 inline F sc_invert(F x)
200 return -x;
203 DEFINE_UNARY_OP_FUNCS(invert, sc_invert)
205 #ifdef NOVA_SIMD
206 FLATTEN void invert_nova(UnaryOpUGen *unit, int inNumSamples)
208 nova::minus_vec_simd(OUT(0), 0.f, IN(0), inNumSamples);
211 FLATTEN void invert_nova_64(UnaryOpUGen *unit, int inNumSamples)
213 nova::minus_vec_simd<64>(OUT(0), 0.f, IN(0));
216 #endif
219 template <typename F>
220 inline F sc_not(F x)
222 return x > 0.f ? 0.f : 1.f;
225 DEFINE_UNARY_OP_FUNCS(not, sc_not)
227 void zero_a(UnaryOpUGen *unit, int inNumSamples)
229 float *out = ZOUT(0);
231 ZClear(inNumSamples, out);
234 void thru_a(UnaryOpUGen *unit, int inNumSamples)
236 float *out = ZOUT(0);
237 float *a = ZIN(0);
239 ZCopy(inNumSamples, out, a);
242 DEFINE_UNARY_OP_FUNCS(abs, std::abs)
244 #ifdef NOVA_SIMD
245 FLATTEN void zero_nova(UnaryOpUGen *unit, int inNumSamples)
247 nova::zerovec_simd(OUT(0), inNumSamples);
250 FLATTEN void zero_nova_64(UnaryOpUGen *unit, int inNumSamples)
252 nova::zerovec_simd<64>(OUT(0));
255 FLATTEN void thru_nova(UnaryOpUGen *unit, int inNumSamples)
257 nova::copyvec_simd(OUT(0), IN(0), inNumSamples);
260 FLATTEN void thru_nova_64(UnaryOpUGen *unit, int inNumSamples)
262 nova::copyvec_simd<64>(OUT(0), IN(0));
265 FLATTEN void abs_nova(UnaryOpUGen *unit, int inNumSamples)
267 nova::abs_vec_simd(OUT(0), IN(0), inNumSamples);
270 FLATTEN void abs_nova_64(UnaryOpUGen *unit, int inNumSamples)
272 nova::abs_vec_simd<64>(OUT(0), IN(0));
274 #endif
276 DEFINE_UNARY_OP_FUNCS(recip, sc_reciprocal)
278 #ifdef NOVA_SIMD
279 FLATTEN void recip_nova(UnaryOpUGen *unit, int inNumSamples)
281 nova::reciprocal_vec_simd(OUT(0), IN(0), inNumSamples);
284 FLATTEN void recip_nova_64(UnaryOpUGen *unit, int inNumSamples)
286 nova::reciprocal_vec_simd<64>(OUT(0), IN(0));
288 #endif
291 DEFINE_UNARY_OP_FUNCS(floor, floor)
292 DEFINE_UNARY_OP_FUNCS(ceil, ceil)
294 #ifdef NOVA_SIMD
295 NOVA_WRAPPER_CT_UNROLL(floor, floor)
296 NOVA_WRAPPER_CT_UNROLL(ceil, ceil)
297 #endif
299 DEFINE_UNARY_OP_FUNCS(sin, sin)
300 DEFINE_UNARY_OP_FUNCS(cos, cos)
301 DEFINE_UNARY_OP_FUNCS(tan, tan)
303 DEFINE_UNARY_OP_FUNCS(asin, asin)
304 DEFINE_UNARY_OP_FUNCS(acos, acos)
305 DEFINE_UNARY_OP_FUNCS(atan, atan)
307 DEFINE_UNARY_OP_FUNCS(sinh, sinh)
308 DEFINE_UNARY_OP_FUNCS(cosh, cosh)
309 DEFINE_UNARY_OP_FUNCS(tanh, tanh)
312 #ifdef NOVA_SIMD
313 NOVA_WRAPPER(sin, sin)
314 NOVA_WRAPPER(cos, cos)
315 NOVA_WRAPPER(tan, tan)
316 NOVA_WRAPPER(asin, asin)
317 NOVA_WRAPPER(acos, acos)
318 NOVA_WRAPPER(atan, atan)
319 NOVA_WRAPPER(tanh, tanh)
320 #endif
323 DEFINE_UNARY_OP_FUNCS(log, std::log)
324 DEFINE_UNARY_OP_FUNCS(log2, sc_log2)
325 DEFINE_UNARY_OP_FUNCS(log10, sc_log10)
326 DEFINE_UNARY_OP_FUNCS(exp, exp)
328 #ifdef NOVA_SIMD
329 NOVA_WRAPPER(log, log)
330 NOVA_WRAPPER(log2, log2)
331 NOVA_WRAPPER(log10, log10)
332 NOVA_WRAPPER(exp, exp)
333 #endif
335 DEFINE_UNARY_OP_FUNCS(sqrt, sc_sqrt)
337 #ifdef NOVA_SIMD
338 NOVA_WRAPPER_CT_UNROLL(sqrt, signed_sqrt)
339 #endif
341 DEFINE_UNARY_OP_FUNCS(ampdb, sc_ampdb)
342 DEFINE_UNARY_OP_FUNCS(dbamp, sc_dbamp)
343 DEFINE_UNARY_OP_FUNCS(midicps, sc_midicps)
344 DEFINE_UNARY_OP_FUNCS(cpsmidi, sc_cpsmidi)
345 DEFINE_UNARY_OP_FUNCS(midiratio, sc_midiratio)
346 DEFINE_UNARY_OP_FUNCS(ratiomidi, sc_ratiomidi)
347 DEFINE_UNARY_OP_FUNCS(cpsoct, sc_cpsoct)
348 DEFINE_UNARY_OP_FUNCS(octcps, sc_octcps)
350 #ifdef NOVA_SIMD
351 NOVA_WRAPPER(ampdb, amp2db)
352 NOVA_WRAPPER(dbamp, db2amp)
353 NOVA_WRAPPER(midicps, midi2freq)
354 NOVA_WRAPPER(cpsmidi, freq2midi)
355 NOVA_WRAPPER(midiratio, midi2ratio)
356 NOVA_WRAPPER(ratiomidi, ratio2midi)
357 NOVA_WRAPPER(cpsoct, freq2oct)
358 NOVA_WRAPPER(octcps, oct2freq)
359 #endif
362 DEFINE_UNARY_OP_FUNCS(frac, sc_frac)
363 #ifdef NOVA_SIMD
364 NOVA_WRAPPER_CT_UNROLL(frac, frac)
365 #endif
368 DEFINE_UNARY_OP_FUNCS(squared, sc_squared)
369 #ifdef NOVA_SIMD
370 NOVA_WRAPPER_CT_UNROLL(squared, square)
371 #endif
374 DEFINE_UNARY_OP_FUNCS(cubed, sc_cubed)
375 #ifdef NOVA_SIMD
376 NOVA_WRAPPER_CT_UNROLL(cubed, cube)
377 #endif
379 DEFINE_UNARY_OP_FUNCS(sign, sc_sign)
381 #ifdef NOVA_SIMD
382 NOVA_WRAPPER_CT_UNROLL(sign, sgn)
383 #endif
385 DEFINE_UNARY_OP_FUNCS(distort, sc_distort)
387 #ifdef NOVA_SIMD
388 NOVA_WRAPPER_CT_UNROLL(distort, distort)
389 #endif
391 DEFINE_UNARY_OP_FUNCS(distortneg, sc_distortneg)
392 DEFINE_UNARY_OP_FUNCS(softclip, sc_softclip)
394 #ifdef NOVA_SIMD
395 NOVA_WRAPPER_CT_UNROLL(softclip, softclip)
396 #endif
398 DEFINE_UNARY_OP_FUNCS(rectwindow, sc_rectwindow)
399 DEFINE_UNARY_OP_FUNCS(hanwindow, sc_hanwindow)
400 DEFINE_UNARY_OP_FUNCS(welwindow, sc_welwindow)
401 DEFINE_UNARY_OP_FUNCS(triwindow, sc_triwindow)
403 DEFINE_UNARY_OP_FUNCS(scurve, sc_scurve)
404 DEFINE_UNARY_OP_FUNCS(ramp, sc_ramp)
407 #ifdef NOVA_SIMD
408 FLATTEN void ramp_nova(UnaryOpUGen *unit, int inNumSamples)
410 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(0.f), wrap_argument(1.f), inNumSamples);
413 FLATTEN void ramp_nova_64(UnaryOpUGen *unit, int inNumSamples)
415 nova::clip_vec_simd<64>(OUT(0), wrap_argument(IN(0)), wrap_argument(0.f), wrap_argument(1.f));
417 #endif
419 ////////////////////////////////////////////////////////////////////////////////////////////////////////
421 void zero_d(UnaryOpUGen *unit, int inNumSamples)
423 if (inNumSamples) {
424 float x = DEMANDINPUT_A(0, inNumSamples);
425 OUT0(0) = sc_isnan(x) ? NAN : 0.f;
426 } else {
427 RESETINPUT(0);
431 void thru_d(UnaryOpUGen *unit, int inNumSamples)
433 if (inNumSamples) {
434 float x = DEMANDINPUT_A(0, inNumSamples);
435 OUT0(0) = sc_isnan(x) ? NAN : (x);
436 } else {
437 RESETINPUT(0);
441 ////////////////////////////////////////////////////////////////////////////////////////////////////////
443 static UnaryOpFunc ChooseNormalFunc(UnaryOpUGen *unit)
445 void (*func)(UnaryOpUGen *unit, int inNumSamples);
447 switch (unit->mSpecialIndex) {
448 case opSilence : func = &zero_a; break;
449 case opThru : func = &thru_a; break;
450 case opNeg : func = &invert_a; break;
451 case opNot : func = &not_a; break;
452 case opAbs : func = &abs_a; break;
453 case opCeil : func = &ceil_a; break;
454 case opFloor : func = &floor_a; break;
455 case opFrac : func = &frac_a; break;
456 case opSign : func = &sign_a; break;
457 case opSquared : func = &squared_a; break;
458 case opCubed : func = &cubed_a; break;
459 case opSqrt : func = &sqrt_a; break;
460 case opExp : func = &exp_a; break;
461 case opRecip : func = &recip_a; break;
462 case opMIDICPS : func = &midicps_a; break;
463 case opCPSMIDI : func = &cpsmidi_a; break;
465 case opMIDIRatio : func = &midiratio_a; break;
466 case opRatioMIDI : func = &ratiomidi_a; break;
467 case opDbAmp : func = &dbamp_a; break;
468 case opAmpDb : func = &ampdb_a; break;
469 case opOctCPS : func = &octcps_a; break;
470 case opCPSOct : func = &cpsoct_a; break;
471 case opLog : func = &log_a; break;
472 case opLog2 : func = &log2_a; break;
473 case opLog10 : func = &log10_a; break;
474 case opSin : func = &sin_a; break;
475 case opCos : func = &cos_a; break;
476 case opTan : func = &tan_a; break;
477 case opArcSin : func = &asin_a; break;
478 case opArcCos : func = &acos_a; break;
479 case opArcTan : func = &atan_a; break;
480 case opSinH : func = &sinh_a; break;
481 case opCosH : func = &cosh_a; break;
482 case opTanH : func = &tanh_a; break;
484 case opDistort : func = &distort_a; break;
485 case opSoftClip : func = &softclip_a; break;
487 case opRectWindow : func = &rectwindow_a; break;
488 case opHanWindow : func = &hanwindow_a; break;
489 case opWelchWindow : func = &welwindow_a; break;
490 case opTriWindow : func = &triwindow_a; break;
492 case opSCurve : func = &scurve_a; break;
493 case opRamp : func = &ramp_a; break;
495 default : func = &thru_a; break;
497 return func;
500 static UnaryOpFunc ChooseOneFunc(UnaryOpUGen *unit)
502 void (*func)(UnaryOpUGen *unit, int inNumSamples);
504 switch (unit->mSpecialIndex) {
505 case opSilence : func = &zero_a; break;
506 case opThru : func = &thru_a; break;
507 case opNeg : func = &invert_1; break;
508 case opNot : func = &not_1; break;
509 case opAbs : func = &abs_1; break;
510 case opCeil : func = &ceil_1; break;
511 case opFloor : func = &floor_1; break;
512 case opFrac : func = &frac_1; break;
513 case opSign : func = &sign_1; break;
514 case opSquared : func = &squared_1; break;
515 case opCubed : func = &cubed_1; break;
516 case opSqrt : func = &sqrt_1; break;
517 case opExp : func = &exp_1; break;
518 case opRecip : func = &recip_1; break;
519 case opMIDICPS : func = &midicps_1; break;
520 case opCPSMIDI : func = &cpsmidi_1; break;
522 case opMIDIRatio : func = &midiratio_1; break;
523 case opRatioMIDI : func = &ratiomidi_1; break;
524 case opDbAmp : func = &dbamp_1; break;
525 case opAmpDb : func = &ampdb_1; break;
526 case opOctCPS : func = &octcps_1; break;
527 case opCPSOct : func = &cpsoct_1; break;
528 case opLog : func = &log_1; break;
529 case opLog2 : func = &log2_1; break;
530 case opLog10 : func = &log10_1; break;
531 case opSin : func = &sin_1; break;
532 case opCos : func = &cos_1; break;
533 case opTan : func = &tan_1; break;
534 case opArcSin : func = &asin_1; break;
535 case opArcCos : func = &acos_1; break;
536 case opArcTan : func = &atan_1; break;
537 case opSinH : func = &sinh_1; break;
538 case opCosH : func = &cosh_1; break;
539 case opTanH : func = &tanh_1; break;
541 case opDistort : func = &distort_1; break;
542 case opSoftClip : func = &softclip_1; break;
544 case opRectWindow : func = &rectwindow_1; break;
545 case opHanWindow : func = &hanwindow_1; break;
546 case opWelchWindow : func = &welwindow_1; break;
547 case opTriWindow : func = &triwindow_1; break;
549 case opSCurve : func = &scurve_1; break;
550 case opRamp : func = &ramp_1; break;
552 default : func = &thru_a; break;
554 return func;
558 static UnaryOpFunc ChooseDemandFunc(UnaryOpUGen *unit)
560 void (*func)(UnaryOpUGen *unit, int inNumSamples);
562 switch (unit->mSpecialIndex) {
563 case opSilence : func = &zero_d; break;
564 case opThru : func = &thru_d; break;
565 case opNeg : func = &invert_d; break;
566 case opNot : func = &not_d; break;
567 case opAbs : func = &abs_d; break;
568 case opCeil : func = &ceil_d; break;
569 case opFloor : func = &floor_d; break;
570 case opFrac : func = &frac_d; break;
571 case opSign : func = &sign_d; break;
572 case opSquared : func = &squared_d; break;
573 case opCubed : func = &cubed_d; break;
574 case opSqrt : func = &sqrt_d; break;
575 case opExp : func = &exp_d; break;
576 case opRecip : func = &recip_d; break;
577 case opMIDICPS : func = &midicps_d; break;
578 case opCPSMIDI : func = &cpsmidi_d; break;
580 case opMIDIRatio : func = &midiratio_d; break;
581 case opRatioMIDI : func = &ratiomidi_d; break;
582 case opDbAmp : func = &dbamp_d; break;
583 case opAmpDb : func = &ampdb_d; break;
584 case opOctCPS : func = &octcps_d; break;
585 case opCPSOct : func = &cpsoct_d; break;
586 case opLog : func = &log_d; break;
587 case opLog2 : func = &log2_d; break;
588 case opLog10 : func = &log10_d; break;
589 case opSin : func = &sin_d; break;
590 case opCos : func = &cos_d; break;
591 case opTan : func = &tan_d; break;
592 case opArcSin : func = &asin_d; break;
593 case opArcCos : func = &acos_d; break;
594 case opArcTan : func = &atan_d; break;
595 case opSinH : func = &sinh_d; break;
596 case opCosH : func = &cosh_d; break;
597 case opTanH : func = &tanh_d; break;
599 case opDistort : func = &distort_d; break;
600 case opSoftClip : func = &softclip_d; break;
602 case opRectWindow : func = &rectwindow_d; break;
603 case opHanWindow : func = &hanwindow_d; break;
604 case opWelchWindow : func = &welwindow_d; break;
605 case opTriWindow : func = &triwindow_d; break;
607 case opSCurve : func = &scurve_d; break;
608 case opRamp : func = &ramp_d; break;
610 default : func = &thru_d; break;
612 return func;
615 #ifdef NOVA_SIMD
617 static UnaryOpFunc ChooseNovaSimdFunc(UnaryOpUGen *unit)
619 void (*func)(UnaryOpUGen *unit, int inNumSamples);
621 if (BUFLENGTH == 64) {
622 switch (unit->mSpecialIndex) {
623 case opSilence : return &zero_nova_64;
624 case opThru : func = &thru_nova; break;
625 case opNeg : return &invert_nova_64;
626 case opNot : func = &not_a; break;
627 case opAbs : return &abs_nova_64;
628 case opCeil : func = &ceil_nova_64; break;
629 case opFloor : func = &floor_nova_64; break;
630 case opFrac : func = &frac_nova_64; break;
631 case opSign : return &sign_nova_64;
632 case opSquared : return &squared_nova_64;
633 case opCubed : return &cubed_nova_64;
634 case opSqrt : func = &sqrt_nova_64; break;
635 case opExp : func = &exp_nova; break;
636 case opRecip : return &recip_nova_64;
637 case opMIDICPS : func = &midicps_nova; break;
638 case opCPSMIDI : func = &cpsmidi_nova; break;
639 case opMIDIRatio : func = &midiratio_nova; break;
640 case opRatioMIDI : func = &ratiomidi_nova; break;
641 case opDbAmp : func = &dbamp_nova; break;
642 case opAmpDb : func = &ampdb_nova; break;
643 case opOctCPS : func = &octcps_nova; break;
644 case opCPSOct : func = &cpsoct_nova; break;
645 case opLog : func = &log_nova; break;
646 case opLog2 : func = &log2_nova; break;
647 case opLog10 : func = &log10_nova; break;
648 case opSin : func = &sin_nova; break;
649 case opCos : func = &cos_nova; break;
650 case opTan : func = &tan_nova; break;
651 case opArcSin : func = &asin_nova; break;
652 case opArcCos : func = &acos_nova; break;
653 case opArcTan : func = &atan_nova; break;
654 case opSinH : func = &sinh_a; break;
655 case opCosH : func = &cosh_a; break;
656 case opTanH : func = &tanh_nova; break;
658 case opDistort : func = &distort_nova_64; break;
659 case opSoftClip : func = &softclip_nova_64; break;
661 case opRectWindow : func = &rectwindow_a; break;
662 case opHanWindow : func = &hanwindow_a; break;
663 case opWelchWindow : func = &welwindow_a; break;
664 case opTriWindow : func = &triwindow_a; break;
666 case opSCurve : func = &scurve_a; break;
667 case opRamp : return &ramp_nova_64;
669 default : return &thru_nova_64;
672 switch (unit->mSpecialIndex) {
673 case opSilence : func = &zero_nova; break;
674 case opThru : func = &thru_nova; break;
675 case opNeg : func = &invert_nova; break;
676 case opNot : func = &not_a; break;
677 case opAbs : func = &abs_nova; break;
678 case opCeil : func = &ceil_nova; break;
679 case opFloor : func = &floor_nova; break;
680 case opFrac : func = &frac_nova; break;
681 case opSign : func = &sign_nova; break;
682 case opSquared : func = &squared_nova; break;
683 case opCubed : func = &cubed_nova; break;
684 case opSqrt : func = &sqrt_nova; break;
685 case opExp : func = &exp_nova; break;
686 case opRecip : func = &recip_nova; break;
687 case opMIDICPS : func = &midicps_nova; break;
688 case opCPSMIDI : func = &cpsmidi_nova; break;
689 case opMIDIRatio : func = &midiratio_nova; break;
690 case opRatioMIDI : func = &ratiomidi_nova; break;
691 case opDbAmp : func = &dbamp_nova; break;
692 case opAmpDb : func = &ampdb_nova; break;
693 case opOctCPS : func = &octcps_nova; break;
694 case opCPSOct : func = &cpsoct_nova; break;
695 case opLog : func = &log_nova; break;
696 case opLog2 : func = &log2_nova; break;
697 case opLog10 : func = &log10_nova; break;
698 case opSin : func = &sin_nova; break;
699 case opCos : func = &cos_nova; break;
700 case opTan : func = &tan_nova; break;
701 case opArcSin : func = &asin_nova; break;
702 case opArcCos : func = &acos_nova; break;
703 case opArcTan : func = &atan_nova; break;
704 case opSinH : func = &sinh_a; break;
705 case opCosH : func = &cosh_a; break;
706 case opTanH : func = &tanh_nova; break;
708 case opDistort : func = &distort_nova; break;
709 case opSoftClip : func = &softclip_nova; break;
711 case opRectWindow : func = &rectwindow_a; break;
712 case opHanWindow : func = &hanwindow_a; break;
713 case opWelchWindow : func = &welwindow_a; break;
714 case opTriWindow : func = &triwindow_a; break;
716 case opSCurve : func = &scurve_a; break;
717 case opRamp : func = &ramp_nova; break;
719 default : func = &thru_nova; break;
721 return func;
723 #endif
725 bool ChooseOperatorFunc(UnaryOpUGen *unit)
727 //Print("->ChooseOperatorFunc %d\n", unit->mSpecialIndex);
728 UnaryOpFunc func;
729 bool ret = false;
730 if (unit->mCalcRate == calc_DemandRate) {
731 func = ChooseDemandFunc(unit);
732 } else if (BUFLENGTH == 1) {
733 func = ChooseOneFunc(unit);
734 #if defined(NOVA_SIMD)
735 } else if (!(BUFLENGTH & 15)) {
736 /* select normal function for initialization */
737 func = ChooseNormalFunc(unit);
738 func(unit, 1);
740 /* select simd function */
741 func = ChooseNovaSimdFunc(unit);
742 ret = true;
743 #endif
744 } else {
745 func = ChooseNormalFunc(unit);
747 unit->mCalcFunc = (UnitCalcFunc)func;
748 //Print("<-ChooseOperatorFunc %p\n", func);
749 //Print("calc %d\n", unit->mCalcRate);
750 return ret;
754 ////////////////////////////////////////////////////////////////////////////////////////////////////////
756 PluginLoad(UnaryOp)
758 ft = inTable;
760 DefineSimpleUnit(UnaryOpUGen);