commit eed7c4d73ef6490fe64419c99562d37005f9ea85
parent 898e58d71a59d7384286d1954d0bc8673f767667
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Sat, 1 Jun 2024 16:43:26 +0200
fix external midi messages not processed on main thread
Diffstat:
3 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/source/jucePluginLib/controller.cpp b/source/jucePluginLib/controller.cpp
@@ -240,11 +240,7 @@ namespace pluginLib
void Controller::timerCallback()
{
- std::vector<synthLib::SMidiEvent> events;
- getPluginMidiOut(events);
-
- for (const auto& e : events)
- parseMidiMessage(e);
+ processMidiMessages();
}
bool Controller::sendSysEx(const std::string& _packetName) const
@@ -367,7 +363,7 @@ namespace pluginLib
auto* p = getParameter(index.second, _part);
if(!p)
return false;
- auto* largestP = p;
+ const auto* largestP = p;
// we might have more than 1 parameter per index, use the one with the largest range
const auto& derived = p->getDerivedParameters();
for (const auto& parameter : derived)
@@ -481,17 +477,29 @@ namespace pluginLib
return parseSysexMessage(_e.sysex, _e.source);
}
- void Controller::addPluginMidiOut(const std::vector<synthLib::SMidiEvent>& _events)
+ void Controller::enqueueMidiMessages(const std::vector<synthLib::SMidiEvent>& _events)
+ {
+ if(_events.empty())
+ return;
+
+ const std::lock_guard l(m_midiMessagesLock);
+ m_midiMessages.insert(m_midiMessages.end(), _events.begin(), _events.end());
+ }
+
+ void Controller::getMidiMessages(std::vector<synthLib::SMidiEvent>& _events)
{
- const std::lock_guard l(m_pluginMidiOutLock);
- m_pluginMidiOut.insert(m_pluginMidiOut.end(), _events.begin(), _events.end());
+ const std::lock_guard l(m_midiMessagesLock);
+ std::swap(m_midiMessages, _events);
+ m_midiMessages.clear();
}
- void Controller::getPluginMidiOut(std::vector<synthLib::SMidiEvent>& _events)
+ void Controller::processMidiMessages()
{
- const std::lock_guard l(m_pluginMidiOutLock);
- std::swap(m_pluginMidiOut, _events);
- m_pluginMidiOut.clear();
+ std::vector<synthLib::SMidiEvent> events;
+ getMidiMessages(events);
+
+ for (const auto& e : events)
+ parseMidiMessage(e);
}
std::set<std::string> Controller::getRegionIdsForParameter(const Parameter* _param) const
diff --git a/source/jucePluginLib/controller.h b/source/jucePluginLib/controller.h
@@ -69,9 +69,13 @@ namespace pluginLib
virtual void onStateLoaded() = 0;
// this is called by the plug-in on audio thread!
- void addPluginMidiOut(const std::vector<synthLib::SMidiEvent>&);
- void getPluginMidiOut(std::vector<synthLib::SMidiEvent>&);
+ void enqueueMidiMessages(const std::vector<synthLib::SMidiEvent>&);
+ private:
+ void getMidiMessages(std::vector<synthLib::SMidiEvent>&);
+ void processMidiMessages();
+
+ public:
ParameterLocking& getParameterLocking() { return m_locking; }
ParameterLinks& getParameterLinks() { return m_parameterLinks; }
@@ -135,9 +139,10 @@ namespace pluginLib
uint8_t m_currentPart = 0;
- std::mutex m_pluginMidiOutLock;
- std::vector<synthLib::SMidiEvent> m_pluginMidiOut;
- std::map<const Parameter*, std::unique_ptr<SoftKnob>> m_softKnobs;
+ std::mutex m_midiMessagesLock;
+ std::vector<synthLib::SMidiEvent> m_midiMessages;
+
+ std::map<const Parameter*, std::unique_ptr<SoftKnob>> m_softKnobs;
protected:
// tries to find synth param in both internal and host
diff --git a/source/jucePluginLib/processor.cpp b/source/jucePluginLib/processor.cpp
@@ -87,7 +87,7 @@ namespace pluginLib
syx.push_back(0xf7);
sm.sysex = std::move(syx);
- getController().parseMidiMessage(sm);
+ getController().enqueueMidiMessages({sm});
addMidiEvent(sm);
}
else
@@ -108,7 +108,7 @@ namespace pluginLib
sm.sysex = syx;
}
- getController().parseMidiMessage(sm);
+ getController().enqueueMidiMessages({sm});
addMidiEvent(sm);
}
}
@@ -512,7 +512,7 @@ namespace pluginLib
if(status == synthLib::M_CONTROLCHANGE || status == synthLib::M_POLYPRESSURE)
{
// forward to UI to react to control input changes that should move knobs
- getController().addPluginMidiOut({ev});
+ getController().enqueueMidiMessages({ev});
}
}
@@ -554,7 +554,7 @@ namespace pluginLib
if (!m_midiOut.empty())
{
- getController().addPluginMidiOut(m_midiOut);
+ getController().enqueueMidiMessages(m_midiOut);
for (auto& e : m_midiOut)
{