Signal processing effects for shaping sound character.
Soft clipping distortion based on analog saturation curves.
use quiver::analog::{Saturator, saturation};
let sat = patch.add("saturator", Saturator::new(saturation::tanh_sat));
| Port | Signal | Description |
in | Audio | Input signal |
drive | Unipolar CV | Saturation amount |
| Port | Signal | Description |
out | Audio | Saturated output |
| Function | Character |
tanh_sat | Smooth, tube-like |
soft_clip | Adjustable knee |
asym_sat | Even harmonics |
diode_clip | Hard, aggressive |
Creates complex harmonics by reflecting the signal about a threshold. Supports opt-in
oversampling via set_oversample. type_id: wavefolder.
let folder = patch.add("folder", Wavefolder::new(1.0)); // threshold
| Port | Signal | Description |
in | Audio | Input signal |
threshold | Unipolar CV | Fold threshold (default = constructor value) |
| Port | Signal | Description |
out | Audio | Folded output |
Input: ╱╲
╱ ╲
╱ ╲
1 Fold: ╱╲╱╲
╱ ╲
2 Folds: ╱╲╱╲╱╲╱╲
╱ ╲
$$y = \sin(f \cdot \pi \cdot x)$$
Where $f$ is the fold amount.
Simulates channel bleed between left and right.
let crosstalk = patch.add("xtalk", Crosstalk::new());
| Port | Signal | Description |
left | Audio | Left channel |
right | Audio | Right channel |
amount | Unipolar CV | Bleed amount (0-10%) |
| Port | Signal | Description |
left | Audio | Left with right bleed |
right | Audio | Right with left bleed |
$$L_{out} = L_{in} + \text{amount} \cdot R_{in}$$
$$R_{out} = R_{in} + \text{amount} \cdot L_{in}$$
Adds subtle width and analog character.
Simulates 50/60Hz power supply hum.
let hum = patch.add("hum", GroundLoop::new(44100.0));
| Port | Signal | Description |
amount | Unipolar CV | Hum level |
| Port | Signal | Description |
out | Audio | Hum signal |
let hum = GroundLoop::new(44100.0)
.with_frequency(60.0) // 60Hz (US) or 50Hz (EU)
.with_harmonics(3); // Include 2nd and 3rd harmonics
Mix very subtly for vintage authenticity.
Real-time waveform visualization.
let scope = patch.add("scope", Scope::new(44100.0));
| Port | Signal | Description |
in | Audio | Signal to display |
trigger | Gate | Trigger sync |
| Mode | Description |
Free | Continuous display |
RisingEdge | Sync on positive zero-cross |
FallingEdge | Sync on negative zero-cross |
Single | One-shot capture |
let waveform = scope.buffer();
// Vec<f64> of recent samples
FFT-based frequency analysis.
let analyzer = patch.add("spectrum", SpectrumAnalyzer::new(44100.0));
| Port | Signal | Description |
in | Audio | Signal to analyze |
let bins = analyzer.bins(); // Frequency bins
let mags = analyzer.magnitudes(); // dB values
let peak = analyzer.peak_frequency(); // Dominant frequency
RMS and peak level monitoring.
let meter = patch.add("meter", LevelMeter::new(44100.0));
| Port | Signal | Description |
in | Audio | Signal to meter |
let rms = meter.rms(); // RMS level in volts
let peak = meter.peak(); // Peak level
let rms_db = meter.rms_db(); // RMS in dB
let meter = LevelMeter::new(44100.0)
.with_peak_hold(500.0); // 500ms hold time
Waveshaping distortion with four selectable algorithms (soft clip, hard clip, foldback,
asymmetric), a one-pole tone control, dry/wet mix, and opt-in oversampling
(set_oversample). type_id: distortion.
let dist = patch.add("dist", Distortion::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
drive | Unipolar CV | 0-10V | Drive into the shaper, default 0.5 |
tone | Unipolar CV | 0-10V | Tone (one-pole lowpass), default 0.5 |
mode | Unipolar CV | 0-10V | Algorithm select (4 modes) |
mix | Unipolar CV | 0-10V | Dry/wet, default fully wet |
| Port | Signal | Description |
out | Audio | Distorted output |
Lo-fi bit-depth and sample-rate reduction. type_id: bitcrusher.
let crush = patch.add("crush", Bitcrusher::new());
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
bits | Unipolar CV | 0-10V | Bit-depth reduction (~1–16 bits), default 0.5 |
downsample | Unipolar CV | 0-10V | Sample-rate reduction |
| Port | Signal | Description |
out | Audio | Crushed output |
Delay of up to 2 seconds with feedback and wet/dry mix; slew-smoothed delay time for
CV-modulated effects. Breaks feedback cycles. type_id: delay_line.
let delay = patch.add("delay", DelayLine::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
time | Unipolar CV | 0-10V | Delay time (1 ms–2 s, exponential), default 0.5 |
feedback | Unipolar CV | 0-10V | Feedback (0–0.99) |
mix | Unipolar CV | 0-10V | Dry/wet, default 0.5 |
| Port | Signal | Description |
out | Audio | Mixed dry + delayed output |
Three-voice modulated-delay chorus with a mono and a stereo-spread output. type_id: chorus.
let chorus = patch.add("chorus", Chorus::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
rate | Unipolar CV | 0-10V | LFO rate (0.1–5 Hz), default 0.3 |
depth | Unipolar CV | 0-10V | Modulation depth (0–25 ms), default 0.5 |
mix | Unipolar CV | 0-10V | Dry/wet, default 0.5 |
| Port | Signal | Description |
out | Audio | Mono mixed output |
left | Audio | Left stereo-spread output |
right | Audio | Right stereo-spread output |
Short-modulated-delay flanger with feedback; mono in, stereo out via a spread control.
out mirrors left for backward compatibility. type_id: flanger.
let flanger = patch.add("flanger", Flanger::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
rate | Unipolar CV | 0-10V | LFO rate, default 0.3 |
depth | Unipolar CV | 0-10V | Sweep depth, default 0.5 |
feedback | Bipolar CV | ±5V | Feedback (−0.95–0.95) |
mix | Unipolar CV | 0-10V | Dry/wet, default 0.5 |
spread | Unipolar CV | 0-10V | Stereo L/R decorrelation (0 = mono, 1 = 180°), default 0.5 |
| Port | Signal | Description |
out | Audio | Legacy mono output (mirrors left) |
left | Audio | Left channel |
right | Audio | Right channel (phase-offset sweep) |
Cascaded-allpass phaser (2/4/6 selectable stages) with feedback; mono in, stereo out with
a spread control. out mirrors left. type_id: phaser.
let phaser = patch.add("phaser", Phaser::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
rate | Unipolar CV | 0-10V | LFO rate, default 0.3 |
depth | Unipolar CV | 0-10V | Notch sweep depth, default 0.7 |
feedback | Bipolar CV | ±5V | Feedback (−0.95–0.95) |
mix | Unipolar CV | 0-10V | Dry/wet, default 0.5 |
stages | Unipolar CV | 0-10V | Allpass stage count (<0.33 → 2, <0.66 → 4, else 6) |
spread | Unipolar CV | 0-10V | Stereo L/R decorrelation, default 0.5 |
| Port | Signal | Description |
out | Audio | Legacy mono output (mirrors left) |
left | Audio | Left channel |
right | Audio | Right channel (phase-offset notch sweep) |
Amplitude-modulation tremolo with a sine-to-triangle shape blend. type_id: tremolo.
let trem = patch.add("trem", Tremolo::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
rate | Unipolar CV | 0-10V | LFO rate (0.1–20 Hz), default 0.3 |
depth | Unipolar CV | 0-10V | Modulation depth, default 0.5 |
shape | Unipolar CV | 0-10V | LFO shape blend (sine ↔ triangle) |
| Port | Signal | Description |
out | Audio | Amplitude-modulated output |
Pitch-modulation vibrato via a modulated delay line; defaults fully wet. type_id: vibrato.
let vib = patch.add("vib", Vibrato::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
rate | Unipolar CV | 0-10V | LFO rate (0.1–15 Hz), default 0.3 |
depth | Unipolar CV | 0-10V | Pitch-modulation depth, default 0.5 |
mix | Unipolar CV | 0-10V | Dry/wet, default fully wet |
| Port | Signal | Description |
out | Audio | Pitch-modulated output |
Freeverb-style algorithmic reverb (8 comb + 4 allpass) with size, damping, mix, and
pre-delay. Stereo output. type_id: reverb.
let reverb = patch.add("reverb", Reverb::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
size | Unipolar CV | 0-10V | Room size / decay, default 0.5 |
damping | Unipolar CV | 0-10V | High-frequency damping, default 0.5 |
mix | Unipolar CV | 0-10V | Dry/wet, default 0.5 |
predelay | Unipolar CV | 0-10V | Pre-delay (0–100 ms) |
| Port | Signal | Description |
left | Audio | Left reverb channel |
right | Audio | Right reverb channel |
Granular (two-grain, crossfaded) real-time pitch shifter. type_id: pitch_shifter.
let shift = patch.add("shift", PitchShifter::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio input |
shift | Bipolar CV | ±5V | Pitch shift (±24 semitones) |
window | Unipolar CV | 0-10V | Grain window (10–100 ms), default 0.5 |
mix | Unipolar CV | 0-10V | Dry/wet, default fully wet |
| Port | Signal | Description |
out | Audio | Pitch-shifted output |
Granular processor: records the input into a circular buffer and plays overlapping
Hann-windowed grains. type_id: granular.
let gran = patch.add("gran", Granular::new(44100.0));
| Port | Signal | Range | Description |
in | Audio | ±5V | Audio recorded into the buffer |
position | Unipolar CV | 0-10V | Playback position, default 0.5 |
size | Unipolar CV | 0-10V | Grain size (10–500 ms), default 0.3 |
density | Unipolar CV | 0-10V | Grains per second (1–20), default 0.5 |
pitch | Bipolar CV | ±5V | Pitch shift (±24 semitones) |
spray | Unipolar CV | 0-10V | Position randomization, default 0.1 |
freeze | Gate | 0/5V | Stops recording while high |
| Port | Signal | Description |
out | Audio | Granular output |
Channel vocoder: per-band envelope followers on the modulator impose its spectral
envelope onto the carrier. type_id: vocoder.
let voc = patch.add("voc", Vocoder::new(44100.0));
| Port | Signal | Range | Description |
carrier | Audio | ±5V | Carrier (typically an oscillator) |
modulator | Audio | ±5V | Modulator (typically voice) |
bands | Unipolar CV | 0-10V | Band count (4–16), default 1.0 |
attack | Unipolar CV | 0-10V | Envelope-follower attack, default 0.3 |
release | Unipolar CV | 0-10V | Envelope-follower release, default 0.3 |
| Port | Signal | Description |
out | Audio | Vocoded output |
// Input → Saturator → Filter → Output
patch.connect(input, sat.in_("in"))?;
patch.connect(sat.out("out"), vcf.in_("in"))?;
patch.connect(vcf.out("lp"), output)?;
// Dry/wet mix
patch.connect(input, mult.in_("in"))?;
patch.connect(mult.out("out_1"), effect.in_("in"))?; // Wet
patch.connect(mult.out("out_2"), xfade.in_("a"))?; // Dry
patch.connect(effect.out("out"), xfade.in_("b"))?; // Wet
// With unit delay to prevent infinite loop
patch.connect(effect.out("out"), delay.in_("in"))?;
patch.connect(delay.out("out"), atten.in_("in"))?; // Feedback amount
patch.connect(atten.out("out"), effect.in_("in"))?;