mirror of
https://codeberg.org/armin/monostep.git
synced 2026-09-01 04:10:46 +02:00
Add delay and reverb FX section with full DSP
Rename the DIST section to FX and expand it with tempo-synced delay (Time/Strength/Sync) and Schroeder reverb (Roomsize/Strength/Diffusion). New FxProcessor runs post-voice on the stereo bus; widen the editor to 1280px to fit the new section. Add a TestHost check that the FX tail rings out after note release.
This commit is contained in:
parent
a45006c201
commit
342d413563
8 changed files with 505 additions and 23 deletions
|
|
@ -3,6 +3,7 @@
|
|||
#include "PluginProcessor.h"
|
||||
#include "Theme.h"
|
||||
#include "BuildInfo.h"
|
||||
#include "dsp/FxProcessor.h"
|
||||
|
||||
using namespace monostep;
|
||||
|
||||
|
|
@ -657,6 +658,11 @@ MonostepAudioProcessorEditor::MonostepAudioProcessorEditor (MonostepAudioProcess
|
|||
fAmountKnob ("Amt"),
|
||||
driveKnob ("Drive"),
|
||||
ringKnob ("Ring"),
|
||||
delayTimeKnob ("Time"),
|
||||
delayStrengthKnob ("Strength"),
|
||||
reverbRoomKnob ("Room"),
|
||||
reverbStrengthKnob ("Strength"),
|
||||
reverbDiffusionKnob ("Diff"),
|
||||
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" }),
|
||||
|
|
@ -759,8 +765,22 @@ MonostepAudioProcessorEditor::MonostepAudioProcessorEditor (MonostepAudioProcess
|
|||
addKnob (fAmountKnob, "filterEnvAmt", [] (float v) { return (v >= 0.0f ? "+" : "") + juce::String (v, 2) + " oct"; });
|
||||
addKnob (driveKnob, "drive", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
|
||||
addKnob (ringKnob, "ringmod", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
|
||||
addKnob (delayTimeKnob, "delayTime", [this] (float v)
|
||||
{
|
||||
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 (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 (accentKnob, "accent", [] (float v) { return juce::String (juce::roundToInt (v * 100.0f)) + "%"; });
|
||||
|
||||
delaySyncToggle.setButtonText ("Sync");
|
||||
delaySyncToggle.setTooltip ("Snap the delay time to the host tempo (off: free milliseconds)");
|
||||
delaySyncAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment> (apvts, "delaySync", delaySyncToggle);
|
||||
content.addAndMakeVisible (delaySyncToggle);
|
||||
|
||||
fAmountKnob.setDragSensitivity (800);
|
||||
|
||||
content.addAndMakeVisible (matrix);
|
||||
|
|
@ -895,11 +915,20 @@ void MonostepAudioProcessorEditor::paintContent (juce::Graphics& g)
|
|||
return r;
|
||||
};
|
||||
|
||||
// Draw a knob group: subtle gradient behind the title legend + a slight border
|
||||
// around the knobs themselves. leftPad extends the frame to the left so it can
|
||||
// enclose side labels.
|
||||
auto drawGroup = [&] (const juce::Component& first, const juce::Component& last,
|
||||
const juce::String& title, float pad, float leftPad = 0.0f)
|
||||
// Draw a knob group frame: a slight border around the knobs themselves.
|
||||
// leftPad extends the frame to the left so it can enclose side labels.
|
||||
auto drawFrame = [&] (const juce::Component& first, const juce::Component& last,
|
||||
float pad, float leftPad = 0.0f)
|
||||
{
|
||||
auto box = groupBox (first, last, pad);
|
||||
box.setLeft (box.getX() - leftPad);
|
||||
g.setColour (colours::section.withAlpha (0.30f));
|
||||
g.drawRoundedRectangle (box, 3.0f, 1.0f);
|
||||
};
|
||||
|
||||
// A gradient legend pill spanning the given group, with the title centred.
|
||||
auto drawPill = [&] (const juce::Component& first, const juce::Component& last,
|
||||
const juce::String& title, float leftPad = 0.0f)
|
||||
{
|
||||
const int capX = first.getX() - (int) leftPad;
|
||||
const int capW = last.getRight() - capX;
|
||||
|
|
@ -912,19 +941,24 @@ void MonostepAudioProcessorEditor::paintContent (juce::Graphics& g)
|
|||
g.setFont (font (9.0f).boldened());
|
||||
g.setColour (colours::bg);
|
||||
g.drawText (title, legend, juce::Justification::centred);
|
||||
|
||||
auto box = groupBox (first, last, pad);
|
||||
box.setLeft (box.getX() - leftPad);
|
||||
g.setColour (colours::section.withAlpha (0.30f));
|
||||
g.drawRoundedRectangle (box, 3.0f, 1.0f);
|
||||
};
|
||||
|
||||
drawGroup (wave1Box, mixKnob, "OSC", 6.0f, (float) (oscLabelW - 21 + 9));
|
||||
drawGroup (glideKnob, accentKnob, "NOTE", 6.0f);
|
||||
drawGroup (driveKnob, ringKnob, "DIST", 6.0f);
|
||||
drawGroup (filterTypeBox, resKnob, "FILTER", 6.0f, 6.0f);
|
||||
drawGroup (attackKnob, releaseKnob, "AMP ENV", 6.0f);
|
||||
drawGroup (fAttackKnob, fAmountKnob, "FILTER ENV", 6.0f);
|
||||
drawFrame (wave1Box, mixKnob, 6.0f, (float) (oscLabelW - 21 + 9));
|
||||
drawPill (wave1Box, mixKnob, "OSC", (float) (oscLabelW - 21 + 9));
|
||||
drawFrame (glideKnob, accentKnob, 6.0f);
|
||||
drawPill (glideKnob, accentKnob, "NOTE");
|
||||
|
||||
drawFrame (driveKnob, reverbDiffusionKnob, 6.0f);
|
||||
drawPill (driveKnob, ringKnob, "FX");
|
||||
drawPill (delayTimeKnob, delaySyncToggle, "DELAY");
|
||||
drawPill (reverbRoomKnob, reverbDiffusionKnob, "REVERB");
|
||||
|
||||
drawFrame (filterTypeBox, resKnob, 6.0f, 6.0f);
|
||||
drawPill (filterTypeBox, resKnob, "FILTER", 6.0f);
|
||||
drawFrame (attackKnob, releaseKnob, 6.0f);
|
||||
drawPill (attackKnob, releaseKnob, "AMP ENV");
|
||||
drawFrame (fAttackKnob, fAmountKnob, 6.0f);
|
||||
drawPill (fAttackKnob, fAmountKnob, "FILTER ENV");
|
||||
|
||||
const int footY = baseHeight - 20;
|
||||
g.setColour (colours::grid);
|
||||
|
|
@ -993,7 +1027,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 + 6 * step + knobW + 48; // +48 = the two group gaps
|
||||
const int blockW = oscColW + 12 * step + 104; // osc col + FX (8 widgets + 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
|
||||
|
|
@ -1013,11 +1047,15 @@ void MonostepAudioProcessorEditor::resized()
|
|||
}
|
||||
};
|
||||
|
||||
// Row 1: coarse / detune / mix / glide / accent / drive / ring.
|
||||
// NOTE and DIST are pushed apart to clear the group frames.
|
||||
// Row 1: coarse / detune / mix / glide / accent / FX (drive / ring / delay / reverb).
|
||||
placeRow (row1Y, oscX, { &coarseKnob, &detuneKnob, &mixKnob });
|
||||
placeRow (row1Y, oscX + 3 * step + 24, { &glideKnob, &accentKnob });
|
||||
placeRow (row1Y, oscX + 5 * step + 48, { &driveKnob, &ringKnob });
|
||||
|
||||
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);
|
||||
|
||||
// Row 2: Filter (dropdown + cutoff, res) [gap] Amp Envelope [gap] Filter Env.
|
||||
// The three sections are centered as one block with equal frame gaps.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue