summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormio <[email protected]>2024-11-17 18:58:30 +1000
committermio <[email protected]>2024-11-17 21:53:31 +1000
commite5122f17b4877374471932478c903248a6832625 (patch)
tree9daef9d07cda38c494adf25b9184e110ba52c907
parentb1e736de5feb49e3f2c8584a56fd322ec07131b9 (diff)
downloadakode-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.cpp54
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