commit ba4d1003bdf40f77d9646ad08731c1172fbd0817
parent bb2b1811635a64ecfe5a3996df9307a5d1caece9
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 8 Mar 2025 22:33:37 +0100
Xenia: implement controller message parsing to update UI parameters
Diffstat:
6 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/doc/changelog.txt b/doc/changelog.txt
@@ -13,6 +13,7 @@ Xenia:
- [Fix] Checksum of exported patches was incorrect due to bug in documentation
- [Fix] Emulator might get stuck while "Reorganising Memory"
+- [Fix] UI didn't react to parameter changes via MIDI controller messages
OsTIrus:
diff --git a/source/jucePluginLib/controller.h b/source/jucePluginLib/controller.h
@@ -79,6 +79,13 @@ namespace pluginLib
static Parameter::Origin midiEventSourceToParameterOrigin(synthLib::MidiEventSource _source);
+ std::vector<uint8_t> getPartsForMidiEvent(const synthLib::SMidiEvent& _e)
+ {
+ return getPartsForMidiChannel(_e.a & 0x0f);
+ }
+
+ virtual std::vector<uint8_t> getPartsForMidiChannel(uint8_t _channel) { return {}; }
+
private:
void getMidiMessages(std::vector<synthLib::SMidiEvent>&);
void processMidiMessages();
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.cpp b/source/nord/n2x/n2xJucePlugin/n2xController.cpp
@@ -161,7 +161,7 @@ namespace n2xJucePlugin
m_state.receive(_e);
- const auto parts = m_state.getPartsForMidiChannel(_e);
+ const auto parts = getPartsForMidiEvent(_e);
for (const uint8_t part : parts)
{
@@ -451,6 +451,11 @@ namespace n2xJucePlugin
return m_state.getKnobState(_result, _type);
}
+ std::vector<uint8_t> Controller::getPartsForMidiChannel(const uint8_t _channel)
+ {
+ return m_state.getPartsForMidiChannel(_channel);
+ }
+
uint8_t Controller::combineSyncRingModDistortion(const uint8_t _part, const uint8_t _currentCombinedValue, bool _lockedOnly)
{
// this controls both Sync and RingMod
diff --git a/source/nord/n2x/n2xJucePlugin/n2xController.h b/source/nord/n2x/n2xJucePlugin/n2xController.h
@@ -62,6 +62,8 @@ namespace n2xJucePlugin
bool getKnobState(uint8_t& _result, n2x::KnobType _type) const;
+ std::vector<uint8_t> getPartsForMidiChannel(uint8_t _channel) override;
+
private:
uint8_t combineSyncRingModDistortion(uint8_t _part, uint8_t _currentCombinedValue, bool _lockedOnly);
diff --git a/source/xtJucePlugin/xtController.cpp b/source/xtJucePlugin/xtController.cpp
@@ -162,6 +162,26 @@ namespace xtJucePlugin
return 8;
}
+ std::vector<uint8_t> Controller::getPartsForMidiChannel(const uint8_t _channel)
+ {
+ if (!isMultiMode())
+ return {0};
+
+ std::vector<uint8_t> parts;
+
+ for (uint8_t p=0; p<getPartCount(); ++p)
+ {
+ char paramName[16];
+ (void)snprintf(paramName, std::size(paramName), "MI%dMidiChannel", static_cast<int>(p));
+ auto* param = getParameter(paramName, 0);
+ assert(param && "parameter not found");
+ const auto v = param->getUnnormalizedValue();
+ if (v < 2 || v - 2 == _channel) // omni, global, 0, 1, ....
+ parts.push_back(p);
+ }
+ return parts;
+ }
+
std::string Controller::getSingleName(const pluginLib::MidiPacket::ParamValues& _values) const
{
std::string name;
@@ -417,10 +437,32 @@ namespace xtJucePlugin
return true;
}
- bool Controller::parseControllerMessage(const synthLib::SMidiEvent&)
+ bool Controller::parseControllerMessage(const synthLib::SMidiEvent& _e)
{
- // TODO
- return false;
+ const auto& cm = getParameterDescriptions().getControllerMap();
+ const auto paramIndices = cm.getControlledParameters(_e);
+
+ if(paramIndices.empty())
+ return false;
+
+ const auto origin = midiEventSourceToParameterOrigin(_e.source);
+
+ const auto parts = isMultiMode() ? getPartsForMidiEvent(_e) : std::vector<uint8_t>{0};
+
+ if (parts.empty())
+ return false;
+
+ for (const uint8_t part : parts)
+ {
+ for (const auto paramIndex : paramIndices)
+ {
+ auto* param = getParameter(paramIndex, part);
+ assert(param && "parameter not found for control change");
+ param->setValueFromSynth(_e.c, origin);
+ }
+ }
+
+ return true;
}
bool Controller::parseMidiPacket(MidiPacketType _type, pluginLib::MidiPacket::Data& _data, pluginLib::MidiPacket::AnyPartParamValues& _params, const pluginLib::SysEx& _sysex) const
diff --git a/source/xtJucePlugin/xtController.h b/source/xtJucePlugin/xtController.h
@@ -95,6 +95,8 @@ namespace xtJucePlugin
uint8_t getPartCount() const override;
+ std::vector<uint8_t> getPartsForMidiChannel(uint8_t _channel) override;
+
private:
void selectPreset(int _offset);