mirror of https://github.com/AxioDL/boo.git
PulseAudio buffering fix
This commit is contained in:
parent
19014e0ba7
commit
fdf37c95e0
|
@ -352,9 +352,7 @@ struct ALSAAudioVoiceEngine : LinuxMidi
|
||||||
m_mixInfo.m_channelMap.m_channelCount = 2;
|
m_mixInfo.m_channelMap.m_channelCount = 2;
|
||||||
m_mixInfo.m_channelMap.m_channels[0] = AudioChannel::FrontLeft;
|
m_mixInfo.m_channelMap.m_channels[0] = AudioChannel::FrontLeft;
|
||||||
m_mixInfo.m_channelMap.m_channels[1] = AudioChannel::FrontRight;
|
m_mixInfo.m_channelMap.m_channels[1] = AudioChannel::FrontRight;
|
||||||
if (m_finalFlt.size() < m_5msFrames * 2)
|
_pumpAndMixVoices(m_5msFrames, (float*)nullptr);
|
||||||
m_finalFlt.resize(m_5msFrames * 2);
|
|
||||||
_pumpAndMixVoices(m_5msFrames, m_finalFlt.data());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,9 @@ BaseAudioVoiceEngine::~BaseAudioVoiceEngine()
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, T* dataOut)
|
void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, T* dataOut)
|
||||||
{
|
{
|
||||||
|
if (dataOut)
|
||||||
memset(dataOut, 0, sizeof(T) * frames * m_mixInfo.m_channelMap.m_channelCount);
|
memset(dataOut, 0, sizeof(T) * frames * m_mixInfo.m_channelMap.m_channelCount);
|
||||||
|
|
||||||
if (m_ltRtProcessing)
|
if (m_ltRtProcessing)
|
||||||
{
|
{
|
||||||
size_t sampleCount = m_5msFrames * 5;
|
size_t sampleCount = m_5msFrames * 5;
|
||||||
|
@ -64,6 +66,10 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, T* dataOut)
|
||||||
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
|
for (auto it = m_linearizedSubmixes.rbegin() ; it != m_linearizedSubmixes.rend() ; ++it)
|
||||||
(*it)->_pumpAndMix<T>(thisFrames);
|
(*it)->_pumpAndMix<T>(thisFrames);
|
||||||
|
|
||||||
|
remFrames -= thisFrames;
|
||||||
|
if (!dataOut)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (m_ltRtProcessing)
|
if (m_ltRtProcessing)
|
||||||
{
|
{
|
||||||
m_ltRtProcessing->Process(_getLtRtIn<T>().data(), dataOut, int(thisFrames));
|
m_ltRtProcessing->Process(_getLtRtIn<T>().data(), dataOut, int(thisFrames));
|
||||||
|
@ -74,7 +80,6 @@ void BaseAudioVoiceEngine::_pumpAndMixVoices(size_t frames, T* dataOut)
|
||||||
for (size_t i=0 ; i<sampleCount ; ++i)
|
for (size_t i=0 ; i<sampleCount ; ++i)
|
||||||
dataOut[i] *= m_totalVol;
|
dataOut[i] *= m_totalVol;
|
||||||
|
|
||||||
remFrames -= thisFrames;
|
|
||||||
dataOut += sampleCount;
|
dataOut += sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,6 @@ struct PulseAudioVoiceEngine : LinuxMidi
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_operation* op;
|
pa_operation* op;
|
||||||
size_t periodSz;
|
|
||||||
|
|
||||||
if (pa_context_connect(m_ctx, nullptr, PA_CONTEXT_NOFLAGS, nullptr))
|
if (pa_context_connect(m_ctx, nullptr, PA_CONTEXT_NOFLAGS, nullptr))
|
||||||
{
|
{
|
||||||
|
@ -117,12 +116,11 @@ struct PulseAudioVoiceEngine : LinuxMidi
|
||||||
}
|
}
|
||||||
|
|
||||||
m_5msFrames = m_sampleSpec.rate * 5 / 1000;
|
m_5msFrames = m_sampleSpec.rate * 5 / 1000;
|
||||||
periodSz = m_5msFrames * 4;
|
|
||||||
|
|
||||||
m_mixInfo.m_sampleRate = m_sampleSpec.rate;
|
m_mixInfo.m_sampleRate = m_sampleSpec.rate;
|
||||||
m_mixInfo.m_sampleFormat = SOXR_FLOAT32;
|
m_mixInfo.m_sampleFormat = SOXR_FLOAT32;
|
||||||
m_mixInfo.m_bitsPerSample = 32;
|
m_mixInfo.m_bitsPerSample = 32;
|
||||||
m_mixInfo.m_periodFrames = periodSz;
|
m_mixInfo.m_periodFrames = m_5msFrames;
|
||||||
if (!(m_stream = pa_stream_new(m_ctx, "master", &m_sampleSpec, &m_chanMap)))
|
if (!(m_stream = pa_stream_new(m_ctx, "master", &m_sampleSpec, &m_chanMap)))
|
||||||
{
|
{
|
||||||
Log.report(logvisor::Error, "Unable to pa_stream_new(): %s", pa_strerror(pa_context_errno(m_ctx)));
|
Log.report(logvisor::Error, "Unable to pa_stream_new(): %s", pa_strerror(pa_context_errno(m_ctx)));
|
||||||
|
@ -130,8 +128,8 @@ struct PulseAudioVoiceEngine : LinuxMidi
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_buffer_attr bufAttr;
|
pa_buffer_attr bufAttr;
|
||||||
bufAttr.minreq = uint32_t(periodSz * m_sampleSpec.channels * sizeof(float));
|
bufAttr.minreq = uint32_t(m_5msFrames * m_sampleSpec.channels * sizeof(float));
|
||||||
bufAttr.maxlength = bufAttr.minreq * 6;
|
bufAttr.maxlength = bufAttr.minreq * 12;
|
||||||
bufAttr.tlength = bufAttr.maxlength;
|
bufAttr.tlength = bufAttr.maxlength;
|
||||||
bufAttr.prebuf = UINT32_MAX;
|
bufAttr.prebuf = UINT32_MAX;
|
||||||
bufAttr.fragsize = UINT32_MAX;
|
bufAttr.fragsize = UINT32_MAX;
|
||||||
|
@ -286,8 +284,6 @@ struct PulseAudioVoiceEngine : LinuxMidi
|
||||||
userdata->_parseAudioChannelSet(&i->channel_map);
|
userdata->_parseAudioChannelSet(&i->channel_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> m_finalFlt;
|
|
||||||
|
|
||||||
void pumpAndMixVoices()
|
void pumpAndMixVoices()
|
||||||
{
|
{
|
||||||
if (!m_stream)
|
if (!m_stream)
|
||||||
|
@ -302,9 +298,7 @@ struct PulseAudioVoiceEngine : LinuxMidi
|
||||||
m_mixInfo.m_channelMap.m_channelCount = 2;
|
m_mixInfo.m_channelMap.m_channelCount = 2;
|
||||||
m_mixInfo.m_channelMap.m_channels[0] = AudioChannel::FrontLeft;
|
m_mixInfo.m_channelMap.m_channels[0] = AudioChannel::FrontLeft;
|
||||||
m_mixInfo.m_channelMap.m_channels[1] = AudioChannel::FrontRight;
|
m_mixInfo.m_channelMap.m_channels[1] = AudioChannel::FrontRight;
|
||||||
if (m_finalFlt.size() < m_5msFrames * 2)
|
_pumpAndMixVoices(m_5msFrames, (float*)nullptr);
|
||||||
m_finalFlt.resize(m_5msFrames * 2);
|
|
||||||
_pumpAndMixVoices(m_5msFrames, m_finalFlt.data());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,8 +328,7 @@ struct PulseAudioVoiceEngine : LinuxMidi
|
||||||
|
|
||||||
writablePeriods = nbytes / periodSz;
|
writablePeriods = nbytes / periodSz;
|
||||||
size_t periodSamples = m_mixInfo.m_periodFrames * m_mixInfo.m_channelMap.m_channelCount;
|
size_t periodSamples = m_mixInfo.m_periodFrames * m_mixInfo.m_channelMap.m_channelCount;
|
||||||
for (int p=0 ; p<writablePeriods ; ++p)
|
_pumpAndMixVoices(m_mixInfo.m_periodFrames * writablePeriods, reinterpret_cast<float*>(data));
|
||||||
_pumpAndMixVoices(m_mixInfo.m_periodFrames, reinterpret_cast<float*>(data) + p * periodSamples);
|
|
||||||
|
|
||||||
if (pa_stream_write(m_stream, data, nbytes, nullptr, 0, PA_SEEK_RELATIVE))
|
if (pa_stream_write(m_stream, data, nbytes, nullptr, 0, PA_SEEK_RELATIVE))
|
||||||
Log.report(logvisor::Error, "Unable to pa_stream_write()");
|
Log.report(logvisor::Error, "Unable to pa_stream_write()");
|
||||||
|
|
2
logvisor
2
logvisor
|
@ -1 +1 @@
|
||||||
Subproject commit 073cf1473bde254516f7637fcb787478aab47d6c
|
Subproject commit 2352699c6598866548b81c3886337b4a8bb91472
|
Loading…
Reference in New Issue