From 42be683ba413c623a2701f21316b4bfe3a9bcdf3 Mon Sep 17 00:00:00 2001 From: Taylor Holliday Date: Fri, 24 Jan 2025 14:03:59 -0800 Subject: [PATCH] #75 use AnalogOsc --- examples/synth/src/synth/mod.rs | 3 +++ examples/synth/src/synth/oscillator.rs | 31 ++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/examples/synth/src/synth/mod.rs b/examples/synth/src/synth/mod.rs index 4d80252..36ebc51 100644 --- a/examples/synth/src/synth/mod.rs +++ b/examples/synth/src/synth/mod.rs @@ -7,6 +7,9 @@ use rodio::Sink; mod oscillator; pub use oscillator::Oscillator; +mod osc; +use osc::AnalogOsc; + // The envelope state struct struct EnvelopeState { envelope: Envelope, diff --git a/examples/synth/src/synth/oscillator.rs b/examples/synth/src/synth/oscillator.rs index b3f8cb2..7a118ff 100644 --- a/examples/synth/src/synth/oscillator.rs +++ b/examples/synth/src/synth/oscillator.rs @@ -3,6 +3,8 @@ use rodio::source::Source; use std::f32::consts::PI; +use super::osc::AnalogOsc; + const SAMPLE_RATE: u32 = 48000; // The sample rate of the audio in Hz. // The wave type of the oscillator @@ -19,6 +21,7 @@ pub struct Oscillator { freq: f32, num_sample: usize, // The number of samples that have been played wave_type: WaveType, + osc: AnalogOsc, } // Allow dead code is used because main.rs doesn't use all of the wave types, just one of them @@ -26,41 +29,61 @@ pub struct Oscillator { impl Oscillator { #[allow(dead_code)] pub fn sine_wave(freq: f32) -> Oscillator { + + let mut osc = AnalogOsc::new(); + osc.set_sample_rate(SAMPLE_RATE as usize); + // Create a new sine wave oscillator Oscillator { freq, num_sample: 0, wave_type: WaveType::Sine, + osc } } #[allow(dead_code)] pub fn square_wave(freq: f32) -> Oscillator { + + let mut osc = AnalogOsc::new(); + osc.set_sample_rate(SAMPLE_RATE as usize); + // Create a new square wave oscillator Oscillator { freq, num_sample: 0, wave_type: WaveType::Square, + osc } } #[allow(dead_code)] pub fn sawtooth_wave(freq: f32) -> Oscillator { + + let mut osc = AnalogOsc::new(); + osc.set_sample_rate(SAMPLE_RATE as usize); + // Create a new sawtooth wave oscillator Oscillator { freq, num_sample: 0, wave_type: WaveType::Sawtooth, + osc } } #[allow(dead_code)] pub fn triangle_wave(freq: f32) -> Oscillator { + + let mut osc = AnalogOsc::new(); + osc.set_sample_rate(SAMPLE_RATE as usize); + // Create a new triangle wave oscillator Oscillator { freq, num_sample: 0, wave_type: WaveType::Triangle, + osc } } } @@ -77,10 +100,10 @@ impl Iterator for Oscillator { let value = 2.0 * PI * self.freq * t; match self.wave_type { - WaveType::Sine => Some(value.sin()), // Sine wave - WaveType::Square => Some(value.sin().signum()), // Signing the sine wave locks it to 1 or -1, making it a square wave. - WaveType::Sawtooth => Some(2.0 * (t % (1.0 / self.freq)) * self.freq - 1.0), // Sawtooth wave using modulo. - WaveType::Triangle => Some(value.sin().asin()), // The arcsine of the sine wave makes it a triangle wave. + WaveType::Sine => Some(value.sin()), // Sine wave, no anti-aliasing needed + WaveType::Square => Some(self.osc.tick_square(self.freq, 0.0, 0.0)), + WaveType::Sawtooth => Some(self.osc.tick_saw(self.freq, 0.0, 0.0)), + WaveType::Triangle => Some(value.sin().asin()), // The arcsine of the sine wave makes it a triangle wave. The MinBLEP AA method doesn't support triangle waves. } } }