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 a56446c5f01ffcc15ac784f8a12d583f6b29de48
parent 309cd8685fc443afd408a57c771ba3417f063052
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Mon, 29 Jul 2024 17:07:17 +0200

add rate limiting to fix DSPs running too fast

Diffstat:
Msource/nord/n2x/n2xLib/n2xhardware.cpp | 21+++++++++++++++++++++
Msource/nord/n2x/n2xLib/n2xhardware.h | 8++++++++
2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/source/nord/n2x/n2xLib/n2xhardware.cpp b/source/nord/n2x/n2xLib/n2xhardware.cpp @@ -73,6 +73,8 @@ namespace n2x const auto processCount = std::min(_frames, static_cast<uint32_t>(64)); _frames -= processCount; + advanceSamples(processCount, _latency); + const auto requiredSize = processCount > 8 ? processCount - 8 : 0; if(esaiB.getAudioOutputs().size() < requiredSize) @@ -167,6 +169,15 @@ namespace n2x { m_requestedFramesAvailableMutex.unlock(); } + + if(m_esaiFrameIndex >= m_maxEsaiCallbacks + m_esaiLatency) + { + std::unique_lock uLock(m_haltDSPmutex); + m_haltDSPcv.wait(uLock, [&] + { + return (m_maxEsaiCallbacks + m_esaiLatency) > m_esaiFrameIndex; + }); + } } void Hardware::syncUCtoDSP() @@ -227,6 +238,16 @@ namespace n2x } } + void Hardware::advanceSamples(const uint32_t _samples, const uint32_t _latency) + { + { + std::lock_guard uLockHalt(m_haltDSPmutex); + m_maxEsaiCallbacks += _samples; + m_esaiLatency = _latency; + } + m_haltDSPcv.notify_one(); + } + void Hardware::haltDSPs() { if(m_dspHalted) diff --git a/source/nord/n2x/n2xLib/n2xhardware.h b/source/nord/n2x/n2xLib/n2xhardware.h @@ -3,6 +3,7 @@ #include "n2xdsp.h" #include "n2xmc.h" #include "n2xrom.h" + #include "synthLib/audioTypes.h" namespace n2x @@ -40,6 +41,7 @@ namespace n2x void onEsaiCallbackB(); void syncUCtoDSP(); void ucThreadFunc(); + void advanceSamples(uint32_t _samples, uint32_t _latency); Rom m_rom; Microcontroller m_uc; @@ -67,5 +69,11 @@ namespace n2x dsp56k::SpscSemaphore m_semDspAtoB; dsp56k::RingBuffer<dsp56k::Audio::RxFrame, 4, true> m_dspAtoBbuf; std::unique_ptr<std::thread> m_ucThread; + + // DSP slowdown + uint32_t m_maxEsaiCallbacks = 0; + uint32_t m_esaiLatency = 0; + std::mutex m_haltDSPmutex; + std::condition_variable m_haltDSPcv; }; }