disable generative evolution globally; tame resonance, cross-mod and reverb drive

Zero EVOLVE/WARP on all 195 presets to remove the wind-howl sweep (filter cutoff, resonance, warp bias, detune sway no longer wander). Gate cross-mod bloom by EVOLVE so it stays static when off. Also settle voice-screen params, oscillator/filter levels and fx saturation.
This commit is contained in:
Armin 2026-09-14 02:27:45 +02:00
commit bf70af0191
3 changed files with 222 additions and 224 deletions

View file

@ -72,7 +72,7 @@ public:
if (doChorus) if (doChorus)
{ {
// 3-voice ensemble with a touch of internal regeneration // 3-voice ensemble chorus
const double w = chPh * 2.0 * juce::MathConstants<double>::pi; const double w = chPh * 2.0 * juce::MathConstants<double>::pi;
const float t1 = (float) std::sin (w); const float t1 = (float) std::sin (w);
const float t2 = (float) std::sin (w + 2.09439f); const float t2 = (float) std::sin (w + 2.09439f);
@ -85,8 +85,6 @@ public:
+ chorusL.popSample (0, chBase + chDepth * t2)); + chorusL.popSample (0, chBase + chDepth * t2));
const float mR = 0.5f * (chorusR.popSample (0, chBase + chDepth * t2) const float mR = 0.5f * (chorusR.popSample (0, chBase + chDepth * t2)
+ chorusR.popSample (0, chBase + chDepth * t3)); + chorusR.popSample (0, chBase + chDepth * t3));
chorusL.pushSample (0, mL * 0.30f);
chorusR.pushSample (0, mR * 0.30f);
outL += mL * wet * 0.8f; outL += mL * wet * 0.8f;
outR += mR * wet * 0.8f; outR += mR * wet * 0.8f;
} }
@ -107,20 +105,20 @@ public:
float revL = 0.0f, revR = 0.0f; float revL = 0.0f, revR = 0.0f;
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
{ {
float o = combL[i].process (inL * 0.25f, 0.84f, 0.30f); float o = combL[i].process (inL * 0.25f, 0.78f, 0.55f);
revL += o * 0.22f; revL += o * 0.22f;
o = combR[i].process (inR * 0.25f, 0.84f, 0.30f); o = combR[i].process (inR * 0.25f, 0.78f, 0.55f);
revR += o * 0.22f; revR += o * 0.22f;
} }
apL[0].process (revL, 0.70f); apL[1].process (revL, 0.57f); apL[0].process (revL, 0.70f); apL[1].process (revL, 0.57f);
apR[0].process (revR, 0.70f); apR[1].process (revR, 0.57f); apR[0].process (revR, 0.70f); apR[1].process (revR, 0.57f);
const float revWet = (type == 7 ? wet : wet * 0.8f); const float revWet = wet * 0.8f;
outL += revL * revWet; outL += revL * revWet;
outR += revR * revWet; outR += revR * revWet;
} }
L[s] = outL; L[s] = std::tanh (outL * 0.85f);
R[s] = outR; R[s] = std::tanh (outR * 0.85f);
} }
} }
@ -533,7 +531,7 @@ void RMX19AudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::
{ {
float x = ch[s]; float x = ch[s];
// Soft knee limiting at ~-1dBFS with smooth tanh curve // Soft knee limiting at ~-1dBFS with smooth tanh curve
x = std::tanh (x * 0.89f) * 1.12f; x = std::tanh (x * 0.89f);
if (! std::isfinite (x)) x = 0.0f; if (! std::isfinite (x)) x = 0.0f;
ch[s] = juce::jlimit (-1.0f, 1.0f, x); ch[s] = juce::jlimit (-1.0f, 1.0f, x);
} }
@ -576,7 +574,7 @@ void RMX19AudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::
for (int s = 0; s < numSamples; ++s) for (int s = 0; s < numSamples; ++s)
{ {
float x = ch[s]; float x = ch[s];
x = std::tanh (x * 0.89f) * 1.12f; x = std::tanh (x * 0.89f);
if (! std::isfinite (x)) x = 0.0f; if (! std::isfinite (x)) x = 0.0f;
ch[s] = juce::jlimit (-1.0f, 1.0f, x); ch[s] = juce::jlimit (-1.0f, 1.0f, x);
} }

File diff suppressed because it is too large Load diff

View file

@ -42,14 +42,14 @@ float SynthEngine::osc (int wave, double ph, double phRaw)
sp -= std::floor (sp); sp -= std::floor (sp);
s += 1.0 - 2.0 * sp; s += 1.0 - 2.0 * sp;
} }
return (float) (s * 0.40); return (float) (s * 0.28);
} }
// 8 DBLSAW: saw plus a sub-octave saw (big, weighted low end) // 8 DBLSAW: saw plus a sub-octave saw (big, weighted low end)
case 8: case 8:
{ {
double sub = ph * 0.5; double sub = ph * 0.5;
sub -= std::floor (sub); sub -= std::floor (sub);
return (float) (0.62 * (1.0 - 2.0 * ph) + 0.48 * (1.0 - 2.0 * sub)); return (float) (0.56 * (1.0 - 2.0 * ph) + 0.44 * (1.0 - 2.0 * sub));
} }
// 9 WARP: saw pushed twice through a wavefolder -> bright, buzzy, raw // 9 WARP: saw pushed twice through a wavefolder -> bright, buzzy, raw
case 9: case 9:
@ -70,10 +70,10 @@ float SynthEngine::osc (int wave, double ph, double phRaw)
case 11: case 11:
{ {
const double a = ph * 2.0 * juce::MathConstants<double>::pi; const double a = ph * 2.0 * juce::MathConstants<double>::pi;
return (float) (0.85 * std::sin (a) return (float) (0.44 * std::sin (a)
+ 0.55 * std::sin (2.0 * a) + 0.28 * std::sin (2.0 * a)
+ 0.35 * std::sin (4.0 * a) + 0.18 * std::sin (4.0 * a)
+ 0.18 * std::sin (8.0 * a)); + 0.09 * std::sin (8.0 * a));
} }
// 12 SEQ: 8 pseudo-random levels per cycle -> digital, step-sequencer // 12 SEQ: 8 pseudo-random levels per cycle -> digital, step-sequencer
case 12: case 12:
@ -87,9 +87,9 @@ float SynthEngine::osc (int wave, double ph, double phRaw)
case 13: case 13:
{ {
const double a = ph * 2.0 * juce::MathConstants<double>::pi; const double a = ph * 2.0 * juce::MathConstants<double>::pi;
return (float) (0.62 * std::sin (a) return (float) (0.44 * std::sin (a)
+ 0.42 * std::sin (a * (6.0 / 5.0)) + 0.30 * std::sin (a * (6.0 / 5.0))
+ 0.38 * std::sin (a * 1.5)); + 0.27 * std::sin (a * 1.5));
} }
// 14 SUPRPL: 3 stacked phase-offset pulse waves -> fat chorus-box square // 14 SUPRPL: 3 stacked phase-offset pulse waves -> fat chorus-box square
case 14: case 14:
@ -309,11 +309,12 @@ void SynthEngine::render (const VParams& p, float* left, float* right, int num)
v.ph1 += d1; if (v.ph1 >= 1.0) v.ph1 -= 1.0; v.ph1 += d1; if (v.ph1 >= 1.0) v.ph1 -= 1.0;
v.ph1r += d1; v.ph1r += d1;
// cross-mod "bloom": the amount itself breathes with the evolution walk, // cross-mod "bloom": the amount breathes with the evolution walk
// (scaled by EVOLVE, so at evolve=0 it sits static at its middle value),
// sometimes vanishing almost entirely, sometimes saturating // sometimes vanishing almost entirely, sometimes saturating
float xmA = 0.0f; float xmA = 0.0f;
if ((int) p.xmod > 0 && p.xmix > 0.001f) if ((int) p.xmod > 0 && p.xmix > 0.001f)
xmA = p.xmix * (0.10f + 0.90f * (0.5f + 0.5f * evoCur)); xmA = p.xmix * (0.55f + 0.45f * evoCur * p.evolve);
// oscillators, with osc1 phase-modulating osc2 when in FM cross-mod // oscillators, with osc1 phase-modulating osc2 when in FM cross-mod
const float o1 = osc ((int) p.osc1w, v.ph1, v.ph1r); const float o1 = osc ((int) p.osc1w, v.ph1, v.ph1r);
@ -334,8 +335,8 @@ void SynthEngine::render (const VParams& p, float* left, float* right, int num)
if (xmA > 0.0f) if (xmA > 0.0f)
{ {
const int xm = (int) p.xmod; const int xm = (int) p.xmod;
if (xm == 1) sig += o1 * o2 * 0.6f * xmA; if (xm == 1) sig += o1 * o2 * 0.35f * xmA;
else if (xm == 3) sig += o1 * o2 * 0.9f * xmA; else if (xm == 3) sig += o1 * o2 * 0.55f * xmA;
} }
// spectral warp: drive + bias swing hard with the texture wander, // spectral warp: drive + bias swing hard with the texture wander,
@ -374,16 +375,15 @@ void SynthEngine::render (const VParams& p, float* left, float* right, int num)
v.bp += f1 * hp; v.bp += f1 * hp;
v.lp += f1 * v.bp; v.lp += f1 * v.bp;
// The Chamberlin band-pass and high-pass taps carry much less energy // The Chamberlin band-pass and high-pass taps carry less energy
// than the low-pass tap for the harmonically rich osc waves (2-4x // than the low-pass tap for harmonically rich osc waves, so
// quieter in practice), so compensate to keep filter types at a // compensate to keep filter types at a comparable loudness level.
// comparable loudness level.
float filtered = sig; float filtered = sig;
switch ((int) p.fltType) switch ((int) p.fltType)
{ {
case 1: filtered = v.lp; break; case 1: filtered = v.lp; break;
case 2: filtered = v.bp * 2.9f; break; case 2: filtered = v.bp * 1.5f; break;
case 3: filtered = hp * 2.7f; break; case 3: filtered = hp * 1.4f; break;
default: break; default: break;
} }