On Fri, Sep 23, 2022 at 10:51 PM Volker Rümelin wrote: > 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 > lgtm Acked-by: Marc-André Lureau > --- > 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.35.3 > > > -- Marc-André Lureau