Add delay/reverb dry-wet, granular randomize toggles, rework accent DSP

- Add delay and reverb Dry/Wet parameters and knobs, wired into presets
- Add Accent/Slide/Fine/Rate toggles to the Randomize panel with new
  per-aspect pattern randomizers
- Soften accent: modest volume lift plus small cutoff and filter-attack
  modulation instead of the heavy 5x gain boost
- Halve reverb comb/allpass delays so the wet speaks sooner
- Regenerate a fresh build stamp on every build
This commit is contained in:
Armin 2026-08-06 18:38:32 +02:00
commit 662a1f7383
11 changed files with 310 additions and 97 deletions

View file

@ -504,6 +504,14 @@ StepPanel::StepPanel (MonostepAudioProcessor& processorRef)
processor.randomizeSeqSettings();
if (randomizeToggles[RandomFx].getToggleState())
processor.randomizeFx();
if (randomizeToggles[RandomAccent].getToggleState())
processor.randomizeAccent();
if (randomizeToggles[RandomSlide].getToggleState())
processor.randomizeSlide();
if (randomizeToggles[RandomFine].getToggleState())
processor.randomizeFine();
if (randomizeToggles[RandomRate].getToggleState())
processor.randomizeRate();
};
addAndMakeVisible (randomizeButton);
@ -513,7 +521,8 @@ StepPanel::StepPanel (MonostepAudioProcessor& processorRef)
randomizeCaption.setColour (juce::Label::textColourId, colours::textDim);
addAndMakeVisible (randomizeCaption);
static const char* groupNames[] = { "Pattern", "Osc", "Filter", "Env", "Length", "FX" };
static const char* groupNames[] = { "Pattern", "Osc", "Filter", "Env", "Length", "FX",
"Accent", "Slide", "Fine", "Rate" };
for (int i = 0; i < RandomGroupCount; ++i)
{
@ -590,41 +599,41 @@ void StepPanel::resized()
const int w = getWidth();
titleLabel.setBounds (0, 4, w, 16);
noteLabel.setBounds (0, 22, w, 28);
noteLabel.setBounds (0, 22, w, 26);
gateLabel.setBounds (0, 50, w, 14);
const int knobX = (w - 74) / 2;
const int knobY = 68;
const int knobY = 66;
fineKnob.setBounds (knobX, knobY, 74, 94);
fineKnob.setBounds (knobX, knobY, 74, 84);
const int btnY = knobY + 102;
const int btnY = knobY + 84 + 6;
prevButton.setBounds (knobX - 32, btnY, 24, 24);
nextButton.setBounds (knobX + 74 + 8, btnY, 24, 24);
const int shiftW = 22;
shiftLeftButton.setBounds (10, btnY + 50, shiftW, 26);
clearButton.setBounds (10 + shiftW + 4, btnY + 50, w - 20 - shiftW * 2 - 8, 26);
shiftRightButton.setBounds (10 + w - 20 - shiftW, btnY + 50, shiftW, 26);
shiftLeftButton.setBounds (10, btnY + 40, shiftW, 24);
clearButton.setBounds (10 + shiftW + 4, btnY + 40, w - 20 - shiftW * 2 - 8, 24);
shiftRightButton.setBounds (10 + w - 20 - shiftW, btnY + 40, shiftW, 24);
toolsCaption.setBounds (10, btnY + 86, w - 20, 14);
presetCombo.setBounds (10, btnY + 102, w - 20, 26);
randomizeButton.setBounds (10, btnY + 134, w - 20, 26);
randomizeCaption.setBounds (10, btnY + 166, w - 20, 12);
toolsCaption.setBounds (10, btnY + 70, w - 20, 12);
presetCombo.setBounds (10, btnY + 84, w - 20, 24);
randomizeButton.setBounds (10, btnY + 112, w - 20, 24);
randomizeCaption.setBounds (10, btnY + 140, w - 20, 12);
const int colW = (w - 20 - 4) / 2;
const int rowH = 20;
const int rowH = 18;
for (int i = 0; i < RandomGroupCount; ++i)
{
const int col = i / 3;
const int row = i % 3;
randomizeToggles[i].setBounds (10 + col * (colW + 4), btnY + 180 + row * (rowH + 2), colW, rowH);
const int col = i % 2;
const int row = i / 2;
randomizeToggles[i].setBounds (10 + col * (colW + 4), btnY + 154 + row * (rowH + 2), colW, rowH);
}
const int retrigW = 100;
retrigToggle.setBounds (10, btnY + 252, retrigW, 26);
resetFineButton.setBounds (10 + retrigW + 4, btnY + 252, w - 20 - retrigW - 4, 26);
retrigToggle.setBounds (10, btnY + 254, retrigW, 24);
resetFineButton.setBounds (10 + retrigW + 4, btnY + 254, w - 20 - retrigW - 4, 24);
}
//==============================================================================
@ -659,10 +668,12 @@ MonostepAudioProcessorEditor::MonostepAudioProcessorEditor (MonostepAudioProcess
driveKnob ("Drive"),
ringKnob ("Ring"),
delayTimeKnob ("Time"),
delayStrengthKnob ("Strength"),
delayFeedbackKnob ("Feedback"),
delayDryWetKnob ("Dry/Wet"),
reverbRoomKnob ("Room"),
reverbStrengthKnob ("Strength"),
reverbStrengthKnob ("Level"),
reverbDiffusionKnob ("Diff"),
reverbDryWetKnob ("Dry/Wet"),
accentKnob ("Accent"),
rateBar (processor.getAPVTS(), "seqRate", { "1/4", "1/8", "1/8T", "1/16", "1/32" }),
octaveBar (processor.getAPVTS(), "seqOctave", { "-2", "-1", "0", "+1", "+2" }),
@ -770,10 +781,12 @@ MonostepAudioProcessorEditor::MonostepAudioProcessorEditor (MonostepAudioProcess
const bool sync = processorRef.getAPVTS().getRawParameterValue ("delaySync")->load() >= 0.5f;
return monostep::FxProcessor::delayTimeLabel (v, sync, 120.0);
});
addKnob (delayStrengthKnob, "delayStrength", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (delayFeedbackKnob, "delayStrength", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (delayDryWetKnob, "delayDryWet", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (reverbRoomKnob, "reverbRoom", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (reverbStrengthKnob, "reverbStrength", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (reverbDiffusionKnob, "reverbDiffusion", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (reverbDryWetKnob, "reverbDryWet", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
addKnob (accentKnob, "accent", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
delaySyncToggle.setButtonText ("Sync");
@ -948,10 +961,10 @@ void MonostepAudioProcessorEditor::paintContent (juce::Graphics& g)
drawFrame (glideKnob, accentKnob, 6.0f);
drawPill (glideKnob, accentKnob, "NOTE");
drawFrame (driveKnob, reverbDiffusionKnob, 6.0f);
drawFrame (driveKnob, reverbDryWetKnob, 6.0f);
drawPill (driveKnob, ringKnob, "FX");
drawPill (delayTimeKnob, delaySyncToggle, "DELAY");
drawPill (reverbRoomKnob, reverbDiffusionKnob, "REVERB");
drawPill (reverbRoomKnob, reverbDryWetKnob, "REVERB");
drawFrame (filterTypeBox, resKnob, 6.0f, 6.0f);
drawPill (filterTypeBox, resKnob, "FILTER", 6.0f);
@ -1027,7 +1040,7 @@ void MonostepAudioProcessorEditor::resized()
const int oscColW = oscLabelW + oscDropW + oscGapW; // labels + dropdowns + gap to knobs
// Both rows are centered over the full bottom bar width.
const int blockW = oscColW + 12 * step + 104; // osc col + FX (8 widgets + subgroup gaps)
const int blockW = oscColW + 15 * step + 152; // osc col + FX (9 widgets + sync toggle + subgroup gaps)
const int oscX = pad + ((w - 2 * pad) - blockW) / 2 + oscColW;
const int row1Y = bottomY + 24;
const int row2Y = row1Y + knobH + 34; // row 1 + a caption band
@ -1053,9 +1066,9 @@ void MonostepAudioProcessorEditor::resized()
const int fxX = oscX + 5 * step + 48;
placeRow (row1Y, fxX, { &driveKnob, &ringKnob });
placeRow (row1Y, fxX + 2 * step + 24, { &delayTimeKnob, &delayStrengthKnob });
placeRow (row1Y, fxX + 5 * step + 48, { &reverbRoomKnob, &reverbStrengthKnob, &reverbDiffusionKnob });
delaySyncToggle.setBounds (fxX + 4 * step + 24, row1Y + (knobH - 24) / 2, knobW, 24);
placeRow (row1Y, fxX + 2 * step + 24, { &delayTimeKnob, &delayFeedbackKnob, &delayDryWetKnob });
placeRow (row1Y, fxX + 6 * step + 46, { &reverbRoomKnob, &reverbStrengthKnob, &reverbDiffusionKnob, &reverbDryWetKnob });
delaySyncToggle.setBounds (fxX + 5 * step + 24, row1Y + (knobH - 24) / 2, knobW, 24);
// Row 2: Filter (dropdown + cutoff, res) [gap] Amp Envelope [gap] Filter Env.
// The three sections are centered as one block with equal frame gaps.