From 7582fbcc9ef031db94941ef69552c3b953fb31d9 Mon Sep 17 00:00:00 2001 From: Alex Birch Date: Thu, 4 Jul 2019 23:48:20 +0100 Subject: [PATCH] sliders control fluidsynth when user interacts with them, but also update their position to reflect incoming MIDI messages, without attempting to control fluidsynth (since audio processor will have already done so) --- Source/PluginProcessor.cpp | 30 +++++++++++++++++------------- Source/SlidersComponent.cpp | 22 ++++++++++++++++------ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 2090560..e2ddf59 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -47,7 +47,7 @@ AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParam // params.push_back (std::make_unique (String (i), String (i), 0, i, 0)); // https://stackoverflow.com/a/8469002/5257399 - unique_ptr params[] = { + unique_ptr 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" ), @@ -216,34 +216,38 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer& buffer, MidiBuffer break; } case SOUND_CTRL3: { // MIDI CC 72 Release time -// valueTreeState.state.setProperty({"release"}, m.getControllerValue(), nullptr); -// valueTreeState.state.flushParameterValuesToValueTree(); -// jassert(dynamic_cast (editor) != nullptr); RangedAudioParameter *param {valueTreeState.getParameter("release")}; -// dynamic_cast(*param) jassert(dynamic_cast (param) != nullptr); AudioParameterInt* castParam {dynamic_cast (param)}; -// castParam->setValue(m.getControllerValue()); -// castParam-> -// param->setValue(m.getControllerValue()); -// param->setValueNotifyingHost(m.getControllerValue()); *castParam = m.getControllerValue(); break; } case SOUND_CTRL4: { // MIDI CC 73 Attack time - valueTreeState.state.setProperty({"attack"}, m.getControllerValue(), nullptr); + RangedAudioParameter *param {valueTreeState.getParameter("release")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + *castParam = m.getControllerValue(); break; } case SOUND_CTRL5: { // MIDI CC 74 Brightness (cutoff frequency, FILTERFC) - valueTreeState.state.setProperty({"filterCutOff"}, m.getControllerValue(), nullptr); + RangedAudioParameter *param {valueTreeState.getParameter("filterCutOff")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + *castParam = m.getControllerValue(); break; } case SOUND_CTRL6: { // MIDI CC 75 Decay Time - valueTreeState.state.setProperty({"decay"}, m.getControllerValue(), nullptr); + RangedAudioParameter *param {valueTreeState.getParameter("decay")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + *castParam = m.getControllerValue(); break; } case SOUND_CTRL10: { // MIDI CC 79 undefined - valueTreeState.state.setProperty({"sustain"}, m.getControllerValue(), nullptr); + RangedAudioParameter *param {valueTreeState.getParameter("sustain")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + *castParam = m.getControllerValue(); break; } default: { diff --git a/Source/SlidersComponent.cpp b/Source/SlidersComponent.cpp index edf88a5..789e696 100644 --- a/Source/SlidersComponent.cpp +++ b/Source/SlidersComponent.cpp @@ -9,10 +9,20 @@ #include "SlidersComponent.h" #include "FluidSynthModel.h" #include "MidiConstants.h" +#include "Util.h" using SliderAttachment = AudioProcessorValueTreeState::SliderAttachment; std::function SlidersComponent::makeSliderListener(Slider& slider, int controller/*, std::function callback*/) { return [this, controller, &slider]{ + + RangedAudioParameter *param {valueTreeState.getParameter("release")}; + jassert(dynamic_cast (param) != nullptr); + AudioParameterInt* castParam {dynamic_cast (param)}; + int value {castParam->get()}; + + String s{"slider "}; + s << slider.getComponentID() << ", controller " << controller << ", value " << slider.getValue() << ", xmlReleaseValue " << value; + DEBUG_PRINT(s); // slider.setValue(slider.getValue(), NotificationType::dontSendNotification); fluidSynthModel->setControllerValue(controller, slider.getValue()); // callback(); @@ -121,37 +131,37 @@ SlidersComponent::SlidersComponent( attackSlider.setSliderStyle(style); attackSlider.setRange(rangeMin, rangeMax, rangeStep); - // attackSlider.onValueChange = makeSliderListener(attackSlider, static_cast(SOUND_CTRL4)); + attackSlider.onDragEnd = makeSliderListener(attackSlider, static_cast(SOUND_CTRL4)); attackSlider.setTextBoxStyle(Slider::TextBoxBelow, true, attackSlider.getTextBoxWidth(), attackSlider.getTextBoxHeight()); attackSliderAttachment = make_unique(valueTreeState, "attack", attackSlider); decaySlider.setSliderStyle(style); decaySlider.setRange(rangeMin, rangeMax, rangeStep); - // decaySlider.onValueChange = makeSliderListener(decaySlider, static_cast(SOUND_CTRL6)); + decaySlider.onDragEnd = makeSliderListener(decaySlider, static_cast(SOUND_CTRL6)); decaySlider.setTextBoxStyle(Slider::TextBoxBelow, true, decaySlider.getTextBoxWidth(), decaySlider.getTextBoxHeight()); decaySliderAttachment = make_unique(valueTreeState, "decay", decaySlider); sustainSlider.setSliderStyle(style); sustainSlider.setRange(rangeMin, rangeMax, rangeStep); - // sustainSlider.onValueChange = makeSliderListener(sustainSlider, static_cast(SOUND_CTRL10)); + sustainSlider.onDragEnd = makeSliderListener(sustainSlider, static_cast(SOUND_CTRL10)); sustainSlider.setTextBoxStyle(Slider::TextBoxBelow, true, sustainSlider.getTextBoxWidth(), sustainSlider.getTextBoxHeight()); sustainSliderAttachment = make_unique(valueTreeState, "sustain", sustainSlider); releaseSlider.setSliderStyle(style); releaseSlider.setRange(rangeMin, rangeMax, rangeStep); - // releaseSlider.onValueChange = makeSliderListener(releaseSlider, static_cast(SOUND_CTRL3)); + releaseSlider.onDragEnd = makeSliderListener(releaseSlider, static_cast(SOUND_CTRL3)); releaseSlider.setTextBoxStyle(Slider::TextBoxBelow, true, releaseSlider.getTextBoxWidth(), releaseSlider.getTextBoxHeight()); releaseSliderAttachment = make_unique(valueTreeState, "release", releaseSlider); filterCutOffSlider.setSliderStyle(style); filterCutOffSlider.setRange(rangeMin, rangeMax, rangeStep); - // filterCutOffSlider.onValueChange = makeSliderListener(filterCutOffSlider, static_cast(SOUND_CTRL5)); + filterCutOffSlider.onDragEnd = makeSliderListener(filterCutOffSlider, static_cast(SOUND_CTRL5)); filterCutOffSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterCutOffSlider.getTextBoxWidth(), filterCutOffSlider.getTextBoxHeight()); filterCutOffSliderAttachment = make_unique(valueTreeState, "filterCutOff", filterCutOffSlider); filterResonanceSlider.setSliderStyle(style); filterResonanceSlider.setRange(rangeMin, rangeMax, rangeStep); - // filterResonanceSlider.onValueChange = makeSliderListener(filterResonanceSlider, static_cast(SOUND_CTRL2)); + filterResonanceSlider.onDragEnd = makeSliderListener(filterResonanceSlider, static_cast(SOUND_CTRL2)); filterResonanceSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterResonanceSlider.getTextBoxWidth(), filterResonanceSlider.getTextBoxHeight()); filterResonanceSliderAttachment = make_unique(valueTreeState, "filterResonance", filterResonanceSlider);