cava
What it is
Section titled “What it is”cava (Console-based Audio Visualizer for Alsa, now cross-platform) is the canonical terminal bar-spectrum visualizer — the one almost every other TUI visualizer (AetherTune, PulseDeck) cites as its inspiration for fall-off and smoothing. It captures system audio, runs an FFT, and draws a row of vertical frequency bars in the terminal that bounce in real time. It is small, fast, and has been the de-facto reference implementation for “audio bars in a terminal” for over a decade.
Two properties make it the Batch-8 rendering reference for KN-86:
- It renders a spectrum in pure brightness/height with sub-character vertical resolution — no color is required for the technique to read. This is precisely the constraint the amber-on-black Toneline and the mono-yellow CIPHER-LINE OLED operate under.
- Its DSP core is split out as a reusable library,
cavacore— a clean core/render separation that is the architectural model for embedding a visualizer inside the nOSh runtime without dragging cava’s terminal front end along.
The rendering technique (the part KN-86 wants)
Section titled “The rendering technique (the part KN-86 wants)”cava achieves 8× the apparent vertical resolution of a plain character grid by drawing the top of each bar with a Unicode 1/8-block character. Full cells below the top are █ (full block); the partial cell at the very top of a bar is one of the seven eighth-blocks:
U+2581 ▁ U+2582 ▂ U+2583 ▃ U+2584 ▄ U+2585 ▅ U+2586 ▆ U+2587 ▇ (+ U+2588 █ full)So a bar whose true height is 3.625 cells draws as three █ cells topped by ▅ (5/8). The eye reads a smooth analog level out of a coarse character grid — exactly the trick the single-color KN-86 brief calls “Unicode density.” cava’s information channel is height + density only; color (its f/b foreground/background keys) is decorative and entirely separable from the technique.
For TTY consoles that lack Unicode, cava ships cava.psf — a console font where glyphs 1–7 are redefined as the eighth-blocks U+2581–2587. That is a direct precedent for KN-86’s situation: the Deckline’s KN-86 Code Page already controls its own 256-glyph bitmap font (per Canonical Hardware Specification), so the eighth-block ramp can be guaranteed present and pixel-correct in the font table rather than relying on terminal Unicode support.
Controls
Section titled “Controls”up/down sensitivity · left/right bar width · f/b fg/bg color · r reload config · c reload colors · q/Ctrl-C quit. Live config reload also via signals (pkill -USR1 cava). INI config ([eq] bands, etc.).
Architecture — the cavacore split
Section titled “Architecture — the cavacore split”cava’s processing engine was extracted into cavacore, a standalone library that does only the DSP: take raw audio samples in, return bar magnitudes out. Everything cava-the-app adds — ncurses drawing, SDL window, raw-stdout mode, audio capture — sits on top of cavacore. The audio backends are themselves pluggable: PulseAudio, PipeWire (default), ALSA, JACK, sndio, OSS, CoreAudio, MPD-FIFO, PortAudio.
Output modes are likewise decoupled from the core:
- ncurses — the default terminal bars.
- SDL — a desktop GL window with GLSL shader support.
- raw — write bar magnitudes to STDOUT as a plain data stream for any downstream program to render however it likes.
That raw mode is the key insight: the visualizer’s output is just an array of bar heights. The renderer is interchangeable.
Toneline-relevance (and Deckline note)
Section titled “Toneline-relevance (and Deckline note)”The Toneline needs to show the operator what they are hearing — the FM voices’ spectrum, a phrase’s level envelope, the bass/mid/treble balance — and it has to do it in monochrome amber. cava is the exact blueprint:
- Spectrum/level rendering = eighth-block bars on the 80×25 grid. A row of frequency bars drawn with
█+ the U+2581–2587 ramp gives the Toneline an analog-looking spectrum analyzer in pure single-color, no palette required. Put it in the content area (Rows 1–23) as a phrase-playback visualizer, or a compact 8–16-band strip docked above the sequencer. cavacoreis the architecture model for embedding the visualizer in nOSh. Build the Toneline/Deckline visualizer as a core DSP unit (samples → bar magnitudes) cleanly separated from the grid renderer (magnitudes → glyph rows) — exactly cava’scavacoreboundary. The same core can feed (a) the 80×25 main-grid spectrum on the Toneline and (b) a tiny level meter on the CIPHER-LINE OLED, with two thin renderers over one DSP core. On KN-86 the input samples come from the YM2149 PSG (Toneline: YM2612 FM) mix produced by the Pico 2 coprocessor, not a system-audio loopback — but the DSP and the magnitude→glyph mapping are unchanged.- CAVA-style gravity fall-off + smoothing is the animation profile. AetherTune and PulseDeck both cite cava’s gravity fall-off and integral smoothing for why the bars look good (they decay naturally instead of snapping). The Toneline’s visualizer should use the same: peak-hold with gravity decay, light temporal smoothing, auto-sensitivity so quiet and loud passages both fill the range. (aethertune.md already specifies this pipeline for the Deckline CIPHER-LINE; cava is its origin.)
- Raw-output decoupling = the FFI seam. cava’s “core emits a magnitude array, anything can draw it” is the same seam KN-86 should expose to cartridge Lisp: a NoshAPI primitive that returns the current spectrum band array, so a Toneline cart (or any music cart on the Deckline) can draw its own visualizer in Lisp without touching the DSP.
Deckline note: even outside the Toneline, this is the implementation reference for the long-planned CIPHER-LINE PSG visualizer (the YM2149 register/level display on the 256×64 OLED). cava’s eighth-block technique plus cavacore’s core/render split is the concrete recipe for that feature on the mono-yellow OLED.
Single-color adaptation
Section titled “Single-color adaptation”cava is the single-color adaptation, already proven: its entire information content survives with color stripped, because the data lives in bar height + the eighth-block partial-cell density at each bar’s top. For KN-86:
- Encode the eight ramp glyphs (
▁▂▃▄▅▆▇█, U+2581–2588) as guaranteed entries in the KN-86 Code Page bitmap font — no dependence on terminal Unicode, pixel-exact on the amber grid. - Bars are amber on black; intensity is height, not hue. Optionally use inversion (black bar on amber field) to distinguish a held/peak band from active bands — a second monochrome channel cava doesn’t need but the grid affords.
- On the 8×8-cell font, the eighth-block ramp gives the same 8× vertical-resolution multiplier cava gets, so an N-row spectrum reads as if it had 8N levels.
- The eighth-block ramp (U+2581–2588) is the single most reusable artifact in this entry. It is the canonical “Unicode density” character set the single-color KN-86 brief keeps gesturing at; cava is where it comes from and where its sub-cell-resolution trick is best documented.
- cavacore is the architecture artifact. Whenever KN-86 builds an audio visualizer (Toneline spectrum, CIPHER-LINE PSG meter, a music-cart visualizer), follow the cavacore core/render split: DSP core in, magnitude array out, thin glyph renderer on top.
- Cross-link line.md —
lineis the sequencer-language half of the Toneline; cava is the see-what-you-hear visualization half. Together they close the loop: type a phrase, watch its spectrum. - Cross-link aethertune.md and pulsedeck.md — both inherit cava’s fall-off/smoothing pipeline for the CIPHER-LINE visualizer; this entry is the upstream source for that technique.
- Cross-link ascii-effects.md — sibling
effect/rendering spec; the eighth-block ramp belongs in the same project-wide single-color rendering vocabulary.