From 5a9d7ae25175d19f9380128ac17f87816fe6f049 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Volker=20R=C3=BCmelin?= Date: Fri, 23 Sep 2022 20:36:32 +0200 Subject: [PATCH] alsaaudio: reduce playback latency MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change the buffer_get_free pcm_ops function to report the free ALSA playback buffer. The generic buffer becomes a temporary buffer and is empty after a call to audio_run_out(). Signed-off-by: Volker Rümelin Acked-by: Marc-André Lureau Message-Id: <20220923183640.8314-4-vr_qemu@t-online.de> Signed-off-by: Gerd Hoffmann --- audio/alsaaudio.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 4a61378cd7..7a2a94cd42 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -602,6 +602,42 @@ static int alsa_open(bool in, struct alsa_params_req *req, return -1; } +static size_t alsa_buffer_get_free(HWVoiceOut *hw) +{ + ALSAVoiceOut *alsa = (ALSAVoiceOut *)hw; + snd_pcm_sframes_t avail; + size_t alsa_free, generic_free, generic_in_use; + + avail = snd_pcm_avail_update(alsa->handle); + if (avail < 0) { + if (avail == -EPIPE) { + if (!alsa_recover(alsa->handle)) { + avail = snd_pcm_avail_update(alsa->handle); + } + } + if (avail < 0) { + alsa_logerr(avail, + "Could not obtain number of available frames\n"); + avail = 0; + } + } + + alsa_free = avail * hw->info.bytes_per_frame; + generic_free = audio_generic_buffer_get_free(hw); + generic_in_use = hw->samples * hw->info.bytes_per_frame - generic_free; + if (generic_in_use) { + /* + * This code can only be reached in the unlikely case that + * snd_pcm_avail_update() returned a larger number of frames + * than snd_pcm_writei() could write. Make sure that all + * remaining bytes in the generic buffer can be written. + */ + alsa_free = alsa_free > generic_in_use ? alsa_free - generic_in_use : 0; + } + + return alsa_free; +} + static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; @@ -916,7 +952,7 @@ static struct audio_pcm_ops alsa_pcm_ops = { .init_out = alsa_init_out, .fini_out = alsa_fini_out, .write = alsa_write, - .buffer_get_free = audio_generic_buffer_get_free, + .buffer_get_free = alsa_buffer_get_free, .run_buffer_out = audio_generic_run_buffer_out, .enable_out = alsa_enable_out, -- 2.11.0