README.md
llimphi-widget-waveform
Live waveform viewer.
The pattern is analogous to llimphi-widget-timeline: the widget keeps no
audio state (no cpal, no AudioProbe, no ring buffer). The caller passes a
Fn(&mut Vec<f32>) -> u16 closure that fills a buffer with the latest samples
and returns how many interleaved channels it carries; the widget folds to
mono and draws a min/max envelope per column (a closed polygon with a faint
fill plus a stroke above and below) over a centre line always present as the
viewer's "ground". No mouse handlers — paint only.
┌─────────────────────────────────────────────────┐
│ ▄▄▄ ▄ ▄▄▄ ▄▄ ▄▄ ▄ │
│ ▄███▄ ▄█▄▄███▄▄██▄▄▄▄██▄▄█▄ │
│──█████──███████████████████████─── centre ──────│
│ ▀███▀ ▀█▀▀███▀▀██▀▀▀▀██▀▀█▀ │
│ ▀▀▀ ▀ ▀▀▀ ▀▀ ▀▀ ▀ │
└─────────────────────────────────────────────────┘
Typical use (a player with an audio probe):
use std::sync::Arc;
let probe = audio_probe(); // the app's own Arc<AudioProbe>
let palette = WaveformPalette::default();
waveform_view(
move |out| {
let (_sr, ch) = probe.snapshot(out);
ch // interleaved channels
},
&palette,
)
If the closure returns 0 channels (or does not fill the buffer), the widget
paints only the centre line — useful to show "viewer alive, no signal" while the
capture device has not come up yet.
Part of llimphi — see llimphi.