First, it hears the file
It puts a sound into words: calibrated tags with the closest alternative readings, AudioSet labels and measurements. It says what it hears, not what you hoped: this camera shutter from the bank read as a snare hit and a box lid closing.
Also in this step: match, rank, find, compare, ab, realness, measure.
$ earshot describe shutter.wav
0.24 s short one-shot (attack 33 ms, decays in 78 ms). Sounds most like: a snare hit (z +3.5), a punchy impact hit (z +3.4), a box lid closing (z +3.3) [clear reading]. Character: dry close, punchy. AudioSet tagger unsure (Sound effect 0.06). peak -1.0 dBFS, brightness 1.8 kHz, bandwidth 10.2 kHz, side/mid -19 dB.
top tags (z calibrated: >= 3 clear, 2.5-3 plausible, 2-2.5 weak, < 2 tentative):
+3.5 a snare hit [impacts] cos 0.290
+3.4 a punchy impact hit [impacts] cos 0.255
+3.3 a box lid closing [foley] cos 0.347
+3.0 a wooden block hit [foley] cos 0.298
+2.3 a kick drum [impacts] cos 0.193
+2.1 a gunshot [impacts] cos 0.182
+2.1 a drawer closing [foley] cos 0.227
+2.0 a suction cup pop [foley] cos 0.246
Then it checks the work
Every render goes through an audit that measures instead of guessing: clicks, cut tails, clipping, a tail that rises again, a tonal pitch that climbs like a synth whip. Here it checks all 72 takes of the launch kit at once.
Also in this step: timeline, sheet, critique, profile.
$ earshot kit check audio/kit.json --out audio/kit
tick_1.wav pro_hover_tick/ping ok
tick_2.wav pro_hover_tick/ping ok
tick_3.wav pro_hover_tick/ping ok
tock_1.wav knock/wood ok
tock_2.wav knock/wood ok
tock_3.wav knock/wood ok
hit_1.wav cut_hit/punch ok
…
text_C4.wav mallet/pluck ok
text_D4.wav mallet/pluck ok
text_E4.wav mallet/pluck ok
text_G4.wav mallet/pluck ok
text_A4.wav mallet/pluck ok
kit launch: 72 / 72 takes clean; off: suck; 2 note(s)
note: riser is sounded: calm, crisp and minimal keep riser, swell, suck off (one clean element on a reveal reads better than a build stacked onto it; launch sounds one riser or swell at a section change)
note: swell is sounded: calm, crisp and minimal keep riser, swell, suck off (one clean element on a reveal reads better than a build stacked onto it; launch sounds one riser or swell at a section change)
Next, it makes the sound
It renders any of 252 sounds stored as code, aimed at the picture: an exact length, the moment of a whoosh’s peak, a note. No models and no network.
Also in this step: sfx list, forge, gallery.
$ earshot sfx render whoosh_fast/crisp -o w.wav --dur 0.8 --apex 0.32
wrote w.wav: whoosh_fast/crisp seed 420116625: 0.800 s, onset 0.053 s, peak at 0.321 s, end 0.650 s, -1.0 dBFS, -17.6 LUFS momentary max; apex 0.320 s (measured 0.321, +0 ms); dur 0.800 s (shape, trim 21 ms (fade 150 ms)); checks: clean
$ earshot sfx render ui_pop/soft -o pop.wav --pitch A4
wrote pop.wav: ui_pop/soft seed 1: 0.173 s, onset 0.003 s, peak at 0.035 s, end 0.148 s, -1.0 dBFS, -16.1 LUFS momentary max; pitch A4 (measured 442.4 Hz); checks: clean
$ earshot sfx render pluck/kalimba -o e5.wav --pitch E5
wrote e5.wav: pluck/kalimba seed 8001: 3.000 s, onset 0.003 s, peak at 0.013 s, end 1.782 s, -1.0 dBFS, -11.4 LUFS momentary max; pitch E5 (measured 659.2 Hz); checks: clean
Or it turns a recording into code
It fits a small synthesis model until its render matches the recording, then writes the model as a recipe module whose render() makes the sound, new takes and variations. Here it tried seven models on a knock and kept the modal one.
The command: fit FILE -o recipe.py.
$ earshot fit knock.wav -o knock_fit.py --report
modal: score 4.20 (mel 3.05 dB, env r 0.992, tone 1.01 dB, …) in 3.1 s
hybrid:sines+modal+spectral: score 5.64 (mel 3.60 dB, …) in 7.1 s
hybrid:modal+spectral: score 4.93 (mel 3.46 dB, …) in 1.4 s
sines: score 8.00 (mel 4.54 dB, …) in 1.1 s
gesture: score 5.61 (mel 3.75 dB, …) in 1.0 s
spectral: score 11.76 (mel 5.58 dB, …) in 0.9 s
hybrid:sines+spectral: score 6.65 (mel 4.34 dB, …) in 1.1 s
confirmed on seeds [2, 3]: modal 4.63, hybrid:modal+spectral 4.91, gesture 6.32
knock.wav -> modal model (auto chose modal) in 29.9 s
mel 3.05 dB (floor 1.97), env r 0.992, tone 1.01 dB, …, CLAP cos 0.968
floor = two renders of the model with different seeds (a noise model cannot beat it)
the recipe's own render equals the fit render: True
wrote recipe: knock_fit.py
Last, it times the whole film
A kit names one bank sound per role. It renders cached takes with their measured onset, peak and end, so a film pipeline can put each one on its frame.
Also in this step: kit init, kit check, mcp, doctor.
$ earshot kit init --preset launch -o audio/kit.json
wrote audio/kit.json: preset launch, 20 roles sounded, 1 off (suck)
$ earshot kit render audio/kit.json --out audio/kit
tick_1.wav pro_hover_tick/ping seed 2094108523 0.039 s
tick_2.wav pro_hover_tick/ping seed 2094108524 0.039 s
tick_3.wav pro_hover_tick/ping seed 2094108525 0.039 s
…
land-light_3.wav tap/finger seed 175124327 0.120 s
pop_1.wav ui_pop/soft seed 1 0.180 s
pop_2.wav ui_pop/soft seed 2 0.172 s
pop_3.wav ui_pop/soft seed 3 0.172 s
pop_4.wav ui_pop/soft seed 4 0.180 s
whoosh-short_1.wav whoosh_fast/crisp seed 420116625 1.056 s
whoosh-short_2.wav whoosh_fast/crisp seed 420116626 1.031 s
whoosh-short_3.wav whoosh_fast/crisp seed 420116627 0.956 s
whoosh-long_1.wav whoosh_big/thump seed 4201 1.030 s
…