summaryrefslogtreecommitdiff
path: root/klangfarbrs
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 /klangfarbrs
parenta8fd8a74ec114fbde563bca62180a160c3cb8a88 (diff)
Bending it like Beckham
Diffstat (limited to 'klangfarbrs')
-rw-r--r--klangfarbrs/src/lib.rs25
1 files changed, 22 insertions, 3 deletions
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