From a78f43d5a79e0bbe0d41d60b3527da3cfec7f117 Mon Sep 17 00:00:00 2001 From: Jacob Lee Date: Thu, 11 Nov 2021 13:05:20 -0500 Subject: Implement White/Brown noise. Refactor needed --- klangfarbrs/src/lib.rs | 23 ++++++++++++++++++++--- klangfarbrs/src/osc.rs | 14 ++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) (limited to 'klangfarbrs/src') diff --git a/klangfarbrs/src/lib.rs b/klangfarbrs/src/lib.rs index ef9417c..1fdc0fb 100644 --- a/klangfarbrs/src/lib.rs +++ b/klangfarbrs/src/lib.rs @@ -11,6 +11,8 @@ use gdnative::prelude::*; use gdnative::core_types::TypedArray; +use rand::Rng; +use std::f32::consts::TAU; mod osc; use osc::Osc; @@ -32,7 +34,8 @@ pub enum Waveform { Square, Triangle, Sawtooth, - // Noise, + WhiteNoise, + BrownNoise, } #[derive(NativeClass)] @@ -116,6 +119,7 @@ impl MonoSynth { frequency_modulation: false, fm_frequency: 10.0, fm_depth: 0.1, + // Noise, fm_phasor: Phasor { phase: 0.0 }, current_envelope_position: 0, } @@ -146,6 +150,16 @@ impl MonoSynth { self.waveform = Waveform::Sawtooth } + #[export] + fn white_noise(&mut self, _owner: &Node) { + self.waveform = Waveform::WhiteNoise + } + + #[export] + fn brown_noise(&mut self, _owner: &Node) { + self.waveform = Waveform::BrownNoise + } + #[export] fn frequency(&mut self, _owner: &Node, frequency: Hz) { self.frequency = frequency @@ -197,13 +211,16 @@ impl MonoSynth { #[export] pub fn frames(&mut self, _owner: &Node, samples: i32) -> TypedArray { let mut frames = TypedArray::new(); + let mut rng = rand::thread_rng(); + let mut last_value = (rng.gen::() * TAU).sin(); for _i in 0..samples { - let mut sample = Osc::generate_sample(&self.waveform, self.phasor.phase); + let mut sample = Osc::generate_sample(&self.waveform, self.phasor.phase, last_value); + last_value = sample; let next_phase : f32; if self.frequency_modulation { - let modulation_value = Osc::generate_sample(&Waveform::Sine, self.fm_phasor.phase) * self.fm_depth; + let modulation_value = Osc::generate_sample(&Waveform::Sine, self.fm_phasor.phase, last_value) * self.fm_depth; self.fm_phasor.phase = self.fm_phasor.next_phase(self.fm_frequency, self.sample_rate); next_phase = self.phasor.next_phase(self.frequency + modulation_value, self.sample_rate); } else { diff --git a/klangfarbrs/src/osc.rs b/klangfarbrs/src/osc.rs index 9e3b147..fd78de1 100644 --- a/klangfarbrs/src/osc.rs +++ b/klangfarbrs/src/osc.rs @@ -1,11 +1,13 @@ use std::f32::consts::TAU; +use rand::Rng; use crate::{Waveform, Phase, Sample}; pub struct Osc {} impl Osc { - pub fn generate_sample(waveform: &Waveform, phase: Phase) -> Sample { + pub fn generate_sample(waveform: &Waveform, phase: Phase, last_value: Sample) -> Sample { let phase = phase; + let mut rng = rand::thread_rng(); match waveform { Waveform::Sine => { @@ -30,7 +32,15 @@ impl Osc { Waveform::Sawtooth => { 2.0 * phase - 1.0 - } + }, + + Waveform::WhiteNoise => { + (rng.gen::()).sin() + }, + + Waveform::BrownNoise => { + (last_value + (rng.gen::()) * 0.2 - 0.1).clamp(-1.0, 1.0) + }, } } } -- cgit v1.2.3