From 69134f8d3e93821e4a97a9f17f80d496f87052ff Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 22 Oct 2023 10:50:03 +0200 Subject: [PATCH] filter-chain: add linear operation to dsp --- .../module-filter-chain/builtin_plugin.c | 8 +-- src/modules/module-filter-chain/dsp-ops-c.c | 56 ++++++++++++++----- src/modules/module-filter-chain/dsp-ops.c | 3 + src/modules/module-filter-chain/dsp-ops.h | 8 +++ 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/modules/module-filter-chain/builtin_plugin.c b/src/modules/module-filter-chain/builtin_plugin.c index 527ad52cb..ab440e5cb 100644 --- a/src/modules/module-filter-chain/builtin_plugin.c +++ b/src/modules/module-filter-chain/builtin_plugin.c @@ -1301,11 +1301,9 @@ static void linear_run(void * Instance, unsigned long SampleCount) float *in = impl->port[1], *out = impl->port[0]; float *ctrl = impl->port[3], *notify = impl->port[2]; - if (in != NULL && out != NULL) { - unsigned long n; - for (n = 0; n < SampleCount; n++) - out[n] = in[n] * mult + add; - } + if (in != NULL && out != NULL) + dsp_ops_linear(dsp_ops, out, in, mult, add, SampleCount); + if (ctrl != NULL && notify != NULL) notify[0] = ctrl[0] * mult + add; } diff --git a/src/modules/module-filter-chain/dsp-ops-c.c b/src/modules/module-filter-chain/dsp-ops-c.c index 30fe8be18..03b4bceb8 100644 --- a/src/modules/module-filter-chain/dsp-ops-c.c +++ b/src/modules/module-filter-chain/dsp-ops-c.c @@ -33,8 +33,14 @@ static inline void dsp_gain_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t i; const float *s = src; float *d = dst; - for (i = 0; i < n_samples; i++) - d[i] = s[i] * gain; + if (gain == 0.0f) + dsp_clear_c(ops, dst, n_samples); + else if (gain == 1.0f) + dsp_copy_c(ops, dst, src, n_samples); + else { + for (i = 0; i < n_samples; i++) + d[i] = s[i] * gain; + } } static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, @@ -43,8 +49,15 @@ static inline void dsp_gain_add_c(struct dsp_ops *ops, void * SPA_RESTRICT dst, uint32_t i; const float *s = src; float *d = dst; - for (i = 0; i < n_samples; i++) - d[i] += s[i] * gain; + + if (gain == 0.0f) + return; + else if (gain == 1.0f) + dsp_add_c(ops, dst, src, n_samples); + else { + for (i = 0; i < n_samples; i++) + d[i] += s[i] * gain; + } } @@ -64,17 +77,9 @@ void dsp_mix_gain_c(struct dsp_ops *ops, if (n_src == 0) { dsp_clear_c(ops, dst, n_samples); } else { - if (gain[0] == 1.0f) - dsp_copy_c(ops, dst, src[0], n_samples); - else - dsp_gain_c(ops, dst, src[0], gain[0], n_samples); - - for (i = 1; i < n_src; i++) { - if (gain[i] == 1.0f) - dsp_add_c(ops, dst, src[i], n_samples); - else - dsp_gain_add_c(ops, dst, src[i], gain[i], n_samples); - } + dsp_gain_c(ops, dst, src[0], gain[0], n_samples); + for (i = 1; i < n_src; i++) + dsp_gain_add_c(ops, dst, src[i], gain[i], n_samples); } } @@ -113,6 +118,27 @@ void dsp_sum_c(struct dsp_ops *ops, float * dst, dst[i] = a[i] + b[i]; } +void dsp_linear_c(struct dsp_ops *ops, float * dst, + const float * SPA_RESTRICT src, const float mult, + const float add, uint32_t n_samples) +{ + uint32_t i; + if (add == 0.0f) { + dsp_gain_c(ops, dst, src, mult, n_samples); + } else { + if (mult == 0.0f) { + for (i = 0; i < n_samples; i++) + dst[i] = add; + } else if (mult == 1.0f) { + for (i = 0; i < n_samples; i++) + dst[i] = src[i] + add; + } else { + for (i = 0; i < n_samples; i++) + dst[i] = mult * src[i] + add; + } + } +} + void *dsp_fft_new_c(struct dsp_ops *ops, int32_t size, bool real) { return pffft_new_setup(size, real ? PFFFT_REAL : PFFFT_COMPLEX); diff --git a/src/modules/module-filter-chain/dsp-ops.c b/src/modules/module-filter-chain/dsp-ops.c index aed2c98d4..a66c8c663 100644 --- a/src/modules/module-filter-chain/dsp-ops.c +++ b/src/modules/module-filter-chain/dsp-ops.c @@ -27,6 +27,7 @@ static struct dsp_info dsp_table[] = .funcs.mix_gain = dsp_mix_gain_sse, .funcs.biquad_run = dsp_biquad_run_c, .funcs.sum = dsp_sum_avx, + .funcs.linear = dsp_linear_c, .funcs.fft_new = dsp_fft_new_c, .funcs.fft_free = dsp_fft_free_c, .funcs.fft_run = dsp_fft_run_c, @@ -41,6 +42,7 @@ static struct dsp_info dsp_table[] = .funcs.mix_gain = dsp_mix_gain_sse, .funcs.biquad_run = dsp_biquad_run_c, .funcs.sum = dsp_sum_sse, + .funcs.linear = dsp_linear_c, .funcs.fft_new = dsp_fft_new_c, .funcs.fft_free = dsp_fft_free_c, .funcs.fft_run = dsp_fft_run_c, @@ -54,6 +56,7 @@ static struct dsp_info dsp_table[] = .funcs.mix_gain = dsp_mix_gain_c, .funcs.biquad_run = dsp_biquad_run_c, .funcs.sum = dsp_sum_c, + .funcs.linear = dsp_linear_c, .funcs.fft_new = dsp_fft_new_c, .funcs.fft_free = dsp_fft_free_c, .funcs.fft_run = dsp_fft_run_c, diff --git a/src/modules/module-filter-chain/dsp-ops.h b/src/modules/module-filter-chain/dsp-ops.h index f6e87421b..8ccf07d18 100644 --- a/src/modules/module-filter-chain/dsp-ops.h +++ b/src/modules/module-filter-chain/dsp-ops.h @@ -37,6 +37,9 @@ struct dsp_ops_funcs { float * dst, const float * src, const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t len, const float scale); + void (*linear) (struct dsp_ops *ops, + float * dst, const float * SPA_RESTRICT src, + const float mult, const float add, uint32_t n_samples); }; struct dsp_ops { @@ -58,6 +61,7 @@ int dsp_ops_init(struct dsp_ops *ops); #define dsp_ops_mix_gain(ops,...) (ops)->funcs.mix_gain(ops, __VA_ARGS__) #define dsp_ops_biquad_run(ops,...) (ops)->funcs.biquad_run(ops, __VA_ARGS__) #define dsp_ops_sum(ops,...) (ops)->funcs.sum(ops, __VA_ARGS__) +#define dsp_ops_linear(ops,...) (ops)->funcs.linear(ops, __VA_ARGS__) #define dsp_ops_fft_new(ops,...) (ops)->funcs.fft_new(ops, __VA_ARGS__) #define dsp_ops_fft_free(ops,...) (ops)->funcs.fft_free(ops, __VA_ARGS__) @@ -79,6 +83,9 @@ void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, \ #define MAKE_SUM_FUNC(arch) \ void dsp_sum_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ const float * SPA_RESTRICT a, const float * SPA_RESTRICT b, uint32_t n_samples) +#define MAKE_LINEAR_FUNC(arch) \ +void dsp_linear_##arch (struct dsp_ops *ops, float * SPA_RESTRICT dst, \ + const float * SPA_RESTRICT src, const float mult, const float add, uint32_t n_samples) #define MAKE_FFT_NEW_FUNC(arch) \ void *dsp_fft_new_##arch(struct dsp_ops *ops, int32_t size, bool real) @@ -102,6 +109,7 @@ MAKE_COPY_FUNC(c); MAKE_MIX_GAIN_FUNC(c); MAKE_BIQUAD_RUN_FUNC(c); MAKE_SUM_FUNC(c); +MAKE_LINEAR_FUNC(c); MAKE_FFT_NEW_FUNC(c); MAKE_FFT_FREE_FUNC(c);