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 abde6747a976d988fb7b483357d72b5cb4cbcced
parent 1705180a99d54c7a76f00180f3e7fb749c93225b
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Wed, 28 Aug 2024 21:50:46 +0200

support locked parameters

Diffstat:
Mdoc/changelog.txt | 1+
Msource/nord/n2x/n2xJucePlugin/n2xController.cpp | 57++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msource/nord/n2x/n2xJucePlugin/n2xController.h | 2+-
Msource/nord/n2x/n2xLib/n2xstate.cpp | 7++++++-
Msource/nord/n2x/n2xLib/n2xstate.h | 4+++-
5 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/doc/changelog.txt b/doc/changelog.txt @@ -6,6 +6,7 @@ Framework: - [Imp] Strip path names from skin names in GUI Skin submenu (mkruselj) +- [Fix] Region Locking is now implemented - [Fix] Crash when dragging a patch from Patch Manager to a part slot - [Fix] Crash when dragging a patch on empty area in grid view - [Fix] Drag target slot rectangles displayed in grid view for areas without content diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.cpp b/source/nord/n2x/n2xJucePlugin/n2xController.cpp @@ -337,11 +337,13 @@ namespace n2xJucePlugin return result; } - bool Controller::activatePatch(const std::vector<uint8_t>& _sysex, const uint32_t _part) const + bool Controller::activatePatch(const std::vector<uint8_t>& _sysex, const uint32_t _part) { if(_part >= getPartCount()) return false; + const auto part = static_cast<uint8_t>(_part); + const auto isSingle = n2x::State::isSingleDump(_sysex); const auto isMulti = n2x::State::isMultiDump(_sysex); @@ -354,10 +356,63 @@ namespace n2xJucePlugin d[n2x::SysexIndex::IdxMsgSpec] = static_cast<uint8_t>(isMulti ? 0 : _part); d[n2x::SysexIndex::IdxDevice] = n2x::DefaultDeviceId; + auto applyLockedParamsToSingle = [&](n2x::State::SingleDump& _dump, const uint8_t _singlePart) + { + const auto& lockedParameters = getParameterLocking().getLockedParameters(_singlePart); + + for (auto& lockedParam : lockedParameters) + { + const auto& name = lockedParam->getDescription().name; + + if(name == "Sync" || name == "RingMod" || name == "Distortion") + { + const auto current = n2x::State::getSingleParam(_dump, n2x::Sync, 0); + const auto value = combineSyncRingModDistortion(_singlePart, current, true); + n2x::State::changeSingleParameter(_dump, n2x::Sync, value); + } + else + { + const auto singleParam = static_cast<n2x::SingleParam>(lockedParam->getDescription().index); + const auto val = lockedParam->getUnnormalizedValue(); + n2x::State::changeSingleParameter(_dump, singleParam, static_cast<uint8_t>(val)); + } + } + }; + + if(isSingle) + { + if(!getParameterLocking().getLockedParameters(part).empty()) + { + n2x::State::SingleDump dump; + std::copy_n(d.begin(), d.size(), dump.begin()); + applyLockedParamsToSingle(dump, part); + std::copy_n(dump.begin(), d.size(), d.begin()); + } + } + else + { + n2x::State::MultiDump multi; + std::copy_n(d.begin(), d.size(), multi.begin()); + for(uint8_t i=0; i<4; ++i) + { + n2x::State::SingleDump single; + + for(uint8_t p=0; p<4; ++p) + { + n2x::State::extractSingleFromMulti(single, multi, p); + applyLockedParamsToSingle(single, p); + n2x::State::copySingleToMulti(multi, single, p); + } + } + std::copy_n(multi.begin(), d.size(), d.begin()); + } + pluginLib::Controller::sendSysEx(n2x::State::validateDump(d)); if(isSingle) + { requestDump(n2x::SysexByte::SingleRequestBankEditBuffer, static_cast<uint8_t>(_part)); + } else { requestDump(n2x::SysexByte::MultiRequestBankEditBuffer, 0); diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h @@ -51,7 +51,7 @@ namespace n2xJucePlugin std::vector<uint8_t> createSingleDump(uint8_t _bank, uint8_t _program, uint8_t _part) const; std::vector<uint8_t> createMultiDump(n2x::SysexByte _bank, uint8_t _program); - bool activatePatch(const std::vector<uint8_t>& _sysex, uint32_t _part) const; + bool activatePatch(const std::vector<uint8_t>& _sysex, uint32_t _part); bool isDerivedParameter(pluginLib::Parameter& _derived, pluginLib::Parameter& _base) const override; diff --git a/source/nord/n2x/n2xLib/n2xstate.cpp b/source/nord/n2x/n2xLib/n2xstate.cpp @@ -351,7 +351,7 @@ namespace n2x { if(_part >= m_singles.size()) return false; - return changeDumpParameter(m_singles[_part], getOffsetInSingleDump(_parameter), _value); + return changeSingleParameter(m_singles[_part], _parameter, _value); } bool State::changeMultiParameter(const MultiParam _parameter, const uint8_t _value) @@ -359,6 +359,11 @@ namespace n2x return changeDumpParameter(m_multi, getOffsetInMultiDump(_parameter), _value); } + bool State::changeSingleParameter(SingleDump& _dump, const SingleParam _param, const uint8_t _value) + { + return changeDumpParameter(_dump, getOffsetInSingleDump(_param), _value); + } + void State::updateMultiFromSingles() { for(uint8_t i=0; i<static_cast<uint8_t>(m_singles.size()); ++i) diff --git a/source/nord/n2x/n2xLib/n2xstate.h b/source/nord/n2x/n2xLib/n2xstate.h @@ -39,8 +39,10 @@ namespace n2x bool changeSingleParameter(uint8_t _part, SingleParam _parameter, uint8_t _value); bool changeMultiParameter(MultiParam _parameter, uint8_t _value); + static bool changeSingleParameter(SingleDump& _dump, SingleParam _param, uint8_t _value); + template<typename TDump> - bool changeDumpParameter(TDump& _dump, uint32_t _offset, uint8_t _value) + static bool changeDumpParameter(TDump& _dump, uint32_t _offset, uint8_t _value) { const auto current = unpackNibbles(_dump, _offset); if(current == _value)