mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	filter-chain: use Q value for biquad shelving filters
The current implementation uses the slope variable S to define the filter slope. Setting S = 1 results in a constant Q value of sqrt(2)/2, or 0.7071, which is a good default value. However, calculating alpha from the Q value instead, as done in RBJ's cookbook [1], the filter shape can be changed which might be desired for certain applications and provides flexibility. Since the current implementation always defaulted to using S = 1, make sure that configurations missing Q uses the same slope value. [1] = https://www.w3.org/TR/audio-eq-cookbook/
This commit is contained in:
		
							parent
							
								
									74fed1d208
								
							
						
					
					
						commit
						08af555e90
					
				
					 1 changed files with 18 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -15,6 +15,9 @@
 | 
			
		|||
#define M_PI 3.14159265358979323846
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* S = 1 in Q */
 | 
			
		||||
#define BIQUAD_SHELVING_DEFAULT_Q 0.707106781186548
 | 
			
		||||
 | 
			
		||||
static void set_coefficient(struct biquad *bq, double b0, double b1, double b2,
 | 
			
		||||
			    double a0, double a1, double a2)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -137,7 +140,8 @@ static void biquad_bandpass(struct biquad *bq, double frequency, double Q)
 | 
			
		|||
	set_coefficient(bq, b0, b1, b2, a0, a1, a2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void biquad_lowshelf(struct biquad *bq, double frequency, double db_gain)
 | 
			
		||||
static void biquad_lowshelf(struct biquad *bq, double frequency, double Q,
 | 
			
		||||
			    double db_gain)
 | 
			
		||||
{
 | 
			
		||||
	/* Clip frequencies to between 0 and 1, inclusive. */
 | 
			
		||||
	frequency = fmax(0.0, fmin(frequency, 1.0));
 | 
			
		||||
| 
						 | 
				
			
			@ -155,9 +159,12 @@ static void biquad_lowshelf(struct biquad *bq, double frequency, double db_gain)
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Set Q to an equivalent value to S = 1 if not specified */
 | 
			
		||||
	if (Q <= 0)
 | 
			
		||||
		Q = BIQUAD_SHELVING_DEFAULT_Q;
 | 
			
		||||
 | 
			
		||||
	double w0 = M_PI * frequency;
 | 
			
		||||
	double S = 1; /* filter slope (1 is max value) */
 | 
			
		||||
	double alpha = 0.5 * sin(w0) * sqrt((A + 1 / A) * (1 / S - 1) + 2);
 | 
			
		||||
	double alpha = sin(w0) / (2 * Q);
 | 
			
		||||
	double k = cos(w0);
 | 
			
		||||
	double k2 = 2 * sqrt(A) * alpha;
 | 
			
		||||
	double a_plus_one = A + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +180,7 @@ static void biquad_lowshelf(struct biquad *bq, double frequency, double db_gain)
 | 
			
		|||
	set_coefficient(bq, b0, b1, b2, a0, a1, a2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void biquad_highshelf(struct biquad *bq, double frequency,
 | 
			
		||||
static void biquad_highshelf(struct biquad *bq, double frequency, double Q,
 | 
			
		||||
			     double db_gain)
 | 
			
		||||
{
 | 
			
		||||
	/* Clip frequencies to between 0 and 1, inclusive. */
 | 
			
		||||
| 
						 | 
				
			
			@ -192,9 +199,12 @@ static void biquad_highshelf(struct biquad *bq, double frequency,
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Set Q to an equivalent value to S = 1 if not specified */
 | 
			
		||||
	if (Q <= 0)
 | 
			
		||||
		Q = BIQUAD_SHELVING_DEFAULT_Q;
 | 
			
		||||
 | 
			
		||||
	double w0 = M_PI * frequency;
 | 
			
		||||
	double S = 1; /* filter slope (1 is max value) */
 | 
			
		||||
	double alpha = 0.5 * sin(w0) * sqrt((A + 1 / A) * (1 / S - 1) + 2);
 | 
			
		||||
	double alpha = sin(w0) / (2 * Q);
 | 
			
		||||
	double k = cos(w0);
 | 
			
		||||
	double k2 = 2 * sqrt(A) * alpha;
 | 
			
		||||
	double a_plus_one = A + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -341,10 +351,10 @@ void biquad_set(struct biquad *bq, enum biquad_type type, double freq, double Q,
 | 
			
		|||
		biquad_bandpass(bq, freq, Q);
 | 
			
		||||
		break;
 | 
			
		||||
	case BQ_LOWSHELF:
 | 
			
		||||
		biquad_lowshelf(bq, freq, gain);
 | 
			
		||||
		biquad_lowshelf(bq, freq, Q, gain);
 | 
			
		||||
		break;
 | 
			
		||||
	case BQ_HIGHSHELF:
 | 
			
		||||
		biquad_highshelf(bq, freq, gain);
 | 
			
		||||
		biquad_highshelf(bq, freq, Q, gain);
 | 
			
		||||
		break;
 | 
			
		||||
	case BQ_PEAKING:
 | 
			
		||||
		biquad_peaking(bq, freq, Q, gain);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue