mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -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)
 | 
			
		||||
{
 | 
			
		||||
	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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <float.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,
 | 
			
		||||
			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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,8 @@
 | 
			
		|||
 | 
			
		||||
#include <spa/utils/defs.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue