mirror of
https://codeberg.org/armin/monostep.git
synced 2026-09-01 04:10:46 +02:00
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:
parent
342d413563
commit
662a1f7383
11 changed files with 310 additions and 97 deletions
|
|
@ -14,8 +14,8 @@ static const char* paramId (int index)
|
|||
"drive", "ringmod", "accent", "fine1",
|
||||
"filterAttack", "filterDecay", "filterSustain", "filterRelease", "filterEnvAmt",
|
||||
"seqRetrig",
|
||||
"delayTime", "delayStrength", "delaySync",
|
||||
"reverbRoom", "reverbStrength", "reverbDiffusion"
|
||||
"delayTime", "delayStrength", "delaySync", "delayDryWet",
|
||||
"reverbRoom", "reverbStrength", "reverbDiffusion", "reverbDryWet"
|
||||
};
|
||||
return ids[index];
|
||||
}
|
||||
|
|
@ -28,8 +28,8 @@ enum ParamIndex
|
|||
pDrive, pRingMod, pAccent, pFine1,
|
||||
pFilterAttack, pFilterDecay, pFilterSustain, pFilterRelease, pFilterEnvAmt,
|
||||
pSeqRetrig,
|
||||
pDelayTime, pDelayStrength, pDelaySync,
|
||||
pReverbRoom, pReverbStrength, pReverbDiffusion,
|
||||
pDelayTime, pDelayStrength, pDelaySync, pDelayDryWet,
|
||||
pReverbRoom, pReverbStrength, pReverbDiffusion, pReverbDryWet,
|
||||
numParams
|
||||
};
|
||||
|
||||
|
|
@ -72,9 +72,11 @@ MonostepAudioProcessor::MonostepAudioProcessor()
|
|||
delayTimeParam = apvts.getRawParameterValue (paramId (pDelayTime));
|
||||
delayStrengthParam = apvts.getRawParameterValue (paramId (pDelayStrength));
|
||||
delaySyncParam = apvts.getRawParameterValue (paramId (pDelaySync));
|
||||
delayDryWetParam = apvts.getRawParameterValue (paramId (pDelayDryWet));
|
||||
reverbRoomParam = apvts.getRawParameterValue (paramId (pReverbRoom));
|
||||
reverbStrengthParam = apvts.getRawParameterValue (paramId (pReverbStrength));
|
||||
reverbDiffusionParam = apvts.getRawParameterValue (paramId (pReverbDiffusion));
|
||||
reverbDryWetParam = apvts.getRawParameterValue (paramId (pReverbDryWet));
|
||||
|
||||
setDefaultPattern();
|
||||
}
|
||||
|
|
@ -186,20 +188,26 @@ juce::AudioProcessorValueTreeState::ParameterLayout MonostepAudioProcessor::crea
|
|||
"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));
|
||||
"Delay Feedback", juce::NormalisableRange<float> (0.0f, 1.0f), 0.5f));
|
||||
|
||||
layout.add (std::make_unique<juce::AudioParameterBool> (paramId (pDelaySync),
|
||||
"Delay Sync", true));
|
||||
|
||||
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pDelayDryWet),
|
||||
"Delay Dry/Wet", juce::NormalisableRange<float> (0.0f, 1.0f), 0.25f));
|
||||
|
||||
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));
|
||||
"Reverb Strength", juce::NormalisableRange<float> (0.0f, 1.0f), 1.0f));
|
||||
|
||||
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pReverbDiffusion),
|
||||
"Reverb Diffusion", juce::NormalisableRange<float> (0.0f, 1.0f), 0.6f));
|
||||
|
||||
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pReverbDryWet),
|
||||
"Reverb Dry/Wet", juce::NormalisableRange<float> (0.0f, 1.0f), 0.25f));
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
|
@ -283,31 +291,39 @@ void MonostepAudioProcessor::applyPreset (int index)
|
|||
float glide; float gateLen; float swing; int rate; int root; int octave;
|
||||
float drive; float ring; float accent;
|
||||
float fAttack; float fDecay; float fSustain; float fRelease; float fAmt;
|
||||
float delayTime = 0.35f; // only audible when delayWet > 0
|
||||
float delayFeedback = 0.45f;
|
||||
bool delaySync = true;
|
||||
float delayWet = 0.0f;
|
||||
float reverbRoom = 0.5f; // only audible when reverbWet > 0
|
||||
float reverbLevel = 0.6f;
|
||||
float reverbDiff = 0.6f;
|
||||
float reverbWet = 0.0f;
|
||||
};
|
||||
|
||||
static const Preset presets[] =
|
||||
{
|
||||
// --- gritty / glidy -----------------------------------------------------
|
||||
{ 0, 1, 0, 15.0f, 0.60f, 4200.0f, 0.15f, 0.02f, 0.25f, 0.70f, 0.35f, 0.25f, 0.80f, 0.10f, 2, 0, 3, 0.55f, 0.00f, 0.5f, 0.02f, 0.30f, 0.60f, 0.25f, 1.5f }, // Wet Tape
|
||||
{ 0, 1, 0, 15.0f, 0.60f, 4200.0f, 0.15f, 0.02f, 0.25f, 0.70f, 0.35f, 0.25f, 0.80f, 0.10f, 2, 0, 3, 0.55f, 0.00f, 0.5f, 0.02f, 0.30f, 0.60f, 0.25f, 1.5f, 0.21f, 0.55f, true, 0.50f, 0.60f, 0.60f, 0.50f, 0.15f }, // Wet Tape
|
||||
{ 2, 0, -12, -8.0f, 0.45f, 1100.0f, 0.65f, 0.003f, 0.40f, 0.10f, 0.08f, 0.12f, 0.90f, 0.00f, 3, 0, 3, 0.85f, 0.00f, 0.4f, 0.005f, 0.35f, 0.10f, 0.10f, 3.0f }, // Acid Wash
|
||||
{ 3, 3, 0, 5.0f, 0.50f, 380.0f, 0.30f, 0.005f, 0.10f, 0.40f, 0.10f, 0.20f, 0.95f, 0.05f, 3, 0, 3, 0.60f, 0.00f, 0.3f, 0.005f, 0.15f, 0.30f, 0.15f, 0.5f }, // Tin Can
|
||||
{ 0, 3, 7, 25.0f, 0.35f, 2500.0f, 0.20f, 0.04f, 0.20f, 0.30f, 0.60f, 0.45f, 0.85f, 0.25f, 2, 0, 3, 0.40f, 0.00f, 0.5f, 0.03f, 0.25f, 0.50f, 0.40f, 1.0f }, // Bent Toy
|
||||
{ 2, 3, 0, 0.0f, 0.55f, 650.0f, 0.45f, 0.002f, 0.15f, 0.20f, 0.05f, 0.10f, 0.90f, 0.10f, 3, 0, 3, 0.95f, 0.60f, 0.3f, 0.005f, 0.20f, 0.40f, 0.15f, 1.5f }, // Broken Radio
|
||||
{ 1, 2, 0, 20.0f, 0.50f, 6000.0f, 0.10f, 0.003f, 0.15f, 0.80f, 0.20f, 0.10f, 0.90f, 0.15f, 3, 0, 3, 0.20f, 0.00f, 0.6f, 0.01f, 0.30f, 0.70f, 0.30f, 1.0f }, // Neon Arcade
|
||||
{ 0, 1, -12, -35.0f, 0.55f, 1800.0f, 0.40f, 0.10f, 0.35f, 0.20f, 0.80f, 0.50f, 0.70f, 0.20f, 2, 0, 3, 0.00f, 0.00f, 0.5f, 0.01f, 0.40f, 0.50f, 0.20f, -1.5f }, // Glitch Garden
|
||||
{ 2, 2, 5, 10.0f, 0.40f, 3200.0f, 0.35f, 0.002f, 0.20f, 0.60f, 0.12f, 0.15f, 0.95f, 0.40f, 3, 0, 3, 0.70f, 0.20f, 0.5f, 0.01f, 0.25f, 0.60f, 0.20f, 2.0f }, // Robo Funk
|
||||
{ 1, 1, -7, -15.0f, 0.50f, 2600.0f, 0.20f, 0.03f, 0.30f, 0.35f, 0.60f, 0.60f, 0.80f, 0.05f, 2, 0, 3, 0.10f, 0.00f, 0.4f, 0.02f, 0.30f, 0.50f, 0.30f, -0.5f }, // Lo-Fi Noir
|
||||
{ 1, 2, 0, 20.0f, 0.50f, 6000.0f, 0.10f, 0.003f, 0.15f, 0.80f, 0.20f, 0.10f, 0.90f, 0.15f, 3, 0, 3, 0.20f, 0.00f, 0.6f, 0.01f, 0.30f, 0.70f, 0.30f, 1.0f, 0.50f, 0.45f, true, 0.30f, 0.50f, 0.50f, 0.60f, 0.30f }, // Neon Arcade
|
||||
{ 0, 1, -12, -35.0f, 0.55f, 1800.0f, 0.40f, 0.10f, 0.35f, 0.20f, 0.80f, 0.50f, 0.70f, 0.20f, 2, 0, 3, 0.00f, 0.00f, 0.5f, 0.01f, 0.40f, 0.50f, 0.20f, -1.5f, 0.36f, 0.70f, true, 0.50f, 0.50f, 0.60f, 0.60f, 0.00f }, // Glitch Garden
|
||||
{ 2, 2, 5, 10.0f, 0.40f, 3200.0f, 0.35f, 0.002f, 0.20f, 0.60f, 0.12f, 0.15f, 0.95f, 0.40f, 3, 0, 3, 0.70f, 0.20f, 0.5f, 0.01f, 0.25f, 0.60f, 0.20f, 2.0f, 0.36f, 0.50f, true, 0.40f, 0.50f, 0.60f, 0.60f, 0.00f }, // Robo Funk
|
||||
{ 1, 1, -7, -15.0f, 0.50f, 2600.0f, 0.20f, 0.03f, 0.30f, 0.35f, 0.60f, 0.60f, 0.80f, 0.05f, 2, 0, 3, 0.10f, 0.00f, 0.4f, 0.02f, 0.30f, 0.50f, 0.30f, -0.5f, 0.21f, 0.40f, true, 0.20f, 0.60f, 0.50f, 0.50f, 0.25f }, // Lo-Fi Noir
|
||||
{ 0, 2, 0, 8.0f, 0.60f, 7000.0f, 0.08f, 0.01f, 0.20f, 0.90f, 0.25f, 0.30f, 0.75f, 0.00f, 3, 0, 3, 0.35f, 0.35f, 0.6f, 0.01f, 0.30f, 0.20f, 0.30f, 3.5f }, // Spectral Sweep
|
||||
{ 3, 0, -12, 12.0f, 0.45f, 5000.0f, 0.25f, 0.02f, 0.50f, 0.70f, 0.30f, 0.40f, 0.60f, 0.20f, 2, 0, 3, 0.30f, 0.15f, 0.5f, 0.02f, 0.40f, 0.80f, 0.30f, 0.5f }, // Plasma Organ
|
||||
{ 0, 0, 0, 0.0f, 0.50f, 900.0f, 0.50f, 0.05f, 0.30f, 0.50f, 0.50f, 0.35f, 0.85f, 0.30f, 2, 0, 3, 0.25f, 0.55f, 0.3f, 0.05f, 0.30f, 0.50f, 0.40f, -2.0f }, // Underwater FM
|
||||
{ 3, 0, -12, 12.0f, 0.45f, 5000.0f, 0.25f, 0.02f, 0.50f, 0.70f, 0.30f, 0.40f, 0.60f, 0.20f, 2, 0, 3, 0.30f, 0.15f, 0.5f, 0.02f, 0.40f, 0.80f, 0.30f, 0.5f, 0.35f, 0.45f, true, 0.00f, 0.70f, 0.80f, 0.70f, 0.40f }, // Plasma Organ
|
||||
{ 0, 0, 0, 0.0f, 0.50f, 900.0f, 0.50f, 0.05f, 0.30f, 0.50f, 0.50f, 0.35f, 0.85f, 0.30f, 2, 0, 3, 0.25f, 0.55f, 0.3f, 0.05f, 0.30f, 0.50f, 0.40f, -2.0f, 0.64f, 0.50f, true, 0.35f, 0.90f, 0.70f, 0.90f, 0.35f }, // Underwater FM
|
||||
|
||||
// --- clean / no glide / no drive ---------------------------------------
|
||||
{ 0, 0, 0, 0.0f, 0.50f, 7000.0f, 0.10f, 0.002f, 0.25f, 0.20f, 0.30f, 0.00f, 0.35f, 0.00f, 3, 0, 4, 0.00f, 0.00f, 0.6f, 0.005f, 0.20f, 0.30f, 0.40f, 0.3f }, // Glass Bells
|
||||
{ 1, 1, 0, 12.0f, 0.60f, 1200.0f, 0.25f, 0.30f, 1.20f, 0.80f, 1.50f, 0.20f, 1.00f, 0.10f, 2, 0, 2, 0.00f, 0.00f, 0.2f, 0.50f, 1.00f, 0.70f, 1.20f, 1.0f }, // Warm Pad
|
||||
{ 1, 1, 0, 12.0f, 0.60f, 1200.0f, 0.25f, 0.30f, 1.20f, 0.80f, 1.50f, 0.20f, 1.00f, 0.10f, 2, 0, 2, 0.00f, 0.00f, 0.2f, 0.50f, 1.00f, 0.70f, 1.20f, 1.0f, 0.35f, 0.45f, true, 0.00f, 0.80f, 0.90f, 0.80f, 0.45f }, // Warm Pad
|
||||
{ 2, 2, 0, 5.0f, 0.50f, 2500.0f, 0.15f, 0.002f, 0.20f, 0.30f, 0.12f, 0.00f, 0.50f, 0.30f, 3, 0, 3, 0.00f, 0.00f, 0.5f, 0.01f, 0.25f, 0.40f, 0.20f, 1.5f }, // Pulse Groove
|
||||
{ 0, 3, 12, 0.0f, 0.40f, 1500.0f, 0.60f, 0.001f, 0.35f, 0.15f, 0.20f, 0.00f, 0.45f, 0.00f, 3, 0, 4, 0.00f, 0.35f, 0.7f, 0.002f, 0.30f, 0.20f, 0.25f, 2.5f }, // Steel Pluck
|
||||
{ 0, 0, 0, -5.0f, 0.40f, 500.0f, 0.20f, 0.01f, 0.40f, 0.90f, 0.30f, 0.00f, 0.90f, 0.00f, 2, 0, 1, 0.00f, 0.00f, 0.3f, 0.01f, 0.30f, 0.60f, 0.30f, -1.0f }, // Sub Rumble
|
||||
{ 1, 0, 0, 8.0f, 0.55f, 3000.0f, 0.20f, 0.005f, 0.30f, 0.60f, 0.25f, 0.30f, 0.70f, 0.15f, 2, 0, 3, 0.25f, 0.00f, 0.5f, 0.01f, 0.30f, 0.50f, 0.30f, 1.0f }, // Tape Bounce
|
||||
{ 1, 0, 0, 8.0f, 0.55f, 3000.0f, 0.20f, 0.005f, 0.30f, 0.60f, 0.25f, 0.30f, 0.70f, 0.15f, 2, 0, 3, 0.25f, 0.00f, 0.5f, 0.01f, 0.30f, 0.50f, 0.30f, 1.0f, 0.64f, 0.60f, true, 0.45f, 0.50f, 0.50f, 0.50f, 0.20f }, // Tape Bounce
|
||||
};
|
||||
|
||||
const auto& pr = presets[juce::jlimit (0, getNumPresets() - 1, index)];
|
||||
|
|
@ -337,6 +353,15 @@ void MonostepAudioProcessor::applyPreset (int index)
|
|||
applyParamValue ("filterSustain", pr.fSustain);
|
||||
applyParamValue ("filterRelease", pr.fRelease);
|
||||
applyParamValue ("filterEnvAmt", pr.fAmt);
|
||||
|
||||
applyParamValue ("delayTime", pr.delayTime);
|
||||
applyParamValue ("delayStrength", pr.delayFeedback);
|
||||
applyParamValue ("delaySync", pr.delaySync ? 1.0f : 0.0f);
|
||||
applyParamValue ("delayDryWet", pr.delayWet);
|
||||
applyParamValue ("reverbRoom", pr.reverbRoom);
|
||||
applyParamValue ("reverbStrength", pr.reverbLevel);
|
||||
applyParamValue ("reverbDiffusion", pr.reverbDiff);
|
||||
applyParamValue ("reverbDryWet", pr.reverbWet);
|
||||
}
|
||||
|
||||
void MonostepAudioProcessor::randomizePattern()
|
||||
|
|
@ -420,11 +445,66 @@ void MonostepAudioProcessor::randomizeFx()
|
|||
applyParamValue ("drive", random.nextFloat());
|
||||
applyParamValue ("ringmod", random.nextFloat());
|
||||
applyParamValue ("delayTime", random.nextFloat());
|
||||
applyParamValue ("delayStrength", random.nextFloat() * 0.8f);
|
||||
applyParamValue ("delayStrength", random.nextFloat() * 0.9f);
|
||||
applyParamValue ("delaySync", random.nextFloat() < 0.8f ? 1.0f : 0.0f);
|
||||
applyParamValue ("delayDryWet", random.nextFloat() * 0.8f);
|
||||
applyParamValue ("reverbRoom", 0.2f + random.nextFloat() * 0.7f);
|
||||
applyParamValue ("reverbStrength", random.nextFloat() * 0.7f);
|
||||
applyParamValue ("reverbStrength", random.nextFloat());
|
||||
applyParamValue ("reverbDiffusion", random.nextFloat());
|
||||
applyParamValue ("reverbDryWet", random.nextFloat() * 0.8f);
|
||||
}
|
||||
|
||||
void MonostepAudioProcessor::randomizeAccent()
|
||||
{
|
||||
const int length = juce::roundToInt (seqLenParam->load());
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
auto& s = sequencer.step (i);
|
||||
if (! s.gate)
|
||||
continue;
|
||||
s.accent = random.nextFloat() < 0.3f;
|
||||
}
|
||||
|
||||
if (onPatternChanged)
|
||||
onPatternChanged();
|
||||
}
|
||||
|
||||
void MonostepAudioProcessor::randomizeSlide()
|
||||
{
|
||||
const int length = juce::roundToInt (seqLenParam->load());
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
auto& s = sequencer.step (i);
|
||||
if (! s.gate)
|
||||
continue;
|
||||
s.slide = random.nextFloat() < 0.25f;
|
||||
}
|
||||
|
||||
if (onPatternChanged)
|
||||
onPatternChanged();
|
||||
}
|
||||
|
||||
void MonostepAudioProcessor::randomizeFine()
|
||||
{
|
||||
const int length = juce::roundToInt (seqLenParam->load());
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
auto& s = sequencer.step (i);
|
||||
if (! s.gate)
|
||||
continue;
|
||||
s.cents = random.nextFloat() * 100.0f - 50.0f;
|
||||
}
|
||||
|
||||
if (onPatternChanged)
|
||||
onPatternChanged();
|
||||
}
|
||||
|
||||
void MonostepAudioProcessor::randomizeRate()
|
||||
{
|
||||
applyParamValue ("seqRate", (float) random.nextInt (5));
|
||||
}
|
||||
|
||||
void MonostepAudioProcessor::randomizeParams()
|
||||
|
|
@ -686,8 +766,9 @@ void MonostepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
|
|||
}
|
||||
|
||||
// Accent tracks the current step (not just gate changes), so it holds for
|
||||
// the whole step even when the note repeats without retriggering.
|
||||
voice.setAccentLevel (seqAccent ? 1.0f + accentParam->load() * 4.0f : 1.0f);
|
||||
// the whole step even when the note repeats without retriggering. Kept
|
||||
// gentle: a modest volume lift plus a bit of brightness/timing (below).
|
||||
voice.setAccentLevel (seqAccent ? 1.0f + accentParam->load() * 0.4f : 1.0f);
|
||||
|
||||
if (wantGate != lastGateApplied)
|
||||
{
|
||||
|
|
@ -714,13 +795,15 @@ void MonostepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
|
|||
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;
|
||||
fp.delayTime = delayTimeParam->load();
|
||||
fp.delayFeedback = delayStrengthParam->load();
|
||||
fp.delaySync = delaySyncParam->load() >= 0.5f;
|
||||
fp.delayMix = delayDryWetParam->load();
|
||||
fp.reverbRoom = reverbRoomParam->load();
|
||||
fp.reverbLevel = reverbStrengthParam->load();
|
||||
fp.reverbMix = reverbDryWetParam->load();
|
||||
fp.reverbDiff = reverbDiffusionParam->load();
|
||||
fp.bpm = bpm;
|
||||
fx.setParams (fp);
|
||||
fx.process (buffer, numSamples);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue