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 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:
Msource/jucePluginLib/controller.cpp | 34+++++++++++++++++++++-------------
Msource/jucePluginLib/controller.h | 15++++++++++-----
Msource/jucePluginLib/processor.cpp | 8++++----
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) {