Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quiver: Modular Audio Synthesis

“A quiver is a directed graph — nodes connected by arrows. In audio, our nodes are modules, our arrows are patch cables, and signal flows through their composition.”

Quiver is a Rust library for building modular audio synthesis systems. It combines the mathematical elegance of category theory with the tactile joy of patching a hardware modular synthesizer.

flowchart LR
    subgraph "Oscillator"
        VCO[🎵 VCO]
    end
    subgraph "Filter"
        VCF[📊 VCF]
    end
    subgraph "Amplifier"
        VCA[🔊 VCA]
    end
    subgraph "Envelope"
        ADSR[📈 ADSR]
    end

    VCO -->|saw| VCF
    VCF -->|lowpass| VCA
    ADSR -->|env| VCF
    ADSR -->|env| VCA
    VCA --> Output[🔈]

Why Quiver?

Type-Safe Patching

Quiver catches connection errors at compile time. Connect a gate to a V/Oct input? The type system prevents it before you hear a single pop.

Hardware-Inspired Semantics

Voltages follow real modular conventions:

  • ±5V for audio signals
  • 1V/octave for pitch (0V = C4)
  • 0-5V for gates and triggers
  • 0-10V for unipolar CV

Mathematical Foundations

Built on Arrow-style functional combinators, Quiver lets you compose DSP operations like mathematical functions:

$$f \ggg g = g \circ f$$

Chain two modules and their types compose automatically.

Three-Layer Architecture

graph TB
    subgraph "Layer 3: Patch Graph"
        G[Runtime Topology]
    end
    subgraph "Layer 2: Port System"
        P[Signal Conventions]
    end
    subgraph "Layer 1: Typed Combinators"
        C[Arrow Composition]
    end

    C --> P --> G

    style C fill:#4a9eff,color:#fff
    style P fill:#f9a826,color:#fff
    style G fill:#50c878,color:#fff
  1. Layer 1 — Compile-time type checking with zero-cost abstractions
  2. Layer 2 — Hardware-inspired signal conventions
  3. Layer 3 — Runtime-configurable patching like a real modular

Quick Taste

//! Quick Taste Example
//!
//! A minimal example showing the core Quiver workflow.
//!
//! Run with: cargo run --example quick_taste

use quiver::prelude::*;

fn main() {
    // Create a patch at CD-quality sample rate
    let mut patch = Patch::new(44100.0);

    // Add an oscillator and output
    let vco = patch.add("vco", Vco::new(44100.0));
    let output = patch.add("out", StereoOutput::new());

    // Connect the sawtooth wave to both channels
    patch.connect(vco.out("saw"), output.in_("left")).unwrap();
    patch.connect(vco.out("saw"), output.in_("right")).unwrap();

    // Compile the patch for processing
    patch.set_output(output.id());
    patch.compile().unwrap();

    // Generate one second of audio
    let mut samples = Vec::new();
    for _ in 0..44100 {
        let (left, _right) = patch.tick();
        samples.push(left);
    }

    // Report the results
    let peak = samples.iter().map(|s| s.abs()).fold(0.0_f64, f64::max);
    println!("Generated {} samples", samples.len());
    println!("Peak amplitude: {:.2}V", peak);
}

What You’ll Learn

This documentation guides you from first patch to advanced synthesis:

The Name

In category theory, a quiver is a directed graph: objects connected by morphisms. In our world:

Category TheoryQuiver Audio
ObjectsModules
Morphisms (Arrows)Patch Cables
CompositionSignal Flow
IdentityPass-through

The math isn’t just decoration—it guides the API design and ensures compositions are well-typed.


Ready to patch? Start with Installation.