diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 8283425..5531372 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -13,14 +13,15 @@ #include "GuiConstants.h" //============================================================================== -JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor& p) +JuicySFAudioProcessorEditor::JuicySFAudioProcessorEditor(JuicySFAudioProcessor& p, AudioProcessorValueTreeState& state) : AudioProcessorEditor{&p}, processor{p}, + state{state}, sharedParams{p.sharedParams}, midiKeyboard{p.keyboardState, SurjectiveMidiKeyboardComponent::horizontalKeyboard}, tablesComponent{p.getFluidSynthModel()}, filePicker{p.getFluidSynthModel()}, - slidersComponent{p.sharedParams, p.getFluidSynthModel()} + slidersComponent{p.sharedParams, state, p.getFluidSynthModel()} { // set resize limits for this plug-in setResizeLimits( @@ -159,4 +160,4 @@ FilePickerFragment& JuicySFAudioProcessorEditor::getFilePicker() { SlidersFragment& JuicySFAudioProcessorEditor::getSliders() { return slidersComponent; -} \ No newline at end of file +} diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index a242cb7..6c2fd07 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -28,7 +28,7 @@ class JuicySFAudioProcessorEditor : public AudioProcessorEditor, public StateChangeSubscriber*/ { public: - JuicySFAudioProcessorEditor (JuicySFAudioProcessor&); + JuicySFAudioProcessorEditor (JuicySFAudioProcessor&, AudioProcessorValueTreeState& state); ~JuicySFAudioProcessorEditor(); //============================================================================== @@ -49,6 +49,7 @@ private: // access the processor object that created it. JuicySFAudioProcessor& processor; + AudioProcessorValueTreeState& state; shared_ptr sharedParams; SurjectiveMidiKeyboardComponent midiKeyboard; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index ba3d357..fb9e166 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -19,21 +19,44 @@ #include "Params.h" using namespace std; +using Parameter = AudioProcessorValueTreeState::Parameter; AudioProcessor* JUCE_CALLTYPE createPluginFilter(); //============================================================================== JuicySFAudioProcessor::JuicySFAudioProcessor() - : AudioProcessor{getBusesProperties()}, - sharedParams{static_pointer_cast(make_shared())}, - fluidSynthModel{sharedParams}/*, - fluidSynthModel{*this}, - pluginEditor(nullptr)*/ +: AudioProcessor{getBusesProperties()} +, sharedParams{static_pointer_cast(make_shared())} +, state{*this, nullptr, + { "PARAMETERS" /* MYPLUGINSETTINGS */ }, + createParameterLayout() + } +, fluidSynthModel{sharedParams} +//, fluidSynthModel{*this} +//, pluginEditor(nullptr) { initialiseSynth(); } +AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParameterLayout() { + // std::vector> params; + + // for (int i = 1; i < 9; ++i) + // params.push_back (std::make_unique (String (i), String (i), 0, i, 0)); + + vector> params{ + make_unique("attack", "volume envelope attack time", 0, 127, 0, "A" ), + make_unique("decay", "volume envelope sustain attentuation", 0, 127, 0, "D" ), + make_unique("sustain", "volume envelope decay time", 0, 127, 0, "S" ), + make_unique("release", "volume envelope release time", 0, 127, 0, "R" ), + make_unique("filterCutOff", "low-pass filter cut-off frequency", 0, 127, 0, "Cut" ), + make_unique("filterResonance", "low-pass filter resonance attentuation", 0, 127, 0, "Res" ), + }; + + return { params.begin(), params.end() }; +} + JuicySFAudioProcessor::~JuicySFAudioProcessor() { // delete fluidSynthModel; @@ -268,7 +291,7 @@ bool JuicySFAudioProcessor::hasEditor() const AudioProcessorEditor* JuicySFAudioProcessor::createEditor() { // grab a raw pointer to it for our own use - return /*pluginEditor = */new JuicySFAudioProcessorEditor (*this); + return /*pluginEditor = */new JuicySFAudioProcessorEditor (*this, state); } //============================================================================== diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 5aee38f..93554f2 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -74,6 +74,8 @@ public: private: void initialiseSynth(); + AudioProcessorValueTreeState state; + FluidSynthModel fluidSynthModel; fluid_synth_t* fluidSynth; Synthesiser synth; @@ -83,6 +85,8 @@ private: // list stateChangeSubscribers; + AudioProcessorValueTreeState::ParameterLayout createParameterLayout(); + static BusesProperties getBusesProperties(); // Model* model; diff --git a/Source/SlidersComponent.cpp b/Source/SlidersComponent.cpp index 1fa4325..608a7fd 100644 --- a/Source/SlidersComponent.cpp +++ b/Source/SlidersComponent.cpp @@ -9,6 +9,7 @@ #include "SlidersComponent.h" #include "FluidSynthModel.h" #include "MidiConstants.h" +using SliderAttachment = AudioProcessorValueTreeState::SliderAttachment; std::function SlidersComponent::makeSliderListener(Slider& slider, int controller/*, std::function callback*/) { return [this, controller, &slider]{ @@ -105,11 +106,13 @@ void SlidersComponent::acceptMidiControlEvent(int controller, int value) { SlidersComponent::SlidersComponent( shared_ptr sharedParams, - FluidSynthModel* fluidSynthModel) : -sharedParams{sharedParams}, -fluidSynthModel{fluidSynthModel}, -envelopeGroup{"envelopeGroup", "Envelope"}, -filterGroup{"filterGroup", "Filter"} + AudioProcessorValueTreeState& state, + FluidSynthModel* fluidSynthModel) +: sharedParams{sharedParams} +, state{state} +, fluidSynthModel{fluidSynthModel} +, envelopeGroup{"envelopeGroup", "Envelope"} +, filterGroup{"filterGroup", "Filter"} { const Slider::SliderStyle style{Slider::SliderStyle::LinearVertical}; const double rangeMin(0); @@ -120,31 +123,37 @@ filterGroup{"filterGroup", "Filter"} attackSlider.setRange(rangeMin, rangeMax, rangeStep); attackSlider.onValueChange = makeSliderListener(attackSlider, static_cast(SOUND_CTRL4)); attackSlider.setTextBoxStyle(Slider::TextBoxBelow, true, attackSlider.getTextBoxWidth(), attackSlider.getTextBoxHeight()); + attackSliderAttachment = make_unique(state, "attack", attackSlider); decaySlider.setSliderStyle(style); decaySlider.setRange(rangeMin, rangeMax, rangeStep); decaySlider.onValueChange = makeSliderListener(decaySlider, static_cast(SOUND_CTRL6)); decaySlider.setTextBoxStyle(Slider::TextBoxBelow, true, decaySlider.getTextBoxWidth(), decaySlider.getTextBoxHeight()); + decaySliderAttachment = make_unique(state, "decay", decaySlider); sustainSlider.setSliderStyle(style); sustainSlider.setRange(rangeMin, rangeMax, rangeStep); sustainSlider.onValueChange = makeSliderListener(sustainSlider, static_cast(SOUND_CTRL10)); sustainSlider.setTextBoxStyle(Slider::TextBoxBelow, true, sustainSlider.getTextBoxWidth(), sustainSlider.getTextBoxHeight()); + sustainSliderAttachment = make_unique(state, "sustain", sustainSlider); releaseSlider.setSliderStyle(style); releaseSlider.setRange(rangeMin, rangeMax, rangeStep); releaseSlider.onValueChange = makeSliderListener(releaseSlider, static_cast(SOUND_CTRL3)); releaseSlider.setTextBoxStyle(Slider::TextBoxBelow, true, releaseSlider.getTextBoxWidth(), releaseSlider.getTextBoxHeight()); + releaseSliderAttachment = make_unique(state, "release", releaseSlider); filterCutOffSlider.setSliderStyle(style); filterCutOffSlider.setRange(rangeMin, rangeMax, rangeStep); filterCutOffSlider.onValueChange = makeSliderListener(filterCutOffSlider, static_cast(SOUND_CTRL5)); filterCutOffSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterCutOffSlider.getTextBoxWidth(), filterCutOffSlider.getTextBoxHeight()); + filterCutOffSliderAttachment = make_unique(state, "filterCutOff", filterCutOffSlider); filterResonanceSlider.setSliderStyle(style); filterResonanceSlider.setRange(rangeMin, rangeMax, rangeStep); filterResonanceSlider.onValueChange = makeSliderListener(filterResonanceSlider, static_cast(SOUND_CTRL2)); filterResonanceSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterResonanceSlider.getTextBoxWidth(), filterResonanceSlider.getTextBoxHeight()); + filterResonanceSliderAttachment = make_unique(state, "filterResonance", filterResonanceSlider); addAndMakeVisible(attackSlider); addAndMakeVisible(decaySlider); diff --git a/Source/SlidersComponent.h b/Source/SlidersComponent.h index 97dfeeb..cc8d1dc 100644 --- a/Source/SlidersComponent.h +++ b/Source/SlidersComponent.h @@ -6,6 +6,7 @@ #include "SlidersFragment.h" using namespace std; +using SliderAttachment = AudioProcessorValueTreeState::SliderAttachment; class SlidersComponent : public Component, public SlidersFragment @@ -13,6 +14,7 @@ class SlidersComponent : public Component, public: SlidersComponent( shared_ptr sharedParams, + AudioProcessorValueTreeState& state, FluidSynthModel* fluidSynthModel); ~SlidersComponent(); @@ -34,29 +36,36 @@ private: std::function makeSliderListener(Slider& slider, int controller); shared_ptr sharedParams; + AudioProcessorValueTreeState& state; FluidSynthModel* fluidSynthModel; GroupComponent envelopeGroup; Slider attackSlider; Label attackLabel; + unique_ptr attackSliderAttachment; Slider decaySlider; Label decayLabel; + unique_ptr decaySliderAttachment; Slider sustainSlider; Label sustainLabel; + unique_ptr sustainSliderAttachment; Slider releaseSlider; Label releaseLabel; + unique_ptr releaseSliderAttachment; GroupComponent filterGroup; Slider filterCutOffSlider; Label filterCutOffLabel; + unique_ptr filterCutOffSliderAttachment; Slider filterResonanceSlider; Label filterResonanceLabel; + unique_ptr filterResonanceSliderAttachment; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SlidersComponent) };