13 releases (4 stable)

1.3.1 Oct 22, 2022
1.2.1 Sep 29, 2022
1.0.0-alpha.7 May 25, 2022
1.0.0-alpha.5 Apr 7, 2022
0.2.0 Oct 30, 2021

#437 in Audio

Download history 14/week @ 2022-08-20 17/week @ 2022-09-03 38/week @ 2022-09-10 17/week @ 2022-09-17 47/week @ 2022-09-24 50/week @ 2022-10-01 16/week @ 2022-10-08 8/week @ 2022-10-15 48/week @ 2022-10-22 28/week @ 2022-10-29 24/week @ 2022-11-05 10/week @ 2022-11-12 10/week @ 2022-11-19 6/week @ 2022-11-26

67 downloads per month
Used in 2 crates

MIT license

82KB
1.5K SLoC

augmented-dsp-filters

crates.io docs.rs


Mechanical port of Vinnie Falco's https://github.com/vinniefalco/DSPFilters/.

Only RBJ filters are ported over. No introspection is supported & the implementation is quite a different (as Rust would prefer composition to multiple inheritance).

Very untested, be careful with your speakers.

Depends on audio-processor-traits. Exports FilterProcessor which may be used for general filtering needs.

See synth on this repository for a nice working example.

Low-pass filter example

use audio_processor_traits::{
    AudioBuffer, AudioProcessor, AudioProcessorSettings
};
use augmented_dsp_filters::rbj::{FilterProcessor, FilterType};

pub struct YourProcessor {
    filter: FilterProcessor<f32>, // <- f32 may be f64 if you wish
}

impl YourProcessor {
    fn new() -> Self {
        Self {
            filter: FilterProcessor::new(FilterType::LowPass),
        }
    }
    
    fn set_cutoff(&mut self, midi_value_between_0_and_127: f32) {
        let cutoff_ratio = midi_value_between_0_and_127 / 127.0;
        let cutoff_freq_hz = 22000.0 * cutoff_ratio;
        self.filter.set_cutoff(cutoff_freq_hz);
    }
    
    fn set_q(&mut self, q: f32) {
        self.filter.set_q(q);
    }
}

impl AudioProcessor for YourProcessor {
    type SampleType = f32;

    fn prepare(&mut self, settings: AudioProcessorSettings) {
        self.filter.prepare(settings);
    }

    fn process<BufferType: AudioBuffer<SampleType = Self::SampleType>>(
        &mut self,
        data: &mut BufferType,
    ) {
        self.filter.process(data);
    }
}

Multi-threading

The filter mutate functions recalculate coefficients for the filter. This should run on the audio-thread only.

In order to integrate with MIDI, see synth; this won't be a problem as AudioProcessor (stand-alone) will receive MIDI on the audio-thread.

For integrating with a GUI thread, the best would probably be to have the audio-thread read the parameters from an atomic store & update the filter when they change (see audio-parameter-store in this repository).

License

MIT licensed as the original.

Dependencies

~0.8–1.5MB
~33K SLoC