#caw #bevy #toml #synthesizer

caw_bevy

Helpers for controlling a caw syntesizer from bevy

3 unstable releases

new 0.2.0 Mar 30, 2025
0.1.1 Feb 22, 2025
0.1.0 Feb 22, 2025

#406 in Game dev

Download history 156/week @ 2025-02-16 115/week @ 2025-02-23 56/week @ 2025-03-02 9/week @ 2025-03-09 3/week @ 2025-03-16

339 downloads per month

MIT license

61KB
1.5K SLoC

CAW Logo

Combinatorial Audia Workspace (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

~25–36MB
~612K SLoC