ALSASink: Set a buffer time of 100ms

A delay is introduced when using ALSA under PulseAudio. This particular
fix helps when, for example, adjusting the volume.

Signed-off-by: mio <stigma@disroot.org>
issue/4/reduce-alsa-delay
mio 7 days ago
parent b1e736de5f
commit e5122f17b4

@ -18,7 +18,8 @@
Boston, MA 02110-1301, USA. Boston, MA 02110-1301, USA.
*/ */
// #define DEBUG #define DEBUG
#define AKODE_MODULE "alsa_sink"
#include "akode_debug.h" #include "akode_debug.h"
@ -172,6 +173,9 @@ found_format:
else else
return -1; return -1;
// Disable ALSA resampling, since we do that.
snd_pcm_hw_params_set_rate_resample(m_data->pcm_playback, hw, 0);
unsigned int rate = config->sample_rate; unsigned int rate = config->sample_rate;
snd_pcm_hw_params_set_rate_near(m_data->pcm_playback, hw, &rate, 0); snd_pcm_hw_params_set_rate_near(m_data->pcm_playback, hw, &rate, 0);
if (m_data->config.sample_rate != rate) { if (m_data->config.sample_rate != rate) {
@ -181,25 +185,49 @@ found_format:
snd_pcm_hw_params_set_channels(m_data->pcm_playback, hw, config->channels); snd_pcm_hw_params_set_channels(m_data->pcm_playback, hw, config->channels);
// Set up buffer parameters.
// This mainly fixes a delay with PulseAudio.
unsigned bufferTime = 100'000; // us (100ms)
unsigned periods = 4;
int err = snd_pcm_hw_params_set_buffer_time_near(m_data->pcm_playback, hw, &bufferTime, nullptr);
if (err < 0)
{
AKODE_WARN("unable to set buffer time: " << snd_strerror(err));
}
if (err >= 0)
{
err = snd_pcm_hw_params_set_periods_near(m_data->pcm_playback, hw, &periods, nullptr);
if (err < 0)
{
AKODE_WARN("unable to set periods near: " << snd_strerror(err));
}
}
m_data->fragmentSize = 1024; err = snd_pcm_hw_params(m_data->pcm_playback, hw);
snd_pcm_uframes_t period_size = m_data->fragmentSize / (wid*config->channels); if (err < 0)
snd_pcm_hw_params_set_period_size_near(m_data->pcm_playback, hw, &period_size, 0); {
AKODE_WARN("unable to set hw params: " << snd_strerror(err));
m_data->error = true;
return -1;
}
m_data->fragmentSize = period_size * (wid*config->channels); snd_pcm_uframes_t bufferSize;
// std::cerr << "akode: ALSA fragment-size: " << m_data->fragmentSize << "\n"; snd_pcm_hw_params_get_buffer_size(hw, &bufferSize);
m_data->fragmentSize = snd_pcm_frames_to_bytes(m_data->pcm_playback, bufferSize) * 2;
delete m_data->buffer; delete m_data->buffer;
m_data->buffer = new char [m_data->fragmentSize]; m_data->buffer = new char [m_data->fragmentSize];
m_data->filled = 0; m_data->filled = 0;
if (snd_pcm_hw_params(m_data->pcm_playback, hw) < 0) {
return -1;
}
else {
m_data->can_pause = (snd_pcm_hw_params_can_pause(hw) == 1); m_data->can_pause = (snd_pcm_hw_params_can_pause(hw) == 1);
AKODE_DEBUG("hw can-pause: " << (m_data->can_pause ? "true" : "false"));
AKODE_DEBUG("buffer-size: " << bufferSize << " frames");
AKODE_DEBUG("fragment-size: " <<
snd_pcm_bytes_to_frames(m_data->pcm_playback, m_data->fragmentSize) << " frames");
return res; return res;
}
} }
const AudioConfiguration* ALSASink::audioConfiguration() const const AudioConfiguration* ALSASink::audioConfiguration() const

Loading…
Cancel
Save