Skip to content

Commit

Permalink
iir copy over documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
GitGhillie committed Apr 3, 2024
1 parent 08fa479 commit 19242f9
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions crates/steam_audio/src/iir.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::delay::Delay;
use biquad::*;

/// Represents a biquad IIR filter, that can be used to carry out various filtering operations on RealSignals. Such a
/// filter is essentially a recurrence relation: sample N of the filtered output signal depends on samples N, N-1, and
/// N-2 of the input, as well as samples N-1 and N-2 of the _output_.
#[derive(Copy, Clone, Debug)]
pub struct IIR(DirectForm1<f32>);

impl IIR {
/// Creates a low-shelf filter (controls the amplitude of all frequencies below the cutoff).
pub fn new_low_shelf(high_cutoff: f32, gain: f32, sample_rate: i32) -> Self {
// Port note: The IIR crate used assumes gain is in dB.
// This does create some extra work that will hopefully be optimized away...
Expand All @@ -20,6 +24,7 @@ impl IIR {
IIR(DirectForm1::<f32>::new(coefficients.unwrap()))
}

/// Creates a high-shelf filter (controls the amplitude of all frequencies above the cutoff).
pub fn new_high_shelf(low_cutoff: f32, gain: f32, sample_rate: i32) -> Self {
// Port note: The IIR crate used assumes gain is in dB.
// This does create some extra work that will hopefully be optimized away...
Expand All @@ -35,6 +40,7 @@ impl IIR {
IIR(DirectForm1::<f32>::new(coefficients.unwrap()))
}

/// Creates a peaking filter (controls the amplitude of all frequencies between the cutoffs).
pub fn new_peaking(low_cutoff: f32, high_cutoff: f32, gain: f32, sample_rate: i32) -> Self {
// Port note: The IIR crate used assumes gain is in dB.
// This does create some extra work that will hopefully be optimized away...
Expand All @@ -57,14 +63,20 @@ impl IIR {
/// when the filter doesn't change between frames. If the filter _does_ change, the caller must implement
/// crossfading or some other approach to ensure smoothness.
pub struct IIRFilterer {
filter: IIR, // The IIR filter to apply.
xm1: f32, // Input value from 1 sample ago.
xm2: f32, // Input value from 2 samples ago.
ym1: f32, // Output value from 1 sample ago.
ym2: f32, // Output value from 2 samples ago.
/// The IIR filter to apply.
filter: IIR,
/// Input value from 1 sample ago.
xm1: f32,
/// Input value from 2 samples ago.
xm2: f32,
/// Output value from 1 sample ago.
ym1: f32,
/// Output value from 2 samples ago.
ym2: f32,
}

impl IIRFilterer {
// todo: With Phonon you can change the filterer at runtime. Let's see if we can get away with not doing that
pub fn new(filter: IIR) -> Self {
Self {
filter,
Expand All @@ -75,6 +87,7 @@ impl IIRFilterer {
}
}

/// Applies the filter to an entire buffer of input, using SIMD operations.
pub fn apply(&self, size: usize, input: &[f32], output: &mut [f32]) {
//self.filter
}
Expand Down

0 comments on commit 19242f9

Please sign in to comment.