diff --git a/include/boo/IWindow.hpp b/include/boo/IWindow.hpp index 4149513..7591660 100644 --- a/include/boo/IWindow.hpp +++ b/include/boo/IWindow.hpp @@ -300,6 +300,7 @@ public: virtual uintptr_t getPlatformHandle() const=0; virtual bool _incomingEvent(void* event) {(void)event; return false;} + virtual void _cleanup() {} virtual ETouchType getTouchType() const=0; diff --git a/lib/audiodev/AudioVoice.cpp b/lib/audiodev/AudioVoice.cpp index 73aaf24..78f04bc 100644 --- a/lib/audiodev/AudioVoice.cpp +++ b/lib/audiodev/AudioVoice.cpp @@ -1,6 +1,7 @@ #include "AudioVoice.hpp" #include "AudioVoiceEngine.hpp" #include "logvisor/logvisor.hpp" +#include namespace boo { @@ -29,8 +30,8 @@ void AudioVoice::_setPitchRatio(double ratio, bool slew) { if (m_dynamicRate) { - soxr_error_t err = soxr_set_io_ratio(m_src, ratio * m_sampleRateIn / m_sampleRateOut, - slew ? m_head->m_5msFrames : 0); + m_sampleRatio = ratio * m_sampleRateIn / m_sampleRateOut; + soxr_error_t err = soxr_set_io_ratio(m_src, m_sampleRatio, slew ? m_head->m_5msFrames : 0); if (err) { Log.report(logvisor::Fatal, "unable to set resampler rate: %s", soxr_strerror(err)); @@ -101,6 +102,7 @@ void AudioVoiceMono::_resetSampleRate(double sampleRate) m_sampleRateIn = sampleRate; m_sampleRateOut = rateOut; + m_sampleRatio = m_sampleRateIn / m_sampleRateOut; soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0); _setPitchRatio(m_pitchRatio, false); m_resetSampleRate = false; @@ -114,7 +116,7 @@ size_t AudioVoiceMono::SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t f *data = scratchIn.data(); if (ctx->m_silentOut) { - memset(*data, 0, frames * 2); + memset(scratchIn.data(), 0, frames * 2); return frames; } else @@ -139,9 +141,6 @@ bool AudioVoiceMono::isSilent() const template size_t AudioVoiceMono::_pumpAndMix(size_t frames) { - if (isSilent()) - return 0; - auto& scratchPre = m_head->_getScratchPre(); if (scratchPre.size() < frames) scratchPre.resize(frames + 2); @@ -153,6 +152,14 @@ size_t AudioVoiceMono::_pumpAndMix(size_t frames) double dt = frames / m_sampleRateOut; m_cb->preSupplyAudio(*this, dt); _midUpdate(); + + if (isSilent()) + { + int16_t* dummy; + SRCCallback(this, &dummy, size_t(std::ceil(frames * m_sampleRatio))); + return 0; + } + size_t oDone = soxr_output(m_src, scratchPre.data(), frames); if (oDone) @@ -248,6 +255,7 @@ void AudioVoiceStereo::_resetSampleRate(double sampleRate) m_sampleRateIn = sampleRate; m_sampleRateOut = rateOut; + m_sampleRatio = m_sampleRateIn / m_sampleRateOut; soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0); _setPitchRatio(m_pitchRatio, false); m_resetSampleRate = false; @@ -262,7 +270,7 @@ size_t AudioVoiceStereo::SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size *data = scratchIn.data(); if (ctx->m_silentOut) { - memset(*data, 0, samples * 2); + memset(scratchIn.data(), 0, samples * 2); return frames; } else @@ -287,9 +295,6 @@ bool AudioVoiceStereo::isSilent() const template size_t AudioVoiceStereo::_pumpAndMix(size_t frames) { - if (isSilent()) - return 0; - size_t samples = frames * 2; auto& scratchPre = m_head->_getScratchPre(); @@ -303,6 +308,14 @@ size_t AudioVoiceStereo::_pumpAndMix(size_t frames) double dt = frames / m_sampleRateOut; m_cb->preSupplyAudio(*this, dt); _midUpdate(); + + if (isSilent()) + { + int16_t* dummy; + SRCCallback(this, &dummy, size_t(std::ceil(frames * m_sampleRatio))); + return 0; + } + size_t oDone = soxr_output(m_src, scratchPre.data(), frames); if (oDone) diff --git a/lib/audiodev/AudioVoice.hpp b/lib/audiodev/AudioVoice.hpp index f780ce1..40fdbfe 100644 --- a/lib/audiodev/AudioVoice.hpp +++ b/lib/audiodev/AudioVoice.hpp @@ -49,6 +49,7 @@ protected: /* Deferred pitch ratio set */ bool m_setPitchRatio = false; double m_pitchRatio = 1.0; + double m_sampleRatio = 1.0; bool m_slew = false; void _setPitchRatio(double ratio, bool slew); diff --git a/lib/graphicsdev/Vulkan.cpp b/lib/graphicsdev/Vulkan.cpp index 680191d..26742d9 100644 --- a/lib/graphicsdev/Vulkan.cpp +++ b/lib/graphicsdev/Vulkan.cpp @@ -2784,7 +2784,8 @@ struct VulkanCommandQueue : IGraphicsCommandQueue void stopRenderer() { m_running = false; - vk::WaitForFences(m_ctx->m_dev, 1, &m_drawCompleteFence, VK_FALSE, -1); + if (m_submitted && vk::GetFenceStatus(m_ctx->m_dev, m_drawCompleteFence) == VK_NOT_READY) + vk::WaitForFences(m_ctx->m_dev, 1, &m_drawCompleteFence, VK_FALSE, -1); static_cast(m_parent->getDataFactory())->DestroyGammaResources(); m_drawResTokens[0].clear(); m_drawResTokens[1].clear(); diff --git a/lib/x11/ApplicationXlib.hpp b/lib/x11/ApplicationXlib.hpp index d2ece33..1846e78 100644 --- a/lib/x11/ApplicationXlib.hpp +++ b/lib/x11/ApplicationXlib.hpp @@ -413,6 +413,14 @@ public: ~ApplicationXlib() { + for (auto& p : m_windows) + if (auto w = p.second.lock()) + w->_cleanup(); + +#if BOO_HAS_VULKAN + g_VulkanContext.destroyDevice(); +#endif + if (m_fontset) XFreeFontSet(m_xDisp, m_fontset); if (m_xIM) @@ -541,10 +549,6 @@ public: if (clientThread.joinable()) clientThread.join(); -#if BOO_HAS_VULKAN - g_VulkanContext.destroyDevice(); -#endif - return clientReturn; } diff --git a/lib/x11/WindowXlib.cpp b/lib/x11/WindowXlib.cpp index 93b79b8..eb73928 100644 --- a/lib/x11/WindowXlib.cpp +++ b/lib/x11/WindowXlib.cpp @@ -1111,13 +1111,9 @@ public: ~WindowXlib() { - XLockDisplay(m_xDisp); - m_gfxCtx->destroy(); - XUnmapWindow(m_xDisp, m_windowId); - XDestroyWindow(m_xDisp, m_windowId); - XFreeColormap(m_xDisp, m_colormapId); - XUnlockDisplay(m_xDisp); - APP->_deletedWindow(this); + _cleanup(); + if (APP) + APP->_deletedWindow(this); } void setCallback(IWindowCallback* cb) @@ -2013,7 +2009,21 @@ public: return false; } - + + void _cleanup() + { + if (m_gfxCtx) + { + XLockDisplay(m_xDisp); + m_gfxCtx->destroy(); + m_gfxCtx.reset(); + XUnmapWindow(m_xDisp, m_windowId); + XDestroyWindow(m_xDisp, m_windowId); + XFreeColormap(m_xDisp, m_colormapId); + XUnlockDisplay(m_xDisp); + } + } + ETouchType getTouchType() const { return m_touchType;