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:
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;
};