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 f345982ed854f9052d3fb8eff75c67a6435ea3a2
parent 193b780bfb63409ee9a6078113c2be42aa25f1a2
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Wed,  9 Mar 2022 23:53:14 +0100

link together DAW parameters that reference a single synth parameter

Diffstat:
Msource/jucePlugin/VirusController.cpp | 8++++++++
Msource/jucePlugin/VirusParameter.cpp | 66+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msource/jucePlugin/VirusParameter.h | 14++++++++++++--
3 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp @@ -89,6 +89,14 @@ namespace Virus auto p = std::make_unique<Parameter>(*this, desc, part, uid); + if(uid > 0) + { + const auto& existingParams = findSynthParam(idx); + + for (auto& existingParam : existingParams) + existingParam->addLinkedParameter(p.get()); + } + m_paramsByParamType[part].push_back(p.get()); const bool isNonPartExclusive = (desc.classFlags & Parameter::Class::GLOBAL) || (desc.classFlags & Parameter::Class::NON_PART_SENSITIVE); diff --git a/source/jucePlugin/VirusParameter.cpp b/source/jucePlugin/VirusParameter.cpp @@ -6,7 +6,7 @@ namespace Virus { Parameter::Parameter(Controller &ctrl, const Description& desc, const uint8_t partNum, const int uniqueId) : RangedAudioParameter(genId(desc, partNum, uniqueId), "Ch " + juce::String(partNum + 1) + " " + desc.name), m_ctrl(ctrl), - m_desc(desc), m_partNum(partNum) + m_desc(desc), m_partNum(partNum), m_uniqueId(uniqueId) { m_range.start = static_cast<float>(m_desc.range.getStart()); m_range.end = static_cast<float>(m_desc.range.getEnd()); @@ -29,10 +29,50 @@ namespace Virus onValueChanged(); } + void Parameter::setLinkedValue(const int _value) + { + const int newValue = juce::roundToInt(m_range.getRange().clipValue(static_cast<float>(_value))); + + if (newValue == m_lastValue) + return; + + m_lastValue = newValue; + + if(getDescription().isPublic) + { + beginChangeGesture(); + setValueNotifyingHost(convertTo0to1(static_cast<float>(newValue))); + endChangeGesture(); + } + else + { + m_value.setValue(newValue); + } + } + + void Parameter::setValue(float newValue) + { + if (m_changingLinkedValues) + return; + + m_value.setValue(convertFrom0to1(newValue)); + + m_changingLinkedValues = true; + + for (const auto& parameter : m_linkedParameters) + { + if(!parameter->m_changingLinkedValues) + parameter->setLinkedValue(m_value.getValue()); + } + + m_changingLinkedValues = false; + } + void Parameter::setValueFromSynth(int newValue, const bool notifyHost) { if (newValue == m_lastValue) return; + m_lastValue = newValue; if (notifyHost && getDescription().isPublic) @@ -45,6 +85,16 @@ namespace Virus { m_value.setValue(newValue); } + + if (m_changingLinkedValues) + return; + + m_changingLinkedValues = true; + + for (const auto& p : m_linkedParameters) + p->setLinkedValue(newValue); + + m_changingLinkedValues = false; } juce::String Parameter::genId(const Description &d, const int part, const int uniqueId) @@ -54,4 +104,18 @@ namespace Virus return juce::String::formatted("%d_%d_%d", static_cast<int>(d.page), part, d.index); } + void Parameter::addLinkedParameter(Parameter* _param) + { + if (_param == this) + return; + + for (auto* p : m_linkedParameters) + { + _param->m_linkedParameters.insert(p); + p->m_linkedParameters.insert(_param); + } + + m_linkedParameters.insert(_param); + _param->m_linkedParameters.insert(this); + } } // namespace Virus diff --git a/source/jucePlugin/VirusParameter.h b/source/jucePlugin/VirusParameter.h @@ -1,5 +1,7 @@ #pragma once +#include <set> + #include <juce_audio_processors/juce_audio_processors.h> #include "VirusParameterDescription.h" @@ -35,7 +37,7 @@ namespace Virus const juce::NormalisableRange<float> &getNormalisableRange() const override { return m_range; } float getValue() const override { return convertTo0to1(m_value.getValue()); } - void setValue(float newValue) override { return m_value.setValue(convertFrom0to1(newValue)); }; + void setValue(float newValue) override; void setValueFromSynth(int newValue, bool notifyHost = true); float getDefaultValue() const override { // default value should probably be in description instead of hardcoded like this. @@ -71,15 +73,23 @@ namespace Virus // eg. multi/single value change requires triggering more logic. std::function<void()> onValueChanged = {}; + void addLinkedParameter(Parameter* _param); + + int getUniqueId() const { return m_uniqueId; } + private: static juce::String genId(const Description &d, int part, int uniqueId); void valueChanged(juce::Value &) override; + void setLinkedValue(int _value); Controller &m_ctrl; const Description m_desc; juce::NormalisableRange<float> m_range; - uint8_t m_partNum; + const uint8_t m_partNum; + const int m_uniqueId; // 0 for all unique parameters, > 0 if multiple Parameter instances reference a single synth parameter int m_lastValue{-1}; juce::Value m_value; + std::set<Parameter*> m_linkedParameters; + bool m_changingLinkedValues = false; }; } // namespace Virus