Skip to content

Commit

Permalink
Add bezier curve oscillator
Browse files Browse the repository at this point in the history
  • Loading branch information
AldaronLau committed May 5, 2024
1 parent 2691f59 commit 0607d43
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
19 changes: 19 additions & 0 deletions examples/bezier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use fon::{chan::Ch16, Audio};
use twang::tree::{line::Line, Synth};

mod wav;
//mod plot;

fn main() {
// Define waveform
let waveform = const { Line(440.0).osc().bezier(Line(1.0)) };
// Initialize audio, and create synthesizer
let mut audio = Audio::<Ch16, 2>::with_silence(48_000, 48_000 * 5);
let mut synth = Synth::new(waveform);

// Synthesize 5 seconds of audio
synth.stream(audio.sink(), &[]);
// Plot synthesized audio, and write to a WAV file
//plot::write(&audio);
wav::write(audio, "bezier.wav").expect("Failed to write WAV file");
}
14 changes: 14 additions & 0 deletions src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@

macro_rules! const_postfix_waveform {
() => {
/// Postfix helper for wrapping synth instruction with [`osc::Bezier`].
///
/// [`osc::Bezier`]: crate::tree::osc::Bezier
pub const fn bezier<J>(
self,
curve: J,
) -> crate::tree::osc::Bezier<Self, J>

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-unknown-redox)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-unknown-redox)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-freebsd)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-freebsd)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile-ios (macos-latest, 1.70.0, aarch64-apple-ios)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile-ios (macos-latest, 1.70.0, aarch64-apple-ios)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-linux-gnu)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-linux-gnu)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, wasm32-unknown-unknown)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, wasm32-unknown-unknown)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-apple-darwin)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-apple-darwin)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, aarch64-linux-android)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, aarch64-linux-android)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-pc-windows-gnu)

unnecessary qualification

Check warning on line 61 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-pc-windows-gnu)

unnecessary qualification
where
J: crate::tree::Wave
{
crate::tree::osc::Bezier(self, curve)

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-unknown-redox)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-unknown-redox)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-freebsd)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-freebsd)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile-ios (macos-latest, 1.70.0, aarch64-apple-ios)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile-ios (macos-latest, 1.70.0, aarch64-apple-ios)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-linux-gnu)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-unknown-linux-gnu)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, wasm32-unknown-unknown)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, wasm32-unknown-unknown)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-apple-darwin)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, x86_64-apple-darwin)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, aarch64-linux-android)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, aarch64-linux-android)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-pc-windows-gnu)

unnecessary qualification

Check warning on line 65 in src/tree/mod.rs

View workflow job for this annotation

GitHub Actions / cross-compile (ubuntu-latest, 1.70.0, i686-pc-windows-gnu)

unnecessary qualification
}

/// Postfix helper for wrapping synth instruction with [`osc::Osc`].
///
/// [`osc::Osc`]: crate::tree::osc::Osc
Expand Down Expand Up @@ -91,6 +104,7 @@ pub use self::synth::Synth;
line::Line,
line::Param,
for<T: Wave> &T,
for<T: Wave, U: Wave> osc::Bezier<T, U>,
for<T: Wave> osc::Osc<T>,
for<T: Wave> osc::Sine<T>,
)]
Expand Down
29 changes: 29 additions & 0 deletions src/tree/osc/bezier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::tree::{Chunk, Wave};

/// Bezier wave
///
/// Takes phase (-1 to 1) and curve (-1 to 1) as input
#[derive(Debug)]
pub struct Bezier<I, J>(pub I, pub J);

impl<I, J> Wave for Bezier<I, J>
where
I: Wave,
J: Wave,
{
fn synthesize(&self, elapsed: u64, interval: u64, vars: &[f32]) -> Chunk {
let mut chunk = self.0.synthesize(elapsed, interval, vars);
let curve = self.1.synthesize(elapsed, interval, vars);

for (src, curve) in chunk.0.iter_mut().zip(curve.0.iter()) {
let sign = src.signum();
let mut output = -src.abs();

output += 1.0;
output = output + output * curve * (output - 1.0) - 1.0;
*src = output.copysign(sign);
}

chunk
}
}
4 changes: 3 additions & 1 deletion src/tree/osc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

#![allow(clippy::module_inception)]

const_postfix_waveform!(Bezier<T, U>, T, U);
const_postfix_waveform!(Osc<T>, T);
const_postfix_waveform!(Sine<T>, T);

mod bezier;
mod osc;
mod sine;

pub use self::{osc::Osc, sine::Sine};
pub use self::{bezier::Bezier, osc::Osc, sine::Sine};

0 comments on commit 0607d43

Please sign in to comment.