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

Signal Types Cheatsheet

Quick reference for Quiver’s signal conventions.

Signal Ranges

TypeRangeZero PointUse
Audio±5V0VSound waveforms
CV Unipolar0-10V0VCutoff, rate, depth
CV Bipolar±5V0VPan, FM, bend
V/Oct±10V0V = C4Pitch
Gate0V or 5V0VSustained on/off
Trigger0V or 5V0VBrief pulse
Clock0V or 5V0VTiming pulses

SignalKind Enum

pub enum SignalKind {
    Audio,           // ±5V AC-coupled
    CvBipolar,       // ±5V control
    CvUnipolar,      // 0-10V control
    VoltPerOctave,   // 1V/Oct pitch
    Gate,            // 0V/+5V sustained
    Trigger,         // 0V/+5V pulse
    Clock,           // Timing pulses
}

Defining Ports

Ports are declared with PortDef::new(id, name, kind) plus chainable builders:

PortDef::new(0, "in", SignalKind::Audio)
PortDef::new(1, "cutoff", SignalKind::CvUnipolar)
    .with_default(5.0)       // Value when unpatched (default 0.0)
    .with_attenuverter()     // Flag an attenuverter control for UIs
PortDef::new(2, "right", SignalKind::Audio)
    .normalled_to(1)         // Falls back to port 1 when unpatched
BuilderEffect
.with_default(v)Sets the value used when no cable is connected
.with_attenuverter()Marks the input as having an attenuverter
.normalled_to(port_id)Internal fallback source when unpatched

Compatibility Quick Reference

Audio ←→ CV:      ⚠ Works but check intent
CV ←→ V/Oct:      ⚠ Usually wrong
Gate ←→ Trigger:  ✓ Compatible
Clock ←→ Trigger: ✓ Compatible
V/Oct ←→ Audio:   ✗ Usually wrong

Common Voltage Conversions

MIDI Note to V/Oct

fn midi_to_voct(note: u8) -> f64 {
    (note as f64 - 60.0) / 12.0
}

V/Oct to Frequency

fn voct_to_hz(v: f64) -> f64 {
    261.63 * 2.0_f64.powf(v)
}

MIDI CC to CV

// 0-127 → 0-10V
fn cc_to_cv(cc: u8) -> f64 {
    cc as f64 / 127.0 * 10.0
}

// 0-127 → ±5V
fn cc_to_cv_bipolar(cc: u8) -> f64 {
    (cc as f64 / 127.0 - 0.5) * 10.0
}

MIDI Velocity to CV

fn velocity_to_cv(vel: u8) -> f64 {
    vel as f64 / 127.0 * 10.0  // 0-10V
}

Pitch Bend to V/Oct

// Standard ±2 semitones
fn bend_to_voct(bend: i16) -> f64 {
    (bend as f64 / 8192.0) * (2.0 / 12.0)
}

Attenuverter Reference

ValueEffect
-2.0Invert and double
-1.0Invert
-0.5Invert and halve
0.0Silence
0.5Half level
1.0Unity (unchanged)
2.0Double

Cable Attenuation

// Scale the signal (0.0-1.0)
patch.connect_attenuated(from, to, 0.5)?;

// Full modulation controls: attenuverter (-2.0 to 2.0) + DC offset (±10V)
patch.connect_modulated(from, to, 0.5, 2.0)?;

Input Summing

Multiple cables to one input are added:

LFO1 (+2V) ─┐
            ├── Input receives +5V
LFO2 (+3V) ─┘

Normalled Connections

When input is unpatched, uses normalled source:

// Port 1 ("right") falls back to port 0 ("left") when unpatched
PortDef::new(1, "right", SignalKind::Audio).normalled_to(0)