diff options
author | mio <[email protected]> | 2024-11-17 18:58:30 +1000 |
---|---|---|
committer | mio <[email protected]> | 2024-11-17 21:53:31 +1000 |
commit | e5122f17b4877374471932478c903248a6832625 (patch) | |
tree | 9daef9d07cda38c494adf25b9184e110ba52c907 | |
parent | b1e736de5feb49e3f2c8584a56fd322ec07131b9 (diff) | |
download | akode-issue/4/reduce-alsa-delay.tar.gz akode-issue/4/reduce-alsa-delay.zip |
ALSASink: Set a buffer time of 100msissue/4/reduce-alsa-delay
A delay is introduced when using ALSA under PulseAudio. This particular
fix helps when, for example, adjusting the volume.
Signed-off-by: mio <[email protected]>
-rw-r--r-- | akode/plugins/alsa_sink/alsa_sink.cpp | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/akode/plugins/alsa_sink/alsa_sink.cpp b/akode/plugins/alsa_sink/alsa_sink.cpp index 501b8ca..c226519 100644 --- a/akode/plugins/alsa_sink/alsa_sink.cpp +++ b/akode/plugins/alsa_sink/alsa_sink.cpp @@ -18,7 +18,8 @@ Boston, MA 02110-1301, USA. */ -// #define DEBUG +#define DEBUG +#define AKODE_MODULE "alsa_sink" #include "akode_debug.h" @@ -172,6 +173,9 @@ found_format: else 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; snd_pcm_hw_params_set_rate_near(m_data->pcm_playback, hw, &rate, 0); 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); + // Set up buffer parameters. + // This mainly fixes a delay with PulseAudio. + unsigned bufferTime = 100'000; // us (100ms) + unsigned periods = 4; - m_data->fragmentSize = 1024; - snd_pcm_uframes_t period_size = m_data->fragmentSize / (wid*config->channels); - snd_pcm_hw_params_set_period_size_near(m_data->pcm_playback, hw, &period_size, 0); + 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 = period_size * (wid*config->channels); -// std::cerr << "akode: ALSA fragment-size: " << m_data->fragmentSize << "\n"; + err = snd_pcm_hw_params(m_data->pcm_playback, hw); + if (err < 0) + { + AKODE_WARN("unable to set hw params: " << snd_strerror(err)); + m_data->error = true; + return -1; + } + + snd_pcm_uframes_t bufferSize; + 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; m_data->buffer = new char [m_data->fragmentSize]; 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); - return res; - } + 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; } const AudioConfiguration* ALSASink::audioConfiguration() const |