Machine-listening QA for audio plugins — close the render → listen → decide loop without human ears.
sonoscope closes the loop (plugin, stimulus, param-set) → wav → versioned analysis JSON,
pairing deterministic ground-truth features with probe-gated, advisory perception. It gives
an LLM (or a developer) machine-readable ground truth about what a plugin actually renders
— features, integrity flags, PASS/RED tripwires, and noise-floor-gated iterate verdicts, plus
an optional advisory natural-language description — so an agent can develop, render, listen,
and decide without human ears.
Requires Python 3.12 and uv. sonoscope is not published to PyPI; install from source:
git clone https://github.com/axiomantic/sonoscope.git
cd sonoscope
uv sync # install pinned core dependencies
uv run sonoscope doctor # verify your environment is healthyThe perception extra (optional, advisory) pulls in torch + transformers and downloads
the ~16 GB Qwen2-Audio model on first use. Skip it unless you want natural-language descriptions:
uv run --extra perception sonoscope analyze --perception --plugin "<plugin>.vst3" --spec <spec>.jsonEvery command emits one JSON object on stdout and a typed exit code
(0 ok/finding · 1 usage · 2 input · 3 render · 4 analysis · 5 environment). A plugin
defect is reported as a finding with exit 0, not a crash — so CI can branch on the JSON, not
on process failure.
uv run sonoscope doctor # is my environment healthy?
uv run sonoscope analyze --plugin "<plugin>.vst3" --spec <spec>.json # what did it render?
uv run sonoscope analyze --wav path/to/render.wav # analyze an existing wav (honest provenance)
uv run sonoscope iterate --plugin "<plugin>.vst3" \
--baseline <a>.json --candidate <b>.json \
--metric deterministic.summary.spectral_centroid_hz --direction decrease # did my change land?A --spec bundles the stimulus and the param-set. Point analyze at a built plugin and a spec:
uv run sonoscope analyze \
--plugin "/Library/Audio/Plug-Ins/VST3/Surge XT.vst3" \
--spec specs/example.jsonIt renders the audio and prints a versioned analysis report (trimmed):
{
"schema_version": "1.4.0",
"deterministic": {
"summary": {
"rms_dbfs": -22.03,
"peak_dbfs": -13.69,
"spectral_centroid_hz": 2809.06,
"spectral_flatness": 0.00051,
"onset_count": 1
},
"integrity": { "is_silent": false, "has_nan": false, "clip_count": 0 }
},
"tripwires": {
"expected_audio": true,
"results": [
{ "id": "silent-output", "verdict": "PASS", "detail": "rms_dbfs -22.0 > -80.0 dBFS" },
{ "id": "nan-inf", "verdict": "PASS" },
{ "id": "clipping", "verdict": "PASS", "detail": "clip_fraction 0.0" }
],
"overall": "PASS"
}
}analyze --wav analyzes a standalone file at its native rate, then resamples the analyzed slice
to 48 kHz — and records exactly what it did in an input_provenance block, so a resampled-from-44.1k
signal is never reported as faked-pristine. Output is a JSON array, one entry per chunk (trimmed):
[
{
"schema_version": "1.4.0",
"kind": "wav-chunk-analysis",
"input_provenance": {
"original_sample_rate": 44100,
"n_channels": 1,
"source_subtype": "PCM_16",
"resample_res_type": "soxr_hq",
"chunk_index": 0,
"n_chunks": 1
},
"deterministic": { "summary": { "rms_dbfs": -12.73, "spectral_centroid_hz": 54.55 } }
}
]doctor gives you a fast, gated readiness check before any of that:
sonoscope doctor:
[OK ] pins: 5 pinned dependencies match
[OK ] lockfile: uv.lock in sync
[OK ] surge_xt: Surge XT install + factory content verified
[OK ] backend: backend pedalboard-vst3 v0.9.23 loaded
[OK ] perception: perception available: Qwen2-Audio-7B-Instruct (transformers)
=> OK
- Plugin hosting: renders VST3 via pedalboard and CLAP via a bundled C host — real audio, not simulation.
- Honest-provenance WAV analysis:
analyze --wavanalyzes existing files at native rate, resamples the slice to 48 kHz, and records source rate/subtype/resampler in aninput_provenanceblock — never faked-pristine. - Spec-driven matrix: one JSON
--specpins the stimulus, param-set, and patch class; swap specs to sweep params and stimuli reproducibly. - Versioned analysis JSON: a schema-versioned (
1.4.0), extra-forbidding pydantic report — stable enough to diff, regression-test, and feed to an LLM. - Deterministic feature ground truth: librosa-backed RMS/peak, spectral centroid/flatness/rolloff, onsets, tempo, and MFCCs, plus NaN/Inf/clip/DC integrity flags.
- PASS/RED tripwires: silent-output, NaN/Inf, denormal, and clipping checks that turn "did it break?" into a machine-readable verdict.
- Noise-floor-gated iterate: compare a baseline vs. candidate on one metric (
iterate) or on descriptor terms (iterate-descriptors), gated against measured nondeterminism floors — no chasing noise. - Optional Qwen2-Audio perception: opt-in, clearly-labelled advisory natural-language descriptions, never treated as ground truth.
docs/using-sonoscope.md is the full guide — an LLM- and developer-oriented walkthrough with a mental model, quickstart, and many worked examples (every command and output captured from real runs against Surge XT and the Qwen2-Audio model). Start there.
docs/music-vocabulary.md is the controlled descriptor vocabulary and grounding contract — the taxonomy sonoscope uses to describe audio, tagging each term by how much is measured versus opinion.
Beyond the commands above, the CLI also exposes render, analyze-midi, determinism,
probe, schema, and corpus. Run uv run sonoscope <command> --help for details.