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

fix crash when changing filter distortion if sysex has to be used to change the parameter due to part overlapping

Diffstat:
Mdoc/changelog.txt | 2++
Msource/nord/n2x/n2xJucePlugin/n2xController.cpp | 52+++++++++++++++++++++++++++++++++++++++++++++++-----
Msource/nord/n2x/n2xJucePlugin/n2xController.h | 2++
3 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/doc/changelog.txt b/doc/changelog.txt @@ -9,6 +9,8 @@ Framework: - [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 +- [Fix] Crash when toggling filter distortion on a part that shares the same MIDI + channel with another part NodalRed2x: diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.cpp b/source/nord/n2x/n2xJucePlugin/n2xController.cpp @@ -222,10 +222,8 @@ namespace n2xJucePlugin if(cc == n2x::ControlChange::CCSync) { // sync and ringmod have the same CC, combine them - const auto* paramSync = getParameter("Sync", part); - const auto* paramRingMod = getParameter("RingMod", part); - - _value = static_cast<uint8_t>(paramSync->getUnnormalizedValue() | (paramRingMod->getUnnormalizedValue() << 1)); + const auto v = combineSyncRingModDistortion(part, 0, false); + _value = v & 3; // strip Distortion, it has its own CC } const auto ch = m_state.getPartMidiChannel(part); @@ -238,7 +236,18 @@ namespace n2xJucePlugin { // this is problematic. We want to edit one part only but two parts receive on the same channel. We have to send a full dump nonConstParam.setRateLimitMilliseconds(sysexRateLimitMs); - setSingleParameter(part, singleParam, static_cast<uint8_t>(_value)); + + const auto& name = _parameter.getDescription().name; + + if(name == "Sync" || name == "RingMod" || name == "Distortion") + { + const auto value = combineSyncRingModDistortion(part, 0, false); + setSingleParameter(part, n2x::Sync, value); + } + else + { + setSingleParameter(part, singleParam, static_cast<uint8_t>(_value)); + } } else { @@ -405,4 +414,37 @@ namespace n2xJucePlugin { return m_state.getKnobState(_result, _type); } + + uint8_t Controller::combineSyncRingModDistortion(const uint8_t _part, const uint8_t _currentCombinedValue, bool _lockedOnly) + { + // this controls both Sync and RingMod + // Sync = bit 0 + // RingMod = bit 1 + // Distortion = bit 4 + const auto* paramSync = getParameter("Sync", _part); + const auto* paramRingMod = getParameter("RingMod", _part); + const auto* paramDistortion = getParameter("Distortion", _part); + + auto v = _currentCombinedValue; + + if(!_lockedOnly || getParameterLocking().isParameterLocked(_part, "Sync")) + { + v &= ~0x01; + v |= paramSync->getUnnormalizedValue() & 1; + } + + if(!_lockedOnly || getParameterLocking().isParameterLocked(_part, "RingMod")) + { + v &= ~0x02; + v |= (paramRingMod->getUnnormalizedValue() & 1) << 1; + } + + if(!_lockedOnly || getParameterLocking().isParameterLocked(_part, "Distortion")) + { + v &= ~0x10; + v |= (paramDistortion->getUnnormalizedValue() & 1) << 4; + } + + return v; + } } diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h @@ -63,6 +63,8 @@ namespace n2xJucePlugin bool getKnobState(uint8_t& _result, n2x::KnobType _type) const; private: + uint8_t combineSyncRingModDistortion(uint8_t _part, uint8_t _currentCombinedValue, bool _lockedOnly); + n2x::State m_state; pluginLib::EventListener<uint8_t> m_currentPartChanged; };