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 e8d79d02c29ef8284b55dc41bb9cdbca31dd8c12
parent 5b185e11ca788c8822f291e20ff7ffdac5f4532b
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Thu, 26 Aug 2021 09:09:05 +0200

reduce locking when adding midi events to plugin

Diffstat:
Msource/synthLib/plugin.cpp | 85+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msource/synthLib/plugin.h | 9+++++++--
2 files changed, 58 insertions(+), 36 deletions(-)

diff --git a/source/synthLib/plugin.cpp b/source/synthLib/plugin.cpp @@ -18,42 +18,14 @@ namespace synthLib void Plugin::addMidiEvent(const SMidiEvent& _ev) { - std::lock_guard lock(m_lock); - - // sysex might be send in multiple chunks. Happens if coming from hardware - if(!_ev.sysex.empty()) - { - const bool isComplete = _ev.sysex.front() == M_STARTOFSYSEX && _ev.sysex.back() == M_ENDOFSYSEX; - - if(isComplete) - { - m_midiIn.push_back(_ev); - return; - } - - const bool isStart = _ev.sysex.front() == M_STARTOFSYSEX && _ev.sysex.back() != M_ENDOFSYSEX; - const bool isEnd = _ev.sysex.front() != M_STARTOFSYSEX && _ev.sysex.back() == M_ENDOFSYSEX; - - if(isStart) - { - m_pendingSyexInput = _ev; - return; - } + std::lock_guard lock(m_lockAddMidiEvent); - if(!m_pendingSyexInput.sysex.empty()) - { - m_pendingSyexInput.sysex.insert(m_pendingSyexInput.sysex.end(), _ev.sysex.begin(), _ev.sysex.end()); - - if(isEnd) - { - m_midiIn.push_back(m_pendingSyexInput); - m_pendingSyexInput.sysex.clear(); - } - } - return; + if(m_midiInRingBuffer.full()) + { + std::lock_guard lock(m_lock); + processMidiInEvents(); } - - m_midiIn.push_back(_ev); + m_midiInRingBuffer.push_back(_ev); } void Plugin::setSamplerate(float _samplerate) @@ -72,6 +44,8 @@ namespace synthLib setFlushDenormalsToZero(); + processMidiInEvents(); + float* inputs[8] {}; float* outputs[8] {}; @@ -241,6 +215,49 @@ namespace synthLib m_deviceLatency = static_cast<uint32_t>(m_device->getInternalLatencySamples() * m_hostSamplerate / m_device->getSamplerate()); } + void Plugin::processMidiInEvents() + { + while (!m_midiInRingBuffer.empty()) + { + const auto _ev = m_midiInRingBuffer.pop_front(); + + // sysex might be send in multiple chunks. Happens if coming from hardware + if (!_ev.sysex.empty()) + { + const bool isComplete = _ev.sysex.front() == M_STARTOFSYSEX && _ev.sysex.back() == M_ENDOFSYSEX; + + if (isComplete) + { + m_midiIn.push_back(_ev); + return; + } + + const bool isStart = _ev.sysex.front() == M_STARTOFSYSEX && _ev.sysex.back() != M_ENDOFSYSEX; + const bool isEnd = _ev.sysex.front() != M_STARTOFSYSEX && _ev.sysex.back() == M_ENDOFSYSEX; + + if (isStart) + { + m_pendingSysexInput = _ev; + return; + } + + if (!m_pendingSysexInput.sysex.empty()) + { + m_pendingSysexInput.sysex.insert(m_pendingSysexInput.sysex.end(), _ev.sysex.begin(), _ev.sysex.end()); + + if (isEnd) + { + m_midiIn.push_back(m_pendingSysexInput); + m_pendingSysexInput.sysex.clear(); + } + } + return; + } + + m_midiIn.push_back(_ev); + } + } + void Plugin::setBlockSize(const uint32_t _blockSize) { std::lock_guard lock(m_lock); diff --git a/source/synthLib/plugin.h b/source/synthLib/plugin.h @@ -5,6 +5,8 @@ #include "../synthLib/midiTypes.h" #include "../synthLib/resamplerInOut.h" +#include "../dsp56300/source/dsp56kEmu/ringbuffer.h" + #include "deviceTypes.h" namespace synthLib @@ -35,14 +37,17 @@ namespace synthLib void processMidiClock(float _bpm, float _ppqPos, bool _isPlaying, size_t _sampleCount); float* getDummyBuffer(size_t _minimumSize); void updateDeviceLatency(); - + void processMidiInEvents(); + + dsp56k::RingBuffer<SMidiEvent, 1024, false> m_midiInRingBuffer; std::vector<SMidiEvent> m_midiIn; std::vector<SMidiEvent> m_midiOut; - SMidiEvent m_pendingSyexInput; + SMidiEvent m_pendingSysexInput; ResamplerInOut m_resampler; mutable std::mutex m_lock; + mutable std::mutex m_lockAddMidiEvent; Device* const m_device;