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 bdab0d8911f4f512a181d53a8358c31149af7615
parent 78e63609576bf53ed907a05934bf64667d16f193
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Tue, 28 Dec 2021 22:53:31 +0100

introduce parameter binding class and bind the first knobs

Diffstat:
Msource/jucePlugin/CMakeLists.txt | 2++
Msource/jucePlugin/PluginEditor.cpp | 5+++--
Msource/jucePlugin/PluginEditor.h | 3++-
Msource/jucePlugin/VirusController.cpp | 11++++++++---
Msource/jucePlugin/VirusController.h | 1+
Msource/jucePlugin/VirusParameter.h | 3+--
Asource/jucePlugin/VirusParameterBinding.cpp | 16++++++++++++++++
Asource/jucePlugin/VirusParameterBinding.h | 20++++++++++++++++++++
Msource/jucePlugin/ui/VirusEditor.cpp | 10+++++-----
Msource/jucePlugin/ui/VirusEditor.h | 6++++--
Msource/jucePlugin/ui/Virus_ArpEditor.cpp | 2+-
Msource/jucePlugin/ui/Virus_ArpEditor.h | 4+++-
Msource/jucePlugin/ui/Virus_FxEditor.cpp | 2+-
Msource/jucePlugin/ui/Virus_FxEditor.h | 4+++-
Msource/jucePlugin/ui/Virus_LfoEditor.cpp | 14+++++++-------
Msource/jucePlugin/ui/Virus_LfoEditor.h | 16+++++++++-------
Msource/jucePlugin/ui/Virus_OscEditor.cpp | 33+++++++++++++++++++++------------
Msource/jucePlugin/ui/Virus_OscEditor.h | 30+++++++++++++++++-------------
18 files changed, 124 insertions(+), 58 deletions(-)

diff --git a/source/jucePlugin/CMakeLists.txt b/source/jucePlugin/CMakeLists.txt @@ -52,6 +52,8 @@ PRIVATE VirusController.h VirusParameter.cpp VirusParameter.h + VirusParameterBinding.cpp + VirusParameterBinding.h version.h ) diff --git a/source/jucePlugin/PluginEditor.cpp b/source/jucePlugin/PluginEditor.cpp @@ -8,8 +8,9 @@ //============================================================================== AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudioProcessor &p) : AudioProcessorEditor(&p), processorRef(p), m_btSingleMode("Single Mode"), m_btMultiMode("Multi Mode"), + m_parameterBinding(p), m_btLoadFile("Load bank"), m_cmbMidiInput("Midi Input"), m_cmbMidiOutput("Midi Output"), - deviceManager(), m_tempEditor(p) + m_tempEditor(p) { ignoreUnused (processorRef); @@ -157,7 +158,7 @@ AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor(AudioPluginAudi m_virusEditor->setUsingNativeTitleBar(true); m_virusEditor->setVisible(true); m_virusEditor->setResizable(true, false); - m_virusEditor->setContentOwned(new VirusEditor(), true); + m_virusEditor->setContentOwned(new VirusEditor(m_parameterBinding), true); }; addAndMakeVisible(m_openEditor); } diff --git a/source/jucePlugin/PluginEditor.h b/source/jucePlugin/PluginEditor.h @@ -1,5 +1,6 @@ #pragma once +#include "VirusParameterBinding.h" #include "PluginProcessor.h" #include <juce_audio_devices/juce_audio_devices.h> //============================================================================== @@ -23,7 +24,7 @@ private: // This reference is provided as a quick way for your editor to // access the processor object that created it. AudioPluginAudioProcessor& processorRef; - + VirusParameterBinding m_parameterBinding; juce::GenericAudioProcessorEditor m_tempEditor; juce::TextButton m_partSelectors[16]; juce::TextButton m_prevPatch[16]; diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp @@ -167,15 +167,20 @@ namespace Virus juce::Value* Controller::getParamValue(const ParameterType _param) { + auto res = getParameter(_param); + return res ? &res->getValueObject() : nullptr; + } + + Parameter* Controller::getParameter(const ParameterType _param) + { const auto it = m_paramTypeToParamIndex.find(_param); if (it == m_paramTypeToParamIndex.end()) return nullptr; const auto& index = it->second; - auto res = findSynthParam(index); - return res ? &res->getValueObject() : nullptr; - } + return findSynthParam(index); + } void Controller::parseParamChange(const SysEx &msg) { diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h @@ -396,6 +396,7 @@ namespace Virus // paramIndex - [0-127] juce::Value *getParamValue(uint8_t ch, uint8_t bank, uint8_t paramIndex); juce::Value *getParamValue(ParameterType _param); + Parameter* getParameter(ParameterType _param); // bank - 0-1 (AB) juce::StringArray getSinglePresetNames(int bank) const; diff --git a/source/jucePlugin/VirusParameter.h b/source/jucePlugin/VirusParameter.h @@ -4,10 +4,9 @@ namespace Virus { - class Controller; - class Parameter : private juce::Value::Listener, public juce::RangedAudioParameter + class Parameter : juce::Value::Listener, public juce::RangedAudioParameter { public: enum Class diff --git a/source/jucePlugin/VirusParameterBinding.cpp b/source/jucePlugin/VirusParameterBinding.cpp @@ -0,0 +1,16 @@ +#include "VirusParameterBinding.h" + +#include "PluginProcessor.h" + +void VirusParameterBinding::bind(juce::Slider& _slider, Virus::ParameterType _param) const +{ + const auto v = m_processor.getController().getParameter(_param); + if (!v) + { + assert(false && "Failed to find parameter"); + return; + } + const auto range = v->getNormalisableRange(); + _slider.setRange(range.start, range.end, range.interval); + _slider.getValueObject().referTo(v->getValueObject()); +} diff --git a/source/jucePlugin/VirusParameterBinding.h b/source/jucePlugin/VirusParameterBinding.h @@ -0,0 +1,20 @@ +#pragma once +#include "VirusController.h" + +namespace juce { + class Value; +} + +class AudioPluginAudioProcessor; + +class VirusParameterBinding +{ +public: + VirusParameterBinding(AudioPluginAudioProcessor& _processor) : m_processor(_processor) + { + } + + void bind(juce::Slider& _control, Virus::ParameterType _param) const; + + AudioPluginAudioProcessor& m_processor; +}; diff --git a/source/jucePlugin/ui/VirusEditor.cpp b/source/jucePlugin/ui/VirusEditor.cpp @@ -11,7 +11,7 @@ using namespace juce; constexpr auto kPanelWidth = 1377; constexpr auto kPanelHeight = 800; -VirusEditor::VirusEditor() +VirusEditor::VirusEditor(VirusParameterBinding& _parameterBinding) : m_parameterBinding(_parameterBinding) { setLookAndFeel(&m_lookAndFeel); @@ -21,10 +21,10 @@ VirusEditor::VirusEditor() addAndMakeVisible (*m_background); addAndMakeVisible (m_mainButtons); - m_arpEditor = std::make_unique<ArpEditor>(); - m_fxEditor = std::make_unique<FxEditor>(); - m_lfoEditor = std::make_unique<LfoEditor>(); - m_oscEditor = std::make_unique<OscEditor>(); + m_arpEditor = std::make_unique<ArpEditor>(_parameterBinding); + m_fxEditor = std::make_unique<FxEditor>(_parameterBinding); + m_lfoEditor = std::make_unique<LfoEditor>(_parameterBinding); + m_oscEditor = std::make_unique<OscEditor>(_parameterBinding); applyToSections([this](Component *s) { addChildComponent(s); }); diff --git a/source/jucePlugin/ui/VirusEditor.h b/source/jucePlugin/ui/VirusEditor.h @@ -4,6 +4,7 @@ #include "Virus_Buttons.h" #include "Virus_LookAndFeel.h" +class VirusParameterBinding; class OscEditor; class LfoEditor; class FxEditor; @@ -12,8 +13,8 @@ class ArpEditor; class VirusEditor : public juce::Component { public: - VirusEditor(); - ~VirusEditor(); + VirusEditor(VirusParameterBinding& _parameterBinding); + ~VirusEditor() override; void resized() override; private: @@ -39,6 +40,7 @@ private: void applyToSections(std::function<void(juce::Component *)>); + VirusParameterBinding& m_parameterBinding; std::unique_ptr<OscEditor> m_oscEditor; std::unique_ptr<LfoEditor> m_lfoEditor; std::unique_ptr<FxEditor> m_fxEditor; diff --git a/source/jucePlugin/ui/Virus_ArpEditor.cpp b/source/jucePlugin/ui/Virus_ArpEditor.cpp @@ -6,7 +6,7 @@ constexpr auto comboBoxWidth = 84; using namespace juce; -ArpEditor::ArpEditor() +ArpEditor::ArpEditor(VirusParameterBinding& _parameterBinding) { setupBackground(*this, m_background, BinaryData::bg_arp_1018x620_png, BinaryData::bg_arp_1018x620_pngSize); setBounds(m_background->getDrawableBounds().toNearestIntEdges()); diff --git a/source/jucePlugin/ui/Virus_ArpEditor.h b/source/jucePlugin/ui/Virus_ArpEditor.h @@ -2,10 +2,12 @@ #include "../PluginProcessor.h" +class VirusParameterBinding; + class ArpEditor : public juce::Component { public: - ArpEditor(); + ArpEditor(VirusParameterBinding& _parameterBinding); private: struct VelocityAmount : juce::Component diff --git a/source/jucePlugin/ui/Virus_FxEditor.cpp b/source/jucePlugin/ui/Virus_FxEditor.cpp @@ -6,7 +6,7 @@ using namespace juce; constexpr auto comboBoxWidth = 84; -FxEditor::FxEditor() +FxEditor::FxEditor(VirusParameterBinding& _parameterBinding) { setupBackground(*this, m_background, BinaryData::bg_fx_1018x620_png, BinaryData::bg_fx_1018x620_pngSize); setBounds(m_background->getDrawableBounds().toNearestIntEdges()); diff --git a/source/jucePlugin/ui/Virus_FxEditor.h b/source/jucePlugin/ui/Virus_FxEditor.h @@ -3,10 +3,12 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" +class VirusParameterBinding; + class FxEditor : public juce::Component { public: - FxEditor(); + FxEditor(VirusParameterBinding& _parameterBinding); private: struct Distortion : juce::Component diff --git a/source/jucePlugin/ui/Virus_LfoEditor.cpp b/source/jucePlugin/ui/Virus_LfoEditor.cpp @@ -5,7 +5,7 @@ using namespace juce; constexpr auto comboBoxWidth = 98; -LfoEditor::LfoEditor() +LfoEditor::LfoEditor(VirusParameterBinding& _parameterBinding) : m_lfoOne(_parameterBinding), m_lfoTwo(_parameterBinding), m_lfoThree(_parameterBinding), m_modMatrix(_parameterBinding) { setupBackground(*this, m_background, BinaryData::bg_lfo_1018x620_png, BinaryData::bg_lfo_1018x620_pngSize); setBounds(m_background->getDrawableBounds().toNearestIntEdges()); @@ -22,7 +22,7 @@ LfoEditor::LfoEditor() addAndMakeVisible(m_modMatrix); } -LfoEditor::LfoBase::LfoBase() +LfoEditor::LfoBase::LfoBase(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_rate, &m_keytrack, &m_amount}) setupRotary(*this, *s); @@ -36,7 +36,7 @@ LfoEditor::LfoBase::LfoBase() addAndMakeVisible(m_assignDest); } -LfoEditor::LfoTwoOneShared::LfoTwoOneShared() : m_link(false) +LfoEditor::LfoTwoOneShared::LfoTwoOneShared(VirusParameterBinding& _parameterBinding) : LfoBase(_parameterBinding), m_link(false) { for (auto *s : {&m_contour, &m_phase}) setupRotary(*this, *s); @@ -52,7 +52,7 @@ LfoEditor::LfoTwoOneShared::LfoTwoOneShared() : m_link(false) m_assignDest.setBounds(393, 122, comboBoxWidth, comboBoxHeight); } -LfoEditor::LfoOne::LfoOne() +LfoEditor::LfoOne::LfoOne(VirusParameterBinding& _parameterBinding) : LfoTwoOneShared(_parameterBinding) { for (auto *s : {&m_osc1Pitch, &m_osc2Pitch, &m_filterGain, &m_pw12, &m_reso12}) setupRotary(*this, *s); @@ -64,7 +64,7 @@ LfoEditor::LfoOne::LfoOne() addAndMakeVisible(m_link); // add last to allow clicking over knobs area... } -LfoEditor::LfoTwo::LfoTwo() +LfoEditor::LfoTwo::LfoTwo(VirusParameterBinding& _parameterBinding) : LfoTwoOneShared(_parameterBinding) { for (auto *s : {&m_f1cutoff, &m_f2cutoff, &m_panning, &m_shape12, &m_fmAmount}) setupRotary(*this, *s); @@ -76,7 +76,7 @@ LfoEditor::LfoTwo::LfoTwo() addAndMakeVisible(m_link); // add last to allow clicking over knobs area... } -LfoEditor::LfoThree::LfoThree() +LfoEditor::LfoThree::LfoThree(VirusParameterBinding& _parameterBinding) : LfoBase(_parameterBinding) { setupRotary(*this, m_fadeIn); m_rate.setBounds(107, 22, knobSize, knobSize); @@ -86,7 +86,7 @@ LfoEditor::LfoThree::LfoThree() m_assignDest.setBounds(393, 45, comboBoxWidth, comboBoxHeight); } -LfoEditor::ModMatrix::ModMatrix() +LfoEditor::ModMatrix::ModMatrix(VirusParameterBinding& _parameterBinding) { constexpr auto kNumOfSlots = 6; for (auto s = 0; s < kNumOfSlots; s++) diff --git a/source/jucePlugin/ui/Virus_LfoEditor.h b/source/jucePlugin/ui/Virus_LfoEditor.h @@ -3,15 +3,17 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" +class VirusParameterBinding; + class LfoEditor : public juce::Component { public: - LfoEditor(); + LfoEditor(VirusParameterBinding& _parameterBinding); private: struct LfoBase : juce::Component { - LfoBase(); + LfoBase(VirusParameterBinding& _parameterBinding); juce::Slider m_rate; juce::Slider m_keytrack; juce::Slider m_amount; @@ -22,7 +24,7 @@ private: struct LfoTwoOneShared : LfoBase { - LfoTwoOneShared(); + LfoTwoOneShared(VirusParameterBinding& _parameterBinding); juce::Slider m_contour; juce::Slider m_phase; Buttons::LfoButton m_envMode; @@ -31,7 +33,7 @@ private: struct LfoOne : LfoTwoOneShared { - LfoOne(); + LfoOne(VirusParameterBinding& _parameterBinding); juce::Slider m_osc1Pitch; juce::Slider m_osc2Pitch; juce::Slider m_filterGain; @@ -41,7 +43,7 @@ private: struct LfoTwo : LfoTwoOneShared { - LfoTwo(); + LfoTwo(VirusParameterBinding& _parameterBinding); juce::Slider m_f1cutoff; juce::Slider m_f2cutoff; juce::Slider m_panning; @@ -51,13 +53,13 @@ private: struct LfoThree : LfoBase { - LfoThree(); + LfoThree(VirusParameterBinding& _parameterBinding); juce::Slider m_fadeIn; } m_lfoThree; struct ModMatrix : juce::Component { - ModMatrix(); + ModMatrix(VirusParameterBinding& _parameterBinding); void setupSlot(int slot, std::initializer_list<juce::Point<int>> destsPos, juce::Point<int> sourcePos); struct MatrixSlot : juce::Component { diff --git a/source/jucePlugin/ui/Virus_OscEditor.cpp b/source/jucePlugin/ui/Virus_OscEditor.cpp @@ -1,12 +1,15 @@ #include "Virus_OscEditor.h" #include "BinaryData.h" #include "Ui_Utils.h" +#include "../VirusParameterBinding.h" using namespace juce; constexpr auto comboBoxWidth = 84; -OscEditor::OscEditor() +OscEditor::OscEditor(VirusParameterBinding& _parameterBinding) +: m_oscOne(_parameterBinding, 0), m_oscTwo(_parameterBinding), m_oscThree(_parameterBinding) +, m_unison(_parameterBinding), m_mixer(_parameterBinding), m_ringMod(_parameterBinding), m_sub(_parameterBinding), m_portamento(_parameterBinding), m_filters(_parameterBinding), m_filterEnv(_parameterBinding), m_ampEnv(_parameterBinding) { setupBackground(*this, m_background, BinaryData::bg_osc_1018x620_png, BinaryData::bg_osc_1018x620_pngSize); setBounds(m_background->getDrawableBounds().toNearestIntEdges()); @@ -42,7 +45,7 @@ void OscEditor::resized() Buttons::SyncButton::kWidth, Buttons::SyncButton::kHeight); } -OscEditor::OscOne::OscOne() +OscEditor::OscOne::OscOne(VirusParameterBinding& _parameterBinding, uint32_t _oscIndex) { for (auto *s : {&m_shape, &m_pulseWidth, &m_semitone, &m_keyFollow}) setupRotary(*this, *s); @@ -53,9 +56,15 @@ OscEditor::OscOne::OscOne() addAndMakeVisible(m_waveSelect); m_waveSelect.setBounds (18, 42, comboBoxWidth, comboBoxHeight); + + _parameterBinding.bind(m_semitone, _oscIndex == 0 ? Virus::Param_Osc1Semitone : Virus::Param_Osc2Semitone); + _parameterBinding.bind(m_shape, _oscIndex == 0 ? Virus::Param_Osc1Shape : Virus::Param_Osc2Shape); + _parameterBinding.bind(m_pulseWidth, _oscIndex == 0 ? Virus::Param_Osc1PW : Virus::Param_Osc2PW); + _parameterBinding.bind(m_keyFollow, _oscIndex == 0 ? Virus::Param_Osc1Keyfollow : Virus::Param_Osc2Keyfollow); +// _parameterBinding.bind(m_waveSelect, _oscIndex == 0 ? Virus::Param_Osc1Wave : Virus::Param_Osc2Wave); } -OscEditor::OscTwo::OscTwo() +OscEditor::OscTwo::OscTwo(VirusParameterBinding& _parameterBinding) : OscOne(_parameterBinding, 1) { for (auto *s : {&m_fmAmount, &m_detune, &m_envFm, &m_envOsc2}) setupRotary(*this, *s); @@ -67,7 +76,7 @@ OscEditor::OscTwo::OscTwo() m_fmMode.setBounds (18, 140, comboBoxWidth, comboBoxHeight); } -OscEditor::OscThree::OscThree() +OscEditor::OscThree::OscThree(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_semitone, &m_detune, &m_level}) setupRotary(*this, *s); @@ -79,7 +88,7 @@ OscEditor::OscThree::OscThree() m_oscThreeMode.setBounds (18, 43, comboBoxWidth, comboBoxHeight); } -OscEditor::Unison::Unison() +OscEditor::Unison::Unison(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_detune, &m_panSpread, &m_lfoPhase, &m_phaseInit}) setupRotary(*this, *s); @@ -91,7 +100,7 @@ OscEditor::Unison::Unison() m_unisonVoices.setBounds (18, 42, comboBoxWidth, comboBoxHeight); } -OscEditor::Mixer::Mixer() +OscEditor::Mixer::Mixer(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_oscBalance, &m_oscLevel}) setupRotary(*this, *s); @@ -100,7 +109,7 @@ OscEditor::Mixer::Mixer() m_oscLevel.setBounds(m_oscBalance.getBounds().translated(knobSize, 0)); } -OscEditor::RingMod::RingMod() +OscEditor::RingMod::RingMod(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_noiseLevel, &m_ringModLevel, &m_noiseColor}) setupRotary(*this, *s); @@ -111,7 +120,7 @@ OscEditor::RingMod::RingMod() m_noiseColor.setBounds(m_noiseLevel.getBounds().translated(0, 95)); } -OscEditor::Sub::Sub() +OscEditor::Sub::Sub(VirusParameterBinding& _parameterBinding) { setupRotary(*this, m_level); m_level.getProperties().set(Virus::LookAndFeel::KnobStyleProp, Virus::LookAndFeel::KnobStyle::GENERIC_RED); @@ -120,13 +129,13 @@ OscEditor::Sub::Sub() addAndMakeVisible(m_subWaveform); } -OscEditor::Portamento::Portamento() +OscEditor::Portamento::Portamento(VirusParameterBinding& _parameterBinding) { setupRotary(*this, m_portamento); m_portamento.setBounds(12, 18, knobSize, knobSize); } -OscEditor::Filters::Filters() : m_link1(true), m_link2(true) +OscEditor::Filters::Filters(VirusParameterBinding& _parameterBinding) : m_filter{_parameterBinding,_parameterBinding}, m_link1(true), m_link2(true) { addAndMakeVisible(m_filter[0]); addAndMakeVisible(m_filter[1]); @@ -155,7 +164,7 @@ OscEditor::Filters::Filters() : m_link1(true), m_link2(true) m_keyFollowBase.setBounds (m_filterMode[0].getBounds().translated (286, 0)); } -OscEditor::Filters::Filter::Filter() +OscEditor::Filters::Filter::Filter(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_cutoff, &m_res, &m_envAmount, &m_keyTrack, &m_resVel, &m_envVel}) setupRotary(*this, *s); @@ -167,7 +176,7 @@ OscEditor::Filters::Filter::Filter() m_envVel.setBounds(m_resVel.getBounds().translated(knobSize - 5, 0)); } -OscEditor::Envelope::Envelope() +OscEditor::Envelope::Envelope(VirusParameterBinding& _parameterBinding) { for (auto *s : {&m_attack, &m_decay, &m_sustain, &m_time, &m_release}) setupRotary(*this, *s); diff --git a/source/jucePlugin/ui/Virus_OscEditor.h b/source/jucePlugin/ui/Virus_OscEditor.h @@ -3,16 +3,18 @@ #include "../PluginProcessor.h" #include "Virus_Buttons.h" +class VirusParameterBinding; + class OscEditor : public juce::Component { public: - OscEditor(); + OscEditor(VirusParameterBinding& _parameterBinding); void resized() override; private: struct OscOne : juce::Component { - OscOne(); + OscOne(VirusParameterBinding& _parameterBinding, uint32_t _oscIndex); juce::Slider m_shape; juce::Slider m_pulseWidth; juce::Slider m_semitone; @@ -22,14 +24,14 @@ private: struct OscTwo : OscOne { - OscTwo(); + OscTwo(VirusParameterBinding& _parameterBinding); juce::Slider m_fmAmount, m_detune, m_envFm, m_envOsc2; juce::ComboBox m_fmMode; } m_oscTwo; struct OscThree : juce::Component { - OscThree(); + OscThree(VirusParameterBinding& _parameterBinding); juce::Slider m_semitone; juce::Slider m_detune; juce::Slider m_level; @@ -38,7 +40,7 @@ private: struct Unison : juce::Component { - Unison(); + Unison(VirusParameterBinding& _parameterBinding); juce::Slider m_detune; juce::Slider m_panSpread; juce::Slider m_lfoPhase; @@ -48,14 +50,14 @@ private: struct Mixer : juce::Component { - Mixer(); + Mixer(VirusParameterBinding& _parameterBinding); juce::Slider m_oscBalance; juce::Slider m_oscLevel; } m_mixer; struct RingMod : juce::Component { - RingMod(); + RingMod(VirusParameterBinding& _parameterBinding); juce::Slider m_noiseLevel; juce::Slider m_ringModLevel; juce::Slider m_noiseColor; @@ -64,23 +66,23 @@ private: struct Sub : juce::Component { - Sub(); + Sub(VirusParameterBinding& _parameterBinding); juce::Slider m_level; Buttons::HandleButton m_subWaveform; } m_sub; struct Portamento : juce::Component { - Portamento(); + Portamento(VirusParameterBinding& _parameterBinding); juce::Slider m_portamento; } m_portamento; struct Filters : juce::Component { - Filters(); + Filters(VirusParameterBinding& _parameterBinding); struct Filter : juce::Component { - Filter(); + Filter(VirusParameterBinding& _parameterBinding); juce::Slider m_cutoff; juce::Slider m_res; juce::Slider m_envAmount; @@ -97,7 +99,7 @@ private: struct Envelope : juce::Component { - Envelope(); + Envelope(VirusParameterBinding& _parameterBinding); juce::Slider m_attack; juce::Slider m_decay; juce::Slider m_sustain; @@ -107,11 +109,13 @@ private: struct FilterEnv : Envelope { + FilterEnv(VirusParameterBinding& _parameterBinding) : Envelope(_parameterBinding) {} } m_filterEnv; struct AmpEnv : Envelope { - } m_ampEnv; + AmpEnv(VirusParameterBinding& _parameterBinding) : Envelope(_parameterBinding) {} + } m_ampEnv; Buttons::SyncButton m_oscSync; std::unique_ptr<juce::Drawable> m_background;