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:
parent
dd052dbfbf
commit
5a9d7ae251
@ -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,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user