diff --git a/src/modules/module-filter-chain/builtin_plugin.c b/src/modules/module-filter-chain/builtin_plugin.c index 6918ad91d..8e88d34e9 100644 --- a/src/modules/module-filter-chain/builtin_plugin.c +++ b/src/modules/module-filter-chain/builtin_plugin.c @@ -260,14 +260,11 @@ static struct fc_port bq_ports[] = { static void bq_run(struct builtin *impl, unsigned long samples, int type) { struct biquad *bq = &impl->bq; - unsigned long i; float *out = impl->port[0]; float *in = impl->port[1]; float freq = impl->port[2][0]; float Q = impl->port[3][0]; float gain = impl->port[4][0]; - float x1, x2, y1, y2; - float b0, b1, b2, a1, a2; if (impl->freq != freq || impl->Q != Q || impl->gain != gain) { impl->freq = freq; @@ -275,30 +272,7 @@ static void bq_run(struct builtin *impl, unsigned long samples, int type) impl->gain = gain; biquad_set(bq, type, freq * 2 / impl->rate, Q, gain); } - x1 = bq->x1; - x2 = bq->x2; - y1 = bq->y1; - y2 = bq->y2; - b0 = bq->b0; - b1 = bq->b1; - b2 = bq->b2; - a1 = bq->a1; - a2 = bq->a2; - for (i = 0; i < samples; i++) { - float x = in[i]; - float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2; - out[i] = y; - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - } -#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x)) - bq->x1 = F(x1); - bq->x2 = F(x2); - bq->y1 = F(y1); - bq->y2 = F(y2); -#undef F + dsp_ops_biquad_run(&dsp_ops, bq, out, in, samples); } /** bq_lowpass */ diff --git a/src/modules/module-filter-chain/dsp-ops-c.c b/src/modules/module-filter-chain/dsp-ops-c.c index 885c8cd38..d559a415b 100644 --- a/src/modules/module-filter-chain/dsp-ops-c.c +++ b/src/modules/module-filter-chain/dsp-ops-c.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -98,3 +99,37 @@ void dsp_mix_gain_c(struct dsp_ops *ops, } } } + +void dsp_biquad_run_c(struct dsp_ops *ops, struct biquad *bq, + float *out, const float *in, uint32_t n_samples) +{ + float x1, x2, y1, y2; + float b0, b1, b2, a1, a2; + uint32_t i; + + x1 = bq->x1; + x2 = bq->x2; + y1 = bq->y1; + y2 = bq->y2; + b0 = bq->b0; + b1 = bq->b1; + b2 = bq->b2; + a1 = bq->a1; + a2 = bq->a2; + for (i = 0; i < n_samples; i++) { + float x = in[i]; + float y = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2; + out[i] = y; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } +#define F(x) (-FLT_MIN < (x) && (x) < FLT_MIN ? 0.0f : (x)) + bq->x1 = F(x1); + bq->x2 = F(x2); + bq->y1 = F(y1); + bq->y2 = F(y2); +#undef F +} + diff --git a/src/modules/module-filter-chain/dsp-ops.c b/src/modules/module-filter-chain/dsp-ops.c index b40278bf6..2fbf5c32f 100644 --- a/src/modules/module-filter-chain/dsp-ops.c +++ b/src/modules/module-filter-chain/dsp-ops.c @@ -42,6 +42,8 @@ struct dsp_info { void * SPA_RESTRICT dst, const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples); + void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, + float *out, const float *in, uint32_t n_samples); }; static struct dsp_info dsp_table[] = @@ -50,11 +52,13 @@ static struct dsp_info dsp_table[] = { SPA_CPU_FLAG_SSE, .copy = dsp_copy_c, .mix_gain = dsp_mix_gain_sse, + .biquad_run = dsp_biquad_run_c, }, #endif { 0, .copy = dsp_copy_c, .mix_gain = dsp_mix_gain_c, + .biquad_run = dsp_biquad_run_c, }, }; @@ -86,6 +90,7 @@ int dsp_ops_init(struct dsp_ops *ops) ops->cpu_flags = info->cpu_flags; ops->copy = info->copy; ops->mix_gain = info->mix_gain; + ops->biquad_run = info->biquad_run; ops->free = impl_dsp_ops_free; return 0; diff --git a/src/modules/module-filter-chain/dsp-ops.h b/src/modules/module-filter-chain/dsp-ops.h index ffbca6ce7..3bf7cda19 100644 --- a/src/modules/module-filter-chain/dsp-ops.h +++ b/src/modules/module-filter-chain/dsp-ops.h @@ -24,6 +24,8 @@ #include +#include "biquad.h" + struct dsp_ops { uint32_t cpu_flags; @@ -35,6 +37,8 @@ struct dsp_ops { void * SPA_RESTRICT dst, const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples); + void (*biquad_run) (struct dsp_ops *ops, struct biquad *bq, + float *out, const float *in, uint32_t n_samples); void (*free) (struct dsp_ops *ops); const void *priv; @@ -44,19 +48,24 @@ int dsp_ops_init(struct dsp_ops *ops); #define dsp_ops_copy(ops,...) (ops)->copy(ops, __VA_ARGS__) #define dsp_ops_mix_gain(ops,...) (ops)->mix_gain(ops, __VA_ARGS__) +#define dsp_ops_biquad_run(ops,...) (ops)->biquad_run(ops, __VA_ARGS__) #define dsp_ops_free(ops) (ops)->free(ops) #define MAKE_COPY_FUNC(arch) \ void dsp_copy_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ - const void * SPA_RESTRICT src, uint32_t n_samples) + const void * SPA_RESTRICT src, uint32_t n_samples) #define MAKE_MIX_GAIN_FUNC(arch) \ void dsp_mix_gain_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \ const void * SPA_RESTRICT src[], float gain[], uint32_t n_src, uint32_t n_samples) +#define MAKE_BIQUAD_RUN_FUNC(arch) \ +void dsp_biquad_run_##arch (struct dsp_ops *ops, struct biquad *bq, \ + float *out, const float *in, uint32_t n_samples) MAKE_COPY_FUNC(c); MAKE_MIX_GAIN_FUNC(c); +MAKE_BIQUAD_RUN_FUNC(c); #if defined (HAVE_SSE) MAKE_MIX_GAIN_FUNC(sse); #endif