rill-core-dsp 0.6.0-M2

Core DSP abstractions and algorithms for Rill
Documentation
use rill_core::builtin::{BuiltinKind, BuiltinSig, Registry};
use rill_core::math::Transcendental;
use rill_core::traits::algorithm::Algorithm;

use crate::filters::{Biquad, FilterParams, FilterType, MoogLadder, OnePole};
use crate::generators::{BasicOscillator, Generator, NoiseGenerator, NoiseType, Waveform};

use super::biquad::{BiquadBuiltin, GeneralBiquadBuiltin};
use super::moog::MoogBuiltin;
use super::noise::NoiseGenBuiltin;
use super::onepole::OnePoleBuiltin;
use super::osc::OscBuiltin;

pub fn register_lang_builtins<T: Transcendental + 'static>(reg: &mut Registry<T>) {
    register_filters(reg);
    register_oscillators(reg);
}

fn register_filters<T: Transcendental + 'static>(reg: &mut Registry<T>) {
    reg.register_sample(
        BuiltinSig::simple("onepole", 1, 1, 2, BuiltinKind::Sample).with_names(vec!["cutoff", "q"]),
        |p, sr| {
            let mut inner = OnePole::<T>::new(FilterParams {
                filter_type: FilterType::LowPass,
                cutoff: p[0] as f32,
                q: p[1] as f32,
                gain_db: 0.0,
            });
            Algorithm::init(&mut inner, sr);
            Box::new(OnePoleBuiltin { inner })
        },
    );
    reg.register_sample(
        BuiltinSig::simple("moog", 1, 1, 2, BuiltinKind::Sample)
            .with_names(vec!["cutoff", "resonance"]),
        |p, sr| {
            let mut inner = MoogLadder::<T>::new(p[0] as f32, p[1] as f32);
            Algorithm::init(&mut inner, sr);
            Box::new(MoogBuiltin { inner })
        },
    );
    reg.register_block(
        BuiltinSig::simple("lowpass", 1, 1, 2, BuiltinKind::Block).with_names(vec!["cutoff", "q"]),
        |p, sr| {
            let mut b = Biquad::<T>::new(FilterParams {
                filter_type: FilterType::LowPass,
                cutoff: p[0] as f32,
                q: p[1] as f32,
                gain_db: 0.0,
            });
            Algorithm::init(&mut b, sr);
            Box::new(BiquadBuiltin { inner: b })
        },
    );
    reg.register_block(
        BuiltinSig::simple("highpass", 1, 1, 2, BuiltinKind::Block).with_names(vec!["cutoff", "q"]),
        |p, sr| {
            let mut b = Biquad::<T>::new(FilterParams {
                filter_type: FilterType::HighPass,
                cutoff: p[0] as f32,
                q: p[1] as f32,
                gain_db: 0.0,
            });
            Algorithm::init(&mut b, sr);
            Box::new(BiquadBuiltin { inner: b })
        },
    );
    reg.register_block(
        BuiltinSig::simple("biquad", 1, 1, 4, BuiltinKind::Block)
            .with_names(vec!["type", "cutoff", "q", "gain_db"]),
        |p, sr| {
            let ft = match p[0] as u8 {
                0 => FilterType::LowPass,
                1 => FilterType::HighPass,
                2 => FilterType::BandPass,
                3 => FilterType::Notch,
                4 => FilterType::Peak,
                5 => FilterType::LowShelf,
                6 => FilterType::HighShelf,
                _ => FilterType::LowPass,
            };
            let mut b = Biquad::<T>::new(FilterParams {
                filter_type: ft,
                cutoff: p[1] as f32,
                q: p[2] as f32,
                gain_db: p[3] as f32,
            });
            Algorithm::init(&mut b, sr);
            Box::new(GeneralBiquadBuiltin { inner: b })
        },
    );
}

fn register_oscillators<T: Transcendental + 'static>(reg: &mut Registry<T>) {
    reg.register_block(
        BuiltinSig::simple("sine", 0, 1, 3, BuiltinKind::Block)
            .with_names(vec!["freq", "amp", "phase"]),
        |p, sr| {
            let freq = p[0] as f32;
            let amp = T::from_f64(p[1]);
            let mut osc = BasicOscillator::<T>::new(Waveform::Sine, freq, amp);
            osc.set_phase(T::from_f64(p[2]));
            Algorithm::init(&mut osc, sr);
            Box::new(OscBuiltin { osc })
        },
    );
    reg.register_block(
        BuiltinSig::simple("saw", 0, 1, 3, BuiltinKind::Block)
            .with_names(vec!["freq", "amp", "phase"]),
        |p, sr| {
            let freq = p[0] as f32;
            let amp = T::from_f64(p[1]);
            let mut osc = BasicOscillator::<T>::new(Waveform::Saw, freq, amp);
            osc.set_phase(T::from_f64(p[2]));
            Algorithm::init(&mut osc, sr);
            Box::new(OscBuiltin { osc })
        },
    );
    reg.register_block(
        BuiltinSig::simple("square", 0, 1, 3, BuiltinKind::Block)
            .with_names(vec!["freq", "amp", "phase"]),
        |p, sr| {
            let freq = p[0] as f32;
            let amp = T::from_f64(p[1]);
            let mut osc = BasicOscillator::<T>::new(Waveform::Square, freq, amp);
            osc.set_phase(T::from_f64(p[2]));
            Algorithm::init(&mut osc, sr);
            Box::new(OscBuiltin { osc })
        },
    );
    reg.register_block(
        BuiltinSig::simple("triangle", 0, 1, 3, BuiltinKind::Block)
            .with_names(vec!["freq", "amp", "phase"]),
        |p, sr| {
            let freq = p[0] as f32;
            let amp = T::from_f64(p[1]);
            let mut osc = BasicOscillator::<T>::new(Waveform::Triangle, freq, amp);
            osc.set_phase(T::from_f64(p[2]));
            Algorithm::init(&mut osc, sr);
            Box::new(OscBuiltin { osc })
        },
    );
    reg.register_block(
        BuiltinSig::simple("noise", 0, 1, 2, BuiltinKind::Block).with_names(vec!["type", "amp"]),
        |p, _sr| {
            let amp = T::from_f64(p[1]);
            let gen = NoiseGenerator::<T>::new(
                match p[0].round() as i32 {
                    1 => NoiseType::Pink,
                    2 => NoiseType::Brown,
                    _ => NoiseType::White,
                },
                amp,
            );
            Box::new(NoiseGenBuiltin { gen })
        },
    );
}