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

n2xVmMap.cpp (4972B)


      1 #include "n2xVmMap.h"
      2 
      3 #include "n2xController.h"
      4 #include "n2xEditor.h"
      5 
      6 namespace n2xJucePlugin
      7 {
      8 	constexpr const char* g_postfix = "Sens";
      9 
     10 	class SliderListener : public juce::Slider::Listener
     11 	{
     12 	public:
     13 		SliderListener() = delete;
     14 
     15 		SliderListener(const SliderListener&) = delete;
     16 		SliderListener(SliderListener&&) = default;
     17 
     18 		SliderListener& operator=(const SliderListener&) = delete;
     19 		SliderListener& operator=(SliderListener&&) = default;
     20 
     21 		SliderListener(juce::Slider* _slider, const std::function<void(juce::Slider*)>& _onValueChanged) : m_slider(_slider), m_onValueChanged(_onValueChanged)
     22 		{
     23 			_slider->addListener(this);
     24 		}
     25 		~SliderListener() override
     26 		{
     27 			m_slider->removeListener(this);
     28 		}
     29 		void sliderValueChanged(juce::Slider* _slider) override
     30 		{
     31 			if (m_onValueChanged)
     32 				m_onValueChanged(_slider);
     33 		}
     34 	private:
     35 		juce::Slider* m_slider;
     36 		std::function<void(juce::Slider*)> m_onValueChanged;
     37 	};
     38 
     39 	VmMap::VmMap(Editor& _editor, pluginLib::ParameterBinding& _binding)
     40 	: m_editor(_editor)
     41 	, m_btVmMap(_editor.findComponentT<juce::Button>("VMMAP"))
     42 	{
     43 		auto& c = _editor.getN2xController();
     44 
     45 		const auto& descs = c.getParameterDescriptions().getDescriptions();
     46 
     47 		for (const auto& desc : descs)
     48 		{
     49 			uint32_t idxBase, idxVm;
     50 
     51 			const auto& nameBase = desc.name;
     52 			const auto& nameVm = desc.name + g_postfix;
     53 
     54 			if(c.getParameterDescriptions().getIndexByName(idxBase, nameBase) &&
     55 				c.getParameterDescriptions().getIndexByName(idxVm, nameVm))
     56 			{
     57 				auto* compBase = _editor.findComponentByParamT<juce::Slider>(nameBase);
     58 				auto* compVm = _editor.findComponentByParamT<juce::Slider>(nameVm);
     59 
     60 				// we do not want vm params to be bound at all, we do this manually. Remove any binding that might still be present in a skin
     61 				_binding.unbind(compVm);
     62 
     63 				auto vmParam = std::make_unique<VmParam>();
     64 
     65 				vmParam->paramNameBase = nameBase;
     66 				vmParam->paramNameVm = nameVm;
     67 				vmParam->compBase = compBase;
     68 				vmParam->compVm = compVm;
     69 
     70 				vmParam->sliderListenerVm = new SliderListener(compVm, [this, vmParam = vmParam.get()](juce::Slider* _slider)
     71 				{
     72 					onVmSliderChanged(*vmParam);
     73 				});
     74 
     75 				m_vmParams.push_back(std::move(vmParam));
     76 			}
     77 		}
     78 
     79 		m_btVmMap->onClick = [this]
     80 		{
     81 			toggleVmMap(m_btVmMap->getToggleState());
     82 		};
     83 		m_onCurrentPartChanged.set(c.onCurrentPartChanged, [this](const uint8_t&/* _part*/)
     84 		{
     85 			onCurrentPartChanged();
     86 		});
     87 
     88 		bindAll();
     89 	}
     90 
     91 	void VmMap::setEnabled(bool _enabled)
     92 	{
     93 		toggleVmMap(_enabled);
     94 	}
     95 
     96 	VmMap::VmParam::~VmParam()
     97 	{
     98 		delete sliderListenerVm;
     99 	}
    100 
    101 	void VmMap::toggleVmMap(const bool _enabled)
    102 	{
    103 		if(m_enabled == _enabled)
    104 			return;
    105 
    106 		m_enabled = _enabled;
    107 
    108 		for (auto& vmParam : m_vmParams)
    109 		{
    110 			vmParam->compVm->setInterceptsMouseClicks(_enabled, _enabled);
    111 			vmParam->compBase->setInterceptsMouseClicks(!_enabled, !_enabled);
    112 			vmParam->compVm->setEnabled(_enabled);
    113 			vmParam->compBase->setEnabled(!_enabled);
    114 		}
    115 
    116 		m_btVmMap->setToggleState(_enabled, juce::dontSendNotification);
    117 	}
    118 
    119 	void VmMap::onCurrentPartChanged() const
    120 	{
    121 		bindAll();
    122 	}
    123 
    124 	void VmMap::bindAll() const
    125 	{
    126 		const auto part = m_editor.getN2xController().getCurrentPart();
    127 
    128 		for (auto& vmParamPtr : m_vmParams)
    129 		{
    130 			auto& vmParam = *vmParamPtr;
    131 
    132 			auto* paramBase = m_editor.getN2xController().getParameter(vmParam.paramNameBase, part);
    133 			auto* paramVm = m_editor.getN2xController().getParameter(vmParam.paramNameVm, part);
    134 
    135 			vmParam.paramBase = paramBase;
    136 			vmParam.paramVm = paramVm;
    137 
    138 			vmParam.parameterListenerBase.set(paramBase, [&vmParam, this](pluginLib::Parameter* _parameter)
    139 			{
    140 				onBaseParamChanged(vmParam, _parameter);
    141 			});
    142 
    143 			vmParam.parameterListenerVm.set(paramVm, [&vmParam, this](pluginLib::Parameter* _parameter)
    144 			{
    145 				onVmParamChanged(vmParam, _parameter);
    146 			});
    147 
    148 			updateVmSlider(vmParam);
    149 		}
    150 	}
    151 
    152 	void VmMap::onVmSliderChanged(const VmParam& _param) const
    153 	{
    154 		if (!_param.paramBase || !_param.paramVm)
    155 			return;
    156 
    157 		int value = juce::roundToInt(_param.compVm->getValue());
    158 		value -= _param.paramBase->getUnnormalizedValue();
    159 
    160 		_param.paramVm->setUnnormalizedValue(value, pluginLib::Parameter::Origin::Ui);
    161 
    162 		m_editor.getFocusedParameter().updateByComponent(_param.compVm);
    163 	}
    164 
    165 	void VmMap::onBaseParamChanged(const VmParam& _vmParam, pluginLib::Parameter*)
    166 	{
    167 		updateVmSlider(_vmParam);
    168 	}
    169 
    170 	void VmMap::onVmParamChanged(const VmParam& _vmParam, pluginLib::Parameter*)
    171 	{
    172 		updateVmSlider(_vmParam);
    173 	}
    174 
    175 	void VmMap::updateVmSlider(const VmParam& _vmParam)
    176 	{
    177 		const auto& range = _vmParam.compBase->getRange();
    178 		_vmParam.compVm->setRange(range.getStart(), range.getEnd());
    179 
    180 		const auto baseValue = _vmParam.paramBase->getUnnormalizedValue();
    181 
    182 		const auto offset = _vmParam.paramVm->getUnnormalizedValue();
    183 
    184 		_vmParam.compVm->setValue(baseValue + offset, juce::dontSendNotification);
    185 		_vmParam.compVm->setDoubleClickReturnValue(true, baseValue);
    186 
    187 		_vmParam.compVm->setAlpha(offset != 0 ? 1.0f : 0.0f);
    188 	}
    189 }