Skip to content

Commit

Permalink
Added Peaking-EQ and Allpass filters
Browse files Browse the repository at this point in the history
  • Loading branch information
yacinbm committed Jan 22, 2024
1 parent f1128fb commit 61f50a8
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 1 deletion.
86 changes: 85 additions & 1 deletion crates/augmented/dsp/dsp-filters/src/rbj/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ pub enum FilterType {
BandStop,
LowShelf,
HighShelf,
// TODO: BandShelf, AllPass,
AllPass,
PeakEq,
// TODO: BandShelf
}

/// Calculate low-pass coefficients
Expand Down Expand Up @@ -214,6 +216,58 @@ pub fn setup_high_shelf<Sample: Float + FloatConst + Pow<Sample, Output = Sample
coefficients.set_coefficients(a0, a1, a2, b0, b1, b2);
}

/// Calculate all-pass coefficients
pub fn setup_all_pass<Sample: Float + FloatConst>(
coefficients: &mut BiquadCoefficients<Sample>,
sample_rate: Sample,
center_frequency: Sample,
q: Sample,
) {
let one: Sample = Sample::from(1.0).unwrap();
let two: Sample = Sample::from(2.0).unwrap();

let w0: Sample = two * Sample::PI() * center_frequency / sample_rate;
let cs: Sample = w0.cos();
let sn: Sample = w0.sin();
let al: Sample = sn / (two * q);
let b0: Sample = one - al;
let b1: Sample = -two * cs;
let b2: Sample = one + al;
let a0: Sample = one + al;
let a1: Sample = -two * cs;
let a2: Sample = one - al;

coefficients.set_coefficients(a0, a1, a2, b0, b1, b2);
}

// Calculate peaking-eq coefficients
pub fn setup_peaking_eq<Sample: Float + FloatConst + Pow<Sample, Output = Sample>>(
coefficients: &mut BiquadCoefficients<Sample>,
sample_rate: Sample,
center_frequency: Sample,
gain_db: Sample,
band_width: Sample,
){
let gain: Sample = Sample::from(10.0)
.unwrap()
.pow(gain_db / Sample::from(40.0).unwrap());
let one: Sample = Sample::from(1.0).unwrap();
let two: Sample = Sample::from(2.0).unwrap();

let w0: Sample = two * Sample::PI() * center_frequency / sample_rate;
let cs: Sample = w0.cos();
let sn: Sample = w0.sin();
let al: Sample = sn * Sample::from(two.ln() * band_width * w0 / (two * sn)).unwrap().sinh();
let b0: Sample = one + al * gain;
let b1: Sample = -two * cs;
let b2: Sample = one - al * gain;
let a0: Sample = one + al / gain;
let a1: Sample = -two * cs;
let a2: Sample = one - al / gain;

coefficients.set_coefficients(a0, a1, a2, b0, b1, b2);
}

/// Holds the state and coefficients for a filter.
pub struct Filter<Sample: Float> {
pub coefficients: BiquadCoefficients<Sample>,
Expand Down Expand Up @@ -333,6 +387,36 @@ impl<Sample: Pow<Sample, Output = Sample> + Debug + Float + FloatConst> Filter<S
);
}

pub fn setup_all_pass(
&mut self,
sample_rate: Sample,
center_frequency: Sample,
q: Sample,
) {
setup_all_pass(
&mut self.coefficients,
sample_rate,
center_frequency,
q
);
}

pub fn setup_peaking_eq(
&mut self,
sample_rate: Sample,
center_frequency: Sample,
gain_db: Sample,
band_width: Sample,
) {
setup_peaking_eq(
&mut self.coefficients,
sample_rate,
center_frequency,
gain_db,
band_width
);
}

/// Process an input [`AudioBuffer`] instance. The [`Filter`] struct is mono (see
/// [`FilterProcessor`] for multi-channel usage).
///
Expand Down
23 changes: 23 additions & 0 deletions crates/augmented/dsp/dsp-filters/src/rbj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ where
self.setup();
}

/// Change the bandwidth
pub fn set_band_width(&mut self, band_width: SampleType) {
self.q = band_width;
self.setup();
}

/// Change the center-frequency
pub fn set_center_frequency(&mut self, center_frequency: SampleType) {
self.cutoff = center_frequency;
Expand Down Expand Up @@ -200,6 +206,21 @@ where
self.slope,
);
}
FilterType::AllPass => {
self.filter.setup_all_pass(
self.sample_rate,
self.cutoff,
self.q
);
}
FilterType::PeakEq => {
self.filter.setup_peaking_eq(
self.sample_rate,
self.cutoff,
self.gain_db,
self.q
);
}
}
}
}
Expand Down Expand Up @@ -254,6 +275,8 @@ mod test {
("band-stop", BandStop),
("low-shelf", LowShelf),
("high-shelf", HighShelf),
("peaking-eq", PeakEq),
("all-pass", AllPass),
];

for (filter_name, filter_type) in filters {
Expand Down

0 comments on commit 61f50a8

Please sign in to comment.