The most advanced terminal and desktop audio visualizer I'm aware of
README.md

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:

  1. $VIZZZZ_PROFILES
  2. $XDG_CONFIG_HOME/vizzzz/profiles.ini
  3. $HOME/.config/vizzzz/profiles.ini
  4. profiles.ini when 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|bark selects linear, musical, or psychoacoustic spacing. CQT mode uses constant-Q-style FFT reduction to keep the realtime cost near one normal FFT.
  • --analysis chroma maps energy into the twelve pitch classes.
  • --analysis fundamentals keeps the normal frequency-bar layout but scores each bar as a possible root using same-frame harmonic support. Use --root-harmonics to set the highest overtone consulted and --root-isolation to suppress candidates without that support.
  • --whitening reveals narrow frequencies above the local spectral envelope.
  • --spectral-contrast emphasizes peaks relative to nearby valleys.
  • --audio-duration integrates energy over time for AE-style rolling hills; --audio-offset creates a precisely delayed spectrum without sleeping.
  • --peak-isolation suppresses bands that are not local maxima.
  • --spectral-flux emphasizes note attacks and percussion transients.
  • --adaptive-gain normalizes each band against a bounded, slowly moving reference so quieter notes remain visible without runaway boosts.
  • --tonal-body uses phase coherence to separate sustained tonal energy from --transient-sparks; --fundamental-core and --harmonic-halo distinguish the likely root from its overtone ladder.
  • --centroid-color shifts the palette with spectral brightness, while --descriptor-motion maps centroid, rolloff, flatness, crest, coherence, and bass ratio into geometry and glow.
  • --formants marks the three strongest formant-like local spectral peaks.
  • --onset-ripples launches fixed-lifetime waves from detected attacks, and --tempo-reactivity pulses geometry from an allocation-free tempo tracker.
  • --phase-scope overlays a live stereo mid/side Lissajous scope.
  • Press f to blend toward a captured spectral frame. --freeze-mix controls the blend and --morph-speed lets that held frame drift toward live audio.
  • --harmonics and --harmonic-boost reinforce harmonic ladders.
  • --low-shelf and --high-shelf explicitly attenuate bass and overtones around smooth configurable crossovers. --compressor-ratio tames any remaining dominant band above --compressor-threshold.
  • --post-filter-gain applies dB makeup gain after shelves and compression, raising the frequencies that remain without driving the compressor harder.
  • --path line|circle|arc|sine|diamond|pulse changes the spectrum baseline.
  • --display braille renders curved paths at a 2x4 subcell resolution.
  • --trails creates delayed ghost layers and supplies waterfall history.
  • --display waterfall shows frequency persistence through time.
  • --bar-style solid|segments|dots|lines|led|outline|comet|peak-only changes the glyph treatment used by --display bars; press b to cycle it while the visualizer is running. Wide bars make the hollow outline style most effective, while comet and peak-only emphasize frequency movement.
  • --beat-reactivity lets bass energy expand the spectrum geometry.
  • --glow-strength and --glow-release control a wider, slower spectrum envelope underneath the sharp core, reproducing the common stacked-AE-layer treatment without running another FFT.
  • --channels stereo maps left to Side A and right to Side B; --channels mid-side maps mono-compatible center energy to A and stereo width to B. The default mix mode 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-devices and --device to 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.