summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Lee <jacob@unabridgedsoftware.com>2021-11-02 23:03:05 -0400
committerJacob Lee <jacob@unabridgedsoftware.com>2021-11-02 23:03:05 -0400
commitb75bdf9ddcf2d6fc40782d519dfefad2a0654c25 (patch)
treeecd79fd5bc78c0e45dfd7a256005b4e517276419
parenta8fd8a74ec114fbde563bca62180a160c3cb8a88 (diff)
Bending it like Beckham
-rw-r--r--klangfarb/Main.tscn3
-rwxr-xr-xklangfarb/libklangfarbrs.sobin20146368 -> 20305280 bytes
-rw-r--r--klangfarb/main.gd3
-rw-r--r--klangfarbrs/src/lib.rs25
4 files changed, 26 insertions, 5 deletions
diff --git a/klangfarb/Main.tscn b/klangfarb/Main.tscn
index 95d51f7..896aa8c 100644
--- a/klangfarb/Main.tscn
+++ b/klangfarb/Main.tscn
@@ -6,5 +6,6 @@
[node name="Audio" type="AudioStreamPlayer"]
stream = SubResource( 1 )
-volume_db = -7.38
+volume_db = -13.216
script = ExtResource( 2 )
+freq = 130.0
diff --git a/klangfarb/libklangfarbrs.so b/klangfarb/libklangfarbrs.so
index 9070316..ee0ba0e 100755
--- a/klangfarb/libklangfarbrs.so
+++ b/klangfarb/libklangfarbrs.so
Binary files differ
diff --git a/klangfarb/main.gd b/klangfarb/main.gd
index cf3d8c1..439bb50 100644
--- a/klangfarb/main.gd
+++ b/klangfarb/main.gd
@@ -2,6 +2,7 @@ extends AudioStreamPlayer
# controllable frequency interface
export(float, 20, 8000, 5) var freq = 440.0
+export(float, 0, 1, 0.1) var bend = 0.5
# control wave form
export(String, "sine", "square", "triangle", "sawtooth") var waveform = "sine"
@@ -21,7 +22,7 @@ func _fill_buffer() -> void:
# ask Rust to generate N frames at freq
# Array<Vector2> gets pushed to the
# playback stream buffer
- playback.push_buffer(wave.frames(freq, to_fill))
+ playback.push_buffer(wave.frames(freq, to_fill, bend))
func _check_waveform():
if waveform == "square":
diff --git a/klangfarbrs/src/lib.rs b/klangfarbrs/src/lib.rs
index 8fb773d..9ba44d9 100644
--- a/klangfarbrs/src/lib.rs
+++ b/klangfarbrs/src/lib.rs
@@ -66,10 +66,28 @@ fn generate_sample(osc: &Osc) -> f32 {
/// for a given wave form. Since audio signals are periodic, we can just calculate
/// the first cycle of a wave repeatedly. This also prevents pitch drift caused by
/// floating point errors over time.
-fn calculate_phase(osc: &Osc, frequency: f32) -> f32 {
+fn next_phase(osc: &Osc, frequency: f32) -> f32 {
(osc.phase + (frequency / osc.sample_rate)) % 1.0
}
+// for (i = 0; i < nframes; ++i) {
+// if (in[i] < x0)
+// out[i] = (y0/x0)*in[i];
+// else
+// out[i] = ((1-y0)/(1-x0)) * (in[i] - x0) + y0;
+// }
+fn bend_phase(osc: &Osc, frequency: f32, bend_factor: f32) -> f32 {
+ let current_phase = osc.phase;
+ let next_phase = next_phase(osc, frequency);
+ let step = next_phase - current_phase;
+
+ if osc.phase < bend_factor {
+ step * 2.0
+ } else {
+ step / 2.0
+ }
+}
+
/// # Examples
///
/// It is more work than benefit to figure out how to instantiate a Godot object (Node)
@@ -126,13 +144,14 @@ impl Osc {
}
#[export]
- pub fn frames(&mut self, _owner: &Node, frequency: f32, duration: i32) -> TypedArray<Vector2> {
+ pub fn frames(&mut self, _owner: &Node, frequency: f32, duration: i32, bend_factor: f32) -> TypedArray<Vector2> {
let mut frames = TypedArray::new();
for _i in 0..duration {
let sample = generate_sample(&self);
frames.push(Vector2::new(sample, sample));
- self.phase = calculate_phase(&self, frequency);
+ // self.phase = next_phase(&self, frequency);
+ self.phase = self.phase + bend_phase(&self, frequency, bend_factor)
}
return frames