alsaaudio: reduce playback latency

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 <vr_qemu@t-online.de>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220923183640.8314-4-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Volker Rümelin 2022-09-23 20:36:32 +02:00 committed by Gerd Hoffmann
parent dd052dbfbf
commit 5a9d7ae251

View file

@ -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,