ruffbox_synth 0.13.0

A beatbox-oriented synthesizer library.
Documentation
use super::encoder::Encoder;
use crate::building_blocks::SynthParameterValue;
use crate::building_blocks::{Panner, StereoPanner};

pub struct StereoEncoder<const BUFSIZE: usize, const NCHAN: usize> {
    left_enc: Encoder<BUFSIZE, NCHAN>,
    right_enc: Encoder<BUFSIZE, NCHAN>,
}

impl<const BUFSIZE: usize, const NCHAN: usize> Default for StereoEncoder<BUFSIZE, NCHAN> {
    fn default() -> Self {
        Self::new()
    }
}

impl<const BUFSIZE: usize, const NCHAN: usize> StereoEncoder<BUFSIZE, NCHAN> {
    pub fn new() -> Self {
        StereoEncoder {
            left_enc: Encoder::new(),
            right_enc: Encoder::new(),
        }
    }
}

impl<const BUFSIZE: usize, const NCHAN: usize> StereoPanner<BUFSIZE, NCHAN>
    for StereoEncoder<BUFSIZE, NCHAN>
{
    fn set_parameter(
        &mut self,
        par: crate::building_blocks::SynthParameterLabel,
        value: &crate::building_blocks::SynthParameterValue,
    ) {
        if let crate::building_blocks::SynthParameterLabel::AmbisonicAzimuth = par {
            let offset = std::f32::consts::PI / 6.0;
            let val_left = match value {
                SynthParameterValue::ScalarF32(s) => &SynthParameterValue::ScalarF32(s + offset),
                _ => value,
            };
            let val_right = match value {
                SynthParameterValue::ScalarF32(s) => &SynthParameterValue::ScalarF32(s - offset),
                _ => value,
            };
            self.left_enc.set_parameter(par, val_left);
            self.right_enc.set_parameter(par, val_right);
        } else {
            self.left_enc.set_parameter(par, value);
            self.right_enc.set_parameter(par, value);
        }
    }

    fn set_modulator(
        &mut self,
        par: crate::building_blocks::SynthParameterLabel,
        init: f32,
        modulator: crate::building_blocks::Modulator<BUFSIZE>,
    ) {
        if let crate::building_blocks::SynthParameterLabel::AmbisonicAzimuth = par {
            let offset = std::f32::consts::PI / 6.0;
            let mut mod_left = modulator.clone();
            let mut mod_right = modulator.clone();
            mod_left.add = offset;
            mod_right.add = -offset;
            self.left_enc.set_modulator(par, init, mod_left);
            self.right_enc.set_modulator(par, init, mod_right);
        } else {
            self.left_enc.set_modulator(par, init, modulator.clone());
            self.right_enc.set_modulator(par, init, modulator);
        }
    }

    fn process_block(
        &mut self,
        block: [[f32; BUFSIZE]; 2],
        start_sample: usize,
        sample_buffers: &[crate::building_blocks::SampleBuffer],
    ) -> [[f32; BUFSIZE]; NCHAN] {
        let left_out = self
            .left_enc
            .process_block(block[0], start_sample, sample_buffers);
        let right_out = self
            .right_enc
            .process_block(block[1], start_sample, sample_buffers);

        let mut out = [[0.0; BUFSIZE]; NCHAN];

        for ch in 0..NCHAN {
            for s in 0..BUFSIZE {
                out[ch][s] = left_out[ch][s] + right_out[ch][s];
            }
        }

        out
    }
}