FFT: Prevent user from attempting hops smaller than SC's block size
[supercollider.git] / server / plugins / LFUGens.cpp
blobceda2008293caa0fe66d7344a55d4c349ce2fc51
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 "SIMD_Unit.hpp"
24 #include <limits.h>
25 #include <cstdio>
26 #include "function_attributes.h"
28 static InterfaceTable *ft;
30 struct Vibrato : public Unit
32 double mPhase, m_attackSlope, m_attackLevel;
33 float mFreqMul, m_scaleA, m_scaleB, mFreq;
34 int m_delay, m_attack;
37 struct LFPulse : public Unit
39 double mPhase;
40 float mFreqMul, mDuty;
43 struct LFSaw : public Unit
45 double mPhase;
46 float mFreqMul;
49 struct LFPar : public Unit
51 double mPhase;
52 float mFreqMul;
55 struct LFCub : public Unit
57 double mPhase;
58 float mFreqMul;
61 struct LFTri : public Unit
63 double mPhase;
64 float mFreqMul;
67 struct LFGauss : public Unit
69 double mPhase;
70 float mDurMul;
73 struct Impulse : public Unit
75 double mPhase, mPhaseOffset;
76 float mFreqMul;
79 struct VarSaw : public Unit
81 double mPhase;
82 float mFreqMul, mDuty, mInvDuty, mInv1Duty;
85 struct SyncSaw : public Unit
87 double mPhase1, mPhase2;
88 float mFreqMul;
91 struct Line : public Unit
93 double mLevel, mSlope;
94 float mEndLevel;
95 int mCounter;
98 struct XLine : public Unit
100 double mLevel, mGrowth;
101 float mEndLevel;
102 int mCounter;
105 struct Cutoff : public Unit
107 double mLevel, mSlope;
108 int mWaitCounter;
111 struct LinExp : public Unit
113 float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo;
116 struct Clip : public Unit
118 float m_lo, m_hi;
121 struct Wrap : public Unit
123 float m_lo, m_hi;
126 struct Fold : public Unit
128 float m_lo, m_hi, m_range;
131 struct Unwrap : public Unit
133 float m_range, m_half, m_offset, m_prev;
136 struct AmpComp : public Unit
138 float m_rootmul, m_exponent;
141 struct AmpCompA : public Unit
143 double m_scale, m_offset;
146 struct InRange : public Unit
148 // nothing
151 struct InRect : public Unit
153 // nothing
156 //struct Trapezoid : public Unit
158 // float m_leftScale, m_rightScale, m_a, m_b, m_c, m_d;
159 //};
161 struct A2K : public Unit
166 struct T2K : public Unit
171 struct T2A : public Unit
173 float mLevel;
176 struct EnvGen : public Unit
178 double m_a1, m_a2, m_b1, m_y1, m_y2, m_grow, m_level, m_endLevel;
179 int m_counter, m_stage, m_shape, m_releaseNode;
180 float m_prevGate;
181 bool m_released;
184 struct Linen : public Unit
186 float m_endLevel;
187 double m_slope, m_level;
188 int m_counter, m_stage;
189 float m_prevGate;
193 //////////////////////////////////////////////////////////////////////////////////////////////////
196 extern "C"
198 void Vibrato_next(Vibrato *unit, int inNumSamples);
199 void Vibrato_Ctor(Vibrato* unit);
201 void LFPulse_next_a(LFPulse *unit, int inNumSamples);
202 void LFPulse_next_k(LFPulse *unit, int inNumSamples);
203 void LFPulse_Ctor(LFPulse* unit);
205 void LFSaw_next_a(LFSaw *unit, int inNumSamples);
206 void LFSaw_next_k(LFSaw *unit, int inNumSamples);
207 void LFSaw_Ctor(LFSaw* unit);
209 void LFTri_next_a(LFTri *unit, int inNumSamples);
210 void LFTri_next_k(LFTri *unit, int inNumSamples);
211 void LFTri_Ctor(LFTri* unit);
213 void LFPar_next_a(LFPar *unit, int inNumSamples);
214 void LFPar_next_k(LFPar *unit, int inNumSamples);
215 void LFPar_Ctor(LFPar* unit);
217 void LFCub_next_a(LFCub *unit, int inNumSamples);
218 void LFCub_next_k(LFCub *unit, int inNumSamples);
219 void LFCub_Ctor(LFCub* unit);
221 void LFGauss_next_a(LFGauss *unit, int inNumSamples);
222 void LFGauss_next_k(LFGauss *unit, int inNumSamples);
223 void LFGauss_next_aa(LFGauss *unit, int inNumSamples);
224 void LFGauss_Ctor(LFGauss* unit);
226 void VarSaw_next_a(VarSaw *unit, int inNumSamples);
227 void VarSaw_next_k(VarSaw *unit, int inNumSamples);
228 void VarSaw_Ctor(VarSaw* unit);
230 void Impulse_next_a(Impulse *unit, int inNumSamples);
231 void Impulse_next_kk(Impulse *unit, int inNumSamples);
232 void Impulse_next_k(Impulse *unit, int inNumSamples);
233 void Impulse_Ctor(Impulse* unit);
235 void SyncSaw_next_aa(SyncSaw *unit, int inNumSamples);
236 void SyncSaw_next_ak(SyncSaw *unit, int inNumSamples);
237 void SyncSaw_next_ka(SyncSaw *unit, int inNumSamples);
238 void SyncSaw_next_kk(SyncSaw *unit, int inNumSamples);
239 void SyncSaw_Ctor(SyncSaw* unit);
241 void A2K_next(A2K *unit, int inNumSamples);
242 void A2K_Ctor(A2K* unit);
244 void T2K_next(T2K *unit, int inNumSamples);
245 void T2K_Ctor(T2K* unit);
247 void T2A_next(T2A *unit, int inNumSamples);
248 void T2A_Ctor(T2A* unit);
250 void Line_next(Line *unit, int inNumSamples);
251 void Line_Ctor(Line* unit);
253 void XLine_next(XLine *unit, int inNumSamples);
254 void XLine_Ctor(XLine* unit);
256 void Wrap_next_kk(Wrap *unit, int inNumSamples);
257 void Wrap_next_ak(Wrap *unit, int inNumSamples);
258 void Wrap_next_ka(Wrap *unit, int inNumSamples);
259 void Wrap_next_aa(Wrap *unit, int inNumSamples);
260 void Wrap_Ctor(Wrap* unit);
262 void Fold_next_kk(Fold *unit, int inNumSamples);
263 void Fold_next_ak(Fold *unit, int inNumSamples);
264 void Fold_next_ka(Fold *unit, int inNumSamples);
265 void Fold_next_aa(Fold *unit, int inNumSamples);
266 void Fold_Ctor(Fold* unit);
268 void Clip_next_kk(Clip *unit, int inNumSamples);
269 void Clip_next_ka(Clip *unit, int inNumSamples);
270 void Clip_next_ak(Clip *unit, int inNumSamples);
271 void Clip_next_aa(Clip *unit, int inNumSamples);
272 void Clip_Ctor(Clip* unit);
274 void Unwrap_next(Unwrap* unit, int inNumSamples);
275 void Unwrap_Ctor(Unwrap* unit);
277 void AmpComp_next(AmpComp *unit, int inNumSamples);
278 void AmpComp_Ctor(AmpComp* unit);
280 void AmpCompA_next(AmpCompA *unit, int inNumSamples);
281 void AmpCompA_Ctor(AmpCompA* unit);
283 void InRange_next(InRange *unit, int inNumSamples);
284 void InRange_Ctor(InRange* unit);
286 void InRect_next(InRect *unit, int inNumSamples);
287 void InRect_Ctor(InRect* unit);
289 void LinExp_next(LinExp *unit, int inNumSamples);
290 void LinExp_next_kk(LinExp *unit, int inNumSamples);
291 void LinExp_next_ak(LinExp *unit, int inNumSamples);
292 void LinExp_next_ka(LinExp *unit, int inNumSamples);
293 void LinExp_Ctor(LinExp* unit);
295 void EnvGen_next_k(EnvGen *unit, int inNumSamples);
296 void EnvGen_next_aa(EnvGen *unit, int inNumSamples);
297 void EnvGen_next_ak(EnvGen *unit, int inNumSamples);
298 void EnvGen_Ctor(EnvGen *unit);
300 void Linen_next_k(Linen *unit, int inNumSamples);
301 void Linen_Ctor(Linen *unit);
305 //////////////////////////////////////////////////////////////////////////////////////////////////
307 // in, rate, depth, rateVariation, depthVariation
308 // 0 1 2 3 4
310 void Vibrato_next(Vibrato *unit, int inNumSamples)
312 float *out = ZOUT(0);
313 float *in = ZIN(0);
315 double ffreq = unit->mFreq;
316 double phase = unit->mPhase;
317 float scaleA = unit->m_scaleA;
318 float scaleB = unit->m_scaleB;
319 if (unit->m_delay > 0)
321 int remain = sc_min(inNumSamples, unit->m_delay);
322 unit->m_delay -= remain;
323 inNumSamples -= remain;
324 LOOP(remain,
325 ZXP(out) = ZXP(in);
327 if (unit->m_delay <= 0 && inNumSamples > 0) {
328 if (unit->m_attack > 0) goto doAttack;
329 else goto doNormal;
332 else if (unit->m_attack)
334 doAttack:
335 int remain = sc_min(inNumSamples, unit->m_attack);
336 unit->m_attack -= remain;
337 inNumSamples -= remain;
338 double attackSlope = unit->m_attackSlope;
339 double attackLevel = unit->m_attackLevel;
340 LOOP(remain,
341 if (phase < 1.f)
343 float z = phase;
344 ZXP(out) = ZXP(in) * (1.f + (float)attackLevel * scaleA * (1.f - z * z)) ;
346 else if (phase < 3.f)
348 float z = phase - 2.f;
349 ZXP(out) = ZXP(in) * (1.f + (float)attackLevel * scaleB * (z * z - 1.f)) ;
351 else
353 phase -= 4.f;
354 float z = phase;
356 float depth = ZIN0(2);
357 float rateVariation = ZIN0(5);
358 float depthVariation = ZIN0(6);
360 float rate = ZIN0(1) * unit->mFreqMul;
361 RGen& rgen = *unit->mParent->mRGen;
362 ffreq = rate * (1.f + rateVariation * rgen.frand2());
363 scaleA = depth * (1.f + depthVariation * rgen.frand2());
364 scaleB = depth * (1.f + depthVariation * rgen.frand2());
366 ZXP(out) = ZXP(in) * (1.f + (float)attackLevel * scaleA * (1.f - z * z)) ;
368 phase += ffreq;
369 attackLevel += attackSlope;
371 unit->m_attackLevel = attackLevel;
372 if (unit->m_attack <= 0 && inNumSamples > 0) goto doNormal;
374 else
376 doNormal:
377 LOOP1(inNumSamples,
378 if (phase < 1.f)
380 float z = phase;
381 ZXP(out) = ZXP(in) * (1.f + scaleA * (1.f - z * z)) ;
383 else if (phase < 3.f)
385 float z = phase - 2.f;
386 ZXP(out) = ZXP(in) * (1.f + scaleB * (z * z - 1.f)) ;
388 else
390 phase -= 4.f;
391 float z = phase;
393 float depth = ZIN0(2);
394 float rateVariation = ZIN0(5);
395 float depthVariation = ZIN0(6);
397 float rate = ZIN0(1) * unit->mFreqMul;
398 RGen& rgen = *unit->mParent->mRGen;
399 ffreq = rate * (1.f + rateVariation * rgen.frand2());
400 scaleA = depth * (1.f + depthVariation * rgen.frand2());
401 scaleB = depth * (1.f + depthVariation * rgen.frand2());
403 ZXP(out) = ZXP(in) * (1.f + scaleA * (1.f - z * z)) ;
405 phase += ffreq;
408 unit->mPhase = phase;
409 unit->mFreq = ffreq;
410 unit->m_scaleA = scaleA;
411 unit->m_scaleB = scaleB;
415 void Vibrato_Ctor(Vibrato* unit)
417 unit->mFreqMul = 4.0 * SAMPLEDUR;
418 unit->mPhase = 4.0 * sc_wrap(ZIN0(7), 0.f, 1.f) - 1.0;
420 RGen& rgen = *unit->mParent->mRGen;
421 float rate = ZIN0(1) * unit->mFreqMul;
422 float depth = ZIN0(2);
423 float rateVariation = ZIN0(5);
424 float depthVariation = ZIN0(6);
425 unit->mFreq = rate * (1.f + rateVariation * rgen.frand2());
426 unit->m_scaleA = depth * (1.f + depthVariation * rgen.frand2());
427 unit->m_scaleB = depth * (1.f + depthVariation * rgen.frand2());
428 unit->m_delay = (int)(ZIN0(3) * SAMPLERATE);
429 unit->m_attack = (int)(ZIN0(4) * SAMPLERATE);
430 unit->m_attackSlope = 1. / (double)(1 + unit->m_attack);
431 unit->m_attackLevel = unit->m_attackSlope;
433 SETCALC(Vibrato_next);
434 Vibrato_next(unit, 1);
437 //////////////////////////////////////////////////////////////////////////////////////////////////
440 void LFPulse_next_a(LFPulse *unit, int inNumSamples)
442 float *out = ZOUT(0);
443 float *freq = ZIN(0);
444 float nextDuty = ZIN0(2);
445 float duty = unit->mDuty;
447 float freqmul = unit->mFreqMul;
448 double phase = unit->mPhase;
449 LOOP1(inNumSamples,
450 float z;
451 if (phase >= 1.f) {
452 phase -= 1.f;
453 duty = unit->mDuty = nextDuty;
454 // output at least one sample from the opposite polarity
455 z = duty < 0.5f ? 1.f : 0.f;
456 } else {
457 z = phase < duty ? 1.f : 0.f;
459 phase += ZXP(freq) * freqmul;
460 ZXP(out) = z;
463 unit->mPhase = phase;
466 void LFPulse_next_k(LFPulse *unit, int inNumSamples)
468 float *out = ZOUT(0);
469 float freq = ZIN0(0) * unit->mFreqMul;
470 float nextDuty = ZIN0(2);
471 float duty = unit->mDuty;
473 double phase = unit->mPhase;
474 LOOP1(inNumSamples,
475 float z;
476 if (phase >= 1.f) {
477 phase -= 1.f;
478 duty = unit->mDuty = nextDuty;
479 // output at least one sample from the opposite polarity
480 z = duty < 0.5f ? 1.f : 0.f;
481 } else {
482 z = phase < duty ? 1.f : 0.f;
484 phase += freq;
485 ZXP(out) = z;
488 unit->mPhase = phase;
491 void LFPulse_Ctor(LFPulse* unit)
493 if (INRATE(0) == calc_FullRate) {
494 SETCALC(LFPulse_next_a);
495 } else {
496 SETCALC(LFPulse_next_k);
499 unit->mFreqMul = unit->mRate->mSampleDur;
500 unit->mPhase = ZIN0(1);
501 unit->mDuty = ZIN0(2);
503 LFPulse_next_k(unit, 1);
507 //////////////////////////////////////////////////////////////////////////////////////////////////
509 void LFSaw_next_a(LFSaw *unit, int inNumSamples)
511 float *out = ZOUT(0);
512 float *freq = ZIN(0);
514 float freqmul = unit->mFreqMul;
515 double phase = unit->mPhase;
516 LOOP1(inNumSamples,
517 float z = phase; // out must be written last for in place operation
518 phase += ZXP(freq) * freqmul;
519 if (phase >= 1.f) phase -= 2.f;
520 else if (phase <= -1.f) phase += 2.f;
521 ZXP(out) = z;
524 unit->mPhase = phase;
527 void LFSaw_next_k(LFSaw *unit, int inNumSamples)
529 float *out = ZOUT(0);
530 float freq = ZIN0(0) * unit->mFreqMul;
532 double phase = unit->mPhase;
533 if (freq >= 0.f) {
534 LOOP1(inNumSamples,
535 ZXP(out) = phase;
536 phase += freq;
537 if (phase >= 1.f) phase -= 2.f;
539 } else {
540 LOOP1(inNumSamples,
541 ZXP(out) = phase;
542 phase += freq;
543 if (phase <= -1.f) phase += 2.f;
547 unit->mPhase = phase;
550 void LFSaw_Ctor(LFSaw* unit)
552 if (INRATE(0) == calc_FullRate)
553 SETCALC(LFSaw_next_a);
554 else
555 SETCALC(LFSaw_next_k);
557 unit->mFreqMul = 2.0 * unit->mRate->mSampleDur;
558 unit->mPhase = ZIN0(1);
560 LFSaw_next_k(unit, 1);
564 //////////////////////////////////////////////////////////////////////////////////////////////////
566 void LFPar_next_a(LFPar *unit, int inNumSamples)
568 float *out = ZOUT(0);
569 float *freq = ZIN(0);
571 float freqmul = unit->mFreqMul;
572 double phase = unit->mPhase;
573 float z, y;
574 LOOP1(inNumSamples,
575 if (phase < 1.f) {
576 z = phase;
577 y = 1.f - z*z;
578 } else if (phase < 3.f) {
579 z = phase - 2.f;
580 y = z*z - 1.f;
581 } else {
582 phase -= 4.f;
583 z = phase;
584 y = 1.f - z*z;
586 // Note: the following two lines were originally one, but seems to compile wrong on mac
587 float phaseadd = ZXP(freq);
588 phase += phaseadd * freqmul;
589 ZXP(out) = y;
592 unit->mPhase = phase;
595 void LFPar_next_k(LFPar *unit, int inNumSamples)
597 float *out = ZOUT(0);
598 float freq = ZIN0(0) * unit->mFreqMul;
600 double phase = unit->mPhase;
601 LOOP1(inNumSamples,
602 if (phase < 1.f) {
603 float z = phase;
604 ZXP(out) = 1.f - z*z;
605 } else if (phase < 3.f) {
606 float z = phase - 2.f;
607 ZXP(out) = z*z - 1.f;
608 } else {
609 phase -= 4.f;
610 float z = phase;
611 ZXP(out) = 1.f - z*z;
613 phase += freq;
616 unit->mPhase = phase;
619 void LFPar_Ctor(LFPar* unit)
621 if (INRATE(0) == calc_FullRate)
622 SETCALC(LFPar_next_a);
623 else
624 SETCALC(LFPar_next_k);
626 unit->mFreqMul = 4.0 * unit->mRate->mSampleDur;
627 unit->mPhase = ZIN0(1);
629 LFPar_next_k(unit, 1);
634 //////////////////////////////////////////////////////////////////////////////////////////////////
636 void LFCub_next_a(LFCub *unit, int inNumSamples)
638 float *out = ZOUT(0);
639 float *freq = ZIN(0);
641 float freqmul = unit->mFreqMul;
642 double phase = unit->mPhase;
643 LOOP1(inNumSamples,
644 float z;
645 if (phase < 1.f) {
646 z = phase;
647 } else if (phase < 2.f) {
648 z = 2.f - phase;
649 } else {
650 phase -= 2.f;
651 z = phase;
653 float phaseadd = ZXP(freq);
654 phase += phaseadd * freqmul;
655 ZXP(out) = z * z * (6.f - 4.f * z) - 1.f;
658 unit->mPhase = phase;
661 void LFCub_next_k(LFCub *unit, int inNumSamples)
663 float *out = ZOUT(0);
664 float freq = ZIN0(0) * unit->mFreqMul;
666 double phase = unit->mPhase;
667 LOOP1(inNumSamples,
668 float z;
669 if (phase < 1.f) {
670 z = phase;
671 } else if (phase < 2.f) {
672 z = 2.f - phase;
673 } else {
674 phase -= 2.f;
675 z = phase;
677 ZXP(out) = z * z * (6.f - 4.f * z) - 1.f;
678 phase += freq;
681 unit->mPhase = phase;
684 void LFCub_Ctor(LFCub* unit)
686 if (INRATE(0) == calc_FullRate)
687 SETCALC(LFCub_next_a);
688 else
689 SETCALC(LFCub_next_k);
691 unit->mFreqMul = 2.0 * unit->mRate->mSampleDur;
692 unit->mPhase = ZIN0(1) + 0.5;
694 LFCub_next_k(unit, 1);
699 //////////////////////////////////////////////////////////////////////////////////////////////////
701 void LFTri_next_a(LFTri *unit, int inNumSamples)
703 float *out = ZOUT(0);
704 float *freq = ZIN(0);
706 float freqmul = unit->mFreqMul;
707 double phase = unit->mPhase;
708 LOOP1(inNumSamples,
709 float z = phase > 1.f ? 2.f - phase : phase;
710 phase += ZXP(freq) * freqmul;
711 if (phase >= 3.f) phase -= 4.f;
712 ZXP(out) = z;
715 unit->mPhase = phase;
718 void LFTri_next_k(LFTri *unit, int inNumSamples)
720 float *out = ZOUT(0);
721 float freq = ZIN0(0) * unit->mFreqMul;
723 double phase = unit->mPhase;
724 LOOP1(inNumSamples,
725 float z = phase > 1.f ? 2.f - phase : phase;
726 phase += freq;
727 if (phase >= 3.f) phase -= 4.f;
728 ZXP(out) = z;
731 unit->mPhase = phase;
734 void LFTri_Ctor(LFTri* unit)
736 if (INRATE(0) == calc_FullRate) {
737 SETCALC(LFTri_next_a);
738 } else {
739 SETCALC(LFTri_next_k);
742 unit->mFreqMul = 4.0 * unit->mRate->mSampleDur;
743 unit->mPhase = ZIN0(1);
745 LFTri_next_k(unit, 1);
749 //////////////////////////////////////////////////////////////////////////////////////////////////
751 void LFGauss_next_k(LFGauss *unit, int inNumSamples)
753 float *out = ZOUT(0);
755 float dur = ZIN0(0);
756 float c = ZIN0(1);
757 float b = ZIN0(2);
758 float loop = ZIN0(3);
760 // offset phase by b
761 double x = unit->mPhase - b;
763 // for a full cycle from -1 to 1 in duration, double the step.
764 float step = 2.f / (dur * unit->mRate->mSampleRate);
766 // calculate exponent only once per loop
767 float factor = -1.f / (2.f * c * c);
769 LOOP1(inNumSamples,
771 if (x > 1.f) {
772 if(loop) { x -= 2.f; } else { DoneAction(ZIN0(4), unit); }
774 ZXP(out) = exp(x * x * factor);
775 x += step;
778 unit->mPhase = x + b;
781 void LFGauss_next_a(LFGauss *unit, int inNumSamples)
783 float *out = ZOUT(0);
785 float *dur = ZIN(0);
787 float c = ZIN0(1);
788 float b = ZIN0(2);
789 float loop = ZIN0(3);
790 float sr = unit->mRate->mSampleRate;
792 // offset phase by b
793 double x = unit->mPhase - b;
794 float factor = -1.f / (2.f * c * c);
796 LOOP1(inNumSamples,
798 if (x > 1.f) {
799 if(loop) { x -= 2.f; } else { DoneAction(ZIN0(4), unit); }
802 // for a full cycle from -1 to 1 in duration, double the step.
803 float step = 2.f / (ZXP(dur) * sr);
805 ZXP(out) = exp(x * x * factor);
807 x += step;
810 unit->mPhase = x + b;
815 void LFGauss_next_aa(LFGauss *unit, int inNumSamples)
817 float *out = ZOUT(0);
819 float *dur = ZIN(0);
820 float *c = ZIN(1);
822 float b = ZIN0(2);
823 float loop = ZIN0(3);
824 float sr = unit->mRate->mSampleRate;
826 // offset phase by b
827 double x = unit->mPhase - b;
829 LOOP1(inNumSamples,
831 if (x > 1.f) {
832 if(loop) { x -= 2.f; } else { DoneAction(ZIN0(4), unit); }
835 // for a full cycle from -1 to 1 in duration, double the step.
836 float step = 2.f / (ZXP(dur) * sr);
838 float cval = ZXP(c);
840 float factor = -1.f / (2.f * cval * cval);
841 ZXP(out) = exp(x * x * factor);
843 x += step;
846 unit->mPhase = x + b;
850 void LFGauss_Ctor(LFGauss* unit)
853 if (INRATE(0) == calc_FullRate) {
854 if (INRATE(1) == calc_FullRate) {
855 SETCALC(LFGauss_next_aa);
856 } else {
857 SETCALC(LFGauss_next_a);
858 printf("LFGauss_next_a\n");
860 } else {
861 SETCALC(LFGauss_next_k);
863 unit->mPhase = -1.0;
865 //LFGauss_next_k(unit, 1);
869 //////////////////////////////////////////////////////////////////////////////////////////////////
871 void Impulse_next_a(Impulse *unit, int inNumSamples)
873 float *out = ZOUT(0);
874 float *freq = ZIN(0);
876 float freqmul = unit->mFreqMul;
877 double phase = unit->mPhase;
878 LOOP1(inNumSamples,
879 float z;
880 if (phase >= 1.f) {
881 phase -= 1.f;
882 z = 1.f;
883 } else {
884 z = 0.f;
886 phase += ZXP(freq) * freqmul;
887 ZXP(out) = z;
890 unit->mPhase = phase;
893 /* phase mod - jrh 03 */
895 void Impulse_next_ak(Impulse *unit, int inNumSamples)
897 float *out = ZOUT(0);
898 float *freq = ZIN(0);
899 double phaseOffset = ZIN0(1);
901 float freqmul = unit->mFreqMul;
902 double phase = unit->mPhase;
903 double prev_phaseOffset = unit->mPhaseOffset;
904 double phaseSlope = CALCSLOPE(phaseOffset, prev_phaseOffset);
905 phase += prev_phaseOffset;
907 LOOP1(inNumSamples,
908 float z;
909 phase += phaseSlope;
910 if (phase >= 1.f) {
911 phase -= 1.f;
912 z = 1.f;
913 } else {
914 z = 0.f;
916 phase += ZXP(freq) * freqmul;
917 ZXP(out) = z;
920 unit->mPhase = phase - phaseOffset;
921 unit->mPhaseOffset = phaseOffset;
924 void Impulse_next_kk(Impulse *unit, int inNumSamples)
926 float *out = ZOUT(0);
927 float freq = ZIN0(0) * unit->mFreqMul;
928 double phaseOffset = ZIN0(1);
930 double phase = unit->mPhase;
931 double prev_phaseOffset = unit->mPhaseOffset;
932 double phaseSlope = CALCSLOPE(phaseOffset, prev_phaseOffset);
933 phase += prev_phaseOffset;
935 LOOP1(inNumSamples,
936 float z;
937 phase += phaseSlope;
938 if (phase >= 1.f) {
939 phase -= 1.f;
940 z = 1.f;
941 } else {
942 z = 0.f;
944 phase += freq;
945 ZXP(out) = z;
948 unit->mPhase = phase - phaseOffset;
949 unit->mPhaseOffset = phaseOffset;
953 void Impulse_next_k(Impulse *unit, int inNumSamples)
955 float *out = ZOUT(0);
956 float freq = ZIN0(0) * unit->mFreqMul;
958 double phase = unit->mPhase;
959 LOOP1(inNumSamples,
960 float z;
961 if (phase >= 1.f) {
962 phase -= 1.f;
963 z = 1.f;
964 } else {
965 z = 0.f;
967 phase += freq;
968 ZXP(out) = z;
971 unit->mPhase = phase;
974 void Impulse_Ctor(Impulse* unit)
977 unit->mPhase = ZIN0(1);
979 if (INRATE(0) == calc_FullRate) {
980 if(INRATE(1) != calc_ScalarRate) {
981 SETCALC(Impulse_next_ak);
982 unit->mPhase = 1.f;
983 } else {
984 SETCALC(Impulse_next_a);
986 } else {
987 if(INRATE(1) != calc_ScalarRate) {
988 SETCALC(Impulse_next_kk);
989 unit->mPhase = 1.f;
990 } else {
991 SETCALC(Impulse_next_k);
996 unit->mPhaseOffset = 0.f;
997 unit->mFreqMul = unit->mRate->mSampleDur;
998 if (unit->mPhase == 0.f) unit->mPhase = 1.f;
1000 ZOUT0(0) = 0.f;
1003 //////////////////////////////////////////////////////////////////////////////////////////////////
1005 void VarSaw_next_a(VarSaw *unit, int inNumSamples)
1007 float *out = ZOUT(0);
1008 float *freq = ZIN(0);
1009 float nextDuty = ZIN0(2);
1010 float duty = unit->mDuty;
1011 float invduty = unit->mInvDuty;
1012 float inv1duty = unit->mInv1Duty;
1014 float freqmul = unit->mFreqMul;
1015 double phase = unit->mPhase;
1017 LOOP1(inNumSamples,
1018 if (phase >= 1.f) {
1019 phase -= 1.f;
1020 duty = unit->mDuty = sc_clip(nextDuty, 0.001, 0.999);
1021 invduty = unit->mInvDuty = 2.f / duty;
1022 inv1duty = unit->mInv1Duty = 2.f / (1.f - duty);
1024 float z = phase < duty ? phase * invduty : (1.f - phase) * inv1duty;
1025 phase += ZXP(freq) * freqmul;
1026 ZXP(out) = z - 1.f;
1029 unit->mPhase = phase;
1032 void VarSaw_next_k(VarSaw *unit, int inNumSamples)
1034 float *out = ZOUT(0);
1035 float freq = ZIN0(0) * unit->mFreqMul;
1036 float nextDuty = ZIN0(2);
1037 float duty = unit->mDuty;
1038 float invduty = unit->mInvDuty;
1039 float inv1duty = unit->mInv1Duty;
1041 double phase = unit->mPhase;
1043 LOOP1(inNumSamples,
1044 if (phase >= 1.f) {
1045 phase -= 1.f;
1046 duty = unit->mDuty = sc_clip(nextDuty, 0.001, 0.999);
1047 invduty = unit->mInvDuty = 2.f / duty;
1048 inv1duty = unit->mInv1Duty = 2.f / (1.f - duty);
1050 float z = phase < duty ? phase * invduty : (1.f - phase) * inv1duty;
1051 phase += freq;
1052 ZXP(out) = z - 1.f;
1055 unit->mPhase = phase;
1058 void VarSaw_Ctor(VarSaw* unit)
1060 if (INRATE(0) == calc_FullRate) {
1061 SETCALC(VarSaw_next_a);
1062 } else {
1063 SETCALC(VarSaw_next_k);
1066 unit->mFreqMul = unit->mRate->mSampleDur;
1067 unit->mPhase = ZIN0(1);
1068 float duty = ZIN0(2);
1069 duty = unit->mDuty = sc_clip(duty, 0.001, 0.999);
1070 unit->mInvDuty = 2.f / duty;
1071 unit->mInv1Duty = 2.f / (1.f - duty);
1073 ZOUT0(0) = 0.f;
1076 //////////////////////////////////////////////////////////////////////////////////////////////////
1078 void SyncSaw_next_aa(SyncSaw *unit, int inNumSamples)
1080 float freqmul = unit->mFreqMul;
1081 float *out = ZOUT(0);
1082 float *freq1 = ZIN(0);
1083 float *freq2 = ZIN(1);
1085 double phase1 = unit->mPhase1;
1086 double phase2 = unit->mPhase2;
1088 LOOP1(inNumSamples,
1089 float freq1x = ZXP(freq1) * freqmul;
1090 float freq2x = ZXP(freq2) * freqmul;
1091 float z = phase2;
1092 phase2 += freq2x;
1093 if (phase2 >= 1.f) phase2 -= 2.f;
1094 phase1 += freq1x;
1095 if (phase1 >= 1.f) {
1096 phase1 -= 2.f;
1097 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1099 ZXP(out) = z;
1102 unit->mPhase1 = phase1;
1103 unit->mPhase2 = phase2;
1106 void SyncSaw_next_ak(SyncSaw *unit, int inNumSamples)
1108 float freqmul = unit->mFreqMul;
1109 float *out = ZOUT(0);
1110 float *freq1 = ZIN(0);
1111 float freq2x = ZIN0(1) * freqmul;
1113 double phase1 = unit->mPhase1;
1114 double phase2 = unit->mPhase2;
1116 LOOP1(inNumSamples,
1117 float freq1x = ZXP(freq1) * freqmul;
1118 float z = phase2;
1119 phase2 += freq2x;
1120 if (phase2 >= 1.f) phase2 -= 2.f;
1121 phase1 += freq1x;
1122 if (phase1 >= 1.f) {
1123 phase1 -= 2.f;
1124 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1126 ZXP(out) = z;
1129 unit->mPhase1 = phase1;
1130 unit->mPhase2 = phase2;
1133 void SyncSaw_next_ka(SyncSaw *unit, int inNumSamples)
1135 float freqmul = unit->mFreqMul;
1136 float *out = ZOUT(0);
1137 float freq1x = ZIN0(0) * freqmul;
1138 float *freq2 = ZIN(1);
1140 double phase1 = unit->mPhase1;
1141 double phase2 = unit->mPhase2;
1143 LOOP1(inNumSamples,
1144 float freq2x = ZXP(freq2) * freqmul;
1145 float z = phase2;
1146 phase2 += freq2x;
1147 if (phase2 >= 1.f) phase2 -= 2.f;
1148 phase1 += freq1x;
1149 if (phase1 >= 1.f) {
1150 phase1 -= 2.f;
1151 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1153 ZXP(out) = z;
1156 unit->mPhase1 = phase1;
1157 unit->mPhase2 = phase2;
1160 void SyncSaw_next_kk(SyncSaw *unit, int inNumSamples)
1162 float *out = ZOUT(0);
1163 float freq1x = ZIN0(0) * unit->mFreqMul;
1164 float freq2x = ZIN0(1) * unit->mFreqMul;
1165 double phase1 = unit->mPhase1;
1166 double phase2 = unit->mPhase2;
1168 LOOP1(inNumSamples,
1169 float z = phase2;
1170 phase2 += freq2x;
1171 if (phase2 >= 1.f) phase2 -= 2.f;
1172 phase1 += freq1x;
1173 if (phase1 >= 1.f) {
1174 phase1 -= 2.f;
1175 phase2 = (phase1 + 1.f) * freq2x / freq1x - 1.f;
1177 ZXP(out) = z;
1180 unit->mPhase1 = phase1;
1181 unit->mPhase2 = phase2;
1184 void SyncSaw_Ctor(SyncSaw* unit)
1186 if (INRATE(0) == calc_FullRate) {
1187 if (INRATE(1) == calc_FullRate) {
1188 SETCALC(SyncSaw_next_aa);
1189 } else {
1190 SETCALC(SyncSaw_next_ak);
1192 } else {
1193 if (INRATE(1) == calc_FullRate) {
1194 SETCALC(SyncSaw_next_ka);
1195 } else {
1196 SETCALC(SyncSaw_next_kk);
1199 unit->mFreqMul = 2.0 * unit->mRate->mSampleDur;
1200 unit->mPhase1 = 0.;
1201 unit->mPhase2 = 0.;
1203 SyncSaw_next_kk(unit, 1);
1206 //////////////////////////////////////////////////////////////////////////////////////////////////
1208 struct K2A:
1209 SIMD_Unit
1211 ControlRateInput<0> mLevel;
1213 K2A(void)
1215 mLevel.init(this);
1216 if (inRate(0) == calc_ScalarRate)
1217 set_unrolled_calc_function<K2A, &K2A::next_i<unrolled_64>, &K2A::next_i<unrolled>, &K2A::next_i<scalar> >();
1218 else
1219 set_unrolled_calc_function<K2A, &K2A::next_k<unrolled_64>, &K2A::next_k<unrolled>, &K2A::next_k<scalar> >();
1222 template <int type>
1223 void next_k(int inNumSamples)
1225 if (mLevel.changed(this))
1226 slope_vec<type>(out(0), mLevel.slope(this), inNumSamples);
1227 else
1228 next_i<type>(inNumSamples);
1231 template <int type>
1232 void next_i(int inNumSamples)
1234 set_vec<type>(out(0), mLevel, inNumSamples);
1238 DEFINE_XTORS(K2A)
1240 //////////////////////////////////////////////////////////////////////////////////////////////////
1242 void A2K_next(A2K *unit, int inNumSamples)
1244 ZOUT0(0) = ZIN0(0); // return first sample in block
1247 void A2K_Ctor(A2K* unit)
1249 SETCALC(A2K_next);
1250 A2K_next(unit, 1);
1253 //////////////////////////////////////////////////////////////////////////////////////////////////
1255 void T2K_next(T2K *unit, int inNumSamples)
1257 float out = 0.f, val;
1258 float *in = ZIN(0);
1259 int n = unit->mWorld->mBufLength;
1260 LOOP1(n,
1261 val = ZXP(in);
1262 if(val>out) out=val;
1264 ZOUT0(0) = out;
1267 void T2K_Ctor(T2K* unit)
1269 SETCALC(T2K_next);
1270 ZOUT0(0) = ZIN0(0);
1273 //////////////////////////////////////////////////////////////////////////////////////////////////
1275 static inline void T2A_write_trigger(T2A * unit, float level)
1277 float *out = OUT(0);
1278 int offset = (int) IN0(1);
1279 out[offset] = level;
1282 void T2A_next(T2A *unit, int inNumSamples)
1284 float level = IN0(0);
1286 ZClear(inNumSamples, ZOUT(0));
1287 if((unit->mLevel <= 0.f && level > 0.f))
1288 T2A_write_trigger(unit, level);
1290 unit->mLevel = level;
1293 #ifdef NOVA_SIMD
1294 FLATTEN void T2A_next_nova(T2A *unit, int inNumSamples)
1296 float level = IN0(0);
1298 nova::zerovec_simd(OUT(0), inNumSamples);
1299 if((unit->mLevel <= 0.f && level > 0.f))
1300 T2A_write_trigger(unit, level);
1302 unit->mLevel = level;
1305 FLATTEN void T2A_next_nova_64(T2A *unit, int inNumSamples)
1307 float level = IN0(0);
1309 nova::zerovec_simd<64>(OUT(0));
1310 if((unit->mLevel <= 0.f && level > 0.f))
1311 T2A_write_trigger(unit, level);
1313 unit->mLevel = level;
1316 #endif
1318 void T2A_Ctor(T2A* unit)
1320 #ifdef NOVA_SIMD
1321 if (BUFLENGTH == 64)
1322 SETCALC(T2A_next_nova_64);
1323 else if (!(BUFLENGTH & 15))
1324 SETCALC(T2A_next_nova);
1325 else
1326 #endif
1327 SETCALC(T2A_next);
1328 T2A_next(unit, 1);
1332 //////////////////////////////////////////////////////////////////////////////////////////////////
1334 struct DC:
1335 SIMD_Unit
1337 float value;
1339 DC(void) {
1340 value = in0(0);
1341 if (value == 0)
1342 set_unrolled_calc_function<DC, &DC::next_i<unrolled_64, true>,
1343 &DC::next_i<unrolled, true>, &DC::next_i<scalar, true> >();
1344 else
1345 set_unrolled_calc_function<DC, &DC::next_i<unrolled_64, false>,
1346 &DC::next_i<unrolled, false>, &DC::next_i<scalar, false> >();
1349 template <int type, bool isZero>
1350 void next_i(int inNumSamples)
1352 if (isZero)
1353 zero_vec<type>(out(0), inNumSamples);
1354 else
1355 set_vec<type>(out(0), value, inNumSamples);
1359 DEFINE_XTORS(DC)
1361 //////////////////////////////////////////////////////////////////////////////////////////////////
1363 static inline void Line_next_loop(Line * unit, int & counter, int remain, double & level)
1365 float *out = ZOUT(0);
1366 double slope = unit->mSlope;
1368 do {
1369 if (counter==0) {
1370 int nsmps = remain;
1371 remain = 0;
1372 float endlevel = unit->mEndLevel;
1373 LOOP(nsmps,
1374 ZXP(out) = endlevel;
1376 } else {
1377 int nsmps = sc_min(remain, counter);
1378 counter -= nsmps;
1379 remain -= nsmps;
1380 LOOP(nsmps,
1381 ZXP(out) = level;
1382 level += slope;
1384 if (counter == 0) {
1385 unit->mDone = true;
1386 int doneAction = (int)ZIN0(3);
1387 DoneAction(doneAction, unit);
1390 } while (remain);
1395 void Line_next(Line *unit, int inNumSamples)
1397 double level = unit->mLevel;
1398 int counter = unit->mCounter;
1399 Line_next_loop(unit, counter, inNumSamples, level);
1400 unit->mCounter = counter;
1401 unit->mLevel = level;
1404 #ifdef NOVA_SIMD
1405 FLATTEN void Line_next_nova(Line *unit, int inNumSamples)
1407 double level = unit->mLevel;
1408 int counter = unit->mCounter;
1410 if (counter == 0)
1412 nova::setvec_simd(OUT(0), unit->mEndLevel, inNumSamples);
1413 return;
1416 if (counter > inNumSamples)
1418 double slope = unit->mSlope;
1419 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, inNumSamples);
1420 unit->mLevel = level + inNumSamples * slope;
1421 unit->mCounter = counter - inNumSamples;
1422 return;
1424 Line_next_loop(unit, counter, inNumSamples, level);
1425 unit->mCounter = counter;
1426 unit->mLevel = level;
1429 FLATTEN void Line_next_nova_64(Line *unit, int inNumSamples)
1431 double level = unit->mLevel;
1432 int counter = unit->mCounter;
1434 if (counter == 0)
1436 nova::setvec_simd<64>(OUT(0), unit->mEndLevel);
1437 return;
1440 if (counter > inNumSamples)
1442 double slope = unit->mSlope;
1443 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, 64);
1444 unit->mLevel = level + inNumSamples * slope;
1445 unit->mCounter = counter - inNumSamples;
1446 return;
1449 Line_next_loop(unit, counter, inNumSamples, level);
1450 unit->mCounter = counter;
1451 unit->mLevel = level;
1454 #endif
1456 void Line_Ctor(Line* unit)
1458 #ifdef NOVA_SIMD
1459 if (BUFLENGTH == 64)
1460 SETCALC(Line_next_nova);
1461 else if (!(BUFLENGTH & 15))
1462 SETCALC(Line_next_nova);
1463 else
1464 #endif
1465 SETCALC(Line_next);
1466 double start = ZIN0(0);
1467 double end = ZIN0(1);
1468 double dur = ZIN0(2);
1470 int counter = (int)(dur * unit->mRate->mSampleRate + .5f);
1471 unit->mCounter = sc_max(1, counter);
1472 if(counter == 0){
1473 unit->mLevel = end;
1474 unit->mSlope = 0.;
1475 } else {
1476 unit->mLevel = start;
1477 unit->mSlope = (end - start) / unit->mCounter;
1478 unit->mLevel += unit->mSlope;
1480 unit->mEndLevel = end;
1481 ZOUT0(0) = unit->mLevel;
1484 //////////////////////////////////////////////////////////////////////////////////////////////////
1486 static inline void Xline_next_loop(XLine * unit, int & counter, int remain, double & level)
1488 float *out = ZOUT(0);
1489 double grow = unit->mGrowth;
1491 do {
1492 if (counter==0) {
1493 int nsmps = remain;
1494 remain = 0;
1495 LOOP(nsmps,
1496 ZXP(out) = level;
1498 } else {
1499 int nsmps = sc_min(remain, counter);
1500 counter -= nsmps;
1501 remain -= nsmps;
1502 LOOP(nsmps,
1503 ZXP(out) = level;
1504 level *= grow;
1506 if (counter == 0) {
1507 level = unit->mEndLevel;
1508 unit->mDone = true;
1509 int doneAction = (int)ZIN0(3);
1510 DoneAction(doneAction, unit);
1513 } while (remain);
1516 void XLine_next(XLine *unit, int inNumSamples)
1518 double level = unit->mLevel;
1519 int counter = unit->mCounter;
1521 Xline_next_loop(unit, counter, inNumSamples, level);
1522 unit->mCounter = counter;
1523 unit->mLevel = level;
1526 #ifdef NOVA_SIMD
1527 FLATTEN void XLine_next_nova(XLine *unit, int inNumSamples)
1529 double level = unit->mLevel;
1530 int counter = unit->mCounter;
1532 if (counter == 0)
1534 nova::setvec_simd(OUT(0), (float)level, inNumSamples);
1535 return;
1537 if (counter > inNumSamples)
1539 double grow = unit->mGrowth;
1540 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, inNumSamples);
1541 level *= sc_powi(grow, inNumSamples);
1542 counter -= inNumSamples;
1543 } else
1544 Xline_next_loop(unit, counter, inNumSamples, level);
1545 unit->mCounter = counter;
1546 unit->mLevel = level;
1549 FLATTEN void XLine_next_nova_64(XLine *unit, int inNumSamples)
1551 double level = unit->mLevel;
1552 int counter = unit->mCounter;
1554 if (counter == 0)
1556 nova::setvec_simd<64>(OUT(0), (float)level);
1557 return;
1559 if (counter > 64)
1561 double grow = unit->mGrowth;
1562 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, 64);
1563 level *= sc_powi(grow, inNumSamples);
1564 counter -= inNumSamples;
1565 } else
1566 Xline_next_loop(unit, counter, inNumSamples, level);
1567 unit->mCounter = counter;
1568 unit->mLevel = level;
1571 #endif
1573 void XLine_Ctor(XLine* unit)
1575 #ifdef NOVA_SIMD
1576 if (BUFLENGTH == 64)
1577 SETCALC(XLine_next_nova_64);
1578 else if (!(BUFLENGTH & 15))
1579 SETCALC(XLine_next_nova);
1580 else
1581 #endif
1583 SETCALC(XLine_next);
1584 double start = ZIN0(0);
1585 double end = ZIN0(1);
1586 double dur = ZIN0(2);
1588 int counter = (int)(dur * unit->mRate->mSampleRate + .5f);
1590 unit->mEndLevel = end;
1592 if (counter == 0) {
1593 ZOUT0(0) = end;
1594 unit->mLevel = end;
1595 unit->mCounter = 0;
1596 unit->mGrowth = 0;
1597 } else {
1598 ZOUT0(0) = start;
1599 unit->mCounter = counter;
1600 unit->mGrowth = pow(end / start, 1.0 / counter);
1601 unit->mLevel = start * unit->mGrowth;
1605 //////////////////////////////////////////////////////////////////////////////////////////////////
1607 void Wrap_next(Wrap* unit, int inNumSamples)
1609 float *out = ZOUT(0);
1610 float *in = ZIN(0);
1611 float lo = unit->m_lo;
1612 float hi = unit->m_hi;
1613 float range = unit->m_range;
1615 LOOP1(inNumSamples,
1616 ZXP(out) = sc_wrap(ZXP(in), lo, hi, range);
1620 void Wrap_Ctor(Wrap* unit)
1623 SETCALC(Wrap_next);
1624 unit->m_lo = ZIN0(1);
1625 unit->m_hi = ZIN0(2);
1627 if (unit->m_lo > unit->m_hi) {
1628 float temp = unit->m_lo;
1629 unit->m_lo = unit->m_hi;
1630 unit->m_hi = temp;
1632 unit->m_range = unit->m_hi - unit->m_lo;
1634 Wrap_next(unit, 1);
1639 void Wrap_next_kk(Wrap* unit, int inNumSamples)
1641 float *out = ZOUT(0);
1642 float *in = ZIN(0);
1643 float next_lo = ZIN0(1);
1644 float next_hi = ZIN0(2);
1645 float lo = unit->m_lo;
1646 float lo_slope = CALCSLOPE(next_lo, lo);
1647 float hi = unit->m_hi;
1648 float hi_slope = CALCSLOPE(next_hi, hi);
1649 LOOP1(inNumSamples,
1650 float range = hi - lo;
1651 ZXP(out) = sc_wrap(ZXP(in), lo, hi, range);
1652 lo += lo_slope;
1653 hi += hi_slope;
1655 unit->m_lo = lo;
1656 unit->m_hi = hi;
1659 void Wrap_next_ka(Wrap* unit, int inNumSamples)
1661 float *out = ZOUT(0);
1662 float *in = ZIN(0);
1663 float next_lo = ZIN0(1);
1664 float *hi = ZIN(2);
1665 float lo = unit->m_lo;
1666 float lo_slope = CALCSLOPE(next_lo, lo);
1667 LOOP1(inNumSamples,
1668 float curhi = ZXP(hi);
1669 ZXP(out) = sc_wrap(ZXP(in), lo, curhi, curhi - lo);
1670 lo += lo_slope;
1672 unit->m_lo = lo;
1675 void Wrap_next_ak(Wrap* unit, int inNumSamples)
1677 float *out = ZOUT(0);
1678 float *in = ZIN(0);
1679 float *lo = ZIN(1);
1680 float next_hi = ZIN0(2);
1681 float hi = unit->m_hi;
1682 float hi_slope = CALCSLOPE(next_hi, hi);
1684 LOOP1(inNumSamples,
1685 float curlo = ZXP(lo);
1686 ZXP(out) = sc_wrap(ZXP(in), curlo, hi, hi - curlo);
1687 hi += hi_slope;
1689 unit->m_hi = hi;
1692 void Wrap_next_aa(Wrap* unit, int inNumSamples)
1694 float *out = ZOUT(0);
1695 float *in = ZIN(0);
1696 float *lo = ZIN(1);
1697 float *hi = ZIN(2);
1699 LOOP1(inNumSamples,
1700 float curhi = ZXP(hi);
1701 float curlo = ZXP(lo);
1702 ZXP(out) = sc_wrap(ZXP(in), curlo, curhi, curhi - curlo);
1706 void Wrap_Ctor(Wrap* unit)
1708 if(BUFLENGTH == 1) {
1709 // _aa? Well, yes - that calc func doesn't interpolate
1710 // and interpolation is not needed for kr (1 sample/block)
1711 SETCALC(Wrap_next_aa);
1712 } else {
1713 if(INRATE(1) == calc_FullRate) {
1714 if(INRATE(2) == calc_FullRate)
1715 SETCALC(Wrap_next_aa);
1716 else
1717 SETCALC(Wrap_next_ak);
1718 } else {
1719 if(INRATE(2) == calc_FullRate)
1720 SETCALC(Wrap_next_ka);
1721 else
1722 SETCALC(Wrap_next_kk);
1726 unit->m_lo = ZIN0(1);
1727 unit->m_hi = ZIN0(2);
1729 Wrap_next_kk(unit, 1);
1733 //////////////////////////////////////////////////////////////////////////////////////////////////
1735 void Fold_next(Fold* unit, int inNumSamples)
1737 float *out = ZOUT(0);
1738 float *in = ZIN(0);
1739 float lo = unit->m_lo;
1740 float hi = unit->m_hi;
1741 float range = unit->m_range;
1742 float range2 = unit->m_range2;
1744 LOOP1(inNumSamples,
1745 ZXP(out) = sc_fold(ZXP(in), lo, hi, range, range2);
1749 void Fold_Ctor(Fold* unit)
1752 SETCALC(Fold_next);
1753 unit->m_lo = ZIN0(1);
1754 unit->m_hi = ZIN0(2);
1756 if (unit->m_lo > unit->m_hi) {
1757 float temp = unit->m_lo;
1758 unit->m_lo = unit->m_hi;
1759 unit->m_hi = temp;
1761 unit->m_range = unit->m_hi - unit->m_lo;
1762 unit->m_range2 = 2.f * unit->m_range;
1764 Fold_next(unit, 1);
1767 void Fold_next_kk(Fold* unit, int inNumSamples)
1769 float *out = ZOUT(0);
1770 float *in = ZIN(0);
1771 float next_lo = ZIN0(1);
1772 float next_hi = ZIN0(2);
1773 float lo = unit->m_lo;
1774 float lo_slope = CALCSLOPE(next_lo, lo);
1775 float hi = unit->m_hi;
1776 float hi_slope = CALCSLOPE(next_hi, hi);
1778 LOOP1(inNumSamples,
1779 float range = hi - lo;
1780 float range2 = range * 2.f;
1781 ZXP(out) = sc_fold(ZXP(in), lo, hi, range, range2);
1783 lo += lo_slope;
1784 hi += hi_slope;
1786 unit->m_lo = lo;
1787 unit->m_hi = hi;
1790 void Fold_next_ka(Fold* unit, int inNumSamples)
1792 float *out = ZOUT(0);
1793 float *in = ZIN(0);
1794 float next_lo = ZIN0(1);
1795 float *hi = ZIN(2);
1796 float lo = unit->m_lo;
1797 float lo_slope = CALCSLOPE(next_lo, lo);
1799 LOOP1(inNumSamples,
1800 float curhi = ZXP(hi);
1801 float range = curhi - lo;
1802 float range2 = range * 2.f;
1803 ZXP(out) = sc_fold(ZXP(in), lo, curhi, range, range2);
1804 lo += lo_slope;
1806 unit->m_lo = lo;
1809 void Fold_next_ak(Fold* unit, int inNumSamples)
1811 float *out = ZOUT(0);
1812 float *in = ZIN(0);
1813 float *lo = ZIN(1);
1814 float next_hi = ZIN0(2);
1815 float hi = unit->m_hi;
1816 float hi_slope = CALCSLOPE(next_hi, hi);
1818 LOOP1(inNumSamples,
1819 float curlo = ZXP(lo);
1820 float range = hi - curlo;
1821 float range2 = range * 2.f;
1822 ZXP(out) = sc_fold(ZXP(in), curlo, hi, range, range2);
1823 hi += hi_slope;
1825 unit->m_hi = hi;
1828 void Fold_next_aa(Fold* unit, int inNumSamples)
1830 float *out = ZOUT(0);
1831 float *in = ZIN(0);
1832 float *lo = ZIN(1);
1833 float *hi = ZIN(2);
1835 LOOP1(inNumSamples,
1836 float curhi = ZXP(hi);
1837 float curlo = ZXP(lo);
1838 float range = curhi - curlo;
1839 float range2 = range * 2.0;
1840 ZXP(out) = sc_fold(ZXP(in), curlo, curhi, range, range2);
1844 void Fold_Ctor(Fold* unit)
1846 if(BUFLENGTH == 1) {
1847 // _aa? Well, yes - that calc func doesn't interpolate
1848 // and interpolation is not needed for kr (1 sample/block)
1849 SETCALC(Fold_next_aa);
1850 } else {
1851 if(INRATE(1) == calc_FullRate) {
1852 if(INRATE(2) == calc_FullRate)
1853 SETCALC(Fold_next_aa);
1854 else
1855 SETCALC(Fold_next_ak);
1856 } else {
1857 if(INRATE(2) == calc_FullRate)
1858 SETCALC(Fold_next_ka);
1859 else
1860 SETCALC(Fold_next_kk);
1864 unit->m_lo = ZIN0(1);
1865 unit->m_hi = ZIN0(2);
1867 Fold_next_kk(unit, 1);
1870 //////////////////////////////////////////////////////////////////////////////////////////////////
1872 void Clip_next_ii(Clip* unit, int inNumSamples)
1874 float *out = ZOUT(0);
1875 float *in = ZIN(0);
1876 float lo = unit->m_lo;
1877 float hi = unit->m_hi;
1879 LOOP1(inNumSamples,
1880 ZXP(out) = sc_clip(ZXP(in), lo, hi);
1884 void Clip_next_kk(Clip* unit, int inNumSamples)
1886 float next_lo = ZIN0(1);
1887 float next_hi = ZIN0(2);
1888 float lo = unit->m_lo;
1889 float hi = unit->m_hi;
1891 if (lo == next_lo && hi == next_hi) {
1892 Clip_next_ii(unit, inNumSamples);
1893 return;
1896 float *out = ZOUT(0);
1897 float *in = ZIN(0);
1898 float lo_slope = CALCSLOPE(next_lo, lo);
1899 float hi_slope = CALCSLOPE(next_hi, hi);
1901 LOOP1(inNumSamples,
1902 ZXP(out) = sc_clip(ZXP(in), lo, hi);
1903 lo += lo_slope;
1904 hi += hi_slope;
1906 unit->m_lo = lo;
1907 unit->m_hi = hi;
1910 void Clip_next_ka(Clip* unit, int inNumSamples)
1912 float *out = ZOUT(0);
1913 float *in = ZIN(0);
1914 float next_lo = ZIN0(1);
1915 float *hi = ZIN(2);
1916 float lo = unit->m_lo;
1917 float lo_slope = CALCSLOPE(next_lo, lo);
1919 LOOP1(inNumSamples,
1920 ZXP(out) = sc_clip(ZXP(in), lo, ZXP(hi));
1921 lo += lo_slope;
1923 unit->m_lo = lo;
1926 void Clip_next_ak(Clip* unit, int inNumSamples)
1928 float *out = ZOUT(0);
1929 float *in = ZIN(0);
1930 float *lo = ZIN(1);
1931 float next_hi = ZIN0(2);
1932 float hi = unit->m_hi;
1933 float hi_slope = CALCSLOPE(next_hi, hi);
1935 LOOP1(inNumSamples,
1936 ZXP(out) = sc_clip(ZXP(in), ZXP(lo), hi);
1937 hi += hi_slope;
1939 unit->m_hi = hi;
1942 void Clip_next_aa(Clip* unit, int inNumSamples)
1944 float *out = ZOUT(0);
1945 float *in = ZIN(0);
1946 float *lo = ZIN(1);
1947 float *hi = ZIN(2);
1949 LOOP1(inNumSamples,
1950 ZXP(out) = sc_clip(ZXP(in), ZXP(lo), ZXP(hi));
1954 void Clip_next_k(Clip* unit, int inNumSamples)
1956 float *out = ZOUT(0);
1957 float *in = ZIN(0);
1958 float lo = ZIN0(1);
1959 float hi = ZIN0(2);
1961 ZXP(out) = sc_clip(ZXP(in), lo, hi);
1964 #ifdef NOVA_SIMD
1965 void Clip_next_nova_ii(Clip* unit, int inNumSamples)
1967 float lo = unit->m_lo;
1968 float hi = unit->m_hi;
1970 nova::clip_vec_simd(OUT(0), IN(0), lo, hi, inNumSamples);
1973 void Clip_next_nova_ki(Clip* unit, int inNumSamples)
1975 float next_lo = ZIN0(1);
1976 float lo = unit->m_lo;
1977 float hi = unit->m_hi;
1979 if (lo == next_lo) {
1980 Clip_next_nova_ii(unit, inNumSamples);
1981 return;
1984 float lo_slope = CALCSLOPE(next_lo, lo);
1985 nova::clip_vec_simd(OUT(0), IN(0), slope_argument(lo, lo_slope), hi, inNumSamples);
1988 void Clip_next_nova_ik(Clip* unit, int inNumSamples)
1990 float next_hi = ZIN0(2);
1991 float lo = unit->m_lo;
1992 float hi = unit->m_hi;
1994 if (hi == next_hi) {
1995 Clip_next_nova_ii(unit, inNumSamples);
1996 return;
1999 float hi_slope = CALCSLOPE(next_hi, hi);
2000 nova::clip_vec_simd(OUT(0), IN(0), lo, slope_argument(hi, hi_slope), inNumSamples);
2003 void Clip_next_nova_kk(Clip* unit, int inNumSamples)
2005 float next_lo = ZIN0(1);
2006 float next_hi = ZIN0(2);
2007 float lo = unit->m_lo;
2008 float hi = unit->m_hi;
2010 if (lo == next_lo && hi == next_hi) {
2011 Clip_next_nova_ii(unit, inNumSamples);
2012 return;
2015 if (lo == next_lo) {
2016 Clip_next_nova_ik(unit, inNumSamples);
2017 return;
2020 if (hi == next_hi) {
2021 Clip_next_nova_ki(unit, inNumSamples);
2022 return;
2025 float lo_slope = CALCSLOPE(next_lo, lo);
2026 float hi_slope = CALCSLOPE(next_hi, hi);
2028 nova::clip_vec_simd(OUT(0), IN(0), slope_argument(lo, lo_slope), slope_argument(hi, hi_slope), inNumSamples);
2031 void Clip_next_nova_ai(Clip* unit, int inNumSamples)
2033 float hi = unit->m_hi;
2034 nova::clip_vec_simd(OUT(0), IN(0), IN(1), hi, inNumSamples);
2037 void Clip_next_nova_ak(Clip* unit, int inNumSamples)
2039 float next_hi = ZIN0(2);
2040 float hi = unit->m_hi;
2042 if (hi == next_hi) {
2043 Clip_next_nova_ai(unit, inNumSamples);
2044 return;
2047 float hi_slope = CALCSLOPE(next_hi, hi);
2049 nova::clip_vec_simd(OUT(0), IN(0), IN(1), slope_argument(hi, hi_slope), inNumSamples);
2052 void Clip_next_nova_ia(Clip* unit, int inNumSamples)
2054 float lo = unit->m_lo;
2055 nova::clip_vec_simd(OUT(0), IN(0), lo, IN(2), inNumSamples);
2058 void Clip_next_nova_ka(Clip* unit, int inNumSamples)
2060 float next_lo = ZIN0(1);
2061 float lo = unit->m_lo;
2063 if (lo == next_lo) {
2064 Clip_next_nova_ia(unit, inNumSamples);
2065 return;
2068 float lo_slope = CALCSLOPE(next_lo, lo);
2069 nova::clip_vec_simd(OUT(0), IN(0), slope_argument(lo, lo_slope), IN(2), inNumSamples);
2073 void Clip_next_nova_aa(Clip* unit, int inNumSamples)
2075 nova::clip_vec_simd(OUT(0), IN(0), IN(1), IN(2), inNumSamples);
2078 #endif
2080 typedef void (*ClipCalcFunc)(Clip*, int);
2082 static ClipCalcFunc Clip_SelectCalc(Clip * unit)
2084 if(BUFLENGTH == 1)
2085 return Clip_next_k;
2087 int loRate = INRATE(1);
2088 int hiRate = INRATE(2);
2090 #ifdef NOVA_SIMD
2091 if (!(BUFLENGTH & 15)) {
2092 switch (loRate)
2094 case calc_FullRate:
2095 switch (hiRate) {
2096 case calc_FullRate:
2097 return Clip_next_nova_aa;
2098 case calc_BufRate:
2099 return Clip_next_nova_ak;
2100 case calc_ScalarRate:
2101 return Clip_next_nova_ai;
2103 break;
2105 case calc_BufRate:
2106 switch (hiRate) {
2107 case calc_FullRate:
2108 return Clip_next_nova_ka;
2109 case calc_BufRate:
2110 return Clip_next_nova_kk;
2111 case calc_ScalarRate:
2112 return Clip_next_nova_ki;
2114 break;
2116 case calc_ScalarRate:
2117 switch (hiRate) {
2118 case calc_FullRate:
2119 return Clip_next_nova_ia;
2120 case calc_BufRate:
2121 return Clip_next_nova_ik;
2122 case calc_ScalarRate:
2123 return Clip_next_nova_ii;
2125 break;
2128 #endif
2130 if (loRate == calc_FullRate && hiRate == calc_FullRate)
2131 return Clip_next_aa;
2133 if (loRate == calc_ScalarRate && hiRate == calc_ScalarRate)
2134 return Clip_next_ii;
2136 if (loRate == calc_FullRate && hiRate != calc_FullRate)
2137 return Clip_next_ak;
2139 if (loRate != calc_FullRate && hiRate == calc_FullRate)
2140 return Clip_next_ak;
2142 return Clip_next_kk;
2145 void Clip_Ctor(Clip* unit)
2147 ClipCalcFunc fn = Clip_SelectCalc(unit);
2148 unit->mCalcFunc = (UnitCalcFunc)fn;
2150 unit->m_lo = ZIN0(1);
2151 unit->m_hi = ZIN0(2);
2153 Clip_next_ii(unit, 1);
2156 //////////////////////////////////////////////////////////////////////////////////////////////////
2158 void Unwrap_next(Unwrap* unit, int inNumSamples)
2160 float *out = ZOUT(0);
2161 float *in = ZIN(0);
2162 float range = unit->m_range;
2163 float half = unit->m_half;
2164 float prev = unit->m_prev;
2165 float offset = unit->m_offset;
2167 LOOP1(inNumSamples,
2168 float zin = ZXP(in);
2169 float diff = zin - prev;
2170 if (fabs(diff) > half) {
2171 if (zin < prev)
2172 offset += range;
2173 else
2174 offset -= range;
2176 ZXP(out) = zin + offset;
2177 prev = zin;
2179 unit->m_prev = prev;
2180 unit->m_offset = offset;
2183 void Unwrap_Ctor(Unwrap* unit)
2185 SETCALC(Unwrap_next);
2186 float in = ZIN0(0);
2187 float lo = ZIN0(1);
2188 float hi = ZIN0(2);
2190 if (lo > hi) {
2191 float temp = lo;
2192 lo = hi;
2193 hi = temp;
2195 unit->m_range = fabs(hi - lo);
2196 unit->m_half = unit->m_range * 0.5f;
2198 if (in < lo || in >= hi) unit->m_offset = floor((lo - in)/unit->m_range) * unit->m_range;
2199 else unit->m_offset = 0.f;
2201 Unwrap_next(unit, 1);
2204 //////////////////////////////////////////////////////////////////////////////////////////////////
2206 void AmpComp_next(AmpComp *unit, int inNumSamples)
2208 float *out = ZOUT(0);
2209 float *freq = ZIN(0);
2210 float rootmul = unit->m_rootmul;
2211 float xb = unit->m_exponent;
2213 LOOP1(inNumSamples,
2214 float xa = ZXP(freq);
2215 ZXP(out) = xa >= 0.f ? pow(xa, xb) * rootmul : -pow(-xa, xb) * rootmul;
2219 void AmpComp_next_kk(AmpComp *unit, int inNumSamples)
2221 float *out = ZOUT(0);
2222 float *freq = ZIN(0);
2223 float root = ZIN0(1);
2224 float xb = ZIN0(2);
2226 LOOP1(inNumSamples,
2227 float xa = root / ZXP(freq);
2228 ZXP(out) = xa >= 0.f ? pow(xa, xb) : -pow(-xa, xb);
2232 void AmpComp_Ctor(AmpComp* unit)
2234 if(INRATE(1) != calc_ScalarRate || INRATE(2) != calc_ScalarRate) {
2235 SETCALC(AmpComp_next_kk);
2236 } else {
2237 float exp = ZIN0(2);
2238 unit->m_rootmul = pow(ZIN0(1), exp);
2239 unit->m_exponent = -1.f * exp;
2240 SETCALC(AmpComp_next);
2242 AmpComp_next(unit, 1);
2246 //////////////////////////////////////////////////////////////////////////////////////////////////
2248 const double AMPCOMP_K = 3.5041384 * 10e15;
2249 const double AMPCOMP_C1 = 20.598997 * 20.598997;
2250 const double AMPCOMP_C2 = 107.65265 * 107.65265;
2251 const double AMPCOMP_C3 = 737.86223 * 737.86223;
2252 const double AMPCOMP_C4 = 12194.217 * 12194.217;
2253 const double AMPCOMP_MINLEVEL = -0.1575371167435;
2255 double AmpCompA_calcLevel(double freq)
2257 double r = freq * freq;
2258 double level = (AMPCOMP_K * r * r * r * r);
2259 double n1 = AMPCOMP_C1 + r;
2260 double n2 = AMPCOMP_C4 + r;
2261 level = level / (
2262 n1 * n1 *
2263 (AMPCOMP_C2 + r) *
2264 (AMPCOMP_C3 + r) *
2265 n2 * n2
2267 level = 1. - sqrt(level);
2268 return level;
2271 void AmpCompA_next(AmpCompA *unit, int inNumSamples)
2273 float *out = ZOUT(0);
2274 float *freq = ZIN(0);
2276 double scale = unit->m_scale;
2277 double offset = unit->m_offset;
2279 LOOP1(inNumSamples,
2280 ZXP(out) = AmpCompA_calcLevel(ZXP(freq)) * scale + offset;
2284 void AmpCompA_Ctor(AmpCompA* unit)
2286 double rootFreq = ZIN0(1);
2287 double rootLevel = AmpCompA_calcLevel(rootFreq);
2288 float minLevel = ZIN0(2);
2289 unit->m_scale = (ZIN0(3) - minLevel) / (rootLevel - AMPCOMP_MINLEVEL);
2290 unit->m_offset = minLevel - unit->m_scale * AMPCOMP_MINLEVEL;
2292 SETCALC(AmpCompA_next);
2293 AmpCompA_next(unit, 1);
2296 //////////////////////////////////////////////////////////////////////////////////////////////////
2298 void InRange_next(InRange *unit, int inNumSamples)
2300 float *out = ZOUT(0);
2301 float *in = ZIN(0);
2302 float lo = ZIN0(1);
2303 float hi = ZIN0(2);
2305 LOOP1(inNumSamples,
2306 float zin = ZXP(in);
2307 ZXP(out) = zin >= lo && zin <= hi ? 1.f : 0.f;
2311 void InRange_Ctor(InRange* unit)
2313 SETCALC(InRange_next);
2314 InRange_next(unit, 1);
2317 //////////////////////////////////////////////////////////////////////////////////////////////////
2319 void InRect_next(InRect* unit, int inNumSamples)
2321 float *out = ZOUT(0);
2322 float *inx = ZIN(0);
2323 float *iny = ZIN(1);
2324 float left = ZIN0(2);
2325 float top = ZIN0(3);
2326 float right = ZIN0(4);
2327 float bottom = ZIN0(5);
2329 LOOP1(inNumSamples,
2330 float x = ZXP(inx);
2331 float y = ZXP(iny);
2332 ZXP(out) = x >= left && x <= right && y >= top && y <= bottom ? 1.f : 0.f;
2336 void InRect_Ctor(InRect* unit)
2338 SETCALC(InRect_next);
2339 InRect_next(unit, 1);
2342 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2344 void LinExp_next(LinExp *unit, int inNumSamples)
2346 float *out = ZOUT(0);
2347 float *in = ZIN(0);
2348 float dstlo = unit->m_dstlo;
2350 float dstratio = unit->m_dstratio;
2351 float rsrcrange = unit->m_rsrcrange;
2352 float rrminuslo = unit->m_rrminuslo;
2354 LOOP1(inNumSamples,
2355 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2359 #ifdef NOVA_SIMD
2360 static inline void LinExp_next_nova_loop(float * out, const float * in, int inNumSamples,
2361 nova::vec<float> dstlo, nova::vec<float> dstratio,
2362 nova::vec<float> rsrcrange, nova::vec<float> rrminuslo)
2364 const int vecSize = nova::vec<float>::size;
2365 int unroll = inNumSamples / (2*vecSize);
2369 nova::vec<float> val0, val1;
2370 val0.load_aligned(in);
2371 val1.load_aligned(in + vecSize);
2373 val0 = dstlo * pow(dstratio, val0 * rsrcrange + rrminuslo);
2374 val1 = dstlo * pow(dstratio, val1 * rsrcrange + rrminuslo);
2376 val0.store_aligned(out);
2377 val1.store_aligned(out + vecSize);
2379 in += 2*vecSize;
2380 out += 2*vecSize;
2381 } while (--unroll);
2384 FLATTEN static void LinExp_next_nova(LinExp *unit, int inNumSamples)
2386 float *out = OUT(0);
2387 float *in = IN(0);
2389 LinExp_next_nova_loop(out, in, inNumSamples, unit->m_dstlo, unit->m_dstratio, unit->m_rsrcrange, unit->m_rrminuslo);
2392 FLATTEN static void LinExp_next_nova_kk(LinExp *unit, int inNumSamples)
2394 float *out = OUT(0);
2395 float *in = IN(0);
2397 float srclo = ZIN0(1);
2398 float srchi = ZIN0(2);
2399 float dstlo = ZIN0(3);
2400 float dsthi = ZIN0(4);
2401 float dstratio = dsthi/dstlo;
2402 float rsrcrange = 1. / (srchi - srclo);
2403 float rrminuslo = rsrcrange * -srclo;
2405 LinExp_next_nova_loop(out, in, inNumSamples, dstlo, dstratio, rsrcrange, rrminuslo);
2408 #endif
2410 void LinExp_next_kk(LinExp *unit, int inNumSamples)
2412 float *out = ZOUT(0);
2413 float *in = ZIN(0);
2414 float srclo = ZIN0(1);
2415 float srchi = ZIN0(2);
2416 float dstlo = ZIN0(3);
2417 float dsthi = ZIN0(4);
2418 float dstratio = dsthi/dstlo;
2419 float rsrcrange = 1. / (srchi - srclo);
2420 float rrminuslo = rsrcrange * -srclo;
2422 LOOP1(inNumSamples,
2423 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2427 void LinExp_next_aa(LinExp *unit, int inNumSamples)
2429 float *out = ZOUT(0);
2430 float *in = ZIN(0);
2431 float *srclo = ZIN(1);
2432 float *srchi = ZIN(2);
2433 float *dstlo = ZIN(3);
2434 float *dsthi = ZIN(4);
2437 LOOP1(inNumSamples,
2438 float zdsthi = ZXP(dsthi);
2439 float zdstlo = ZXP(dstlo);
2440 float zsrchi = ZXP(srchi);
2441 float zsrclo = ZXP(srclo);
2442 float dstratio = zdsthi/zdstlo;
2443 float rsrcrange = 1. / (zsrchi - zsrclo);
2444 float rrminuslo = rsrcrange * -zsrclo;
2445 ZXP(out) = zdstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2449 void LinExp_next_ak(LinExp *unit, int inNumSamples)
2451 float *out = ZOUT(0);
2452 float *in = ZIN(0);
2453 float *srclo = ZIN(1);
2454 float *srchi = ZIN(2);
2455 float dstlo = ZIN0(3);
2456 float dsthi = ZIN0(4);
2457 float dstratio = dsthi/dstlo;
2459 LOOP1(inNumSamples,
2460 float zsrchi = ZXP(srchi);
2461 float zsrclo = ZXP(srclo);
2463 float rsrcrange = 1. / (zsrchi - zsrclo);
2464 float rrminuslo = rsrcrange * -zsrclo;
2465 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2469 void LinExp_next_ka(LinExp *unit, int inNumSamples)
2471 float *out = ZOUT(0);
2472 float *in = ZIN(0);
2473 float srclo = ZIN0(1);
2474 float srchi = ZIN0(2);
2475 float *dstlo = ZIN(3);
2476 float *dsthi = ZIN(4);
2477 float rsrcrange = 1. / (srchi - srclo);
2478 float rrminuslo = rsrcrange * -srclo;
2480 LOOP1(inNumSamples,
2481 float zdsthi = ZXP(dsthi);
2482 float zdstlo = ZXP(dstlo);
2483 float dstratio = zdsthi/zdstlo;
2484 ZXP(out) = zdstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2489 static void LinExp_SetCalc(LinExp* unit)
2491 if(INRATE(1) == calc_FullRate || INRATE(2) == calc_FullRate) {
2492 if(INRATE(3) == calc_FullRate || INRATE(4) == calc_FullRate) {
2493 SETCALC(LinExp_next_aa); return;
2494 } else {
2495 SETCALC(LinExp_next_ak); return;
2497 } else {
2498 if(INRATE(3) == calc_FullRate || INRATE(4) == calc_FullRate) {
2499 SETCALC(LinExp_next_ka); return;
2503 bool allScalar = true;
2504 for(int i = 1; i<5; i++) {
2505 if(INRATE(i) != calc_ScalarRate) {
2506 allScalar = false;
2507 break;
2511 #ifdef NOVA_SIMD
2512 if ((BUFLENGTH % (2*nova::vec<float>::size)) == 0)
2513 if (allScalar)
2514 SETCALC(LinExp_next_nova);
2515 else
2516 SETCALC(LinExp_next_nova_kk);
2517 else
2518 #endif
2519 if (allScalar)
2520 SETCALC(LinExp_next);
2521 else
2522 SETCALC(LinExp_next_kk);
2524 if (!allScalar)
2525 return;
2527 float srclo = ZIN0(1);
2528 float srchi = ZIN0(2);
2529 float dstlo = ZIN0(3);
2530 float dsthi = ZIN0(4);
2531 unit->m_dstlo = dstlo;
2532 unit->m_dstratio = dsthi/dstlo;
2533 unit->m_rsrcrange = 1. / (srchi - srclo);
2534 unit->m_rrminuslo = unit->m_rsrcrange * -srclo;
2537 void LinExp_Ctor(LinExp* unit)
2539 LinExp_SetCalc(unit);
2540 float srclo = ZIN0(1);
2541 float srchi = ZIN0(2);
2542 float dstlo = ZIN0(3);
2543 float dsthi = ZIN0(4);
2544 unit->m_dstlo = dstlo;
2545 unit->m_dstratio = dsthi/dstlo;
2546 unit->m_rsrcrange = 1. / (srchi - srclo);
2547 unit->m_rrminuslo = unit->m_rsrcrange * -srclo;
2548 LinExp_next(unit, 1);
2551 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2554 enum {
2555 kEnvGen_gate,
2556 kEnvGen_levelScale,
2557 kEnvGen_levelBias,
2558 kEnvGen_timeScale,
2559 kEnvGen_doneAction,
2560 kEnvGen_initLevel,
2561 kEnvGen_numStages,
2562 kEnvGen_releaseNode,
2563 kEnvGen_loopNode,
2564 // 'kEnvGen_nodeOffset' must always be last
2565 // if you need to add an arg, put it before this one
2566 kEnvGen_nodeOffset
2569 #ifdef NOVA_SIMD
2570 void EnvGen_next_ak_nova(EnvGen *unit, int inNumSamples);
2571 #endif
2573 void EnvGen_Ctor(EnvGen *unit)
2575 //Print("EnvGen_Ctor A\n");
2576 if (unit->mCalcRate == calc_FullRate) {
2577 if (INRATE(0) == calc_FullRate) {
2578 SETCALC(EnvGen_next_aa);
2579 } else {
2580 #ifdef NOVA_SIMD
2581 if (!(BUFLENGTH & 15))
2582 SETCALC(EnvGen_next_ak_nova);
2583 else
2584 #endif
2585 SETCALC(EnvGen_next_ak);
2587 } else {
2588 SETCALC(EnvGen_next_k);
2591 // gate = 1.0, levelScale = 1.0, levelBias = 0.0, timeScale
2592 // level0, numstages, releaseNode, loopNode,
2593 // [level, dur, shape, curve]
2595 unit->m_endLevel = unit->m_level = ZIN0(kEnvGen_initLevel) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2596 unit->m_counter = 0;
2597 unit->m_stage = 1000000000;
2598 unit->m_prevGate = 0.f;
2599 unit->m_released = false;
2600 unit->m_releaseNode = (int)ZIN0(kEnvGen_releaseNode);
2601 EnvGen_next_k(unit, 1);
2604 enum {
2605 shape_Step,
2606 shape_Linear,
2607 shape_Exponential,
2608 shape_Sine,
2609 shape_Welch,
2610 shape_Curve,
2611 shape_Squared,
2612 shape_Cubed,
2613 shape_Sustain = 9999
2616 void EnvGen_next_k(EnvGen *unit, int inNumSamples)
2618 float *out = OUT(0);
2619 float gate = ZIN0(kEnvGen_gate);
2620 //Print("->EnvGen_next_k gate %g\n", gate);
2621 int counter = unit->m_counter;
2622 double level = unit->m_level;
2624 if (unit->m_prevGate <= 0. && gate > 0.) {
2625 unit->m_stage = -1;
2626 unit->mDone = false;
2627 unit->m_released = false;
2628 counter = 0;
2629 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
2630 // cutoff
2631 int numstages = (int)ZIN0(kEnvGen_numStages);
2632 float dur = -gate - 1.f;
2633 counter = (int32)(dur * SAMPLERATE);
2634 counter = sc_max(1, counter);
2635 unit->m_stage = numstages;
2636 unit->m_shape = shape_Linear;
2637 // first ZIN0 gets the last envelope node's level, then apply levelScale and levelBias
2638 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2639 unit->m_grow = (unit->m_endLevel - level) / counter;
2640 } else if (unit->m_prevGate > 0.f && gate <= 0.f
2641 && unit->m_releaseNode >= 0 && !unit->m_released) {
2642 counter = 0;
2643 unit->m_stage = unit->m_releaseNode - 1;
2644 unit->m_released = true;
2646 unit->m_prevGate = gate;
2649 // gate = 1.0, levelScale = 1.0, levelBias = 0.0, timeScale
2650 // level0, numstages, releaseNode, loopNode,
2651 // [level, dur, shape, curve]
2653 if (counter <= 0) {
2654 //Print("stage %d rel %d\n", unit->m_stage, (int)ZIN0(kEnvGen_releaseNode));
2655 int numstages = (int)ZIN0(kEnvGen_numStages);
2657 //Print("stage %d numstages %d\n", unit->m_stage, numstages);
2658 if (unit->m_stage+1 >= numstages) { // num stages
2659 //Print("stage+1 > num stages\n");
2660 counter = INT_MAX;
2661 unit->m_shape = 0;
2662 level = unit->m_endLevel;
2663 unit->mDone = true;
2664 int doneAction = (int)ZIN0(kEnvGen_doneAction);
2665 DoneAction(doneAction, unit);
2666 } else if (unit->m_stage+1 == unit->m_releaseNode && !unit->m_released) { // sustain stage
2667 int loopNode = (int)ZIN0(kEnvGen_loopNode);
2668 if (loopNode >= 0 && loopNode < numstages) {
2669 unit->m_stage = loopNode;
2670 goto initSegment;
2671 } else {
2672 counter = INT_MAX;
2673 unit->m_shape = shape_Sustain;
2674 level = unit->m_endLevel;
2676 //Print("sustain\n");
2677 } else {
2678 unit->m_stage++;
2679 initSegment:
2680 //Print("stage %d\n", unit->m_stage);
2681 //Print("initSegment\n");
2682 //out = unit->m_level;
2683 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
2685 if (stageOffset + 4 > unit->mNumInputs) {
2686 // oops.
2687 Print("envelope went past end of inputs.\n");
2688 ClearUnitOutputs(unit, 1);
2689 NodeEnd(&unit->mParent->mNode);
2690 return;
2693 float** envPtr = unit->mInBuf + stageOffset;
2694 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
2695 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
2696 unit->m_shape = (int32)*envPtr[2];
2697 double curve = *envPtr[3];
2698 unit->m_endLevel = endLevel;
2700 counter = (int32)(dur * SAMPLERATE);
2701 counter = sc_max(1, counter);
2702 //Print("stageOffset %d level %g endLevel %g dur %g shape %d curve %g\n", stageOffset, level, endLevel, dur, unit->m_shape, curve);
2703 //Print("SAMPLERATE %g\n", SAMPLERATE);
2704 if (counter == 1) unit->m_shape = 1; // shape_Linear
2705 //Print("new counter = %d shape = %d\n", counter, unit->m_shape);
2706 switch (unit->m_shape) {
2707 case shape_Step : {
2708 level = endLevel;
2709 } break;
2710 case shape_Linear : {
2711 unit->m_grow = (endLevel - level) / counter;
2712 //Print("grow %g\n", unit->m_grow);
2713 } break;
2714 case shape_Exponential : {
2715 unit->m_grow = pow(endLevel / level, 1.0 / counter);
2716 } break;
2717 case shape_Sine : {
2718 double w = pi / counter;
2720 unit->m_a2 = (endLevel + level) * 0.5;
2721 unit->m_b1 = 2. * cos(w);
2722 unit->m_y1 = (endLevel - level) * 0.5;
2723 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
2724 level = unit->m_a2 - unit->m_y1;
2725 } break;
2726 case shape_Welch : {
2727 double w = (pi * 0.5) / counter;
2729 unit->m_b1 = 2. * cos(w);
2731 if (endLevel >= level) {
2732 unit->m_a2 = level;
2733 unit->m_y1 = 0.;
2734 unit->m_y2 = -sin(w) * (endLevel - level);
2735 } else {
2736 unit->m_a2 = endLevel;
2737 unit->m_y1 = level - endLevel;
2738 unit->m_y2 = cos(w) * (level - endLevel);
2740 level = unit->m_a2 + unit->m_y1;
2741 } break;
2742 case shape_Curve : {
2743 if (fabs(curve) < 0.001) {
2744 unit->m_shape = 1; // shape_Linear
2745 unit->m_grow = (endLevel - level) / counter;
2746 } else {
2747 double a1 = (endLevel - level) / (1.0 - exp(curve));
2748 unit->m_a2 = level + a1;
2749 unit->m_b1 = a1;
2750 unit->m_grow = exp(curve / counter);
2752 } break;
2753 case shape_Squared : {
2754 unit->m_y1 = sqrt(level);
2755 unit->m_y2 = sqrt(endLevel);
2756 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2757 } break;
2758 case shape_Cubed : {
2759 unit->m_y1 = pow(level, 0.33333333);
2760 unit->m_y2 = pow(endLevel, 0.33333333);
2761 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2762 } break;
2768 switch (unit->m_shape) {
2769 case shape_Step : {
2770 } break;
2771 case shape_Linear : {
2772 double grow = unit->m_grow;
2773 //Print("level %g\n", level);
2774 level += grow;
2775 } break;
2776 case shape_Exponential : {
2777 double grow = unit->m_grow;
2778 level *= grow;
2779 } break;
2780 case shape_Sine : {
2781 double a2 = unit->m_a2;
2782 double b1 = unit->m_b1;
2783 double y2 = unit->m_y2;
2784 double y1 = unit->m_y1;
2785 double y0 = b1 * y1 - y2;
2786 level = a2 - y0;
2787 y2 = y1;
2788 y1 = y0;
2789 unit->m_y1 = y1;
2790 unit->m_y2 = y2;
2791 } break;
2792 case shape_Welch : {
2793 double a2 = unit->m_a2;
2794 double b1 = unit->m_b1;
2795 double y2 = unit->m_y2;
2796 double y1 = unit->m_y1;
2797 double y0 = b1 * y1 - y2;
2798 level = a2 + y0;
2799 y2 = y1;
2800 y1 = y0;
2801 unit->m_y1 = y1;
2802 unit->m_y2 = y2;
2803 } break;
2804 case shape_Curve : {
2805 double a2 = unit->m_a2;
2806 double b1 = unit->m_b1;
2807 double grow = unit->m_grow;
2808 b1 *= grow;
2809 level = a2 - b1;
2810 unit->m_b1 = b1;
2811 } break;
2812 case shape_Squared : {
2813 double grow = unit->m_grow;
2814 double y1 = unit->m_y1;
2815 y1 += grow;
2816 level = y1*y1;
2817 unit->m_y1 = y1;
2818 } break;
2819 case shape_Cubed : {
2820 double grow = unit->m_grow;
2821 double y1 = unit->m_y1;
2822 y1 += grow;
2823 level = y1*y1*y1;
2824 unit->m_y1 = y1;
2825 } break;
2826 case shape_Sustain : {
2827 } break;
2829 *out = level;
2830 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, *out);
2831 unit->m_level = level;
2832 unit->m_counter = counter - 1;
2836 void EnvGen_next_ak(EnvGen *unit, int inNumSamples)
2838 float *out = ZOUT(0);
2839 float gate = ZIN0(kEnvGen_gate);
2840 int counter = unit->m_counter;
2841 double level = unit->m_level;
2843 if (unit->m_prevGate <= 0. && gate > 0.) {
2844 unit->m_stage = -1;
2845 unit->mDone = false;
2846 unit->m_released = false;
2847 counter = 0;
2848 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
2849 // cutoff
2850 int numstages = (int)ZIN0(kEnvGen_numStages);
2851 float dur = -gate - 1.f;
2852 counter = (int32)(dur * SAMPLERATE);
2853 counter = sc_max(1, counter);
2854 unit->m_stage = numstages;
2855 unit->m_shape = shape_Linear;
2856 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2857 unit->m_grow = (unit->m_endLevel - level) / counter;
2858 } else if (unit->m_prevGate > 0.f && gate <= 0.f
2859 && unit->m_releaseNode >= 0 && !unit->m_released) {
2860 counter = 0;
2861 unit->m_stage = unit->m_releaseNode - 1;
2862 unit->m_released = true;
2864 unit->m_prevGate = gate;
2866 int remain = inNumSamples;
2867 while (remain)
2869 if (counter == 0) {
2870 int numstages = (int)ZIN0(kEnvGen_numStages);
2872 if (unit->m_stage+1 >= numstages) { // num stages
2873 counter = INT_MAX;
2874 unit->m_shape = 0;
2875 level = unit->m_endLevel;
2876 unit->mDone = true;
2877 int doneAction = (int)ZIN0(kEnvGen_doneAction);
2878 DoneAction(doneAction, unit);
2879 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
2880 int loopNode = (int)ZIN0(kEnvGen_loopNode);
2881 if (loopNode >= 0 && loopNode < numstages) {
2882 unit->m_stage = loopNode;
2883 goto initSegment;
2884 } else {
2885 counter = INT_MAX;
2886 unit->m_shape = shape_Sustain;
2887 level = unit->m_endLevel;
2889 } else {
2890 unit->m_stage++;
2891 initSegment:
2892 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
2894 if (stageOffset + 4 > unit->mNumInputs) {
2895 // oops.
2896 Print("envelope went past end of inputs.\n");
2897 ClearUnitOutputs(unit, 1);
2898 NodeEnd(&unit->mParent->mNode);
2899 return;
2902 float** envPtr = unit->mInBuf + stageOffset;
2903 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
2904 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
2905 unit->m_shape = (int32)*envPtr[2];
2906 double curve = *envPtr[3];
2907 unit->m_endLevel = endLevel;
2909 counter = (int32)(dur * SAMPLERATE);
2910 counter = sc_max(1, counter);
2912 if (counter == 1) unit->m_shape = 1; // shape_Linear
2913 switch (unit->m_shape) {
2914 case shape_Step : {
2915 level = endLevel;
2916 } break;
2917 case shape_Linear : {
2918 unit->m_grow = (endLevel - level) / counter;
2919 } break;
2920 case shape_Exponential : {
2921 unit->m_grow = pow(endLevel / level, 1.0 / counter);
2922 } break;
2923 case shape_Sine : {
2924 double w = pi / counter;
2926 unit->m_a2 = (endLevel + level) * 0.5;
2927 unit->m_b1 = 2. * cos(w);
2928 unit->m_y1 = (endLevel - level) * 0.5;
2929 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
2930 level = unit->m_a2 - unit->m_y1;
2931 } break;
2932 case shape_Welch : {
2933 double w = (pi * 0.5) / counter;
2935 unit->m_b1 = 2. * cos(w);
2937 if (endLevel >= level) {
2938 unit->m_a2 = level;
2939 unit->m_y1 = 0.;
2940 unit->m_y2 = -sin(w) * (endLevel - level);
2941 } else {
2942 unit->m_a2 = endLevel;
2943 unit->m_y1 = level - endLevel;
2944 unit->m_y2 = cos(w) * (level - endLevel);
2946 level = unit->m_a2 + unit->m_y1;
2947 } break;
2948 case shape_Curve : {
2949 if (fabs(curve) < 0.001) {
2950 unit->m_shape = 1; // shape_Linear
2951 unit->m_grow = (endLevel - level) / counter;
2952 } else {
2953 double a1 = (endLevel - level) / (1.0 - exp(curve));
2954 unit->m_a2 = level + a1;
2955 unit->m_b1 = a1;
2956 unit->m_grow = exp(curve / counter);
2958 } break;
2959 case shape_Squared : {
2960 unit->m_y1 = sqrt(level);
2961 unit->m_y2 = sqrt(endLevel);
2962 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2963 } break;
2964 case shape_Cubed : {
2965 unit->m_y1 = pow(level, 0.33333333);
2966 unit->m_y2 = pow(endLevel, 0.33333333);
2967 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2968 } break;
2973 int nsmps = sc_min(remain, counter);
2974 switch (unit->m_shape) {
2975 case shape_Step : {
2976 for (int i=0; i<nsmps; ++i) {
2977 ZXP(out) = level;
2979 } break;
2980 case shape_Linear : {
2981 double grow = unit->m_grow;
2982 for (int i=0; i<nsmps; ++i) {
2983 ZXP(out) = level;
2984 level += grow;
2986 } break;
2987 case shape_Exponential : {
2988 double grow = unit->m_grow;
2989 for (int i=0; i<nsmps; ++i) {
2990 ZXP(out) = level;
2991 level *= grow;
2993 } break;
2994 case shape_Sine : {
2995 double a2 = unit->m_a2;
2996 double b1 = unit->m_b1;
2997 double y2 = unit->m_y2;
2998 double y1 = unit->m_y1;
2999 for (int i=0; i<nsmps; ++i) {
3000 ZXP(out) = level;
3001 double y0 = b1 * y1 - y2;
3002 level = a2 - y0;
3003 y2 = y1;
3004 y1 = y0;
3006 unit->m_y1 = y1;
3007 unit->m_y2 = y2;
3008 } break;
3009 case shape_Welch : {
3010 double a2 = unit->m_a2;
3011 double b1 = unit->m_b1;
3012 double y2 = unit->m_y2;
3013 double y1 = unit->m_y1;
3014 for (int i=0; i<nsmps; ++i) {
3015 ZXP(out) = level;
3016 double y0 = b1 * y1 - y2;
3017 level = a2 + y0;
3018 y2 = y1;
3019 y1 = y0;
3021 unit->m_y1 = y1;
3022 unit->m_y2 = y2;
3023 } break;
3024 case shape_Curve : {
3025 double a2 = unit->m_a2;
3026 double b1 = unit->m_b1;
3027 double grow = unit->m_grow;
3028 for (int i=0; i<nsmps; ++i) {
3029 ZXP(out) = level;
3030 b1 *= grow;
3031 level = a2 - b1;
3033 unit->m_b1 = b1;
3034 } break;
3035 case shape_Squared : {
3036 double grow = unit->m_grow;
3037 double y1 = unit->m_y1;
3038 for (int i=0; i<nsmps; ++i) {
3039 ZXP(out) = level;
3040 y1 += grow;
3041 level = y1*y1;
3043 unit->m_y1 = y1;
3044 } break;
3045 case shape_Cubed : {
3046 double grow = unit->m_grow;
3047 double y1 = unit->m_y1;
3048 for (int i=0; i<nsmps; ++i) {
3049 ZXP(out) = level;
3050 y1 += grow;
3051 level = y1*y1*y1;
3053 unit->m_y1 = y1;
3054 } break;
3055 case shape_Sustain : {
3056 for (int i=0; i<nsmps; ++i) {
3057 ZXP(out) = level;
3059 } break;
3061 remain -= nsmps;
3062 counter -= nsmps;
3064 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, ZOUT0(0));
3065 unit->m_level = level;
3066 unit->m_counter = counter;
3070 #ifdef NOVA_SIMD
3071 FLATTEN void EnvGen_next_ak_nova(EnvGen *unit, int inNumSamples)
3073 float *out = ZOUT(0);
3074 float gate = ZIN0(kEnvGen_gate);
3075 int counter = unit->m_counter;
3076 double level = unit->m_level;
3078 if (unit->m_prevGate <= 0. && gate > 0.) {
3079 unit->m_stage = -1;
3080 unit->mDone = false;
3081 unit->m_released = false;
3082 counter = 0;
3083 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
3084 // cutoff
3085 int numstages = (int)ZIN0(kEnvGen_numStages);
3086 float dur = -gate - 1.f;
3087 counter = (int32)(dur * SAMPLERATE);
3088 counter = sc_max(1, counter);
3089 unit->m_stage = numstages;
3090 unit->m_shape = shape_Linear;
3091 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
3092 unit->m_grow = (unit->m_endLevel - level) / counter;
3093 } else if (unit->m_prevGate > 0.f && gate <= 0.f
3094 && unit->m_releaseNode >= 0 && !unit->m_released) {
3095 counter = 0;
3096 unit->m_stage = unit->m_releaseNode - 1;
3097 unit->m_released = true;
3099 unit->m_prevGate = gate;
3101 int remain = inNumSamples;
3102 if (counter > inNumSamples)
3104 switch (unit->m_shape) {
3105 case shape_Step :
3106 case shape_Sustain :
3107 nova::setvec_simd(OUT(0), (float)level, inNumSamples);
3108 remain = 0;
3109 counter -= inNumSamples;
3110 break;
3111 case shape_Linear : {
3112 double slope = unit->m_grow;
3113 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, inNumSamples);
3114 level += 64 * slope;
3115 remain = 0;
3116 counter -= inNumSamples;
3117 } break;
3118 case shape_Exponential : {
3119 double grow = unit->m_grow;
3120 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, inNumSamples);
3121 level *= sc_powi(grow, inNumSamples);
3122 remain = 0;
3123 counter -= inNumSamples;
3124 } break;
3128 while (remain)
3130 if (counter == 0) {
3131 int numstages = (int)ZIN0(kEnvGen_numStages);
3133 if (unit->m_stage+1 >= numstages) { // num stages
3134 counter = INT_MAX;
3135 unit->m_shape = 0;
3136 level = unit->m_endLevel;
3137 unit->mDone = true;
3138 int doneAction = (int)ZIN0(kEnvGen_doneAction);
3139 DoneAction(doneAction, unit);
3140 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
3141 int loopNode = (int)ZIN0(kEnvGen_loopNode);
3142 if (loopNode >= 0 && loopNode < numstages) {
3143 unit->m_stage = loopNode;
3144 goto initSegment;
3145 } else {
3146 counter = INT_MAX;
3147 unit->m_shape = shape_Sustain;
3148 level = unit->m_endLevel;
3150 } else {
3151 unit->m_stage++;
3152 initSegment:
3153 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
3155 if (stageOffset + 4 > unit->mNumInputs) {
3156 // oops.
3157 Print("envelope went past end of inputs.\n");
3158 ClearUnitOutputs(unit, 1);
3159 NodeEnd(&unit->mParent->mNode);
3160 return;
3163 float** envPtr = unit->mInBuf + stageOffset;
3164 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
3165 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
3166 unit->m_shape = (int32)*envPtr[2];
3167 double curve = *envPtr[3];
3168 unit->m_endLevel = endLevel;
3170 counter = (int32)(dur * SAMPLERATE);
3171 counter = sc_max(1, counter);
3173 if (counter == 1) unit->m_shape = 1; // shape_Linear
3174 switch (unit->m_shape) {
3175 case shape_Step : {
3176 level = endLevel;
3177 } break;
3178 case shape_Linear : {
3179 unit->m_grow = (endLevel - level) / counter;
3180 } break;
3181 case shape_Exponential : {
3182 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3183 } break;
3184 case shape_Sine : {
3185 double w = pi / counter;
3187 unit->m_a2 = (endLevel + level) * 0.5;
3188 unit->m_b1 = 2. * cos(w);
3189 unit->m_y1 = (endLevel - level) * 0.5;
3190 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3191 level = unit->m_a2 - unit->m_y1;
3192 } break;
3193 case shape_Welch : {
3194 double w = (pi * 0.5) / counter;
3196 unit->m_b1 = 2. * cos(w);
3198 if (endLevel >= level) {
3199 unit->m_a2 = level;
3200 unit->m_y1 = 0.;
3201 unit->m_y2 = -sin(w) * (endLevel - level);
3202 } else {
3203 unit->m_a2 = endLevel;
3204 unit->m_y1 = level - endLevel;
3205 unit->m_y2 = cos(w) * (level - endLevel);
3207 level = unit->m_a2 + unit->m_y1;
3208 } break;
3209 case shape_Curve : {
3210 if (fabs(curve) < 0.001) {
3211 unit->m_shape = 1; // shape_Linear
3212 unit->m_grow = (endLevel - level) / counter;
3213 } else {
3214 double a1 = (endLevel - level) / (1.0 - exp(curve));
3215 unit->m_a2 = level + a1;
3216 unit->m_b1 = a1;
3217 unit->m_grow = exp(curve / counter);
3219 } break;
3220 case shape_Squared : {
3221 unit->m_y1 = sqrt(level);
3222 unit->m_y2 = sqrt(endLevel);
3223 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3224 } break;
3225 case shape_Cubed : {
3226 unit->m_y1 = pow(level, 0.33333333);
3227 unit->m_y2 = pow(endLevel, 0.33333333);
3228 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3229 } break;
3234 int nsmps = sc_min(remain, counter);
3235 switch (unit->m_shape) {
3236 case shape_Step : {
3237 for (int i=0; i<nsmps; ++i) {
3238 ZXP(out) = level;
3240 } break;
3241 case shape_Linear : {
3242 double grow = unit->m_grow;
3243 for (int i=0; i<nsmps; ++i) {
3244 ZXP(out) = level;
3245 level += grow;
3247 } break;
3248 case shape_Exponential : {
3249 double grow = unit->m_grow;
3250 for (int i=0; i<nsmps; ++i) {
3251 ZXP(out) = level;
3252 level *= grow;
3254 } break;
3255 case shape_Sine : {
3256 double a2 = unit->m_a2;
3257 double b1 = unit->m_b1;
3258 double y2 = unit->m_y2;
3259 double y1 = unit->m_y1;
3260 for (int i=0; i<nsmps; ++i) {
3261 ZXP(out) = level;
3262 double y0 = b1 * y1 - y2;
3263 level = a2 - y0;
3264 y2 = y1;
3265 y1 = y0;
3267 unit->m_y1 = y1;
3268 unit->m_y2 = y2;
3269 } break;
3270 case shape_Welch : {
3271 double a2 = unit->m_a2;
3272 double b1 = unit->m_b1;
3273 double y2 = unit->m_y2;
3274 double y1 = unit->m_y1;
3275 for (int i=0; i<nsmps; ++i) {
3276 ZXP(out) = level;
3277 double y0 = b1 * y1 - y2;
3278 level = a2 + y0;
3279 y2 = y1;
3280 y1 = y0;
3282 unit->m_y1 = y1;
3283 unit->m_y2 = y2;
3284 } break;
3285 case shape_Curve : {
3286 double a2 = unit->m_a2;
3287 double b1 = unit->m_b1;
3288 double grow = unit->m_grow;
3289 for (int i=0; i<nsmps; ++i) {
3290 ZXP(out) = level;
3291 b1 *= grow;
3292 level = a2 - b1;
3294 unit->m_b1 = b1;
3295 } break;
3296 case shape_Squared : {
3297 double grow = unit->m_grow;
3298 double y1 = unit->m_y1;
3299 for (int i=0; i<nsmps; ++i) {
3300 ZXP(out) = level;
3301 y1 += grow;
3302 level = y1*y1;
3304 unit->m_y1 = y1;
3305 } break;
3306 case shape_Cubed : {
3307 double grow = unit->m_grow;
3308 double y1 = unit->m_y1;
3309 for (int i=0; i<nsmps; ++i) {
3310 ZXP(out) = level;
3311 y1 += grow;
3312 level = y1*y1*y1;
3314 unit->m_y1 = y1;
3315 } break;
3316 case shape_Sustain : {
3317 for (int i=0; i<nsmps; ++i) {
3318 ZXP(out) = level;
3320 } break;
3322 remain -= nsmps;
3323 counter -= nsmps;
3325 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, ZOUT0(0));
3326 unit->m_level = level;
3327 unit->m_counter = counter;
3330 #endif
3332 #define CHECK_GATE \
3333 float prevGate = gate; \
3334 gate = ZXP(gatein); \
3335 if (prevGate <= 0.f && gate > 0.f) { \
3336 gatein--; \
3337 unit->m_stage = -1; \
3338 unit->m_released = false; \
3339 unit->mDone = false; \
3340 counter = i; \
3341 nsmps = i; \
3342 break; \
3343 } else if (gate <= -1.f && unit->m_prevGate > -1.f) { \
3344 int numstages = (int)ZIN0(kEnvGen_numStages); \
3345 float dur = -gate - 1.f; \
3346 gatein--; \
3347 counter = (int32)(dur * SAMPLERATE); \
3348 counter = sc_max(1, counter) + i; \
3349 unit->m_stage = numstages; \
3350 unit->m_shape = shape_Linear; \
3351 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); \
3352 unit->m_grow = (unit->m_endLevel - level) / counter; \
3353 nsmps = i; \
3354 break; \
3355 } else if (prevGate > 0.f && gate <= 0.f \
3356 && unit->m_releaseNode >= 0 && !unit->m_released) { \
3357 gatein--; \
3358 counter = i; \
3359 unit->m_stage = unit->m_releaseNode - 1; \
3360 unit->m_released = true; \
3361 nsmps = i; \
3362 break; \
3366 void EnvGen_next_aa(EnvGen *unit, int inNumSamples)
3368 float *out = ZOUT(0);
3369 float *gatein = ZIN(kEnvGen_gate);
3370 int counter = unit->m_counter;
3371 double level = unit->m_level;
3372 float gate = unit->m_prevGate;
3373 int remain = inNumSamples;
3374 while (remain)
3376 if (counter == 0) {
3378 int numstages = (int)ZIN0(kEnvGen_numStages);
3380 if (unit->m_stage+1 >= numstages) { // num stages
3381 counter = INT_MAX;
3382 unit->m_shape = 0;
3383 level = unit->m_endLevel;
3384 unit->mDone = true;
3385 int doneAction = (int)ZIN0(kEnvGen_doneAction);
3386 DoneAction(doneAction, unit);
3387 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
3388 int loopNode = (int)ZIN0(kEnvGen_loopNode);
3389 if (loopNode >= 0 && loopNode < numstages) {
3390 unit->m_stage = loopNode;
3391 goto initSegment;
3392 } else {
3393 counter = INT_MAX;
3394 unit->m_shape = shape_Sustain;
3395 level = unit->m_endLevel;
3397 } else {
3398 unit->m_stage++;
3399 initSegment:
3400 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
3402 if (stageOffset + 4 > unit->mNumInputs) {
3403 // oops.
3404 Print("envelope went past end of inputs.\n");
3405 ClearUnitOutputs(unit, 1);
3406 NodeEnd(&unit->mParent->mNode);
3407 return;
3410 float** envPtr = unit->mInBuf + stageOffset;
3411 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
3412 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
3413 unit->m_shape = (int32)*envPtr[2];
3414 double curve = *envPtr[3];
3415 unit->m_endLevel = endLevel;
3417 counter = (int32)(dur * SAMPLERATE);
3418 counter = sc_max(1, counter);
3419 if (counter == 1) unit->m_shape = 1; // shape_Linear
3420 switch (unit->m_shape) {
3421 case shape_Step : {
3422 level = endLevel;
3423 } break;
3424 case shape_Linear : {
3425 unit->m_grow = (endLevel - level) / counter;
3426 } break;
3427 case shape_Exponential : {
3428 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3429 } break;
3430 case shape_Sine : {
3431 double w = pi / counter;
3433 unit->m_a2 = (endLevel + level) * 0.5;
3434 unit->m_b1 = 2. * cos(w);
3435 unit->m_y1 = (endLevel - level) * 0.5;
3436 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3437 level = unit->m_a2 - unit->m_y1;
3438 } break;
3439 case shape_Welch : {
3440 double w = (pi * 0.5) / counter;
3442 unit->m_b1 = 2. * cos(w);
3444 if (endLevel >= level) {
3445 unit->m_a2 = level;
3446 unit->m_y1 = 0.;
3447 unit->m_y2 = -sin(w) * (endLevel - level);
3448 } else {
3449 unit->m_a2 = endLevel;
3450 unit->m_y1 = level - endLevel;
3451 unit->m_y2 = cos(w) * (level - endLevel);
3453 level = unit->m_a2 + unit->m_y1;
3454 } break;
3455 case shape_Curve : {
3456 if (fabs(curve) < 0.001) {
3457 unit->m_shape = 1; // shape_Linear
3458 unit->m_grow = (endLevel - level) / counter;
3459 } else {
3460 double a1 = (endLevel - level) / (1.0 - exp(curve));
3461 unit->m_a2 = level + a1;
3462 unit->m_b1 = a1;
3463 unit->m_grow = exp(curve / counter);
3465 } break;
3466 case shape_Squared : {
3467 unit->m_y1 = sqrt(level);
3468 unit->m_y2 = sqrt(endLevel);
3469 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3470 } break;
3471 case shape_Cubed : {
3472 unit->m_y1 = pow(level, 0.33333333);
3473 unit->m_y2 = pow(endLevel, 0.33333333);
3474 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3475 } break;
3480 int nsmps = sc_min(remain, counter);
3482 switch (unit->m_shape) {
3483 case shape_Step : {
3484 for (int i=0; i<nsmps; ++i) {
3485 CHECK_GATE
3486 ZXP(out) = level;
3488 } break;
3489 case shape_Linear : {
3490 double grow = unit->m_grow;
3491 for (int i=0; i<nsmps; ++i) {
3492 CHECK_GATE
3493 ZXP(out) = level;
3494 level += grow;
3496 } break;
3497 case shape_Exponential : {
3498 double grow = unit->m_grow;
3499 for (int i=0; i<nsmps; ++i) {
3500 CHECK_GATE
3501 ZXP(out) = level;
3502 level *= grow;
3504 } break;
3505 case shape_Sine : {
3506 double a2 = unit->m_a2;
3507 double b1 = unit->m_b1;
3508 double y2 = unit->m_y2;
3509 double y1 = unit->m_y1;
3510 for (int i=0; i<nsmps; ++i) {
3511 CHECK_GATE
3512 ZXP(out) = level;
3513 double y0 = b1 * y1 - y2;
3514 level = a2 - y0;
3515 y2 = y1;
3516 y1 = y0;
3518 unit->m_y1 = y1;
3519 unit->m_y2 = y2;
3520 } break;
3521 case shape_Welch : {
3522 double a2 = unit->m_a2;
3523 double b1 = unit->m_b1;
3524 double y2 = unit->m_y2;
3525 double y1 = unit->m_y1;
3526 for (int i=0; i<nsmps; ++i) {
3527 CHECK_GATE
3528 ZXP(out) = level;
3529 double y0 = b1 * y1 - y2;
3530 level = a2 + y0;
3531 y2 = y1;
3532 y1 = y0;
3534 unit->m_y1 = y1;
3535 unit->m_y2 = y2;
3536 } break;
3537 case shape_Curve : {
3538 double a2 = unit->m_a2;
3539 double b1 = unit->m_b1;
3540 double grow = unit->m_grow;
3541 for (int i=0; i<nsmps; ++i) {
3542 CHECK_GATE
3543 ZXP(out) = level;
3544 b1 *= grow;
3545 level = a2 - b1;
3547 unit->m_b1 = b1;
3548 } break;
3549 case shape_Squared : {
3550 double grow = unit->m_grow;
3551 double y1 = unit->m_y1;
3552 for (int i=0; i<nsmps; ++i) {
3553 CHECK_GATE
3554 ZXP(out) = level;
3555 y1 += grow;
3556 level = y1*y1;
3558 unit->m_y1 = y1;
3559 } break;
3560 case shape_Cubed : {
3561 double grow = unit->m_grow;
3562 double y1 = unit->m_y1;
3563 for (int i=0; i<nsmps; ++i) {
3564 CHECK_GATE
3565 ZXP(out) = level;
3566 y1 += grow;
3567 level = y1*y1*y1;
3569 unit->m_y1 = y1;
3570 } break;
3571 case shape_Sustain : {
3572 for (int i=0; i<nsmps; ++i) {
3573 CHECK_GATE
3574 ZXP(out) = level;
3576 } break;
3578 remain -= nsmps;
3579 counter -= nsmps;
3581 unit->m_level = level;
3582 unit->m_counter = counter;
3583 unit->m_prevGate = gate;
3586 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3588 void Linen_Ctor(Linen *unit)
3590 // gate attack level release
3591 SETCALC(Linen_next_k);
3593 unit->m_level = 0.f;
3594 unit->m_stage = 4;
3595 unit->m_prevGate = 0.f;
3596 Linen_next_k(unit, 1);
3599 void Linen_next_k(Linen *unit, int inNumSamples)
3601 float gate = ZIN0(0);
3602 float *out = OUT(0);
3604 if (unit->m_prevGate <= 0.f && gate > 0.f) {
3605 unit->mDone = false;
3606 unit->m_stage = 0;
3607 float attackTime = ZIN0(1);
3608 float susLevel = ZIN0(2);
3609 int counter = (int)(attackTime * SAMPLERATE);
3610 counter = sc_max(1, counter);
3611 unit->m_slope = (susLevel - unit->m_level) / counter;
3612 unit->m_counter = counter;
3615 switch (unit->m_stage) {
3616 case 0 :
3617 case 2 :
3618 *out = unit->m_level;
3619 unit->m_level += unit->m_slope;
3620 if (--unit->m_counter == 0) unit->m_stage++;
3621 break;
3622 case 1 :
3623 *out = unit->m_level;
3624 if (gate <= -1.f) {
3625 // cutoff
3626 unit->m_stage = 2;
3627 float releaseTime = -gate - 1.f;
3628 int counter = (int)(releaseTime * SAMPLERATE);
3629 counter = sc_max(1, counter);
3630 unit->m_slope = -unit->m_level / counter;
3631 unit->m_counter = counter;
3632 } else if (gate <= 0.f) {
3633 unit->m_stage = 2;
3634 float releaseTime = ZIN0(3);
3635 int counter = (int)(releaseTime * SAMPLERATE);
3636 counter = sc_max(1, counter);
3637 unit->m_slope = -unit->m_level / counter;
3638 unit->m_counter = counter;
3640 //Print("release %d %d\n", unit->mParent->mNode.mID, counter);
3642 break;
3643 case 3 : {
3644 *out = 0.f;
3645 //Print("done %d\n", unit->mParent->mNode.mID);
3646 unit->mDone = true;
3647 unit->m_stage++;
3648 int doneAction = (int)ZIN0(4);
3649 DoneAction(doneAction, unit);
3650 } break;
3651 case 4 :
3652 *out = 0.f;
3653 break;
3655 unit->m_prevGate = gate;
3658 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3660 void EnvFill(World *world, struct SndBuf *buf, struct sc_msg_iter *msg)
3662 if (buf->channels != 1) return;
3664 int size = buf->samples;
3665 int byteSize = size * sizeof(float);
3666 float *data = (float*)malloc(byteSize);
3668 double level = msg->getf();
3669 int numStages = msg->geti();
3670 /*int releaseNode =*/ msg->geti(); // ignored
3671 /*int loopNode =*/ msg->geti(); // ignored
3673 double pos = 0.;
3674 int32 index = 0;
3675 int32 remain = size;
3677 for (int j=0; j < numStages; ++j)
3679 double endLevel = msg->getf();
3680 double dur = msg->getf();
3681 int shape = msg->geti();
3682 double curve = msg->getf();
3684 int32 ipos = (int32)pos;
3685 double smpdur = dur * size;
3686 int32 nsmps = (int32)smpdur - ipos;
3687 nsmps = sc_min(nsmps, remain);
3689 switch (shape) {
3690 case shape_Step : {
3691 level = endLevel;
3692 for (int i=0; i<nsmps; ++i) {
3693 data[index++] = level;
3695 } break;
3696 case shape_Linear : {
3697 double grow = (endLevel - level) / nsmps;
3698 for (int i=0; i<nsmps; ++i) {
3699 data[index++] = level;
3700 level += grow;
3702 } break;
3703 case shape_Exponential : {
3704 double grow = pow(endLevel / level, 1.0 / nsmps);
3705 for (int i=0; i<nsmps; ++i) {
3706 data[index++] = level;
3707 level *= grow;
3709 } break;
3710 case shape_Sine : {
3711 double w = pi / nsmps;
3713 double a2 = (endLevel + level) * 0.5;
3714 double b1 = 2. * cos(w);
3715 double y1 = (endLevel - level) * 0.5;
3716 double y2 = y1 * sin(pi * 0.5 - w);
3717 level = a2 - y1;
3718 for (int i=0; i<nsmps; ++i) {
3719 data[index++] = level;
3720 double y0 = b1 * y1 - y2;
3721 level = a2 - y0;
3722 y2 = y1;
3723 y1 = y0;
3725 } break;
3726 case shape_Welch : {
3727 double w = (pi * 0.5) / nsmps;
3729 double b1 = 2. * cos(w);
3730 double a2, y1, y2;
3731 if (endLevel >= level) {
3732 a2 = level;
3733 y1 = 0.;
3734 y2 = -sin(w) * (endLevel - level);
3735 } else {
3736 a2 = endLevel;
3737 y1 = level - endLevel;
3738 y2 = cos(w) * (level - endLevel);
3740 level = a2 + y1;
3741 for (int i=0; i<nsmps; ++i) {
3742 data[index++] = level;
3743 double y0 = b1 * y1 - y2;
3744 level = a2 - y0;
3745 y2 = y1;
3746 y1 = y0;
3748 } break;
3749 case shape_Curve : {
3750 if (fabs(curve) < 0.001) {
3751 double grow = (endLevel - level) / nsmps;
3752 for (int i=0; i<nsmps; ++i) {
3753 data[index++] = level;
3754 level += grow;
3756 } else {
3757 double a1 = (endLevel - level) / (1.0 - exp(curve));
3758 double a2 = level + a1;
3759 double b1 = a1;
3760 double grow = exp(curve / nsmps);
3761 for (int i=0; i<nsmps; ++i) {
3762 data[index++] = level;
3763 b1 *= grow;
3764 level = a2 - b1;
3767 } break;
3768 case shape_Squared : {
3769 double y1 = sqrt(level);
3770 double y2 = sqrt(endLevel);
3771 double grow = (y2 - y1) / nsmps;
3772 for (int i=0; i<nsmps; ++i) {
3773 data[index++] = level;
3774 y1 += grow;
3775 level = y1*y1;
3777 } break;
3778 case shape_Cubed : {
3779 double y1 = pow(level, 0.33333333);
3780 double y2 = pow(endLevel, 0.33333333);
3781 double grow = (y2 - y1) / nsmps;
3782 for (int i=0; i<nsmps; ++i) {
3783 data[index++] = level;
3784 y1 += grow;
3785 level = y1*y1*y1;
3787 } break;
3790 pos += smpdur;
3791 level = endLevel;
3792 remain -= nsmps;
3794 memcpy(buf->data, data, byteSize);
3795 free(data);
3798 //////////////////// Add IEnvGen 06/06/2007 /////////////////////////////////
3801 struct IEnvGen : public Unit
3803 float m_level, m_offset;
3804 float m_startpoint, m_numvals, m_pointin;
3805 float* m_envvals;
3809 extern "C"
3811 void IEnvGen_next_a(IEnvGen *unit, int inNumSamples);
3812 void IEnvGen_next_k(IEnvGen *unit, int inNumSamples);
3813 void IEnvGen_Ctor(IEnvGen* unit);
3814 void IEnvGen_Dtor(IEnvGen* unit);
3817 #define GET_ENV_VAL \
3818 switch (shape) \
3820 case shape_Step : \
3821 level = unit->m_level = endLevel; \
3822 break; \
3823 case shape_Linear : \
3824 default: \
3825 level = unit->m_level = pos * (endLevel - begLevel) + begLevel; \
3826 break; \
3827 case shape_Exponential : \
3828 level = unit->m_level = begLevel * pow(endLevel / begLevel, pos); \
3829 break; \
3830 case shape_Sine : \
3831 level = unit->m_level = begLevel + (endLevel - begLevel) * (-cos(pi * pos) * 0.5 + 0.5); \
3832 break; \
3833 case shape_Welch : \
3835 if (begLevel < endLevel) \
3836 level = unit->m_level = begLevel + (endLevel - begLevel) * sin(pi2 * pos); \
3837 else \
3838 level = unit->m_level = endLevel - (endLevel - begLevel) * sin(pi2 - pi2 * pos); \
3839 break; \
3841 case shape_Curve : \
3842 if (fabs((float)curve) < 0.0001) { \
3843 level = unit->m_level = pos * (endLevel - begLevel) + begLevel; \
3844 } else { \
3845 double denom = 1. - exp((float)curve); \
3846 double numer = 1. - exp((float)(pos * curve)); \
3847 level = unit->m_level = begLevel + (endLevel - begLevel) * (numer/denom); \
3849 break; \
3850 case shape_Squared : \
3852 double sqrtBegLevel = sqrt(begLevel); \
3853 double sqrtEndLevel = sqrt(endLevel); \
3854 double sqrtLevel = pos * (sqrtEndLevel - sqrtBegLevel) + sqrtBegLevel; \
3855 level = unit->m_level = sqrtLevel * sqrtLevel; \
3856 break; \
3858 case shape_Cubed : \
3860 double cbrtBegLevel = pow(begLevel, 0.3333333f); \
3861 double cbrtEndLevel = pow(endLevel, 0.3333333f); \
3862 double cbrtLevel = pos * (cbrtEndLevel - cbrtBegLevel) + cbrtBegLevel; \
3863 level = unit->m_level = cbrtLevel * cbrtLevel * cbrtLevel; \
3864 break; \
3869 void IEnvGen_Ctor(IEnvGen *unit)
3872 if (INRATE(0) == calc_FullRate) {
3873 SETCALC(IEnvGen_next_a);
3874 } else {
3875 SETCALC(IEnvGen_next_k);
3878 // pointer, offset
3879 // initlevel, numstages, totaldur,
3880 // [dur, shape, curve, level] * numvals
3881 int numStages = (int)IN0(3);
3882 int numvals = numStages * 4; // initlevel + (levels, dur, shape, curves) * stages
3883 float offset = unit->m_offset = IN0(1);
3884 float point = unit->m_pointin = IN0(0) - offset;
3885 unit->m_envvals = (float*)RTAlloc(unit->mWorld, (int)(numvals + 1.) * sizeof(float));
3887 unit->m_envvals[0] = IN0(2);
3888 // Print("%3.3f\n", unit->m_envvals[0]);
3889 // fill m_envvals with the values;
3890 for (int i = 1; i <= numvals; i++) {
3891 unit->m_envvals[i] = IN0(4 + i);
3892 // Print("%3.3f\n", unit->m_envvals[i]);
3895 // float out = OUT0(0);
3896 float totalDur = IN0(4);
3897 float level = 0.f;
3898 float newtime = 0.f;
3899 int stage = 0;
3900 float seglen = 0.f;
3901 if (point >= totalDur) {
3902 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
3903 } else {
3904 if (point <= 0.0) {
3905 unit->m_level = level = unit->m_envvals[0];
3906 } else {
3907 float segpos = point;
3908 // determine which segment the current time pointer needs calculated
3909 for(int j = 0; point >= newtime; j++) {
3910 seglen = unit->m_envvals[(j * 4) + 1];
3911 newtime += seglen;
3912 segpos -= seglen;
3913 stage = j;
3916 segpos = segpos + seglen;
3917 float begLevel = unit->m_envvals[(stage * 4)];
3918 int shape = (int)unit->m_envvals[(stage * 4) + 2];
3919 int curve = (int)unit->m_envvals[(stage * 4) + 3];
3920 float endLevel = unit->m_envvals[(stage * 4) + 4];
3921 float pos = (segpos / seglen);
3923 GET_ENV_VAL
3926 OUT0(0) = level;
3929 void IEnvGen_Dtor(IEnvGen *unit)
3931 RTFree(unit->mWorld, unit->m_envvals);
3935 void IEnvGen_next_a(IEnvGen *unit, int inNumSamples)
3937 float* out = OUT(0);
3938 float level = unit->m_level;
3939 float* pointin = IN(0);
3940 float offset = unit->m_offset;
3941 int numStages = (int)IN0(3);
3942 float point; // = unit->m_pointin;
3944 float totalDur = IN0(4);
3946 int stagemul;
3947 // pointer, offset
3948 // level0, numstages, totaldur,
3949 // [initval, [dur, shape, curve, level] * N ]
3951 for( int i = 0; i < inNumSamples; i++) {
3952 if (pointin[i] == unit->m_pointin){
3953 out[i] = level;
3954 } else {
3955 unit->m_pointin = point = sc_max(pointin[i] - offset, 0.0);
3956 float newtime = 0.f;
3957 int stage = 0;
3958 float seglen = 0.f;
3959 if (point >= totalDur) {
3960 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
3961 } else {
3962 if (point <= 0.0) {
3963 unit->m_level = level = unit->m_envvals[0];
3964 } else {
3965 float segpos = point;
3966 // determine which segment the current time pointer needs
3967 for(int j = 0; point >= newtime; j++) {
3968 seglen = unit->m_envvals[(j * 4) + 1];
3969 newtime += seglen;
3970 segpos -= seglen;
3971 stage = j;
3973 stagemul = stage * 4;
3974 segpos = segpos + seglen;
3975 float begLevel = unit->m_envvals[stagemul];
3976 int shape = (int)unit->m_envvals[stagemul + 2];
3977 int curve = (int)unit->m_envvals[stagemul + 3];
3978 float endLevel = unit->m_envvals[stagemul + 4];
3979 float pos = (segpos / seglen);
3981 GET_ENV_VAL
3984 out[i] = level;
3990 void IEnvGen_next_k(IEnvGen *unit, int inNumSamples)
3992 float* out = OUT(0);
3993 float level = unit->m_level;
3994 float pointin = sc_max(IN0(0) - unit->m_offset, 0);
3995 int numStages = (int)IN0(3);
3997 float totalDur = IN0(4);
3998 // pointer, offset
3999 // level0, numstages, totaldur,
4000 float point = unit->m_pointin;
4002 // [initval, [dur, shape, curve, level] * N ]
4004 if (pointin == unit->m_pointin) {
4005 Fill(inNumSamples, out, level);
4006 } else {
4007 float pointslope = CALCSLOPE(pointin, point);
4008 for( int i = 0; i < inNumSamples; i++) {
4009 float newtime = 0.f;
4010 int stage = 0;
4011 float seglen = 0.f;
4012 if (point >= totalDur) {
4013 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
4014 } else {
4015 if (point <= 0.0) {
4016 unit->m_level = level = unit->m_envvals[0];
4017 } else {
4018 float segpos = point;
4019 // determine which segment the current time pointer needs calculated
4020 for(int j = 0; point >= newtime; j++) {
4021 seglen = unit->m_envvals[(j * 4) + 1];
4022 newtime += seglen;
4023 segpos -= seglen;
4024 stage = j;
4027 segpos = segpos + seglen;
4028 float begLevel = unit->m_envvals[(stage * 4)];
4029 int shape = (int)unit->m_envvals[(stage * 4) + 2];
4030 float curve = unit->m_envvals[(stage * 4) + 3];
4031 float endLevel = unit->m_envvals[(stage * 4) + 4];
4032 float pos = (segpos / seglen);
4034 GET_ENV_VAL
4037 out[i] = level;
4038 point += pointslope;
4041 unit->m_pointin = pointin;
4046 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4049 PluginLoad(LF)
4051 ft = inTable;
4053 DefineSimpleUnit(Vibrato);
4054 DefineSimpleUnit(LFPulse);
4055 DefineSimpleUnit(LFSaw);
4056 DefineSimpleUnit(LFPar);
4057 DefineSimpleUnit(LFCub);
4058 DefineSimpleUnit(LFTri);
4059 DefineSimpleUnit(LFGauss);
4060 DefineSimpleUnit(Impulse);
4061 DefineSimpleUnit(VarSaw);
4062 DefineSimpleUnit(SyncSaw);
4063 DefineSimpleUnit(K2A);
4064 DefineSimpleUnit(A2K);
4065 DefineSimpleUnit(T2K);
4066 DefineSimpleUnit(T2A);
4067 DefineSimpleUnit(DC);
4068 DefineSimpleUnit(Line);
4069 DefineSimpleUnit(XLine);
4071 DefineSimpleUnit(Wrap);
4072 DefineSimpleUnit(Fold);
4073 DefineSimpleUnit(Clip);
4074 DefineSimpleUnit(Unwrap);
4075 DefineSimpleUnit(AmpComp);
4076 DefineSimpleUnit(AmpCompA);
4077 DefineSimpleUnit(InRange);
4078 DefineSimpleUnit(InRect);
4079 DefineSimpleUnit(LinExp);
4080 DefineSimpleUnit(EnvGen);
4081 DefineSimpleUnit(Linen);
4083 DefineBufGen("env", EnvFill);
4085 DefineDtorUnit(IEnvGen);