commit 663aecbbabe6907eeaeb3cf9d5f2aec2ec069b9c
parent c877bc5acfa8efeab169630d4e9f0c90dbfd1540
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 16 Nov 2024 23:58:55 +0100
fix DSP crash when switching preset with locked parameters
Diffstat:
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/source/virusJucePlugin/VirusController.cpp b/source/virusJucePlugin/VirusController.cpp
@@ -424,14 +424,30 @@ namespace virus
const auto locked = m_locking.getLockedParameterNames(ch);
- for(auto it = _parameterValues.begin(); it != _parameterValues.end(); ++it)
+ // if there are locked parameters and the current values in the received preset do not match
+ // the values of the parameters that are locked, create a new preset that contains all
+ // locked parameter values and send it back to the device
+ std::unordered_set<const pluginLib::Parameter*> lockedParamsToApply;
+
+ for (const auto& parameterValue : _parameterValues)
{
- auto* p = getParameter(it->first.second, ch);
+ auto* p = getParameter(parameterValue.first.second, ch);
+ // if a parameter is not locked, apply it
if(locked.find(p->getDescription().name) == locked.end())
- p->setValueFromSynth(it->second, pluginLib::Parameter::Origin::PresetChange);
+ p->setValueFromSynth(parameterValue.second, pluginLib::Parameter::Origin::PresetChange);
+ // otherwise, remember the locked parameter if the locked value doesn't match the preset value
+ else if (parameterValue.second != p->getUnnormalizedValue())
+ lockedParamsToApply.insert(p);
}
+ // if we have any locked parameters that need to be applied, create a new preset and send it to the device
+ if (!lockedParamsToApply.empty())
+ {
+ auto newDump = createSingleDump(patch.progNumber == virusLib::SINGLE ? 0 : patch.progNumber, virusLib::toMidiByte(virusLib::BankNumber::EditBuffer), patch.progNumber);
+ sendSysEx(newDump);
+ }
+
getProcessor().updateHostDisplay(juce::AudioProcessorListener::ChangeDetails().withProgramChanged(true));
if(m_currentPresetSource[ch] != PresetSource::Browser)
@@ -520,7 +536,7 @@ namespace virus
}
}
- bool Controller::parseControllerDump(const synthLib::SMidiEvent& m)
+ bool Controller::parseControllerDump(const synthLib::SMidiEvent& m) const
{
const uint8_t status = m.a & 0xf0;
const uint8_t part = m.a & 0x0f;
@@ -823,10 +839,6 @@ namespace virus
sendSysEx(msg);
- // if we have locked parameters, get them, send the preset and then send each locked parameter value afterward.
- // Modifying the preset directly does not work because a preset might be an old version that we do not know
- sendLockedParameters(static_cast<uint8_t>(_part == virusLib::SINGLE ? 0 : _part));
-
requestSingle(toMidiByte(virusLib::BankNumber::EditBuffer), program);
setCurrentPartPresetSource(program == virusLib::ProgramType::SINGLE ? 0 : program, PresetSource::Browser);
diff --git a/source/virusJucePlugin/VirusController.h b/source/virusJucePlugin/VirusController.h
@@ -173,7 +173,7 @@ namespace virus
void parseMulti(const pluginLib::SysEx& _msg, const pluginLib::MidiPacket::Data& _data, const pluginLib::MidiPacket::ParamValues& _parameterValues);
void parseParamChange(const pluginLib::MidiPacket::Data& _data);
- bool parseControllerDump(const synthLib::SMidiEvent&);
+ bool parseControllerDump(const synthLib::SMidiEvent&) const;
VirusProcessor& m_processor;
virusLib::DeviceModel m_defaultModel;