Permalink
Cannot retrieve contributors at this time
| /* | |
| SuperCollider real time audio synthesis system | |
| Copyright (c) 2002 James McCartney. All rights reserved. | |
| http://www.audiosynth.com | |
| This program is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2 of the License, or | |
| (at your option) any later version. | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with this program; if not, write to the Free Software | |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| Chaos Ugens created by Lance Putnam on Mon Jul 19 2004. | |
| */ | |
| #include "SC_PlugIn.h" | |
| #define TWOPI 6.283185307179586 | |
| #define PI 3.141592653589793 | |
| #define RECPI 0.3183098861837907 | |
| #define RECTWOPI 0.1591549430918953 | |
| #define ONESIXTH 0.1666666666666667 | |
| static InterfaceTable* ft; | |
| struct NonLinear : public Unit { | |
| double x0, y0, xn, yn, xnm1, ynm1; | |
| float counter; | |
| // bool stable; | |
| }; | |
| struct CuspN : public NonLinear {}; | |
| struct CuspL : public CuspN { | |
| double frac; | |
| }; | |
| struct GbmanN : public NonLinear {}; | |
| struct GbmanL : public GbmanN { | |
| double frac; | |
| }; | |
| struct HenonN : public Unit { | |
| double x0, x1, xn, xnm1, xnm2, a, b; | |
| float counter; | |
| bool stable; | |
| }; | |
| struct HenonL : public HenonN { | |
| double frac; | |
| }; | |
| struct HenonC : public HenonL { | |
| double xnm3, c0, c1, c2, c3; | |
| }; | |
| struct LatoocarfianN : public NonLinear {}; | |
| struct LatoocarfianL : public LatoocarfianN { | |
| double frac; | |
| }; | |
| struct LatoocarfianC : public LatoocarfianL { | |
| double xnm3, xnm2, c0, c1, c2, c3; | |
| }; | |
| struct LinCongN : public NonLinear {}; | |
| struct LinCongL : public LinCongN { | |
| double frac; | |
| }; | |
| struct LinCongC : public LinCongL { | |
| double xnm3, xnm2, c0, c1, c2, c3; | |
| }; | |
| struct LorenzN : public NonLinear { | |
| double z0, zn, znm1; | |
| }; | |
| struct LorenzL : public LorenzN { | |
| double frac; | |
| }; | |
| struct QuadN : public NonLinear {}; | |
| struct QuadL : public QuadN { | |
| double frac; | |
| }; | |
| struct QuadC : public QuadL { | |
| double xnm3, xnm2; | |
| double c0, c1, c2, c3; | |
| }; | |
| struct StandardN : public NonLinear {}; | |
| struct StandardL : public StandardN { | |
| double frac; | |
| }; | |
| struct FBSineN : public NonLinear {}; | |
| struct FBSineL : public FBSineN { | |
| double frac; | |
| }; | |
| struct FBSineC : public FBSineL { | |
| double xnm3, xnm2; | |
| double c0, c1, c2, c3; | |
| }; | |
| extern "C" { | |
| void CuspN_next(CuspN* unit, int inNumSamples); | |
| void CuspN_Ctor(CuspN* unit); | |
| void CuspL_next(CuspL* unit, int inNumSamples); | |
| void CuspL_Ctor(CuspL* unit); | |
| void GbmanN_next(GbmanN* unit, int inNumSamples); | |
| void GbmanN_Ctor(GbmanN* unit); | |
| void GbmanL_next(GbmanL* unit, int inNumSamples); | |
| void GbmanL_Ctor(GbmanL* unit); | |
| void HenonN_next(HenonN* unit, int inNumSamples); | |
| void HenonN_Ctor(HenonN* unit); | |
| void HenonL_next(HenonL* unit, int inNumSamples); | |
| void HenonL_Ctor(HenonL* unit); | |
| void HenonC_next(HenonC* unit, int inNumSamples); | |
| void HenonC_Ctor(HenonC* unit); | |
| void LinCongN_next(LinCongN* unit, int inNumSamples); | |
| void LinCongN_Ctor(LinCongN* unit); | |
| void LinCongL_next(LinCongL* unit, int inNumSamples); | |
| void LinCongL_Ctor(LinCongL* unit); | |
| void LinCongC_next(LinCongC* unit, int inNumSamples); | |
| void LinCongC_Ctor(LinCongC* unit); | |
| void LatoocarfianN_next(LatoocarfianN* unit, int inNumSamples); | |
| void LatoocarfianN_Ctor(LatoocarfianN* unit); | |
| void LatoocarfianL_next(LatoocarfianL* unit, int inNumSamples); | |
| void LatoocarfianL_Ctor(LatoocarfianL* unit); | |
| void LatoocarfianC_next(LatoocarfianC* unit, int inNumSamples); | |
| void LatoocarfianC_Ctor(LatoocarfianC* unit); | |
| void LorenzL_next(LorenzL* unit, int inNumSamples); | |
| void LorenzL_Ctor(LorenzL* unit); | |
| void QuadN_next(QuadN* unit, int inNumSamples); | |
| void QuadN_Ctor(QuadN* unit); | |
| void QuadL_next(QuadL* unit, int inNumSamples); | |
| void QuadL_Ctor(QuadL* unit); | |
| void QuadC_next(QuadC* unit, int inNumSamples); | |
| void QuadC_Ctor(QuadC* unit); | |
| void StandardN_next(StandardN* unit, int inNumSamples); | |
| void StandardN_Ctor(StandardN* unit); | |
| void StandardL_next(StandardL* unit, int inNumSamples); | |
| void StandardL_Ctor(StandardL* unit); | |
| void FBSineN_next(FBSineN* unit, int inNumSamples); | |
| void FBSineN_Ctor(FBSineN* unit); | |
| void FBSineL_next(FBSineL* unit, int inNumSamples); | |
| void FBSineL_Ctor(FBSineL* unit); | |
| void FBSineC_next(FBSineC* unit, int inNumSamples); | |
| void FBSineC_Ctor(FBSineC* unit); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| // calc 3rd order interpolation coefs from four points | |
| static inline void ipol3Coef(double xnm3, double xnm2, double xnm1, double xn, double& c0, double& c1, double& c2, | |
| double& c3) { | |
| c0 = xnm2; | |
| c1 = 0.5f * (xnm1 - xnm3); | |
| c2 = xnm3 - (2.5f * xnm2) + xnm1 + xnm1 - 0.5f * xn; | |
| c3 = 0.5f * (xn - xnm3) + 1.5f * (xnm2 - xnm1); | |
| } | |
| // do 3rd order interpolation using coefs | |
| static inline double ipol3(float frac, double c0, double c1, double c2, double c3) { | |
| return ((c3 * frac + c2) * frac + c1) * frac + c0; | |
| } | |
| // quick 2pi modulo | |
| inline double mod2pi(double in) { | |
| const double lo = (double)0.; | |
| const double hi = TWOPI; | |
| if (in >= hi) { | |
| in -= hi; | |
| if (in < hi) | |
| return in; | |
| } else if (in < lo) { | |
| in += hi; | |
| if (in >= lo) | |
| return in; | |
| } else | |
| return in; | |
| return in - hi * (double)((int)(in * RECTWOPI)); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void CuspN_next(CuspN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double x0 = ZIN0(3); | |
| double xn = unit->xn; | |
| float counter = unit->counter; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| if (unit->x0 != x0) { | |
| unit->x0 = xn = x0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| xn = a - (b * sqrt(sc_abs(xn))); | |
| } | |
| counter++; | |
| ZXP(out) = xn; | |
| } | |
| unit->xn = xn; | |
| unit->counter = counter; | |
| } | |
| void CuspN_Ctor(CuspN* unit) { | |
| SETCALC(CuspN_next); | |
| unit->x0 = ZIN0(3); | |
| unit->xn = unit->x0; | |
| unit->counter = 0.f; | |
| CuspN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void CuspL_next(CuspL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double x0 = ZIN0(3); | |
| double xn = unit->xn; | |
| float counter = unit->counter; | |
| double xnm1 = unit->xnm1; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| if (unit->x0 != x0) { | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| } | |
| double dx = xn - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| xnm1 = xn; | |
| xn = a - (b * sqrt(sc_abs(xn))); | |
| dx = xn - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = xnm1 + dx * frac; | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->counter = counter; | |
| unit->xnm1 = xnm1; | |
| unit->frac = frac; | |
| } | |
| void CuspL_Ctor(CuspL* unit) { | |
| SETCALC(CuspL_next); | |
| unit->x0 = ZIN0(3); | |
| unit->xn = unit->x0; | |
| unit->xnm1 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.f; | |
| CuspL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void FBSineN_next(FBSineN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double d = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| xn = sin(a * yn + b * xn); | |
| yn = c * yn + d; | |
| yn = mod2pi(yn); | |
| } | |
| counter++; | |
| ZXP(out) = xn; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| } | |
| void FBSineN_Ctor(FBSineN* unit) { | |
| SETCALC(FBSineN_next); | |
| unit->x0 = ZIN0(5); | |
| unit->y0 = ZIN0(6); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->counter = 0.f; | |
| FBSineN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void FBSineL_next(FBSineL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double d = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| double xnm1 = unit->xnm1; | |
| float counter = unit->counter; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| double dx = xn - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.0; | |
| xnm1 = xn; | |
| xn = sin(a * yn + b * xn); | |
| yn = c * yn + d; | |
| yn = mod2pi(yn); | |
| dx = xn - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = xnm1 + dx * frac; | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->xnm1 = xnm1; | |
| unit->counter = counter; | |
| unit->frac = frac; | |
| } | |
| void FBSineL_Ctor(FBSineL* unit) { | |
| SETCALC(FBSineL_next); | |
| unit->x0 = ZIN0(5); | |
| unit->y0 = ZIN0(6); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->xnm1 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.0; | |
| FBSineL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void FBSineC_next(FBSineC* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double d = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| double xnm3 = unit->xnm3; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| double frac = unit->frac; | |
| double c0 = unit->c0; | |
| double c1 = unit->c1; | |
| double c2 = unit->c2; | |
| double c3 = unit->c3; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else | |
| samplesPerCycle = slope = 1.f; | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| unit->x0 = xn = x0; | |
| unit->y0 = y0; | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.0; | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| xn = sin(a * yn + b * xn); | |
| yn = c * yn + d; | |
| yn = mod2pi(yn); | |
| ipol3Coef(xnm3, xnm2, xnm1, xn, c0, c1, c2, c3); | |
| } | |
| counter++; | |
| ZXP(out) = ipol3(frac, c0, c1, c2, c3); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->xnm3 = xnm3; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| unit->frac = frac; | |
| unit->c0 = c0; | |
| unit->c1 = c1; | |
| unit->c2 = c2; | |
| unit->c3 = c3; | |
| } | |
| void FBSineC_Ctor(FBSineC* unit) { | |
| SETCALC(FBSineC_next); | |
| unit->x0 = ZIN0(5); | |
| unit->y0 = ZIN0(6); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->xnm1 = unit->xnm2 = unit->xnm3 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.0; | |
| unit->c0 = unit->c1 = unit->c2 = unit->c3 = 0.; | |
| FBSineC_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void GbmanN_next(GbmanN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| double xPrev = xn; | |
| if (xPrev < 0.f) | |
| xn = 1.f - yn - xPrev; | |
| else | |
| xn = 1.f - yn + xPrev; | |
| yn = xPrev; | |
| } | |
| counter++; | |
| ZXP(out) = xn; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| } | |
| void GbmanN_Ctor(GbmanN* unit) { | |
| SETCALC(GbmanN_next); | |
| unit->xn = ZIN0(1); | |
| unit->yn = ZIN0(2); | |
| unit->counter = 0.f; | |
| GbmanN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void GbmanL_next(GbmanL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| double diff = xn - yn; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| double xPrev = xn; | |
| if (xPrev < 0.f) | |
| xn = 1.f - yn - xPrev; | |
| else | |
| xn = 1.f - yn + xPrev; | |
| yn = xPrev; | |
| diff = xn - xPrev; | |
| } | |
| counter++; | |
| ZXP(out) = yn + (frac * diff); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| unit->frac = frac; | |
| } | |
| void GbmanL_Ctor(GbmanL* unit) { | |
| SETCALC(GbmanL_next); | |
| unit->xn = ZIN0(1); | |
| unit->yn = ZIN0(2); | |
| unit->counter = 0.f; | |
| unit->frac = 0.f; | |
| GbmanL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void HenonN_next(HenonN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double x0 = ZIN0(3); | |
| double x1 = ZIN0(4); | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| float counter = unit->counter; | |
| bool stable = unit->stable; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| if ((unit->a != a) || (unit->b != b) || (unit->x0 != x0) || (unit->x1 != x1)) { | |
| if (!stable) { | |
| xnm2 = x0; | |
| xnm1 = x0; | |
| xn = x1; | |
| } | |
| stable = true; | |
| unit->a = a; | |
| unit->b = b; | |
| unit->x0 = x0; | |
| unit->x1 = x1; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| if (stable) { | |
| xn = 1.f - (a * xnm1 * xnm1) + (b * xnm2); | |
| // Print("%g, ", xn); | |
| if ((xn > 1.5f) || (xn < -1.5f)) { | |
| stable = false; | |
| xn = 0.f; | |
| xnm2 = x0; | |
| xnm1 = x1; | |
| } else { | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| } | |
| } | |
| } | |
| counter++; | |
| ZXP(out) = xnm2; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->counter = counter; | |
| unit->stable = stable; | |
| } | |
| void HenonN_Ctor(HenonN* unit) { | |
| SETCALC(HenonN_next); | |
| unit->x0 = ZIN0(3); | |
| unit->x1 = ZIN0(4); | |
| unit->xn = unit->x1; | |
| unit->xnm1 = unit->x0; | |
| unit->xnm2 = unit->x1; | |
| unit->a = ZIN0(1); | |
| unit->b = ZIN0(2); | |
| unit->counter = 0.f; | |
| unit->stable = true; | |
| HenonN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void HenonL_next(HenonL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double x0 = ZIN0(3); | |
| double x1 = ZIN0(4); | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| float counter = unit->counter; | |
| bool stable = unit->stable; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else | |
| samplesPerCycle = slope = 1.f; | |
| if ((unit->a != a) || (unit->b != b) || (unit->x0 != x0) || (unit->x1 != x1)) { | |
| if (!stable) { | |
| xnm2 = x0; | |
| xnm1 = x0; | |
| xn = x1; | |
| } | |
| stable = true; | |
| unit->a = a; | |
| unit->b = b; | |
| unit->x0 = x0; | |
| unit->x1 = x1; | |
| } | |
| double diff = xnm1 - xnm2; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| if (stable) { | |
| xn = 1.f - (a * xnm1 * xnm1) + (b * xnm2); | |
| if (xn > 1.5f || xn < -1.5f) { | |
| stable = false; | |
| diff = 0.f; | |
| xn = 1.f; | |
| xnm1 = 0.f; | |
| xnm2 = 0.f; | |
| } else { | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| diff = xnm1 - xnm2; | |
| } | |
| frac = 0.f; | |
| } | |
| // Print("slope %g, x2 %g\n", slope, x2); | |
| } | |
| counter++; | |
| ZXP(out) = xnm2 + (diff * frac); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->counter = counter; | |
| unit->stable = stable; | |
| unit->frac = frac; | |
| } | |
| void HenonL_Ctor(HenonL* unit) { | |
| SETCALC(HenonL_next); | |
| unit->x0 = ZIN0(3); | |
| unit->x1 = ZIN0(4); | |
| unit->xn = unit->x1; | |
| unit->xnm1 = unit->x0; | |
| unit->xnm2 = unit->x1; | |
| unit->a = ZIN0(1); | |
| unit->b = ZIN0(2); | |
| unit->counter = 0.f; | |
| unit->stable = true; | |
| unit->frac = 0.; | |
| HenonL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void HenonC_next(HenonC* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double x0 = ZIN0(3); | |
| double x1 = ZIN0(4); | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| double xnm3 = unit->xnm3; | |
| float counter = unit->counter; | |
| bool stable = unit->stable; | |
| double frac = unit->frac; | |
| double c0 = unit->c0; | |
| double c1 = unit->c1; | |
| double c2 = unit->c2; | |
| double c3 = unit->c3; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else | |
| samplesPerCycle = slope = 1.f; | |
| if ((unit->a != a) || (unit->b != b) || (unit->x0 != x0) || (unit->x1 != x1)) { | |
| if (!stable) { | |
| xnm3 = xnm2; | |
| xnm2 = x0; | |
| xnm1 = x0; | |
| xn = x1; | |
| } | |
| stable = true; | |
| unit->a = a; | |
| unit->b = b; | |
| unit->x0 = x0; | |
| unit->x1 = x1; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.0; | |
| if (stable) { | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| xn = 1.f - (a * xnm1 * xnm1) + (b * xnm2); | |
| if ((xn > 1.5) || (xn < -1.5)) { | |
| stable = false; | |
| xn = 1.; | |
| xnm1 = xnm2 = xnm3 = 0.; | |
| } | |
| ipol3Coef(xnm3, xnm2, xnm1, xn, c0, c1, c2, c3); | |
| } | |
| // Print("slope %g, x2 %g\n", slope, x2); | |
| } | |
| counter++; | |
| ZXP(out) = ipol3(frac, c0, c1, c2, c3); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->xnm3 = xnm3; | |
| unit->counter = counter; | |
| unit->stable = stable; | |
| unit->frac = frac; | |
| unit->c0 = c0; | |
| unit->c1 = c1; | |
| unit->c2 = c2; | |
| unit->c3 = c3; | |
| } | |
| void HenonC_Ctor(HenonC* unit) { | |
| SETCALC(HenonC_next); | |
| unit->x0 = ZIN0(3); | |
| unit->x1 = ZIN0(4); | |
| unit->xn = unit->x1; | |
| unit->xnm1 = unit->x0; | |
| unit->xnm2 = unit->xnm3 = unit->x1; | |
| unit->a = ZIN0(1); | |
| unit->b = ZIN0(2); | |
| unit->counter = 0.f; | |
| unit->stable = true; | |
| unit->frac = 0.0; | |
| unit->c0 = unit->c1 = unit->c2 = unit->c3 = 0.; | |
| HenonC_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LatoocarfianN_next(LatoocarfianN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double d = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| const double xnm1 = xn; | |
| xn = sin(yn * b) + c * sin(xnm1 * b); | |
| yn = sin(xnm1 * a) + d * sin(yn * a); | |
| } | |
| counter++; | |
| ZXP(out) = xn; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| } | |
| void LatoocarfianN_Ctor(LatoocarfianN* unit) { | |
| SETCALC(LatoocarfianN_next); | |
| unit->x0 = ZIN0(5); | |
| unit->y0 = ZIN0(6); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->counter = 0.f; | |
| LatoocarfianN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LatoocarfianL_next(LatoocarfianL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double d = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| double xnm1 = unit->xnm1; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| double dx = xn - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| xnm1 = xn; | |
| xn = sin(yn * b) + c * sin(xnm1 * b); | |
| yn = sin(xnm1 * a) + d * sin(yn * a); | |
| dx = xn - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = xnm1 + dx * frac; | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| unit->xnm1 = xnm1; | |
| unit->frac = frac; | |
| } | |
| void LatoocarfianL_Ctor(LatoocarfianL* unit) { | |
| SETCALC(LatoocarfianL_next); | |
| unit->x0 = ZIN0(5); | |
| unit->y0 = ZIN0(6); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->xnm1 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.f; | |
| LatoocarfianL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LatoocarfianC_next(LatoocarfianC* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double d = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| double xnm3 = unit->xnm3; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| double frac = unit->frac; | |
| double c0 = unit->c0; | |
| double c1 = unit->c1; | |
| double c2 = unit->c2; | |
| double c3 = unit->c3; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else | |
| samplesPerCycle = slope = 1.f; | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.0; | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| xn = sin(yn * b) + c * sin(xnm1 * b); | |
| yn = sin(xnm1 * a) + d * sin(yn * a); | |
| ipol3Coef(xnm3, xnm2, xnm1, xn, c0, c1, c2, c3); | |
| } | |
| counter++; | |
| ZXP(out) = ipol3(frac, c0, c1, c2, c3); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->xnm3 = xnm3; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| unit->frac = frac; | |
| unit->c0 = c0; | |
| unit->c1 = c1; | |
| unit->c2 = c2; | |
| unit->c3 = c3; | |
| } | |
| void LatoocarfianC_Ctor(LatoocarfianC* unit) { | |
| SETCALC(LatoocarfianC_next); | |
| unit->x0 = ZIN0(5); | |
| unit->y0 = ZIN0(6); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->xnm1 = unit->xnm2 = unit->xnm3 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.0; | |
| unit->c0 = unit->c1 = unit->c2 = unit->c3 = unit->x0; | |
| LatoocarfianC_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LinCongN_next(LinCongN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); // multiplier | |
| double c = ZIN0(2); // increment | |
| double m = sc_max(ZIN0(3), 0.001f); // modulus | |
| double xn = unit->xn; | |
| float counter = unit->counter; | |
| double scaleFactor = 2.f / m; | |
| double xscaled = (xn * scaleFactor) - 1.f; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| xn = (xn * a) + c; | |
| xn = sc_mod(xn, m); | |
| xscaled = (xn * scaleFactor) - 1.f; | |
| } | |
| counter++; | |
| ZXP(out) = xscaled; | |
| } | |
| unit->xn = xn; | |
| unit->counter = counter; | |
| } | |
| void LinCongN_Ctor(LinCongN* unit) { | |
| SETCALC(LinCongN_next); | |
| unit->xn = ZIN0(4); // initial x | |
| unit->counter = 0.f; | |
| LinCongN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LinCongL_next(LinCongL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); // multiplier | |
| double c = ZIN0(2); // increment | |
| double m = sc_max(ZIN0(3), 0.001f); // modulus | |
| double xn = unit->xn; | |
| float counter = unit->counter; | |
| double xnm1 = unit->xnm1; | |
| double frac = unit->frac; | |
| double scaleFactor = 2.f / m; | |
| double xscaled = (xn * scaleFactor) - 1.f; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| double diff = xscaled - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| xnm1 = xscaled; | |
| xn = (xn * a) + c; | |
| xn = sc_mod(xn, m); | |
| xscaled = (xn * scaleFactor) - 1.f; | |
| diff = xscaled - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = xnm1 + (frac * diff); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->counter = counter; | |
| unit->xnm1 = xnm1; | |
| unit->frac = frac; | |
| } | |
| void LinCongL_Ctor(LinCongL* unit) { | |
| SETCALC(LinCongL_next); | |
| unit->xn = ZIN0(4); | |
| unit->counter = 0.f; | |
| unit->xnm1 = unit->xn; | |
| unit->frac = 0.f; | |
| LinCongL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LinCongC_next(LinCongC* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); // multiplier | |
| double c = ZIN0(2); // increment | |
| double m = sc_max(ZIN0(3), 0.001f); // modulus | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| double xnm3 = unit->xnm3; | |
| float counter = unit->counter; | |
| double frac = unit->frac; | |
| double c0 = unit->c0; | |
| double c1 = unit->c1; | |
| double c2 = unit->c2; | |
| double c3 = unit->c3; | |
| double scaleFactor = 2.f / m; | |
| double xscaled = (xn * scaleFactor) - 1.f; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else | |
| samplesPerCycle = slope = 1.f; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.0; | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xscaled; | |
| xn = (xn * a) + c; | |
| xn = sc_mod(xn, m); | |
| xscaled = (xn * scaleFactor) - 1.f; | |
| ipol3Coef(xnm3, xnm2, xnm1, xscaled, c0, c1, c2, c3); | |
| } | |
| counter++; | |
| ZXP(out) = ipol3(frac, c0, c1, c2, c3); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->xnm3 = xnm3; | |
| unit->counter = counter; | |
| unit->frac = frac; | |
| unit->c0 = c0; | |
| unit->c1 = c1; | |
| unit->c2 = c2; | |
| unit->c3 = c3; | |
| } | |
| void LinCongC_Ctor(LinCongC* unit) { | |
| SETCALC(LinCongC_next); | |
| unit->x0 = ZIN0(4); | |
| unit->xn = unit->x0; | |
| unit->xnm1 = unit->xnm2 = unit->xnm3 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.0; | |
| unit->c0 = unit->c1 = unit->c2 = unit->c3 = unit->x0; | |
| LinCongC_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void LorenzL_next(LorenzL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double s = ZIN0(1); | |
| double r = ZIN0(2); | |
| double b = ZIN0(3); | |
| double h = ZIN0(4); | |
| double x0 = ZIN0(5); | |
| double y0 = ZIN0(6); | |
| double z0 = ZIN0(7); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| double zn = unit->zn; | |
| float counter = unit->counter; | |
| double xnm1 = unit->xnm1; | |
| double ynm1 = unit->ynm1; | |
| double znm1 = unit->znm1; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| if ((unit->x0 != x0) || (unit->y0 != y0) || (unit->z0 != z0)) { | |
| xnm1 = xn; | |
| ynm1 = yn; | |
| znm1 = zn; | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| unit->z0 = zn = z0; | |
| } | |
| double dx = xn - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| xnm1 = xn; | |
| ynm1 = yn; | |
| znm1 = zn; | |
| double k1x, k2x, k3x, k4x, k1y, k2y, k3y, k4y, k1z, k2z, k3z, k4z, kxHalf, kyHalf, kzHalf; | |
| double hTimesS = h * s; | |
| // 4th order Runge-Kutta | |
| k1x = hTimesS * (ynm1 - xnm1); | |
| k1y = h * (xnm1 * (r - znm1) - ynm1); | |
| k1z = h * (xnm1 * ynm1 - b * znm1); | |
| kxHalf = k1x * 0.5; | |
| kyHalf = k1y * 0.5; | |
| kzHalf = k1z * 0.5; | |
| k2x = hTimesS * (ynm1 + kyHalf - xnm1 - kxHalf); | |
| k2y = h * ((xnm1 + kxHalf) * (r - znm1 - kzHalf) - (ynm1 + kyHalf)); | |
| k2z = h * ((xnm1 + kxHalf) * (ynm1 + kyHalf) - b * (znm1 + kzHalf)); | |
| kxHalf = k2x * 0.5; | |
| kyHalf = k2y * 0.5; | |
| kzHalf = k2z * 0.5; | |
| k3x = hTimesS * (ynm1 + kyHalf - xnm1 - kxHalf); | |
| k3y = h * ((xnm1 + kxHalf) * (r - znm1 - kzHalf) - (ynm1 + kyHalf)); | |
| k3z = h * ((xnm1 + kxHalf) * (ynm1 + kyHalf) - b * (znm1 + kzHalf)); | |
| k4x = hTimesS * (ynm1 + k3y - xnm1 - k3x); | |
| k4y = h * ((xnm1 + k3x) * (r - znm1 - k3z) - (ynm1 + k3y)); | |
| k4z = h * ((xnm1 + k3x) * (ynm1 + k3y) - b * (znm1 + k3z)); | |
| xn = xn + (k1x + 2.0 * (k2x + k3x) + k4x) * ONESIXTH; | |
| yn = yn + (k1y + 2.0 * (k2y + k3y) + k4y) * ONESIXTH; | |
| zn = zn + (k1z + 2.0 * (k2z + k3z) + k4z) * ONESIXTH; | |
| // Euler's method | |
| // xn = xnm1 + h * (s * (ynm1 - xnm1)); | |
| // yn = ynm1 + h * (xnm1 * (r - znm1) - ynm1); | |
| // zn = znm1 + h * (xnm1 * ynm1 - b * znm1); | |
| dx = xn - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = (xnm1 + dx * frac) * 0.04f; | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->zn = zn; | |
| unit->counter = counter; | |
| unit->xnm1 = xnm1; | |
| unit->ynm1 = ynm1; | |
| unit->znm1 = znm1; | |
| unit->frac = frac; | |
| } | |
| void LorenzL_Ctor(LorenzL* unit) { | |
| SETCALC(LorenzL_next); | |
| unit->x0 = unit->xn = unit->xnm1 = ZIN0(5); | |
| unit->y0 = unit->yn = unit->ynm1 = ZIN0(6); | |
| unit->z0 = unit->zn = unit->znm1 = ZIN0(7); | |
| unit->counter = 0.f; | |
| unit->frac = 0.f; | |
| LorenzL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void QuadN_next(QuadN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double x0 = ZIN0(4); | |
| double xn = unit->xn; | |
| float counter = unit->counter; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| if (unit->x0 != x0) { | |
| unit->x0 = xn = x0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| xn = a * xn * xn + b * xn + c; | |
| } | |
| counter++; | |
| ZXP(out) = xn; | |
| } | |
| unit->xn = xn; | |
| unit->counter = counter; | |
| } | |
| void QuadN_Ctor(QuadN* unit) { | |
| SETCALC(QuadN_next); | |
| unit->x0 = ZIN0(4); | |
| unit->xn = unit->x0; | |
| unit->counter = 0.f; | |
| QuadN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void QuadL_next(QuadL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double x0 = ZIN0(4); | |
| double xn = unit->xn; | |
| float counter = unit->counter; | |
| double xnm1 = unit->xnm1; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| if (unit->x0 != x0) { | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| } | |
| double dx = xn - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| xnm1 = xn; | |
| xn = a * xn * xn + b * xn + c; | |
| dx = xn - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = xnm1 + dx * frac; | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->counter = counter; | |
| unit->xnm1 = xnm1; | |
| unit->frac = frac; | |
| } | |
| void QuadL_Ctor(QuadL* unit) { | |
| SETCALC(QuadL_next); | |
| unit->x0 = ZIN0(4); | |
| unit->xn = unit->x0; | |
| unit->xnm1 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.f; | |
| QuadL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void QuadC_next(QuadC* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double a = ZIN0(1); | |
| double b = ZIN0(2); | |
| double c = ZIN0(3); | |
| double x0 = ZIN0(4); | |
| double xn = unit->xn; | |
| double xnm1 = unit->xnm1; | |
| double xnm2 = unit->xnm2; | |
| double xnm3 = unit->xnm3; | |
| float counter = unit->counter; | |
| double frac = unit->frac; | |
| double c0 = unit->c0; | |
| double c1 = unit->c1; | |
| double c2 = unit->c2; | |
| double c3 = unit->c3; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else | |
| samplesPerCycle = slope = 1.f; | |
| if (unit->x0 != x0) { | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.0; | |
| xnm3 = xnm2; | |
| xnm2 = xnm1; | |
| xnm1 = xn; | |
| xn = a * xn * xn + b * xn + c; | |
| ipol3Coef(xnm3, xnm2, xnm1, xn, c0, c1, c2, c3); | |
| } | |
| counter++; | |
| ZXP(out) = ipol3(frac, c0, c1, c2, c3); | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->xnm1 = xnm1; | |
| unit->xnm2 = xnm2; | |
| unit->xnm3 = xnm3; | |
| unit->counter = counter; | |
| unit->frac = frac; | |
| unit->c0 = c0; | |
| unit->c1 = c1; | |
| unit->c2 = c2; | |
| unit->c3 = c3; | |
| } | |
| void QuadC_Ctor(QuadC* unit) { | |
| SETCALC(QuadC_next); | |
| unit->x0 = ZIN0(4); | |
| unit->xn = unit->x0; | |
| unit->xnm1 = unit->xnm2 = unit->xnm3 = unit->x0; | |
| unit->c0 = unit->c1 = unit->c2 = unit->c3 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.0; | |
| QuadC_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void StandardN_next(StandardN* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double k = ZIN0(1); | |
| double x0 = ZIN0(2); | |
| double y0 = ZIN0(3); | |
| double xn = unit->xn; | |
| double output = (xn - PI) * RECPI; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| float samplesPerCycle; | |
| if (freq < unit->mRate->mSampleRate) | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| else | |
| samplesPerCycle = 1.f; | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| yn = yn + k * sin(xn); | |
| yn = mod2pi(yn); | |
| xn = xn + yn; | |
| xn = mod2pi(xn); | |
| output = (xn - PI) * RECPI; | |
| } | |
| counter++; | |
| ZXP(out) = output; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| } | |
| void StandardN_Ctor(StandardN* unit) { | |
| SETCALC(StandardN_next); | |
| unit->x0 = ZIN0(2); | |
| unit->y0 = ZIN0(3); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->counter = 0.f; | |
| StandardN_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| void StandardL_next(StandardL* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| double k = ZIN0(1); | |
| double x0 = ZIN0(2); | |
| double y0 = ZIN0(3); | |
| double xn = unit->xn; | |
| double yn = unit->yn; | |
| float counter = unit->counter; | |
| double xnm1 = unit->xnm1; | |
| double frac = unit->frac; | |
| float samplesPerCycle; | |
| double slope; | |
| if (freq < unit->mRate->mSampleRate) { | |
| samplesPerCycle = unit->mRate->mSampleRate / sc_max(freq, 0.001f); | |
| slope = 1.f / samplesPerCycle; | |
| } else { | |
| samplesPerCycle = 1.f; | |
| slope = 1.f; | |
| } | |
| if ((unit->x0 != x0) || (unit->y0 != y0)) { | |
| xnm1 = xn; | |
| unit->x0 = xn = x0; | |
| unit->y0 = yn = y0; | |
| } | |
| double dx = xn - xnm1; | |
| for (int i = 0; i < inNumSamples; ++i) { | |
| if (counter >= samplesPerCycle) { | |
| counter -= samplesPerCycle; | |
| frac = 0.f; | |
| xnm1 = xn; | |
| yn = yn + k * sin(xn); | |
| yn = mod2pi(yn); | |
| xn = xn + yn; | |
| xn = mod2pi(xn); | |
| dx = xn - xnm1; | |
| } | |
| counter++; | |
| ZXP(out) = (xnm1 + dx * frac - PI) * RECPI; | |
| frac += slope; | |
| } | |
| unit->xn = xn; | |
| unit->yn = yn; | |
| unit->counter = counter; | |
| unit->xnm1 = xnm1; | |
| unit->frac = frac; | |
| } | |
| void StandardL_Ctor(StandardL* unit) { | |
| SETCALC(StandardL_next); | |
| unit->x0 = ZIN0(2); | |
| unit->y0 = ZIN0(3); | |
| unit->xn = unit->x0; | |
| unit->yn = unit->y0; | |
| unit->xnm1 = unit->x0; | |
| unit->counter = 0.f; | |
| unit->frac = 0.f; | |
| StandardL_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////// | |
| PluginLoad(Chaos) { | |
| ft = inTable; | |
| DefineSimpleUnit(CuspN); | |
| DefineSimpleUnit(CuspL); | |
| DefineSimpleUnit(FBSineN); | |
| DefineSimpleUnit(FBSineL); | |
| DefineSimpleUnit(FBSineC); | |
| DefineSimpleUnit(GbmanN); | |
| DefineSimpleUnit(GbmanL); | |
| DefineSimpleUnit(HenonN); | |
| DefineSimpleUnit(HenonL); | |
| DefineSimpleUnit(HenonC); | |
| DefineSimpleUnit(LatoocarfianN); | |
| DefineSimpleUnit(LatoocarfianL); | |
| DefineSimpleUnit(LatoocarfianC); | |
| DefineSimpleUnit(LinCongN); | |
| DefineSimpleUnit(LinCongL); | |
| DefineSimpleUnit(LinCongC); | |
| DefineSimpleUnit(LorenzL); | |
| DefineSimpleUnit(QuadN); | |
| DefineSimpleUnit(QuadL); | |
| DefineSimpleUnit(QuadC); | |
| DefineSimpleUnit(StandardN); | |
| DefineSimpleUnit(StandardL); | |
| } |