diff options
author | Grant Shangreaux <grant@unabridgedsoftware.com> | 2021-11-12 23:40:33 -0600 |
---|---|---|
committer | Grant Shangreaux <grant@unabridgedsoftware.com> | 2021-11-12 23:40:33 -0600 |
commit | d3776887db90ac1ea15fd55d833ff6b3042e7caf (patch) | |
tree | a23ba500470883cf12635405f86fb2adc0ba1546 /klangfarbrs/src/osc.rs | |
parent | 200e3568f5b7b5aab5388512ddefceb813168f90 (diff) |
Add: Osc Iterator refactor
Now the MonoSynth has one main `osc` property, and it holds an Osc
struct which contains its own instance of a Phasor. The Phasor has
been mostly hidden away from the top level, though we still have our
Bender for bending phase. I think we can implement methods on Osc in
order to manipulate the Phasor of a particular instance of osc if need
be.
The outer `frames` function has been partially refactored. However, I
think we should/could wrap the Osc's `next` function in something like
`next_sample` which returns a Sample (vs an Option). we could also do
something like `osc.take(frames_count).map { |s| frames.push(s) }`
Diffstat (limited to 'klangfarbrs/src/osc.rs')
-rw-r--r-- | klangfarbrs/src/osc.rs | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/klangfarbrs/src/osc.rs b/klangfarbrs/src/osc.rs index fd78de1..8225eb1 100644 --- a/klangfarbrs/src/osc.rs +++ b/klangfarbrs/src/osc.rs @@ -1,15 +1,50 @@ use std::f32::consts::TAU; use rand::Rng; -use crate::{Waveform, Phase, Sample}; +use super::{Hz, Sample}; +use super::phasor::{Phasor}; -pub struct Osc {} +/// The various waveforms the `MonoSynth` can generate. +pub enum Waveform { + Sine, + Square, + Triangle, + Sawtooth, + WhiteNoise, + BrownNoise, +} + +pub struct Osc { + pub phasor: Phasor, + pub waveform: Waveform, + pub last_value: Sample, +} impl Osc { - pub fn generate_sample(waveform: &Waveform, phase: Phase, last_value: Sample) -> Sample { - let phase = phase; + pub fn new(frequency: Hz, sample_rate: f32) -> Self { + Self { + phasor: Phasor::new(frequency, sample_rate), + waveform: Waveform::Sine, + last_value: 0.1, + } + } + + pub fn get_frequency(&self) -> Hz { + self.phasor.frequency + } + + pub fn set_frequency(&mut self, frequency: Hz) { + self.phasor.frequency = frequency; + } +} + +impl Iterator for Osc { + type Item = Sample; + + fn next(&mut self) -> Option<Self::Item> { + let phase = self.phasor.next().unwrap(); let mut rng = rand::thread_rng(); - match waveform { + let sample = match self.waveform { Waveform::Sine => { (TAU * phase).sin() }, @@ -39,9 +74,11 @@ impl Osc { }, Waveform::BrownNoise => { - (last_value + (rng.gen::<f32>()) * 0.2 - 0.1).clamp(-1.0, 1.0) + (self.last_value + (rng.gen::<f32>()) * 0.2 - 0.1).clamp(-1.0, 1.0) }, - } + }; + + Some(sample) } } |