commit a6ff82eea530df1b7523940d81e6705ee0abff0d
parent df42e631d9a90be598e3383cb23972ac50c2d2e8
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date: Thu, 6 Feb 2025 20:37:55 +0100
fix NR2x getting stuck after 12 hours
Diffstat:
2 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/source/nord/n2x/n2xLib/n2xhardware.cpp b/source/nord/n2x/n2xLib/n2xhardware.cpp
@@ -57,7 +57,6 @@ namespace n2x
m_dspB.terminate();
m_esaiFrameIndex = 0;
- m_maxEsaiCallbacks = std::numeric_limits<uint32_t>::max();
m_esaiLatency = 0;
while(!m_dspA.getDSPThread().runThread() || !m_dspB.getDSPThread().runThread())
@@ -69,7 +68,7 @@ namespace n2x
m_dspB.getPeriph().getEsai().getAudioInputs().pop_front();
// DSP B waits for ESAI rate limiting and for DSP A to provide audio data
- m_haltDSPcv.notify_all();
+ m_haltDSPSem.notify(999999);
if(m_dspA.getPeriph().getEsai().getAudioOutputs().empty())
m_dspA.getPeriph().getEsai().getAudioOutputs().push_back({});
}
@@ -246,14 +245,7 @@ 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;
- });
- }
+ m_haltDSPSem.wait(1);
}
void Hardware::syncUCtoDSP()
@@ -317,12 +309,23 @@ namespace n2x
void Hardware::advanceSamples(const uint32_t _samples, const uint32_t _latency)
{
+ // if the latency was higher first but now is lower, we might report < 0 samples. In this case we
+ // cannot notify but have to wait for another sample block until we can notify again
+
+ const auto latencyDiff = static_cast<int>(_latency) - static_cast<int>(m_esaiLatency);
+ m_esaiLatency = _latency;
+
+ const auto notifyCount = static_cast<int>(_samples) + latencyDiff + m_dspNotifyCorrection;
+
+ if (notifyCount > 0)
+ {
+ m_haltDSPSem.notify(notifyCount);
+ m_dspNotifyCorrection = 0;
+ }
+ else
{
- std::lock_guard uLockHalt(m_haltDSPmutex);
- m_maxEsaiCallbacks += _samples;
- m_esaiLatency = _latency;
+ m_dspNotifyCorrection = notifyCount;
}
- m_haltDSPcv.notify_one();
}
void Hardware::haltDSPs()
diff --git a/source/nord/n2x/n2xLib/n2xhardware.h b/source/nord/n2x/n2xLib/n2xhardware.h
@@ -91,10 +91,9 @@ namespace n2x
uint32_t m_midiOffsetCounter = 0;
// DSP slowdown
- uint32_t m_maxEsaiCallbacks = 0;
uint32_t m_esaiLatency = 0;
- std::mutex m_haltDSPmutex;
- dsp56k::ConditionVariable m_haltDSPcv;
+ int32_t m_dspNotifyCorrection = 0;
+ dsp56k::SpscSemaphoreWithCount m_haltDSPSem;
bool m_bootFinished = false;
};