summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Lee <jacob@unabridgedsoftware.com>2021-11-11 13:05:20 -0500
committerJacob Lee <jacob@unabridgedsoftware.com>2021-11-11 13:05:20 -0500
commita78f43d5a79e0bbe0d41d60b3527da3cfec7f117 (patch)
treeefb1610b2bb7606f41729add2f9d01c0e3894a4f
parenta17829f5412ee0757574b34e34ce78b2975df1fe (diff)
Implement White/Brown noise. Refactor needed
-rw-r--r--klangfarb/Main.tscn2
-rw-r--r--klangfarb/main.gd6
-rw-r--r--klangfarbrs/Cargo.lock47
-rw-r--r--klangfarbrs/Cargo.toml1
-rw-r--r--klangfarbrs/src/lib.rs23
-rw-r--r--klangfarbrs/src/osc.rs14
6 files changed, 87 insertions, 6 deletions
diff --git a/klangfarb/Main.tscn b/klangfarb/Main.tscn
index e7a1b90..0c2f046 100644
--- a/klangfarb/Main.tscn
+++ b/klangfarb/Main.tscn
@@ -8,3 +8,5 @@
stream = SubResource( 1 )
volume_db = -13.216
script = ExtResource( 2 )
+frequency_modulation = true
+fm_index = 100.0
diff --git a/klangfarb/main.gd b/klangfarb/main.gd
index c1cb6e8..268934f 100644
--- a/klangfarb/main.gd
+++ b/klangfarb/main.gd
@@ -1,7 +1,7 @@
extends AudioStreamPlayer
# control wave form
-export(String, "sine", "square", "triangle", "sawtooth") var waveform = "sine"
+export(String, "sine", "square", "triangle", "sawtooth", "white_noise", "brown_noise") var waveform = "sine"
# controllable frequency interface
export(float, 20, 8000, 5) var freq = 440.0
# bending the waveform
@@ -50,6 +50,10 @@ func _check_waveform():
synth.triangle()
elif waveform == "sawtooth":
synth.sawtooth()
+ elif waveform == "white_noise":
+ synth.white_noise()
+ elif waveform == "brown_noise":
+ synth.brown_noise()
func _process(_delta):
if self.is_playing():
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]]
@@ -366,6 +367,12 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -384,6 +391,46 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
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,
}
@@ -147,6 +151,16 @@ impl MonoSynth {
}
#[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<Vector2> {
let mut frames = TypedArray::new();
+ let mut rng = rand::thread_rng();
+ let mut last_value = (rng.gen::<f32>() * 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::<f32>()).sin()
+ },
+
+ Waveform::BrownNoise => {
+ (last_value + (rng.gen::<f32>()) * 0.2 - 0.1).clamp(-1.0, 1.0)
+ },
}
}
}