mirror of https://github.com/AxioDL/boo.git
Silent audio mixing fix; Xlib Vulkan destruction order fix
This commit is contained in:
parent
d5ec7bcc1e
commit
3028e34b51
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue