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)

This commit is contained in:
Alex Birch 2019-07-04 23:48:20 +01:00
parent 82f18ed4a0
commit 7582fbcc9e
No known key found for this signature in database
GPG Key ID: 305EB1F98D44ACBA
2 changed files with 33 additions and 19 deletions

View File

@ -47,7 +47,7 @@ AudioProcessorValueTreeState::ParameterLayout JuicySFAudioProcessor::createParam
// params.push_back (std::make_unique<AudioParameterInt> (String (i), String (i), 0, i, 0));
// https://stackoverflow.com/a/8469002/5257399
unique_ptr<AudioParameterInt> params[] = {
unique_ptr<AudioParameterInt> params[] {
make_unique<AudioParameterInt>("attack", "volume envelope attack time", 0, 127, 0, "A" ),
make_unique<AudioParameterInt>("decay", "volume envelope sustain attentuation", 0, 127, 0, "D" ),
make_unique<AudioParameterInt>("sustain", "volume envelope decay time", 0, 127, 0, "S" ),
@ -216,34 +216,38 @@ void JuicySFAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer
break;
}
case SOUND_CTRL3: { // MIDI CC 72 Release time
// valueTreeState.state.setProperty({"release"}, m.getControllerValue(), nullptr);
// valueTreeState.state.flushParameterValuesToValueTree();
// jassert(dynamic_cast<ExposesComponents*> (editor) != nullptr);
RangedAudioParameter *param {valueTreeState.getParameter("release")};
// dynamic_cast<AudioParameterInt&>(*param)
jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (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<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (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<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (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<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (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<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (param)};
*castParam = m.getControllerValue();
break;
}
default: {

View File

@ -9,10 +9,20 @@
#include "SlidersComponent.h"
#include "FluidSynthModel.h"
#include "MidiConstants.h"
#include "Util.h"
using SliderAttachment = AudioProcessorValueTreeState::SliderAttachment;
std::function<void()> SlidersComponent::makeSliderListener(Slider& slider, int controller/*, std::function<void()> callback*/) {
return [this, controller, &slider]{
RangedAudioParameter *param {valueTreeState.getParameter("release")};
jassert(dynamic_cast<AudioParameterInt*> (param) != nullptr);
AudioParameterInt* castParam {dynamic_cast<AudioParameterInt*> (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<int>(SOUND_CTRL4));
attackSlider.onDragEnd = makeSliderListener(attackSlider, static_cast<int>(SOUND_CTRL4));
attackSlider.setTextBoxStyle(Slider::TextBoxBelow, true, attackSlider.getTextBoxWidth(), attackSlider.getTextBoxHeight());
attackSliderAttachment = make_unique<SliderAttachment>(valueTreeState, "attack", attackSlider);
decaySlider.setSliderStyle(style);
decaySlider.setRange(rangeMin, rangeMax, rangeStep);
// decaySlider.onValueChange = makeSliderListener(decaySlider, static_cast<int>(SOUND_CTRL6));
decaySlider.onDragEnd = makeSliderListener(decaySlider, static_cast<int>(SOUND_CTRL6));
decaySlider.setTextBoxStyle(Slider::TextBoxBelow, true, decaySlider.getTextBoxWidth(), decaySlider.getTextBoxHeight());
decaySliderAttachment = make_unique<SliderAttachment>(valueTreeState, "decay", decaySlider);
sustainSlider.setSliderStyle(style);
sustainSlider.setRange(rangeMin, rangeMax, rangeStep);
// sustainSlider.onValueChange = makeSliderListener(sustainSlider, static_cast<int>(SOUND_CTRL10));
sustainSlider.onDragEnd = makeSliderListener(sustainSlider, static_cast<int>(SOUND_CTRL10));
sustainSlider.setTextBoxStyle(Slider::TextBoxBelow, true, sustainSlider.getTextBoxWidth(), sustainSlider.getTextBoxHeight());
sustainSliderAttachment = make_unique<SliderAttachment>(valueTreeState, "sustain", sustainSlider);
releaseSlider.setSliderStyle(style);
releaseSlider.setRange(rangeMin, rangeMax, rangeStep);
// releaseSlider.onValueChange = makeSliderListener(releaseSlider, static_cast<int>(SOUND_CTRL3));
releaseSlider.onDragEnd = makeSliderListener(releaseSlider, static_cast<int>(SOUND_CTRL3));
releaseSlider.setTextBoxStyle(Slider::TextBoxBelow, true, releaseSlider.getTextBoxWidth(), releaseSlider.getTextBoxHeight());
releaseSliderAttachment = make_unique<SliderAttachment>(valueTreeState, "release", releaseSlider);
filterCutOffSlider.setSliderStyle(style);
filterCutOffSlider.setRange(rangeMin, rangeMax, rangeStep);
// filterCutOffSlider.onValueChange = makeSliderListener(filterCutOffSlider, static_cast<int>(SOUND_CTRL5));
filterCutOffSlider.onDragEnd = makeSliderListener(filterCutOffSlider, static_cast<int>(SOUND_CTRL5));
filterCutOffSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterCutOffSlider.getTextBoxWidth(), filterCutOffSlider.getTextBoxHeight());
filterCutOffSliderAttachment = make_unique<SliderAttachment>(valueTreeState, "filterCutOff", filterCutOffSlider);
filterResonanceSlider.setSliderStyle(style);
filterResonanceSlider.setRange(rangeMin, rangeMax, rangeStep);
// filterResonanceSlider.onValueChange = makeSliderListener(filterResonanceSlider, static_cast<int>(SOUND_CTRL2));
filterResonanceSlider.onDragEnd = makeSliderListener(filterResonanceSlider, static_cast<int>(SOUND_CTRL2));
filterResonanceSlider.setTextBoxStyle(Slider::TextBoxBelow, true, filterResonanceSlider.getTextBoxWidth(), filterResonanceSlider.getTextBoxHeight());
filterResonanceSliderAttachment = make_unique<SliderAttachment>(valueTreeState, "filterResonance", filterResonanceSlider);