Prototype

This commit is contained in:
Armin 2026-08-05 23:12:17 +02:00
commit 4271fc34bb
14 changed files with 950 additions and 169 deletions

View file

@ -8,30 +8,35 @@ static const char* paramId (int index)
{
static const char* ids[] =
{
"osc1Wave", "osc2Wave", "detune", "mix",
"osc1Wave", "osc2Wave", "osc1Coarse", "osc2Coarse", "detune", "mix",
"cutoff", "res", "attack", "decay", "sustain", "release", "glide", "master",
"seqLen", "seqRate", "seqRoot", "seqOctave", "seqSwing", "seqGateLen"
"seqLen", "seqRate", "seqRoot", "seqOctave", "seqSwing", "seqGateLen",
"drive", "ringmod", "accent", "fine1"
};
return ids[index];
}
enum ParamIndex
{
pOsc1Wave, pOsc2Wave, pDetune, pMix,
pOsc1Wave, pOsc2Wave, pOsc1Coarse, pOsc2Coarse, pDetune, pMix,
pCutoff, pRes, pAttack, pDecay, pSustain, pRelease, pGlide, pMaster,
pSeqLen, pSeqRate, pSeqRoot, pSeqOctave, pSeqSwing, pSeqGateLen,
pDrive, pRingMod, pAccent, pFine1,
numParams
};
MonoStepAudioProcessor::MonoStepAudioProcessor()
MonostepAudioProcessor::MonostepAudioProcessor()
: AudioProcessor (BusesProperties()
.withOutput ("Output", juce::AudioChannelSet::stereo(), true))
, apvts (*this, nullptr, "PARAMS", createParameterLayout())
{
osc1WaveParam = apvts.getRawParameterValue (paramId (pOsc1Wave));
osc2WaveParam = apvts.getRawParameterValue (paramId (pOsc2Wave));
osc1CoarseParam = apvts.getRawParameterValue (paramId (pOsc1Coarse));
osc2CoarseParam = apvts.getRawParameterValue (paramId (pOsc2Coarse));
detuneParam = apvts.getRawParameterValue (paramId (pDetune));
mixParam = apvts.getRawParameterValue (paramId (pMix));
osc1PhaseParam = apvts.getRawParameterValue (paramId (pFine1));
cutoffParam = apvts.getRawParameterValue (paramId (pCutoff));
resParam = apvts.getRawParameterValue (paramId (pRes));
attackParam = apvts.getRawParameterValue (paramId (pAttack));
@ -46,16 +51,22 @@ MonoStepAudioProcessor::MonoStepAudioProcessor()
seqOctaveParam = apvts.getRawParameterValue (paramId (pSeqOctave));
seqSwingParam = apvts.getRawParameterValue (paramId (pSeqSwing));
seqGateLenParam = apvts.getRawParameterValue (paramId (pSeqGateLen));
driveParam = apvts.getRawParameterValue (paramId (pDrive));
ringModParam = apvts.getRawParameterValue (paramId (pRingMod));
accentParam = apvts.getRawParameterValue (paramId (pAccent));
setDefaultPattern();
}
juce::AudioProcessorValueTreeState::ParameterLayout MonoStepAudioProcessor::createParameterLayout()
juce::AudioProcessorValueTreeState::ParameterLayout MonostepAudioProcessor::createParameterLayout()
{
juce::AudioProcessorValueTreeState::ParameterLayout layout;
layout.add (std::make_unique<juce::AudioParameterInt> (paramId (pOsc1Wave), "Osc 1 Wave", 0, 3, 2));
layout.add (std::make_unique<juce::AudioParameterInt> (paramId (pOsc2Wave), "Osc 2 Wave", 0, 3, 3));
layout.add (std::make_unique<juce::AudioParameterInt> (paramId (pOsc1Wave), "Osc 1 Wave", 0, 7, 2));
layout.add (std::make_unique<juce::AudioParameterInt> (paramId (pOsc2Wave), "Osc 2 Wave", 0, 7, 3));
layout.add (std::make_unique<juce::AudioParameterInt> (paramId (pOsc1Coarse), "Osc 1 Coarse", -12, 12, 0));
layout.add (std::make_unique<juce::AudioParameterInt> (paramId (pOsc2Coarse), "Osc 2 Coarse", -12, 12, 0));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pDetune),
"Osc 2 Detune", juce::NormalisableRange<float> (-100.0f, 100.0f), 0.0f,
@ -64,6 +75,10 @@ juce::AudioProcessorValueTreeState::ParameterLayout MonoStepAudioProcessor::crea
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pMix),
"Osc Mix", juce::NormalisableRange<float> (0.0f, 1.0f), 0.5f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pFine1),
"Phase Offset", juce::NormalisableRange<float> (-1.0f, 1.0f), 0.0f,
juce::AudioParameterFloatAttributes().withLabel ("±1")));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pCutoff),
"Filter Cutoff", juce::NormalisableRange<float> (40.0f, 16000.0f, 0.01f, 0.3f), 7000.0f,
juce::AudioParameterFloatAttributes().withLabel ("Hz")));
@ -109,10 +124,19 @@ juce::AudioProcessorValueTreeState::ParameterLayout MonoStepAudioProcessor::crea
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pSeqGateLen),
"Gate Length", juce::NormalisableRange<float> (0.05f, 1.0f), 0.8f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pDrive),
"Distortion Drive", juce::NormalisableRange<float> (0.0f, 1.0f), 0.0f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pRingMod),
"Ring Mod", juce::NormalisableRange<float> (0.0f, 1.0f), 0.0f));
layout.add (std::make_unique<juce::AudioParameterFloat> (paramId (pAccent),
"Accent", juce::NormalisableRange<float> (0.0f, 1.0f), 0.7f));
return layout;
}
void MonoStepAudioProcessor::setDefaultPattern()
void MonostepAudioProcessor::setDefaultPattern()
{
struct Def { int step; bool gate; int semitone; bool slide; };
const Def defs[] =
@ -136,9 +160,199 @@ void MonoStepAudioProcessor::setDefaultPattern()
sequencer.step (d.step).semitone = d.semitone;
sequencer.step (d.step).slide = d.slide;
}
sequencer.step (0).accent = true;
sequencer.step (4).accent = true;
sequencer.step (8).accent = true;
}
void MonoStepAudioProcessor::prepareToPlay (double sr, int samplesPerBlock)
void MonostepAudioProcessor::applyParamValue (const juce::String& id, float value)
{
if (auto* param = apvts.getParameter (id))
{
param->setValueNotifyingHost (param->getNormalisableRange().convertTo0to1 (value));
apvts.getParameterAsValue (id) = value;
}
}
int MonostepAudioProcessor::getNumPresets() const
{
return 18;
}
const char* MonostepAudioProcessor::getPresetName (int index) const
{
static const char* names[] =
{
"Wet Tape",
"Acid Wash",
"Tin Can",
"Bent Toy",
"Neon Arcade",
"Glitch Garden",
"Underwater FM",
"Robo Funk",
"Lo-Fi Noir",
"Spectral Sweep",
"Broken Radio",
"Plasma Organ",
"Glass Bells",
"Warm Pad",
"Pulse Groove",
"Steel Pluck",
"Sub Rumble",
"Tape Bounce"
};
return names[juce::jlimit (0, getNumPresets() - 1, index)];
}
void MonostepAudioProcessor::applyPreset (int index)
{
struct Preset
{
int osc1; int osc2; int coarse; float detune; float mix;
float cutoff; float res; float attack; float decay; float sustain; float release;
float glide; float gateLen; float swing; int rate; int root; int octave;
float drive; float ring; float accent;
};
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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // Tape Bounce
};
const auto& pr = presets[juce::jlimit (0, getNumPresets() - 1, index)];
applyParamValue ("osc1Wave", (float) pr.osc1);
applyParamValue ("osc2Wave", (float) pr.osc2);
applyParamValue ("osc2Coarse", (float) pr.coarse);
applyParamValue ("detune", pr.detune);
applyParamValue ("mix", pr.mix);
applyParamValue ("cutoff", pr.cutoff);
applyParamValue ("res", pr.res);
applyParamValue ("attack", pr.attack);
applyParamValue ("decay", pr.decay);
applyParamValue ("sustain", pr.sustain);
applyParamValue ("release", pr.release);
applyParamValue ("glide", pr.glide);
applyParamValue ("seqGateLen", pr.gateLen);
applyParamValue ("seqSwing", pr.swing);
applyParamValue ("seqRate", (float) pr.rate);
applyParamValue ("seqRoot", (float) pr.root);
applyParamValue ("seqOctave", (float) pr.octave);
applyParamValue ("drive", pr.drive);
applyParamValue ("ringmod", pr.ring);
applyParamValue ("accent", pr.accent);
}
void MonostepAudioProcessor::randomizePattern()
{
const int length = juce::roundToInt (seqLenParam->load());
int filled = 0;
for (int i = 0; i < monostep::numSteps; ++i)
{
auto& s = sequencer.step (i);
if (i >= length)
{
s.gate = false;
continue;
}
const float chance = (i == 0) ? 0.9f : 0.45f;
s.gate = random.nextFloat() < chance;
if (s.gate)
{
++filled;
s.semitone = random.nextInt (monostep::maxSemitone - monostep::minSemitone + 1) + monostep::minSemitone;
s.cents = random.nextFloat() * 100.0f - 50.0f;
s.slide = random.nextFloat() < 0.25f;
s.accent = random.nextFloat() < 0.3f;
}
}
if (filled == 0)
{
auto& s = sequencer.step (random.nextInt (length));
s.gate = true;
s.semitone = 0;
}
if (onPatternChanged)
onPatternChanged();
}
void MonostepAudioProcessor::randomizeOsc()
{
applyParamValue ("osc1Wave", (float) random.nextInt (4));
applyParamValue ("osc2Wave", (float) random.nextInt (4));
applyParamValue ("osc2Coarse", (float) (random.nextInt (25) - 12));
applyParamValue ("detune", (float) (random.nextInt (101) - 50));
applyParamValue ("mix", 0.2f + random.nextFloat() * 0.6f);
}
void MonostepAudioProcessor::randomizeFilter()
{
applyParamValue ("cutoff", 200.0f * std::pow (2.0f, random.nextFloat() * 5.0f));
applyParamValue ("res", random.nextFloat() * 0.8f);
}
void MonostepAudioProcessor::randomizeEnv()
{
applyParamValue ("attack", 0.001f * std::pow (500.0f, random.nextFloat()));
applyParamValue ("decay", 0.05f * std::pow (30.0f, random.nextFloat()));
applyParamValue ("sustain", random.nextFloat());
applyParamValue ("release", 0.05f * std::pow (40.0f, random.nextFloat()));
applyParamValue ("glide", random.nextFloat() * 0.5f);
}
void MonostepAudioProcessor::randomizeSeqSettings()
{
applyParamValue ("seqGateLen", 0.3f + random.nextFloat() * 0.7f);
applyParamValue ("seqSwing", random.nextFloat() * 0.4f);
applyParamValue ("seqRate", (float) random.nextInt (5));
applyParamValue ("seqLen", (float) (random.nextInt (13) + 4));
}
void MonostepAudioProcessor::randomizeFx()
{
applyParamValue ("drive", random.nextFloat());
applyParamValue ("ringmod", random.nextFloat());
}
void MonostepAudioProcessor::randomizeParams()
{
randomizeOsc();
randomizeFilter();
randomizeEnv();
randomizeSeqSettings();
randomizeFx();
}
void MonostepAudioProcessor::prepareToPlay (double sr, int samplesPerBlock)
{
sampleRate = sr;
voice.prepare (sr);
@ -151,17 +365,18 @@ void MonoStepAudioProcessor::prepareToPlay (double sr, int samplesPerBlock)
lastHostPpq = -1.0;
}
void MonoStepAudioProcessor::releaseResources()
void MonostepAudioProcessor::releaseResources()
{
voice.reset();
}
void MonoStepAudioProcessor::updateVoiceParams()
void MonostepAudioProcessor::updateVoiceParams()
{
monostep::SynthVoice::Params p;
p.waveA = (monostep::Waveform) (int) osc1WaveParam->load();
p.waveB = (monostep::Waveform) (int) osc2WaveParam->load();
p.detuneRatio = std::pow (2.0f, detuneParam->load() / 1200.0f);
p.detuneRatio = std::pow (2.0f, osc2CoarseParam->load() / 12.0f)
* std::pow (2.0f, detuneParam->load() / 1200.0f);
p.mix = mixParam->load();
p.cutoff = cutoffParam->load();
p.resonance = resParam->load();
@ -171,15 +386,17 @@ void MonoStepAudioProcessor::updateVoiceParams()
p.release = releaseParam->load();
p.glide = glideParam->load();
p.master = masterParam->load();
p.drive = driveParam->load();
p.ringMod = ringModParam->load();
voice.setParams (p);
}
float MonoStepAudioProcessor::midiToFreq (float note) const
float MonostepAudioProcessor::midiToFreq (float note) const
{
return 440.0f * std::pow (2.0f, (note - 69.0f) / 12.0f);
}
void MonoStepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
void MonostepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
juce::ScopedNoDenormals noDenormals;
@ -265,8 +482,12 @@ void MonoStepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
}
else
{
if (lastGateApplied)
voice.noteOff();
lastStep = -1;
lastGateApplied = false;
lastFreqApplied = -1.0f;
playStep.store (-1);
}
@ -277,6 +498,7 @@ void MonoStepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
bool seqGate = false;
float seqFreq = 0.0f;
bool seqSlide = false;
bool seqAccent = false;
if (midiHeld)
{
@ -307,10 +529,21 @@ void MonoStepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
const auto& s = sequencer.step (stepIdx);
seqSlide = s.slide;
seqAccent = s.accent;
// A step whose successor slides keeps its gate open until the next
// step so the glide into it is seamless; otherwise the gate closes
// after gateLen of the step.
const int nextIdx = (stepIdx + 1) % seqLen;
const bool slideIntoNext = sequencer.step (nextIdx).slide;
const float nextStart = (stepIdx + 1) * stepLen
+ (((stepIdx + 1) % 2) ? swing * stepLen : 0.0f);
// gate length: the step's note sustains for gateLen of the step
const float ppqWithinStep = ppqInCycle - stepStart;
seqGate = s.gate && (ppqWithinStep < stepLen * gateLen);
const float gateClose = slideIntoNext ? (nextStart - stepStart)
: stepLen * gateLen;
seqGate = s.gate && (ppqWithinStep < gateClose);
if (seqGate)
{
@ -332,6 +565,10 @@ void MonoStepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
wantLegato = seqSlide;
}
// 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);
if (wantGate != lastGateApplied)
{
if (wantGate)
@ -357,7 +594,7 @@ void MonoStepAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juc
buffer.addFrom (ch, 0, scratch, 0, 0, numSamples);
}
void MonoStepAudioProcessor::setStepGate (int idx, bool gate)
void MonostepAudioProcessor::setStepGate (int idx, bool gate)
{
if (idx < 0 || idx >= monostep::numSteps)
return;
@ -368,7 +605,7 @@ void MonoStepAudioProcessor::setStepGate (int idx, bool gate)
onPatternChanged();
}
void MonoStepAudioProcessor::setStepNote (int idx, int semitone)
void MonostepAudioProcessor::setStepNote (int idx, int semitone)
{
if (idx < 0 || idx >= monostep::numSteps)
return;
@ -379,7 +616,7 @@ void MonoStepAudioProcessor::setStepNote (int idx, int semitone)
onPatternChanged();
}
void MonoStepAudioProcessor::setStepCents (int idx, float cents)
void MonostepAudioProcessor::setStepCents (int idx, float cents)
{
if (idx < 0 || idx >= monostep::numSteps)
return;
@ -390,7 +627,7 @@ void MonoStepAudioProcessor::setStepCents (int idx, float cents)
onPatternChanged();
}
void MonoStepAudioProcessor::setStepSlide (int idx, bool slide)
void MonostepAudioProcessor::setStepSlide (int idx, bool slide)
{
if (idx < 0 || idx >= monostep::numSteps)
return;
@ -401,7 +638,26 @@ void MonoStepAudioProcessor::setStepSlide (int idx, bool slide)
onPatternChanged();
}
juce::String MonoStepAudioProcessor::getStepNoteName (int idx) const
void MonostepAudioProcessor::setStepAccent (int idx, bool accent)
{
if (idx < 0 || idx >= monostep::numSteps)
return;
sequencer.step (idx).accent = accent;
if (onPatternChanged)
onPatternChanged();
}
void MonostepAudioProcessor::shiftPattern (int dir)
{
sequencer.shift (dir);
if (onPatternChanged)
onPatternChanged();
}
juce::String MonostepAudioProcessor::getStepNoteName (int idx) const
{
const int root = juce::roundToInt (seqRootParam->load());
const int octave = juce::roundToInt (seqOctaveParam->load()) - 2;
@ -414,12 +670,13 @@ juce::String MonoStepAudioProcessor::getStepNoteName (int idx) const
return juce::MidiMessage::getMidiNoteName (note, true, true, 3);
}
void MonoStepAudioProcessor::storeSequence (juce::ValueTree& seq) const
void MonostepAudioProcessor::storeSequence (juce::ValueTree& seq) const
{
juce::String gates;
juce::String notes;
juce::String cents;
juce::String slides;
juce::String accents;
for (int i = 0; i < monostep::numSteps; ++i)
{
@ -429,15 +686,17 @@ void MonoStepAudioProcessor::storeSequence (juce::ValueTree& seq) const
notes += juce::String (s.semitone) + ",";
cents += juce::String (s.cents, 2) + ",";
slides += s.slide ? "1" : "0";
accents += s.accent ? "1" : "0";
}
seq.setProperty ("gates", gates, nullptr);
seq.setProperty ("notes", notes.dropLastCharacters (1), nullptr);
seq.setProperty ("cents", cents.dropLastCharacters (1), nullptr);
seq.setProperty ("slides", slides, nullptr);
seq.setProperty ("accents", accents, nullptr);
}
void MonoStepAudioProcessor::loadSequence (const juce::ValueTree& seq)
void MonostepAudioProcessor::loadSequence (const juce::ValueTree& seq)
{
const auto splitFloats = [] (const juce::String& text)
{
@ -455,6 +714,7 @@ void MonoStepAudioProcessor::loadSequence (const juce::ValueTree& seq)
const auto notes = splitFloats (seq.getProperty ("notes").toString());
const auto cents = splitFloats (seq.getProperty ("cents").toString());
const auto slides = seq.getProperty ("slides").toString();
const auto accents = seq.getProperty ("accents").toString();
for (int i = 0; i < monostep::numSteps; ++i)
{
@ -471,12 +731,15 @@ void MonoStepAudioProcessor::loadSequence (const juce::ValueTree& seq)
if (i < slides.length())
s.slide = slides[i] == '1';
if (i < accents.length())
s.accent = accents[i] == '1';
}
}
void MonoStepAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
void MonostepAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
juce::ValueTree state = apvts.state.createCopy();
juce::ValueTree state = apvts.copyState();
juce::ValueTree seq = state.getOrCreateChildWithName ("SEQ", nullptr);
storeSequence (seq);
@ -484,7 +747,7 @@ void MonoStepAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
copyXmlToBinary (*xml, destData);
}
void MonoStepAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
void MonostepAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
std::unique_ptr<juce::XmlElement> xml (juce::AudioProcessor::getXmlFromBinary (data, sizeInBytes));
@ -501,10 +764,10 @@ void MonoStepAudioProcessor::setStateInformation (const void* data, int sizeInBy
onPatternChanged();
}
juce::AudioProcessorEditor* MonoStepAudioProcessor::createEditor()
juce::AudioProcessorEditor* MonostepAudioProcessor::createEditor()
{
#ifndef MONOSTEP_HEADLESS
return new MonoStepAudioProcessorEditor (*this);
return new MonostepAudioProcessorEditor (*this);
#else
return nullptr;
#endif
@ -512,5 +775,5 @@ juce::AudioProcessorEditor* MonoStepAudioProcessor::createEditor()
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
return new MonoStepAudioProcessor();
return new MonostepAudioProcessor();
}