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;
|
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)
|
static size_t alsa_write(HWVoiceOut *hw, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
|
ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw;
|
||||||
|
@ -916,7 +952,7 @@ static struct audio_pcm_ops alsa_pcm_ops = {
|
||||||
.init_out = alsa_init_out,
|
.init_out = alsa_init_out,
|
||||||
.fini_out = alsa_fini_out,
|
.fini_out = alsa_fini_out,
|
||||||
.write = alsa_write,
|
.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,
|
.run_buffer_out = audio_generic_run_buffer_out,
|
||||||
.enable_out = alsa_enable_out,
|
.enable_out = alsa_enable_out,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue