A small terminal audio spectrum visualizer in Rust. It is like cava.
NOTE: This is a toy project. It is not finished. Many features are missing. Use it for fun and learning only.
mini_cava can show 4 display modes. The 4 videos below show each mode.
You can only change the mode by editing the const values in src/main.rs and rebuilding. There is no runtime switch yet.
This project was only tested on:
- Arch Linux
- PipeWire (only, no PulseAudio or JACK)
It reads audio from the PipeWire default_sink monitor. It may not work on other systems.
- Rust (nightly, edition 2024)
- System libraries:
pkgconf,pipewire,alsa-lib,clang
Install on Arch Linux:
./install_deps.shcargo runPress q to quit.
cpal(PipeWire host) captures thedefault_sinkmonitor.- Samples go through a ring buffer, then
rustfftdoes an FFT. - FFT size is 1024, with a Hanning window. Stereo is mixed to mono.
- DC is removed by subtracting each frame's mean before windowing.
- Each bar sums the linear magnitudes (
norm / window_sum) of its FFT bins, then converts to dB with20 * log10(sum). crosstermdraws the bars on the alternate screen.- Bars use a log-frequency scale from 40 Hz to 13 kHz.
- A cava-style noise-reduction filter smooths each bar over time:
a
falloffcurve for the falling edge plus anintegrallow-pass. autosensuses cava's multiplicative gain (overshoot detection) to keep the tallest bar near the top without amplifying the noise floor during silence.- Optional
monstercat/wavesfilters blend neighbouring bars. - A damped-oscillator spring animates each bar toward its target, overshooting and bouncing back (non-linear rebound) instead of moving monotonically.
- Each bar has a peak cap that falls slowly.
- Bar color is an HSV rainbow gradient: hue sweeps continuously from
GRADIENT_START_HUE(bottom) toGRADIENT_END_HUE(top). - The gradient's palette continuously cycles over time: a running hue phase
rotates both
GRADIENT_START_HUEandGRADIENT_END_HUEtogether, and the cycling speed is set by the smoothed audio intensity (INTENSITY_SMOOTHING), from a slow idle rate (HUE_CYCLE_BASE_SPEED) up to a fast rate at full intensity (HUE_CYCLE_INTENSITY_SPEED). - Full cells use the half-block
▀with the top half in the foreground colour and the bottom half in the background colour, giving half-cell gradient steps.
Change these const values in src/main.rs:
| Constant | Default | Meaning |
|---|---|---|
FFT_SIZE |
1024 | FFT window size |
DB_FLOOR |
-60.0 | dB floor for bar height |
GRAVITY |
1.5 | power curve (>1 drops quiet bars) |
NOISE_REDUCTION |
0.77 | noise-reduction strength (0..1] |
FRAMERATE |
60.0 | nominal frame rate for smoothing/autosens |
AUTOSENS |
1.0 | autosens gain rise speed |
MONSTERCAT |
0.0 | monstercat neighbour smoothing (0 = off) |
WAVES |
0 | waves neighbour smoothing (0 = off) |
SPRING_STIFFNESS |
0.16 | spring stiffness (higher = harder/faster) |
SPRING_DAMPING |
0.70 | spring damping (lower = more bounce) |
BAR_AMPLITUDE |
1.2 | bar height multiplier (>1 = taller) |
INTENSITY_SMOOTHING |
0.08 | intensity envelope smoothing (lower=slower) |
HUE_CYCLE_BASE_SPEED |
0.3 | idle palette spin speed (deg/frame) |
HUE_CYCLE_INTENSITY_SPEED |
3.0 | extra spin speed at full intensity (deg/frame) |
LOWER_CUTOFF_FREQ |
40.0 | lowest bar frequency (Hz) |
HIGHER_CUTOFF_FREQ |
13000.0 | highest bar frequency (Hz) |
CAP_SIZE |
0 | peak cap height (1/8 cells, 8 = 1 cell) |
CAP_GRAVITY |
1.0 | peak cap fall step (1/8 cells) |
BAR_WIDTH |
3 | bar width (columns) |
BAR_SPACING |
1 | gap between bars (columns) |
GRADIENT_START_HUE |
0.0 | gradient hue at the bottom (deg) |
GRADIENT_END_HUE |
240.0 | gradient hue at the top (deg) |
GRADIENT_SAT |
1.0 | gradient saturation (0..1) |
GRADIENT_VAL |
1.0 | gradient value/brightness (0..1) |



