mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 04:10:47 +02:00
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:
parent
0279a3530f
commit
6f63b403e3
7 changed files with 881 additions and 7 deletions
|
|
@ -44,6 +44,11 @@ juce::AudioProcessorValueTreeState::ParameterLayout ChromaFlockProcessor::create
|
|||
|
||||
auto zeroOne = juce::NormalisableRange<float>(0.0f, 1.0f, 0.01f);
|
||||
|
||||
// LFO1 depth: fine 0.001 step, with a skew of 2.0 (value = p^2) so the
|
||||
// lower knob range resolves much finer and the 0.001 step only applies
|
||||
// in the upper range.
|
||||
juce::NormalisableRange<float> lfoDepthRange(0.0f, 1.0f, 0.001f, 2.0f);
|
||||
|
||||
// OSC 1
|
||||
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||
juce::ParameterID{"osc1Wave", 1}, "OSC1 Wave",
|
||||
|
|
@ -181,7 +186,7 @@ juce::AudioProcessorValueTreeState::ParameterLayout ChromaFlockProcessor::create
|
|||
juce::ParameterID{"lfo1Rate", 1}, "LFO1 Rate",
|
||||
juce::NormalisableRange<float>(0.05f, 20.0f, 0.01f, 0.4f), 2.0f));
|
||||
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
||||
juce::ParameterID{"lfo1Depth", 1}, "LFO1 Depth", zeroOne, 0.0f));
|
||||
juce::ParameterID{"lfo1Depth", 1}, "LFO1 Depth", lfoDepthRange, 0.0f));
|
||||
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||
juce::ParameterID{"lfo1Shape", 1}, "LFO1 Shape",
|
||||
juce::StringArray{"Sine", "Triangle", "Saw", "Square"}, 0));
|
||||
|
|
@ -202,7 +207,7 @@ juce::AudioProcessorValueTreeState::ParameterLayout ChromaFlockProcessor::create
|
|||
juce::ParameterID{"lfo2Rate", 1}, "LFO2 Rate",
|
||||
juce::NormalisableRange<float>(0.05f, 20.0f, 0.01f, 0.4f), 2.0f));
|
||||
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
||||
juce::ParameterID{"lfo2Depth", 1}, "LFO2 Depth", zeroOne, 0.0f));
|
||||
juce::ParameterID{"lfo2Depth", 1}, "LFO2 Depth", lfoDepthRange, 0.0f));
|
||||
layout.add(std::make_unique<juce::AudioParameterChoice>(
|
||||
juce::ParameterID{"lfo2Shape", 1}, "LFO2 Shape",
|
||||
juce::StringArray{"Sine", "Triangle", "Saw", "Square"}, 0));
|
||||
|
|
@ -259,6 +264,15 @@ void ChromaFlockProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
|
|||
|
||||
void ChromaFlockProcessor::releaseResources() {}
|
||||
|
||||
void ChromaFlockProcessor::fadeOutActiveVoices(float seconds) {
|
||||
for (int i = 0; i < synth.getNumVoices(); ++i) {
|
||||
if (auto* v = dynamic_cast<SubtractiveVoice*>(synth.getVoice(i))) {
|
||||
if (v->isVoiceActive())
|
||||
v->triggerQuickRelease(seconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChromaFlockProcessor::updateVoiceParameters() {
|
||||
auto getParam = [&](const juce::String& id) -> float {
|
||||
auto* p = apvts.getRawParameterValue(id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue