Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
1162 lines (925 sloc) 30.6 KB
/*
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);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////