Guide — The round-trip invariant
The single rule the toolkit is built around.
The rule
At every stage of processing — raw, bandpassed, segmented, clustered, embedded — there must be a way to get back to playable audio.
Why it matters
Acoustic-communication analysis routinely produces strange-looking results: a "novel" cluster, an unusual transition, a perplexity spike. Most of the time, when you listen to the underlying clip, the cause is obvious — a single contaminating event, a microphone artefact, a clipped peak. If you can listen in two minutes, you debug in two minutes. If the clustering and the audio have drifted apart, you debug for a day.
How it shows up in the API
load_audioreturns anAudioSourcewhosesamplesare immediately writable to disk.bandpassandresample_toreturn raw float32 arrays thatwrite_wavconsumes directly.detect_unitsreturnsUnitobjects each holding their ownsource_samples— a unit is listenable on its own.cluster_featureslabels feature rows; the contract is that the caller keeps the parallelunitslist, sounits[i]is the audio forlabels[i].SymbolStreambundles the symbols and units together so the round-trip is a constructor invariant.
The invariant in action
Four stages of the same humpback clip — raw, bandpassed, one detected unit, and a cluster exemplar. Every stage is a WAV you can play.
What the contract excludes
You will never find a primitive that returns a feature matrix without a parallel structure that lets you recover the audio. If you find one, that is a bug.