Repository navigation
fix(cli): audio --read reads music onsets, effect peaks, pauses and voice against music - #6546
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
A run of the bed is split where sound fills less than half of the surrounding 2 s, so a short tone and scattered clicks that bridge into the music no longer pull its start earlier. Sparse stretches are left to effects.
…m the mix A sound ends where the next one starts, so a run of kicks is not one long riser. Effects are searched in the drums and in the bed outside music, each on its own, so a click inside a tone is still found. Each effect's peak is read from the decoded mix in dBFS, and the music reference is taken next to the effect rather than under it, where its own leakage sits.
Pauses carry the whole recording's level so the read can say what keeps playing while the voice stops.
…music Effect lines print the absolute peak and name the reference of the relative figure; pause lines keep the pause kind and list the effects, music and ambience under them; sentences over music print voice and music loudness and which is louder. Read schema version 4.
4da5293 to
587d997
Compare
There was a problem hiding this comment.
Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head 587d9974
One blocker: zeroing the bed over music and ambience spans adds a fake onset where each span ends, so an ordinary music fade-out reads as an effect. Details inline.
Scope
Read all of effects.ts, music.ts, read.ts, format.ts, voice.ts, signal.ts and types.ts, plus the tests. vitest run src/audio/read/ passes locally (46/46). I probed the bed path with synthetic beds through readMusic → findEffects, which is what fromStems does. No prior reviews. CI and Comments were green on this head when I posted; one CI and one Windows render run were still in progress.
— Genesis
…ked one Blanking the bed wherever music or ambience played made every blanked stretch that ended while sound was still audible look like a sound rising out of silence. Fades and quiet bridges then printed as dings, hits and whooshes. The bed is now searched whole, and each source carries the spans it plays music or ambience in. A sound whose onset-to-peak overlaps one of those spans belongs to it, so it is not an effect. The drums and the bare mix carry no spans. — Jerrai
What
Four accuracy fixes to
hyperframes audio --read(what Desktop'sread_audiowraps). They come from a DSH e2e on a 30 s fixture: speech, silence, clicks at 8.0/8.5/9.0/9.5, a 1 kHz tone burst, a 120 BPM bed from 10.0 with a kick every 0.5 s, and speech over music.pause 3.8–21.0said nothing about the sound that kept playing.All four are in this PR.
Why: causes found
I reproduced these on a rebuilt fixture: macOS
sayspeech, synthesized clicks, burst, kick and pad, plus synthetic stems with cross-stem leakage. The base read reproduces the reported failures:boom/riser;+34 dB over music.The causes:
runs()sees one run from 7.9 to the end, and the run's tonality makes it all music. Effects were searched only in the drum stem, so the burst could never become an effect.extent()ran for up to 4 s while the level stayed above the silent floor from before the music. Every following kick extended the same sound, which gave a long attack and a riser/boom kind.How
music.ts. Each run of the bed is split into sustained parts. A frame counts as sustained when sound fills at least half of the 0.1 s frames within ±1 s. Part edges move in to where the sound holds for 0.5 s without a gap. Sparse stretches are neither music nor ambience.effects.ts, onsets. A sound ends where the next one steps 6 dB up out of it, and the onset walk-back stops at the trough after the previous sound.effects.ts, per-track search. Effects are found in each source track on its own: the drums, and the bed with its music and ambience stretches silenced ±0.1 s. Duplicates within 30 ms keep the louder finding. The speech skip gets 0.1 s of slack for word timing.effects.ts, levels.peakDb: the loudest 20 ms RMS of the decoded mix within ±50 ms of the effect's peak.overMusicDb: measured against the music's (bed + drums) mean level in the second before the onset, or after the end when the music starts with the effect.riseDb: measured against the mix's median level in the half second before;nullwhen that level is under −55 dBFS.voice.ts/read.ts.recordingDb.againstMusic: { voiceLufs, musicLufs }. This is BS.1770 integrated loudness (coreloudness()) of the vocals stem and of everything else, measured over the overlap only.READ_VERSIONgoes 3 → 4, so cached reads recompute. Docs are updated indocs/packages/cli.mdx.Related work
Builds on #6536 (noise beds as ambience), now merged into
main. This PR is rebased onto it. The bed is silenced for effect search outside both music segments and ambience, and pause lines name ambience too.Stem separation billing
/v3/audio/stemsis a billed call. It is charged per second of audio to the caller's HeyGen credits, or to the HyperFrames usage pool for Desktop, and refunded on failure. Only--quality besttriggers it, and cached stems are reused.Model-facing text (for Xuanru's review)
…, tail 0.0 s, +34 dB over music, ……, tail 0.0 s, peak -23 dBFS, +4 dB over music, ……, while the music is out, …(stems) /+104 dB over what played before(mix)…, peak -17 dBFS, out of silence, …+12 dB over what played beforepeak -20 dBFS, +12 dB over what played beforepause 19.4 spause 19.4 s; during it: 5 effects (whoosh, click, tick ×3), music 10.0–21.0pause 19.4 spause 19.4 s; during it: 7 effects (…), sound continues at -18 dBFSpause 1.0 spause 1.0 s, silentvoice "…" 3.2 words/s (mean 4.2)voice "…" 3.2 words/s (mean 4.2) voice -24 LUFS, music -20 LUFS: music 4 dB over voicevoice "…" …voice "…" … voice -14 LUFS, music -18 LUFS: voice 4 dB over musicpause 2.0 spause 2.0 s; during it: ambience 4.0–6.0voice "…" …voice "…" … voice -18 LUFS, music -19 LUFS: level with each otherThe
pausetoken stays first on pause lines, because Desktop's show filter takes the first word as the kind.Test plan
Fixture. 30 s, built locally:
sayspeech plus synthesized clicks, burst, 120 BPM kick and pad, and synthetic stems with leakage re-encoded as 192 kb/s MP3. It was encoded as mono 22.05 kHz, mono 44.1 kHz and stereo 48 kHz.+34 dB over music.music 4 dB over voice(5 dB on the 22 kHz encoding, where the voice measures −25 LUFS).boomat+114 dB; it now readsthump ×3 … peak -7 dBFS.New tests. Each one is confirmed to fail on the base code where that applies:
format.test.tscovers the three voice-vs-music wordings (music louder, voice louder, level within 0.5 dB).Checks.
vitest run src/audio/read/: 46 passed.tscis clean for these files.Not run for real.
Known limits.
whoosh: the kind table has no plain tone kind.click: midwhile the other clicks readtick: high.