From 92047f5e9e03ed564410ab177e0a489c311c78fc Mon Sep 17 00:00:00 2001 From: Armin Kazmi Date: Fri, 20 Nov 2009 22:47:35 +0100 Subject: [PATCH] AudioPulseAudio: fixed latency and underrun problems Try to adjust latency of PulseAudio according to our settings of mixer so it does not have such a bad latency anymore. Furthermore force PulseAudio to play silence instead of rewinding streams in case of underruns. --- src/core/audio/AudioPulseAudio.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index 14a0a3b86..539b1fba5 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -35,6 +35,7 @@ #include "gui_templates.h" #include "templates.h" #include "Cpu.h" +#include "engine.h" static void stream_write_callback(pa_stream *s, size_t length, void *userdata) @@ -169,11 +170,29 @@ static void context_state_callback(pa_context *c, void *userdata) _this->m_s = pa_stream_new( c, "lmms", &_this->m_sampleSpec, NULL); pa_stream_set_state_callback( _this->m_s, stream_state_callback, _this ); pa_stream_set_write_callback( _this->m_s, stream_write_callback, _this ); - pa_stream_connect_playback( _this->m_s, NULL, NULL, - (pa_stream_flags) 0, - pa_cvolume_set( &cv, _this->m_sampleSpec.channels, - PA_VOLUME_NORM ), - NULL ); + + pa_buffer_attr buffer_attr; + + buffer_attr.maxlength = (uint32_t)(-1); + + // play silence in case of buffer underun instead of using default rewind + buffer_attr.prebuf = 0; + + buffer_attr.minreq = (uint32_t)(-1); + buffer_attr.fragsize = (uint32_t)(-1); + + double latency = (double)( engine::getMixer()->framesPerPeriod() ) / + (double)_this->sampleRate(); + + // ask PulseAudio for the desired latency (which might not be approved) + buffer_attr.tlength = pa_usec_to_bytes( latency * PA_USEC_PER_MSEC, + &_this->m_sampleSpec ); + + pa_stream_connect_playback( _this->m_s, NULL, &buffer_attr, + PA_STREAM_ADJUST_LATENCY, + pa_cvolume_set( &cv, _this->m_sampleSpec.channels, + PA_VOLUME_NORM ), + NULL ); break; }