From cc9250b7fd4ae500c0fceaef388346013597b672 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Wed, 9 Feb 2022 12:45:11 +0200 Subject: [PATCH] Audio: EQIIR: Optimize pass-through mode read/write frags This patch optimizes the remaining EQ functions eq_iir_s32_s16_pass() and eq_iir_s32_s24_pass() to not use audio stream read/write frag functions. This patch did not change x-x bit case that was already handled efficiently by 1:1 stream copy function with 6 MCPS. The 32-16 bits case improved 22.4 MCPS to 6.4 MCPS (-16 MCPS), the 32-24 bits case improved 23.6 MCPS to 6.8 MCPS (-16.8 MCPS). Signed-off-by: Seppo Ingalsuo --- src/audio/eq_iir/eq_iir.c | 50 +++++++++++++++++++-------- src/include/sof/audio/eq_iir/eq_iir.h | 4 +++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 16a045e7bdb0..ab6e9b3fcc30 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -297,15 +297,26 @@ static void eq_iir_s32_s16_pass(const struct comp_dev *dev, struct audio_stream *sink, uint32_t frames) { - int32_t *x; - int16_t *y; + int32_t *x = source->r_ptr; + int16_t *y = sink->w_ptr; + int nmax; + int n; int i; - int n = frames * source->channels; + int remaining_samples = frames * source->channels; - for (i = 0; i < n; i++) { - x = audio_stream_read_frag_s32(source, i); - y = audio_stream_write_frag_s16(sink, i); - *y = sat_int16(Q_SHIFT_RND(*x, 31, 15)); + while (remaining_samples) { + nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + n = MIN(remaining_samples, nmax); + nmax = EQ_IIR_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + n = MIN(n, nmax); + for (i = 0; i < n; i++) { + *y = sat_int16(Q_SHIFT_RND(*x, 31, 15)); + x++; + y++; + } + remaining_samples -= n; + x = audio_stream_wrap(source, x); + y = audio_stream_wrap(sink, y); } } #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ @@ -316,15 +327,26 @@ static void eq_iir_s32_s24_pass(const struct comp_dev *dev, struct audio_stream *sink, uint32_t frames) { - int32_t *x; - int32_t *y; + int32_t *x = source->r_ptr; + int32_t *y = sink->w_ptr; + int nmax; + int n; int i; - int n = frames * source->channels; + int remaining_samples = frames * source->channels; - for (i = 0; i < n; i++) { - x = audio_stream_read_frag_s32(source, i); - y = audio_stream_write_frag_s16(sink, i); - *y = sat_int24(Q_SHIFT_RND(*x, 31, 23)); + while (remaining_samples) { + nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + n = MIN(remaining_samples, nmax); + nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + n = MIN(n, nmax); + for (i = 0; i < n; i++) { + *y = sat_int24(Q_SHIFT_RND(*x, 31, 23)); + x++; + y++; + } + remaining_samples -= n; + x = audio_stream_wrap(source, x); + y = audio_stream_wrap(sink, y); } } #endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */ diff --git a/src/include/sof/audio/eq_iir/eq_iir.h b/src/include/sof/audio/eq_iir/eq_iir.h index ce9a4e82abb5..290e05a8467e 100644 --- a/src/include/sof/audio/eq_iir/eq_iir.h +++ b/src/include/sof/audio/eq_iir/eq_iir.h @@ -13,6 +13,10 @@ #include #include +/** \brief Macros to convert without division bytes count to samples count */ +#define EQ_IIR_BYTES_TO_S16_SAMPLES(b) ((b) >> 1) +#define EQ_IIR_BYTES_TO_S32_SAMPLES(b) ((b) >> 2) + struct audio_stream; struct comp_dev;