[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 11/17] audio: replace the resampling loop in audio_pcm_sw_read()
From: |
Volker Rümelin |
Subject: |
[PATCH 11/17] audio: replace the resampling loop in audio_pcm_sw_read() |
Date: |
Sun, 15 Jan 2023 14:12:18 +0100 |
From: Volker Rümelin <vr_qemu@t-online.de>
Replace the resampling loop in audio_pcm_sw_read() with the new
function audio_pcm_sw_resample_in(). 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.
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
---
audio/audio.c | 59 ++++++++++++++++++++++++++++++---------------------
1 file changed, 35 insertions(+), 24 deletions(-)
diff --git a/audio/audio.c b/audio/audio.c
index 3d3b5e5b91..83bac97fa4 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -541,11 +541,43 @@ static size_t audio_pcm_hw_conv_in(HWVoiceIn *hw, void
*pcm_buf, size_t samples)
/*
* Soft voice (capture)
*/
+static void audio_pcm_sw_resample_in(SWVoiceIn *sw,
+ size_t frames_in_max, size_t frames_out_max,
+ size_t *total_in, size_t *total_out)
+{
+ HWVoiceIn *hw = sw->hw;
+ struct st_sample *src, *dst;
+ size_t live, rpos, frames_in, frames_out;
+
+ live = hw->total_samples_captured - sw->total_hw_samples_acquired;
+ rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
+
+ /* resample conv_buf from rpos to end of buffer */
+ src = hw->conv_buf.buffer + rpos;
+ frames_in = MIN(live, hw->conv_buf.size - rpos);
+ dst = sw->resample_buf.buffer;
+ frames_out = frames_out_max;
+ st_rate_flow(sw->rate, src, dst, &frames_in, &frames_out);
+ rpos += frames_in;
+ *total_in = frames_in;
+ *total_out = frames_out;
+
+ /* resample conv_buf from start of buffer if there are input frames left */
+ if (live - frames_in && rpos == hw->conv_buf.size) {
+ src = hw->conv_buf.buffer;
+ frames_in = live - frames_in;
+ dst += frames_out;
+ frames_out = frames_out_max - frames_out;
+ st_rate_flow(sw->rate, src, dst, &frames_in, &frames_out);
+ *total_in += frames_in;
+ *total_out += frames_out;
+ }
+}
+
static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
{
HWVoiceIn *hw = sw->hw;
- size_t samples, live, ret = 0, swlim, isamp, osamp, rpos, total = 0;
- struct st_sample *src, *dst = sw->resample_buf.buffer;
+ size_t samples, live, ret, swlim, total;
live = hw->total_samples_captured - sw->total_hw_samples_acquired;
if (!live) {
@@ -556,33 +588,12 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf,
size_t size)
return 0;
}
- rpos = audio_ring_posb(hw->conv_buf.pos, live, hw->conv_buf.size);
-
samples = size / sw->info.bytes_per_frame;
swlim = (live * sw->ratio) >> 32;
swlim = MIN (swlim, samples);
- while (swlim) {
- src = hw->conv_buf.buffer + rpos;
- if (hw->conv_buf.pos > rpos) {
- isamp = hw->conv_buf.pos - rpos;
- } else {
- isamp = hw->conv_buf.size - rpos;
- }
-
- if (!isamp) {
- break;
- }
- osamp = swlim;
-
- st_rate_flow (sw->rate, src, dst, &isamp, &osamp);
- swlim -= osamp;
- rpos = (rpos + isamp) % hw->conv_buf.size;
- dst += osamp;
- ret += osamp;
- total += isamp;
- }
+ audio_pcm_sw_resample_in(sw, live, swlim, &total, &ret);
if (!hw->pcm_ops->volume_in) {
mixeng_volume(sw->resample_buf.buffer, ret, &sw->vol);
--
2.35.3
- [PATCH 01/17] audio: change type of mix_buf and conv_buf, (continued)
- [PATCH 01/17] audio: change type of mix_buf and conv_buf, Volker Rümelin, 2023/01/15
- [PATCH 03/17] audio: make the resampling code greedy, Volker Rümelin, 2023/01/15
- [PATCH 02/17] audio: change type and name of the resample buffer, Volker Rümelin, 2023/01/15
- [PATCH 04/17] audio: replace the resampling loop in audio_pcm_sw_write(), Volker Rümelin, 2023/01/15
- [PATCH 05/17] audio: remove sw == NULL check, Volker Rümelin, 2023/01/15
- [PATCH 07/17] audio: don't misuse audio_pcm_sw_write(), Volker Rümelin, 2023/01/15
- [PATCH 06/17] audio: rename variables in audio_pcm_sw_write(), Volker Rümelin, 2023/01/15
- [PATCH 08/17] audio: remove unused noop_conv() function, Volker Rümelin, 2023/01/15
- [PATCH 09/17] audio/mixeng: calculate number of input frames, Volker Rümelin, 2023/01/15
- [PATCH 10/17] audio: wire up st_rate_frames_in(), Volker Rümelin, 2023/01/15
- [PATCH 11/17] audio: replace the resampling loop in audio_pcm_sw_read(),
Volker Rümelin <=
- [PATCH 12/17] audio: rename variables in audio_pcm_sw_read(), Volker Rümelin, 2023/01/15
- [PATCH 14/17] audio: wire up st_rate_frames_out(), Volker Rümelin, 2023/01/15
- [PATCH 16/17] audio/audio_template: substitute sw->hw with hw, Volker Rümelin, 2023/01/15
- [PATCH 13/17] audio/mixeng: calculate number of output frames, Volker Rümelin, 2023/01/15
- [PATCH 15/17] audio: handle leftover audio frame from upsampling, Volker Rümelin, 2023/01/15
- [PATCH 17/17] audio: remove sw->ratio, Volker Rümelin, 2023/01/15
- Re: [PATCH 00/17] audio: improve callback interface for audio frontends, Volker Rümelin, 2023/01/15