vizzzz #
The most featureful termiminal audio visualizer I'm aware of.
vizzzz is a responsive terminal spectrum visualizer written in Rust with
ratatui.
On macOS and Windows, the default source is the main system output through
ScreenCaptureKit or WASAPI loopback. On other platforms, and with
--source input, it captures a microphone, audio interface, monitor source, or
virtual loopback device through CPAL.
Run #
cargo run --release
The native GPU frontend opens by default. To draw in the terminal instead:
cargo run --release -- --frontend terminal
The window frontend uses Metal on macOS and Vulkan or OpenGL under Wayland on
Linux. It is a native winit + wgpu application and does not embed a browser.
The first macOS system-output launch may ask for Screen & System Audio Recording access. Grant access to the terminal under System Settings > Privacy & Security > Screen & System Audio Recording, restart the terminal, and launch again.
Install with Nix #
Linux is distributed through the flake:
nix run .
nix profile install .#vizzzz
The installed package also provides a desktop entry that starts the native GPU frontend.
Release artifacts #
Tangled CI runs formatting, lint, tests, and a release build for pushes and
pull requests to master. Pushing an annotated v* tag builds and publishes
an x86-64 Windows executable using cargo-xwin:
git tag -a v0.1.0 -m "vizzzz 0.1.0"
git push origin v0.1.0
Artifact publishing requires an AT Protocol app password for the repository
owner, stored as the ATP_APP_PASSWORD repository secret. Tangled's current
Nixery and microVM engines are Linux-only, while this project's macOS capture
backend requires Xcode, Swift, and Apple's SDK. A macOS host can produce the
corresponding ad-hoc-signed .app.zip with:
scripts/package-macos-app.sh
See BUILDING.md for complete bundle, signing, and notarization instructions.
Notarized public macOS releases additionally require an Apple Developer signing identity and notarization credentials.
Use an input source instead:
cargo run --release -- --list-devices
cargo run --release -- --source input --device "Wave:3"
Verify capture without opening the TUI:
cargo run --release -- --check 3
cargo run --release -- --source input --check 3
Shell completions #
vizzzz generates completion scripts directly from its clap command definition,
so the scripts always include the current options and value enums. Supported
shells are Bash, Elvish, Fish, PowerShell, and Zsh:
vizzzz --generate-completion SHELL
Install completion for Bash:
mkdir -p ~/.local/share/bash-completion/completions
vizzzz --generate-completion bash \
> ~/.local/share/bash-completion/completions/vizzzz
Install completion for Zsh:
mkdir -p ~/.zfunc
vizzzz --generate-completion zsh > ~/.zfunc/_vizzzz
Then ensure these lines are present in ~/.zshrc:
fpath=(~/.zfunc $fpath)
autoload -Uz compinit && compinit
Install completion for Fish:
mkdir -p ~/.config/fish/completions
vizzzz --generate-completion fish > ~/.config/fish/completions/vizzzz.fish
The generator writes only the completion script to standard output and exits
before opening an audio device. When running from the repository, replace
vizzzz above with cargo run --release --.
Profiles #
Named profiles are INI sections whose keys match long command-line options:
[roots-low-latency]
display = bars
bar-style = peak-only
theme = mono-dark
fft-size = 2048
fps = 120
attack = 5
trails = 0
minimal = true
default and nice-vocals are included in the binary. default is the current
sane command-line defaults. nice-vocals is a focused 25-1200 Hz Mel/RMS bars
preset with adaptive gain and vocal-oriented shelf filtering:
vizzzz --profile nice-vocals
The default profile file is selected in this order:
$VIZZZZ_PROFILES$XDG_CONFIG_HOME/vizzzz/profiles.ini$HOME/.config/vizzzz/profiles.iniprofiles.iniwhen no home directory is available
Load a profile or list those available:
vizzzz --profile roots-low-latency
vizzzz --list-profiles
vizzzz --profile-file ./profiles.ini --profile roots-low-latency
Explicit command-line options take precedence because they are applied after the profile. For example, this loads the profile but uses a 60 FPS redraw rate:
vizzzz --profile roots-low-latency --fps 60
Underscores in profile keys are accepted as aliases for hyphens. Boolean flags
such as minimal and peaks accept true, false, yes, no, on, off,
1, or 0. See profiles.ini.example for complete presets.
Press r while either the terminal or desktop frontend is running to cycle
through included and user-defined profiles. Analyzer state is rebuilt when the
profile changes; capture source, selected device, and frontend stay unchanged.
Response shaping #
The defaults combine techniques used by motion-graphics and metering tools:
- A Hann-windowed FFT reduces spectral leakage.
- Selectable linear, logarithmic, constant-Q-style, Mel, and Bark bands cover motion-graphics, musical, and psychoacoustic layouts.
- Independent exponential attack and release envelopes are stable at any FPS.
- Neighbor-band spatial smoothing prevents isolated, twitchy columns.
- Peak hold and controlled dB-per-second decay retain transients.
- Frequency tilt compensates for the natural high-frequency falloff in music.
All of these are configurable. For example:
cargo run --release -- \
--bands 64 --fft-size 8192 --min-freq 20 --max-freq 2000 \
--frequency-scale linear --detector peak --contrast 1.65 \
--attack 30 --release 180 --spatial-smoothing 0.08 \
--peak-hold 550 --peak-decay 18 --tilt 3.0 \
--compressor-threshold -18 --compressor-ratio 3 \
--post-filter-gain 8 \
--db-floor -78 --db-ceiling -4 --gain 8 --theme sunset \
--display analog-lines --side both --max-height 0.9 \
--softness 0.6 --hue-cycles 1.5
Run vizzzz --help for every parameter.
For a black and red presentation, use --theme crimson. Additional palettes
include vaporwave, toxic, gold, midnight, ocean, ember, orchid,
forest, and the cherry-pink, plum, and warm cream sakura. mono-dark uses
the grayscale mono bars on an explicit
near-black background.
AE-style radial color interpolation is available with, for example,
--inside-color FF2040 --outside-color FFFFFF; --hue-cycles continues to
rotate the selected theme along the frequency path when explicit colors are
not supplied.
Experimental modes #
The analyzer effects share the same allocation-free FFT frame and can be combined:
cargo run --release -- \
--frequency-scale cqt --whitening 0.8 --peak-isolation 0.7 \
--spectral-contrast 0.7 --audio-duration 90 --audio-offset 0 \
--spectral-flux 0.25 --harmonics 6 --harmonic-boost 0.35 \
--trails 6 --beat-reactivity 0.5 --path circle --theme crimson
--frequency-scale linear|log|cqt|mel|barkselects linear, musical, or psychoacoustic spacing. CQT mode uses constant-Q-style FFT reduction to keep the realtime cost near one normal FFT.--analysis chromamaps energy into the twelve pitch classes.--analysis fundamentalskeeps the normal frequency-bar layout but scores each bar as a possible root using same-frame harmonic support. Use--root-harmonicsto set the highest overtone consulted and--root-isolationto suppress candidates without that support.--whiteningreveals narrow frequencies above the local spectral envelope.--spectral-contrastemphasizes peaks relative to nearby valleys.--audio-durationintegrates energy over time for AE-style rolling hills;--audio-offsetcreates a precisely delayed spectrum without sleeping.--peak-isolationsuppresses bands that are not local maxima.--spectral-fluxemphasizes note attacks and percussion transients.--adaptive-gainnormalizes each band against a bounded, slowly moving reference so quieter notes remain visible without runaway boosts.--tonal-bodyuses phase coherence to separate sustained tonal energy from--transient-sparks;--fundamental-coreand--harmonic-halodistinguish the likely root from its overtone ladder.--centroid-colorshifts the palette with spectral brightness, while--descriptor-motionmaps centroid, rolloff, flatness, crest, coherence, and bass ratio into geometry and glow.--formantsmarks the three strongest formant-like local spectral peaks.--onset-rippleslaunches fixed-lifetime waves from detected attacks, and--tempo-reactivitypulses geometry from an allocation-free tempo tracker.--phase-scopeoverlays a live stereo mid/side Lissajous scope.- Press
fto blend toward a captured spectral frame.--freeze-mixcontrols the blend and--morph-speedlets that held frame drift toward live audio. --harmonicsand--harmonic-boostreinforce harmonic ladders.--low-shelfand--high-shelfexplicitly attenuate bass and overtones around smooth configurable crossovers.--compressor-ratiotames any remaining dominant band above--compressor-threshold.--post-filter-gainapplies dB makeup gain after shelves and compression, raising the frequencies that remain without driving the compressor harder.--path line|circle|arc|sine|diamond|pulsechanges the spectrum baseline.--display braillerenders curved paths at a 2x4 subcell resolution.--trailscreates delayed ghost layers and supplies waterfall history.--display waterfallshows frequency persistence through time.--bar-style solid|segments|dots|lines|led|outline|comet|peak-onlychanges the glyph treatment used by--display bars; pressbto cycle it while the visualizer is running. Wide bars make the hollowoutlinestyle most effective, whilecometandpeak-onlyemphasize frequency movement.--beat-reactivitylets bass energy expand the spectrum geometry.--glow-strengthand--glow-releasecontrol a wider, slower spectrum envelope underneath the sharp core, reproducing the common stacked-AE-layer treatment without running another FFT.--channels stereomaps left to Side A and right to Side B;--channels mid-sidemaps mono-compatible center energy to A and stereo width to B. The defaultmixmode computes only one FFT.
Advanced examples #
Tonal body, fundamental core, and overtone halo:
cargo run --release -- \
--frequency-scale cqt --bands 72 --tonal-body 0.9 \
--fundamental-core 1 --harmonic-halo 0.8 --formants 0.7 \
--display braille --path circle --theme midnight
Transient sparks and onset ripples:
cargo run --release -- \
--transient-sparks 1 --onset-ripples 0.9 --tempo-reactivity 0.65 \
--attack 8 --release 140 --path sine --theme toxic
Adaptive note balancing for material with uneven frequency energy:
cargo run --release -- \
--frequency-scale log --adaptive-gain 0.9 --adaptive-window 5000 \
--adaptive-max-boost 10 --adaptive-max-cut 15 --spectral-contrast 0.45 \
--theme gold
Live stereo phase scope:
cargo run --release -- \
--channels stereo --phase-scope 0.9 --display braille \
--path circle --theme vaporwave
Spectral freeze and gradual morph; press f after launch to capture/release:
cargo run --release -- \
--freeze-mix 0.85 --morph-speed 0.08 --trails 10 \
--path arc --display analog-dots --theme ice
Combined high-production presentation:
cargo run --release -- \
--frequency-scale cqt --bands 96 --adaptive-gain 0.75 \
--tonal-body 0.8 --transient-sparks 0.9 \
--fundamental-core 0.9 --harmonic-halo 0.7 --formants 0.6 \
--onset-ripples 0.75 --tempo-reactivity 0.55 \
--centroid-color 0.8 --descriptor-motion 0.65 \
--compressor-threshold -16 --compressor-ratio 3 --post-filter-gain 8 \
--channels stereo --phase-scope 0.5 --trails 8 \
--display braille --path circle --theme vaporwave
Keys #
| Key | Action |
|---|---|
q, Esc |
Quit |
+, - |
Adjust gain by 1 dB |
r |
Cycle profile |
d |
Cycle display style |
x |
Cycle spectrum path |
s |
Cycle Side A, Side B, and both |
t |
Cycle palette |
p |
Toggle peaks |
Space |
Freeze/resume |
f |
Freeze/release the spectral morph layer |
? |
Show controls |
Platform notes #
- macOS 13 or newer can capture system output directly with
--source output. - Windows captures the default render endpoint through WASAPI loopback with
--source output; use--list-devicesand--deviceto select another. - Input capture works wherever CPAL has a host backend.
- On Linux, select a PipeWire/PulseAudio monitor source as an input to visualize system output.
- Bluetooth headset microphone profiles often run at 16 kHz. Use system output or a higher-rate interface for a full-width music spectrum.