// Calculate and LFO and move phase similar to Oscillator.rs // Ardura extern crate num_traits; use nih_plug::prelude::Enum; use serde::{Deserialize, Serialize}; #[derive(Clone, Serialize, Deserialize)] pub struct LFOController { frequency: f32, phase: f32, amplitude: f32, waveform: Waveform, } #[derive(Enum, PartialEq, Clone, Copy, Serialize, Deserialize)] pub enum LFORetrigger { None, NoteOn, } #[derive(Enum, PartialEq, Clone, Copy, Serialize, Deserialize)] pub enum LFOSnapValues { Quad, QuadD, QuadT, Double, DoubleD, DoubleT, Whole, WholeD, WholeT, Half, HalfD, HalfT, Quarter, QuarterD, QuarterT, Eighth, EighthD, EighthT, Sixteen, SixteenD, SixteenT, ThirtySecond, ThirtySecondD, ThirtySecondT, } #[derive(Enum, PartialEq, Clone, Copy, Serialize, Deserialize)] pub enum Waveform { Sine, Square, Triangle, Sawtooth, Ramp, PulseQuarter, PulseEigth, } impl LFOController { pub fn new(frequency: f32, amplitude: f32, waveform: Waveform, phase: f32) -> Self { LFOController { frequency, phase, amplitude, waveform, } } pub fn set_frequency(&mut self, frequency: f32) { self.frequency = frequency; } pub fn set_waveform(&mut self, waveform: Waveform) { self.waveform = waveform; } pub fn set_phase(&mut self, phase: f32) { self.phase = phase; } pub fn get_frequency(&mut self) -> f32 { self.frequency } pub fn get_waveform(&mut self) -> Waveform { self.waveform } pub fn next_sample(&mut self, sample_rate: f32) -> f32 { let delta_time = 1.0 / sample_rate; self.phase += self.frequency * delta_time; if self.phase >= 1.0 { self.phase -= 1.0; } match self.waveform { Waveform::Sine => self.amplitude * (2.0 * std::f32::consts::PI * self.phase).sin(), Waveform::Triangle => { if self.phase < 0.5 { 4.0 * self.amplitude * self.phase - self.amplitude } else { 3.0 * self.amplitude - 4.0 * self.amplitude * self.phase } } Waveform::Sawtooth => self.amplitude * (1.0 - 2.0 * self.phase), Waveform::Ramp => self.amplitude * self.phase, Waveform::Square => { if self.phase < 0.5 { self.amplitude } else { -self.amplitude } } Waveform::PulseQuarter => { if self.phase < 0.25 { self.amplitude } else { -self.amplitude } } Waveform::PulseEigth => { if self.phase < 0.125 { self.amplitude } else { -self.amplitude } } } } }