Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / plugins / LFUGens.cpp
blobf7e898caab2ea58f2cfbd589e5da9f02c06e25a7
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 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2345 void LinExp_next(LinExp *unit, int inNumSamples)
2347 float *out = ZOUT(0);
2348 float *in = ZIN(0);
2349 float dstlo = unit->m_dstlo;
2351 float dstratio = unit->m_dstratio;
2352 float rsrcrange = unit->m_rsrcrange;
2353 float rrminuslo = unit->m_rrminuslo;
2355 LOOP1(inNumSamples,
2356 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2360 #ifdef NOVA_SIMD
2361 static inline void LinExp_next_nova_loop(float * out, const float * in, int inNumSamples,
2362 nova::vec<float> dstlo, nova::vec<float> dstratio,
2363 nova::vec<float> rsrcrange, nova::vec<float> rrminuslo)
2365 const int vecSize = nova::vec<float>::size;
2366 int unroll = inNumSamples / (2*vecSize);
2370 nova::vec<float> val0, val1;
2371 val0.load_aligned(in);
2372 val1.load_aligned(in + vecSize);
2374 val0 = dstlo * pow(dstratio, val0 * rsrcrange + rrminuslo);
2375 val1 = dstlo * pow(dstratio, val1 * rsrcrange + rrminuslo);
2377 val0.store_aligned(out);
2378 val1.store_aligned(out + vecSize);
2380 in += 2*vecSize;
2381 out += 2*vecSize;
2382 } while (--unroll);
2385 FLATTEN static void LinExp_next_nova(LinExp *unit, int inNumSamples)
2387 float *out = OUT(0);
2388 float *in = IN(0);
2390 LinExp_next_nova_loop(out, in, inNumSamples, unit->m_dstlo, unit->m_dstratio, unit->m_rsrcrange, unit->m_rrminuslo);
2393 FLATTEN static void LinExp_next_nova_kk(LinExp *unit, int inNumSamples)
2395 float *out = OUT(0);
2396 float *in = IN(0);
2398 float srclo = ZIN0(1);
2399 float srchi = ZIN0(2);
2400 float dstlo = ZIN0(3);
2401 float dsthi = ZIN0(4);
2402 float dstratio = dsthi/dstlo;
2403 float rsrcrange = sc_reciprocal(srchi - srclo);
2404 float rrminuslo = rsrcrange * -srclo;
2406 LinExp_next_nova_loop(out, in, inNumSamples, dstlo, dstratio, rsrcrange, rrminuslo);
2409 #endif
2411 void LinExp_next_kk(LinExp *unit, int inNumSamples)
2413 float *out = ZOUT(0);
2414 float *in = ZIN(0);
2415 float srclo = ZIN0(1);
2416 float srchi = ZIN0(2);
2417 float dstlo = ZIN0(3);
2418 float dsthi = ZIN0(4);
2419 float dstratio = dsthi * sc_reciprocal(dstlo);
2420 float rsrcrange = sc_reciprocal(srchi - srclo);
2421 float rrminuslo = rsrcrange * -srclo;
2423 LOOP1(inNumSamples,
2424 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2428 void LinExp_next_aa(LinExp *unit, int inNumSamples)
2430 float *out = ZOUT(0);
2431 float *in = ZIN(0);
2432 float *srclo = ZIN(1);
2433 float *srchi = ZIN(2);
2434 float *dstlo = ZIN(3);
2435 float *dsthi = ZIN(4);
2438 LOOP1(inNumSamples,
2439 float zdsthi = ZXP(dsthi);
2440 float zdstlo = ZXP(dstlo);
2441 float zsrchi = ZXP(srchi);
2442 float zsrclo = ZXP(srclo);
2443 float dstratio = zdsthi/zdstlo;
2444 float rsrcrange = sc_reciprocal(zsrchi - zsrclo);
2445 float rrminuslo = rsrcrange * -zsrclo;
2446 ZXP(out) = zdstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2450 void LinExp_next_ak(LinExp *unit, int inNumSamples)
2452 float *out = ZOUT(0);
2453 float *in = ZIN(0);
2454 float *srclo = ZIN(1);
2455 float *srchi = ZIN(2);
2456 float dstlo = ZIN0(3);
2457 float dsthi = ZIN0(4);
2458 float dstratio = dsthi/dstlo;
2460 LOOP1(inNumSamples,
2461 float zsrchi = ZXP(srchi);
2462 float zsrclo = ZXP(srclo);
2464 float rsrcrange = sc_reciprocal(zsrchi - zsrclo);
2465 float rrminuslo = rsrcrange * -zsrclo;
2466 ZXP(out) = dstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2470 void LinExp_next_ka(LinExp *unit, int inNumSamples)
2472 float *out = ZOUT(0);
2473 float *in = ZIN(0);
2474 float srclo = ZIN0(1);
2475 float srchi = ZIN0(2);
2476 float *dstlo = ZIN(3);
2477 float *dsthi = ZIN(4);
2478 float rsrcrange = sc_reciprocal(srchi - srclo);
2479 float rrminuslo = rsrcrange * -srclo;
2481 LOOP1(inNumSamples,
2482 float zdsthi = ZXP(dsthi);
2483 float zdstlo = ZXP(dstlo);
2484 float dstratio = zdsthi/zdstlo;
2485 ZXP(out) = zdstlo * pow(dstratio, ZXP(in) * rsrcrange + rrminuslo);
2490 static void LinExp_SetCalc(LinExp* unit)
2492 if(INRATE(1) == calc_FullRate || INRATE(2) == calc_FullRate) {
2493 if(INRATE(3) == calc_FullRate || INRATE(4) == calc_FullRate) {
2494 SETCALC(LinExp_next_aa); return;
2495 } else {
2496 SETCALC(LinExp_next_ak); return;
2498 } else {
2499 if(INRATE(3) == calc_FullRate || INRATE(4) == calc_FullRate) {
2500 SETCALC(LinExp_next_ka); return;
2504 bool allScalar = true;
2505 for(int i = 1; i<5; i++) {
2506 if(INRATE(i) != calc_ScalarRate) {
2507 allScalar = false;
2508 break;
2512 #ifdef NOVA_SIMD
2513 if ((BUFLENGTH % (2*nova::vec<float>::size)) == 0)
2514 if (allScalar)
2515 SETCALC(LinExp_next_nova);
2516 else
2517 SETCALC(LinExp_next_nova_kk);
2518 else
2519 #endif
2520 if (allScalar)
2521 SETCALC(LinExp_next);
2522 else
2523 SETCALC(LinExp_next_kk);
2525 if (!allScalar)
2526 return;
2528 float srclo = ZIN0(1);
2529 float srchi = ZIN0(2);
2530 float dstlo = ZIN0(3);
2531 float dsthi = ZIN0(4);
2532 unit->m_dstlo = dstlo;
2533 unit->m_dstratio = dsthi/dstlo;
2534 unit->m_rsrcrange = sc_reciprocal(srchi - srclo);
2535 unit->m_rrminuslo = unit->m_rsrcrange * -srclo;
2538 void LinExp_Ctor(LinExp* unit)
2540 LinExp_SetCalc(unit);
2541 float srclo = ZIN0(1);
2542 float srchi = ZIN0(2);
2543 float dstlo = ZIN0(3);
2544 float dsthi = ZIN0(4);
2545 unit->m_dstlo = dstlo;
2546 unit->m_dstratio = dsthi/dstlo;
2547 unit->m_rsrcrange = 1. / (srchi - srclo);
2548 unit->m_rrminuslo = unit->m_rsrcrange * -srclo;
2549 LinExp_next(unit, 1);
2552 ////////////////////////////////////////////////////////////////////////////////////////////////////////
2555 enum {
2556 kEnvGen_gate,
2557 kEnvGen_levelScale,
2558 kEnvGen_levelBias,
2559 kEnvGen_timeScale,
2560 kEnvGen_doneAction,
2561 kEnvGen_initLevel,
2562 kEnvGen_numStages,
2563 kEnvGen_releaseNode,
2564 kEnvGen_loopNode,
2565 // 'kEnvGen_nodeOffset' must always be last
2566 // if you need to add an arg, put it before this one
2567 kEnvGen_nodeOffset
2570 #ifdef NOVA_SIMD
2571 void EnvGen_next_ak_nova(EnvGen *unit, int inNumSamples);
2572 #endif
2574 void EnvGen_Ctor(EnvGen *unit)
2576 //Print("EnvGen_Ctor A\n");
2577 if (unit->mCalcRate == calc_FullRate) {
2578 if (INRATE(0) == calc_FullRate) {
2579 SETCALC(EnvGen_next_aa);
2580 } else {
2581 #ifdef NOVA_SIMD
2582 if (!(BUFLENGTH & 15))
2583 SETCALC(EnvGen_next_ak_nova);
2584 else
2585 #endif
2586 SETCALC(EnvGen_next_ak);
2588 } else {
2589 SETCALC(EnvGen_next_k);
2592 // gate = 1.0, levelScale = 1.0, levelBias = 0.0, timeScale
2593 // level0, numstages, releaseNode, loopNode,
2594 // [level, dur, shape, curve]
2596 unit->m_endLevel = unit->m_level = ZIN0(kEnvGen_initLevel) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2597 unit->m_counter = 0;
2598 unit->m_stage = 1000000000;
2599 unit->m_prevGate = 0.f;
2600 unit->m_released = false;
2601 unit->m_releaseNode = (int)ZIN0(kEnvGen_releaseNode);
2602 EnvGen_next_k(unit, 1);
2605 enum {
2606 shape_Step,
2607 shape_Linear,
2608 shape_Exponential,
2609 shape_Sine,
2610 shape_Welch,
2611 shape_Curve,
2612 shape_Squared,
2613 shape_Cubed,
2614 shape_Sustain = 9999
2617 void EnvGen_next_k(EnvGen *unit, int inNumSamples)
2619 float *out = OUT(0);
2620 float gate = ZIN0(kEnvGen_gate);
2621 //Print("->EnvGen_next_k gate %g\n", gate);
2622 int counter = unit->m_counter;
2623 double level = unit->m_level;
2625 if (unit->m_prevGate <= 0. && gate > 0.) {
2626 unit->m_stage = -1;
2627 unit->mDone = false;
2628 unit->m_released = false;
2629 counter = 0;
2630 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
2631 // cutoff
2632 int numstages = (int)ZIN0(kEnvGen_numStages);
2633 float dur = -gate - 1.f;
2634 counter = (int32)(dur * SAMPLERATE);
2635 counter = sc_max(1, counter);
2636 unit->m_stage = numstages;
2637 unit->m_shape = shape_Linear;
2638 // first ZIN0 gets the last envelope node's level, then apply levelScale and levelBias
2639 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2640 unit->m_grow = (unit->m_endLevel - level) / counter;
2641 } else if (unit->m_prevGate > 0.f && gate <= 0.f
2642 && unit->m_releaseNode >= 0 && !unit->m_released) {
2643 counter = 0;
2644 unit->m_stage = unit->m_releaseNode - 1;
2645 unit->m_released = true;
2647 unit->m_prevGate = gate;
2650 // gate = 1.0, levelScale = 1.0, levelBias = 0.0, timeScale
2651 // level0, numstages, releaseNode, loopNode,
2652 // [level, dur, shape, curve]
2654 if (counter <= 0) {
2655 //Print("stage %d rel %d\n", unit->m_stage, (int)ZIN0(kEnvGen_releaseNode));
2656 int numstages = (int)ZIN0(kEnvGen_numStages);
2658 //Print("stage %d numstages %d\n", unit->m_stage, numstages);
2659 if (unit->m_stage+1 >= numstages) { // num stages
2660 //Print("stage+1 > num stages\n");
2661 counter = INT_MAX;
2662 unit->m_shape = 0;
2663 level = unit->m_endLevel;
2664 unit->mDone = true;
2665 int doneAction = (int)ZIN0(kEnvGen_doneAction);
2666 DoneAction(doneAction, unit);
2667 } else if (unit->m_stage+1 == unit->m_releaseNode && !unit->m_released) { // sustain stage
2668 int loopNode = (int)ZIN0(kEnvGen_loopNode);
2669 if (loopNode >= 0 && loopNode < numstages) {
2670 unit->m_stage = loopNode;
2671 goto initSegment;
2672 } else {
2673 counter = INT_MAX;
2674 unit->m_shape = shape_Sustain;
2675 level = unit->m_endLevel;
2677 //Print("sustain\n");
2678 } else {
2679 unit->m_stage++;
2680 initSegment:
2681 //Print("stage %d\n", unit->m_stage);
2682 //Print("initSegment\n");
2683 //out = unit->m_level;
2684 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
2686 if (stageOffset + 4 > unit->mNumInputs) {
2687 // oops.
2688 Print("envelope went past end of inputs.\n");
2689 ClearUnitOutputs(unit, 1);
2690 NodeEnd(&unit->mParent->mNode);
2691 return;
2694 float** envPtr = unit->mInBuf + stageOffset;
2695 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
2696 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
2697 unit->m_shape = (int32)*envPtr[2];
2698 double curve = *envPtr[3];
2699 unit->m_endLevel = endLevel;
2701 counter = (int32)(dur * SAMPLERATE);
2702 counter = sc_max(1, counter);
2703 //Print("stageOffset %d level %g endLevel %g dur %g shape %d curve %g\n", stageOffset, level, endLevel, dur, unit->m_shape, curve);
2704 //Print("SAMPLERATE %g\n", SAMPLERATE);
2705 if (counter == 1) unit->m_shape = 1; // shape_Linear
2706 //Print("new counter = %d shape = %d\n", counter, unit->m_shape);
2707 switch (unit->m_shape) {
2708 case shape_Step : {
2709 level = endLevel;
2710 } break;
2711 case shape_Linear : {
2712 unit->m_grow = (endLevel - level) / counter;
2713 //Print("grow %g\n", unit->m_grow);
2714 } break;
2715 case shape_Exponential : {
2716 unit->m_grow = pow(endLevel / level, 1.0 / counter);
2717 } break;
2718 case shape_Sine : {
2719 double w = pi / counter;
2721 unit->m_a2 = (endLevel + level) * 0.5;
2722 unit->m_b1 = 2. * cos(w);
2723 unit->m_y1 = (endLevel - level) * 0.5;
2724 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
2725 level = unit->m_a2 - unit->m_y1;
2726 } break;
2727 case shape_Welch : {
2728 double w = (pi * 0.5) / counter;
2730 unit->m_b1 = 2. * cos(w);
2732 if (endLevel >= level) {
2733 unit->m_a2 = level;
2734 unit->m_y1 = 0.;
2735 unit->m_y2 = -sin(w) * (endLevel - level);
2736 } else {
2737 unit->m_a2 = endLevel;
2738 unit->m_y1 = level - endLevel;
2739 unit->m_y2 = cos(w) * (level - endLevel);
2741 level = unit->m_a2 + unit->m_y1;
2742 } break;
2743 case shape_Curve : {
2744 if (fabs(curve) < 0.001) {
2745 unit->m_shape = 1; // shape_Linear
2746 unit->m_grow = (endLevel - level) / counter;
2747 } else {
2748 double a1 = (endLevel - level) / (1.0 - exp(curve));
2749 unit->m_a2 = level + a1;
2750 unit->m_b1 = a1;
2751 unit->m_grow = exp(curve / counter);
2753 } break;
2754 case shape_Squared : {
2755 unit->m_y1 = sqrt(level);
2756 unit->m_y2 = sqrt(endLevel);
2757 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2758 } break;
2759 case shape_Cubed : {
2760 unit->m_y1 = pow(level, 0.33333333);
2761 unit->m_y2 = pow(endLevel, 0.33333333);
2762 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2763 } break;
2769 switch (unit->m_shape) {
2770 case shape_Step : {
2771 } break;
2772 case shape_Linear : {
2773 double grow = unit->m_grow;
2774 //Print("level %g\n", level);
2775 level += grow;
2776 } break;
2777 case shape_Exponential : {
2778 double grow = unit->m_grow;
2779 level *= grow;
2780 } break;
2781 case shape_Sine : {
2782 double a2 = unit->m_a2;
2783 double b1 = unit->m_b1;
2784 double y2 = unit->m_y2;
2785 double y1 = unit->m_y1;
2786 double y0 = b1 * y1 - y2;
2787 level = a2 - y0;
2788 y2 = y1;
2789 y1 = y0;
2790 unit->m_y1 = y1;
2791 unit->m_y2 = y2;
2792 } break;
2793 case shape_Welch : {
2794 double a2 = unit->m_a2;
2795 double b1 = unit->m_b1;
2796 double y2 = unit->m_y2;
2797 double y1 = unit->m_y1;
2798 double y0 = b1 * y1 - y2;
2799 level = a2 + y0;
2800 y2 = y1;
2801 y1 = y0;
2802 unit->m_y1 = y1;
2803 unit->m_y2 = y2;
2804 } break;
2805 case shape_Curve : {
2806 double a2 = unit->m_a2;
2807 double b1 = unit->m_b1;
2808 double grow = unit->m_grow;
2809 b1 *= grow;
2810 level = a2 - b1;
2811 unit->m_b1 = b1;
2812 } break;
2813 case shape_Squared : {
2814 double grow = unit->m_grow;
2815 double y1 = unit->m_y1;
2816 y1 += grow;
2817 level = y1*y1;
2818 unit->m_y1 = y1;
2819 } break;
2820 case shape_Cubed : {
2821 double grow = unit->m_grow;
2822 double y1 = unit->m_y1;
2823 y1 += grow;
2824 level = y1*y1*y1;
2825 unit->m_y1 = y1;
2826 } break;
2827 case shape_Sustain : {
2828 } break;
2830 *out = level;
2831 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, *out);
2832 unit->m_level = level;
2833 unit->m_counter = counter - 1;
2837 void EnvGen_next_ak(EnvGen *unit, int inNumSamples)
2839 float *out = ZOUT(0);
2840 float gate = ZIN0(kEnvGen_gate);
2841 int counter = unit->m_counter;
2842 double level = unit->m_level;
2844 if (unit->m_prevGate <= 0. && gate > 0.) {
2845 unit->m_stage = -1;
2846 unit->mDone = false;
2847 unit->m_released = false;
2848 counter = 0;
2849 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
2850 // cutoff
2851 int numstages = (int)ZIN0(kEnvGen_numStages);
2852 float dur = -gate - 1.f;
2853 counter = (int32)(dur * SAMPLERATE);
2854 counter = sc_max(1, counter);
2855 unit->m_stage = numstages;
2856 unit->m_shape = shape_Linear;
2857 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
2858 unit->m_grow = (unit->m_endLevel - level) / counter;
2859 } else if (unit->m_prevGate > 0.f && gate <= 0.f
2860 && unit->m_releaseNode >= 0 && !unit->m_released) {
2861 counter = 0;
2862 unit->m_stage = unit->m_releaseNode - 1;
2863 unit->m_released = true;
2865 unit->m_prevGate = gate;
2867 int remain = inNumSamples;
2868 while (remain)
2870 if (counter == 0) {
2871 int numstages = (int)ZIN0(kEnvGen_numStages);
2873 if (unit->m_stage+1 >= numstages) { // num stages
2874 counter = INT_MAX;
2875 unit->m_shape = 0;
2876 level = unit->m_endLevel;
2877 unit->mDone = true;
2878 int doneAction = (int)ZIN0(kEnvGen_doneAction);
2879 DoneAction(doneAction, unit);
2880 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
2881 int loopNode = (int)ZIN0(kEnvGen_loopNode);
2882 if (loopNode >= 0 && loopNode < numstages) {
2883 unit->m_stage = loopNode;
2884 goto initSegment;
2885 } else {
2886 counter = INT_MAX;
2887 unit->m_shape = shape_Sustain;
2888 level = unit->m_endLevel;
2890 } else {
2891 unit->m_stage++;
2892 initSegment:
2893 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
2895 if (stageOffset + 4 > unit->mNumInputs) {
2896 // oops.
2897 Print("envelope went past end of inputs.\n");
2898 ClearUnitOutputs(unit, 1);
2899 NodeEnd(&unit->mParent->mNode);
2900 return;
2903 float** envPtr = unit->mInBuf + stageOffset;
2904 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
2905 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
2906 unit->m_shape = (int32)*envPtr[2];
2907 double curve = *envPtr[3];
2908 unit->m_endLevel = endLevel;
2910 counter = (int32)(dur * SAMPLERATE);
2911 counter = sc_max(1, counter);
2913 if (counter == 1) unit->m_shape = 1; // shape_Linear
2914 switch (unit->m_shape) {
2915 case shape_Step : {
2916 level = endLevel;
2917 } break;
2918 case shape_Linear : {
2919 unit->m_grow = (endLevel - level) / counter;
2920 } break;
2921 case shape_Exponential : {
2922 unit->m_grow = pow(endLevel / level, 1.0 / counter);
2923 } break;
2924 case shape_Sine : {
2925 double w = pi / counter;
2927 unit->m_a2 = (endLevel + level) * 0.5;
2928 unit->m_b1 = 2. * cos(w);
2929 unit->m_y1 = (endLevel - level) * 0.5;
2930 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
2931 level = unit->m_a2 - unit->m_y1;
2932 } break;
2933 case shape_Welch : {
2934 double w = (pi * 0.5) / counter;
2936 unit->m_b1 = 2. * cos(w);
2938 if (endLevel >= level) {
2939 unit->m_a2 = level;
2940 unit->m_y1 = 0.;
2941 unit->m_y2 = -sin(w) * (endLevel - level);
2942 } else {
2943 unit->m_a2 = endLevel;
2944 unit->m_y1 = level - endLevel;
2945 unit->m_y2 = cos(w) * (level - endLevel);
2947 level = unit->m_a2 + unit->m_y1;
2948 } break;
2949 case shape_Curve : {
2950 if (fabs(curve) < 0.001) {
2951 unit->m_shape = 1; // shape_Linear
2952 unit->m_grow = (endLevel - level) / counter;
2953 } else {
2954 double a1 = (endLevel - level) / (1.0 - exp(curve));
2955 unit->m_a2 = level + a1;
2956 unit->m_b1 = a1;
2957 unit->m_grow = exp(curve / counter);
2959 } break;
2960 case shape_Squared : {
2961 unit->m_y1 = sqrt(level);
2962 unit->m_y2 = sqrt(endLevel);
2963 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2964 } break;
2965 case shape_Cubed : {
2966 unit->m_y1 = pow(level, 0.33333333);
2967 unit->m_y2 = pow(endLevel, 0.33333333);
2968 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
2969 } break;
2974 int nsmps = sc_min(remain, counter);
2975 switch (unit->m_shape) {
2976 case shape_Step : {
2977 for (int i=0; i<nsmps; ++i) {
2978 ZXP(out) = level;
2980 } break;
2981 case shape_Linear : {
2982 double grow = unit->m_grow;
2983 for (int i=0; i<nsmps; ++i) {
2984 ZXP(out) = level;
2985 level += grow;
2987 } break;
2988 case shape_Exponential : {
2989 double grow = unit->m_grow;
2990 for (int i=0; i<nsmps; ++i) {
2991 ZXP(out) = level;
2992 level *= grow;
2994 } break;
2995 case shape_Sine : {
2996 double a2 = unit->m_a2;
2997 double b1 = unit->m_b1;
2998 double y2 = unit->m_y2;
2999 double y1 = unit->m_y1;
3000 for (int i=0; i<nsmps; ++i) {
3001 ZXP(out) = level;
3002 double y0 = b1 * y1 - y2;
3003 level = a2 - y0;
3004 y2 = y1;
3005 y1 = y0;
3007 unit->m_y1 = y1;
3008 unit->m_y2 = y2;
3009 } break;
3010 case shape_Welch : {
3011 double a2 = unit->m_a2;
3012 double b1 = unit->m_b1;
3013 double y2 = unit->m_y2;
3014 double y1 = unit->m_y1;
3015 for (int i=0; i<nsmps; ++i) {
3016 ZXP(out) = level;
3017 double y0 = b1 * y1 - y2;
3018 level = a2 + y0;
3019 y2 = y1;
3020 y1 = y0;
3022 unit->m_y1 = y1;
3023 unit->m_y2 = y2;
3024 } break;
3025 case shape_Curve : {
3026 double a2 = unit->m_a2;
3027 double b1 = unit->m_b1;
3028 double grow = unit->m_grow;
3029 for (int i=0; i<nsmps; ++i) {
3030 ZXP(out) = level;
3031 b1 *= grow;
3032 level = a2 - b1;
3034 unit->m_b1 = b1;
3035 } break;
3036 case shape_Squared : {
3037 double grow = unit->m_grow;
3038 double y1 = unit->m_y1;
3039 for (int i=0; i<nsmps; ++i) {
3040 ZXP(out) = level;
3041 y1 += grow;
3042 level = y1*y1;
3044 unit->m_y1 = y1;
3045 } break;
3046 case shape_Cubed : {
3047 double grow = unit->m_grow;
3048 double y1 = unit->m_y1;
3049 for (int i=0; i<nsmps; ++i) {
3050 ZXP(out) = level;
3051 y1 += grow;
3052 level = y1*y1*y1;
3054 unit->m_y1 = y1;
3055 } break;
3056 case shape_Sustain : {
3057 for (int i=0; i<nsmps; ++i) {
3058 ZXP(out) = level;
3060 } break;
3062 remain -= nsmps;
3063 counter -= nsmps;
3065 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, ZOUT0(0));
3066 unit->m_level = level;
3067 unit->m_counter = counter;
3071 #ifdef NOVA_SIMD
3072 FLATTEN void EnvGen_next_ak_nova(EnvGen *unit, int inNumSamples)
3074 float *out = ZOUT(0);
3075 float gate = ZIN0(kEnvGen_gate);
3076 int counter = unit->m_counter;
3077 double level = unit->m_level;
3079 if (unit->m_prevGate <= 0. && gate > 0.) {
3080 unit->m_stage = -1;
3081 unit->mDone = false;
3082 unit->m_released = false;
3083 counter = 0;
3084 } else if (gate <= -1.f && unit->m_prevGate > -1.f) {
3085 // cutoff
3086 int numstages = (int)ZIN0(kEnvGen_numStages);
3087 float dur = -gate - 1.f;
3088 counter = (int32)(dur * SAMPLERATE);
3089 counter = sc_max(1, counter);
3090 unit->m_stage = numstages;
3091 unit->m_shape = shape_Linear;
3092 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias);
3093 unit->m_grow = (unit->m_endLevel - level) / counter;
3094 } else if (unit->m_prevGate > 0.f && gate <= 0.f
3095 && unit->m_releaseNode >= 0 && !unit->m_released) {
3096 counter = 0;
3097 unit->m_stage = unit->m_releaseNode - 1;
3098 unit->m_released = true;
3100 unit->m_prevGate = gate;
3102 int remain = inNumSamples;
3103 if (counter > inNumSamples)
3105 switch (unit->m_shape) {
3106 case shape_Step :
3107 case shape_Sustain :
3108 nova::setvec_simd(OUT(0), (float)level, inNumSamples);
3109 remain = 0;
3110 counter -= inNumSamples;
3111 break;
3112 case shape_Linear : {
3113 double slope = unit->m_grow;
3114 nova::set_slope_vec_simd(OUT(0), (float)level, (float)slope, inNumSamples);
3115 level += inNumSamples * slope;
3116 remain = 0;
3117 counter -= inNumSamples;
3118 } break;
3119 case shape_Exponential : {
3120 double grow = unit->m_grow;
3121 nova::set_exp_vec_simd(OUT(0), (float)level, (float)grow, inNumSamples);
3122 level *= sc_powi(grow, inNumSamples);
3123 remain = 0;
3124 counter -= inNumSamples;
3125 } break;
3129 while (remain)
3131 if (counter == 0) {
3132 int numstages = (int)ZIN0(kEnvGen_numStages);
3134 if (unit->m_stage+1 >= numstages) { // num stages
3135 counter = INT_MAX;
3136 unit->m_shape = 0;
3137 level = unit->m_endLevel;
3138 unit->mDone = true;
3139 int doneAction = (int)ZIN0(kEnvGen_doneAction);
3140 DoneAction(doneAction, unit);
3141 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
3142 int loopNode = (int)ZIN0(kEnvGen_loopNode);
3143 if (loopNode >= 0 && loopNode < numstages) {
3144 unit->m_stage = loopNode;
3145 goto initSegment;
3146 } else {
3147 counter = INT_MAX;
3148 unit->m_shape = shape_Sustain;
3149 level = unit->m_endLevel;
3151 } else {
3152 unit->m_stage++;
3153 initSegment:
3154 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
3156 if (stageOffset + 4 > unit->mNumInputs) {
3157 // oops.
3158 Print("envelope went past end of inputs.\n");
3159 ClearUnitOutputs(unit, 1);
3160 NodeEnd(&unit->mParent->mNode);
3161 return;
3164 float** envPtr = unit->mInBuf + stageOffset;
3165 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
3166 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
3167 unit->m_shape = (int32)*envPtr[2];
3168 double curve = *envPtr[3];
3169 unit->m_endLevel = endLevel;
3171 counter = (int32)(dur * SAMPLERATE);
3172 counter = sc_max(1, counter);
3174 if (counter == 1) unit->m_shape = 1; // shape_Linear
3175 switch (unit->m_shape) {
3176 case shape_Step : {
3177 level = endLevel;
3178 } break;
3179 case shape_Linear : {
3180 unit->m_grow = (endLevel - level) / counter;
3181 } break;
3182 case shape_Exponential : {
3183 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3184 } break;
3185 case shape_Sine : {
3186 double w = pi / counter;
3188 unit->m_a2 = (endLevel + level) * 0.5;
3189 unit->m_b1 = 2. * cos(w);
3190 unit->m_y1 = (endLevel - level) * 0.5;
3191 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3192 level = unit->m_a2 - unit->m_y1;
3193 } break;
3194 case shape_Welch : {
3195 double w = (pi * 0.5) / counter;
3197 unit->m_b1 = 2. * cos(w);
3199 if (endLevel >= level) {
3200 unit->m_a2 = level;
3201 unit->m_y1 = 0.;
3202 unit->m_y2 = -sin(w) * (endLevel - level);
3203 } else {
3204 unit->m_a2 = endLevel;
3205 unit->m_y1 = level - endLevel;
3206 unit->m_y2 = cos(w) * (level - endLevel);
3208 level = unit->m_a2 + unit->m_y1;
3209 } break;
3210 case shape_Curve : {
3211 if (fabs(curve) < 0.001) {
3212 unit->m_shape = 1; // shape_Linear
3213 unit->m_grow = (endLevel - level) / counter;
3214 } else {
3215 double a1 = (endLevel - level) / (1.0 - exp(curve));
3216 unit->m_a2 = level + a1;
3217 unit->m_b1 = a1;
3218 unit->m_grow = exp(curve / counter);
3220 } break;
3221 case shape_Squared : {
3222 unit->m_y1 = sqrt(level);
3223 unit->m_y2 = sqrt(endLevel);
3224 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3225 } break;
3226 case shape_Cubed : {
3227 unit->m_y1 = pow(level, 0.33333333);
3228 unit->m_y2 = pow(endLevel, 0.33333333);
3229 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3230 } break;
3235 int nsmps = sc_min(remain, counter);
3236 switch (unit->m_shape) {
3237 case shape_Step : {
3238 for (int i=0; i<nsmps; ++i) {
3239 ZXP(out) = level;
3241 } break;
3242 case shape_Linear : {
3243 double grow = unit->m_grow;
3244 for (int i=0; i<nsmps; ++i) {
3245 ZXP(out) = level;
3246 level += grow;
3248 } break;
3249 case shape_Exponential : {
3250 double grow = unit->m_grow;
3251 for (int i=0; i<nsmps; ++i) {
3252 ZXP(out) = level;
3253 level *= grow;
3255 } break;
3256 case shape_Sine : {
3257 double a2 = unit->m_a2;
3258 double b1 = unit->m_b1;
3259 double y2 = unit->m_y2;
3260 double y1 = unit->m_y1;
3261 for (int i=0; i<nsmps; ++i) {
3262 ZXP(out) = level;
3263 double y0 = b1 * y1 - y2;
3264 level = a2 - y0;
3265 y2 = y1;
3266 y1 = y0;
3268 unit->m_y1 = y1;
3269 unit->m_y2 = y2;
3270 } break;
3271 case shape_Welch : {
3272 double a2 = unit->m_a2;
3273 double b1 = unit->m_b1;
3274 double y2 = unit->m_y2;
3275 double y1 = unit->m_y1;
3276 for (int i=0; i<nsmps; ++i) {
3277 ZXP(out) = level;
3278 double y0 = b1 * y1 - y2;
3279 level = a2 + y0;
3280 y2 = y1;
3281 y1 = y0;
3283 unit->m_y1 = y1;
3284 unit->m_y2 = y2;
3285 } break;
3286 case shape_Curve : {
3287 double a2 = unit->m_a2;
3288 double b1 = unit->m_b1;
3289 double grow = unit->m_grow;
3290 for (int i=0; i<nsmps; ++i) {
3291 ZXP(out) = level;
3292 b1 *= grow;
3293 level = a2 - b1;
3295 unit->m_b1 = b1;
3296 } break;
3297 case shape_Squared : {
3298 double grow = unit->m_grow;
3299 double y1 = unit->m_y1;
3300 for (int i=0; i<nsmps; ++i) {
3301 ZXP(out) = level;
3302 y1 += grow;
3303 level = y1*y1;
3305 unit->m_y1 = y1;
3306 } break;
3307 case shape_Cubed : {
3308 double grow = unit->m_grow;
3309 double y1 = unit->m_y1;
3310 for (int i=0; i<nsmps; ++i) {
3311 ZXP(out) = level;
3312 y1 += grow;
3313 level = y1*y1*y1;
3315 unit->m_y1 = y1;
3316 } break;
3317 case shape_Sustain : {
3318 for (int i=0; i<nsmps; ++i) {
3319 ZXP(out) = level;
3321 } break;
3323 remain -= nsmps;
3324 counter -= nsmps;
3326 //Print("x %d %d %d %g\n", unit->m_stage, counter, unit->m_shape, ZOUT0(0));
3327 unit->m_level = level;
3328 unit->m_counter = counter;
3331 #endif
3333 #define CHECK_GATE \
3334 float prevGate = gate; \
3335 gate = ZXP(gatein); \
3336 if (prevGate <= 0.f && gate > 0.f) { \
3337 gatein--; \
3338 unit->m_stage = -1; \
3339 unit->m_released = false; \
3340 unit->mDone = false; \
3341 counter = i; \
3342 nsmps = i; \
3343 break; \
3344 } else if (gate <= -1.f && unit->m_prevGate > -1.f) { \
3345 int numstages = (int)ZIN0(kEnvGen_numStages); \
3346 float dur = -gate - 1.f; \
3347 gatein--; \
3348 counter = (int32)(dur * SAMPLERATE); \
3349 counter = sc_max(1, counter) + i; \
3350 unit->m_stage = numstages; \
3351 unit->m_shape = shape_Linear; \
3352 unit->m_endLevel = ZIN0(unit->mNumInputs - 4) * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); \
3353 unit->m_grow = (unit->m_endLevel - level) / counter; \
3354 nsmps = i; \
3355 break; \
3356 } else if (prevGate > 0.f && gate <= 0.f \
3357 && unit->m_releaseNode >= 0 && !unit->m_released) { \
3358 gatein--; \
3359 counter = i; \
3360 unit->m_stage = unit->m_releaseNode - 1; \
3361 unit->m_released = true; \
3362 nsmps = i; \
3363 break; \
3367 void EnvGen_next_aa(EnvGen *unit, int inNumSamples)
3369 float *out = ZOUT(0);
3370 float *gatein = ZIN(kEnvGen_gate);
3371 int counter = unit->m_counter;
3372 double level = unit->m_level;
3373 float gate = unit->m_prevGate;
3374 int remain = inNumSamples;
3375 while (remain)
3377 if (counter == 0) {
3379 int numstages = (int)ZIN0(kEnvGen_numStages);
3381 if (unit->m_stage+1 >= numstages) { // num stages
3382 counter = INT_MAX;
3383 unit->m_shape = 0;
3384 level = unit->m_endLevel;
3385 unit->mDone = true;
3386 int doneAction = (int)ZIN0(kEnvGen_doneAction);
3387 DoneAction(doneAction, unit);
3388 } else if (unit->m_stage+1 == (int)ZIN0(kEnvGen_releaseNode) && !unit->m_released) { // sustain stage
3389 int loopNode = (int)ZIN0(kEnvGen_loopNode);
3390 if (loopNode >= 0 && loopNode < numstages) {
3391 unit->m_stage = loopNode;
3392 goto initSegment;
3393 } else {
3394 counter = INT_MAX;
3395 unit->m_shape = shape_Sustain;
3396 level = unit->m_endLevel;
3398 } else {
3399 unit->m_stage++;
3400 initSegment:
3401 int stageOffset = (unit->m_stage << 2) + kEnvGen_nodeOffset;
3403 if (stageOffset + 4 > unit->mNumInputs) {
3404 // oops.
3405 Print("envelope went past end of inputs.\n");
3406 ClearUnitOutputs(unit, 1);
3407 NodeEnd(&unit->mParent->mNode);
3408 return;
3411 float** envPtr = unit->mInBuf + stageOffset;
3412 double endLevel = *envPtr[0] * ZIN0(kEnvGen_levelScale) + ZIN0(kEnvGen_levelBias); // scale levels
3413 double dur = *envPtr[1] * ZIN0(kEnvGen_timeScale);
3414 unit->m_shape = (int32)*envPtr[2];
3415 double curve = *envPtr[3];
3416 unit->m_endLevel = endLevel;
3418 counter = (int32)(dur * SAMPLERATE);
3419 counter = sc_max(1, counter);
3420 if (counter == 1) unit->m_shape = 1; // shape_Linear
3421 switch (unit->m_shape) {
3422 case shape_Step : {
3423 level = endLevel;
3424 } break;
3425 case shape_Linear : {
3426 unit->m_grow = (endLevel - level) / counter;
3427 } break;
3428 case shape_Exponential : {
3429 unit->m_grow = pow(endLevel / level, 1.0 / counter);
3430 } break;
3431 case shape_Sine : {
3432 double w = pi / counter;
3434 unit->m_a2 = (endLevel + level) * 0.5;
3435 unit->m_b1 = 2. * cos(w);
3436 unit->m_y1 = (endLevel - level) * 0.5;
3437 unit->m_y2 = unit->m_y1 * sin(pi * 0.5 - w);
3438 level = unit->m_a2 - unit->m_y1;
3439 } break;
3440 case shape_Welch : {
3441 double w = (pi * 0.5) / counter;
3443 unit->m_b1 = 2. * cos(w);
3445 if (endLevel >= level) {
3446 unit->m_a2 = level;
3447 unit->m_y1 = 0.;
3448 unit->m_y2 = -sin(w) * (endLevel - level);
3449 } else {
3450 unit->m_a2 = endLevel;
3451 unit->m_y1 = level - endLevel;
3452 unit->m_y2 = cos(w) * (level - endLevel);
3454 level = unit->m_a2 + unit->m_y1;
3455 } break;
3456 case shape_Curve : {
3457 if (fabs(curve) < 0.001) {
3458 unit->m_shape = 1; // shape_Linear
3459 unit->m_grow = (endLevel - level) / counter;
3460 } else {
3461 double a1 = (endLevel - level) / (1.0 - exp(curve));
3462 unit->m_a2 = level + a1;
3463 unit->m_b1 = a1;
3464 unit->m_grow = exp(curve / counter);
3466 } break;
3467 case shape_Squared : {
3468 unit->m_y1 = sqrt(level);
3469 unit->m_y2 = sqrt(endLevel);
3470 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3471 } break;
3472 case shape_Cubed : {
3473 unit->m_y1 = pow(level, 0.33333333);
3474 unit->m_y2 = pow(endLevel, 0.33333333);
3475 unit->m_grow = (unit->m_y2 - unit->m_y1) / counter;
3476 } break;
3481 int nsmps = sc_min(remain, counter);
3483 switch (unit->m_shape) {
3484 case shape_Step : {
3485 for (int i=0; i<nsmps; ++i) {
3486 CHECK_GATE
3487 ZXP(out) = level;
3489 } break;
3490 case shape_Linear : {
3491 double grow = unit->m_grow;
3492 for (int i=0; i<nsmps; ++i) {
3493 CHECK_GATE
3494 ZXP(out) = level;
3495 level += grow;
3497 } break;
3498 case shape_Exponential : {
3499 double grow = unit->m_grow;
3500 for (int i=0; i<nsmps; ++i) {
3501 CHECK_GATE
3502 ZXP(out) = level;
3503 level *= grow;
3505 } break;
3506 case shape_Sine : {
3507 double a2 = unit->m_a2;
3508 double b1 = unit->m_b1;
3509 double y2 = unit->m_y2;
3510 double y1 = unit->m_y1;
3511 for (int i=0; i<nsmps; ++i) {
3512 CHECK_GATE
3513 ZXP(out) = level;
3514 double y0 = b1 * y1 - y2;
3515 level = a2 - y0;
3516 y2 = y1;
3517 y1 = y0;
3519 unit->m_y1 = y1;
3520 unit->m_y2 = y2;
3521 } break;
3522 case shape_Welch : {
3523 double a2 = unit->m_a2;
3524 double b1 = unit->m_b1;
3525 double y2 = unit->m_y2;
3526 double y1 = unit->m_y1;
3527 for (int i=0; i<nsmps; ++i) {
3528 CHECK_GATE
3529 ZXP(out) = level;
3530 double y0 = b1 * y1 - y2;
3531 level = a2 + y0;
3532 y2 = y1;
3533 y1 = y0;
3535 unit->m_y1 = y1;
3536 unit->m_y2 = y2;
3537 } break;
3538 case shape_Curve : {
3539 double a2 = unit->m_a2;
3540 double b1 = unit->m_b1;
3541 double grow = unit->m_grow;
3542 for (int i=0; i<nsmps; ++i) {
3543 CHECK_GATE
3544 ZXP(out) = level;
3545 b1 *= grow;
3546 level = a2 - b1;
3548 unit->m_b1 = b1;
3549 } break;
3550 case shape_Squared : {
3551 double grow = unit->m_grow;
3552 double y1 = unit->m_y1;
3553 for (int i=0; i<nsmps; ++i) {
3554 CHECK_GATE
3555 ZXP(out) = level;
3556 y1 += grow;
3557 level = y1*y1;
3559 unit->m_y1 = y1;
3560 } break;
3561 case shape_Cubed : {
3562 double grow = unit->m_grow;
3563 double y1 = unit->m_y1;
3564 for (int i=0; i<nsmps; ++i) {
3565 CHECK_GATE
3566 ZXP(out) = level;
3567 y1 += grow;
3568 level = y1*y1*y1;
3570 unit->m_y1 = y1;
3571 } break;
3572 case shape_Sustain : {
3573 for (int i=0; i<nsmps; ++i) {
3574 CHECK_GATE
3575 ZXP(out) = level;
3577 } break;
3579 remain -= nsmps;
3580 counter -= nsmps;
3582 unit->m_level = level;
3583 unit->m_counter = counter;
3584 unit->m_prevGate = gate;
3587 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3589 void Linen_Ctor(Linen *unit)
3591 // gate attack level release
3592 SETCALC(Linen_next_k);
3594 unit->m_level = 0.f;
3595 unit->m_stage = 4;
3596 unit->m_prevGate = 0.f;
3597 Linen_next_k(unit, 1);
3600 void Linen_next_k(Linen *unit, int inNumSamples)
3602 float gate = ZIN0(0);
3603 float *out = OUT(0);
3605 if (unit->m_prevGate <= 0.f && gate > 0.f) {
3606 unit->mDone = false;
3607 unit->m_stage = 0;
3608 float attackTime = ZIN0(1);
3609 float susLevel = ZIN0(2);
3610 int counter = (int)(attackTime * SAMPLERATE);
3611 counter = sc_max(1, counter);
3612 unit->m_slope = (susLevel - unit->m_level) / counter;
3613 unit->m_counter = counter;
3616 switch (unit->m_stage) {
3617 case 0 :
3618 case 2 :
3619 *out = unit->m_level;
3620 unit->m_level += unit->m_slope;
3621 if (--unit->m_counter == 0) unit->m_stage++;
3622 break;
3623 case 1 :
3624 *out = unit->m_level;
3625 if (gate <= -1.f) {
3626 // cutoff
3627 unit->m_stage = 2;
3628 float releaseTime = -gate - 1.f;
3629 int counter = (int)(releaseTime * SAMPLERATE);
3630 counter = sc_max(1, counter);
3631 unit->m_slope = -unit->m_level / counter;
3632 unit->m_counter = counter;
3633 } else if (gate <= 0.f) {
3634 unit->m_stage = 2;
3635 float releaseTime = ZIN0(3);
3636 int counter = (int)(releaseTime * SAMPLERATE);
3637 counter = sc_max(1, counter);
3638 unit->m_slope = -unit->m_level / counter;
3639 unit->m_counter = counter;
3641 //Print("release %d %d\n", unit->mParent->mNode.mID, counter);
3643 break;
3644 case 3 : {
3645 *out = 0.f;
3646 //Print("done %d\n", unit->mParent->mNode.mID);
3647 unit->mDone = true;
3648 unit->m_stage++;
3649 int doneAction = (int)ZIN0(4);
3650 DoneAction(doneAction, unit);
3651 } break;
3652 case 4 :
3653 *out = 0.f;
3654 break;
3656 unit->m_prevGate = gate;
3659 ////////////////////////////////////////////////////////////////////////////////////////////////////////
3661 void EnvFill(World *world, struct SndBuf *buf, struct sc_msg_iter *msg)
3663 if (buf->channels != 1) return;
3665 int size = buf->samples;
3666 int byteSize = size * sizeof(float);
3667 float *data = (float*)malloc(byteSize);
3669 double level = msg->getf();
3670 int numStages = msg->geti();
3671 /*int releaseNode =*/ msg->geti(); // ignored
3672 /*int loopNode =*/ msg->geti(); // ignored
3674 double pos = 0.;
3675 int32 index = 0;
3676 int32 remain = size;
3678 for (int j=0; j < numStages; ++j)
3680 double endLevel = msg->getf();
3681 double dur = msg->getf();
3682 int shape = msg->geti();
3683 double curve = msg->getf();
3685 int32 ipos = (int32)pos;
3686 double smpdur = dur * size;
3687 int32 nsmps = (int32)smpdur - ipos;
3688 nsmps = sc_min(nsmps, remain);
3690 switch (shape) {
3691 case shape_Step : {
3692 level = endLevel;
3693 for (int i=0; i<nsmps; ++i) {
3694 data[index++] = level;
3696 } break;
3697 case shape_Linear : {
3698 double grow = (endLevel - level) / nsmps;
3699 for (int i=0; i<nsmps; ++i) {
3700 data[index++] = level;
3701 level += grow;
3703 } break;
3704 case shape_Exponential : {
3705 double grow = pow(endLevel / level, 1.0 / nsmps);
3706 for (int i=0; i<nsmps; ++i) {
3707 data[index++] = level;
3708 level *= grow;
3710 } break;
3711 case shape_Sine : {
3712 double w = pi / nsmps;
3714 double a2 = (endLevel + level) * 0.5;
3715 double b1 = 2. * cos(w);
3716 double y1 = (endLevel - level) * 0.5;
3717 double y2 = y1 * sin(pi * 0.5 - w);
3718 level = a2 - y1;
3719 for (int i=0; i<nsmps; ++i) {
3720 data[index++] = level;
3721 double y0 = b1 * y1 - y2;
3722 level = a2 - y0;
3723 y2 = y1;
3724 y1 = y0;
3726 } break;
3727 case shape_Welch : {
3728 double w = (pi * 0.5) / nsmps;
3730 double b1 = 2. * cos(w);
3731 double a2, y1, y2;
3732 if (endLevel >= level) {
3733 a2 = level;
3734 y1 = 0.;
3735 y2 = -sin(w) * (endLevel - level);
3736 } else {
3737 a2 = endLevel;
3738 y1 = level - endLevel;
3739 y2 = cos(w) * (level - endLevel);
3741 level = a2 + y1;
3742 for (int i=0; i<nsmps; ++i) {
3743 data[index++] = level;
3744 double y0 = b1 * y1 - y2;
3745 level = a2 - y0;
3746 y2 = y1;
3747 y1 = y0;
3749 } break;
3750 case shape_Curve : {
3751 if (fabs(curve) < 0.001) {
3752 double grow = (endLevel - level) / nsmps;
3753 for (int i=0; i<nsmps; ++i) {
3754 data[index++] = level;
3755 level += grow;
3757 } else {
3758 double a1 = (endLevel - level) / (1.0 - exp(curve));
3759 double a2 = level + a1;
3760 double b1 = a1;
3761 double grow = exp(curve / nsmps);
3762 for (int i=0; i<nsmps; ++i) {
3763 data[index++] = level;
3764 b1 *= grow;
3765 level = a2 - b1;
3768 } break;
3769 case shape_Squared : {
3770 double y1 = sqrt(level);
3771 double y2 = sqrt(endLevel);
3772 double grow = (y2 - y1) / nsmps;
3773 for (int i=0; i<nsmps; ++i) {
3774 data[index++] = level;
3775 y1 += grow;
3776 level = y1*y1;
3778 } break;
3779 case shape_Cubed : {
3780 double y1 = pow(level, 0.33333333);
3781 double y2 = pow(endLevel, 0.33333333);
3782 double grow = (y2 - y1) / nsmps;
3783 for (int i=0; i<nsmps; ++i) {
3784 data[index++] = level;
3785 y1 += grow;
3786 level = y1*y1*y1;
3788 } break;
3791 pos += smpdur;
3792 level = endLevel;
3793 remain -= nsmps;
3795 memcpy(buf->data, data, byteSize);
3796 free(data);
3799 //////////////////// Add IEnvGen 06/06/2007 /////////////////////////////////
3802 struct IEnvGen : public Unit
3804 float m_level, m_offset;
3805 float m_startpoint, m_numvals, m_pointin;
3806 float* m_envvals;
3810 extern "C"
3812 void IEnvGen_next_a(IEnvGen *unit, int inNumSamples);
3813 void IEnvGen_next_k(IEnvGen *unit, int inNumSamples);
3814 void IEnvGen_Ctor(IEnvGen* unit);
3815 void IEnvGen_Dtor(IEnvGen* unit);
3818 #define GET_ENV_VAL \
3819 switch (shape) \
3821 case shape_Step : \
3822 level = unit->m_level = endLevel; \
3823 break; \
3824 case shape_Linear : \
3825 default: \
3826 level = unit->m_level = pos * (endLevel - begLevel) + begLevel; \
3827 break; \
3828 case shape_Exponential : \
3829 level = unit->m_level = begLevel * pow(endLevel / begLevel, pos); \
3830 break; \
3831 case shape_Sine : \
3832 level = unit->m_level = begLevel + (endLevel - begLevel) * (-cos(pi * pos) * 0.5 + 0.5); \
3833 break; \
3834 case shape_Welch : \
3836 if (begLevel < endLevel) \
3837 level = unit->m_level = begLevel + (endLevel - begLevel) * sin(pi2 * pos); \
3838 else \
3839 level = unit->m_level = endLevel - (endLevel - begLevel) * sin(pi2 - pi2 * pos); \
3840 break; \
3842 case shape_Curve : \
3843 if (fabs((float)curve) < 0.0001) { \
3844 level = unit->m_level = pos * (endLevel - begLevel) + begLevel; \
3845 } else { \
3846 double denom = 1. - exp((float)curve); \
3847 double numer = 1. - exp((float)(pos * curve)); \
3848 level = unit->m_level = begLevel + (endLevel - begLevel) * (numer/denom); \
3850 break; \
3851 case shape_Squared : \
3853 double sqrtBegLevel = sqrt(begLevel); \
3854 double sqrtEndLevel = sqrt(endLevel); \
3855 double sqrtLevel = pos * (sqrtEndLevel - sqrtBegLevel) + sqrtBegLevel; \
3856 level = unit->m_level = sqrtLevel * sqrtLevel; \
3857 break; \
3859 case shape_Cubed : \
3861 double cbrtBegLevel = pow(begLevel, 0.3333333f); \
3862 double cbrtEndLevel = pow(endLevel, 0.3333333f); \
3863 double cbrtLevel = pos * (cbrtEndLevel - cbrtBegLevel) + cbrtBegLevel; \
3864 level = unit->m_level = cbrtLevel * cbrtLevel * cbrtLevel; \
3865 break; \
3870 void IEnvGen_Ctor(IEnvGen *unit)
3873 if (INRATE(0) == calc_FullRate) {
3874 SETCALC(IEnvGen_next_a);
3875 } else {
3876 SETCALC(IEnvGen_next_k);
3879 // pointer, offset
3880 // initlevel, numstages, totaldur,
3881 // [dur, shape, curve, level] * numvals
3882 int numStages = (int)IN0(3);
3883 int numvals = numStages * 4; // initlevel + (levels, dur, shape, curves) * stages
3884 float offset = unit->m_offset = IN0(1);
3885 float point = unit->m_pointin = IN0(0) - offset;
3886 unit->m_envvals = (float*)RTAlloc(unit->mWorld, (int)(numvals + 1.) * sizeof(float));
3888 unit->m_envvals[0] = IN0(2);
3889 // Print("offset of and initial values %3,3f, %3.3f\n", offset, unit->m_envvals[0]);
3890 // fill m_envvals with the values;
3891 for (int i = 1; i <= numvals; i++) {
3892 unit->m_envvals[i] = IN0(4 + i);
3893 // Print("val for: %d, %3.3f\n", i, unit->m_envvals[i]);
3896 // float out = OUT0(0);
3897 float totalDur = IN0(4);
3898 float level = 0.f;
3899 float newtime = 0.f;
3900 int stage = 0;
3901 float seglen = 0.f;
3902 if (point >= totalDur) {
3903 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
3904 } else {
3905 if (point <= 0.0) {
3906 unit->m_level = level = unit->m_envvals[0];
3907 } else {
3908 float segpos = point;
3909 // determine which segment the current time pointer needs calculated
3910 for(int j = 0; point >= newtime; j++) {
3911 seglen = unit->m_envvals[(j * 4) + 1];
3912 newtime += seglen;
3913 segpos -= seglen;
3914 stage = j;
3917 segpos = segpos + seglen;
3918 float begLevel = unit->m_envvals[(stage * 4)];
3919 int shape = (int)unit->m_envvals[(stage * 4) + 2];
3920 int curve = (int)unit->m_envvals[(stage * 4) + 3];
3921 float endLevel = unit->m_envvals[(stage * 4) + 4];
3922 float pos = (segpos / seglen);
3924 GET_ENV_VAL
3927 OUT0(0) = level;
3930 void IEnvGen_Dtor(IEnvGen *unit)
3932 RTFree(unit->mWorld, unit->m_envvals);
3936 void IEnvGen_next_a(IEnvGen *unit, int inNumSamples)
3938 float* out = OUT(0);
3939 float level = unit->m_level;
3940 float* pointin = IN(0);
3941 float offset = unit->m_offset;
3942 int numStages = (int)IN0(3);
3943 float point; // = unit->m_pointin;
3945 float totalDur = IN0(4);
3947 int stagemul;
3948 // pointer, offset
3949 // level0, numstages, totaldur,
3950 // [initval, [dur, shape, curve, level] * N ]
3952 for( int i = 0; i < inNumSamples; i++) {
3953 if (pointin[i] == unit->m_pointin){
3954 out[i] = level;
3955 } else {
3956 unit->m_pointin = point = sc_max(pointin[i] - offset, 0.0);
3957 float newtime = 0.f;
3958 int stage = 0;
3959 float seglen = 0.f;
3960 if (point >= totalDur) {
3961 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
3962 } else {
3963 if (point <= 0.0) {
3964 unit->m_level = level = unit->m_envvals[0];
3965 } else {
3966 float segpos = point;
3967 // determine which segment the current time pointer needs
3968 for(int j = 0; point >= newtime; j++) {
3969 seglen = unit->m_envvals[(j * 4) + 1];
3970 newtime += seglen;
3971 segpos -= seglen;
3972 stage = j;
3974 stagemul = stage * 4;
3975 segpos = segpos + seglen;
3976 float begLevel = unit->m_envvals[stagemul];
3977 int shape = (int)unit->m_envvals[stagemul + 2];
3978 int curve = (int)unit->m_envvals[stagemul + 3];
3979 float endLevel = unit->m_envvals[stagemul + 4];
3980 float pos = (segpos / seglen);
3982 GET_ENV_VAL
3985 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 = IN0(0);
3995 float offset = unit->m_offset;
3996 int numStages = (int)IN0(3);
3997 float point; // = unit->m_pointin;
3999 float totalDur = IN0(4);
4001 int stagemul;
4002 // pointer, offset
4003 // level0, numstages, totaldur,
4004 // [initval, [dur, shape, curve, level] * N ]
4006 for( int i = 0; i < inNumSamples; i++) {
4007 if (pointin == unit->m_pointin){
4008 out[i] = level;
4009 } else {
4010 unit->m_pointin = point = sc_max(pointin - offset, 0.0);
4011 float newtime = 0.f;
4012 int stage = 0;
4013 float seglen = 0.f;
4014 if (point >= totalDur) {
4015 unit->m_level = level = unit->m_envvals[numStages * 4]; // grab the last value
4016 } else {
4017 if (point <= 0.0) {
4018 unit->m_level = level = unit->m_envvals[0];
4019 } else {
4020 float segpos = point;
4021 // determine which segment the current time pointer needs
4022 for(int j = 0; point >= newtime; j++) {
4023 seglen = unit->m_envvals[(j * 4) + 1];
4024 newtime += seglen;
4025 segpos -= seglen;
4026 stage = j;
4028 stagemul = stage * 4;
4029 segpos = segpos + seglen;
4030 float begLevel = unit->m_envvals[stagemul];
4031 int shape = (int)unit->m_envvals[stagemul + 2];
4032 int curve = (int)unit->m_envvals[stagemul + 3];
4033 float endLevel = unit->m_envvals[stagemul + 4];
4034 float pos = (segpos / seglen);
4036 GET_ENV_VAL
4039 out[i] = level;
4044 ////////////////////////////////////////////////////////////////////////////////////////////////////////
4047 PluginLoad(LF)
4049 ft = inTable;
4051 DefineSimpleUnit(Vibrato);
4052 DefineSimpleUnit(LFPulse);
4053 DefineSimpleUnit(LFSaw);
4054 DefineSimpleUnit(LFPar);
4055 DefineSimpleUnit(LFCub);
4056 DefineSimpleUnit(LFTri);
4057 DefineSimpleUnit(LFGauss);
4058 DefineSimpleUnit(Impulse);
4059 DefineSimpleUnit(VarSaw);
4060 DefineSimpleUnit(SyncSaw);
4061 DefineSimpleUnit(K2A);
4062 DefineSimpleUnit(A2K);
4063 DefineSimpleUnit(T2K);
4064 DefineSimpleUnit(T2A);
4065 DefineSimpleUnit(DC);
4066 DefineSimpleUnit(Line);
4067 DefineSimpleUnit(XLine);
4069 DefineSimpleUnit(Wrap);
4070 DefineSimpleUnit(Fold);
4071 DefineSimpleUnit(Clip);
4072 DefineSimpleUnit(Unwrap);
4073 DefineSimpleUnit(AmpComp);
4074 DefineSimpleUnit(AmpCompA);
4075 DefineSimpleUnit(InRange);
4076 DefineSimpleUnit(InRect);
4077 DefineSimpleUnit(LinExp);
4078 DefineSimpleUnit(EnvGen);
4079 DefineSimpleUnit(Linen);
4081 DefineBufGen("env", EnvFill);
4083 DefineDtorUnit(IEnvGen);