qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 04/17] audio: replace the resampling loop in audio_pcm_sw_


From: Marc-André Lureau
Subject: Re: [PATCH v2 04/17] audio: replace the resampling loop in audio_pcm_sw_write()
Date: Wed, 22 Feb 2023 14:49:42 +0400

Hi

On Mon, Feb 6, 2023 at 10:53 PM Volker Rümelin <vr_qemu@t-online.de> wrote:
>
> Replace the resampling loop in audio_pcm_sw_write() with the new
> function audio_pcm_sw_resample_out(). Unlike the old resample
> loop the new function will try to consume input frames even if
> the output buffer is full. This is necessary when downsampling
> to avoid reading less audio frames than calculated in advance.
> The loop was unrolled to avoid complicated loop control conditions
> in this case.
>
> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>

lgtm
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>



> ---
>  audio/audio.c | 63 +++++++++++++++++++++++++++++----------------------
>  1 file changed, 36 insertions(+), 27 deletions(-)
>
> diff --git a/audio/audio.c b/audio/audio.c
> index a399147486..4412b5fad8 100644
> --- a/audio/audio.c
> +++ b/audio/audio.c
> @@ -673,11 +673,44 @@ static void audio_pcm_hw_clip_out(HWVoiceOut *hw, void 
> *pcm_buf, size_t len)
>  /*
>   * Soft voice (playback)
>   */
> +static void audio_pcm_sw_resample_out(SWVoiceOut *sw,
> +    size_t frames_in_max, size_t frames_out_max,
> +    size_t *total_in, size_t *total_out)
> +{
> +    HWVoiceOut *hw = sw->hw;
> +    struct st_sample *src, *dst;
> +    size_t live, wpos, frames_in, frames_out;
> +
> +    live = sw->total_hw_samples_mixed;
> +    wpos = (hw->mix_buf.pos + live) % hw->mix_buf.size;
> +
> +    /* write to mix_buf from wpos to end of buffer */
> +    src = sw->resample_buf.buffer;
> +    frames_in = frames_in_max;
> +    dst = hw->mix_buf.buffer + wpos;
> +    frames_out = MIN(frames_out_max, hw->mix_buf.size - wpos);
> +    st_rate_flow_mix(sw->rate, src, dst, &frames_in, &frames_out);
> +    wpos += frames_out;
> +    *total_in = frames_in;
> +    *total_out = frames_out;
> +
> +    /* write to mix_buf from start of buffer if there are input frames left 
> */
> +    if (frames_in_max - frames_in > 0 && wpos == hw->mix_buf.size) {
> +        src += frames_in;
> +        frames_in = frames_in_max - frames_in;
> +        dst = hw->mix_buf.buffer;
> +        frames_out = frames_out_max - frames_out;
> +        st_rate_flow_mix(sw->rate, src, dst, &frames_in, &frames_out);
> +        *total_in += frames_in;
> +        *total_out += frames_out;
> +    }
> +}
> +
>  static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
>  {
> -    size_t hwsamples, samples, isamp, osamp, wpos, live, dead, left, blck;
> +    size_t hwsamples, samples, live, dead;
>      size_t hw_free;
> -    size_t ret = 0, pos = 0, total = 0;
> +    size_t ret, total;
>
>      if (!sw) {
>          return size;
> @@ -698,8 +731,6 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
> *buf, size_t size)
>          return 0;
>      }
>
> -    wpos = (sw->hw->mix_buf.pos + live) % hwsamples;
> -
>      dead = hwsamples - live;
>      hw_free = audio_pcm_hw_get_free(sw->hw);
>      hw_free = hw_free > live ? hw_free - live : 0;
> @@ -713,29 +744,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void 
> *buf, size_t size)
>          }
>      }
>
> -    while (samples) {
> -        dead = hwsamples - live;
> -        left = hwsamples - wpos;
> -        blck = MIN (dead, left);
> -        if (!blck) {
> -            break;
> -        }
> -        isamp = samples;
> -        osamp = blck;
> -        st_rate_flow_mix (
> -            sw->rate,
> -            sw->resample_buf.buffer + pos,
> -            sw->hw->mix_buf.buffer + wpos,
> -            &isamp,
> -            &osamp
> -            );
> -        ret += isamp;
> -        samples -= isamp;
> -        pos += isamp;
> -        live += osamp;
> -        wpos = (wpos + osamp) % hwsamples;
> -        total += osamp;
> -    }
> +    audio_pcm_sw_resample_out(sw, samples, MIN(dead, hw_free), &ret, &total);
>
>      sw->total_hw_samples_mixed += total;
>      sw->empty = sw->total_hw_samples_mixed == 0;
> --
> 2.35.3
>


--
Marc-André Lureau



reply via email to

[Prev in Thread] Current Thread [Next in Thread]