[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 04/15] audio: replace the resampling loop in audio_pcm_sw_writ
From: |
Volker Rümelin |
Subject: |
[PATCH v3 04/15] audio: replace the resampling loop in audio_pcm_sw_write() |
Date: |
Fri, 24 Feb 2023 20:05:44 +0100 |
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>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
---
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
- [PATCH v3 00/15] audio: improve callback interface for audio frontends, Volker Rümelin, 2023/02/24
- [PATCH v3 02/15] audio: change type and name of the resample buffer, Volker Rümelin, 2023/02/24
- [PATCH v3 01/15] audio: change type of mix_buf and conv_buf, Volker Rümelin, 2023/02/24
- [PATCH v3 03/15] audio: make the resampling code greedy, Volker Rümelin, 2023/02/24
- [PATCH v3 04/15] audio: replace the resampling loop in audio_pcm_sw_write(),
Volker Rümelin <=
- [PATCH v3 05/15] audio: remove sw == NULL check, Volker Rümelin, 2023/02/24
- [PATCH v3 07/15] audio: don't misuse audio_pcm_sw_write(), Volker Rümelin, 2023/02/24
- [PATCH v3 08/15] audio: remove unused noop_conv() function, Volker Rümelin, 2023/02/24
- [PATCH v3 09/15] audio: make playback packet length calculation exact, Volker Rümelin, 2023/02/24
- [PATCH v3 10/15] audio: replace the resampling loop in audio_pcm_sw_read(), Volker Rümelin, 2023/02/24
- [PATCH v3 11/15] audio: rename variables in audio_pcm_sw_read(), Volker Rümelin, 2023/02/24
- [PATCH v3 06/15] audio: rename variables in audio_pcm_sw_write(), Volker Rümelin, 2023/02/24
- [PATCH v3 13/15] audio: handle leftover audio frame from upsampling, Volker Rümelin, 2023/02/24
- [PATCH v3 12/15] audio: make recording packet length calculation exact, Volker Rümelin, 2023/02/24
- [PATCH v3 14/15] audio/audio_template: substitute sw->hw with hw, Volker Rümelin, 2023/02/24