summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--klangfarb/main.gd17
-rw-r--r--klangfarbrs/src/envelope.rs (renamed from klangfarbrs/src/adsr.rs)29
-rw-r--r--klangfarbrs/src/lib.rs32
3 files changed, 49 insertions, 29 deletions
diff --git a/klangfarb/main.gd b/klangfarb/main.gd
index 268934f..751527a 100644
--- a/klangfarb/main.gd
+++ b/klangfarb/main.gd
@@ -57,19 +57,19 @@ func _check_waveform():
func _process(_delta):
if self.is_playing():
- synth.apply_bend(apply_bend)
- synth.frequency(freq)
- synth.phasor_bend(phasor_bend)
+# synth.apply_bend(apply_bend)
+# synth.frequency(freq)
+# synth.phasor_bend(phasor_bend)
synth.frequency_modulation(frequency_modulation)
- synth.fm_frequency(fm_multiplier * freq)
+# synth.fm_frequency(fm_multiplier * freq)
synth.fm_depth(fm_index)
synth.continuous(continuous)
_check_waveform()
_fill_buffer()
func _ready() -> void:
- # buffer length of 100ms gives us ~realtime response to input changes
- self.stream.buffer_length = 0.1
+ # buffer length of 10ms gives us ~realtime response to input changes
+ self.stream.buffer_length = 0.05
# ensure Godot/Sine have the same sample rate
synth.set_sample_rate(self.stream.mix_rate)
# get our AudioStreamPlayback object
@@ -80,10 +80,13 @@ func _ready() -> void:
func _input(event):
# Mouse in viewport coordinates.
- if event is InputEventMouseButton:
+ if event is InputEventMouseButton && event.is_pressed():
print("Mouse Click/Unclick at: ", event.position)
+ synth.trigger()
elif event is InputEventMouseMotion:
freq = event.position.x
+ synth.frequency(freq)
# phasor_bend.x = event.position.x / 1024
# phasor_bend.y = event.position.y / 600
fm_multiplier = 600 / (event.position.y + 1)
+ synth.fm_frequency(fm_multiplier * freq)
diff --git a/klangfarbrs/src/adsr.rs b/klangfarbrs/src/envelope.rs
index 9d51ba3..3da7977 100644
--- a/klangfarbrs/src/adsr.rs
+++ b/klangfarbrs/src/envelope.rs
@@ -4,6 +4,7 @@ pub struct Envelope {
pub attack: Vec<Amplitude>,
pub decay: Vec<Amplitude>,
pub release: Vec<Amplitude>,
+ pub index: usize,
}
impl Envelope {
@@ -14,7 +15,7 @@ impl Envelope {
let decay = interpolate(1.0, sustain, ms_to_samples(decay, sample_rate));
let release = interpolate(sustain, 0.0, ms_to_samples(release, sample_rate));
- Self{attack, decay, release}
+ Self { attack, decay, release, index: 0 }
}
pub fn len(&self) -> usize {
@@ -22,6 +23,32 @@ impl Envelope {
}
}
+impl Iterator for Envelope {
+ type Item = Amplitude;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let idx = self.index;
+ let atk = self.attack.len();
+ let atkdcy = atk + self.decay.len();
+
+ self.index += 1;
+
+ if idx < self.len() {
+ let val = if idx < atk {
+ self.attack[idx]
+ } else if idx >= atk && idx < atkdcy {
+ self.decay[idx - atk]
+ } else {
+ self.release[idx - atkdcy]
+ };
+
+ Some(val)
+ } else {
+ None
+ }
+ }
+}
+
fn interpolate(start: Amplitude, end: Amplitude, milliseconds: Millisecond) -> Vec<Amplitude> {
let step_size = (end - start) / milliseconds as f32;
let mut amps = vec!();
diff --git a/klangfarbrs/src/lib.rs b/klangfarbrs/src/lib.rs
index 8bd1e50..fc5e6f9 100644
--- a/klangfarbrs/src/lib.rs
+++ b/klangfarbrs/src/lib.rs
@@ -17,8 +17,8 @@ mod phasor;
mod osc;
use osc::{Osc, Waveform};
-pub mod adsr;
-use adsr::Envelope;
+pub mod envelope;
+use envelope::Envelope;
/// Aliasing some types to distinguish various audio properties.
type Sample = f32;
@@ -47,7 +47,6 @@ pub struct MonoSynth {
pub fm_frequency: Hz,
pub fm_depth: Amplitude,
fm_osc: Osc,
- current_envelope_position: usize,
}
#[methods]
@@ -72,13 +71,12 @@ impl MonoSynth {
phasor_bend: Vector2::new(0.0, 0.0),
continuous: true,
duration: 0,
- envelope: Envelope::new(500, 1000, 0.5, 4000, sprt),
+ envelope: Envelope::new(30, 500, 0.5, 1000, sprt),
cutoff: 0.0,
frequency_modulation: false,
fm_frequency: 10.0,
fm_depth: 0.1,
fm_osc: Osc::new(freq * 2.0, sprt),
- current_envelope_position: 0,
}
}
@@ -167,6 +165,11 @@ impl MonoSynth {
}
#[export]
+ fn trigger(&mut self, _owner: &Node) {
+ self.envelope.index = 0;
+ }
+
+ #[export]
pub fn frames(&mut self, _owner: &Node, samples: i32) -> TypedArray<Vector2> {
let mut frames = TypedArray::new();
@@ -189,22 +192,9 @@ impl MonoSynth {
// }
if !self.continuous {
- let pos = self.current_envelope_position;
- let atk = self.envelope.attack.len();
- let atkdcy = atk + self.envelope.decay.len();
-
- if pos < atk {
- sample = sample * self.envelope.attack[pos]
- } else if pos >= atk && pos < atkdcy {
- sample = sample * self.envelope.decay[pos - atk]
- } else if pos < self.envelope.len() {
- sample = sample * self.envelope.release[pos - atkdcy]
- }
-
- self.current_envelope_position += 1;
-
- if self.current_envelope_position >= self.envelope.len() {
- self.current_envelope_position = 0;
+ sample *= match self.envelope.next() {
+ Some(a) => a,
+ None => 0.0,
}
}