Skip to content

Commit

Permalink
Start to add way to calculate response
Browse files Browse the repository at this point in the history
  • Loading branch information
yamadapc committed Aug 20, 2024
1 parent 5962ecd commit 2cea36b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 10 deletions.
38 changes: 37 additions & 1 deletion crates/augmented/dsp/dsp-filters/src/coefficients/biquad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
use num::Float;

use num::{Complex, Float};
use std::f64::consts::PI;

pub struct BiquadCoefficients<Sample: Float> {
pub(crate) a0: Sample,
Expand All @@ -44,7 +46,41 @@ impl<Sample: Float> Default for BiquadCoefficients<Sample> {
}
}

fn add_mul<T: Float>(c: Complex<T>, v: T, c1: Complex<T>) -> Complex<T> {
Complex::new(c.re + v * c1.re, c.im + v * c1.im)
}

impl<Sample: Float> BiquadCoefficients<Sample> {
/// Calculate the filter response to a given frequency. Useful for drawing frequency response
/// charts.
///
/// Takes in a normalized_frequency between 0 and 1.
pub fn response(&self, normalized_frequency: Sample) -> Complex<f64> {
let w: f64 = 2.0 * PI * normalized_frequency.to_f64().unwrap();
let czn1 = Complex::from_polar(1., -w);
let czn2 = Complex::from_polar(1., -2.0 * w);
let mut ch = Complex::new(1.0, 0.0);
let mut cbot = Complex::new(1.0, 0.0);

let a0: f64 = self.a0.to_f64().unwrap();
let b0: f64 = self.b0.to_f64().unwrap();
let b1: f64 = self.b1.to_f64().unwrap();
let b2: f64 = self.b2.to_f64().unwrap();
let a1: f64 = self.a1.to_f64().unwrap();
let a2: f64 = self.a2.to_f64().unwrap();

let mut ct = Complex::new(b0 / a0, 0.0);
let mut cb = Complex::new(1.0, 0.0);
ct = add_mul(ct, b1 / a0, czn1);
ct = add_mul(ct, b2 / a0, czn2);
cb = add_mul(cb, a1 / a0, czn1);
cb = add_mul(cb, a2 / a0, czn2);
ch *= ct;
cbot *= cb;

ch / cbot
}

pub fn set_coefficients(
&mut self,
a0: Sample,
Expand Down
22 changes: 13 additions & 9 deletions crates/augmented/dsp/dsp-filters/src/rbj/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,7 @@ where
#[cfg(test)]
mod test {
use audio_processor_testing_helpers::charts::*;

use audio_processor_traits::simple_processor::MultiChannel;
use num::complex::ComplexFloat;

use super::*;

Expand All @@ -273,16 +272,21 @@ mod test {
];

for (filter_name, filter_type) in filters {
let mut processor = MultiChannel::new(move || {
let processor = {
let mut processor = FilterProcessor::new(filter_type);
processor.set_cutoff(880.0);
processor
});
generate_frequency_response_plot(
&format!("{}{}", env!("CARGO_MANIFEST_DIR"), "/src/rbj/mod.rs"),
&format!("{}-880hz-frequency-response", filter_name),
&mut processor,
);
};
let filename = format!("{}{}", env!("CARGO_MANIFEST_DIR"), "/src/rbj/mod.rs");
let plot_name = format!("{}-880hz-frequency-response", filter_name);
let mut data = vec![];
let mut freq = 0.0;
while freq < 44100.0 {
let response = processor.filter.coefficients.response(freq / 44100.0);
data.push(response.abs() as f32);
freq += 100.0;
}
draw_vec_chart(&filename, &plot_name, data);
}
}
}

0 comments on commit 2cea36b

Please sign in to comment.