Beta We are beta testing now, and open for business soon.
Defined formats. Your own scripts.
Every recording's facts, every detection, every review and every correction is a plain, versioned file beside the audio. Read them, script against them, write your own: everything captured in Sound Onion is yours to analyse at scale.
What goes in
| Where | Reads |
|---|---|
| Sound Onion, in the browser | WAV: 8, 16, 24 and 32-bit integer and 32-bit float, any sample rate, any number of channels (it reads the first channel) |
| Acoustic Analyzer | WAV; FLAC and AIFF one file at a time |
Your recordings stay in your folders, named as you name them. Sound Onion adds its files beside them and never changes yours.
What is written beside your recordings
Survey_2026/ a review pack
review_pack.yaml the mark a pack is found by: its clips, how it was made
DEMO_A_20260601_101500_000/ one recording's clips
DEMO_A_20260601_101500_000__02m10.0s-02m16.0s.wav a clip: the recording's own samples
metadata/ what a script wrote
DEMO_A_20260601_101500_000__02m10.0s-02m16.0s.info.yaml where the clip came from, the detector's claim
DEMO_A_20260601_101500_000__02m10.0s-02m16.0s.pyramid.* the spectrogram's detail levels
edits/ what a person wrote
DEMO_A_20260601_101500_000__02m10.0s-02m16.0s.AB.k3x9q2.yaml reviewer AB's answer
DEMO_A_20260601_101500_000__02m10.0s-02m16.0s.AB.k3x9q2-002.yaml AB's next answer; the earlier one is kept
metadata/
Written by programs: the analyser, the detectors and the data joins. A correction you make goes in a file of your own beside it, never over it.
edits/
Written by people: one file per reviewer per browser, and a new one for every change of mind, so the files themselves are the history. A change made within a couple of minutes updates the newest file instead.
Plain text
Every review, and every file of facts beside the audio, is YAML a person can read and a program can parse, without Sound Onion. Only the spectrogram's own files are not: its detail levels (binary and JSON) and its pictures (PNG).
Versioned, so old files keep working
Every file the analyser writes, and every review, starts with its format, a number, and its schema, the kind of file. A reader brings an older format up to date as it reads, and refuses one newer than it knows rather than guess. A new optional field does not change the format; removing, renaming or changing the meaning of one does, with a step to upgrade.
| Kind | File | Holds |
|---|---|---|
detection | <recording>.detection.yaml | everything the analyser found in a recording, with its evidence |
clip | metadata/<clip>.info.yaml | where a clip came from, its gain, and the detector's claim |
review-pack | <pack>/review_pack.yaml | the mark a pack of clips is found by |
learnings | learnings_<stamp>.yaml | every reviewer's answers, scored, for the analyser to learn from |
rules | <name>.rules.yaml | the rules a run reached from its learnings |
A detection, as the analyser writes it
One entry for each thing found, in time order: the box in time and frequency, the model's class and how sure it is, in numbers and in words.
format: 2
schema: detection
detections:
- t0: 1395.5 # s, in the recording's own time
t1: 1398.5
f0: 3183.1 # Hz
f1: 14337.7
label: pinger
group: man-made # animal, man-made, ambient or unsure
confidence: 0.83
sure: fairly # very, fairly, leaning or guessing
runner_up: rowing
share: 0.82 # this box's part of the evidence at that moment
energy_in_band: mostly above
said: "Pinger, fairly sure (runner-up: rowing), at 1395.5–1398.5 s in 3.2 kHz–14.3 kHz
(82% of the evidence at that time). …"
A review, as a reviewer saves it
format: 3
schema: review
clip: DEMO_A_20260601_101500_000__02m10.0s-02m16.0s.wav
reviewer: AB
install: k3x9q2
at: '2026-06-03T10:00:00.000Z'
rows:
- source: animal # animal, man-made, ambient or unsure
what: whistle
notes: ''
tags: []
Script it, at any scale
Because every answer is a file, a few lines of your own code reach everything captured in Sound Onion: every reviewer, every clip, every survey. This counts what each reviewer said, taking each one's latest answer:
from collections import Counter
from pathlib import Path
import yaml
latest = {}
for f in Path("Survey_2026").rglob("edits/*.yaml"):
review = yaml.safe_load(f.read_text())
if not isinstance(review, dict) or review.get("schema") != "review" or "rows" not in review:
continue # a folder's tags, or an answer withdrawn
key = (review["clip"], review["reviewer"])
if key not in latest or review["at"] > latest[key]["at"]:
latest[key] = review # each reviewer's newest answer is the one that stands
said = Counter((row.get("source"), row.get("what")) for r in latest.values() for row in r["rows"])
print(said.most_common())
Publish results does the whole collection for you, scored against every detection, into one learnings file.
Bring your own
Your own detector
If your detector or model writes a review pack in this format (the clips and their
info.yaml), your team reviews it in Sound Onion exactly as it reviews ours. Your model, our review.Your own data
Your WAV folders as they are. Sound Onion reads them where they are and adds its files beside them.
Your own tools
Read the reviews and detections with anything that reads YAML: Python, R, MATLAB.
Talk to us
We are beta testing now and will open for business soon. Tell us what you record and how much of it there is: we will show you your own data in Sound Onion, and you will be among the first.
accounts@sound-onion.com