feat(fx): add effect rack and effect units
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
#include "Hyper.h"
|
||||
|
||||
namespace serum
|
||||
{
|
||||
|
||||
void HyperUnit::prepare (double sampleRate, int)
|
||||
{
|
||||
sr = sampleRate;
|
||||
lpL.setSampleRate (sr); lpR.setSampleRate (sr);
|
||||
hpL.setSampleRate (sr); hpR.setSampleRate (sr);
|
||||
lpL.setLowpass (150.0, 0.7071); lpR.setLowpass (150.0, 0.7071);
|
||||
hpL.setHighpass (2500.0, 0.7071); hpR.setHighpass (2500.0, 0.7071);
|
||||
reset();
|
||||
}
|
||||
|
||||
void HyperUnit::reset()
|
||||
{
|
||||
lpL.clear(); lpR.clear(); hpL.clear(); hpR.clear();
|
||||
for (auto& b : bL) { b.env = 0.0f; b.gain = 1.0f; }
|
||||
for (auto& b : bR) { b.env = 0.0f; b.gain = 1.0f; }
|
||||
}
|
||||
|
||||
float HyperUnit::computeGain (Band& band, float absIn, float intensity) noexcept
|
||||
{
|
||||
// Peak envelope follower with fast attack, slower release.
|
||||
const float attack = (absIn > band.env) ? 0.3f : 0.003f;
|
||||
band.env += attack * (absIn - band.env);
|
||||
|
||||
const float env = band.env + 1e-6f;
|
||||
const float ratio = 4.0f + 8.0f * intensity;
|
||||
const float upAmount = intensity * 0.7f;
|
||||
|
||||
// Downward compression above the reference level, upward expansion below.
|
||||
float target;
|
||||
if (env > 1.0f)
|
||||
target = 1.0f + (env - 1.0f) / ratio;
|
||||
else
|
||||
target = 1.0f - (1.0f - env) * (1.0f - upAmount);
|
||||
|
||||
float desired = target / env;
|
||||
desired = juce::jlimit (0.2f, 4.0f, desired);
|
||||
band.gain += 0.01f * (desired - band.gain);
|
||||
return band.gain;
|
||||
}
|
||||
|
||||
void HyperUnit::process (float* l, float* r, int numSamples, const float p[4])
|
||||
{
|
||||
const float intensity = p[0];
|
||||
const float lowAmt = 0.4f + 0.6f * p[1];
|
||||
const float highAmt = 0.4f + 0.6f * p[2];
|
||||
const float output = 0.5f + p[3] * 1.0f;
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
const float inL = l[i], inR = r[i];
|
||||
|
||||
const float loL = lpL.process (inL);
|
||||
const float restL = inL - loL;
|
||||
const float hiL = hpL.process (restL);
|
||||
const float midL = restL - hiL;
|
||||
|
||||
const float loR = lpR.process (inR);
|
||||
const float restR = inR - loR;
|
||||
const float hiR = hpR.process (restR);
|
||||
const float midR = restR - hiR;
|
||||
|
||||
const float gLL = computeGain (bL[0], std::abs (loL), intensity);
|
||||
const float gML = computeGain (bL[1], std::abs (midL), intensity);
|
||||
const float gHL = computeGain (bL[2], std::abs (hiL), intensity);
|
||||
|
||||
const float gLR = computeGain (bR[0], std::abs (loR), intensity);
|
||||
const float gMR = computeGain (bR[1], std::abs (midR), intensity);
|
||||
const float gHR = computeGain (bR[2], std::abs (hiR), intensity);
|
||||
|
||||
l[i] = (loL * gLL * lowAmt + midL * gML + hiL * gHL * highAmt) * output;
|
||||
r[i] = (loR * gLR * lowAmt + midR * gMR + hiR * gHR * highAmt) * output;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace serum
|
||||
Reference in New Issue
Block a user