class library: SynthDef - replaceUGen fixes
[supercollider.git] / server / plugins / UnaryOpUGens.cpp
blob436e4e292ee0e2884b832000c8e380294b6a5d35
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 #if defined(__GNUC__) && !defined(__clang__)
34 #define inline_functions __attribute__ ((flatten))
35 #else
36 #define inline_functions
37 #endif
39 using nova::wrap_argument;
41 #define NOVA_WRAPPER(NAME, NOVANAME) \
42 inline_functions void NAME##_nova(UnaryOpUGen *unit, int inNumSamples) \
43 { \
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) \
49 { \
50 nova::NOVANAME##_vec_simd(OUT(0), IN(0), inNumSamples); \
51 } \
53 inline_functions void NAME##_nova_64(UnaryOpUGen *unit, int inNumSamples) \
54 { \
55 nova::NOVANAME##_vec_simd<64>(OUT(0), IN(0)); \
58 #endif
60 using namespace std; // for math functions
62 static InterfaceTable *ft;
64 //////////////////////////////////////////////////////////////////////////////////////////////////
67 /* special unary math operators */
68 enum {
69 opNeg,
70 opNot,
71 opIsNil,
72 opNotNil,
73 opBitNot,
74 opAbs,
75 opAsFloat,
76 opAsInt,
77 opCeil,
78 opFloor,
79 opFrac,
80 opSign,
81 opSquared,
82 opCubed,
83 opSqrt,
84 opExp,
85 opRecip,
86 opMIDICPS,
87 opCPSMIDI,
89 opMIDIRatio,
90 opRatioMIDI,
91 opDbAmp,
92 opAmpDb,
93 opOctCPS,
94 opCPSOct,
95 opLog,
96 opLog2,
97 opLog10,
98 opSin,
99 opCos,
100 opTan,
101 opArcSin,
102 opArcCos,
103 opArcTan,
104 opSinH,
105 opCosH,
106 opTanH,
107 opRand,
108 opRand2,
109 opLinRand,
110 opBiLinRand,
112 opSum3Rand,
114 opDistort,
115 opSoftClip,
116 opCoin,
118 opDigitValue,
119 opSilence,
120 opThru,
121 opRectWindow,
122 opHanWindow,
123 opWelchWindow,
124 opTriWindow,
126 opRamp,
127 opSCurve,
129 opNumUnarySelectors
133 struct UnaryOpUGen : public Unit
137 typedef void (*UnaryOpFunc)(UnaryOpUGen *unit, int inNumSamples);
139 extern "C"
142 void UnaryOpUGen_Ctor(UnaryOpUGen *unit);
145 bool ChooseOperatorFunc(UnaryOpUGen *unit);
147 void UnaryOpUGen_Ctor(UnaryOpUGen *unit)
149 bool initialized = ChooseOperatorFunc(unit);
150 if (!initialized)
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); \
160 float *a = ZIN(0); \
162 LOOP1(inNumSamples, \
163 ZXP(out) = function(ZXP(a)); \
164 ); \
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); \
177 } else { \
178 RESETINPUT(0); \
182 template <typename F>
183 inline F sc_invert(F x)
185 return -x;
188 DEFINE_UNARY_OP_FUNCS(invert, sc_invert)
190 #ifdef NOVA_SIMD
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));
201 #endif
204 template <typename F>
205 inline F sc_not(F x)
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);
222 float *a = ZIN(0);
224 ZCopy(inNumSamples, out, a);
227 DEFINE_UNARY_OP_FUNCS(abs, std::abs)
229 #ifdef NOVA_SIMD
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));
259 #endif
261 template <typename F>
262 inline F sc_recip(F x)
264 return (F)1. / x;
267 DEFINE_UNARY_OP_FUNCS(recip, sc_recip)
269 #ifdef NOVA_SIMD
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));
279 #endif
282 DEFINE_UNARY_OP_FUNCS(floor, floor)
283 DEFINE_UNARY_OP_FUNCS(ceil, ceil)
285 #ifdef NOVA_SIMD
286 NOVA_WRAPPER_CT_UNROLL(floor, floor)
287 NOVA_WRAPPER_CT_UNROLL(ceil, ceil)
288 #endif
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)
303 #ifdef NOVA_SIMD
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)
311 #endif
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)
319 #ifdef NOVA_SIMD
320 NOVA_WRAPPER(log, log)
321 NOVA_WRAPPER(log2, log2)
322 NOVA_WRAPPER(log10, log10)
323 NOVA_WRAPPER(exp, exp)
324 #endif
326 DEFINE_UNARY_OP_FUNCS(sqrt, sc_sqrt)
328 #ifdef NOVA_SIMD
329 NOVA_WRAPPER_CT_UNROLL(sqrt, signed_sqrt)
330 #endif
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)
341 #ifdef NOVA_SIMD
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)
350 #endif
353 DEFINE_UNARY_OP_FUNCS(frac, sc_frac)
354 #ifdef NOVA_SIMD
355 NOVA_WRAPPER_CT_UNROLL(frac, frac)
356 #endif
359 DEFINE_UNARY_OP_FUNCS(squared, sc_squared)
360 #ifdef NOVA_SIMD
361 NOVA_WRAPPER_CT_UNROLL(squared, square)
362 #endif
365 DEFINE_UNARY_OP_FUNCS(cubed, sc_cubed)
366 #ifdef NOVA_SIMD
367 NOVA_WRAPPER_CT_UNROLL(cubed, cube)
368 #endif
370 DEFINE_UNARY_OP_FUNCS(sign, sc_sign)
372 #ifdef NOVA_SIMD
373 NOVA_WRAPPER_CT_UNROLL(sign, sgn)
374 #endif
376 DEFINE_UNARY_OP_FUNCS(distort, sc_distort)
378 #ifdef NOVA_SIMD
379 void distort_a_nova(UnaryOpUGen *unit, int inNumSamples)
381 float *out = OUT(0);
382 float *a = IN(0);
383 using namespace nova;
385 int vs = vec<float>::size;
386 int len = inNumSamples / vs;
387 vec<float> one(1.f);
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);
393 out += vs; a += vs;
396 #endif
398 DEFINE_UNARY_OP_FUNCS(distortneg, sc_distortneg)
399 DEFINE_UNARY_OP_FUNCS(softclip, sc_softclip)
401 #ifdef NOVA_SIMD
402 NOVA_WRAPPER_CT_UNROLL(softclip, softclip)
403 #endif
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)
414 #ifdef NOVA_SIMD
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));
424 #endif
426 ////////////////////////////////////////////////////////////////////////////////////////////////////////
428 void zero_d(UnaryOpUGen *unit, int inNumSamples)
430 if (inNumSamples) {
431 float x = DEMANDINPUT_A(0, inNumSamples);
432 OUT0(0) = sc_isnan(x) ? NAN : 0.f;
433 } else {
434 RESETINPUT(0);
438 void thru_d(UnaryOpUGen *unit, int inNumSamples)
440 if (inNumSamples) {
441 float x = DEMANDINPUT_A(0, inNumSamples);
442 OUT0(0) = sc_isnan(x) ? NAN : (x);
443 } else {
444 RESETINPUT(0);
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 = &not_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 = &ampdb_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;
504 return func;
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 = &not_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 = &ampdb_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;
561 return func;
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 = &not_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 = &ampdb_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;
619 return func;
622 #ifdef NOVA_SIMD
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 = &not_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 = &ampdb_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 = &not_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 = &ampdb_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;
728 return func;
730 #endif
732 bool ChooseOperatorFunc(UnaryOpUGen *unit)
734 //Print("->ChooseOperatorFunc %d\n", unit->mSpecialIndex);
735 UnaryOpFunc func;
736 bool ret = false;
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);
745 func(unit, 1);
747 /* select simd function */
748 func = ChooseNovaSimdFunc(unit);
749 ret = true;
750 #endif
751 } else {
752 func = ChooseNormalFunc(unit);
754 unit->mCalcFunc = (UnitCalcFunc)func;
755 //Print("<-ChooseOperatorFunc %p\n", func);
756 //Print("calc %d\n", unit->mCalcRate);
757 return ret;
761 ////////////////////////////////////////////////////////////////////////////////////////////////////////
763 PluginLoad(UnaryOp)
765 ft = inTable;
767 DefineSimpleUnit(UnaryOpUGen);