mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
filter-chain: add biquad to dsp functions
This commit is contained in:
parent
01b2552b71
commit
ca8bc59d0a
4 changed files with 51 additions and 28 deletions
|
|
@ -260,14 +260,11 @@ static struct fc_port bq_ports[] = {
|
||||||
static void bq_run(struct builtin *impl, unsigned long samples, int type)
|
static void bq_run(struct builtin *impl, unsigned long samples, int type)
|
||||||
{
|
{
|
||||||
struct biquad *bq = &impl->bq;
|
struct biquad *bq = &impl->bq;
|
||||||
unsigned long i;
|
|
||||||
float *out = impl->port[0];
|
float *out = impl->port[0];
|
||||||
float *in = impl->port[1];
|
float *in = impl->port[1];
|
||||||
float freq = impl->port[2][0];
|
float freq = impl->port[2][0];
|
||||||
float Q = impl->port[3][0];
|
float Q = impl->port[3][0];
|
||||||
float gain = impl->port[4][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) {
|
if (impl->freq != freq || impl->Q != Q || impl->gain != gain) {
|
||||||
impl->freq = freq;
|
impl->freq = freq;
|
||||||
|
|
@ -275,30 +272,7 @@ static void bq_run(struct builtin *impl, unsigned long samples, int type)
|
||||||
impl->gain = gain;
|
impl->gain = gain;
|
||||||
biquad_set(bq, type, freq * 2 / impl->rate, Q, gain);
|
biquad_set(bq, type, freq * 2 / impl->rate, Q, gain);
|
||||||
}
|
}
|
||||||
x1 = bq->x1;
|
dsp_ops_biquad_run(&dsp_ops, bq, out, in, samples);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** bq_lowpass */
|
/** bq_lowpass */
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
#include <spa/utils/defs.h>
|
#include <spa/utils/defs.h>
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ struct dsp_info {
|
||||||
void * SPA_RESTRICT dst,
|
void * SPA_RESTRICT dst,
|
||||||
const void * SPA_RESTRICT src[],
|
const void * SPA_RESTRICT src[],
|
||||||
float gain[], uint32_t n_src, uint32_t n_samples);
|
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[] =
|
static struct dsp_info dsp_table[] =
|
||||||
|
|
@ -50,11 +52,13 @@ static struct dsp_info dsp_table[] =
|
||||||
{ SPA_CPU_FLAG_SSE,
|
{ SPA_CPU_FLAG_SSE,
|
||||||
.copy = dsp_copy_c,
|
.copy = dsp_copy_c,
|
||||||
.mix_gain = dsp_mix_gain_sse,
|
.mix_gain = dsp_mix_gain_sse,
|
||||||
|
.biquad_run = dsp_biquad_run_c,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
{ 0,
|
{ 0,
|
||||||
.copy = dsp_copy_c,
|
.copy = dsp_copy_c,
|
||||||
.mix_gain = dsp_mix_gain_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->cpu_flags = info->cpu_flags;
|
||||||
ops->copy = info->copy;
|
ops->copy = info->copy;
|
||||||
ops->mix_gain = info->mix_gain;
|
ops->mix_gain = info->mix_gain;
|
||||||
|
ops->biquad_run = info->biquad_run;
|
||||||
ops->free = impl_dsp_ops_free;
|
ops->free = impl_dsp_ops_free;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
#include <spa/utils/defs.h>
|
#include <spa/utils/defs.h>
|
||||||
|
|
||||||
|
#include "biquad.h"
|
||||||
|
|
||||||
struct dsp_ops {
|
struct dsp_ops {
|
||||||
uint32_t cpu_flags;
|
uint32_t cpu_flags;
|
||||||
|
|
||||||
|
|
@ -35,6 +37,8 @@ struct dsp_ops {
|
||||||
void * SPA_RESTRICT dst,
|
void * SPA_RESTRICT dst,
|
||||||
const void * SPA_RESTRICT src[],
|
const void * SPA_RESTRICT src[],
|
||||||
float gain[], uint32_t n_src, uint32_t n_samples);
|
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);
|
void (*free) (struct dsp_ops *ops);
|
||||||
|
|
||||||
const void *priv;
|
const void *priv;
|
||||||
|
|
@ -44,6 +48,7 @@ int dsp_ops_init(struct dsp_ops *ops);
|
||||||
|
|
||||||
#define dsp_ops_copy(ops,...) (ops)->copy(ops, __VA_ARGS__)
|
#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_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 dsp_ops_free(ops) (ops)->free(ops)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -53,10 +58,14 @@ void dsp_copy_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \
|
||||||
#define MAKE_MIX_GAIN_FUNC(arch) \
|
#define MAKE_MIX_GAIN_FUNC(arch) \
|
||||||
void dsp_mix_gain_##arch(struct dsp_ops *ops, void * SPA_RESTRICT dst, \
|
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)
|
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_COPY_FUNC(c);
|
||||||
MAKE_MIX_GAIN_FUNC(c);
|
MAKE_MIX_GAIN_FUNC(c);
|
||||||
|
MAKE_BIQUAD_RUN_FUNC(c);
|
||||||
#if defined (HAVE_SSE)
|
#if defined (HAVE_SSE)
|
||||||
MAKE_MIX_GAIN_FUNC(sse);
|
MAKE_MIX_GAIN_FUNC(sse);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue