Silent audio mixing fix; Xlib Vulkan destruction order fix

This commit is contained in:
Jack Andersen 2018-05-28 09:28:36 -10:00
parent d5ec7bcc1e
commit 3028e34b51
6 changed files with 53 additions and 23 deletions

View File

@ -300,6 +300,7 @@ public:
virtual uintptr_t getPlatformHandle() const=0; virtual uintptr_t getPlatformHandle() const=0;
virtual bool _incomingEvent(void* event) {(void)event; return false;} virtual bool _incomingEvent(void* event) {(void)event; return false;}
virtual void _cleanup() {}
virtual ETouchType getTouchType() const=0; virtual ETouchType getTouchType() const=0;

View File

@ -1,6 +1,7 @@
#include "AudioVoice.hpp" #include "AudioVoice.hpp"
#include "AudioVoiceEngine.hpp" #include "AudioVoiceEngine.hpp"
#include "logvisor/logvisor.hpp" #include "logvisor/logvisor.hpp"
#include <cmath>
namespace boo namespace boo
{ {
@ -29,8 +30,8 @@ void AudioVoice::_setPitchRatio(double ratio, bool slew)
{ {
if (m_dynamicRate) if (m_dynamicRate)
{ {
soxr_error_t err = soxr_set_io_ratio(m_src, ratio * m_sampleRateIn / m_sampleRateOut, m_sampleRatio = ratio * m_sampleRateIn / m_sampleRateOut;
slew ? m_head->m_5msFrames : 0); soxr_error_t err = soxr_set_io_ratio(m_src, m_sampleRatio, slew ? m_head->m_5msFrames : 0);
if (err) if (err)
{ {
Log.report(logvisor::Fatal, "unable to set resampler rate: %s", soxr_strerror(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_sampleRateIn = sampleRate;
m_sampleRateOut = rateOut; m_sampleRateOut = rateOut;
m_sampleRatio = m_sampleRateIn / m_sampleRateOut;
soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0); soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0);
_setPitchRatio(m_pitchRatio, false); _setPitchRatio(m_pitchRatio, false);
m_resetSampleRate = false; m_resetSampleRate = false;
@ -114,7 +116,7 @@ size_t AudioVoiceMono::SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t f
*data = scratchIn.data(); *data = scratchIn.data();
if (ctx->m_silentOut) if (ctx->m_silentOut)
{ {
memset(*data, 0, frames * 2); memset(scratchIn.data(), 0, frames * 2);
return frames; return frames;
} }
else else
@ -139,9 +141,6 @@ bool AudioVoiceMono::isSilent() const
template <typename T> template <typename T>
size_t AudioVoiceMono::_pumpAndMix(size_t frames) size_t AudioVoiceMono::_pumpAndMix(size_t frames)
{ {
if (isSilent())
return 0;
auto& scratchPre = m_head->_getScratchPre<T>(); auto& scratchPre = m_head->_getScratchPre<T>();
if (scratchPre.size() < frames) if (scratchPre.size() < frames)
scratchPre.resize(frames + 2); scratchPre.resize(frames + 2);
@ -153,6 +152,14 @@ size_t AudioVoiceMono::_pumpAndMix(size_t frames)
double dt = frames / m_sampleRateOut; double dt = frames / m_sampleRateOut;
m_cb->preSupplyAudio(*this, dt); m_cb->preSupplyAudio(*this, dt);
_midUpdate(); _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); size_t oDone = soxr_output(m_src, scratchPre.data(), frames);
if (oDone) if (oDone)
@ -248,6 +255,7 @@ void AudioVoiceStereo::_resetSampleRate(double sampleRate)
m_sampleRateIn = sampleRate; m_sampleRateIn = sampleRate;
m_sampleRateOut = rateOut; m_sampleRateOut = rateOut;
m_sampleRatio = m_sampleRateIn / m_sampleRateOut;
soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0); soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0);
_setPitchRatio(m_pitchRatio, false); _setPitchRatio(m_pitchRatio, false);
m_resetSampleRate = false; m_resetSampleRate = false;
@ -262,7 +270,7 @@ size_t AudioVoiceStereo::SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size
*data = scratchIn.data(); *data = scratchIn.data();
if (ctx->m_silentOut) if (ctx->m_silentOut)
{ {
memset(*data, 0, samples * 2); memset(scratchIn.data(), 0, samples * 2);
return frames; return frames;
} }
else else
@ -287,9 +295,6 @@ bool AudioVoiceStereo::isSilent() const
template <typename T> template <typename T>
size_t AudioVoiceStereo::_pumpAndMix(size_t frames) size_t AudioVoiceStereo::_pumpAndMix(size_t frames)
{ {
if (isSilent())
return 0;
size_t samples = frames * 2; size_t samples = frames * 2;
auto& scratchPre = m_head->_getScratchPre<T>(); auto& scratchPre = m_head->_getScratchPre<T>();
@ -303,6 +308,14 @@ size_t AudioVoiceStereo::_pumpAndMix(size_t frames)
double dt = frames / m_sampleRateOut; double dt = frames / m_sampleRateOut;
m_cb->preSupplyAudio(*this, dt); m_cb->preSupplyAudio(*this, dt);
_midUpdate(); _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); size_t oDone = soxr_output(m_src, scratchPre.data(), frames);
if (oDone) if (oDone)

View File

@ -49,6 +49,7 @@ protected:
/* Deferred pitch ratio set */ /* Deferred pitch ratio set */
bool m_setPitchRatio = false; bool m_setPitchRatio = false;
double m_pitchRatio = 1.0; double m_pitchRatio = 1.0;
double m_sampleRatio = 1.0;
bool m_slew = false; bool m_slew = false;
void _setPitchRatio(double ratio, bool slew); void _setPitchRatio(double ratio, bool slew);

View File

@ -2784,7 +2784,8 @@ struct VulkanCommandQueue : IGraphicsCommandQueue
void stopRenderer() void stopRenderer()
{ {
m_running = false; 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<VulkanDataFactoryImpl*>(m_parent->getDataFactory())->DestroyGammaResources(); static_cast<VulkanDataFactoryImpl*>(m_parent->getDataFactory())->DestroyGammaResources();
m_drawResTokens[0].clear(); m_drawResTokens[0].clear();
m_drawResTokens[1].clear(); m_drawResTokens[1].clear();

View File

@ -413,6 +413,14 @@ public:
~ApplicationXlib() ~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) if (m_fontset)
XFreeFontSet(m_xDisp, m_fontset); XFreeFontSet(m_xDisp, m_fontset);
if (m_xIM) if (m_xIM)
@ -541,10 +549,6 @@ public:
if (clientThread.joinable()) if (clientThread.joinable())
clientThread.join(); clientThread.join();
#if BOO_HAS_VULKAN
g_VulkanContext.destroyDevice();
#endif
return clientReturn; return clientReturn;
} }

View File

@ -1111,13 +1111,9 @@ public:
~WindowXlib() ~WindowXlib()
{ {
XLockDisplay(m_xDisp); _cleanup();
m_gfxCtx->destroy(); if (APP)
XUnmapWindow(m_xDisp, m_windowId); APP->_deletedWindow(this);
XDestroyWindow(m_xDisp, m_windowId);
XFreeColormap(m_xDisp, m_colormapId);
XUnlockDisplay(m_xDisp);
APP->_deletedWindow(this);
} }
void setCallback(IWindowCallback* cb) void setCallback(IWindowCallback* cb)
@ -2013,7 +2009,21 @@ public:
return false; 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 ETouchType getTouchType() const
{ {
return m_touchType; return m_touchType;