927 lines
43 KiB
C++
927 lines
43 KiB
C++
#include "PluginProcessor.h"
|
|
#include "PluginEditor.h"
|
|
#include "WavetableOsc.h"
|
|
#include <array>
|
|
#include <map>
|
|
|
|
//==============================================================================
|
|
NeuralSynthAudioProcessor::NeuralSynthAudioProcessor()
|
|
: parameters(*this, nullptr, "PARAMETERS", createParameterLayout())
|
|
, AudioProcessor(BusesProperties().withOutput("Output", juce::AudioChannelSet::stereo(), true))
|
|
, audioEngine(sp)
|
|
, factoryPresets(makeFactoryPresets())
|
|
{
|
|
parameters.addParameterListener("wt_phase", this);
|
|
parameters.addParameterListener("wt_on", this);
|
|
parameters.addParameterListener("wt_morph", this);
|
|
parameters.addParameterListener("wt_bank", this);
|
|
parameters.addParameterListener("wt_lfoRate", this);
|
|
parameters.addParameterListener("wt_lfoDepth", this);
|
|
parameters.addParameterListener("wt_lfoShape", this);
|
|
parameters.addParameterListener("wt_level", this);
|
|
|
|
parameters.addParameterListener("wt2_phase", this);
|
|
parameters.addParameterListener("wt2_on", this);
|
|
parameters.addParameterListener("wt2_morph", this);
|
|
parameters.addParameterListener("wt2_bank", this);
|
|
parameters.addParameterListener("wt2_lfoRate", this);
|
|
parameters.addParameterListener("wt2_lfoDepth", this);
|
|
parameters.addParameterListener("wt2_lfoShape", this);
|
|
parameters.addParameterListener("wt2_level", this);
|
|
|
|
sp.wtPhase = parameters.getRawParameterValue("wt_phase");
|
|
sp.wtOn = parameters.getRawParameterValue("wt_on");
|
|
sp.wtMorph = parameters.getRawParameterValue("wt_morph");
|
|
sp.wtBank = parameters.getRawParameterValue("wt_bank");
|
|
sp.wtLfoRate = parameters.getRawParameterValue("wt_lfoRate");
|
|
sp.wtLfoDepth= parameters.getRawParameterValue("wt_lfoDepth");
|
|
sp.wtLfoShape= parameters.getRawParameterValue("wt_lfoShape");
|
|
sp.wtLevel = parameters.getRawParameterValue("wt_level");
|
|
|
|
sp.wt2Phase = parameters.getRawParameterValue("wt2_phase");
|
|
sp.wt2On = parameters.getRawParameterValue("wt2_on");
|
|
sp.wt2Morph = parameters.getRawParameterValue("wt2_morph");
|
|
sp.wt2Bank = parameters.getRawParameterValue("wt2_bank");
|
|
sp.wt2LfoRate= parameters.getRawParameterValue("wt2_lfoRate");
|
|
sp.wt2LfoDepth= parameters.getRawParameterValue("wt2_lfoDepth");
|
|
sp.wt2LfoShape= parameters.getRawParameterValue("wt2_lfoShape");
|
|
sp.wt2Level = parameters.getRawParameterValue("wt2_level");
|
|
|
|
if (! factoryPresets.empty())
|
|
applyPreset(0);
|
|
|
|
// === Per-panel bypass (default OFF) ===
|
|
sp.chorusOn = parameters.getRawParameterValue("chorus_on");
|
|
sp.delayOn = parameters.getRawParameterValue("delay_on");
|
|
sp.reverbOn = parameters.getRawParameterValue("reverb_on");
|
|
sp.flangerOn = parameters.getRawParameterValue("flanger_on");
|
|
sp.distortionOn = parameters.getRawParameterValue("distortion_on");
|
|
sp.filterOn = parameters.getRawParameterValue("filter_on");
|
|
sp.eqOn = parameters.getRawParameterValue("eq_on");
|
|
|
|
// === Chorus ===
|
|
parameters.addParameterListener("chorus_rate", this);
|
|
parameters.addParameterListener("chorus_depth", this);
|
|
parameters.addParameterListener("chorus_centre", this);
|
|
parameters.addParameterListener("chorus_feedback", this);
|
|
parameters.addParameterListener("chorus_mix", this);
|
|
|
|
sp.chorusRate = parameters.getRawParameterValue("chorus_rate");
|
|
sp.chorusDepth = parameters.getRawParameterValue("chorus_depth");
|
|
sp.chorusCentre = parameters.getRawParameterValue("chorus_centre");
|
|
sp.chorusFeedback = parameters.getRawParameterValue("chorus_feedback");
|
|
sp.chorusMix = parameters.getRawParameterValue("chorus_mix");
|
|
|
|
// === Delay ===
|
|
parameters.addParameterListener("delay_delay", this);
|
|
sp.delayTime = parameters.getRawParameterValue("delay_delay");
|
|
|
|
// === Reverb ===
|
|
parameters.addParameterListener("reverb_roomSize", this);
|
|
parameters.addParameterListener("reverb_damping", this);
|
|
parameters.addParameterListener("reverb_wetLevel", this);
|
|
parameters.addParameterListener("reverb_dryLevel", this);
|
|
parameters.addParameterListener("reverb_width", this);
|
|
parameters.addParameterListener("reverb_freezeMode", this);
|
|
|
|
sp.reverbRoomSize = parameters.getRawParameterValue("reverb_roomSize");
|
|
sp.reverbDamping = parameters.getRawParameterValue("reverb_damping");
|
|
sp.reverbWetLevel = parameters.getRawParameterValue("reverb_wetLevel");
|
|
sp.reverbDryLevel = parameters.getRawParameterValue("reverb_dryLevel");
|
|
sp.reverbWidth = parameters.getRawParameterValue("reverb_width");
|
|
sp.reverbFreezeMode= parameters.getRawParameterValue("reverb_freezeMode");
|
|
|
|
// === Amp ADSR ===
|
|
parameters.addParameterListener("adsr_attack", this);
|
|
parameters.addParameterListener("adsr_decay", this);
|
|
parameters.addParameterListener("adsr_sustain", this);
|
|
parameters.addParameterListener("adsr_release", this);
|
|
|
|
sp.adsrAttack = parameters.getRawParameterValue("adsr_attack");
|
|
sp.adsrDecay = parameters.getRawParameterValue("adsr_decay");
|
|
sp.adsrSustain = parameters.getRawParameterValue("adsr_sustain");
|
|
sp.adsrRelease = parameters.getRawParameterValue("adsr_release");
|
|
|
|
// === Filter Env ===
|
|
parameters.addParameterListener("fenv_attack", this);
|
|
parameters.addParameterListener("fenv_decay", this);
|
|
parameters.addParameterListener("fenv_sustain", this);
|
|
parameters.addParameterListener("fenv_release", this);
|
|
parameters.addParameterListener("fenv_amount", this);
|
|
|
|
sp.fenvAttack = parameters.getRawParameterValue("fenv_attack");
|
|
sp.fenvDecay = parameters.getRawParameterValue("fenv_decay");
|
|
sp.fenvSustain = parameters.getRawParameterValue("fenv_sustain");
|
|
sp.fenvRelease = parameters.getRawParameterValue("fenv_release");
|
|
sp.fenvAmount = parameters.getRawParameterValue("fenv_amount");
|
|
|
|
// === Filter base ===
|
|
parameters.addParameterListener("filter_cutoff", this);
|
|
parameters.addParameterListener("filter_resonance", this);
|
|
parameters.addParameterListener("filter_type", this);
|
|
parameters.addParameterListener("filter_drive", this);
|
|
parameters.addParameterListener("filter_mod", this);
|
|
parameters.addParameterListener("filter_key", this);
|
|
|
|
sp.filterCutoff = parameters.getRawParameterValue("filter_cutoff");
|
|
sp.filterResonance = parameters.getRawParameterValue("filter_resonance");
|
|
sp.filterType = parameters.getRawParameterValue("filter_type");
|
|
sp.filterDrive = parameters.getRawParameterValue("filter_drive");
|
|
sp.filterMod = parameters.getRawParameterValue("filter_mod");
|
|
sp.filterKey = parameters.getRawParameterValue("filter_key");
|
|
|
|
// === Distortion ===
|
|
parameters.addParameterListener("distortion_drive", this);
|
|
parameters.addParameterListener("distortion_mix", this);
|
|
parameters.addParameterListener("distortion_bias", this);
|
|
parameters.addParameterListener("distortion_tone", this);
|
|
parameters.addParameterListener("distortion_shape", this);
|
|
|
|
sp.distortionDrive = parameters.getRawParameterValue("distortion_drive");
|
|
sp.distortionMix = parameters.getRawParameterValue("distortion_mix");
|
|
sp.distortionBias = parameters.getRawParameterValue("distortion_bias");
|
|
sp.distortionTone = parameters.getRawParameterValue("distortion_tone");
|
|
sp.distortionShape = parameters.getRawParameterValue("distortion_shape");
|
|
|
|
// === Master / EQ ===
|
|
parameters.addParameterListener("master", this);
|
|
parameters.addParameterListener("lowEQ", this);
|
|
parameters.addParameterListener("midEQ", this);
|
|
parameters.addParameterListener("highEQ", this);
|
|
|
|
sp.masterDbls = parameters.getRawParameterValue("master");
|
|
sp.lowGainDbls = parameters.getRawParameterValue("lowEQ");
|
|
sp.midGainDbls = parameters.getRawParameterValue("midEQ");
|
|
sp.highGainDbls = parameters.getRawParameterValue("highEQ");
|
|
}
|
|
|
|
NeuralSynthAudioProcessor::~NeuralSynthAudioProcessor() = default;
|
|
|
|
//==============================================================================
|
|
const juce::String NeuralSynthAudioProcessor::getName() const { return JucePlugin_Name; }
|
|
|
|
bool NeuralSynthAudioProcessor::acceptsMidi() const
|
|
{
|
|
#if JucePlugin_WantsMidiInput
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool NeuralSynthAudioProcessor::producesMidi() const
|
|
{
|
|
#if JucePlugin_ProducesMidiOutput
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool NeuralSynthAudioProcessor::isMidiEffect() const
|
|
{
|
|
#if JucePlugin_IsMidiEffect
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
double NeuralSynthAudioProcessor::getTailLengthSeconds() const { return 0.0; }
|
|
|
|
int NeuralSynthAudioProcessor::getNumPrograms() { return 1; }
|
|
int NeuralSynthAudioProcessor::getCurrentProgram() { return 0; }
|
|
void NeuralSynthAudioProcessor::setCurrentProgram (int) {}
|
|
const juce::String NeuralSynthAudioProcessor::getProgramName (int) { return {}; }
|
|
void NeuralSynthAudioProcessor::changeProgramName (int, const juce::String&) {}
|
|
|
|
//==============================================================================
|
|
void NeuralSynthAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
|
|
{
|
|
audioEngine.prepare({ sampleRate, (juce::uint32)samplesPerBlock, 2 });
|
|
const auto numChannels = (juce::uint32) juce::jmax (1, getTotalNumOutputChannels());
|
|
juce::dsp::ProcessSpec limiterSpec { sampleRate, (juce::uint32) samplesPerBlock, numChannels };
|
|
outputLimiter.reset();
|
|
outputLimiter.prepare (limiterSpec);
|
|
outputLimiter.setThreshold (-0.8f);
|
|
outputLimiter.setRelease (0.05f);
|
|
midiMessageCollector.reset(sampleRate);
|
|
}
|
|
|
|
void NeuralSynthAudioProcessor::releaseResources() {}
|
|
|
|
bool NeuralSynthAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const
|
|
{
|
|
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
|
|
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void NeuralSynthAudioProcessor::processBlock(juce::AudioSampleBuffer& buffer, juce::MidiBuffer& midiMessages)
|
|
{
|
|
juce::ScopedNoDenormals noDenormals;
|
|
auto totalNumInputChannels = getTotalNumInputChannels();
|
|
auto totalNumOutputChannels = getTotalNumOutputChannels();
|
|
|
|
midiMessageCollector.removeNextBlockOfMessages(midiMessages, buffer.getNumSamples());
|
|
|
|
for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
|
|
buffer.clear(i, 0, buffer.getNumSamples());
|
|
|
|
audioEngine.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
|
|
juce::dsp::AudioBlock<float> outputBlock (buffer);
|
|
outputLimiter.process (juce::dsp::ProcessContextReplacing<float> (outputBlock));
|
|
scopeDataCollector.process(buffer.getReadPointer(0), (size_t)buffer.getNumSamples());
|
|
}
|
|
|
|
//==============================================================================
|
|
bool NeuralSynthAudioProcessor::hasEditor() const { return true; }
|
|
|
|
juce::AudioProcessorEditor* NeuralSynthAudioProcessor::createEditor()
|
|
{
|
|
return new NeuralSynthAudioProcessorEditor (*this);
|
|
}
|
|
|
|
//==============================================================================
|
|
void NeuralSynthAudioProcessor::getStateInformation (juce::MemoryBlock& destData) { juce::ignoreUnused(destData); }
|
|
void NeuralSynthAudioProcessor::setStateInformation (const void* data, int sizeInBytes) { juce::ignoreUnused(data, sizeInBytes); }
|
|
|
|
void NeuralSynthAudioProcessor::parameterChanged(const juce::String& id, float newValue)
|
|
{
|
|
if (id == "wt_bank" && ! presetChangeInProgress)
|
|
{
|
|
const int targetBank = juce::jlimit(0, (int)WT::FactoryLibrary::get().size() - 1,
|
|
(int) std::lround(newValue));
|
|
int matched = -1;
|
|
for (int i = 0; i < (int) factoryPresets.size(); ++i)
|
|
{
|
|
if (factoryPresets[(size_t)i].wtBankIndex == targetBank)
|
|
{
|
|
matched = i;
|
|
break;
|
|
}
|
|
}
|
|
currentPresetIndex = matched;
|
|
}
|
|
else if (id == "wt2_bank" && ! presetChangeInProgress)
|
|
{
|
|
juce::ignoreUnused(newValue);
|
|
currentPresetIndex = -1;
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
// This creates new instances of the plugin..
|
|
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() { return new NeuralSynthAudioProcessor(); }
|
|
|
|
void NeuralSynthAudioProcessor::buildParams(std::vector<std::unique_ptr<juce::RangedAudioParameter>>& params, const std::string& paramGroup) {
|
|
const auto& paramGroupSettings = PARAM_SETTINGS.at(paramGroup);
|
|
|
|
for (const auto& [name, s] : paramGroupSettings) {
|
|
params.push_back(std::make_unique<juce::AudioParameterFloat>(
|
|
paramGroup + "_" + name, s.label,
|
|
juce::NormalisableRange<float>(s.min, s.max, s.interval),
|
|
s.defValue));
|
|
}
|
|
}
|
|
|
|
std::vector<NeuralSynthAudioProcessor::PresetDefinition> NeuralSynthAudioProcessor::makeFactoryPresets()
|
|
{
|
|
std::vector<PresetDefinition> presets;
|
|
const auto& wtLibrary = WT::FactoryLibrary::get();
|
|
if (wtLibrary.empty())
|
|
return presets;
|
|
|
|
presets.reserve(220);
|
|
|
|
std::map<juce::String, std::vector<int>> categoryToIndices;
|
|
for (int i = 0; i < (int) wtLibrary.size(); ++i)
|
|
categoryToIndices[wtLibrary[(size_t) i].category].push_back(i);
|
|
|
|
const std::array<juce::String, 12> requestedCategories = {
|
|
"Electric Piano", "Organ", "Bass", "Drums", "Strings",
|
|
"Brass", "Choir", "Pad", "SFX", "Lead", "Pluck", "Misc"
|
|
};
|
|
|
|
static const std::array<std::pair<int, const char*>, 20> gmDrumInfo = {{
|
|
{35, "Acoustic Bass Drum"},
|
|
{36, "Bass Drum 1"},
|
|
{37, "Side Stick"},
|
|
{38, "Acoustic Snare"},
|
|
{39, "Hand Clap"},
|
|
{40, "Electric Snare"},
|
|
{41, "Low Floor Tom"},
|
|
{42, "Closed Hi-Hat"},
|
|
{43, "High Floor Tom"},
|
|
{44, "Pedal Hi-Hat"},
|
|
{45, "Low Tom"},
|
|
{46, "Open Hi-Hat"},
|
|
{47, "Low-Mid Tom"},
|
|
{48, "Hi-Mid Tom"},
|
|
{49, "Crash Cymbal 1"},
|
|
{50, "High Tom"},
|
|
{51, "Ride Cymbal 1"},
|
|
{52, "Chinese Cymbal"},
|
|
{53, "Ride Bell"},
|
|
{54, "Tambourine"}
|
|
}};
|
|
|
|
auto clampMorph = [](float v) { return juce::jlimit(0.0f, 15.0f, v); };
|
|
auto clampUnit = [](float v) { return juce::jlimit(0.0f, 1.0f, v); };
|
|
auto clampLfoDepth = [](float v) { return juce::jlimit(0.0f, 8.0f, v); };
|
|
auto clampLfoRate = [](float v) { return juce::jlimit(0.01f, 10.0f, v); };
|
|
auto clampCutoff = [](float v) { return juce::jlimit(20.0f, 20000.0f, v); };
|
|
auto clampRes = [](float v) { return juce::jlimit(0.1f, 10.0f, v); };
|
|
auto clampDb = [](float v) { return juce::jlimit(-24.0f, 24.0f, v); };
|
|
|
|
for (const auto& category : requestedCategories)
|
|
{
|
|
auto mapIt = categoryToIndices.find(category);
|
|
if (mapIt == categoryToIndices.end())
|
|
continue;
|
|
|
|
const auto& indices = mapIt->second;
|
|
if (indices.size() < 20)
|
|
continue;
|
|
|
|
for (int variant = 0; variant < 20; ++variant)
|
|
{
|
|
const bool layered = variant >= 10;
|
|
const int primaryIndex = indices[(size_t) (variant % indices.size())];
|
|
const int secondaryIndex = layered ? indices[(size_t) ((variant + 5) % indices.size())]
|
|
: primaryIndex;
|
|
|
|
const float t = (float) variant / 19.0f;
|
|
const float subT = (float) (variant % 10) / 9.0f;
|
|
|
|
const bool isDrumCategory = (category == "Drums");
|
|
std::pair<int, const char*> gmInfo { 0, "" };
|
|
if (isDrumCategory)
|
|
gmInfo = gmDrumInfo[(size_t) variant];
|
|
|
|
std::map<juce::String, float> values;
|
|
auto set = [&](const juce::String& param, float value)
|
|
{
|
|
values[param] = value;
|
|
};
|
|
|
|
set("wt_on", 1.0f);
|
|
set("wt_bank", (float) primaryIndex);
|
|
set("wt_morph", clampMorph(2.0f + 8.0f * t));
|
|
set("wt_phase", 0.0f);
|
|
set("wt_lfoRate", clampLfoRate(0.25f + 0.8f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(0.6f + 2.0f * t));
|
|
set("wt_lfoShape", (float) (variant % 4));
|
|
set("wt_level", clampUnit(layered ? 0.72f : 0.85f));
|
|
|
|
set("wt2_on", layered ? 1.0f : 0.0f);
|
|
set("wt2_bank", (float) secondaryIndex);
|
|
set("wt2_morph", layered ? clampMorph(4.0f + 6.0f * (1.0f - t)) : 0.0f);
|
|
set("wt2_phase", layered ? 0.25f : 0.0f);
|
|
set("wt2_lfoRate", clampLfoRate(layered ? (0.4f + 1.3f * (1.0f - t)) : 0.3f));
|
|
set("wt2_lfoDepth", clampLfoDepth(layered ? (1.0f + 2.0f * subT) : 0.0f));
|
|
set("wt2_lfoShape", layered ? (float) ((variant + 1) % 4) : 0.0f);
|
|
set("wt2_level", layered ? clampUnit(0.5f + 0.3f * t) : 0.0f);
|
|
|
|
set("chorus_on", 0.0f);
|
|
set("chorus_rate", clampUnit(0.3f));
|
|
set("chorus_depth", clampUnit(0.3f));
|
|
set("chorus_centre", clampUnit(0.5f));
|
|
set("chorus_feedback", clampUnit(0.12f));
|
|
set("chorus_mix", clampUnit(0.2f));
|
|
|
|
set("delay_on", 0.0f);
|
|
set("delay_delay", clampUnit(0.2f));
|
|
|
|
set("reverb_on", 0.0f);
|
|
set("reverb_roomSize", clampUnit(0.3f));
|
|
set("reverb_damping", clampUnit(0.5f));
|
|
set("reverb_wetLevel", clampUnit(0.18f));
|
|
set("reverb_dryLevel", clampUnit(0.85f));
|
|
set("reverb_width", clampUnit(0.9f));
|
|
set("reverb_freezeMode", 0.0f);
|
|
|
|
set("flanger_on", 0.0f);
|
|
set("flanger_rate", clampUnit(0.35f));
|
|
set("flanger_depth", 2.5f);
|
|
set("flanger_feedback", clampUnit(0.15f));
|
|
set("flanger_dryMix", clampUnit(0.25f));
|
|
set("flanger_phase", clampUnit(0.2f));
|
|
set("flanger_delay", 0.2f);
|
|
|
|
set("distortion_on", 0.0f);
|
|
set("distortion_drive", 10.0f);
|
|
set("distortion_mix", clampUnit(0.2f));
|
|
set("distortion_bias", 0.0f);
|
|
set("distortion_tone", juce::jlimit(100.0f, 8000.0f, 2400.0f));
|
|
set("distortion_shape", 0.0f);
|
|
|
|
set("filter_on", 0.0f);
|
|
set("filter_cutoff", clampCutoff(2000.0f));
|
|
set("filter_resonance", clampRes(0.7f));
|
|
set("filter_type", 0.0f);
|
|
set("filter_drive", 0.0f);
|
|
set("filter_mod", 0.0f);
|
|
set("filter_key", 0.0f);
|
|
|
|
set("adsr_attack", clampUnit(0.02f));
|
|
set("adsr_decay", clampUnit(0.3f));
|
|
set("adsr_sustain", clampUnit(0.7f));
|
|
set("adsr_release", clampUnit(0.4f));
|
|
|
|
set("fenv_attack", juce::jlimit(0.0f, 2.0f, 0.03f));
|
|
set("fenv_decay", juce::jlimit(0.0f, 2.0f, 0.3f));
|
|
set("fenv_sustain", clampUnit(0.5f));
|
|
set("fenv_release", juce::jlimit(0.0f, 4.0f, 0.4f));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.2f));
|
|
|
|
set("eq_on", 1.0f);
|
|
set("lowEQ", clampDb(0.0f));
|
|
set("midEQ", clampDb(0.0f));
|
|
set("highEQ", clampDb(0.0f));
|
|
|
|
set("master", layered ? -8.0f : -6.0f);
|
|
|
|
if (category == "Electric Piano")
|
|
{
|
|
set("chorus_on", 1.0f);
|
|
set("chorus_rate", clampUnit(0.18f + 0.25f * t));
|
|
set("chorus_depth", clampUnit(0.35f + 0.2f * t));
|
|
set("chorus_mix", clampUnit(0.2f + 0.15f * t));
|
|
set("chorus_feedback", clampUnit(0.18f + 0.1f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.35f + 0.25f * t));
|
|
set("reverb_wetLevel", clampUnit(0.2f + 0.12f * t));
|
|
set("reverb_damping", clampUnit(0.45f + 0.1f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(1500.0f + 700.0f * t));
|
|
set("filter_resonance", clampRes(0.8f + 0.3f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.35f + 0.15f * t));
|
|
set("adsr_attack", clampUnit(0.02f + 0.03f * t));
|
|
set("adsr_decay", clampUnit(0.25f + 0.1f * t));
|
|
set("adsr_sustain", clampUnit(0.65f + 0.1f * t));
|
|
set("adsr_release", clampUnit(0.45f + 0.18f * t));
|
|
set("wt_level", clampUnit(layered ? 0.7f : 0.83f));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.55f + 0.2f * t));
|
|
set("wt2_lfoRate", clampLfoRate(0.35f + 0.9f * (1.0f - t)));
|
|
set("wt2_lfoDepth", clampLfoDepth(1.1f + 1.4f * t));
|
|
}
|
|
set("lowEQ", clampDb(1.5f));
|
|
set("midEQ", clampDb(-1.0f + 2.5f * t));
|
|
set("highEQ", clampDb(2.0f + 3.0f * t));
|
|
}
|
|
else if (category == "Organ")
|
|
{
|
|
set("chorus_on", 1.0f);
|
|
set("chorus_rate", clampUnit(0.45f + 0.15f * t));
|
|
set("chorus_depth", clampUnit(0.3f + 0.1f * t));
|
|
set("chorus_mix", clampUnit(0.33f + 0.08f * t));
|
|
set("chorus_feedback", clampUnit(0.15f + 0.05f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.25f + 0.2f * t));
|
|
set("reverb_wetLevel", clampUnit(0.16f + 0.1f * t));
|
|
set("reverb_damping", clampUnit(0.4f + 0.15f * t));
|
|
set("filter_on", 0.0f);
|
|
set("adsr_attack", clampUnit(0.01f));
|
|
set("adsr_decay", clampUnit(0.3f));
|
|
set("adsr_sustain", clampUnit(1.0f));
|
|
set("adsr_release", clampUnit(0.3f + 0.2f * t));
|
|
set("fenv_amount", 0.0f);
|
|
set("wt_morph", clampMorph(3.0f + 5.0f * t));
|
|
set("wt_lfoRate", clampLfoRate(0.4f + 0.45f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(0.25f + 0.35f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.5f + 0.2f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(0.4f + 0.5f * t));
|
|
set("distortion_on", variant >= 15 ? 1.0f : 0.0f);
|
|
if (variant >= 15)
|
|
{
|
|
set("distortion_drive", 9.0f + 5.0f * t);
|
|
set("distortion_mix", clampUnit(0.18f + 0.12f * t));
|
|
set("distortion_shape", 1.0f);
|
|
}
|
|
}
|
|
set("midEQ", clampDb(1.5f + 1.0f * t));
|
|
set("highEQ", clampDb(2.0f + 1.5f * t));
|
|
set("master", layered ? -8.0f : -5.0f);
|
|
}
|
|
else if (category == "Bass")
|
|
{
|
|
set("wt_morph", clampMorph(1.5f + 5.5f * t));
|
|
set("wt_lfoRate", clampLfoRate(0.2f + 0.6f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(0.5f + 1.3f * t));
|
|
set("wt_level", clampUnit(0.92f));
|
|
set("adsr_attack", clampUnit(0.005f));
|
|
set("adsr_decay", clampUnit(0.18f + 0.08f * t));
|
|
set("adsr_sustain", clampUnit(0.45f - 0.15f * t));
|
|
set("adsr_release", clampUnit(0.22f + 0.12f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(180.0f + 720.0f * t));
|
|
set("filter_resonance", clampRes(0.85f + 0.35f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.6f + 0.25f * t));
|
|
set("distortion_on", (layered || variant >= 6) ? 1.0f : 0.0f);
|
|
if (values["distortion_on"] > 0.5f)
|
|
{
|
|
set("distortion_drive", 14.0f + 8.0f * t);
|
|
set("distortion_mix", clampUnit(0.25f + 0.25f * t));
|
|
set("distortion_shape", 2.0f);
|
|
}
|
|
set("lowEQ", clampDb(3.5f + 2.0f * t));
|
|
set("midEQ", clampDb(-2.5f + 1.8f * t));
|
|
set("highEQ", clampDb(-5.0f + 2.0f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.6f + 0.2f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(0.8f + 1.6f * t));
|
|
set("wt2_lfoRate", clampLfoRate(0.3f + 0.7f * t));
|
|
}
|
|
set("master", layered ? -7.5f : -5.0f);
|
|
}
|
|
else if (category == "Drums")
|
|
{
|
|
set("wt_morph", clampMorph(1.0f + 9.0f * t));
|
|
set("wt_lfoRate", clampLfoRate(1.2f + 2.5f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(0.3f + 2.8f * t));
|
|
set("wt_level", clampUnit(0.88f));
|
|
set("adsr_attack", clampUnit(0.001f));
|
|
set("adsr_decay", clampUnit(0.12f + 0.08f * t));
|
|
set("adsr_sustain", clampUnit(0.05f));
|
|
set("adsr_release", clampUnit(0.18f + 0.12f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, -0.2f + 0.4f * t));
|
|
set("distortion_on", 1.0f);
|
|
set("distortion_drive", 16.0f + 10.0f * t);
|
|
set("distortion_mix", clampUnit(0.35f + 0.2f * t));
|
|
set("distortion_shape", (float) (variant % 3));
|
|
set("distortion_bias", juce::jlimit(-1.0f, 1.0f, 0.05f * (variant % 5)));
|
|
set("reverb_on", layered ? 1.0f : (variant >= 8 ? 1.0f : 0.0f));
|
|
if (values["reverb_on"] > 0.5f)
|
|
{
|
|
set("reverb_roomSize", clampUnit(layered ? (0.45f + 0.3f * t) : 0.35f + 0.15f * t));
|
|
set("reverb_wetLevel", clampUnit(layered ? (0.3f + 0.18f * t) : 0.18f + 0.1f * t));
|
|
set("reverb_damping", clampUnit(0.45f + 0.25f * t));
|
|
}
|
|
set("filter_on", layered ? 1.0f : 0.0f);
|
|
if (values["filter_on"] > 0.5f)
|
|
{
|
|
set("filter_cutoff", clampCutoff(800.0f + 1200.0f * t));
|
|
set("filter_resonance", clampRes(1.0f + 0.6f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.1f + 0.35f * t));
|
|
}
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.6f + 0.25f * t));
|
|
set("wt2_lfoRate", clampLfoRate(0.9f + 1.6f * (1.0f - t)));
|
|
set("wt2_lfoDepth", clampLfoDepth(1.3f + 1.7f * t));
|
|
}
|
|
set("lowEQ", clampDb(4.0f + 2.0f * t));
|
|
set("midEQ", clampDb(-4.0f + 3.0f * t));
|
|
set("highEQ", clampDb(3.0f + 4.0f * t));
|
|
set("master", layered ? -8.5f : -6.5f);
|
|
}
|
|
else if (category == "Strings")
|
|
{
|
|
set("wt_morph", clampMorph(3.0f + 9.0f * t));
|
|
set("wt_lfoRate", clampLfoRate(0.18f + 0.4f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(0.8f + 1.8f * t));
|
|
set("adsr_attack", clampUnit(0.22f + 0.18f * t));
|
|
set("adsr_decay", clampUnit(0.3f + 0.12f * t));
|
|
set("adsr_sustain", clampUnit(0.85f));
|
|
set("adsr_release", clampUnit(0.6f + 0.25f * t));
|
|
set("chorus_on", 1.0f);
|
|
set("chorus_rate", clampUnit(0.25f + 0.1f * t));
|
|
set("chorus_depth", clampUnit(0.45f + 0.15f * t));
|
|
set("chorus_mix", clampUnit(0.3f + 0.1f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.55f + 0.2f * t));
|
|
set("reverb_wetLevel", clampUnit(0.35f + 0.15f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(2600.0f + 1500.0f * t));
|
|
set("filter_resonance", clampRes(0.85f + 0.25f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.25f + 0.1f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.5f + 0.25f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(1.0f + 1.5f * t));
|
|
}
|
|
set("midEQ", clampDb(-1.0f + 2.0f * t));
|
|
set("highEQ", clampDb(2.5f + 2.5f * t));
|
|
set("master", -7.5f);
|
|
}
|
|
else if (category == "Brass")
|
|
{
|
|
set("adsr_attack", clampUnit(0.05f + 0.05f * t));
|
|
set("adsr_decay", clampUnit(0.25f + 0.1f * t));
|
|
set("adsr_sustain", clampUnit(0.75f));
|
|
set("adsr_release", clampUnit(0.35f + 0.15f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(2200.0f + 1800.0f * t));
|
|
set("filter_resonance", clampRes(1.0f + 0.3f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.55f + 0.25f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.4f + 0.25f * t));
|
|
set("reverb_wetLevel", clampUnit(0.3f + 0.1f * t));
|
|
set("distortion_on", (layered || variant >= 8) ? 1.0f : 0.0f);
|
|
if (values["distortion_on"] > 0.5f)
|
|
{
|
|
set("distortion_drive", 10.0f + 6.0f * t);
|
|
set("distortion_mix", clampUnit(0.18f + 0.18f * t));
|
|
set("distortion_shape", 1.0f);
|
|
}
|
|
set("flanger_on", layered ? 1.0f : 0.0f);
|
|
if (values["flanger_on"] > 0.5f)
|
|
{
|
|
set("flanger_rate", clampUnit(0.35f + 0.25f * t));
|
|
set("flanger_depth", 4.0f + 3.0f * t);
|
|
set("flanger_dryMix", clampUnit(0.5f));
|
|
}
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.52f + 0.22f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(0.8f + 1.4f * t));
|
|
}
|
|
set("lowEQ", clampDb(2.0f + 1.0f * t));
|
|
set("midEQ", clampDb(1.0f + 1.5f * t));
|
|
set("highEQ", clampDb(1.0f + 2.5f * t));
|
|
}
|
|
else if (category == "Choir")
|
|
{
|
|
set("adsr_attack", clampUnit(0.3f + 0.2f * t));
|
|
set("adsr_decay", clampUnit(0.4f + 0.1f * t));
|
|
set("adsr_sustain", clampUnit(0.9f));
|
|
set("adsr_release", clampUnit(0.55f + 0.3f * t));
|
|
set("chorus_on", 1.0f);
|
|
set("chorus_rate", clampUnit(0.2f + 0.15f * t));
|
|
set("chorus_depth", clampUnit(0.5f + 0.2f * t));
|
|
set("chorus_mix", clampUnit(0.35f + 0.15f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.6f + 0.25f * t));
|
|
set("reverb_wetLevel", clampUnit(0.4f + 0.15f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(1800.0f + 800.0f * t));
|
|
set("filter_resonance", clampRes(0.7f + 0.2f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.15f + 0.08f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(1.0f + 2.0f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.48f + 0.2f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(1.2f + 1.5f * t));
|
|
}
|
|
set("midEQ", clampDb(-1.5f + 1.5f * t));
|
|
set("highEQ", clampDb(3.0f + 2.0f * t));
|
|
set("master", -7.5f);
|
|
}
|
|
else if (category == "Pad")
|
|
{
|
|
set("adsr_attack", clampUnit(0.35f + 0.25f * t));
|
|
set("adsr_decay", clampUnit(0.35f + 0.15f * t));
|
|
set("adsr_sustain", clampUnit(0.85f));
|
|
set("adsr_release", clampUnit(0.7f + 0.35f * t));
|
|
set("chorus_on", 1.0f);
|
|
set("chorus_rate", clampUnit(0.18f + 0.12f * t));
|
|
set("chorus_depth", clampUnit(0.55f + 0.2f * t));
|
|
set("chorus_mix", clampUnit(0.35f + 0.15f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.65f + 0.25f * t));
|
|
set("reverb_wetLevel", clampUnit(0.4f + 0.2f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(1500.0f + 900.0f * t));
|
|
set("filter_resonance", clampRes(0.8f + 0.25f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.2f + 0.12f * t));
|
|
set("flanger_on", (layered || variant % 3 == 0) ? 1.0f : 0.0f);
|
|
if (values["flanger_on"] > 0.5f)
|
|
{
|
|
set("flanger_rate", clampUnit(0.25f + 0.15f * t));
|
|
set("flanger_depth", 5.0f + 3.0f * t);
|
|
set("flanger_dryMix", clampUnit(0.4f));
|
|
}
|
|
set("wt_lfoRate", clampLfoRate(0.15f + 0.35f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(1.5f + 2.5f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.5f + 0.3f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(1.3f + 2.0f * t));
|
|
}
|
|
set("master", -8.5f);
|
|
}
|
|
else if (category == "SFX")
|
|
{
|
|
set("wt_morph", clampMorph(4.0f + 10.0f * t));
|
|
set("wt_lfoRate", clampLfoRate(1.2f + 3.5f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(2.5f + 5.0f * t));
|
|
set("wt_lfoShape", (float) (variant % 4));
|
|
set("wt_phase", (variant % 2 == 0) ? 0.0f : 0.5f);
|
|
set("chorus_on", 1.0f);
|
|
set("chorus_rate", clampUnit(0.35f + 0.3f * t));
|
|
set("chorus_depth", clampUnit(0.45f + 0.25f * t));
|
|
set("chorus_mix", clampUnit(0.3f + 0.2f * t));
|
|
set("flanger_on", 1.0f);
|
|
set("flanger_rate", clampUnit(0.45f + 0.4f * t));
|
|
set("flanger_depth", 6.0f + 4.0f * t);
|
|
set("flanger_phase", clampUnit(0.2f + 0.5f * t));
|
|
set("flanger_dryMix", clampUnit(0.5f));
|
|
set("distortion_on", 1.0f);
|
|
set("distortion_drive", 18.0f + 7.0f * t);
|
|
set("distortion_mix", clampUnit(0.35f + 0.2f * t));
|
|
set("distortion_shape", (float) ((variant + 1) % 3));
|
|
set("distortion_bias", juce::jlimit(-1.0f, 1.0f, -0.2f + 0.4f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.7f + 0.2f * t));
|
|
set("reverb_wetLevel", clampUnit(0.45f + 0.2f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.6f + 0.25f * t));
|
|
set("wt2_morph", clampMorph(6.0f + 7.0f * (1.0f - t)));
|
|
set("wt2_lfoRate", clampLfoRate(0.8f + 4.0f * (1.0f - t)));
|
|
set("wt2_lfoDepth", clampLfoDepth(2.0f + 4.0f * t));
|
|
set("wt2_lfoShape", (float) ((variant + 2) % 4));
|
|
}
|
|
set("lowEQ", clampDb(-4.0f + 4.0f * t));
|
|
set("midEQ", clampDb(3.0f - 4.0f * t));
|
|
set("highEQ", clampDb(6.0f + 4.0f * t));
|
|
set("master", -12.0f);
|
|
}
|
|
else if (category == "Lead")
|
|
{
|
|
set("wt_morph", clampMorph(3.0f + 8.0f * t));
|
|
set("wt_lfoRate", clampLfoRate(0.4f + 1.2f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(1.0f + 2.0f * t));
|
|
set("adsr_attack", clampUnit(0.01f + 0.02f * t));
|
|
set("adsr_decay", clampUnit(0.18f + 0.08f * t));
|
|
set("adsr_sustain", clampUnit(0.85f));
|
|
set("adsr_release", clampUnit(0.25f + 0.1f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(2300.0f + 3200.0f * t));
|
|
set("filter_resonance", clampRes(0.9f + 0.25f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.45f + 0.25f * t));
|
|
set("distortion_on", 1.0f);
|
|
set("distortion_drive", 12.0f + 10.0f * t);
|
|
set("distortion_mix", clampUnit(0.25f + 0.25f * t));
|
|
set("distortion_shape", (float) ((variant % 2) + 1));
|
|
set("chorus_on", (layered || variant % 3 == 0) ? 1.0f : 0.0f);
|
|
if (values["chorus_on"] > 0.5f)
|
|
{
|
|
set("chorus_rate", clampUnit(0.3f + 0.2f * t));
|
|
set("chorus_depth", clampUnit(0.4f + 0.2f * t));
|
|
set("chorus_mix", clampUnit(0.25f + 0.15f * t));
|
|
}
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.35f + 0.25f * t));
|
|
set("reverb_wetLevel", clampUnit(0.22f + 0.15f * t));
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.52f + 0.22f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(1.1f + 1.6f * t));
|
|
}
|
|
set("lowEQ", clampDb(-1.5f + 1.5f * t));
|
|
set("midEQ", clampDb(2.0f + 1.5f * t));
|
|
set("highEQ", clampDb(4.0f + 3.0f * t));
|
|
set("master", layered ? -7.5f : -6.0f);
|
|
}
|
|
else if (category == "Pluck")
|
|
{
|
|
set("wt_morph", clampMorph(2.5f + 7.0f * t));
|
|
set("wt_lfoRate", clampLfoRate(0.25f + 0.7f * t));
|
|
set("wt_lfoDepth", clampLfoDepth(0.6f + 1.8f * t));
|
|
set("adsr_attack", clampUnit(0.005f));
|
|
set("adsr_decay", clampUnit(0.22f + 0.15f * t));
|
|
set("adsr_sustain", clampUnit(0.2f + 0.1f * t));
|
|
set("adsr_release", clampUnit(0.25f + 0.1f * t));
|
|
set("fenv_amount", juce::jlimit(-1.0f, 1.0f, 0.4f + 0.2f * t));
|
|
set("filter_on", 1.0f);
|
|
set("filter_cutoff", clampCutoff(1800.0f + 2000.0f * t));
|
|
set("filter_resonance", clampRes(1.1f + 0.3f * t));
|
|
set("delay_on", 1.0f);
|
|
set("delay_delay", clampUnit(0.25f + 0.25f * t));
|
|
set("reverb_on", 1.0f);
|
|
set("reverb_roomSize", clampUnit(0.45f + 0.25f * t));
|
|
set("reverb_wetLevel", clampUnit(0.25f + 0.15f * t));
|
|
set("chorus_on", 0.0f);
|
|
set("distortion_on", variant >= 12 ? 1.0f : 0.0f);
|
|
if (values["distortion_on"] > 0.5f)
|
|
{
|
|
set("distortion_drive", 10.0f + 8.0f * t);
|
|
set("distortion_mix", clampUnit(0.2f + 0.2f * t));
|
|
set("distortion_shape", 2.0f);
|
|
}
|
|
if (layered)
|
|
{
|
|
set("wt2_level", clampUnit(0.48f + 0.25f * t));
|
|
set("wt2_lfoDepth", clampLfoDepth(0.9f + 1.5f * t));
|
|
}
|
|
set("lowEQ", clampDb(-1.0f + 2.0f * t));
|
|
set("midEQ", clampDb(-2.0f + 3.0f * t));
|
|
set("highEQ", clampDb(3.0f + 2.5f * t));
|
|
}
|
|
|
|
juce::String presetName;
|
|
if (isDrumCategory)
|
|
{
|
|
presetName = juce::String::formatted("GM %d %s%s",
|
|
gmInfo.first,
|
|
gmInfo.second,
|
|
layered ? " Stack" : "");
|
|
}
|
|
else
|
|
{
|
|
presetName = category + (layered ? " Duo " : " Solo ")
|
|
+ juce::String(variant + 1).paddedLeft('0', 2);
|
|
}
|
|
|
|
auto scaleLevel = [&](const juce::String& paramId, float factor)
|
|
{
|
|
auto it = values.find(paramId);
|
|
if (it != values.end())
|
|
it->second = juce::jlimit(0.0f, 1.0f, it->second * factor);
|
|
};
|
|
|
|
scaleLevel("wt_level", 0.75f);
|
|
scaleLevel("wt2_level", 0.75f);
|
|
|
|
if (auto it = values.find("master"); it != values.end())
|
|
it->second = juce::jlimit(-24.0f, 24.0f, it->second - 4.0f);
|
|
|
|
PresetDefinition def;
|
|
def.category = category;
|
|
def.name = presetName.trim();
|
|
def.wtBankIndex = primaryIndex;
|
|
def.wt2BankIndex = layered ? secondaryIndex : -1;
|
|
def.parameterValues.reserve(values.size());
|
|
for (const auto& entry : values)
|
|
def.parameterValues.emplace_back(entry.first, entry.second);
|
|
|
|
presets.push_back(std::move(def));
|
|
}
|
|
}
|
|
|
|
return presets;
|
|
}
|
|
|
|
void NeuralSynthAudioProcessor::setParameterValue(const juce::String& paramID, float value)
|
|
{
|
|
if (parameters.getParameter(paramID) != nullptr)
|
|
parameters.getParameterAsValue(paramID) = value;
|
|
}
|
|
|
|
void NeuralSynthAudioProcessor::applyPreset(int index)
|
|
{
|
|
if (factoryPresets.empty())
|
|
return;
|
|
|
|
index = juce::jlimit(0, (int) factoryPresets.size() - 1, index);
|
|
const auto& preset = factoryPresets[(size_t) index];
|
|
|
|
juce::ScopedValueSetter<bool> guard(presetChangeInProgress, true, false);
|
|
|
|
for (const auto& entry : preset.parameterValues)
|
|
setParameterValue(entry.first, entry.second);
|
|
|
|
currentPresetIndex = index;
|
|
}
|
|
|
|
juce::AudioProcessorValueTreeState::ParameterLayout NeuralSynthAudioProcessor::createParameterLayout()
|
|
{
|
|
std::vector<std::unique_ptr<juce::RangedAudioParameter>> params;
|
|
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>(
|
|
"wt_on", "Layer A On", true));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>(
|
|
"wt2_on", "Layer B On", false));
|
|
|
|
// Per-panel bypass toggles (default OFF)
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("chorus_on", "Chorus On", false));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("delay_on", "Delay On", false));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("reverb_on", "Reverb On", false));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("flanger_on", "Flanger On", false));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("distortion_on", "Distortion On", false));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("filter_on", "Filter On", false));
|
|
params.push_back(std::make_unique<juce::AudioParameterBool>("eq_on", "EQ On", false));
|
|
|
|
buildParams(params, "adsr");
|
|
buildParams(params, "fenv");
|
|
buildParams(params, "chorus");
|
|
buildParams(params, "delay");
|
|
buildParams(params, "reverb");
|
|
buildParams(params, "flanger");
|
|
buildParams(params, "distortion");
|
|
buildParams(params, "filter");
|
|
buildParams(params, "wt");
|
|
buildParams(params, "wt2");
|
|
|
|
params.push_back(std::make_unique<juce::AudioParameterFloat>("master", "Master",
|
|
juce::NormalisableRange<float>(-24.0f, 24.0f, 0.1f), -6.0f));
|
|
|
|
params.push_back(std::make_unique<juce::AudioParameterFloat>("lowEQ", "Low Gain",
|
|
juce::NormalisableRange<float>(-24.0f, 24.0f, 0.1f), 0.5f));
|
|
params.push_back(std::make_unique<juce::AudioParameterFloat>("midEQ", "Mid EQ",
|
|
juce::NormalisableRange<float>(-24.0f, 24.0f, 0.1f), 0.8f));
|
|
params.push_back(std::make_unique<juce::AudioParameterFloat>("highEQ", "High EQ",
|
|
juce::NormalisableRange<float>(-24.0f, 24.0f, 0.1f), 1.0f));
|
|
|
|
return { params.begin(), params.end() };
|
|
}
|