A Rust auto-vocoder: pitch-detects the input voice, quantizes it to a scale, synthesizes a carrier (single note, triad, or fixed "Soundwave" pitch), and drives a classic 16-band channel vocoder. Ships as:
- An LV2 plugin with 25 named presets (Ardour on Linux)
- A standalone CLI for offline WAV rendering and live audio (Mac / Linux)
- A WASM build for running in a webpage via AudioWorklet
- A shell wrapper for routing a robot voice into Teams/Zoom/Discord on Mac
Intergalactic-style robot voice, live on Mac, into any meeting app:
./scripts/robot-voice.sh intergalacticVocode a WAV file:
autovocoder render --input vocal.wav --output robot.wav --mode fixed --fixed-note 48In Ardour (AVLinux or any Linux distro): Mixer → insert → Autovocoder →
right-click → pick a preset.
One-shot installer — builds and drops the bundle into ~/.lv2/:
./scripts/install-lv2.shRequires Rust (rustup install stable). After install,
Ardour / Carla / any LV2 host will see Autovocoder after a plugin rescan.
# render-only (no audio deps)
cargo build --release -p autovocoder-standalone
# with live mic → speakers support
cargo build --release -p autovocoder-standalone --features liveOn Linux, --features live needs libasound2-dev for ALSA.
./target/release/autovocoder render \
--input in.wav --output out.wav \
--mode fixed --fixed-note 48 # Soundwave, C3All modes: mono (track the singer's pitch), major-triad, minor-triad,
fixed. Scale snapping: --scale major --scale-root 0 etc.
Full flag list: ./target/release/autovocoder render --help.
./target/release/autovocoder live --mode fixed --fixed-note 48Use headphones — live output into the same mic creates feedback loops fast.
One-time setup:
brew install blackhole-2ch— virtual audio device. Reboot after, or:sudo killall coreaudiod.- In Audio MIDI Setup, create a Multi-Output Device with both BlackHole and your headphones checked — lets you monitor yourself.
- In Teams / Zoom / Discord, set Microphone →
BlackHole 2ch.
Per-call:
./scripts/robot-voice.sh intergalactic
# or: ./scripts/robot-voice.sh soundwave-c2
# or: ./scripts/robot-voice.sh --list # see all presetsCtrl-C to restore your normal voice.
The LV2 plugin and the robot-voice.sh script share a curated preset set:
| Preset | Flavor |
|---|---|
soundwave-c2 |
Deep Decepticon. Fixed C2, fully wet. |
soundwave-c3 |
Neutral Soundwave register. Fixed C3. |
soundwave-g2 |
Slightly higher Soundwave — more intelligible. |
intergalactic |
Beastie Boys refrain vibe — fixed A2, bright buzzy carrier. |
chromatic-robot |
Tracks pitch chromatically with a snappy glide. |
heavy-glide |
Same as chromatic-robot but with long portamento (dub-style). |
in-key-c-major |
Autotune-to-C-major. Wrong notes become right notes. |
in-key-a-minor |
Autotune-to-A-minor. Melodic, natural. |
dark-choir |
Minor triad per detected note. Eerie pad effect. |
bright-angels |
Major triad per detected note. Auto-Tune-on-steroids heaven. |
subtle-support |
30% wet — layer under a real vocal for harmonic reinforcement. |
The LV2 plugin also bundles a set of effect-showcase presets that exercise the chorus / tremolo modules (LV2-only — the standalone CLI doesn't expose those parameters yet):
| Preset | Flavor |
|---|---|
soundwave-stutter |
Soundwave C2 + 8 Hz square chop. Mechanical staccato villain. |
liquid-carrier |
Mono pitch tracking + deep chorus on the carrier. Watery timbre. |
wormhole |
Fixed dim7 with both choruses deep + slow. Disorienting wash. |
helicopter |
14 Hz hard-square tremolo over chromatic mono. Rotor blades. |
trance-gate-c |
Major-scale auto-tune + 6 Hz EDM gate + subtle output chorus. |
synthwave-pad |
Sus2 fixed chord + lush slow output chorus. '80s pad. |
megatron |
Low dom7 + slow square chop + carrier chorus. Heavier than Soundwave. |
robotic-telegraph |
Fixed A2 + 10 Hz square chop. Speech as Morse code. |
tron-cycle |
Low power chord + deep carrier chorus + slow sine tremolo. |
vintage-choir-wash |
Major triad per note + subtle slow chorus. Mellotron-ish. |
glitch-bot |
Augmented chord + 3.5 Hz hard chop + animated chorus. Rhythmic weird. |
cyberbird |
Mono + fast carrier chorus + subtle sine tremolo. Inhuman creature. |
Cargo workspace, one DSP core + three frontends:
crates/
├── autovocoder-dsp/ # host-agnostic DSP: osc, filter, pitch (YIN),
│ # scale, 16-band vocoder, top-level processor
├── autovocoder-lv2/ # LV2 plugin wrapper (hand-rolled C FFI)
│ └── lv2/*.ttl # plugin manifest + presets
├── autovocoder-standalone/ # CLI: render + live (cpal) subcommands
└── autovocoder-wasm/ # wasm-bindgen bindings for browser use
Signal chain in one glance:
voice ──► YIN pitch detect ──► scale quantize ──► portamento ──► saw carrier(s)
│
voice ──► analysis filterbank ──► envelope followers ──► × carrier bands ─┴─► out
just check # fmt + clippy + tests
just test # run tests only
just render ... # run the CLI render subcommand
just lv2-bundle # build the LV2 bundle under target/lv2/
just lv2-install # build + copy to ~/.lv2/
just wasm # build the WASM package (needs wasm-pack)Or without just, any cargo command works — e.g. cargo test --workspace --exclude autovocoder-wasm.
The default release profile builds a portable x86-64 binary — safe but
leaves SIMD on the table. For a small (~2 vCPU) Linux box, build with
the AVX2/FMA baseline:
just release-cloud # RUSTFLAGS="-C target-cpu=x86-64-v3" cargo build --releaseThen pick the cheapest pitch detector your material tolerates — the plugin exposes three:
- YIN (FFT) — default, recommended. Same accuracy as classic YIN, ~30× cheaper for our window size.
- YIN (classic) — pure time-domain, no FFT. Use only if FFT init cost matters (very rare).
- FFT (HPS) — cheapest per-estimate. Best on sustained, harmonic voices; less robust on breathy / noisy material.
MIT OR Apache-2.0 — pick whichever you prefer.