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 | |
| */ | |
| #include "SC_PlugIn.h" | |
| static InterfaceTable* ft; | |
| struct WhiteNoise : public Unit {}; | |
| struct ClipNoise : public Unit {}; | |
| struct BrownNoise : public Unit { | |
| float mLevel; | |
| }; | |
| struct PinkNoise : public Unit { | |
| uint32 mDice[16]; | |
| int32 mTotal; | |
| }; | |
| struct Dust : public Unit { | |
| float m_density, m_thresh, m_scale; | |
| }; | |
| struct Dust2 : public Unit { | |
| float m_density, m_thresh, m_scale; | |
| }; | |
| struct GrayNoise : public Unit { | |
| int32 mCounter; | |
| }; | |
| struct Crackle : public Unit { | |
| double m_y1, m_y2; | |
| }; | |
| struct Logistic : public Unit { | |
| double m_y1; | |
| int mCounter; | |
| }; | |
| struct Hasher : public Unit {}; | |
| struct MantissaMask : public Unit {}; | |
| struct IRand : public Unit {}; | |
| struct Rand : public Unit {}; | |
| struct TRand : public Unit { | |
| float m_trig, m_value; | |
| }; | |
| struct TIRand : public Unit { | |
| float m_trig, m_value; | |
| }; | |
| struct TExpRand : public Unit { | |
| float m_trig, m_value; | |
| }; | |
| struct NRand : public Unit {}; | |
| struct LinRand : public Unit {}; | |
| struct ExpRand : public Unit {}; | |
| struct CoinGate : public Unit { | |
| float m_trig; | |
| }; | |
| struct LFClipNoise : public Unit { | |
| float mLevel; | |
| int mCounter; | |
| }; | |
| struct LFNoise0 : public Unit { | |
| float mLevel; | |
| int mCounter; | |
| }; | |
| struct LFNoise1 : public Unit { | |
| float mLevel, mSlope; | |
| int mCounter; | |
| }; | |
| struct LFNoise2 : public Unit { | |
| float mLevel, mSlope, mCurve; | |
| float m_nextvalue, m_nextmidpt; | |
| int mCounter; | |
| }; | |
| struct RandSeed : public Unit { | |
| float m_trig; | |
| }; | |
| struct RandID : public Unit { | |
| float m_id; | |
| }; | |
| ////////////////////////////////////////////////////////////////////////////////////////////////// | |
| extern "C" { | |
| void WhiteNoise_next(WhiteNoise* unit, int inNumSamples); | |
| void WhiteNoise_Ctor(WhiteNoise* unit); | |
| void GrayNoise_next(GrayNoise* unit, int inNumSamples); | |
| void GrayNoise_Ctor(GrayNoise* unit); | |
| void ClipNoise_next(ClipNoise* unit, int inNumSamples); | |
| void ClipNoise_Ctor(ClipNoise* unit); | |
| void PinkNoise_next(PinkNoise* unit, int inNumSamples); | |
| void PinkNoise_Ctor(PinkNoise* unit); | |
| void BrownNoise_next(BrownNoise* unit, int inNumSamples); | |
| void BrownNoise_Ctor(BrownNoise* unit); | |
| void Dust_next(Dust* unit, int inNumSamples); | |
| void Dust_Ctor(Dust* unit); | |
| void Dust2_next(Dust2* unit, int inNumSamples); | |
| void Dust2_Ctor(Dust2* unit); | |
| void Crackle_next(Crackle* unit, int inNumSamples); | |
| void Crackle_Ctor(Crackle* unit); | |
| void Hasher_next(Hasher* unit, int inNumSamples); | |
| void Hasher_Ctor(Hasher* unit); | |
| void MantissaMask_next(MantissaMask* unit, int inNumSamples); | |
| void MantissaMask_Ctor(MantissaMask* unit); | |
| void IRand_Ctor(IRand* unit); | |
| void Rand_Ctor(Rand* unit); | |
| void LinRand_Ctor(LinRand* unit); | |
| void NRand_Ctor(NRand* unit); | |
| void ExpRand_Ctor(ExpRand* unit); | |
| void CoinGate_Ctor(CoinGate* unit); | |
| void CoinGate_next_k(CoinGate* unit, int inNumSamples); | |
| void CoinGate_next(CoinGate* unit, int inNumSamples); | |
| void TIRand_next_a(TIRand* unit, int inNumSamples); | |
| void TIRand_next_k(TIRand* unit, int inNumSamples); | |
| void TIRand_Ctor(TIRand* unit); | |
| void TRand_next_a(TRand* unit, int inNumSamples); | |
| void TRand_next_k(TRand* unit, int inNumSamples); | |
| void TRand_Ctor(TRand* unit); | |
| void TExpRand_next_a(TExpRand* unit, int inNumSamples); | |
| void TExpRand_next_k(TExpRand* unit, int inNumSamples); | |
| void TExpRand_Ctor(TExpRand* unit); | |
| void Logistic_next_1(Logistic* unit, int inNumSamples); | |
| void Logistic_next_k(Logistic* unit, int inNumSamples); | |
| void Logistic_Ctor(Logistic* unit); | |
| void LFClipNoise_next(LFClipNoise* unit, int inNumSamples); | |
| void LFClipNoise_Ctor(LFClipNoise* unit); | |
| void LFNoise0_next(LFNoise0* unit, int inNumSamples); | |
| void LFNoise0_Ctor(LFNoise0* unit); | |
| void LFNoise1_next(LFNoise1* unit, int inNumSamples); | |
| void LFNoise1_Ctor(LFNoise1* unit); | |
| void LFNoise2_next(LFNoise2* unit, int inNumSamples); | |
| void LFNoise2_Ctor(LFNoise2* unit); | |
| void RandSeed_next(RandSeed* unit, int inNumSamples); | |
| void RandSeed_next_k(RandSeed* unit, int inNumSamples); | |
| void RandSeed_Ctor(RandSeed* unit); | |
| void RandID_next(RandID* unit, int inNumSamples); | |
| void RandID_Ctor(RandID* unit); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void ClipNoise_next(ClipNoise* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| RGET LOOP1(inNumSamples, ZXP(out) = fcoin(s1, s2, s3);); | |
| RPUT | |
| } | |
| void ClipNoise_Ctor(ClipNoise* unit) { | |
| SETCALC(ClipNoise_next); | |
| ClipNoise_next(unit, 1); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void GrayNoise_next(GrayNoise* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| RGET int counter = unit->mCounter; | |
| LOOP1(inNumSamples, counter ^= 1L << (trand(s1, s2, s3) & 31); ZXP(out) = counter * 4.65661287308e-10f;); | |
| unit->mCounter = counter; | |
| RPUT | |
| } | |
| void GrayNoise_Ctor(GrayNoise* unit) { | |
| SETCALC(GrayNoise_next); | |
| unit->mCounter = 0; | |
| GrayNoise_next(unit, 1); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void WhiteNoise_next(WhiteNoise* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| RGET LOOP1(inNumSamples, ZXP(out) = frand2(s1, s2, s3);); | |
| RPUT | |
| } | |
| void WhiteNoise_Ctor(WhiteNoise* unit) { | |
| SETCALC(WhiteNoise_next); | |
| WhiteNoise_next(unit, 1); | |
| } | |
| ////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void PinkNoise_next(PinkNoise* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| RGET | |
| uint32 total = unit->mTotal; | |
| uint32* dice = unit->mDice; | |
| LOOP1(inNumSamples, uint32 counter = trand(s1, s2, s3); // Magnus Jonsson's suggestion. | |
| uint32 newrand = counter >> 13; int k = (CTZ(counter)) & 15; uint32 prevrand = dice[k]; dice[k] = newrand; | |
| total += (newrand - prevrand); newrand = trand(s1, s2, s3) >> 13; elem32 val; // ensure write before read <sk> | |
| val.u = (total + newrand) | 0x40000000; ZXP(out) = val.f - 3.0f; counter++;); | |
| unit->mTotal = total; | |
| RPUT | |
| } | |
| void PinkNoise_Ctor(PinkNoise* unit) { | |
| SETCALC(PinkNoise_next); | |
| RGET uint32* dice = unit->mDice; | |
| int32 total = 0; | |
| for (int i = 0; i < 16; ++i) { | |
| uint32 newrand = trand(s1, s2, s3) >> 13; | |
| total += newrand; | |
| dice[i] = newrand; | |
| } | |
| unit->mTotal = total; | |
| RPUT | |
| PinkNoise_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void BrownNoise_next(BrownNoise* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| RGET | |
| float z = unit->mLevel; | |
| LOOP1(inNumSamples, z += frand8(s1, s2, s3); if (z > 1.f) z = 2.f - z; else if (z < -1.f) z = -2.f - z; | |
| ZXP(out) = z;); | |
| unit->mLevel = z; | |
| RPUT | |
| } | |
| void BrownNoise_Ctor(BrownNoise* unit) { | |
| SETCALC(BrownNoise_next); | |
| unit->mLevel = unit->mParent->mRGen->frand2(); | |
| ZOUT0(0) = unit->mLevel; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void Dust_Ctor(Dust* unit) { | |
| SETCALC(Dust_next); | |
| unit->m_density = 0.f; | |
| unit->m_scale = 0.f; | |
| unit->m_thresh = 0.f; | |
| Dust_next(unit, 1); | |
| } | |
| void Dust_next(Dust* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float density = ZIN0(0); | |
| float thresh, scale; | |
| RGET | |
| if (density != unit->m_density) { | |
| thresh = unit->m_thresh = density * unit->mRate->mSampleDur; | |
| scale = unit->m_scale = thresh > 0.f ? 1.f / thresh : 0.f; | |
| unit->m_density = density; | |
| } | |
| else { | |
| thresh = unit->m_thresh; | |
| scale = unit->m_scale; | |
| } | |
| LOOP1(inNumSamples, float z = frand(s1, s2, s3); if (z < thresh) ZXP(out) = z * scale; else ZXP(out) = 0.f;); | |
| RPUT | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void Dust2_Ctor(Dust2* unit) { | |
| SETCALC(Dust2_next); | |
| unit->m_density = 0.f; | |
| unit->m_scale = 0.f; | |
| unit->m_thresh = 0.f; | |
| Dust2_next(unit, 1); | |
| } | |
| void Dust2_next(Dust2* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float density = ZIN0(0); | |
| float thresh, scale; | |
| RGET | |
| if (density != unit->m_density) { | |
| thresh = unit->m_thresh = density * unit->mRate->mSampleDur; | |
| scale = unit->m_scale = thresh > 0.f ? 2.f / thresh : 0.f; | |
| unit->m_density = density; | |
| } | |
| else { | |
| thresh = unit->m_thresh; | |
| scale = unit->m_scale; | |
| } | |
| LOOP1(inNumSamples, float z = frand(s1, s2, s3); if (z < thresh) ZXP(out) = z * scale - 1.f; else ZXP(out) = 0.f;); | |
| RPUT | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void Crackle_next(Crackle* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float paramf = ZIN0(0); | |
| float y1 = unit->m_y1; | |
| float y2 = unit->m_y2; | |
| float y0; | |
| LOOP1(inNumSamples, ZXP(out) = y0 = fabs(y1 * paramf - y2 - 0.05f); y2 = y1; y1 = y0;); | |
| unit->m_y1 = y1; | |
| unit->m_y2 = y2; | |
| } | |
| void Crackle_Ctor(Crackle* unit) { | |
| SETCALC(Crackle_next); | |
| unit->m_y1 = unit->mParent->mRGen->drand(); | |
| unit->m_y2 = 0.f; | |
| Crackle_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void Logistic_next_1(Logistic* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| double paramf = ZIN0(0); | |
| double y1 = unit->m_y1; | |
| LOOP1(inNumSamples, | |
| ZXP(out) = y1 = paramf * y1 * (1.0 - y1); // chaotic equation | |
| ); | |
| unit->m_y1 = y1; | |
| } | |
| void Logistic_next_k(Logistic* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| double paramf = ZIN0(0); | |
| float freq = ZIN0(1); | |
| double y1 = unit->m_y1; | |
| int32 counter = unit->mCounter; | |
| long remain = inNumSamples; | |
| do { | |
| if (counter <= 0) { | |
| counter = (int32)(unit->mRate->mSampleRate / sc_max(freq, .001f)); | |
| counter = sc_max(1, counter); | |
| y1 = paramf * y1 * (1.0 - y1); // chaotic equation | |
| } | |
| long nsmps = sc_min(counter, remain); | |
| counter -= nsmps; | |
| remain -= nsmps; | |
| LOOP(nsmps, ZXP(out) = y1;); | |
| } while (remain); | |
| unit->m_y1 = y1; | |
| unit->mCounter = counter; | |
| } | |
| void Logistic_Ctor(Logistic* unit) { | |
| if (INRATE(0) == calc_ScalarRate && ZIN0(1) >= unit->mRate->mSampleRate) | |
| SETCALC(Logistic_next_1); | |
| else | |
| SETCALC(Logistic_next_k); | |
| unit->m_y1 = ZIN0(2); | |
| unit->mCounter = 0; | |
| Logistic_next_1(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void Rand_Ctor(Rand* unit) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float range = hi - lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = rgen.frand() * range + lo; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void TRand_next_k(TRand* unit, int inNumSamples) { | |
| float trig = ZIN0(2); | |
| if (trig > 0.f && unit->m_trig <= 0.f) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float range = hi - lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = unit->m_value = rgen.frand() * range + lo; | |
| } else { | |
| ZOUT0(0) = unit->m_value; | |
| } | |
| unit->m_trig = trig; | |
| } | |
| void TRand_next_a(TRand* unit, int inNumSamples) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float* trig = ZIN(2); | |
| float prev = unit->m_trig; | |
| float* out = ZOUT(0); | |
| float outval = unit->m_value; | |
| float next; | |
| LOOP1( | |
| inNumSamples, next = ZXP(trig); if (next > 0.f && prev <= 0.f) { | |
| float range = hi - lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZXP(out) = outval = rgen.frand() * range + lo; | |
| } else { ZXP(out) = outval; }; | |
| prev = next;) | |
| unit->m_trig = next; | |
| unit->m_value = outval; | |
| } | |
| void TRand_next_aa(TRand* unit, int inNumSamples) { | |
| float* lo = ZIN(0); | |
| float* hi = ZIN(1); | |
| float* trig = ZIN(2); | |
| float prev = unit->m_trig; | |
| float* out = ZOUT(0); | |
| float outval = unit->m_value; | |
| float next; | |
| LOOP1( | |
| inNumSamples, next = ZXP(trig); if (next > 0.f && prev <= 0.f) { | |
| float loval = ZXP(lo); | |
| float range = ZXP(hi) - loval; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZXP(out) = outval = rgen.frand() * range + loval; | |
| } else { ZXP(out) = outval; }; | |
| prev = next;) | |
| unit->m_trig = next; | |
| unit->m_value = outval; | |
| } | |
| void TRand_Ctor(TRand* unit) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float range = hi - lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = unit->m_value = rgen.frand() * range + lo; | |
| if (unit->mCalcRate == calc_FullRate) { | |
| if (INRATE(0) == calc_FullRate) { | |
| SETCALC(TRand_next_aa); | |
| } else { | |
| SETCALC(TRand_next_a); | |
| } | |
| } else { | |
| SETCALC(TRand_next_k); | |
| } | |
| unit->m_trig = ZIN0(2); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void TExpRand_next_k(TExpRand* unit, int inNumSamples) { | |
| float trig = ZIN0(2); | |
| if (trig > 0.f && unit->m_trig <= 0.f) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float ratio = hi / lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = unit->m_value = pow(ratio, rgen.frand()) * lo; | |
| } else { | |
| ZOUT0(0) = unit->m_value; | |
| } | |
| unit->m_trig = trig; | |
| } | |
| void TExpRand_next_a(TExpRand* unit, int inNumSamples) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float* trig = ZIN(2); | |
| float prev = unit->m_trig; | |
| float* out = ZOUT(0); | |
| float outval = unit->m_value; | |
| float next; | |
| LOOP1( | |
| inNumSamples, next = ZXP(trig); if (next > 0.f && prev <= 0.f) { | |
| float ratio = hi / lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZXP(out) = outval = pow(ratio, rgen.frand()) * lo; | |
| } else { ZXP(out) = outval; }) | |
| unit->m_trig = next; | |
| unit->m_value = outval; | |
| } | |
| void TExpRand_next_aa(TExpRand* unit, int inNumSamples) { | |
| float* lo = ZIN(0); | |
| float* hi = ZIN(1); | |
| float* trig = ZIN(2); | |
| float prev = unit->m_trig; | |
| float* out = ZOUT(0); | |
| float outval = unit->m_value; | |
| float next; | |
| LOOP1( | |
| inNumSamples, next = ZXP(trig); if (next > 0.f && prev <= 0.f) { | |
| float loval = ZXP(lo); | |
| float ratio = ZXP(hi) / loval; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZXP(out) = outval = pow(ratio, rgen.frand()) * loval; | |
| } else { ZXP(out) = outval; }) | |
| unit->m_trig = next; | |
| unit->m_value = outval; | |
| } | |
| void TExpRand_Ctor(TExpRand* unit) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float ratio = hi / lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = unit->m_value = pow(ratio, rgen.frand()) * lo; | |
| if (unit->mCalcRate == calc_FullRate) { | |
| if (INRATE(0) == calc_FullRate) { | |
| SETCALC(TExpRand_next_aa); | |
| } else { | |
| SETCALC(TExpRand_next_a); | |
| } | |
| } else { | |
| SETCALC(TExpRand_next_k); | |
| } | |
| unit->m_trig = ZIN0(2); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void IRand_Ctor(IRand* unit) { | |
| int lo = (int)ZIN0(0); | |
| int hi = (int)ZIN0(1); | |
| int range = hi - lo + 1; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = (float)(rgen.irand(range) + lo); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void TIRand_next_k(TIRand* unit, int inNumSamples) { | |
| float trig = ZIN0(2); | |
| if (trig > 0.f && unit->m_trig <= 0.f) { | |
| int lo = (int)ZIN0(0); | |
| int hi = (int)ZIN0(1); | |
| int range = hi - lo + 1; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = unit->m_value = (float)(rgen.irand(range) + lo); | |
| } else { | |
| ZOUT0(0) = unit->m_value; | |
| } | |
| unit->m_trig = trig; | |
| } | |
| void TIRand_next_a(TIRand* unit, int inNumSamples) { | |
| int lo = (int)ZIN0(0); | |
| int hi = (int)ZIN0(1); | |
| float* trig = ZIN(2); | |
| float prev = unit->m_trig; | |
| float* out = ZOUT(0); | |
| float outval = unit->m_value; | |
| float next; | |
| LOOP1( | |
| inNumSamples, next = ZXP(trig); if (next > 0.f && prev <= 0.f) { | |
| int range = hi - lo + 1; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZXP(out) = outval = (float)(rgen.irand(range) + lo); | |
| } else { ZXP(out) = outval; }) | |
| unit->m_trig = next; | |
| unit->m_value = outval; | |
| } | |
| void TIRand_next_aa(TIRand* unit, int inNumSamples) { | |
| float* lo = ZIN(0); | |
| float* hi = ZIN(1); | |
| float* trig = ZIN(2); | |
| float prev = unit->m_trig; | |
| float* out = ZOUT(0); | |
| float outval = unit->m_value; | |
| float next; | |
| LOOP1( | |
| inNumSamples, next = ZXP(trig); if (next > 0.f && prev <= 0.f) { | |
| int loval = (int)ZXP(lo); | |
| int range = (int)ZXP(hi) - loval + 1; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZXP(out) = outval = (float)(rgen.irand(range) + loval); | |
| } else { ZXP(out) = outval; }) | |
| unit->m_trig = next; | |
| unit->m_value = outval; | |
| } | |
| void TIRand_Ctor(TIRand* unit) { | |
| int lo = (int)ZIN0(0); | |
| int hi = (int)ZIN0(1); | |
| int range = hi - lo + 1; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| ZOUT0(0) = unit->m_value = (float)(rgen.irand(range) + lo); | |
| if (unit->mCalcRate == calc_FullRate) { | |
| if (INRATE(0) == calc_FullRate) { | |
| SETCALC(TIRand_next_aa); | |
| } else { | |
| SETCALC(TIRand_next_a); | |
| } | |
| } else { | |
| SETCALC(TIRand_next_k); | |
| } | |
| unit->m_trig = ZIN0(2); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void CoinGate_Ctor(CoinGate* unit) { | |
| if (unit->mCalcRate == calc_FullRate) { | |
| SETCALC(CoinGate_next); | |
| } else { | |
| SETCALC(CoinGate_next_k); | |
| } | |
| unit->m_trig = ZIN0(1); | |
| ClearUnitOutputs(unit, 1); | |
| } | |
| void CoinGate_next_k(CoinGate* unit, int inNumSamples) { | |
| float trig = ZIN0(1); | |
| float level = 0.f; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| if (trig > 0.f && unit->m_trig <= 0.f) { | |
| if (rgen.frand() < ZIN0(0)) { | |
| level = trig; | |
| } | |
| } | |
| ZOUT0(0) = level; | |
| unit->m_trig = trig; | |
| } | |
| void CoinGate_next(CoinGate* unit, int inNumSamples) { | |
| float* trig = ZIN(1); | |
| float* out = ZOUT(0); | |
| float prevtrig = unit->m_trig; | |
| float probability = ZIN0(0); | |
| RGen& rgen = *unit->mParent->mRGen; | |
| LOOP1( | |
| inNumSamples, float curtrig = ZXP(trig); float level = 0.f; if (prevtrig <= 0.f && curtrig > 0.f) { | |
| if (rgen.frand() < probability) { | |
| level = curtrig; | |
| } else { | |
| level = 0.f; | |
| } | |
| } prevtrig = curtrig; | |
| ZXP(out) = level;) | |
| unit->m_trig = prevtrig; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void RandSeed_Ctor(RandSeed* unit) { | |
| unit->m_trig = 0.; | |
| if (unit->mCalcRate == calc_FullRate) { | |
| SETCALC(RandSeed_next); | |
| } else { | |
| SETCALC(RandSeed_next_k); | |
| } | |
| RandSeed_next(unit, 1); | |
| } | |
| void RandSeed_next_k(RandSeed* unit, int inNumSamples) { | |
| float trig = ZIN0(0); | |
| if (trig > 0.f && unit->m_trig <= 0.f) { | |
| RGen& rgen = *unit->mParent->mRGen; | |
| int seed = (int)DEMANDINPUT_A(1, inNumSamples); | |
| rgen.init(seed); | |
| } | |
| unit->m_trig = trig; | |
| ZOUT0(0) = 0.f; | |
| } | |
| void RandSeed_next(RandSeed* unit, int inNumSamples) { | |
| float* trig = ZIN(0); | |
| float* out = ZOUT(0); | |
| float prevtrig = unit->m_trig; | |
| float curtrig; | |
| LOOP1( | |
| inNumSamples, | |
| curtrig = ZXP(trig); | |
| if (curtrig > 0.f && prevtrig <= 0.f) { | |
| RGen& rgen = *unit->mParent->mRGen; | |
| int seed = (int)DEMANDINPUT_A(1, inNumSamples); | |
| rgen.init(seed); | |
| } prevtrig = curtrig; | |
| ZXP(out) = 0.f; | |
| ) | |
| unit->m_trig = curtrig; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void RandID_Ctor(RandID* unit) { | |
| unit->m_id = -1.; | |
| SETCALC(RandID_next); | |
| RandID_next(unit, 1); | |
| } | |
| void RandID_next(RandID* unit, int inNumSamples) { | |
| float id = ZIN0(0); | |
| if (id != unit->m_id) { | |
| unit->m_id = id; | |
| uint32 iid = (uint32)id; | |
| if (iid < unit->mWorld->mNumRGens) { | |
| unit->mParent->mRGen = unit->mWorld->mRGen + iid; | |
| } | |
| } | |
| ZOUT0(0) = 0.f; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void LinRand_Ctor(LinRand* unit) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| int n = (int)ZIN0(2); | |
| float range = hi - lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| float a, b; | |
| a = rgen.frand(); | |
| b = rgen.frand(); | |
| if (n <= 0) { | |
| ZOUT0(0) = sc_min(a, b) * range + lo; | |
| } else { | |
| ZOUT0(0) = sc_max(a, b) * range + lo; | |
| } | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void NRand_Ctor(NRand* unit) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| int n = (int)ZIN0(2); | |
| float range = hi - lo; | |
| RGen& rgen = *unit->mParent->mRGen; | |
| float sum = 0; | |
| for (int i = 0; i < n; ++i) { | |
| sum += rgen.frand(); | |
| } | |
| ZOUT0(0) = (sum / n) * range + lo; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void ExpRand_Ctor(ExpRand* unit) { | |
| float lo = ZIN0(0); | |
| float hi = ZIN0(1); | |
| float ratio = hi / lo; | |
| ZOUT0(0) = pow(ratio, unit->mParent->mRGen->frand()) * lo; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void Hasher_next(Hasher* unit, int inNumSamples) { | |
| int32* in = (int32*)ZIN(0); | |
| float* out = ZOUT(0); | |
| LOOP1( | |
| inNumSamples, | |
| union { | |
| float f; | |
| int i; | |
| } u; | |
| int z = ZXP(in); u.i = 0x40000000 | ((uint32)Hash(z) >> 9); ZXP(out) = u.f - 3.f;); | |
| } | |
| void Hasher_Ctor(Hasher* unit) { | |
| SETCALC(Hasher_next); | |
| Hasher_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void MantissaMask_next(MantissaMask* unit, int inNumSamples) { | |
| int32* in = (int32*)ZIN(0); | |
| int32 bits = (int32)ZIN0(1); | |
| int32* out = (int32*)ZOUT(0); | |
| int32 mask = -1 << (23 - bits); | |
| LOOP1(inNumSamples, ZXP(out) = mask & ZXP(in);); | |
| } | |
| void MantissaMask_Ctor(MantissaMask* unit) { | |
| SETCALC(MantissaMask_next); | |
| MantissaMask_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void LFClipNoise_next(LFClipNoise* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| float level = unit->mLevel; | |
| int32 counter = unit->mCounter; | |
| RGET | |
| int remain = inNumSamples; | |
| do { | |
| if (counter <= 0) { | |
| counter = (int)(unit->mRate->mSampleRate / sc_max(freq, .001f)); | |
| counter = sc_max(1, counter); | |
| level = fcoin(s1, s2, s3); | |
| } | |
| int nsmps = sc_min(remain, counter); | |
| remain -= nsmps; | |
| counter -= nsmps; | |
| LOOP(nsmps, ZXP(out) = level;); | |
| } while (remain); | |
| unit->mLevel = level; | |
| unit->mCounter = counter; | |
| RPUT | |
| } | |
| void LFClipNoise_Ctor(LFClipNoise* unit) { | |
| SETCALC(LFClipNoise_next); | |
| unit->mCounter = 0; | |
| unit->mLevel = 0.f; | |
| LFClipNoise_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void LFNoise0_next(LFNoise0* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| float level = unit->mLevel; | |
| int32 counter = unit->mCounter; | |
| RGET | |
| int remain = inNumSamples; | |
| do { | |
| if (counter <= 0) { | |
| counter = (int32)(unit->mRate->mSampleRate / sc_max(freq, .001f)); | |
| counter = sc_max(1, counter); | |
| level = frand2(s1, s2, s3); | |
| } | |
| int nsmps = sc_min(remain, counter); | |
| remain -= nsmps; | |
| counter -= nsmps; | |
| LOOP(nsmps, ZXP(out) = level;); | |
| } while (remain); | |
| unit->mLevel = level; | |
| unit->mCounter = counter; | |
| RPUT | |
| } | |
| void LFNoise0_next_1(LFNoise0* unit, int inNumSamples) { | |
| assert(inNumSamples == 1); | |
| float freq = ZIN0(0); | |
| float level = unit->mLevel; | |
| int32 counter = unit->mCounter; | |
| if (counter <= 0) { | |
| counter = (int32)(unit->mRate->mSampleRate / sc_max(freq, .001f)); | |
| counter = sc_max(1, counter); | |
| RGET level = frand2(s1, s2, s3); | |
| unit->mLevel = level; | |
| RPUT | |
| } | |
| ZOUT0(0) = level; | |
| counter -= 1; | |
| unit->mCounter = counter; | |
| } | |
| void LFNoise0_Ctor(LFNoise0* unit) { | |
| if (BUFLENGTH == 1) | |
| SETCALC(LFNoise0_next_1); | |
| else | |
| SETCALC(LFNoise0_next); | |
| unit->mCounter = 0; | |
| unit->mLevel = 0.f; | |
| LFNoise0_next_1(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void LFNoise1_next(LFNoise1* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| float level = unit->mLevel; | |
| float slope = unit->mSlope; | |
| int32 counter = unit->mCounter; | |
| RGET | |
| int remain = inNumSamples; | |
| do { | |
| if (counter <= 0) { | |
| counter = (int32)(unit->mRate->mSampleRate / sc_max(freq, .001f)); | |
| counter = sc_max(1, counter); | |
| float nextlevel = frand2(s1, s2, s3); | |
| slope = (nextlevel - level) / counter; | |
| } | |
| int nsmps = sc_min(remain, counter); | |
| remain -= nsmps; | |
| counter -= nsmps; | |
| LOOP(nsmps, ZXP(out) = level; level += slope;); | |
| } while (remain); | |
| unit->mLevel = level; | |
| unit->mSlope = slope; | |
| unit->mCounter = counter; | |
| RPUT | |
| } | |
| void LFNoise1_Ctor(LFNoise1* unit) { | |
| SETCALC(LFNoise1_next); | |
| unit->mCounter = 0; | |
| unit->mLevel = unit->mParent->mRGen->frand2(); | |
| unit->mSlope = 0.f; | |
| LFNoise1_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void LFNoise2_next(LFNoise2* unit, int inNumSamples) { | |
| float* out = ZOUT(0); | |
| float freq = ZIN0(0); | |
| float level = unit->mLevel; | |
| float slope = unit->mSlope; | |
| float curve = unit->mCurve; | |
| int counter = unit->mCounter; | |
| RGET | |
| int remain = inNumSamples; | |
| do { | |
| if (counter <= 0) { | |
| float value = unit->m_nextvalue; | |
| unit->m_nextvalue = frand2(s1, s2, s3); | |
| level = unit->m_nextmidpt; | |
| unit->m_nextmidpt = (unit->m_nextvalue + value) * .5; | |
| counter = (int32)(unit->mRate->mSampleRate / sc_max(freq, .001f)); | |
| counter = sc_max(2, counter); | |
| float fseglen = (float)counter; | |
| curve = 2.f * (unit->m_nextmidpt - level - fseglen * slope) / (fseglen * fseglen + fseglen); | |
| } | |
| int nsmps = sc_min(remain, counter); | |
| remain -= nsmps; | |
| counter -= nsmps; | |
| LOOP(nsmps, ZXP(out) = level; slope += curve; level += slope;); | |
| } while (remain); | |
| unit->mLevel = level; | |
| unit->mSlope = slope; | |
| unit->mCurve = curve; | |
| unit->mCounter = counter; | |
| RPUT | |
| } | |
| void LFNoise2_Ctor(LFNoise2* unit) { | |
| SETCALC(LFNoise2_next); | |
| unit->mCounter = 0; | |
| unit->mSlope = 0.f; | |
| unit->mLevel = 0.f; | |
| unit->m_nextvalue = unit->mParent->mRGen->frand2(); | |
| unit->m_nextmidpt = unit->m_nextvalue * .5f; | |
| LFNoise2_next(unit, 1); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| void WrapBufRd_next0(Unit* unit, int inNumSamples); | |
| void WrapBufRd_next0(Unit* unit, int inNumSamples) { | |
| int bufnum = (int)ZIN0(0); | |
| float* pos = ZIN(1); | |
| const SndBuf* buf = unit->mWorld->mSndBufs + bufnum; | |
| int numchan = buf->channels; | |
| LOCK_SNDBUF_SHARED(buf); | |
| if (numchan != unit->mNumOutputs) { | |
| ClearUnitOutputs(unit, inNumSamples); | |
| return; | |
| } | |
| const float* data = buf->data; | |
| int numframes = buf->frames; | |
| float* out[16]; | |
| for (int i = 0; i < numchan; ++i) | |
| out[i] = OUT(i); | |
| LOOP1( | |
| inNumSamples, float fpos = ZXP(pos); int ipos = (int)fpos * numchan; ipos = sc_mod(ipos, numframes); | |
| int index = numchan * ipos; for (int i = 0; i < numchan; ++i) { | |
| *++(out[i]) = data[index]; | |
| index++; | |
| }); | |
| } | |
| void ClipBufRd_next0(Unit* unit, int inNumSamples); | |
| void ClipBufRd_next0(Unit* unit, int inNumSamples) { | |
| int bufnum = (int)ZIN0(0); | |
| float* pos = ZIN(1); | |
| const SndBuf* buf = unit->mWorld->mSndBufs + bufnum; | |
| LOCK_SNDBUF_SHARED(buf); | |
| int numchan = buf->channels; | |
| if (numchan != unit->mNumOutputs) { | |
| ClearUnitOutputs(unit, inNumSamples); | |
| return; | |
| } | |
| const float* data = buf->data; | |
| int numframes = buf->frames; | |
| int maxframe = numframes - 2; | |
| float* out[16]; | |
| for (int i = 0; i < numchan; ++i) | |
| out[i] = OUT(i); | |
| LOOP1( | |
| inNumSamples, float fpos = ZXP(pos); int ipos = (int)fpos * numchan; ipos = sc_clip(ipos, 0, maxframe); | |
| int index = numchan * ipos; for (int i = 0; i < numchan; ++i) { | |
| *++(out[i]) = data[index]; | |
| index++; | |
| }); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| PluginLoad(Noise) { | |
| ft = inTable; | |
| DefineSimpleUnit(WhiteNoise); | |
| DefineSimpleUnit(GrayNoise); | |
| DefineSimpleUnit(ClipNoise); | |
| DefineSimpleUnit(PinkNoise); | |
| DefineSimpleUnit(BrownNoise); | |
| DefineSimpleUnit(Dust); | |
| DefineSimpleUnit(Dust2); | |
| DefineSimpleUnit(Crackle); | |
| DefineSimpleUnit(Logistic); | |
| DefineSimpleUnit(Hasher); | |
| DefineSimpleUnit(MantissaMask); | |
| DefineSimpleUnit(LFClipNoise); | |
| DefineSimpleUnit(LFNoise0); | |
| DefineSimpleUnit(LFNoise1); | |
| DefineSimpleUnit(LFNoise2); | |
| DefineSimpleUnit(Rand); | |
| DefineSimpleUnit(IRand); | |
| DefineSimpleUnit(TRand); | |
| DefineSimpleUnit(TExpRand); | |
| DefineSimpleUnit(TIRand); | |
| DefineSimpleUnit(NRand); | |
| DefineSimpleUnit(LinRand); | |
| DefineSimpleUnit(ExpRand); | |
| DefineSimpleUnit(CoinGate); | |
| DefineSimpleUnit(RandSeed); | |
| DefineSimpleUnit(RandID); | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////// |