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:
Armin 2026-08-06 16:35:34 +02:00
commit 342d413563
8 changed files with 505 additions and 23 deletions

View file

@ -13,7 +13,9 @@ static const char* paramId (int index)
"seqLen", "seqRate", "seqRoot", "seqOctave", "seqSwing", "seqGateLen",
"drive", "ringmod", "accent", "fine1",
"filterAttack", "filterDecay", "filterSustain", "filterRelease", "filterEnvAmt",
"seqRetrig"
"seqRetrig",
"delayTime", "delayStrength", "delaySync",
"reverbRoom", "reverbStrength", "reverbDiffusion"
};
return ids[index];
}
@ -26,6 +28,8 @@ enum ParamIndex
pDrive, pRingMod, pAccent, pFine1,
pFilterAttack, pFilterDecay, pFilterSustain, pFilterRelease, pFilterEnvAmt,
pSeqRetrig,
pDelayTime, pDelayStrength, pDelaySync,
pReverbRoom, pReverbStrength, pReverbDiffusion,
numParams
};
@ -65,6 +69,12 @@ MonostepAudioProcessor::MonostepAudioProcessor()
ringModParam = apvts.getRawParameterValue (paramId (pRingMod));
accentParam = apvts.getRawParameterValue (paramId (pAccent));
seqRetrigParam = apvts.getRawParameterValue (paramId (pSeqRetrig));
delayTimeParam = apvts.getRawParameterValue (paramId (pDelayTime));
delayStrengthParam = apvts.getRawParameterValue (paramId (pDelayStrength));
delaySyncParam = apvts.getRawParameterValue (paramId (pDelaySync));
reverbRoomParam = apvts.getRawParameterValue (paramId (pReverbRoom));
reverbStrengthParam = apvts.getRawParameterValue (paramId (pReverbStrength));
reverbDiffusionParam = apvts.getRawParameterValue (paramId (pReverbDiffusion));
setDefaultPattern();
}
@ -172,6 +182,24 @@ juce::AudioProcessorValueTreeState::ParameterLayout MonostepAudioProcessor::crea
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pAccent),
"Accent", juce::NormalisableRange<float> (0.0f, 1.0f), 0.7f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pDelayTime),
"Delay Time", juce::NormalisableRange<float> (0.0f, 1.0f), 0.35f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pDelayStrength),
"Delay Strength", juce::NormalisableRange<float> (0.0f, 1.0f), 0.0f));
layout.add (std::make_unique<juce::AudioParameterBool> (paramId (pDelaySync),
"Delay Sync", true));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pReverbRoom),
"Reverb Roomsize", juce::NormalisableRange<float> (0.0f, 1.0f), 0.5f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pReverbStrength),
"Reverb Strength", juce::NormalisableRange<float> (0.0f, 1.0f), 0.0f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pReverbDiffusion),
"Reverb Diffusion", juce::NormalisableRange<float> (0.0f, 1.0f), 0.6f));
return layout;
}
@ -391,6 +419,12 @@ void MonostepAudioProcessor::randomizeFx()
{
applyParamValue ("drive", random.nextFloat());
applyParamValue ("ringmod", random.nextFloat());
applyParamValue ("delayTime", random.nextFloat());
applyParamValue ("delayStrength", random.nextFloat() * 0.8f);
applyParamValue ("delaySync", random.nextFloat() < 0.8f ? 1.0f : 0.0f);
applyParamValue ("reverbRoom", 0.2f + random.nextFloat() * 0.7f);
applyParamValue ("reverbStrength", random.nextFloat() * 0.7f);
applyParamValue ("reverbDiffusion", random.nextFloat());
}
void MonostepAudioProcessor::randomizeParams()
@ -407,6 +441,7 @@ void MonostepAudioProcessor::prepareToPlay (double sr, int samplesPerBlock)
sampleRate = sr;
voice.prepare (sr);
scratch.setSize (1, samplesPerBlock);
fx.prepare (sr, juce::jmax (1, getTotalNumOutputChannels()));
lastStep = -1;
lastGateApplied = false;
lastFreqApplied = -1.0f;
@ -418,6 +453,7 @@ void MonostepAudioProcessor::prepareToPlay (double sr, int samplesPerBlock)
void MonostepAudioProcessor::releaseResources()
{
voice.reset();
fx.reset();
}
void MonostepAudioProcessor::updateVoiceParams()
@ -676,6 +712,17 @@ void MonostepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
for (int ch = 0; ch < numChannels; ++ch)
buffer.addFrom (ch, 0, scratch, 0, 0, numSamples);
monostep::FxProcessor::Params fp;
fp.delayTime = delayTimeParam->load();
fp.delayMix = delayStrengthParam->load();
fp.delaySync = delaySyncParam->load() >= 0.5f;
fp.reverbRoom = reverbRoomParam->load();
fp.reverbMix = reverbStrengthParam->load();
fp.reverbDiff = reverbDiffusionParam->load();
fp.bpm = bpm;
fx.setParams (fp);
fx.process (buffer, numSamples);
}
void MonostepAudioProcessor::setStepGate (int idx, bool gate)