#synthesizer #modular #signal #building #framework #musical

caw

A framework for building software-defined modular synthesizers

8 releases (5 breaking)

new 0.6.0 Jan 27, 2025
0.5.0 Jan 27, 2025
0.4.1 Jan 14, 2025
0.3.1 Jan 11, 2025
0.1.0 May 20, 2024

#272 in Audio

Download history 1/week @ 2024-10-09 5/week @ 2024-10-16 1/week @ 2024-11-13 369/week @ 2025-01-08 116/week @ 2025-01-15 172/week @ 2025-01-22

657 downloads per month

MIT license

310KB
8K SLoC

CAW Logo

caw

Version Documentation test dependency status

CAW is a framework for building synthesizers as Rust programs.

Here's a simple example that plays a 60Hz saw wave:

# Cargo.toml

[dependencies]
caw = { version = "0.4", features = ["interactive"] }
use caw::prelude::*;

fn main() {
    // Open a window that can play and visualize an audio signal.
    let window = Window::builder().build();

    // Describe the audio signal.
    let sig = oscillator(Saw, 60.0).build();

    // Play the audio signal, visualizing its waveform in the window.
    window.play_mono(sig, Default::default());
}

Filters can be applied to audio signals to build up more complex sounds. In this next example the mouse position within the window controls a low-pass filter cutoff and resonance.

use caw::prelude::*;

fn main() {
    // Open a window that can play and visualize an audio signal.
    let window = Window::builder().build();


    // Describe the audio signal.
    let input = window.input();
    let sig = oscillator(Saw, 60.0).build().filter(
        low_pass::default(input.mouse.x_01() * 20_000.0)
            .resonance(input.mouse.y_01()),
    );

    // Play the audio signal, visualizing its waveform in the window.
    window.play_mono(sig, Default::default()).unwrap();
}

It's possible to treat your computer keyboard as a musical keyboard in a few more lines of code.

use caw::prelude::*;

fn main() {
    // Open a window that can play and visualize an audio signal.
    let window = Window::builder().build();

    // Describe the audio signal.
    let input = window.input();
    let MonoVoice {
        note,
        key_down_gate,
        ..
    } = input.keyboard.opinionated_key_events(Note::B2).mono_voice();
    let env = adsr_linear_01(key_down_gate).attack_s(0.1).build();
    let sig = oscillator(Saw, note.freq_hz()).build().filter(
        low_pass::default(env * input.mouse.x_01() * 20_000.0)
            .resonance(input.mouse.y_01()),
    )
    .filter(chorus())
    .filter(reverb::default());

    // Play the audio signal, visualizing its waveform in the window.
    window.play_mono(sig, Default::default()).unwrap();
}

There's a bunch of effects that can be chained onto signals. Here we'll add a chorus and reverb effect.

See the examples in the caw and caw_interactive crates for more complex examples.

Dependencies

~2–33MB
~500K SLoC