class library: SynthDef - replaceUGen fixes
[supercollider.git] / server / plugins / LFUGens.cpp
blob9534e6edb5e89990608ef829fc2fa714096b80e8
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"
23 #include <limits.h>
24 #include <cstdio>
26 #ifdef NOVA_SIMD
27 #include "simd_memory.hpp"
28 #include "simd_ternary_arithmetic.hpp"
30 using nova::wrap_argument;
32 #if defined (__GNUC__) && !(defined(__clang__))
33 #define inline_functions __attribute__ ((flatten))
34 #else
35 #define inline_functions
36 #endif
38 #endif
40 static InterfaceTable *ft;
42 struct Vibrato : public Unit
44 double mPhase, m_attackSlope, m_attackLevel;
45 float mFreqMul, m_scaleA, m_scaleB, mFreq;
46 int m_delay, m_attack;
49 struct LFPulse : public Unit
51 double mPhase;
52 float mFreqMul, mDuty;
55 struct LFSaw : public Unit
57 double mPhase;
58 float mFreqMul;
61 struct LFPar : public Unit
63 double mPhase;
64 float mFreqMul;
67 struct LFCub : public Unit
69 double mPhase;
70 float mFreqMul;
73 struct LFTri : public Unit
75 double mPhase;
76 float mFreqMul;
79 struct LFGauss : public Unit
81 double mPhase;
82 float mDurMul;
85 struct Impulse : public Unit
87 double mPhase, mPhaseOffset;
88 float mFreqMul;
91 struct VarSaw : public Unit
93 double mPhase;
94 float mFreqMul, mDuty, mInvDuty, mInv1Duty;
97 struct SyncSaw : public Unit
99 double mPhase1, mPhase2;
100 float mFreqMul;
103 struct Line : public Unit
105 double mLevel, mSlope;
106 float mEndLevel;
107 int mCounter;
110 struct XLine : public Unit
112 double mLevel, mGrowth;
113 float mEndLevel;
114 int mCounter;
117 struct Cutoff : public Unit
119 double mLevel, mSlope;
120 int mWaitCounter;
123 struct LinExp : public Unit
125 float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo;
128 struct Clip : public Unit
130 float m_lo, m_hi;
133 struct Wrap : public Unit
135 float m_lo, m_hi;
138 struct Fold : public Unit
140 float m_lo, m_hi, m_range;
143 struct Unwrap : public Unit
145 float m_range, m_half, m_offset, m_prev;
148 struct AmpComp : public Unit
150 float m_rootmul, m_exponent;
153 struct AmpCompA : public Unit
155 double m_scale, m_offset;
158 struct InRange : public Unit
160 // nothing
163 struct InRect : public Unit
165 // nothing
168 //struct Trapezoid : public Unit
170 // float m_leftScale, m_rightScale, m_a, m_b, m_c, m_d;
171 //};
173 struct K2A : public Unit
175 float mLevel;
178 struct A2K : public Unit
183 struct T2K : public Unit
188 struct T2A : public Unit
190 float mLevel;
193 struct DC : public Unit
195 float m_val;
198 struct Silent : public Unit
202 struct EnvGen : public Unit
204 double m_a1, m_a2, m_b1, m_y1, m_y2, m_grow, m_level, m_endLevel;
205 int m_counter, m_stage, m_shape, m_releaseNode;
206 float m_prevGate;
207 bool m_released;
210 struct Linen : public Unit
212 float m_endLevel;
213 double m_slope, m_level;
214 int m_counter, m_stage;
215 float m_prevGate;
219 //////////////////////////////////////////////////////////////////////////////////////////////////
222 extern "C"
224 void Vibrato_next(Vibrato *unit, int inNumSamples);
225 void Vibrato_Ctor(Vibrato* unit);
227 void LFPulse_next_a(LFPulse *unit, int inNumSamples);
228 void LFPulse_next_k(LFPulse *unit, int inNumSamples);
229 void LFPulse_Ctor(LFPulse* unit);
231 void LFSaw_next_a(LFSaw *unit, int inNumSamples);
232 void LFSaw_next_k(LFSaw *unit, int inNumSamples);
233 void LFSaw_Ctor(LFSaw* unit);
235 void LFTri_next_a(LFTri *unit, int inNumSamples);
236 void LFTri_next_k(LFTri *unit, int inNumSamples);
237 void LFTri_Ctor(LFTri* unit);
239 void LFPar_next_a(LFPar *unit, int inNumSamples);
240 void LFPar_next_k(LFPar *unit, int inNumSamples);
241 void LFPar_Ctor(LFPar* unit);
243 void LFCub_next_a(LFCub *unit, int inNumSamples);
244 void LFCub_next_k(LFCub *unit, int inNumSamples);
245 void LFCub_Ctor(LFCub* unit);
247 void LFGauss_next_a(LFGauss *unit, int inNumSamples);
248 void LFGauss_next_k(LFGauss *unit, int inNumSamples);
249 void LFGauss_next_aa(LFGauss *unit, int inNumSamples);
250 void LFGauss_Ctor(LFGauss* unit);
252 void VarSaw_next_a(VarSaw *unit, int inNumSamples);
253 void VarSaw_next_k(VarSaw *unit, int inNumSamples);
254 void VarSaw_Ctor(VarSaw* unit);
256 void Impulse_next_a(Impulse *unit, int inNumSamples);
257 void Impulse_next_kk(Impulse *unit, int inNumSamples);
258 void Impulse_next_k(Impulse *unit, int inNumSamples);
259 void Impulse_Ctor(Impulse* unit);
261 void SyncSaw_next_aa(SyncSaw *unit, int inNumSamples);
262 void SyncSaw_next_ak(SyncSaw *unit, int inNumSamples);
263 void SyncSaw_next_ka(SyncSaw *unit, int inNumSamples);
264 void SyncSaw_next_kk(SyncSaw *unit, int inNumSamples);
265 void SyncSaw_Ctor(SyncSaw* unit);
267 void K2A_next(K2A *unit, int inNumSamples);
268 void K2A_Ctor(K2A* unit);
270 void A2K_next(A2K *unit, int inNumSamples);
271 void A2K_Ctor(A2K* unit);
273 void T2K_next(T2K *unit, int inNumSamples);
274 void T2K_Ctor(T2K* unit);
276 void T2A_next(T2A *unit, int inNumSamples);
277 void T2A_Ctor(T2A* unit);
279 void Silent_next(Silent *unit, int inNumSamples);
280 void Silent_Ctor(Silent* unit);
282 void Line_next(Line *unit, int inNumSamples);
283 void Line_Ctor(Line* unit);
285 void XLine_next(XLine *unit, int inNumSamples);
286 void XLine_Ctor(XLine* unit);
288 void Wrap_next_kk(Wrap *unit, int inNumSamples);
289 void Wrap_next_ak(Wrap *unit, int inNumSamples);
290 void Wrap_next_ka(Wrap *unit, int inNumSamples);
291 void Wrap_next_aa(Wrap *unit, int inNumSamples);
292 void Wrap_Ctor(Wrap* unit);
294 void Fold_next_kk(Fold *unit, int inNumSamples);
295 void Fold_next_ak(Fold *unit, int inNumSamples);
296 void Fold_next_ka(Fold *unit, int inNumSamples);
297 void Fold_next_aa(Fold *unit, int inNumSamples);
298 void Fold_Ctor(Fold* unit);
300 void Clip_next_kk(Clip *unit, int inNumSamples);
301 void Clip_next_ka(Clip *unit, int inNumSamples);
302 void Clip_next_ak(Clip *unit, int inNumSamples);
303 void Clip_next_aa(Clip *unit, int inNumSamples);
304 void Clip_Ctor(Clip* unit);
306 void Unwrap_next(Unwrap* unit, int inNumSamples);
307 void Unwrap_Ctor(Unwrap* unit);
309 void AmpComp_next(AmpComp *unit, int inNumSamples);
310 void AmpComp_Ctor(AmpComp* unit);
312 void AmpCompA_next(AmpCompA *unit, int inNumSamples);
313 void AmpCompA_Ctor(AmpCompA* unit);
315 void InRange_next(InRange *unit, int inNumSamples);
316 void InRange_Ctor(InRange* unit);
318 void InRect_next(InRect *unit, int inNumSamples);
319 void InRect_Ctor(InRect* unit);
321 void LinExp_next(LinExp *unit, int inNumSamples);
322 void LinExp_next_kk(LinExp *unit, int inNumSamples);
323 void LinExp_next_ak(LinExp *unit, int inNumSamples);
324 void LinExp_next_ka(LinExp *unit, int inNumSamples);
325 void LinExp_Ctor(LinExp* unit);
327 void EnvGen_next_k(EnvGen *unit, int inNumSamples);
328 void EnvGen_next_aa(EnvGen *unit, int inNumSamples);
329 void EnvGen_next_ak(EnvGen *unit, int inNumSamples);
330 void EnvGen_Ctor(EnvGen *unit);
332 void Linen_next_k(Linen *unit, int inNumSamples);
333 void Linen_Ctor(Linen *unit);
337 //////////////////////////////////////////////////////////////////////////////////////////////////
339 // in, rate, depth, rateVariation, depthVariation
340 // 0 1 2 3 4
342 void Vibrato_next(Vibrato *unit, int inNumSamples)
344 float *out = ZOUT(0);
345 float *in = ZIN(0);
347 double ffreq = unit->mFreq;
348 double phase = unit->mPhase;
349 float scaleA = unit->m_scaleA;
350 float scaleB = unit->m_scaleB;
351 if (unit->m_delay > 0)
353 int remain = sc_min(inNumSamples, unit->m_delay);
354 unit->m_delay -= remain;
355 inNumSamples -= remain;
356 LOOP(remain,
357 ZXP(out) = ZXP(in);
359 if (unit->m_delay <= 0 && inNumSamples > 0) {
360 if (unit->m_attack > 0) goto doAttack;
361 else goto doNormal;
364 else if (unit->m_attack)
366 doAttack:
367 int remain = sc_min(inNumSamples, unit->m_attack);
368 unit->m_attack -= remain;
369 inNumSamples -= remain;
370 double attackSlope = unit->m_attackSlope;
371 double attackLevel = unit->m_attackLevel;
372 LOOP(remain,
373 if (phase < 1.f)
375 float z = phase;
376 ZXP(out) = ZXP(in) * (1.f + (float)attackLevel * scaleA * (1.f - z * z)) ;
378 else if (phase < 3.f)
380 float z = phase - 2.f;
381 ZXP(out) = ZXP(in) * (1.f + (float)attackLevel * scaleB * (z * z - 1.f)) ;
383 else
385 phase -= 4.f;
386 float z = phase;
388 float depth = ZIN0(2);
389 float rateVariation = ZIN0(5);
390 float depthVariation = ZIN0(6);
392 float rate = ZIN0(1) * unit->mFreqMul;
393 RGen& rgen = *unit->mParent->mRGen;
394 ffreq = rate * (1.f + rateVariation * rgen.frand2());
395 scaleA = depth * (1.f + depthVariation * rgen.frand2());
396 scaleB = depth * (1.f + depthVariation * rgen.frand2());
398 ZXP(out) = ZXP(in) * (1.f + (float)attackLevel * scaleA * (1.f - z * z)) ;
400 phase += ffreq;
401 attackLevel += attackSlope;
403 unit->m_attackLevel = attackLevel;
404 if (unit->m_attack <= 0 && inNumSamples > 0) goto doNormal;
406 else
408 doNormal:
409 LOOP1(inNumSamples,
410 if (phase < 1.f)
412 float z = phase;
413 ZXP(out) = ZXP(in) * (1.f + scaleA * (1.f - z * z)) ;
415 else if (phase < 3.f)
417 float z = phase - 2.f;
418 ZXP(out) = ZXP(in) * (1.f + scaleB * (z * z - 1.f)) ;
420 else
422 phase -= 4.f;
423 float z = phase;
425 float depth = ZIN0(2);
426 float rateVariation = ZIN0(5);
427 float depthVariation = ZIN0(6);
429 float rate = ZIN0(1) * unit->mFreqMul;
430 RGen& rgen = *unit->mParent->mRGen;
431 ffreq = rate * (1.f + rateVariation * rgen.frand2());
432 scaleA = depth * (1.f + depthVariation * rgen.frand2());
433 scaleB = depth * (1.f + depthVariation * rgen.frand2());
435 ZXP(out) = ZXP(in) * (1.f + scaleA * (1.f - z * z)) ;
437 phase += ffreq;
440 unit->mPhase = phase;
441 unit->mFreq = ffreq;
442 unit->m_scaleA = scaleA;
443 unit->m_scaleB = scaleB;
447 void Vibrato_Ctor(Vibrato* unit)
449 unit->mFreqMul = 4.0 * SAMPLEDUR;
450 unit->mPhase = 4.0 * sc_wrap(ZIN0(7), 0.f, 1.f) - 1.0;
452 RGen& rgen = *unit->mParent->mRGen;
453 float rate = ZIN0(1) * unit->mFreqMul;
454 float depth = ZIN0(2);
455 float rateVariation = ZIN0(5);
456 float depthVariation = ZIN0(6);
457 unit->mFreq = rate * (1.f + rateVariation * rgen.frand2());
458 unit->m_scaleA = depth * (1.f + depthVariation * rgen.frand2());
459 unit->m_scaleB = depth * (1.f + depthVariation * rgen.frand2());
460 unit->m_delay = (int)(ZIN0(3) * SAMPLERATE);
461 unit->m_attack = (int)(ZIN0(4) * SAMPLERATE);
462 unit->m_attackSlope = 1. / (double)(1 + unit->m_attack);
463 unit->m_attackLevel = unit->m_attackSlope;
465 SETCALC(Vibrato_next);
466 Vibrato_next(unit, 1);
469 //////////////////////////////////////////////////////////////////////////////////////////////////
472 void LFPulse_next_a(LFPulse *unit, int inNumSamples)
474 float *out = ZOUT(0);
475 float *freq = ZIN(0);
476 float nextDuty = ZIN0(2);
477 float duty = unit->mDuty;
479 float freqmul = unit->mFreqMul;
480 double phase = unit->mPhase;
481 LOOP1(inNumSamples,
482 float z;
483 if (phase >= 1.f) {
484 phase -= 1.f;
485 duty = unit->mDuty = nextDuty;
486 // output at least one sample from the opposite polarity
487 z = duty < 0.5f ? 1.f : 0.f;
488 } else {
489 z = phase < duty ? 1.f : 0.f;
491 phase += ZXP(freq) * freqmul;
492 ZXP(out) = z;
495 unit->mPhase = phase;
498 void LFPulse_next_k(LFPulse *unit, int inNumSamples)
500 float *out = ZOUT(0);
501 float freq = ZIN0(0) * unit->mFreqMul;
502 float nextDuty = ZIN0(2);
503 float duty = unit->mDuty;
505 double phase = unit->mPhase;
506 LOOP1(inNumSamples,
507 float z;
508 if (phase >= 1.f) {
509 phase -= 1.f;
510 duty = unit->mDuty = nextDuty;
511 // output at least one sample from the opposite polarity
512 z = duty < 0.5f ? 1.f : 0.f;
513 } else {
514 z = phase < duty ? 1.f : 0.f;
516 phase += freq;
517 ZXP(out) = z;
520 unit->mPhase = phase;
523 void LFPulse_Ctor(LFPulse* unit)
525 if (INRATE(0) == calc_FullRate) {
526 SETCALC(LFPulse_next_a);
527 } else {
528 SETCALC(LFPulse_next_k);
531 unit->mFreqMul = unit->mRate->mSampleDur;
532 unit->mPhase = ZIN0(1);
533 unit->mDuty = ZIN0(2);
535 LFPulse_next_k(unit, 1);
539 //////////////////////////////////////////////////////////////////////////////////////////////////
541 void LFSaw_next_a(LFSaw *unit, int inNumSamples)
543 float *out = ZOUT(0);
544 float *freq = ZIN(0);
546 float freqmul = unit->mFreqMul;
547 double phase = unit->mPhase;
548 LOOP1(inNumSamples,
549 float z = phase; // out must be written last for in place operation
550 phase += ZXP(freq) * freqmul;
551 if (phase >= 1.f) phase -= 2.f;
552 else if (phase <= -1.f) phase += 2.f;
553 ZXP(out) = z;
556 unit->mPhase = phase;
559 void LFSaw_next_k(LFSaw *unit, int inNumSamples)
561 float *out = ZOUT(0);
562 float freq = ZIN0(0) * unit->mFreqMul;
564 double phase = unit->mPhase;
565 if (freq >= 0.f) {
566 LOOP1(inNumSamples,
567 ZXP(out) = phase;
568 phase += freq;
569 if (phase >= 1.f) phase -= 2.f;
571 } else {
572 LOOP1(inNumSamples,
573 ZXP(out) = phase;
574 phase += freq;
575 if (phase <= -1.f) phase += 2.f;
579 unit->mPhase = phase;
582 void LFSaw_Ctor(LFSaw* unit)
584 if (INRATE(0) == calc_FullRate)
585 SETCALC(LFSaw_next_a);
586 else
587 SETCALC(LFSaw_next_k);
589 unit->mFreqMul = 2.0 * unit->mRate->mSampleDur;
590 unit->mPhase = ZIN0(1);
592 LFSaw_next_k(unit, 1);
596 //////////////////////////////////////////////////////////////////////////////////////////////////
598 void LFPar_next_a(LFPar *unit, int inNumSamples)
600 float *out = ZOUT(0);
601 float *freq = ZIN(0);
603 float freqmul = unit->mFreqMul;
604 double phase = unit->mPhase;
605 float z, y;
606 LOOP1(inNumSamples,
607 if (phase < 1.f) {
608 z = phase;
609 y = 1.f - z*z;
610 } else if (phase < 3.f) {
611 z = phase - 2.f;
612 y = z*z - 1.f;
613 } else {
614 phase -= 4.f;
615 z = phase;
616 y = 1.f - z*z;
618 // Note: the following two lines were originally one, but seems to compile wrong on mac
619 float phaseadd = ZXP(freq);
620 phase += phaseadd * freqmul;
621 ZXP(out) = y;
624 unit->mPhase = phase;
627 void LFPar_next_k(LFPar *unit, int inNumSamples)
629 float *out = ZOUT(0);
630 float freq = ZIN0(0) * unit->mFreqMul;
632 double phase = unit->mPhase;
633 LOOP1(inNumSamples,
634 if (phase < 1.f) {
635 float z = phase;
636 ZXP(out) = 1.f - z*z;
637 } else if (phase < 3.f) {
638 float z = phase - 2.f;
639 ZXP(out) = z*z - 1.f;
640 } else {
641 phase -= 4.f;
642 float z = phase;
643 ZXP(out) = 1.f - z*z;
645 phase += freq;
648 unit->mPhase = phase;
651 void LFPar_Ctor(LFPar* unit)
653 if (INRATE(0) == calc_FullRate)
654 SETCALC(LFPar_next_a);
655 else
656 SETCALC(LFPar_next_k);
658 unit->mFreqMul = 4.0 * unit->mRate->mSampleDur;
659 unit->mPhase = ZIN0(1);
661 LFPar_next_k(unit, 1);
666 //////////////////////////////////////////////////////////////////////////////////////////////////
668 void LFCub_next_a(LFCub *unit, int inNumSamples)
670 float *out = ZOUT(0);
671 float *freq = ZIN(0);
673 float freqmul = unit->mFreqMul;
674 double phase = unit->mPhase;
675 LOOP1(inNumSamples,
676 float z;
677 if (phase < 1.f) {
678 z = phase;
679 } else if (phase < 2.f) {
680 z = 2.f - phase;
681 } else {
682 phase -= 2.f;
683 z = phase;
685 float phaseadd = ZXP(freq);
686 phase += phaseadd * freqmul;
687 ZXP(out) = z * z * (6.f - 4.f * z) - 1.f;
690 unit->mPhase = phase;
693 void LFCub_next_k(LFCub *unit, int inNumSamples)
695 float *out = ZOUT(0);
696 float freq = ZIN0(0) * unit->mFreqMul;
698 double phase = unit->mPhase;
699 LOOP1(inNumSamples,
700 float z;
701 if (phase < 1.f) {
702 z = phase;
703 } else if (phase < 2.f) {
704 z = 2.f - phase;
705 } else {
706 phase -= 2.f;
707 z = phase;
709 ZXP(out) = z * z * (6.f - 4.f * z) - 1.f;
710 phase += freq;
713 unit->mPhase = phase;
716 void LFCub_Ctor(LFCub* unit)
718 if (INRATE(0) == calc_FullRate)
719 SETCALC(LFCub_next_a);
720 else
721 SETCALC(LFCub_next_k);
723 unit->mFreqMul = 2.0 * unit->mRate->mSampleDur;
724 unit->mPhase = ZIN0(1) + 0.5;
726 LFCub_next_k(unit, 1);
731 //////////////////////////////////////////////////////////////////////////////////////////////////
733 void LFTri_next_a(LFTri *unit, int inNumSamples)
735 float *out = ZOUT(0);
736 float *freq = ZIN(0);
738 float freqmul = unit->mFreqMul;
739 double phase = unit->mPhase;
740 LOOP1(inNumSamples,
741 float z = phase > 1.f ? 2.f - phase : phase;
742 phase += ZXP(freq) * freqmul;
743 if (phase >= 3.f) phase -= 4.f;
744 ZXP(out) = z;
747 unit->mPhase = phase;
750 void LFTri_next_k(LFTri *unit, int inNumSamples)
752 float *out = ZOUT(0);
753 float freq = ZIN0(0) * unit->mFreqMul;
755 double phase = unit->mPhase;
756 LOOP1(inNumSamples,
757 float z = phase > 1.f ? 2.f - phase : phase;
758 phase += freq;
759 if (phase >= 3.f) phase -= 4.f;
760 ZXP(out) = z;
763 unit->mPhase = phase;
766 void LFTri_Ctor(LFTri* unit)
768 if (INRATE(0) == calc_FullRate) {
769 SETCALC(LFTri_next_a);
770 } else {
771 SETCALC(LFTri_next_k);
774 unit->mFreqMul = 4.0 * unit->mRate->mSampleDur;
775 unit->mPhase = ZIN0(1);
777 LFTri_next_k(unit, 1);
781 //////////////////////////////////////////////////////////////////////////////////////////////////
783 void LFGauss_next_k(LFGauss *unit, int inNumSamples)
785 float *out = ZOUT(0);
787 float dur = ZIN0(0);
788 float c = ZIN0(1);
789 float b = ZIN0(2);
790 float loop = ZIN0(3);
792 // offset phase by b
793 double x = unit->mPhase - b;
795 // for a full cycle from -1 to 1 in duration, double the step.
796 float step = 2.f / (dur * unit->mRate->mSampleRate);
798 // calculate exponent only once per loop
799 float factor = -1.f / (2.f * c * c);
801 LOOP1(inNumSamples,
803 if (x > 1.f) {
804 if(loop) { x -= 2.f; } else { DoneAction(ZIN0(4), unit); }
806 ZXP(out) = exp(x * x * factor);
807 x += step;
810 unit->mPhase = x + b;
813 void LFGauss_next_a(LFGauss *unit, int inNumSamples)
815 float *out = ZOUT(0);
817 float *dur = ZIN(0);
819 float c = ZIN0(1);
820 float b = ZIN0(2);
821 float loop = ZIN0(3);
822 float sr = unit->mRate->mSampleRate;
824 // offset phase by b
825 double x = unit->mPhase - b;
826 float factor = -1.f / (2.f * c * c);
828 LOOP1(inNumSamples,
830 if (x > 1.f) {
831 if(loop) { x -= 2.f; } else { DoneAction(ZIN0(4), unit); }
834 // for a full cycle from -1 to 1 in duration, double the step.
835 float step = 2.f / (ZXP(dur) * sr);
837 ZXP(out) = exp(x * x * factor);
839 x += step;
842 unit->mPhase = x + b;
847 void LFGauss_next_aa(LFGauss *unit, int inNumSamples)
849 float *out = ZOUT(0);
851 float *dur = ZIN(0);
852 float *c = ZIN(1);
854 float b = ZIN0(2);
855 float loop = ZIN0(3);
856 float sr = unit->mRate->mSampleRate;
858 // offset phase by b
859 double x = unit->mPhase - b;
861 LOOP1(inNumSamples,
863 if (x > 1.f) {
864 if(loop) { x -= 2.f; } else { DoneAction(ZIN0(4), unit); }
867 // for a full cycle from -1 to 1 in duration, double the step.
868 float step = 2.f / (ZXP(dur) * sr);
870 float cval = ZXP(c);
872 float factor = -1.f / (2.f * cval * cval);
873 ZXP(out) = exp(x * x * factor);
875 x += step;
878 unit->mPhase = x + b;
882 void LFGauss_Ctor(LFGauss* unit)
885 if (INRATE(0) == calc_FullRate) {
886 if (INRATE(1) == calc_FullRate) {
887 SETCALC(LFGauss_next_aa);
888 } else {
889 SETCALC(LFGauss_next_a);
890 printf("LFGauss_next_a\n");
892 } else {
893 SETCALC(LFGauss_next_k);
895 unit->mPhase = -1.0;
897 //LFGauss_next_k(unit, 1);
901 //////////////////////////////////////////////////////////////////////////////////////////////////
903 void Impulse_next_a(Impulse *unit, int inNumSamples)
905 float *out = ZOUT(0);
906 float *freq = ZIN(0);
908 float freqmul = unit->mFreqMul;
909 double phase = unit->mPhase;
910 LOOP1(inNumSamples,
911 float z;
912 if (phase >= 1.f) {
913 phase -= 1.f;
914 z = 1.f;
915 } else {
916 z = 0.f;
918 phase += ZXP(freq) * freqmul;
919 ZXP(out) = z;
922 unit->mPhase = phase;
925 /* phase mod - jrh 03 */
927 void Impulse_next_ak(Impulse *unit, int inNumSamples)
929 float *out = ZOUT(0);
930 float *freq = ZIN(0);
931 double phaseOffset = ZIN0(1);
933 float freqmul = unit->mFreqMul;
934 double phase = unit->mPhase;
935 double prev_phaseOffset = unit->mPhaseOffset;
936 double phaseSlope = CALCSLOPE(phaseOffset, prev_phaseOffset);
937 phase += prev_phaseOffset;
939 LOOP1(inNumSamples,
940 float z;
941 phase += phaseSlope;
942 if (phase >= 1.f) {
943 phase -= 1.f;
944 z = 1.f;
945 } else {
946 z = 0.f;
948 phase += ZXP(freq) * freqmul;
949 ZXP(out) = z;
952 unit->mPhase = phase - phaseOffset;
953 unit->mPhaseOffset = phaseOffset;
956 void Impulse_next_kk(Impulse *unit, int inNumSamples)
958 float *out = ZOUT(0);
959 float freq = ZIN0(0) * unit->mFreqMul;
960 double phaseOffset = ZIN0(1);
962 double phase = unit->mPhase;
963 double prev_phaseOffset = unit->mPhaseOffset;
964 double phaseSlope = CALCSLOPE(phaseOffset, prev_phaseOffset);
965 phase += prev_phaseOffset;
967 LOOP1(inNumSamples,
968 float z;
969 phase += phaseSlope;
970 if (phase >= 1.f) {
971 phase -= 1.f;
972 z = 1.f;
973 } else {
974 z = 0.f;
976 phase += freq;
977 ZXP(out) = z;
980 unit->mPhase = phase - phaseOffset;
981 unit->mPhaseOffset = phaseOffset;
985 void Impulse_next_k(Impulse *unit, int inNumSamples)
987 float *out = ZOUT(0);
988 float freq = ZIN0(0) * unit->mFreqMul;
990 double phase = unit->mPhase;
991 LOOP1(inNumSamples,
992 float z;
993 if (phase >= 1.f) {
994 phase -= 1.f;
995 z = 1.f;
996 } else {
997 z = 0.f;
999 phase += freq;
1000 ZXP(out) = z;
1003 unit->mPhase = phase;
1006 void Impulse_Ctor(Impulse* unit)
1009 unit->mPhase = ZIN0(1);
1011 if (INRATE(0) == calc_FullRate) {
1012 if(INRATE(1) != calc_ScalarRate) {
1013 SETCALC(Impulse_next_ak);
1014 unit->mPhase = 1.f;
1015 } else {
1016 SETCALC(Impulse_next_a);
1018 } else {
1019 if(INRATE(1) != calc_ScalarRate) {
1020 SETCALC(Impulse_next_kk);
1021 unit->mPhase = 1.f;
1022 } else {
1023 SETCALC(Impulse_next_k);
1028 unit->mPhaseOffset = 0.f;
1029 unit->mFreqMul = unit->mRate->mSampleDur;
1030 if (unit->mPhase == 0.f) unit->mPhase = 1.f;
1032 ZOUT0(0) = 0.f;
1035 //////////////////////////////////////////////////////////////////////////////////////////////////
1037 void VarSaw_next_a(VarSaw *unit, int inNumSamples)
1039 float *out = ZOUT(0);
1040 float *freq = ZIN(0);
1041 float nextDuty = ZIN0(2);
1042 float duty = unit->mDuty;
1043 float invduty = unit->mInvDuty;
1044 float inv1duty = unit->mInv1Duty;
1046 float freqmul = unit->mFreqMul;
1047 double phase = unit->mPhase;
1049 LOOP1(inNumSamples,
1050 if (phase >= 1.f) {
1051 phase -= 1.f;
1052 duty = unit->mDuty = sc_clip(nextDuty, 0.001, 0.999);
1053 invduty = unit->mInvDuty = 2.f / duty;
1054 inv1duty = unit->mInv1Duty = 2.f / (1.f - duty);
1056 float z = phase < duty ? phase * invduty : (1.f - phase) * inv1duty;
1057 phase += ZXP(freq) * freqmul;
1058 ZXP(out) = z - 1.f;
1061 unit->mPhase = phase;
1064 void VarSaw_next_k(VarSaw *unit, int inNumSamples)
1066 float *out = ZOUT(0);
1067 float freq = ZIN0(0) * unit->mFreqMul;
1068 float nextDuty = ZIN0(2);
1069 float duty = unit->mDuty;
1070 float invduty = unit->mInvDuty;
1071 float inv1duty = unit->mInv1Duty;
1073 double phase = unit->mPhase;
1075 LOOP1(inNumSamples,
1076 if (phase >= 1.f) {
1077 phase -= 1.f;
1078 duty = unit->mDuty = sc_clip(nextDuty, 0.001, 0.999);
1079 invduty = unit->mInvDuty = 2.f / duty;
1080 inv1duty = unit->mInv1Duty = 2.f / (1.f - duty);
1082 float z = phase < duty ? phase * invduty : (1.f - phase) * inv1duty;
1083 phase += freq;
1084 ZXP(out) = z - 1.f;
1087 unit->mPhase = phase;
1090 void VarSaw_Ctor(VarSaw* unit)
1092 if (INRATE(0) == calc_FullRate) {
1093 SETCALC(VarSaw_next_a);
1094 } else {
1095 SETCALC(VarSaw_next_k);
1098 unit->mFreqMul = unit->mRate->mSampleDur;
1099 unit->mPhase = ZIN0(1);
1100 float duty = ZIN0(2);
1101 duty = unit->mDuty = sc_clip(duty, 0.001, 0.999);
1102 unit->mInvDuty = 2.f / duty;
1103 unit->mInv1Duty = 2.f / (1.f - duty);
1105 ZOUT0(0) = 0.f;
1108 //////////////////////////////////////////////////////////////////////////////////////////////////
1110 void SyncSaw_next_aa(SyncSaw *unit, int inNumSamples)
1112 float freqmul = unit->mFreqMul;
1113 float *out = ZOUT(0);
1114 float *freq1 = ZIN(0);
1115 float *freq2 = ZIN(1);
1117 double phase1 = unit->mPhase1;
1118 double phase2 = unit->mPhase2;
1120 LOOP1(inNumSamples,
1121 float freq1x = ZXP(freq1) * freqmul;
1122 float freq2x = ZXP(freq2) * freqmul;
1123 float z = phase2;
1124 phase2 += freq2x;
1125 if (phase2 >= 1.f) phase2 -= 2.f;
1126 phase1 += freq1x;
1127 if (phase1 >= 1.f) {
1128 phase1 -= 2.f;
1129 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1131 ZXP(out) = z;
1134 unit->mPhase1 = phase1;
1135 unit->mPhase2 = phase2;
1138 void SyncSaw_next_ak(SyncSaw *unit, int inNumSamples)
1140 float freqmul = unit->mFreqMul;
1141 float *out = ZOUT(0);
1142 float *freq1 = ZIN(0);
1143 float freq2x = ZIN0(1) * freqmul;
1145 double phase1 = unit->mPhase1;
1146 double phase2 = unit->mPhase2;
1148 LOOP1(inNumSamples,
1149 float freq1x = ZXP(freq1) * freqmul;
1150 float z = phase2;
1151 phase2 += freq2x;
1152 if (phase2 >= 1.f) phase2 -= 2.f;
1153 phase1 += freq1x;
1154 if (phase1 >= 1.f) {
1155 phase1 -= 2.f;
1156 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1158 ZXP(out) = z;
1161 unit->mPhase1 = phase1;
1162 unit->mPhase2 = phase2;
1165 void SyncSaw_next_ka(SyncSaw *unit, int inNumSamples)
1167 float freqmul = unit->mFreqMul;
1168 float *out = ZOUT(0);
1169 float freq1x = ZIN0(0) * freqmul;
1170 float *freq2 = ZIN(1);
1172 double phase1 = unit->mPhase1;
1173 double phase2 = unit->mPhase2;
1175 LOOP1(inNumSamples,
1176 float freq2x = ZXP(freq2) * freqmul;
1177 float z = phase2;
1178 phase2 += freq2x;
1179 if (phase2 >= 1.f) phase2 -= 2.f;
1180 phase1 += freq1x;
1181 if (phase1 >= 1.f) {
1182 phase1 -= 2.f;
1183 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1185 ZXP(out) = z;
1188 unit->mPhase1 = phase1;
1189 unit->mPhase2 = phase2;
1192 void SyncSaw_next_kk(SyncSaw *unit, int inNumSamples)
1194 float *out = ZOUT(0);
1195 float freq1x = ZIN0(0) * unit->mFreqMul;
1196 float freq2x = ZIN0(1) * unit->mFreqMul;
1197 double phase1 = unit->mPhase1;
1198 double phase2 = unit->mPhase2;
1200 LOOP1(inNumSamples,
1201 float z = phase2;
1202 phase2 += freq2x;
1203 if (phase2 >= 1.f) phase2 -= 2.f;
1204 phase1 += freq1x;
1205 if (phase1 >= 1.f) {
1206 phase1 -= 2.f;
1207 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1209 ZXP(out) = z;
1212 unit->mPhase1 = phase1;
1213 unit->mPhase2 = phase2;
1216 void SyncSaw_Ctor(SyncSaw* unit)
1218 if (INRATE(0) == calc_FullRate) {
1219 if (INRATE(1) == calc_FullRate) {
1220 SETCALC(SyncSaw_next_aa);
1221 } else {
1222 SETCALC(SyncSaw_next_ak);
1224 } else {
1225 if (INRATE(1) == calc_FullRate) {
1226 SETCALC(SyncSaw_next_ka);
1227 } else {
1228 SETCALC(SyncSaw_next_kk);
1231 unit->mFreqMul = 2.0 * unit->mRate->mSampleDur;
1232 unit->mPhase1 = 0.;
1233 unit->mPhase2 = 0.;
1235 SyncSaw_next_kk(unit, 1);
1238 //////////////////////////////////////////////////////////////////////////////////////////////////
1240 void K2A_next(K2A *unit, int inNumSamples)
1242 float *out = ZOUT(0);
1243 float in = ZIN0(0);
1245 float level = unit->mLevel;
1246 float slope = CALCSLOPE(in, level);
1248 LOOP1(inNumSamples,
1249 ZXP(out) = level += slope;
1251 unit->mLevel = level;
1254 #ifdef NOVA_SIMD
1255 inline_functions void K2A_next_nova(K2A *unit, int inNumSamples)
1257 float in = ZIN0(0);
1258 float level = unit->mLevel;
1260 if (level == in)
1261 nova::setvec_simd(OUT(0), level, inNumSamples);
1262 else
1264 float slope = CALCSLOPE(in, level);
1265 nova::set_slope_vec_simd(OUT(0), level, slope, inNumSamples);
1268 unit->mLevel = in;
1271 inline_functions void K2A_next_nova_64(K2A *unit, int inNumSamples)
1273 float in = ZIN0(0);
1274 float level = unit->mLevel;
1276 if (level == in)
1277 nova::setvec_simd<64>(OUT(0), level);
1278 else
1280 float slope = CALCSLOPE(in, level);
1281 nova::set_slope_vec_simd(OUT(0), level, slope, 64);
1284 unit->mLevel = in;
1287 #endif
1289 void K2A_Ctor(K2A* unit)
1291 #ifdef NOVA_SIMD
1292 if (BUFLENGTH == 64)
1293 SETCALC(K2A_next_nova_64);
1294 else if (!(BUFLENGTH & 15))
1295 SETCALC(K2A_next_nova);
1296 else
1297 #endif
1298 SETCALC(K2A_next);
1299 unit->mLevel = ZIN0(0);
1301 ZOUT0(0) = unit->mLevel;
1304 //////////////////////////////////////////////////////////////////////////////////////////////////
1306 void A2K_next(A2K *unit, int inNumSamples)
1308 ZOUT0(0) = ZIN0(0); // return first sample in block
1311 void A2K_Ctor(A2K* unit)
1313 SETCALC(A2K_next);
1314 A2K_next(unit, 1);
1317 //////////////////////////////////////////////////////////////////////////////////////////////////
1319 void T2K_next(T2K *unit, int inNumSamples)
1321 float out = 0.f, val;
1322 float *in = ZIN(0);
1323 int n = unit->mWorld->mBufLength;
1324 LOOP1(n,
1325 val = ZXP(in);
1326 if(val>out) out=val;
1328 ZOUT0(0) = out;
1331 void T2K_Ctor(T2K* unit)
1333 SETCALC(T2K_next);
1334 ZOUT0(0) = ZIN0(0);
1337 //////////////////////////////////////////////////////////////////////////////////////////////////
1339 static inline void T2A_write_trigger(T2A * unit, float level)
1341 float *out = OUT(0);
1342 int offset = (int) IN0(1);
1343 out[offset] = level;
1346 void T2A_next(T2A *unit, int inNumSamples)
1348 float level = IN0(0);
1350 ZClear(inNumSamples, ZOUT(0));
1351 if((unit->mLevel <= 0.f && level > 0.f))
1352 T2A_write_trigger(unit, level);
1354 unit->mLevel = level;
1357 #ifdef NOVA_SIMD
1358 inline_functions void T2A_next_nova(T2A *unit, int inNumSamples)
1360 float level = IN0(0);
1362 nova::zerovec_simd(OUT(0), inNumSamples);
1363 if((unit->mLevel <= 0.f && level > 0.f))
1364 T2A_write_trigger(unit, level);
1366 unit->mLevel = level;
1369 inline_functions void T2A_next_nova_64(T2A *unit, int inNumSamples)
1371 float level = IN0(0);
1373 nova::zerovec_simd<64>(OUT(0));
1374 if((unit->mLevel <= 0.f && level > 0.f))
1375 T2A_write_trigger(unit, level);
1377 unit->mLevel = level;
1380 #endif
1382 void T2A_Ctor(T2A* unit)
1384 #ifdef NOVA_SIMD
1385 if (BUFLENGTH == 64)
1386 SETCALC(T2A_next_nova_64);
1387 else if (!(BUFLENGTH & 15))
1388 SETCALC(T2A_next_nova);
1389 else
1390 #endif
1391 SETCALC(T2A_next);
1392 T2A_next(unit, 1);
1396 //////////////////////////////////////////////////////////////////////////////////////////////////
1398 #ifdef NOVA_SIMD
1399 inline_functions static void DC_next_nova(DC *unit, int inNumSamples)
1401 float val = unit->m_val;
1402 nova::setvec_simd(OUT(0), val, inNumSamples);
1405 inline_functions static void DC_next_nova_64(DC *unit, int inNumSamples)
1407 float val = unit->m_val;
1408 nova::setvec_simd<64>(OUT(0), val);
1410 #endif
1412 static void DC_next(DC *unit, int inNumSamples)
1414 float val = unit->m_val;
1415 float *out = ZOUT(0);
1416 LOOP1(inNumSamples, ZXP(out) = val;)
1419 static void DC_next_1(DC *unit, int inNumSamples)
1421 ZOUT0(0) = unit->m_val;
1424 static void DC_Ctor(DC* unit)
1426 unit->m_val = IN0(0);
1427 #ifdef NOVA_SIMD
1428 if (BUFLENGTH == 64)
1429 SETCALC(DC_next_nova_64);
1430 if (!(BUFLENGTH & 15))
1431 SETCALC(DC_next_nova);
1432 else
1433 #endif
1434 if (BUFLENGTH == 1)
1435 SETCALC(DC_next_1);
1436 else
1437 SETCALC(DC_next);
1438 ZOUT0(0) = unit->m_val;
1442 //////////////////////////////////////////////////////////////////////////////////////////////////
1444 void Silent_Ctor(Unit* unit)
1446 SETCALC(ClearUnitOutputs);
1447 ZOUT0(0) = 0.f;
1450 //////////////////////////////////////////////////////////////////////////////////////////////////
1452 static inline void Line_next_loop(Line * unit, int & counter, int remain, double & level)
1454 float *out = ZOUT(0);
1455 double slope = unit->mSlope;
1457 do {
1458 if (counter==0) {
1459 int nsmps = remain;
1460 remain = 0;
1461 float endlevel = unit->mEndLevel;
1462 LOOP(nsmps,
1463 ZXP(out) = endlevel;
1465 } else {
1466 int nsmps = sc_min(remain, counter);
1467 counter -= nsmps;
1468 remain -= nsmps;
1469 LOOP(nsmps,
1470 ZXP(out) = level;
1471 level += slope;
1473 if (counter == 0) {
1474 unit->mDone = true;
1475 int doneAction = (int)ZIN0(3);
1476 DoneAction(doneAction, unit);
1479 } while (remain);
1484 void Line_next(Line *unit, int inNumSamples)
1486 double level = unit->mLevel;
1487 int counter = unit->mCounter;
1488 Line_next_loop(unit, counter, inNumSamples, level);
1489 unit->mCounter = counter;
1490 unit->mLevel = level;
1493 #ifdef NOVA_SIMD
1494 inline_functions void Line_next_nova(Line *unit, int inNumSamples)
1496 double level = unit->mLevel;
1497 int counter = unit->mCounter;
1499 if (counter == 0)
1501 nova::setvec_simd(OUT(0), unit->mEndLevel, inNumSamples);
1502 return;
1505 if (counter > inNumSamples)
1507 double slope = unit->mSlope;
1508 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, inNumSamples);
1509 unit->mLevel = level + inNumSamples * slope;
1510 unit->mCounter = counter - inNumSamples;
1511 return;
1513 Line_next_loop(unit, counter, inNumSamples, level);
1514 unit->mCounter = counter;
1515 unit->mLevel = level;
1518 inline_functions void Line_next_nova_64(Line *unit, int inNumSamples)
1520 double level = unit->mLevel;
1521 int counter = unit->mCounter;
1523 if (counter == 0)
1525 nova::setvec_simd<64>(OUT(0), unit->mEndLevel);
1526 return;
1529 if (counter > inNumSamples)
1531 double slope = unit->mSlope;
1532 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, 64);
1533 unit->mLevel = level + inNumSamples * slope;
1534 unit->mCounter = counter - inNumSamples;
1535 return;
1538 Line_next_loop(unit, counter, inNumSamples, level);
1539 unit->mCounter = counter;
1540 unit->mLevel = level;
1543 #endif
1545 void Line_Ctor(Line* unit)
1547 #ifdef NOVA_SIMD
1548 if (BUFLENGTH == 64)
1549 SETCALC(Line_next_nova);
1550 else if (!(BUFLENGTH & 15))
1551 SETCALC(Line_next_nova);
1552 else
1553 #endif
1554 SETCALC(Line_next);
1555 double start = ZIN0(0);
1556 double end = ZIN0(1);
1557 double dur = ZIN0(2);
1559 int counter = (int)(dur * unit->mRate->mSampleRate + .5f);
1560 unit->mCounter = sc_max(1, counter);
1561 if(counter == 0){
1562 unit->mLevel = end;
1563 unit->mSlope = 0.;
1564 } else {
1565 unit->mLevel = start;
1566 unit->mSlope = (end - start) / unit->mCounter;
1567 unit->mLevel += unit->mSlope;
1569 unit->mEndLevel = end;
1570 ZOUT0(0) = unit->mLevel;
1573 //////////////////////////////////////////////////////////////////////////////////////////////////
1575 static inline void Xline_next_loop(XLine * unit, int & counter, int remain, double & level)
1577 float *out = ZOUT(0);
1578 double grow = unit->mGrowth;
1580 do {
1581 if (counter==0) {
1582 int nsmps = remain;
1583 remain = 0;
1584 LOOP(nsmps,
1585 ZXP(out) = level;
1587 } else {
1588 int nsmps = sc_min(remain, counter);
1589 counter -= nsmps;
1590 remain -= nsmps;
1591 LOOP(nsmps,
1592 ZXP(out) = level;
1593 level *= grow;
1595 if (counter == 0) {
1596 level = unit->mEndLevel;
1597 unit->mDone = true;
1598 int doneAction = (int)ZIN0(3);
1599 DoneAction(doneAction, unit);
1602 } while (remain);
1605 void XLine_next(XLine *unit, int inNumSamples)
1607 double level = unit->mLevel;
1608 int counter = unit->mCounter;
1610 Xline_next_loop(unit, counter, inNumSamples, level);
1611 unit->mCounter = counter;
1612 unit->mLevel = level;
1615 #ifdef NOVA_SIMD
1616 inline_functions void XLine_next_nova(XLine *unit, int inNumSamples)
1618 double level = unit->mLevel;
1619 int counter = unit->mCounter;
1621 if (counter == 0)
1623 nova::setvec_simd(OUT(0), (float)level, inNumSamples);
1624 return;
1626 if (counter > inNumSamples)
1628 double grow = unit->mGrowth;
1629 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, inNumSamples);
1630 level *= sc_powi(grow, inNumSamples);
1631 counter -= inNumSamples;
1632 } else
1633 Xline_next_loop(unit, counter, inNumSamples, level);
1634 unit->mCounter = counter;
1635 unit->mLevel = level;
1638 inline_functions void XLine_next_nova_64(XLine *unit, int inNumSamples)
1640 double level = unit->mLevel;
1641 int counter = unit->mCounter;
1643 if (counter == 0)
1645 nova::setvec_simd<64>(OUT(0), (float)level);
1646 return;
1648 if (counter > 64)
1650 double grow = unit->mGrowth;
1651 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, 64);
1652 level *= sc_powi(grow, inNumSamples);
1653 counter -= inNumSamples;
1654 } else
1655 Xline_next_loop(unit, counter, inNumSamples, level);
1656 unit->mCounter = counter;
1657 unit->mLevel = level;
1660 #endif
1662 void XLine_Ctor(XLine* unit)
1664 #ifdef NOVA_SIMD
1665 if (BUFLENGTH == 64)
1666 SETCALC(XLine_next_nova_64);
1667 else if (!(BUFLENGTH & 15))
1668 SETCALC(XLine_next_nova);
1669 else
1670 #endif
1672 SETCALC(XLine_next);
1673 double start = ZIN0(0);
1674 double end = ZIN0(1);
1675 double dur = ZIN0(2);
1677 int counter = (int)(dur * unit->mRate->mSampleRate + .5f);
1679 unit->mEndLevel = end;
1681 if (counter == 0) {
1682 ZOUT0(0) = end;
1683 unit->mLevel = end;
1684 unit->mCounter = 0;
1685 unit->mGrowth = 0;
1686 } else {
1687 ZOUT0(0) = start;
1688 unit->mCounter = counter;
1689 unit->mGrowth = pow(end / start, 1.0 / counter);
1690 unit->mLevel = start * unit->mGrowth;
1694 //////////////////////////////////////////////////////////////////////////////////////////////////
1696 void Wrap_next(Wrap* unit, int inNumSamples)
1698 float *out = ZOUT(0);
1699 float *in = ZIN(0);
1700 float lo = unit->m_lo;
1701 float hi = unit->m_hi;
1702 float range = unit->m_range;
1704 LOOP1(inNumSamples,
1705 ZXP(out) = sc_wrap(ZXP(in), lo, hi, range);
1709 void Wrap_Ctor(Wrap* unit)
1712 SETCALC(Wrap_next);
1713 unit->m_lo = ZIN0(1);
1714 unit->m_hi = ZIN0(2);
1716 if (unit->m_lo > unit->m_hi) {
1717 float temp = unit->m_lo;
1718 unit->m_lo = unit->m_hi;
1719 unit->m_hi = temp;
1721 unit->m_range = unit->m_hi - unit->m_lo;
1723 Wrap_next(unit, 1);
1728 void Wrap_next_kk(Wrap* unit, int inNumSamples)
1730 float *out = ZOUT(0);
1731 float *in = ZIN(0);
1732 float next_lo = ZIN0(1);
1733 float next_hi = ZIN0(2);
1734 float lo = unit->m_lo;
1735 float lo_slope = CALCSLOPE(next_lo, lo);
1736 float hi = unit->m_hi;
1737 float hi_slope = CALCSLOPE(next_hi, hi);
1738 LOOP1(inNumSamples,
1739 float range = hi - lo;
1740 ZXP(out) = sc_wrap(ZXP(in), lo, hi, range);
1741 lo += lo_slope;
1742 hi += hi_slope;
1744 unit->m_lo = lo;
1745 unit->m_hi = hi;
1748 void Wrap_next_ka(Wrap* unit, int inNumSamples)
1750 float *out = ZOUT(0);
1751 float *in = ZIN(0);
1752 float next_lo = ZIN0(1);
1753 float *hi = ZIN(2);
1754 float lo = unit->m_lo;
1755 float lo_slope = CALCSLOPE(next_lo, lo);
1756 LOOP1(inNumSamples,
1757 float curhi = ZXP(hi);
1758 ZXP(out) = sc_wrap(ZXP(in), lo, curhi, curhi - lo);
1759 lo += lo_slope;
1761 unit->m_lo = lo;
1764 void Wrap_next_ak(Wrap* unit, int inNumSamples)
1766 float *out = ZOUT(0);
1767 float *in = ZIN(0);
1768 float *lo = ZIN(1);
1769 float next_hi = ZIN0(2);
1770 float hi = unit->m_hi;
1771 float hi_slope = CALCSLOPE(next_hi, hi);
1773 LOOP1(inNumSamples,
1774 float curlo = ZXP(lo);
1775 ZXP(out) = sc_wrap(ZXP(in), curlo, hi, hi - curlo);
1776 hi += hi_slope;
1778 unit->m_hi = hi;
1781 void Wrap_next_aa(Wrap* unit, int inNumSamples)
1783 float *out = ZOUT(0);
1784 float *in = ZIN(0);
1785 float *lo = ZIN(1);
1786 float *hi = ZIN(2);
1788 LOOP1(inNumSamples,
1789 float curhi = ZXP(hi);
1790 float curlo = ZXP(lo);
1791 ZXP(out) = sc_wrap(ZXP(in), curlo, curhi, curhi - curlo);
1795 void Wrap_Ctor(Wrap* unit)
1797 if(BUFLENGTH == 1) {
1798 // _aa? Well, yes - that calc func doesn't interpolate
1799 // and interpolation is not needed for kr (1 sample/block)
1800 SETCALC(Wrap_next_aa);
1801 } else {
1802 if(INRATE(1) == calc_FullRate) {
1803 if(INRATE(2) == calc_FullRate)
1804 SETCALC(Wrap_next_aa);
1805 else
1806 SETCALC(Wrap_next_ak);
1807 } else {
1808 if(INRATE(2) == calc_FullRate)
1809 SETCALC(Wrap_next_ka);
1810 else
1811 SETCALC(Wrap_next_kk);
1815 unit->m_lo = ZIN0(1);
1816 unit->m_hi = ZIN0(2);
1818 Wrap_next_kk(unit, 1);
1822 //////////////////////////////////////////////////////////////////////////////////////////////////
1824 void Fold_next(Fold* unit, int inNumSamples)
1826 float *out = ZOUT(0);
1827 float *in = ZIN(0);
1828 float lo = unit->m_lo;
1829 float hi = unit->m_hi;
1830 float range = unit->m_range;
1831 float range2 = unit->m_range2;
1833 LOOP1(inNumSamples,
1834 ZXP(out) = sc_fold(ZXP(in), lo, hi, range, range2);
1838 void Fold_Ctor(Fold* unit)
1841 SETCALC(Fold_next);
1842 unit->m_lo = ZIN0(1);
1843 unit->m_hi = ZIN0(2);
1845 if (unit->m_lo > unit->m_hi) {
1846 float temp = unit->m_lo;
1847 unit->m_lo = unit->m_hi;
1848 unit->m_hi = temp;
1850 unit->m_range = unit->m_hi - unit->m_lo;
1851 unit->m_range2 = 2.f * unit->m_range;
1853 Fold_next(unit, 1);
1856 void Fold_next_kk(Fold* unit, int inNumSamples)
1858 float *out = ZOUT(0);
1859 float *in = ZIN(0);
1860 float next_lo = ZIN0(1);
1861 float next_hi = ZIN0(2);
1862 float lo = unit->m_lo;
1863 float lo_slope = CALCSLOPE(next_lo, lo);
1864 float hi = unit->m_hi;
1865 float hi_slope = CALCSLOPE(next_hi, hi);
1867 LOOP1(inNumSamples,
1868 float range = hi - lo;
1869 float range2 = range * 2.f;
1870 ZXP(out) = sc_fold(ZXP(in), lo, hi, range, range2);
1872 lo += lo_slope;
1873 hi += hi_slope;
1875 unit->m_lo = lo;
1876 unit->m_hi = hi;
1879 void Fold_next_ka(Fold* unit, int inNumSamples)
1881 float *out = ZOUT(0);
1882 float *in = ZIN(0);
1883 float next_lo = ZIN0(1);
1884 float *hi = ZIN(2);
1885 float lo = unit->m_lo;
1886 float lo_slope = CALCSLOPE(next_lo, lo);
1888 LOOP1(inNumSamples,
1889 float curhi = ZXP(hi);
1890 float range = curhi - lo;
1891 float range2 = range * 2.f;
1892 ZXP(out) = sc_fold(ZXP(in), lo, curhi, range, range2);
1893 lo += lo_slope;
1895 unit->m_lo = lo;
1898 void Fold_next_ak(Fold* unit, int inNumSamples)
1900 float *out = ZOUT(0);
1901 float *in = ZIN(0);
1902 float *lo = ZIN(1);
1903 float next_hi = ZIN0(2);
1904 float hi = unit->m_hi;
1905 float hi_slope = CALCSLOPE(next_hi, hi);
1907 LOOP1(inNumSamples,
1908 float curlo = ZXP(lo);
1909 float range = hi - curlo;
1910 float range2 = range * 2.f;
1911 ZXP(out) = sc_fold(ZXP(in), curlo, hi, range, range2);
1912 hi += hi_slope;
1914 unit->m_hi = hi;
1917 void Fold_next_aa(Fold* unit, int inNumSamples)
1919 float *out = ZOUT(0);
1920 float *in = ZIN(0);
1921 float *lo = ZIN(1);
1922 float *hi = ZIN(2);
1924 LOOP1(inNumSamples,
1925 float curhi = ZXP(hi);
1926 float curlo = ZXP(lo);
1927 float range = curhi - curlo;
1928 float range2 = range * 2.0;
1929 ZXP(out) = sc_fold(ZXP(in), curlo, curhi, range, range2);
1933 void Fold_Ctor(Fold* unit)
1935 if(BUFLENGTH == 1) {
1936 // _aa? Well, yes - that calc func doesn't interpolate
1937 // and interpolation is not needed for kr (1 sample/block)
1938 SETCALC(Fold_next_aa);
1939 } else {
1940 if(INRATE(1) == calc_FullRate) {
1941 if(INRATE(2) == calc_FullRate)
1942 SETCALC(Fold_next_aa);
1943 else
1944 SETCALC(Fold_next_ak);
1945 } else {
1946 if(INRATE(2) == calc_FullRate)
1947 SETCALC(Fold_next_ka);
1948 else
1949 SETCALC(Fold_next_kk);
1953 unit->m_lo = ZIN0(1);
1954 unit->m_hi = ZIN0(2);
1956 Fold_next_kk(unit, 1);
1959 //////////////////////////////////////////////////////////////////////////////////////////////////
1961 void Clip_next_ii(Clip* unit, int inNumSamples)
1963 float *out = ZOUT(0);
1964 float *in = ZIN(0);
1965 float lo = unit->m_lo;
1966 float hi = unit->m_hi;
1968 LOOP1(inNumSamples,
1969 ZXP(out) = sc_clip(ZXP(in), lo, hi);
1973 void Clip_next_kk(Clip* unit, int inNumSamples)
1975 float next_lo = ZIN0(1);
1976 float next_hi = ZIN0(2);
1977 float lo = unit->m_lo;
1978 float hi = unit->m_hi;
1980 if (lo == next_lo && hi == next_hi) {
1981 Clip_next_ii(unit, inNumSamples);
1982 return;
1985 float *out = ZOUT(0);
1986 float *in = ZIN(0);
1987 float lo_slope = CALCSLOPE(next_lo, lo);
1988 float hi_slope = CALCSLOPE(next_hi, hi);
1990 LOOP1(inNumSamples,
1991 ZXP(out) = sc_clip(ZXP(in), lo, hi);
1992 lo += lo_slope;
1993 hi += hi_slope;
1995 unit->m_lo = lo;
1996 unit->m_hi = hi;
1999 void Clip_next_ka(Clip* unit, int inNumSamples)
2001 float *out = ZOUT(0);
2002 float *in = ZIN(0);
2003 float next_lo = ZIN0(1);
2004 float *hi = ZIN(2);
2005 float lo = unit->m_lo;
2006 float lo_slope = CALCSLOPE(next_lo, lo);
2008 LOOP1(inNumSamples,
2009 ZXP(out) = sc_clip(ZXP(in), lo, ZXP(hi));
2010 lo += lo_slope;
2012 unit->m_lo = lo;
2015 void Clip_next_ak(Clip* unit, int inNumSamples)
2017 float *out = ZOUT(0);
2018 float *in = ZIN(0);
2019 float *lo = ZIN(1);
2020 float next_hi = ZIN0(2);
2021 float hi = unit->m_hi;
2022 float hi_slope = CALCSLOPE(next_hi, hi);
2024 LOOP1(inNumSamples,
2025 ZXP(out) = sc_clip(ZXP(in), ZXP(lo), hi);
2026 hi += hi_slope;
2028 unit->m_hi = hi;
2031 void Clip_next_aa(Clip* unit, int inNumSamples)
2033 float *out = ZOUT(0);
2034 float *in = ZIN(0);
2035 float *lo = ZIN(1);
2036 float *hi = ZIN(2);
2038 LOOP1(inNumSamples,
2039 ZXP(out) = sc_clip(ZXP(in), ZXP(lo), ZXP(hi));
2043 void Clip_next_k(Clip* unit, int inNumSamples)
2045 float *out = ZOUT(0);
2046 float *in = ZIN(0);
2047 float lo = unit->m_lo;
2048 float hi = unit->m_hi;
2050 ZXP(out) = sc_clip(ZXP(in), lo, hi);
2053 #ifdef NOVA_SIMD
2054 void Clip_next_nova_ii(Clip* unit, int inNumSamples)
2056 float lo = unit->m_lo;
2057 float hi = unit->m_hi;
2059 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(lo), wrap_argument(hi), inNumSamples);
2062 void Clip_next_nova_ki(Clip* unit, int inNumSamples)
2064 float next_lo = ZIN0(1);
2065 float lo = unit->m_lo;
2066 float hi = unit->m_hi;
2068 if (lo == next_lo) {
2069 Clip_next_nova_ii(unit, inNumSamples);
2070 return;
2073 float lo_slope = CALCSLOPE(next_lo, lo);
2074 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(lo, lo_slope), wrap_argument(hi), inNumSamples);
2077 void Clip_next_nova_ik(Clip* unit, int inNumSamples)
2079 float next_hi = ZIN0(2);
2080 float lo = unit->m_lo;
2081 float hi = unit->m_hi;
2083 if (hi == next_hi) {
2084 Clip_next_nova_ii(unit, inNumSamples);
2085 return;
2088 float hi_slope = CALCSLOPE(next_hi, hi);
2089 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(lo), wrap_argument(hi, hi_slope), inNumSamples);
2092 void Clip_next_nova_kk(Clip* unit, int inNumSamples)
2094 float next_lo = ZIN0(1);
2095 float next_hi = ZIN0(2);
2096 float lo = unit->m_lo;
2097 float hi = unit->m_hi;
2099 if (lo == next_lo && hi == next_hi) {
2100 Clip_next_nova_ii(unit, inNumSamples);
2101 return;
2104 if (lo == next_lo) {
2105 Clip_next_nova_ik(unit, inNumSamples);
2106 return;
2109 if (hi == next_hi) {
2110 Clip_next_nova_ki(unit, inNumSamples);
2111 return;
2114 float lo_slope = CALCSLOPE(next_lo, lo);
2115 float hi_slope = CALCSLOPE(next_hi, hi);
2117 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(lo, lo_slope), wrap_argument(hi, hi_slope), inNumSamples);
2120 void Clip_next_nova_ai(Clip* unit, int inNumSamples)
2122 float hi = unit->m_hi;
2123 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(IN(1)), wrap_argument(hi), inNumSamples);
2126 void Clip_next_nova_ak(Clip* unit, int inNumSamples)
2128 float next_hi = ZIN0(2);
2129 float hi = unit->m_hi;
2131 if (hi == next_hi) {
2132 Clip_next_nova_ai(unit, inNumSamples);
2133 return;
2136 float hi_slope = CALCSLOPE(next_hi, hi);
2138 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(IN(1)), wrap_argument(hi, hi_slope), inNumSamples);
2141 void Clip_next_nova_ia(Clip* unit, int inNumSamples)
2143 float lo = unit->m_lo;
2144 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(lo), wrap_argument(IN(2)), inNumSamples);
2147 void Clip_next_nova_ka(Clip* unit, int inNumSamples)
2149 float next_lo = ZIN0(1);
2150 float lo = unit->m_lo;
2152 if (lo == next_lo) {
2153 Clip_next_nova_ia(unit, inNumSamples);
2154 return;
2157 float lo_slope = CALCSLOPE(next_lo, lo);
2158 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(lo, lo_slope), wrap_argument(IN(2)), inNumSamples);
2162 void Clip_next_nova_aa(Clip* unit, int inNumSamples)
2164 nova::clip_vec_simd(OUT(0), wrap_argument(IN(0)), wrap_argument(IN(1)), wrap_argument(IN(2)), inNumSamples);
2167 #endif
2169 typedef void (*ClipCalcFunc)(Clip*, int);
2171 static ClipCalcFunc Clip_SelectCalc(Clip * unit)
2173 if(BUFLENGTH == 1)
2174 return Clip_next_k;
2176 int loRate = INRATE(1);
2177 int hiRate = INRATE(2);
2179 #ifdef NOVA_SIMD
2180 if (!(BUFLENGTH & 15)) {
2181 switch (loRate)
2183 case calc_FullRate:
2184 switch (hiRate) {
2185 case calc_FullRate:
2186 return Clip_next_nova_aa;
2187 case calc_BufRate:
2188 return Clip_next_nova_ak;
2189 case calc_ScalarRate:
2190 return Clip_next_nova_ai;
2192 break;
2194 case calc_BufRate:
2195 switch (hiRate) {
2196 case calc_FullRate:
2197 return Clip_next_nova_ka;
2198 case calc_BufRate:
2199 return Clip_next_nova_kk;
2200 case calc_ScalarRate:
2201 return Clip_next_nova_ki;
2203 break;
2205 case calc_ScalarRate:
2206 switch (hiRate) {
2207 case calc_FullRate:
2208 return Clip_next_nova_ia;
2209 case calc_BufRate:
2210 return Clip_next_nova_ik;
2211 case calc_ScalarRate:
2212 return Clip_next_nova_ii;
2214 break;
2217 #endif
2219 if (loRate == calc_FullRate && hiRate == calc_FullRate)
2220 return Clip_next_aa;
2222 if (loRate == calc_ScalarRate && hiRate == calc_ScalarRate)
2223 return Clip_next_ii;
2225 if (loRate == calc_FullRate && hiRate != calc_FullRate)
2226 return Clip_next_ak;
2228 if (loRate != calc_FullRate && hiRate == calc_FullRate)
2229 return Clip_next_ak;
2231 return Clip_next_kk;
2234 void Clip_Ctor(Clip* unit)
2236 ClipCalcFunc fn = Clip_SelectCalc(unit);
2237 unit->mCalcFunc = (UnitCalcFunc)fn;
2239 unit->m_lo = ZIN0(1);
2240 unit->m_hi = ZIN0(2);
2242 Clip_next_ii(unit, 1);
2245 //////////////////////////////////////////////////////////////////////////////////////////////////
2247 void Unwrap_next(Unwrap* unit, int inNumSamples)
2249 float *out = ZOUT(0);
2250 float *in = ZIN(0);
2251 float range = unit->m_range;
2252 float half = unit->m_half;
2253 float prev = unit->m_prev;
2254 float offset = unit->m_offset;
2256 LOOP1(inNumSamples,
2257 float zin = ZXP(in);
2258 float diff = zin - prev;
2259 if (fabs(diff) > half) {
2260 if (zin < prev)
2261 offset += range;
2262 else
2263 offset -= range;
2265 ZXP(out) = zin + offset;
2266 prev = zin;
2268 unit->m_prev = prev;
2269 unit->m_offset = offset;
2272 void Unwrap_Ctor(Unwrap* unit)
2274 SETCALC(Unwrap_next);
2275 float in = ZIN0(0);
2276 float lo = ZIN0(1);
2277 float hi = ZIN0(2);
2279 if (lo > hi) {
2280 float temp = lo;
2281 lo = hi;
2282 hi = temp;
2284 unit->m_range = fabs(hi - lo);
2285 unit->m_half = unit->m_range * 0.5f;
2287 if (in < lo || in >= hi) unit->m_offset = floor((lo - in)/unit->m_range) * unit->m_range;
2288 else unit->m_offset = 0.f;
2290 Unwrap_next(unit, 1);
2293 //////////////////////////////////////////////////////////////////////////////////////////////////
2295 void AmpComp_next(AmpComp *unit, int inNumSamples)
2297 float *out = ZOUT(0);
2298 float *freq = ZIN(0);
2299 float rootmul = unit->m_rootmul;
2300 float xb = unit->m_exponent;
2302 LOOP1(inNumSamples,
2303 float xa = ZXP(freq);
2304 ZXP(out) = xa >= 0.f ? pow(xa, xb) * rootmul : -pow(-xa, xb) * rootmul;
2308 void AmpComp_next_kk(AmpComp *unit, int inNumSamples)
2310 float *out = ZOUT(0);
2311 float *freq = ZIN(0);
2312 float root = ZIN0(1);
2313 float xb = ZIN0(2);
2315 LOOP1(inNumSamples,
2316 float xa = root / ZXP(freq);
2317 ZXP(out) = xa >= 0.f ? pow(xa, xb) : -pow(-xa, xb);
2321 void AmpComp_Ctor(AmpComp* unit)
2323 if(INRATE(1) != calc_ScalarRate || INRATE(2) != calc_ScalarRate) {
2324 SETCALC(AmpComp_next_kk);
2325 } else {
2326 float exp = ZIN0(2);
2327 unit->m_rootmul = pow(ZIN0(1), exp);
2328 unit->m_exponent = -1.f * exp;
2329 SETCALC(AmpComp_next);
2331 AmpComp_next(unit, 1);
2335 //////////////////////////////////////////////////////////////////////////////////////////////////
2337 const double AMPCOMP_K = 3.5041384 * 10e15;
2338 const double AMPCOMP_C1 = 20.598997 * 20.598997;
2339 const double AMPCOMP_C2 = 107.65265 * 107.65265;
2340 const double AMPCOMP_C3 = 737.86223 * 737.86223;
2341 const double AMPCOMP_C4 = 12194.217 * 12194.217;
2342 const double AMPCOMP_MINLEVEL = -0.1575371167435;
2344 double AmpCompA_calcLevel(double freq)
2346 double r = freq * freq;
2347 double level = (AMPCOMP_K * r * r * r * r);
2348 double n1 = AMPCOMP_C1 + r;
2349 double n2 = AMPCOMP_C4 + r;
2350 level = level / (
2351 n1 * n1 *
2352 (AMPCOMP_C2 + r) *
2353 (AMPCOMP_C3 + r) *
2354 n2 * n2
2356 level = 1. - sqrt(level);
2357 return level;
2360 void AmpCompA_next(AmpCompA *unit, int inNumSamples)
2362 float *out = ZOUT(0);
2363 float *freq = ZIN(0);
2365 double scale = unit->m_scale;
2366 double offset = unit->m_offset;
2368 LOOP1(inNumSamples,
2369 ZXP(out) = AmpCompA_calcLevel(ZXP(freq)) * scale + offset;
2373 void AmpCompA_Ctor(AmpCompA* unit)
2375 double rootFreq = ZIN0(1);
2376 double rootLevel = AmpCompA_calcLevel(rootFreq);
2377 float minLevel = ZIN0(2);
2378 unit->m_scale = (ZIN0(3) - minLevel) / (rootLevel - AMPCOMP_MINLEVEL);
2379 unit->m_offset = minLevel - unit->m_scale * AMPCOMP_MINLEVEL;
2381 SETCALC(AmpCompA_next);
2382 AmpCompA_next(unit, 1);
2385 //////////////////////////////////////////////////////////////////////////////////////////////////
2387 void InRange_next(InRange *unit, int inNumSamples)
2389 float *out = ZOUT(0);
2390 float *in = ZIN(0);
2391 float lo = ZIN0(1);
2392 float hi = ZIN0(2);
2394 LOOP1(inNumSamples,
2395 float zin = ZXP(in);
2396 ZXP(out) = zin >= lo && zin <= hi ? 1.f : 0.f;
2400 void InRange_Ctor(InRange* unit)
2402 SETCALC(InRange_next);
2403 InRange_next(unit, 1);
2406 //////////////////////////////////////////////////////////////////////////////////////////////////
2408 void InRect_next(InRect* unit, int inNumSamples)
2410 float *out = ZOUT(0);
2411 float *inx = ZIN(0);
2412 float *iny = ZIN(1);
2413 float left = ZIN0(2);
2414 float top = ZIN0(3);
2415 float right = ZIN0(4);
2416 float bottom = ZIN0(5);
2418 LOOP1(inNumSamples,
2419 float x = ZXP(inx);
2420 float y = ZXP(iny);
2421 ZXP(out) = x >= left && x <= right && y >= top && y <= bottom ? 1.f : 0.f;
2425 void InRect_Ctor(InRect* unit)
2427 SETCALC(InRect_next);
2428 InRect_next(unit, 1);
2431 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2433 void LinExp_next(LinExp *unit, int inNumSamples)
2435 float *out = ZOUT(0);
2436 float *in = ZIN(0);
2437 float dstlo = unit->m_dstlo;
2439 float dstratio = unit->m_dstratio;
2440 float rsrcrange = unit->m_rsrcrange;
2441 float rrminuslo = unit->m_rrminuslo;
2443 LOOP1(inNumSamples,
2444 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2448 #ifdef NOVA_SIMD
2449 static inline void LinExp_next_nova_loop(float * out, const float * in, int inNumSamples,
2450 nova::vec<float> dstlo, nova::vec<float> dstratio,
2451 nova::vec<float> rsrcrange, nova::vec<float> rrminuslo)
2453 const int vecSize = nova::vec<float>::size;
2454 int unroll = inNumSamples / (2*vecSize);
2458 nova::vec<float> val0, val1;
2459 val0.load_aligned(in);
2460 val1.load_aligned(in + vecSize);
2462 val0 = dstlo * pow(dstratio, val0 * rsrcrange + rrminuslo);
2463 val1 = dstlo * pow(dstratio, val1 * rsrcrange + rrminuslo);
2465 val0.store_aligned(out);
2466 val1.store_aligned(out + vecSize);
2468 in += 2*vecSize;
2469 out += 2*vecSize;
2470 } while (--unroll);
2473 static void LinExp_next_nova(LinExp *unit, int inNumSamples)
2475 float *out = OUT(0);
2476 float *in = IN(0);
2478 LinExp_next_nova_loop(out, in, inNumSamples, unit->m_dstlo, unit->m_dstratio, unit->m_rsrcrange, unit->m_rrminuslo);
2481 static void LinExp_next_nova_kk(LinExp *unit, int inNumSamples)
2483 float *out = OUT(0);
2484 float *in = IN(0);
2486 float srclo = ZIN0(1);
2487 float srchi = ZIN0(2);
2488 float dstlo = ZIN0(3);
2489 float dsthi = ZIN0(4);
2490 float dstratio = dsthi/dstlo;
2491 float rsrcrange = 1. / (srchi - srclo);
2492 float rrminuslo = rsrcrange * -srclo;
2494 LinExp_next_nova_loop(out, in, inNumSamples, dstlo, dstratio, rsrcrange, rrminuslo);
2497 #endif
2499 void LinExp_next_kk(LinExp *unit, int inNumSamples)
2501 float *out = ZOUT(0);
2502 float *in = ZIN(0);
2503 float srclo = ZIN0(1);
2504 float srchi = ZIN0(2);
2505 float dstlo = ZIN0(3);
2506 float dsthi = ZIN0(4);
2507 float dstratio = dsthi/dstlo;
2508 float rsrcrange = 1. / (srchi - srclo);
2509 float rrminuslo = rsrcrange * -srclo;
2511 LOOP1(inNumSamples,
2512 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2516 void LinExp_next_aa(LinExp *unit, int inNumSamples)
2518 float *out = ZOUT(0);
2519 float *in = ZIN(0);
2520 float *srclo = ZIN(1);
2521 float *srchi = ZIN(2);
2522 float *dstlo = ZIN(3);
2523 float *dsthi = ZIN(4);
2526 LOOP1(inNumSamples,
2527 float zdsthi = ZXP(dsthi);
2528 float zdstlo = ZXP(dstlo);
2529 float zsrchi = ZXP(srchi);
2530 float zsrclo = ZXP(srclo);
2531 float dstratio = zdsthi/zdstlo;
2532 float rsrcrange = 1. / (zsrchi - zsrclo);
2533 float rrminuslo = rsrcrange * -zsrclo;
2534 ZXP(out) = zdstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2538 void LinExp_next_ak(LinExp *unit, int inNumSamples)
2540 float *out = ZOUT(0);
2541 float *in = ZIN(0);
2542 float *srclo = ZIN(1);
2543 float *srchi = ZIN(2);
2544 float dstlo = ZIN0(3);
2545 float dsthi = ZIN0(4);
2546 float dstratio = dsthi/dstlo;
2548 LOOP1(inNumSamples,
2549 float zsrchi = ZXP(srchi);
2550 float zsrclo = ZXP(srclo);
2552 float rsrcrange = 1. / (zsrchi - zsrclo);
2553 float rrminuslo = rsrcrange * -zsrclo;
2554 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2558 void LinExp_next_ka(LinExp *unit, int inNumSamples)
2560 float *out = ZOUT(0);
2561 float *in = ZIN(0);
2562 float srclo = ZIN0(1);
2563 float srchi = ZIN0(2);
2564 float *dstlo = ZIN(3);
2565 float *dsthi = ZIN(4);
2566 float rsrcrange = 1. / (srchi - srclo);
2567 float rrminuslo = rsrcrange * -srclo;
2569 LOOP1(inNumSamples,
2570 float zdsthi = ZXP(dsthi);
2571 float zdstlo = ZXP(dstlo);
2572 float dstratio = zdsthi/zdstlo;
2573 ZXP(out) = zdstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2578 static void LinExp_SetCalc(LinExp* unit)
2580 if(INRATE(1) == calc_FullRate || INRATE(2) == calc_FullRate) {
2581 if(INRATE(3) == calc_FullRate || INRATE(4) == calc_FullRate) {
2582 SETCALC(LinExp_next_aa); return;
2583 } else {
2584 SETCALC(LinExp_next_ak); return;
2586 } else {
2587 if(INRATE(3) == calc_FullRate || INRATE(4) == calc_FullRate) {
2588 SETCALC(LinExp_next_ka); return;
2592 bool allScalar = true;
2593 for(int i = 1; i<5; i++) {
2594 if(INRATE(i) != calc_ScalarRate) {
2595 allScalar = false;
2596 break;
2600 #ifdef NOVA_SIMD
2601 if ((BUFLENGTH % (2*nova::vec<float>::size)) == 0)
2602 if (allScalar)
2603 SETCALC(LinExp_next_nova);
2604 else
2605 SETCALC(LinExp_next_nova_kk);
2606 else
2607 #endif
2608 if (allScalar)
2609 SETCALC(LinExp_next);
2610 else
2611 SETCALC(LinExp_next_kk);
2613 if (!allScalar)
2614 return;
2616 float srclo = ZIN0(1);
2617 float srchi = ZIN0(2);
2618 float dstlo = ZIN0(3);
2619 float dsthi = ZIN0(4);
2620 unit->m_dstlo = dstlo;
2621 unit->m_dstratio = dsthi/dstlo;
2622 unit->m_rsrcrange = 1. / (srchi - srclo);
2623 unit->m_rrminuslo = unit->m_rsrcrange * -srclo;
2626 void LinExp_Ctor(LinExp* unit)
2628 LinExp_SetCalc(unit);
2629 float srclo = ZIN0(1);
2630 float srchi = ZIN0(2);
2631 float dstlo = ZIN0(3);
2632 float dsthi = ZIN0(4);
2633 unit->m_dstlo = dstlo;
2634 unit->m_dstratio = dsthi/dstlo;
2635 unit->m_rsrcrange = 1. / (srchi - srclo);
2636 unit->m_rrminuslo = unit->m_rsrcrange * -srclo;
2637 LinExp_next(unit, 1);
2640 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2643 enum {
2644 kEnvGen_gate,
2645 kEnvGen_levelScale,
2646 kEnvGen_levelBias,
2647 kEnvGen_timeScale,
2648 kEnvGen_doneAction,
2649 kEnvGen_initLevel,
2650 kEnvGen_numStages,
2651 kEnvGen_releaseNode,
2652 kEnvGen_loopNode,
2653 // 'kEnvGen_nodeOffset' must always be last
2654 // if you need to add an arg, put it before this one
2655 kEnvGen_nodeOffset
2658 #ifdef NOVA_SIMD
2659 void EnvGen_next_ak_nova(EnvGen *unit, int inNumSamples);
2660 #endif
2662 void EnvGen_Ctor(EnvGen *unit)
2664 //Print("EnvGen_Ctor A\n");
2665 if (unit->mCalcRate == calc_FullRate) {
2666 if (INRATE(0) == calc_FullRate) {
2667 SETCALC(EnvGen_next_aa);
2668 } else {
2669 #ifdef NOVA_SIMD
2670 if (!(BUFLENGTH & 15))
2671 SETCALC(EnvGen_next_ak_nova);
2672 else
2673 #endif
2674 SETCALC(EnvGen_next_ak);
2676 } else {
2677 SETCALC(EnvGen_next_k);
2680 // gate = 1.0, levelScale = 1.0, levelBias = 0.0, timeScale
2681 // level0, numstages, releaseNode, loopNode,
2682 // [level, dur, shape, curve]
2684 unit->m_endLevel = unit->m_level = ZIN0(kEnvGen_initLevel) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2685 unit->m_counter = 0;
2686 unit->m_stage = 1000000000;
2687 unit->m_prevGate = 0.f;
2688 unit->m_released = false;
2689 unit->m_releaseNode = (int)ZIN0(kEnvGen_releaseNode);
2690 EnvGen_next_k(unit, 1);
2693 enum {
2694 shape_Step,
2695 shape_Linear,
2696 shape_Exponential,
2697 shape_Sine,
2698 shape_Welch,
2699 shape_Curve,
2700 shape_Squared,
2701 shape_Cubed,
2702 shape_Sustain = 9999
2705 void EnvGen_next_k(EnvGen *unit, int inNumSamples)
2707 float *out = OUT(0);
2708 float gate = ZIN0(kEnvGen_gate);
2709 //Print("->EnvGen_next_k gate %g\n", gate);
2710 int counter = unit->m_counter;
2711 double level = unit->m_level;
2713 if (unit->m_prevGate <= 0. && gate > 0.) {
2714 unit->m_stage = -1;
2715 unit->mDone = false;
2716 unit->m_released = false;
2717 counter = 0;
2718 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
2719 // cutoff
2720 int numstages = (int)ZIN0(kEnvGen_numStages);
2721 float dur = -gate - 1.f;
2722 counter = (int32)(dur * SAMPLERATE);
2723 counter = sc_max(1, counter);
2724 unit->m_stage = numstages;
2725 unit->m_shape = shape_Linear;
2726 // first ZIN0 gets the last envelope node's level, then apply levelScale and levelBias
2727 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2728 unit->m_grow = (unit->m_endLevel - level) / counter;
2729 } else if (unit->m_prevGate > 0.f && gate <= 0.f
2730 && unit->m_releaseNode >= 0 && !unit->m_released) {
2731 counter = 0;
2732 unit->m_stage = unit->m_releaseNode - 1;
2733 unit->m_released = true;
2735 unit->m_prevGate = gate;
2738 // gate = 1.0, levelScale = 1.0, levelBias = 0.0, timeScale
2739 // level0, numstages, releaseNode, loopNode,
2740 // [level, dur, shape, curve]
2742 if (counter <= 0) {
2743 //Print("stage %d rel %d\n", unit->m_stage, (int)ZIN0(kEnvGen_releaseNode));
2744 int numstages = (int)ZIN0(kEnvGen_numStages);
2746 //Print("stage %d numstages %d\n", unit->m_stage, numstages);
2747 if (unit->m_stage+1 >= numstages) { // num stages
2748 //Print("stage+1 > num stages\n");
2749 counter = INT_MAX;
2750 unit->m_shape = 0;
2751 level = unit->m_endLevel;
2752 unit->mDone = true;
2753 int doneAction = (int)ZIN0(kEnvGen_doneAction);
2754 DoneAction(doneAction, unit);
2755 } else if (unit->m_stage+1 == unit->m_releaseNode && !unit->m_released) { // sustain stage
2756 int loopNode = (int)ZIN0(kEnvGen_loopNode);
2757 if (loopNode >= 0 && loopNode < numstages) {
2758 unit->m_stage = loopNode;
2759 goto initSegment;
2760 } else {
2761 counter = INT_MAX;
2762 unit->m_shape = shape_Sustain;
2763 level = unit->m_endLevel;
2765 //Print("sustain\n");
2766 } else {
2767 unit->m_stage++;
2768 initSegment:
2769 //Print("stage %d\n", unit->m_stage);
2770 //Print("initSegment\n");
2771 //out = unit->m_level;
2772 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
2774 if (stageOffset + 4 > unit->mNumInputs) {
2775 // oops.
2776 Print("envelope went past end of inputs.\n");
2777 ClearUnitOutputs(unit, 1);
2778 NodeEnd(&unit->mParent->mNode);
2779 return;
2782 float** envPtr = unit->mInBuf + stageOffset;
2783 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
2784 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
2785 unit->m_shape = (int32)*envPtr[2];
2786 double curve = *envPtr[3];
2787 unit->m_endLevel = endLevel;
2789 counter = (int32)(dur * SAMPLERATE);
2790 counter = sc_max(1, counter);
2791 //Print("stageOffset %d level %g endLevel %g dur %g shape %d curve %g\n", stageOffset, level, endLevel, dur, unit->m_shape, curve);
2792 //Print("SAMPLERATE %g\n", SAMPLERATE);
2793 if (counter == 1) unit->m_shape = 1; // shape_Linear
2794 //Print("new counter = %d shape = %d\n", counter, unit->m_shape);
2795 switch (unit->m_shape) {
2796 case shape_Step : {
2797 level = endLevel;
2798 } break;
2799 case shape_Linear : {
2800 unit->m_grow = (endLevel - level) / counter;
2801 //Print("grow %g\n", unit->m_grow);
2802 } break;
2803 case shape_Exponential : {
2804 unit->m_grow = pow(endLevel / level, 1.0 / counter);
2805 } break;
2806 case shape_Sine : {
2807 double w = pi / counter;
2809 unit->m_a2 = (endLevel + level) * 0.5;
2810 unit->m_b1 = 2. * cos(w);
2811 unit->m_y1 = (endLevel - level) * 0.5;
2812 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
2813 level = unit->m_a2 - unit->m_y1;
2814 } break;
2815 case shape_Welch : {
2816 double w = (pi * 0.5) / counter;
2818 unit->m_b1 = 2. * cos(w);
2820 if (endLevel >= level) {
2821 unit->m_a2 = level;
2822 unit->m_y1 = 0.;
2823 unit->m_y2 = -sin(w) * (endLevel - level);
2824 } else {
2825 unit->m_a2 = endLevel;
2826 unit->m_y1 = level - endLevel;
2827 unit->m_y2 = cos(w) * (level - endLevel);
2829 level = unit->m_a2 + unit->m_y1;
2830 } break;
2831 case shape_Curve : {
2832 if (fabs(curve) < 0.001) {
2833 unit->m_shape = 1; // shape_Linear
2834 unit->m_grow = (endLevel - level) / counter;
2835 } else {
2836 double a1 = (endLevel - level) / (1.0 - exp(curve));
2837 unit->m_a2 = level + a1;
2838 unit->m_b1 = a1;
2839 unit->m_grow = exp(curve / counter);
2841 } break;
2842 case shape_Squared : {
2843 unit->m_y1 = sqrt(level);
2844 unit->m_y2 = sqrt(endLevel);
2845 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2846 } break;
2847 case shape_Cubed : {
2848 unit->m_y1 = pow(level, 0.33333333);
2849 unit->m_y2 = pow(endLevel, 0.33333333);
2850 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2851 } break;
2857 switch (unit->m_shape) {
2858 case shape_Step : {
2859 } break;
2860 case shape_Linear : {
2861 double grow = unit->m_grow;
2862 //Print("level %g\n", level);
2863 level += grow;
2864 } break;
2865 case shape_Exponential : {
2866 double grow = unit->m_grow;
2867 level *= grow;
2868 } break;
2869 case shape_Sine : {
2870 double a2 = unit->m_a2;
2871 double b1 = unit->m_b1;
2872 double y2 = unit->m_y2;
2873 double y1 = unit->m_y1;
2874 double y0 = b1 * y1 - y2;
2875 level = a2 - y0;
2876 y2 = y1;
2877 y1 = y0;
2878 unit->m_y1 = y1;
2879 unit->m_y2 = y2;
2880 } break;
2881 case shape_Welch : {
2882 double a2 = unit->m_a2;
2883 double b1 = unit->m_b1;
2884 double y2 = unit->m_y2;
2885 double y1 = unit->m_y1;
2886 double y0 = b1 * y1 - y2;
2887 level = a2 + y0;
2888 y2 = y1;
2889 y1 = y0;
2890 unit->m_y1 = y1;
2891 unit->m_y2 = y2;
2892 } break;
2893 case shape_Curve : {
2894 double a2 = unit->m_a2;
2895 double b1 = unit->m_b1;
2896 double grow = unit->m_grow;
2897 b1 *= grow;
2898 level = a2 - b1;
2899 unit->m_b1 = b1;
2900 } break;
2901 case shape_Squared : {
2902 double grow = unit->m_grow;
2903 double y1 = unit->m_y1;
2904 y1 += grow;
2905 level = y1*y1;
2906 unit->m_y1 = y1;
2907 } break;
2908 case shape_Cubed : {
2909 double grow = unit->m_grow;
2910 double y1 = unit->m_y1;
2911 y1 += grow;
2912 level = y1*y1*y1;
2913 unit->m_y1 = y1;
2914 } break;
2915 case shape_Sustain : {
2916 } break;
2918 *out = level;
2919 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, *out);
2920 unit->m_level = level;
2921 unit->m_counter = counter - 1;
2925 void EnvGen_next_ak(EnvGen *unit, int inNumSamples)
2927 float *out = ZOUT(0);
2928 float gate = ZIN0(kEnvGen_gate);
2929 int counter = unit->m_counter;
2930 double level = unit->m_level;
2932 if (unit->m_prevGate <= 0. && gate > 0.) {
2933 unit->m_stage = -1;
2934 unit->mDone = false;
2935 unit->m_released = false;
2936 counter = 0;
2937 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
2938 // cutoff
2939 int numstages = (int)ZIN0(kEnvGen_numStages);
2940 float dur = -gate - 1.f;
2941 counter = (int32)(dur * SAMPLERATE);
2942 counter = sc_max(1, counter);
2943 unit->m_stage = numstages;
2944 unit->m_shape = shape_Linear;
2945 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2946 unit->m_grow = (unit->m_endLevel - level) / counter;
2947 } else if (unit->m_prevGate > 0.f && gate <= 0.f
2948 && unit->m_releaseNode >= 0 && !unit->m_released) {
2949 counter = 0;
2950 unit->m_stage = unit->m_releaseNode - 1;
2951 unit->m_released = true;
2953 unit->m_prevGate = gate;
2955 int remain = inNumSamples;
2956 while (remain)
2958 if (counter == 0) {
2959 int numstages = (int)ZIN0(kEnvGen_numStages);
2961 if (unit->m_stage+1 >= numstages) { // num stages
2962 counter = INT_MAX;
2963 unit->m_shape = 0;
2964 level = unit->m_endLevel;
2965 unit->mDone = true;
2966 int doneAction = (int)ZIN0(kEnvGen_doneAction);
2967 DoneAction(doneAction, unit);
2968 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
2969 int loopNode = (int)ZIN0(kEnvGen_loopNode);
2970 if (loopNode >= 0 && loopNode < numstages) {
2971 unit->m_stage = loopNode;
2972 goto initSegment;
2973 } else {
2974 counter = INT_MAX;
2975 unit->m_shape = shape_Sustain;
2976 level = unit->m_endLevel;
2978 } else {
2979 unit->m_stage++;
2980 initSegment:
2981 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
2983 if (stageOffset + 4 > unit->mNumInputs) {
2984 // oops.
2985 Print("envelope went past end of inputs.\n");
2986 ClearUnitOutputs(unit, 1);
2987 NodeEnd(&unit->mParent->mNode);
2988 return;
2991 float** envPtr = unit->mInBuf + stageOffset;
2992 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
2993 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
2994 unit->m_shape = (int32)*envPtr[2];
2995 double curve = *envPtr[3];
2996 unit->m_endLevel = endLevel;
2998 counter = (int32)(dur * SAMPLERATE);
2999 counter = sc_max(1, counter);
3001 if (counter == 1) unit->m_shape = 1; // shape_Linear
3002 switch (unit->m_shape) {
3003 case shape_Step : {
3004 level = endLevel;
3005 } break;
3006 case shape_Linear : {
3007 unit->m_grow = (endLevel - level) / counter;
3008 } break;
3009 case shape_Exponential : {
3010 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3011 } break;
3012 case shape_Sine : {
3013 double w = pi / counter;
3015 unit->m_a2 = (endLevel + level) * 0.5;
3016 unit->m_b1 = 2. * cos(w);
3017 unit->m_y1 = (endLevel - level) * 0.5;
3018 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3019 level = unit->m_a2 - unit->m_y1;
3020 } break;
3021 case shape_Welch : {
3022 double w = (pi * 0.5) / counter;
3024 unit->m_b1 = 2. * cos(w);
3026 if (endLevel >= level) {
3027 unit->m_a2 = level;
3028 unit->m_y1 = 0.;
3029 unit->m_y2 = -sin(w) * (endLevel - level);
3030 } else {
3031 unit->m_a2 = endLevel;
3032 unit->m_y1 = level - endLevel;
3033 unit->m_y2 = cos(w) * (level - endLevel);
3035 level = unit->m_a2 + unit->m_y1;
3036 } break;
3037 case shape_Curve : {
3038 if (fabs(curve) < 0.001) {
3039 unit->m_shape = 1; // shape_Linear
3040 unit->m_grow = (endLevel - level) / counter;
3041 } else {
3042 double a1 = (endLevel - level) / (1.0 - exp(curve));
3043 unit->m_a2 = level + a1;
3044 unit->m_b1 = a1;
3045 unit->m_grow = exp(curve / counter);
3047 } break;
3048 case shape_Squared : {
3049 unit->m_y1 = sqrt(level);
3050 unit->m_y2 = sqrt(endLevel);
3051 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3052 } break;
3053 case shape_Cubed : {
3054 unit->m_y1 = pow(level, 0.33333333);
3055 unit->m_y2 = pow(endLevel, 0.33333333);
3056 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3057 } break;
3062 int nsmps = sc_min(remain, counter);
3063 switch (unit->m_shape) {
3064 case shape_Step : {
3065 for (int i=0; i<nsmps; ++i) {
3066 ZXP(out) = level;
3068 } break;
3069 case shape_Linear : {
3070 double grow = unit->m_grow;
3071 for (int i=0; i<nsmps; ++i) {
3072 ZXP(out) = level;
3073 level += grow;
3075 } break;
3076 case shape_Exponential : {
3077 double grow = unit->m_grow;
3078 for (int i=0; i<nsmps; ++i) {
3079 ZXP(out) = level;
3080 level *= grow;
3082 } break;
3083 case shape_Sine : {
3084 double a2 = unit->m_a2;
3085 double b1 = unit->m_b1;
3086 double y2 = unit->m_y2;
3087 double y1 = unit->m_y1;
3088 for (int i=0; i<nsmps; ++i) {
3089 ZXP(out) = level;
3090 double y0 = b1 * y1 - y2;
3091 level = a2 - y0;
3092 y2 = y1;
3093 y1 = y0;
3095 unit->m_y1 = y1;
3096 unit->m_y2 = y2;
3097 } break;
3098 case shape_Welch : {
3099 double a2 = unit->m_a2;
3100 double b1 = unit->m_b1;
3101 double y2 = unit->m_y2;
3102 double y1 = unit->m_y1;
3103 for (int i=0; i<nsmps; ++i) {
3104 ZXP(out) = level;
3105 double y0 = b1 * y1 - y2;
3106 level = a2 + y0;
3107 y2 = y1;
3108 y1 = y0;
3110 unit->m_y1 = y1;
3111 unit->m_y2 = y2;
3112 } break;
3113 case shape_Curve : {
3114 double a2 = unit->m_a2;
3115 double b1 = unit->m_b1;
3116 double grow = unit->m_grow;
3117 for (int i=0; i<nsmps; ++i) {
3118 ZXP(out) = level;
3119 b1 *= grow;
3120 level = a2 - b1;
3122 unit->m_b1 = b1;
3123 } break;
3124 case shape_Squared : {
3125 double grow = unit->m_grow;
3126 double y1 = unit->m_y1;
3127 for (int i=0; i<nsmps; ++i) {
3128 ZXP(out) = level;
3129 y1 += grow;
3130 level = y1*y1;
3132 unit->m_y1 = y1;
3133 } break;
3134 case shape_Cubed : {
3135 double grow = unit->m_grow;
3136 double y1 = unit->m_y1;
3137 for (int i=0; i<nsmps; ++i) {
3138 ZXP(out) = level;
3139 y1 += grow;
3140 level = y1*y1*y1;
3142 unit->m_y1 = y1;
3143 } break;
3144 case shape_Sustain : {
3145 for (int i=0; i<nsmps; ++i) {
3146 ZXP(out) = level;
3148 } break;
3150 remain -= nsmps;
3151 counter -= nsmps;
3153 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, ZOUT0(0));
3154 unit->m_level = level;
3155 unit->m_counter = counter;
3159 #ifdef NOVA_SIMD
3160 inline_functions void EnvGen_next_ak_nova(EnvGen *unit, int inNumSamples)
3162 float *out = ZOUT(0);
3163 float gate = ZIN0(kEnvGen_gate);
3164 int counter = unit->m_counter;
3165 double level = unit->m_level;
3167 if (unit->m_prevGate <= 0. && gate > 0.) {
3168 unit->m_stage = -1;
3169 unit->mDone = false;
3170 unit->m_released = false;
3171 counter = 0;
3172 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
3173 // cutoff
3174 int numstages = (int)ZIN0(kEnvGen_numStages);
3175 float dur = -gate - 1.f;
3176 counter = (int32)(dur * SAMPLERATE);
3177 counter = sc_max(1, counter);
3178 unit->m_stage = numstages;
3179 unit->m_shape = shape_Linear;
3180 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
3181 unit->m_grow = (unit->m_endLevel - level) / counter;
3182 } else if (unit->m_prevGate > 0.f && gate <= 0.f
3183 && unit->m_releaseNode >= 0 && !unit->m_released) {
3184 counter = 0;
3185 unit->m_stage = unit->m_releaseNode - 1;
3186 unit->m_released = true;
3188 unit->m_prevGate = gate;
3190 int remain = inNumSamples;
3191 if (counter > inNumSamples)
3193 switch (unit->m_shape) {
3194 case shape_Step :
3195 case shape_Sustain :
3196 nova::setvec_simd(OUT(0), (float)level, inNumSamples);
3197 remain = 0;
3198 counter -= inNumSamples;
3199 break;
3200 case shape_Linear : {
3201 double slope = unit->m_grow;
3202 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, inNumSamples);
3203 level += 64 * slope;
3204 remain = 0;
3205 counter -= inNumSamples;
3206 } break;
3207 case shape_Exponential : {
3208 double grow = unit->m_grow;
3209 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, inNumSamples);
3210 level *= sc_powi(grow, inNumSamples);
3211 remain = 0;
3212 counter -= inNumSamples;
3213 } break;
3217 while (remain)
3219 if (counter == 0) {
3220 int numstages = (int)ZIN0(kEnvGen_numStages);
3222 if (unit->m_stage+1 >= numstages) { // num stages
3223 counter = INT_MAX;
3224 unit->m_shape = 0;
3225 level = unit->m_endLevel;
3226 unit->mDone = true;
3227 int doneAction = (int)ZIN0(kEnvGen_doneAction);
3228 DoneAction(doneAction, unit);
3229 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
3230 int loopNode = (int)ZIN0(kEnvGen_loopNode);
3231 if (loopNode >= 0 && loopNode < numstages) {
3232 unit->m_stage = loopNode;
3233 goto initSegment;
3234 } else {
3235 counter = INT_MAX;
3236 unit->m_shape = shape_Sustain;
3237 level = unit->m_endLevel;
3239 } else {
3240 unit->m_stage++;
3241 initSegment:
3242 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
3244 if (stageOffset + 4 > unit->mNumInputs) {
3245 // oops.
3246 Print("envelope went past end of inputs.\n");
3247 ClearUnitOutputs(unit, 1);
3248 NodeEnd(&unit->mParent->mNode);
3249 return;
3252 float** envPtr = unit->mInBuf + stageOffset;
3253 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
3254 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
3255 unit->m_shape = (int32)*envPtr[2];
3256 double curve = *envPtr[3];
3257 unit->m_endLevel = endLevel;
3259 counter = (int32)(dur * SAMPLERATE);
3260 counter = sc_max(1, counter);
3262 if (counter == 1) unit->m_shape = 1; // shape_Linear
3263 switch (unit->m_shape) {
3264 case shape_Step : {
3265 level = endLevel;
3266 } break;
3267 case shape_Linear : {
3268 unit->m_grow = (endLevel - level) / counter;
3269 } break;
3270 case shape_Exponential : {
3271 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3272 } break;
3273 case shape_Sine : {
3274 double w = pi / counter;
3276 unit->m_a2 = (endLevel + level) * 0.5;
3277 unit->m_b1 = 2. * cos(w);
3278 unit->m_y1 = (endLevel - level) * 0.5;
3279 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3280 level = unit->m_a2 - unit->m_y1;
3281 } break;
3282 case shape_Welch : {
3283 double w = (pi * 0.5) / counter;
3285 unit->m_b1 = 2. * cos(w);
3287 if (endLevel >= level) {
3288 unit->m_a2 = level;
3289 unit->m_y1 = 0.;
3290 unit->m_y2 = -sin(w) * (endLevel - level);
3291 } else {
3292 unit->m_a2 = endLevel;
3293 unit->m_y1 = level - endLevel;
3294 unit->m_y2 = cos(w) * (level - endLevel);
3296 level = unit->m_a2 + unit->m_y1;
3297 } break;
3298 case shape_Curve : {
3299 if (fabs(curve) < 0.001) {
3300 unit->m_shape = 1; // shape_Linear
3301 unit->m_grow = (endLevel - level) / counter;
3302 } else {
3303 double a1 = (endLevel - level) / (1.0 - exp(curve));
3304 unit->m_a2 = level + a1;
3305 unit->m_b1 = a1;
3306 unit->m_grow = exp(curve / counter);
3308 } break;
3309 case shape_Squared : {
3310 unit->m_y1 = sqrt(level);
3311 unit->m_y2 = sqrt(endLevel);
3312 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3313 } break;
3314 case shape_Cubed : {
3315 unit->m_y1 = pow(level, 0.33333333);
3316 unit->m_y2 = pow(endLevel, 0.33333333);
3317 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3318 } break;
3323 int nsmps = sc_min(remain, counter);
3324 switch (unit->m_shape) {
3325 case shape_Step : {
3326 for (int i=0; i<nsmps; ++i) {
3327 ZXP(out) = level;
3329 } break;
3330 case shape_Linear : {
3331 double grow = unit->m_grow;
3332 for (int i=0; i<nsmps; ++i) {
3333 ZXP(out) = level;
3334 level += grow;
3336 } break;
3337 case shape_Exponential : {
3338 double grow = unit->m_grow;
3339 for (int i=0; i<nsmps; ++i) {
3340 ZXP(out) = level;
3341 level *= grow;
3343 } break;
3344 case shape_Sine : {
3345 double a2 = unit->m_a2;
3346 double b1 = unit->m_b1;
3347 double y2 = unit->m_y2;
3348 double y1 = unit->m_y1;
3349 for (int i=0; i<nsmps; ++i) {
3350 ZXP(out) = level;
3351 double y0 = b1 * y1 - y2;
3352 level = a2 - y0;
3353 y2 = y1;
3354 y1 = y0;
3356 unit->m_y1 = y1;
3357 unit->m_y2 = y2;
3358 } break;
3359 case shape_Welch : {
3360 double a2 = unit->m_a2;
3361 double b1 = unit->m_b1;
3362 double y2 = unit->m_y2;
3363 double y1 = unit->m_y1;
3364 for (int i=0; i<nsmps; ++i) {
3365 ZXP(out) = level;
3366 double y0 = b1 * y1 - y2;
3367 level = a2 + y0;
3368 y2 = y1;
3369 y1 = y0;
3371 unit->m_y1 = y1;
3372 unit->m_y2 = y2;
3373 } break;
3374 case shape_Curve : {
3375 double a2 = unit->m_a2;
3376 double b1 = unit->m_b1;
3377 double grow = unit->m_grow;
3378 for (int i=0; i<nsmps; ++i) {
3379 ZXP(out) = level;
3380 b1 *= grow;
3381 level = a2 - b1;
3383 unit->m_b1 = b1;
3384 } break;
3385 case shape_Squared : {
3386 double grow = unit->m_grow;
3387 double y1 = unit->m_y1;
3388 for (int i=0; i<nsmps; ++i) {
3389 ZXP(out) = level;
3390 y1 += grow;
3391 level = y1*y1;
3393 unit->m_y1 = y1;
3394 } break;
3395 case shape_Cubed : {
3396 double grow = unit->m_grow;
3397 double y1 = unit->m_y1;
3398 for (int i=0; i<nsmps; ++i) {
3399 ZXP(out) = level;
3400 y1 += grow;
3401 level = y1*y1*y1;
3403 unit->m_y1 = y1;
3404 } break;
3405 case shape_Sustain : {
3406 for (int i=0; i<nsmps; ++i) {
3407 ZXP(out) = level;
3409 } break;
3411 remain -= nsmps;
3412 counter -= nsmps;
3414 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, ZOUT0(0));
3415 unit->m_level = level;
3416 unit->m_counter = counter;
3419 #endif
3421 #define CHECK_GATE \
3422 prevGate = gate; \
3423 gate = ZXP(gatein); \
3424 if (prevGate <= 0.f && gate > 0.f) { \
3425 gatein--; \
3426 unit->m_stage = -1; \
3427 unit->m_released = false; \
3428 unit->mDone = false; \
3429 counter = i; \
3430 nsmps = i; \
3431 break; \
3432 } else if (gate <= -1.f && unit->m_prevGate > -1.f) { \
3433 int numstages = (int)ZIN0(kEnvGen_numStages); \
3434 float dur = -gate - 1.f; \
3435 gatein--; \
3436 counter = (int32)(dur * SAMPLERATE); \
3437 counter = sc_max(1, counter) + i; \
3438 unit->m_stage = numstages; \
3439 unit->m_shape = shape_Linear; \
3440 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); \
3441 unit->m_grow = (unit->m_endLevel - level) / counter; \
3442 nsmps = i; \
3443 break; \
3444 } else if (prevGate > 0.f && gate <= 0.f \
3445 && unit->m_releaseNode >= 0 && !unit->m_released) { \
3446 gatein--; \
3447 counter = i; \
3448 unit->m_stage = unit->m_releaseNode - 1; \
3449 unit->m_released = true; \
3450 nsmps = i; \
3451 break; \
3455 void EnvGen_next_aa(EnvGen *unit, int inNumSamples)
3457 float *out = ZOUT(0);
3458 float *gatein = ZIN(kEnvGen_gate);
3459 int counter = unit->m_counter;
3460 double level = unit->m_level;
3461 float gate = 0.;
3462 float prevGate = unit->m_prevGate;
3463 int remain = inNumSamples;
3464 while (remain)
3466 if (counter == 0) {
3468 int numstages = (int)ZIN0(kEnvGen_numStages);
3470 if (unit->m_stage+1 >= numstages) { // num stages
3471 counter = INT_MAX;
3472 unit->m_shape = 0;
3473 level = unit->m_endLevel;
3474 unit->mDone = true;
3475 int doneAction = (int)ZIN0(kEnvGen_doneAction);
3476 DoneAction(doneAction, unit);
3477 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
3478 int loopNode = (int)ZIN0(kEnvGen_loopNode);
3479 if (loopNode >= 0 && loopNode < numstages) {
3480 unit->m_stage = loopNode;
3481 goto initSegment;
3482 } else {
3483 counter = INT_MAX;
3484 unit->m_shape = shape_Sustain;
3485 level = unit->m_endLevel;
3487 } else {
3488 unit->m_stage++;
3489 initSegment:
3490 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
3492 if (stageOffset + 4 > unit->mNumInputs) {
3493 // oops.
3494 Print("envelope went past end of inputs.\n");
3495 ClearUnitOutputs(unit, 1);
3496 NodeEnd(&unit->mParent->mNode);
3497 return;
3500 float** envPtr = unit->mInBuf + stageOffset;
3501 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
3502 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
3503 unit->m_shape = (int32)*envPtr[2];
3504 double curve = *envPtr[3];
3505 unit->m_endLevel = endLevel;
3507 counter = (int32)(dur * SAMPLERATE);
3508 counter = sc_max(1, counter);
3509 if (counter == 1) unit->m_shape = 1; // shape_Linear
3510 switch (unit->m_shape) {
3511 case shape_Step : {
3512 level = endLevel;
3513 } break;
3514 case shape_Linear : {
3515 unit->m_grow = (endLevel - level) / counter;
3516 } break;
3517 case shape_Exponential : {
3518 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3519 } break;
3520 case shape_Sine : {
3521 double w = pi / counter;
3523 unit->m_a2 = (endLevel + level) * 0.5;
3524 unit->m_b1 = 2. * cos(w);
3525 unit->m_y1 = (endLevel - level) * 0.5;
3526 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3527 level = unit->m_a2 - unit->m_y1;
3528 } break;
3529 case shape_Welch : {
3530 double w = (pi * 0.5) / counter;
3532 unit->m_b1 = 2. * cos(w);
3534 if (endLevel >= level) {
3535 unit->m_a2 = level;
3536 unit->m_y1 = 0.;
3537 unit->m_y2 = -sin(w) * (endLevel - level);
3538 } else {
3539 unit->m_a2 = endLevel;
3540 unit->m_y1 = level - endLevel;
3541 unit->m_y2 = cos(w) * (level - endLevel);
3543 level = unit->m_a2 + unit->m_y1;
3544 } break;
3545 case shape_Curve : {
3546 if (fabs(curve) < 0.001) {
3547 unit->m_shape = 1; // shape_Linear
3548 unit->m_grow = (endLevel - level) / counter;
3549 } else {
3550 double a1 = (endLevel - level) / (1.0 - exp(curve));
3551 unit->m_a2 = level + a1;
3552 unit->m_b1 = a1;
3553 unit->m_grow = exp(curve / counter);
3555 } break;
3556 case shape_Squared : {
3557 unit->m_y1 = sqrt(level);
3558 unit->m_y2 = sqrt(endLevel);
3559 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3560 } break;
3561 case shape_Cubed : {
3562 unit->m_y1 = pow(level, 0.33333333);
3563 unit->m_y2 = pow(endLevel, 0.33333333);
3564 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3565 } break;
3570 int nsmps = sc_min(remain, counter);
3572 switch (unit->m_shape) {
3573 case shape_Step : {
3574 for (int i=0; i<nsmps; ++i) {
3575 CHECK_GATE
3576 ZXP(out) = level;
3578 } break;
3579 case shape_Linear : {
3580 double grow = unit->m_grow;
3581 for (int i=0; i<nsmps; ++i) {
3582 CHECK_GATE
3583 ZXP(out) = level;
3584 level += grow;
3586 } break;
3587 case shape_Exponential : {
3588 double grow = unit->m_grow;
3589 for (int i=0; i<nsmps; ++i) {
3590 CHECK_GATE
3591 ZXP(out) = level;
3592 level *= grow;
3594 } break;
3595 case shape_Sine : {
3596 double a2 = unit->m_a2;
3597 double b1 = unit->m_b1;
3598 double y2 = unit->m_y2;
3599 double y1 = unit->m_y1;
3600 for (int i=0; i<nsmps; ++i) {
3601 CHECK_GATE
3602 ZXP(out) = level;
3603 double y0 = b1 * y1 - y2;
3604 level = a2 - y0;
3605 y2 = y1;
3606 y1 = y0;
3608 unit->m_y1 = y1;
3609 unit->m_y2 = y2;
3610 } break;
3611 case shape_Welch : {
3612 double a2 = unit->m_a2;
3613 double b1 = unit->m_b1;
3614 double y2 = unit->m_y2;
3615 double y1 = unit->m_y1;
3616 for (int i=0; i<nsmps; ++i) {
3617 CHECK_GATE
3618 ZXP(out) = level;
3619 double y0 = b1 * y1 - y2;
3620 level = a2 + y0;
3621 y2 = y1;
3622 y1 = y0;
3624 unit->m_y1 = y1;
3625 unit->m_y2 = y2;
3626 } break;
3627 case shape_Curve : {
3628 double a2 = unit->m_a2;
3629 double b1 = unit->m_b1;
3630 double grow = unit->m_grow;
3631 for (int i=0; i<nsmps; ++i) {
3632 CHECK_GATE
3633 ZXP(out) = level;
3634 b1 *= grow;
3635 level = a2 - b1;
3637 unit->m_b1 = b1;
3638 } break;
3639 case shape_Squared : {
3640 double grow = unit->m_grow;
3641 double y1 = unit->m_y1;
3642 for (int i=0; i<nsmps; ++i) {
3643 CHECK_GATE
3644 ZXP(out) = level;
3645 y1 += grow;
3646 level = y1*y1;
3648 unit->m_y1 = y1;
3649 } break;
3650 case shape_Cubed : {
3651 double grow = unit->m_grow;
3652 double y1 = unit->m_y1;
3653 for (int i=0; i<nsmps; ++i) {
3654 CHECK_GATE
3655 ZXP(out) = level;
3656 y1 += grow;
3657 level = y1*y1*y1;
3659 unit->m_y1 = y1;
3660 } break;
3661 case shape_Sustain : {
3662 for (int i=0; i<nsmps; ++i) {
3663 CHECK_GATE
3664 ZXP(out) = level;
3666 } break;
3668 remain -= nsmps;
3669 counter -= nsmps;
3671 unit->m_level = level;
3672 unit->m_counter = counter;
3673 unit->m_prevGate = gate;
3676 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3678 void Linen_Ctor(Linen *unit)
3680 // gate attack level release
3681 SETCALC(Linen_next_k);
3683 unit->m_level = 0.f;
3684 unit->m_stage = 4;
3685 unit->m_prevGate = 0.f;
3686 Linen_next_k(unit, 1);
3689 void Linen_next_k(Linen *unit, int inNumSamples)
3691 float gate = ZIN0(0);
3692 float *out = OUT(0);
3694 if (unit->m_prevGate <= 0.f && gate > 0.f) {
3695 unit->mDone = false;
3696 unit->m_stage = 0;
3697 float attackTime = ZIN0(1);
3698 float susLevel = ZIN0(2);
3699 int counter = (int)(attackTime * SAMPLERATE);
3700 counter = sc_max(1, counter);
3701 unit->m_slope = (susLevel - unit->m_level) / counter;
3702 unit->m_counter = counter;
3705 switch (unit->m_stage) {
3706 case 0 :
3707 case 2 :
3708 *out = unit->m_level;
3709 unit->m_level += unit->m_slope;
3710 if (--unit->m_counter == 0) unit->m_stage++;
3711 break;
3712 case 1 :
3713 *out = unit->m_level;
3714 if (gate <= -1.f) {
3715 // cutoff
3716 unit->m_stage = 2;
3717 float releaseTime = -gate - 1.f;
3718 int counter = (int)(releaseTime * SAMPLERATE);
3719 counter = sc_max(1, counter);
3720 unit->m_slope = -unit->m_level / counter;
3721 unit->m_counter = counter;
3722 } else if (gate <= 0.f) {
3723 unit->m_stage = 2;
3724 float releaseTime = ZIN0(3);
3725 int counter = (int)(releaseTime * SAMPLERATE);
3726 counter = sc_max(1, counter);
3727 unit->m_slope = -unit->m_level / counter;
3728 unit->m_counter = counter;
3730 //Print("release %d %d\n", unit->mParent->mNode.mID, counter);
3732 break;
3733 case 3 : {
3734 *out = 0.f;
3735 //Print("done %d\n", unit->mParent->mNode.mID);
3736 unit->mDone = true;
3737 unit->m_stage++;
3738 int doneAction = (int)ZIN0(4);
3739 DoneAction(doneAction, unit);
3740 } break;
3741 case 4 :
3742 *out = 0.f;
3743 break;
3745 unit->m_prevGate = gate;
3748 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3750 void EnvFill(World *world, struct SndBuf *buf, struct sc_msg_iter *msg)
3752 if (buf->channels != 1) return;
3754 int size = buf->samples;
3755 int byteSize = size * sizeof(float);
3756 float *data = (float*)malloc(byteSize);
3758 double level = msg->getf();
3759 int numStages = msg->geti();
3760 /*int releaseNode =*/ msg->geti(); // ignored
3761 /*int loopNode =*/ msg->geti(); // ignored
3763 double pos = 0.;
3764 int32 index = 0;
3765 int32 remain = size;
3767 for (int j=0; j < numStages; ++j)
3769 double endLevel = msg->getf();
3770 double dur = msg->getf();
3771 int shape = msg->geti();
3772 double curve = msg->getf();
3774 int32 ipos = (int32)pos;
3775 double smpdur = dur * size;
3776 int32 nsmps = (int32)smpdur - ipos;
3777 nsmps = sc_min(nsmps, remain);
3779 switch (shape) {
3780 case shape_Step : {
3781 level = endLevel;
3782 for (int i=0; i<nsmps; ++i) {
3783 data[index++] = level;
3785 } break;
3786 case shape_Linear : {
3787 double grow = (endLevel - level) / nsmps;
3788 for (int i=0; i<nsmps; ++i) {
3789 data[index++] = level;
3790 level += grow;
3792 } break;
3793 case shape_Exponential : {
3794 double grow = pow(endLevel / level, 1.0 / nsmps);
3795 for (int i=0; i<nsmps; ++i) {
3796 data[index++] = level;
3797 level *= grow;
3799 } break;
3800 case shape_Sine : {
3801 double w = pi / nsmps;
3803 double a2 = (endLevel + level) * 0.5;
3804 double b1 = 2. * cos(w);
3805 double y1 = (endLevel - level) * 0.5;
3806 double y2 = y1 * sin(pi * 0.5 - w);
3807 level = a2 - y1;
3808 for (int i=0; i<nsmps; ++i) {
3809 data[index++] = level;
3810 double y0 = b1 * y1 - y2;
3811 level = a2 - y0;
3812 y2 = y1;
3813 y1 = y0;
3815 } break;
3816 case shape_Welch : {
3817 double w = (pi * 0.5) / nsmps;
3819 double b1 = 2. * cos(w);
3820 double a2, y1, y2;
3821 if (endLevel >= level) {
3822 a2 = level;
3823 y1 = 0.;
3824 y2 = -sin(w) * (endLevel - level);
3825 } else {
3826 a2 = endLevel;
3827 y1 = level - endLevel;
3828 y2 = cos(w) * (level - endLevel);
3830 level = a2 + y1;
3831 for (int i=0; i<nsmps; ++i) {
3832 data[index++] = level;
3833 double y0 = b1 * y1 - y2;
3834 level = a2 - y0;
3835 y2 = y1;
3836 y1 = y0;
3838 } break;
3839 case shape_Curve : {
3840 if (fabs(curve) < 0.001) {
3841 double grow = (endLevel - level) / nsmps;
3842 for (int i=0; i<nsmps; ++i) {
3843 data[index++] = level;
3844 level += grow;
3846 } else {
3847 double a1 = (endLevel - level) / (1.0 - exp(curve));
3848 double a2 = level + a1;
3849 double b1 = a1;
3850 double grow = exp(curve / nsmps);
3851 for (int i=0; i<nsmps; ++i) {
3852 data[index++] = level;
3853 b1 *= grow;
3854 level = a2 - b1;
3857 } break;
3858 case shape_Squared : {
3859 double y1 = sqrt(level);
3860 double y2 = sqrt(endLevel);
3861 double grow = (y2 - y1) / nsmps;
3862 for (int i=0; i<nsmps; ++i) {
3863 data[index++] = level;
3864 y1 += grow;
3865 level = y1*y1;
3867 } break;
3868 case shape_Cubed : {
3869 double y1 = pow(level, 0.33333333);
3870 double y2 = pow(endLevel, 0.33333333);
3871 double grow = (y2 - y1) / nsmps;
3872 for (int i=0; i<nsmps; ++i) {
3873 data[index++] = level;
3874 y1 += grow;
3875 level = y1*y1*y1;
3877 } break;
3880 pos += smpdur;
3881 level = endLevel;
3882 remain -= nsmps;
3884 memcpy(buf->data, data, byteSize);
3885 free(data);
3888 //////////////////// Add IEnvGen 06/06/2007 /////////////////////////////////
3891 struct IEnvGen : public Unit
3893 float m_level, m_offset;
3894 float m_startpoint, m_numvals, m_pointin;
3895 float* m_envvals;
3899 extern "C"
3901 void IEnvGen_next_a(IEnvGen *unit, int inNumSamples);
3902 void IEnvGen_next_k(IEnvGen *unit, int inNumSamples);
3903 void IEnvGen_Ctor(IEnvGen* unit);
3904 void IEnvGen_Dtor(IEnvGen* unit);
3907 #define GET_ENV_VAL \
3908 switch (shape) \
3910 case shape_Step : \
3911 level = unit->m_level = endLevel; \
3912 break; \
3913 case shape_Linear : \
3914 default: \
3915 level = unit->m_level = pos * (endLevel - begLevel) + begLevel; \
3916 break; \
3917 case shape_Exponential : \
3918 level = unit->m_level = begLevel * pow(endLevel / begLevel, pos); \
3919 break; \
3920 case shape_Sine : \
3921 level = unit->m_level = begLevel + (endLevel - begLevel) * (-cos(pi * pos) * 0.5 + 0.5); \
3922 break; \
3923 case shape_Welch : \
3925 if (begLevel < endLevel) \
3926 level = unit->m_level = begLevel + (endLevel - begLevel) * sin(pi2 * pos); \
3927 else \
3928 level = unit->m_level = endLevel - (endLevel - begLevel) * sin(pi2 - pi2 * pos); \
3929 break; \
3931 case shape_Curve : \
3932 if (fabs((float)curve) < 0.0001) { \
3933 level = unit->m_level = pos * (endLevel - begLevel) + begLevel; \
3934 } else { \
3935 double denom = 1. - exp((float)curve); \
3936 double numer = 1. - exp((float)(pos * curve)); \
3937 level = unit->m_level = begLevel + (endLevel - begLevel) * (numer/denom); \
3939 break; \
3940 case shape_Squared : \
3942 double sqrtBegLevel = sqrt(begLevel); \
3943 double sqrtEndLevel = sqrt(endLevel); \
3944 double sqrtLevel = pos * (sqrtEndLevel - sqrtBegLevel) + sqrtBegLevel; \
3945 level = unit->m_level = sqrtLevel * sqrtLevel; \
3946 break; \
3948 case shape_Cubed : \
3950 double cbrtBegLevel = pow(begLevel, 0.3333333f); \
3951 double cbrtEndLevel = pow(endLevel, 0.3333333f); \
3952 double cbrtLevel = pos * (cbrtEndLevel - cbrtBegLevel) + cbrtBegLevel; \
3953 level = unit->m_level = cbrtLevel * cbrtLevel * cbrtLevel; \
3954 break; \
3959 void IEnvGen_Ctor(IEnvGen *unit)
3962 if (INRATE(0) == calc_FullRate) {
3963 SETCALC(IEnvGen_next_a);
3964 } else {
3965 SETCALC(IEnvGen_next_k);
3968 // pointer, offset
3969 // initlevel, numstages, totaldur,
3970 // [dur, shape, curve, level] * numvals
3971 int numStages = (int)IN0(3);
3972 int numvals = numStages * 4; // initlevel + (levels, dur, shape, curves) * stages
3973 float offset = unit->m_offset = IN0(1);
3974 float point = unit->m_pointin = IN0(0) - offset;
3975 unit->m_envvals = (float*)RTAlloc(unit->mWorld, (int)(numvals + 1.) * sizeof(float));
3977 unit->m_envvals[0] = IN0(2);
3978 // Print("%3.3f\n", unit->m_envvals[0]);
3979 // fill m_envvals with the values;
3980 for (int i = 1; i <= numvals; i++) {
3981 unit->m_envvals[i] = IN0(4 + i);
3982 // Print("%3.3f\n", unit->m_envvals[i]);
3985 // float out = OUT0(0);
3986 float totalDur = IN0(4);
3987 float level = 0.f;
3988 float newtime = 0.f;
3989 int stage = 0;
3990 float seglen = 0.f;
3991 if (point >= totalDur) {
3992 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
3993 } else {
3994 if (point <= 0.0) {
3995 unit->m_level = level = unit->m_envvals[0];
3996 } else {
3997 float segpos = point;
3998 // determine which segment the current time pointer needs calculated
3999 for(int j = 0; point >= newtime; j++) {
4000 seglen = unit->m_envvals[(j * 4) + 1];
4001 newtime += seglen;
4002 segpos -= seglen;
4003 stage = j;
4006 segpos = segpos + seglen;
4007 float begLevel = unit->m_envvals[(stage * 4)];
4008 int shape = (int)unit->m_envvals[(stage * 4) + 2];
4009 int curve = (int)unit->m_envvals[(stage * 4) + 3];
4010 float endLevel = unit->m_envvals[(stage * 4) + 4];
4011 float pos = (segpos / seglen);
4013 GET_ENV_VAL
4016 OUT0(0) = level;
4019 void IEnvGen_Dtor(IEnvGen *unit)
4021 RTFree(unit->mWorld, unit->m_envvals);
4025 void IEnvGen_next_a(IEnvGen *unit, int inNumSamples)
4027 float* out = OUT(0);
4028 float level = unit->m_level;
4029 float* pointin = IN(0);
4030 float offset = unit->m_offset;
4031 int numStages = (int)IN0(3);
4032 float point; // = unit->m_pointin;
4034 float totalDur = IN0(4);
4036 int stagemul;
4037 // pointer, offset
4038 // level0, numstages, totaldur,
4039 // [initval, [dur, shape, curve, level] * N ]
4041 for( int i = 0; i < inNumSamples; i++) {
4042 if (pointin[i] == unit->m_pointin){
4043 out[i] = level;
4044 } else {
4045 unit->m_pointin = point = sc_max(pointin[i] - offset, 0.0);
4046 float newtime = 0.f;
4047 int stage = 0;
4048 float seglen = 0.f;
4049 if (point >= totalDur) {
4050 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
4051 } else {
4052 if (point <= 0.0) {
4053 unit->m_level = level = unit->m_envvals[0];
4054 } else {
4055 float segpos = point;
4056 // determine which segment the current time pointer needs
4057 for(int j = 0; point >= newtime; j++) {
4058 seglen = unit->m_envvals[(j * 4) + 1];
4059 newtime += seglen;
4060 segpos -= seglen;
4061 stage = j;
4063 stagemul = stage * 4;
4064 segpos = segpos + seglen;
4065 float begLevel = unit->m_envvals[stagemul];
4066 int shape = (int)unit->m_envvals[stagemul + 2];
4067 int curve = (int)unit->m_envvals[stagemul + 3];
4068 float endLevel = unit->m_envvals[stagemul + 4];
4069 float pos = (segpos / seglen);
4071 GET_ENV_VAL
4074 out[i] = level;
4080 void IEnvGen_next_k(IEnvGen *unit, int inNumSamples)
4082 float* out = OUT(0);
4083 float level = unit->m_level;
4084 float pointin = sc_max(IN0(0) - unit->m_offset, 0);
4085 int numStages = (int)IN0(3);
4087 float totalDur = IN0(4);
4088 // pointer, offset
4089 // level0, numstages, totaldur,
4090 float point = unit->m_pointin;
4092 // [initval, [dur, shape, curve, level] * N ]
4094 if (pointin == unit->m_pointin) {
4095 Fill(inNumSamples, out, level);
4096 } else {
4097 float pointslope = CALCSLOPE(pointin, point);
4098 for( int i = 0; i < inNumSamples; i++) {
4099 float newtime = 0.f;
4100 int stage = 0;
4101 float seglen = 0.f;
4102 if (point >= totalDur) {
4103 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
4104 } else {
4105 if (point <= 0.0) {
4106 unit->m_level = level = unit->m_envvals[0];
4107 } else {
4108 float segpos = point;
4109 // determine which segment the current time pointer needs calculated
4110 for(int j = 0; point >= newtime; j++) {
4111 seglen = unit->m_envvals[(j * 4) + 1];
4112 newtime += seglen;
4113 segpos -= seglen;
4114 stage = j;
4117 segpos = segpos + seglen;
4118 float begLevel = unit->m_envvals[(stage * 4)];
4119 int shape = (int)unit->m_envvals[(stage * 4) + 2];
4120 float curve = unit->m_envvals[(stage * 4) + 3];
4121 float endLevel = unit->m_envvals[(stage * 4) + 4];
4122 float pos = (segpos / seglen);
4124 GET_ENV_VAL
4127 out[i] = level;
4128 point += pointslope;
4131 unit->m_pointin = pointin;
4136 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4139 PluginLoad(LF)
4141 ft = inTable;
4143 DefineSimpleUnit(Vibrato);
4144 DefineSimpleUnit(LFPulse);
4145 DefineSimpleUnit(LFSaw);
4146 DefineSimpleUnit(LFPar);
4147 DefineSimpleUnit(LFCub);
4148 DefineSimpleUnit(LFTri);
4149 DefineSimpleUnit(LFGauss);
4150 DefineSimpleUnit(Impulse);
4151 DefineSimpleUnit(VarSaw);
4152 DefineSimpleUnit(SyncSaw);
4153 DefineSimpleUnit(K2A);
4154 DefineSimpleUnit(A2K);
4155 DefineSimpleUnit(T2K);
4156 DefineSimpleUnit(T2A);
4157 DefineSimpleUnit(DC);
4158 DefineSimpleUnit(Silent);
4159 DefineSimpleUnit(Line);
4160 DefineSimpleUnit(XLine);
4162 DefineSimpleUnit(Wrap);
4163 DefineSimpleUnit(Fold);
4164 DefineSimpleUnit(Clip);
4165 DefineSimpleUnit(Unwrap);
4166 DefineSimpleUnit(AmpComp);
4167 DefineSimpleUnit(AmpCompA);
4168 DefineSimpleUnit(InRange);
4169 DefineSimpleUnit(InRect);
4170 DefineSimpleUnit(LinExp);
4171 DefineSimpleUnit(EnvGen);
4172 DefineSimpleUnit(Linen);
4174 DefineBufGen("env", EnvFill);
4176 DefineDtorUnit(IEnvGen);