midix_synth 0.0.4

SoundFont compatible MIDI synthesizer for midix
Documentation
use std::f64::consts;

pub(crate) struct Chorus {
    buffer_l: Vec<f32>,
    buffer_r: Vec<f32>,

    delay_table: Vec<f32>,

    buffer_index: usize,

    delay_table_index_l: usize,
    delay_table_index_r: usize,
}

impl Chorus {
    pub(crate) fn new(sample_rate: i32, delay: f64, depth: f64, frequency: f64) -> Self {
        let buffer_l = vec![0_f32; ((sample_rate as f64) * (delay + depth)) as usize + 2];
        let buffer_r = vec![0_f32; ((sample_rate as f64) * (delay + depth)) as usize + 2];

        let mut delay_table = vec![0_f32; ((sample_rate as f64) / frequency).round() as usize];
        let delay_table_length = delay_table.len();
        for (t, input) in delay_table.iter_mut().enumerate().take(delay_table_length) {
            let phase = 2.0 * consts::PI * (t as f64) / (delay_table_length as f64);
            *input = ((sample_rate as f64) * (delay + depth * phase.sin())) as f32;
        }

        let buffer_index: usize = 0;

        let delay_table_index_l: usize = 0;
        let delay_table_index_r: usize = delay_table_length / 4;

        Self {
            buffer_l,
            buffer_r,
            delay_table,
            buffer_index,
            delay_table_index_l,
            delay_table_index_r,
        }
    }

    pub(crate) fn process(
        &mut self,
        input_left: &[f32],
        input_right: &[f32],
        output_left: &mut [f32],
        output_right: &mut [f32],
    ) {
        let buffer_length = self.buffer_l.len();
        let delay_table_length = self.delay_table.len();
        let output_length = output_left.len();

        for t in 0..output_length {
            {
                let mut position =
                    self.buffer_index as f64 - self.delay_table[self.delay_table_index_l] as f64;
                if position < 0.0 {
                    position += buffer_length as f64;
                }

                let index1 = position as usize;
                let mut index2 = index1 + 1;
                if index2 == buffer_length {
                    index2 = 0;
                }

                let x1 = self.buffer_l[index1] as f64;
                let x2 = self.buffer_l[index2] as f64;
                let a = position - index1 as f64;
                output_left[t] = (x1 + a * (x2 - x1)) as f32;

                self.delay_table_index_l += 1;
                if self.delay_table_index_l == delay_table_length {
                    self.delay_table_index_l = 0;
                }
            }

            {
                let mut position =
                    self.buffer_index as f64 - self.delay_table[self.delay_table_index_r] as f64;
                if position < 0.0 {
                    position += buffer_length as f64;
                }

                let index1 = position as usize;
                let mut index2 = index1 + 1;
                if index2 == buffer_length {
                    index2 = 0;
                }

                let x1 = self.buffer_r[index1] as f64;
                let x2 = self.buffer_r[index2] as f64;
                let a = position - index1 as f64;
                output_right[t] = (x1 + a * (x2 - x1)) as f32;

                self.delay_table_index_r += 1;
                if self.delay_table_index_r == delay_table_length {
                    self.delay_table_index_r = 0;
                }
            }

            self.buffer_l[self.buffer_index] = input_left[t];
            self.buffer_r[self.buffer_index] = input_right[t];
            self.buffer_index += 1;
            if self.buffer_index == buffer_length {
                self.buffer_index = 0;
            }
        }
    }

    pub(crate) fn mute(&mut self) {
        let buffer_length = self.buffer_l.len();

        for t in 0..buffer_length {
            self.buffer_l[t] = 0_f32;
        }

        for t in 0..buffer_length {
            self.buffer_r[t] = 0_f32;
        }
    }
}