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/Cargo.lock | 47 +++++++++++++++++++++++++++++++++++++++++++++++ klangfarbrs/Cargo.toml | 1 + klangfarbrs/src/lib.rs | 23 ++++++++++++++++++++--- klangfarbrs/src/osc.rs | 14 ++++++++++++-- 4 files changed, 80 insertions(+), 5 deletions(-) (limited to 'klangfarbrs') diff --git a/klangfarbrs/Cargo.lock b/klangfarbrs/Cargo.lock index f784589..f642fb8 100644 --- a/klangfarbrs/Cargo.lock +++ b/klangfarbrs/Cargo.lock @@ -242,6 +242,7 @@ name = "klangfarbrs" version = "0.1.0" dependencies = [ "gdnative", + "rand", ] [[package]] @@ -365,6 +366,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "ppv-lite86" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" + [[package]] name = "proc-macro2" version = "1.0.30" @@ -383,6 +390,46 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.2.10" diff --git a/klangfarbrs/Cargo.toml b/klangfarbrs/Cargo.toml index c896efa..798f475 100644 --- a/klangfarbrs/Cargo.toml +++ b/klangfarbrs/Cargo.toml @@ -11,3 +11,4 @@ name = "klangfarbrs" [dependencies] gdnative = "0.9" +rand = "0.8.4" 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