gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit b08056e9e5d36ad684d770057f7a7c4284fe7f2a
parent f512241114a63627ebe15ecf877692b7fc7879eb
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Tue, 15 Mar 2022 21:06:04 +0100

rework virus parameter binding to be able to rebind a control to a different parameter without the need to recreate it

Diffstat:
Msource/jucePlugin/VirusParameterBinding.cpp | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msource/jucePlugin/VirusParameterBinding.h | 17++++++++++++++---
2 files changed, 84 insertions(+), 21 deletions(-)

diff --git a/source/jucePlugin/VirusParameterBinding.cpp b/source/jucePlugin/VirusParameterBinding.cpp @@ -8,25 +8,65 @@ VirusParameterBinding::~VirusParameterBinding() { clearBindings(); } -void VirusParameterBinding::clearBindings() { + +void VirusParameterBinding::clearBindings() +{ for (const auto b : m_bindings) - { - b->onValueChanged = nullptr; - } + b.parameter->onValueChanged = nullptr; m_bindings.clear(); } + void VirusParameterBinding::setPart(uint8_t _part) { - clearBindings(); m_processor.getController().setCurrentPart(_part); + + std::vector<BoundParameter> bindings; + bindings.swap(m_bindings); + + for(size_t i=0; i<bindings.size(); ++i) + { + auto& b = bindings[i]; + + if(b.part != CurrentPart) + { + m_bindings.push_back(b); + continue; + } + + const auto& desc = b.parameter->getDescription(); + const bool isNonPartExclusive = (desc.classFlags & Virus::Parameter::Class::GLOBAL) || (desc.classFlags & Virus::Parameter::Class::NON_PART_SENSITIVE); + + if(isNonPartExclusive) + continue; + + auto* slider = dynamic_cast<juce::Slider*>(b.component); + if(slider) + { + bind(*slider, b.type); + continue; + } + auto* button = dynamic_cast<juce::DrawableButton*>(b.component); + if(button) + { + bind(*button, b.type); + continue; + } + auto* comboBox = dynamic_cast<juce::ComboBox*>(b.component); + if(comboBox) + { + bind(*comboBox, b.type); + continue; + } + assert(false && "unknown component type"); + } } void VirusParameterBinding::bind(juce::Slider &_slider, Virus::ParameterType _param) { - bind(_slider, _param, m_processor.getController().getCurrentPart()); + bind(_slider, _param, CurrentPart); } -void VirusParameterBinding::bind(juce::Slider &_slider, Virus::ParameterType _param, uint8_t part) +void VirusParameterBinding::bind(juce::Slider &_slider, Virus::ParameterType _param, const uint8_t _part) { - const auto v = m_processor.getController().getParameter(_param, part); + const auto v = m_processor.getController().getParameter(_param, _part == CurrentPart ? m_processor.getController().getCurrentPart() : _part); if (!v) { assert(false && "Failed to find parameter"); @@ -42,39 +82,49 @@ void VirusParameterBinding::bind(juce::Slider &_slider, Virus::ParameterType _pa if (v->isBipolar()) { _slider.getProperties().set("bipolar", true); } + const BoundParameter p{v, &_slider, _param, _part}; + m_bindings.emplace_back(p); } -void VirusParameterBinding::bind(juce::ComboBox& _combo, Virus::ParameterType _param) { - bind(_combo, _param, m_processor.getController().getCurrentPart()); + +void VirusParameterBinding::bind(juce::ComboBox& _combo, Virus::ParameterType _param) +{ + bind(_combo, _param, CurrentPart); } -void VirusParameterBinding::bind(juce::ComboBox& _combo, Virus::ParameterType _param, uint8_t _part) + +void VirusParameterBinding::bind(juce::ComboBox& _combo, const Virus::ParameterType _param, uint8_t _part) { - const auto v = m_processor.getController().getParameter(_param, _part); + const auto v = m_processor.getController().getParameter(_param, _part == CurrentPart ? m_processor.getController().getCurrentPart() : _part); if (!v) { assert(false && "Failed to find parameter"); return; } - _combo.setTextWhenNothingSelected("--"); + _combo.setTextWhenNothingSelected("-"); _combo.setScrollWheelEnabled(true); + + _combo.onChange = nullptr; + _combo.clear(); + int idx = 1; - for (auto vs : v->getAllValueStrings()) { + for (const auto& vs : v->getAllValueStrings()) { if(vs.isNotEmpty()) _combo.addItem(vs, idx); idx++; } //_combo.addItemList(v->getAllValueStrings(), 1); - _combo.setSelectedId((int)v->getValueObject().getValueSource().getValue() + 1, juce::dontSendNotification); + _combo.setSelectedId(static_cast<int>(v->getValueObject().getValueSource().getValue()) + 1, juce::dontSendNotification); _combo.onChange = [this, &_combo, v]() { v->beginChangeGesture(); v->setValueNotifyingHost(v->convertTo0to1(static_cast<float>(_combo.getSelectedId() - 1))); v->endChangeGesture(); v->getValueObject().getValueSource().setValue((int)_combo.getSelectedId() - 1); }; - v->onValueChanged = [this, &_combo, v]() { _combo.setSelectedId((int)v->getValueObject().getValueSource().getValue() + 1, juce::dontSendNotification); }; - m_bindings.add(v); + v->onValueChanged = [this, &_combo, v]() { _combo.setSelectedId(static_cast<int>(v->getValueObject().getValueSource().getValue()) + 1, juce::dontSendNotification); }; + const BoundParameter p{v, &_combo, _param, _part}; + m_bindings.emplace_back(p); } -void VirusParameterBinding::bind(juce::DrawableButton &_btn, Virus::ParameterType _param) +void VirusParameterBinding::bind(juce::Button &_btn, const Virus::ParameterType _param) { const auto v = m_processor.getController().getParameter(_param, m_processor.getController().getCurrentPart()); if (!v) @@ -83,4 +133,6 @@ void VirusParameterBinding::bind(juce::DrawableButton &_btn, Virus::ParameterTyp return; } _btn.getToggleStateValue().referTo(v->getValueObject()); + const BoundParameter p{v, &_btn, _param, CurrentPart}; + m_bindings.emplace_back(p); } diff --git a/source/jucePlugin/VirusParameterBinding.h b/source/jucePlugin/VirusParameterBinding.h @@ -1,5 +1,5 @@ #pragma once -#include "VirusController.h" + #include "VirusParameter.h" #include "ui/Virus_Buttons.h" namespace juce { @@ -34,8 +34,19 @@ public: void bind(juce::Slider& _control, Virus::ParameterType _param, uint8_t _part); void bind(juce::ComboBox &_control, Virus::ParameterType _param); void bind(juce::ComboBox &_control, Virus::ParameterType _param, uint8_t _part); - void bind(juce::DrawableButton &_control, Virus::ParameterType _param); + void bind(juce::Button &_control, Virus::ParameterType _param); AudioPluginAudioProcessor& m_processor; - juce::Array<Virus::Parameter*> m_bindings; + + static constexpr uint8_t CurrentPart = 0xff; + + struct BoundParameter + { + Virus::Parameter* parameter = nullptr; + juce::Component* component = nullptr; + Virus::ParameterType type = Virus::Param_Invalid; + uint8_t part = CurrentPart; + }; + + std::vector<BoundParameter> m_bindings; };