feat: add presets, Randomize button, menu highlight, finer LFO depth, preset-switch fade-out

- PresetManager: add ~40 new presets including a new Techno category with
  LFO-to-OSC-pitch movement, plus Bass/Lead/Pad/Keys/Brass/Strings/Wind/
  Arp/Pluck/FX expansions
- UI: add RANDOM button; highlight the currently selected entry in all
  dropdown menus (incl. ticking the active preset in the preset browser)
- LFO depth: finer 0.001 step with a skew curve so the lower range resolves
  much finer than the upper range (shared by LFO1 and LFO2)
- DSP: fade out active voices over 250ms on preset change / randomize so long
  release tails from the previous sound are silenced
- Update bg.png
This commit is contained in:
Armin 2026-07-14 13:54:17 +02:00
commit 6f63b403e3
7 changed files with 881 additions and 7 deletions

View file

@ -57,6 +57,9 @@ public:
env.noteOn();
filterEnv.noteOn();
quickFade = 1.0f;
quickFadeStep = 0.0f;
}
void stopNote(float velocity, bool allowTailOff) override {
@ -80,6 +83,10 @@ public:
return;
}
// Per-voice quick fade (triggered on preset change)
if (quickFade < 1.0f)
quickFade = std::max(0.0f, quickFade - quickFadeStep);
// LFO outputs
float lfo1Out = lfo1.getNextSample();
float lfo2Out = lfo2.getNextSample();
@ -135,8 +142,13 @@ public:
left = std::tanh(left * drive) / std::tanh(drive);
right = std::tanh(right * drive) / std::tanh(drive);
outputBuffer.addSample(0, i, left * outputLevel);
outputBuffer.addSample(1, i, right * outputLevel);
outputBuffer.addSample(0, i, left * outputLevel * quickFade);
outputBuffer.addSample(1, i, right * outputLevel * quickFade);
if (quickFade <= 0.0f) {
clearCurrentNote();
return;
}
}
}
@ -197,6 +209,16 @@ public:
void setPitchBend(float semitones) { pitchBendSemitones = semitones; }
// Quickly fade out this voice (e.g. when a preset is switched) so any
// long release tail from the previous sound is silenced over `seconds`.
void triggerQuickRelease(float seconds) {
double sr = getSampleRate();
if (sr <= 0.0) sr = 44100.0;
quickFadeStep = 1.0f / static_cast<float>(seconds * sr);
env.noteOff();
filterEnv.noteOff();
}
private:
Oscillator osc1, osc2;
Filter filter;
@ -228,4 +250,6 @@ private:
float pitchBendSemitones = 0.0f;
int currentMidiNote = 60;
float noteVelocity = 1.0f;
float quickFade = 1.0f;
float quickFadeStep = 0.0f;
};