agentleFS
gothicpixiegothicpixie/opendubstage/skills/mix-qc-and-delivery/SKILL.md

mix-qc-and-delivery

Skill1 starsChanged 31 days agoApache-2.0View on GitHub

The objective QC gate and delivery specs for a spoken-word mix (documentary, radio feature, podcast): dialogue-anchored loudness, true peak at 4x oversampling, LRA, dead air, clicks at cue edges, masking, level jumps, tonal balance, the transcription check of every narration cut, the half-volume test and the multi-system listen, with the thresholds and their sources (PRSS, ATSC A/85, EBU R128, Netflix, Torcoli/AES) and the opendubstage qc CLI. Use before any picture render, when someone asks "is this mix ready", "what loudness should this be", "why does the limiter still show overs", "is there a click here", "how do I check the cuts", or when writing a verify step / CI gate for a mix. Do NOT use for choosing processing (dialogue-editing-and-restoration) or music placement (music-under-narration).

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Never loudnorm in dynamic mode on a long mix: ffmpeg falls back to dynamic (3 s window compression) whenever the measured LRA exceeds the …

    line 43
  2. Very specific:

    Verify with ebur128=peak=true or opendubstage qc (true_peak_max −2.0), never with the limiter's own meter.

    line 53
  3. Distinctive:

    Leave 0.3–0.5 dB for the codec.

    line 54
  4. Distinctive:

    Dead air comes from beds shorter than their scenes: Before mixing, check every bed's source length against the span it must cover (loop it, …

    line 91
  5. Distinctive:

    check every cue: a 12-cut sample missed "and--" endings a model reviewer heard.

    line 110

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

mix-qc-and-delivery

The mix is checked before any picture is rendered. A late mix failure after a picture render cost hours in practice; the gate exists so that cannot happen again. OpenDubStage tool: opendubstage qc (opendubstage.qc.mixqc: qc(mix, cues, stems, thresholds), Thresholds).

opendubstage qc MIX.wav [--cues SHEET.json] [--stem dialogue=DX.wav --stem background=BG.wav] [--thresholds T.json] [--json OUT.json] [--md OUT.md]

Exit 1 when a blocking check fails. Without a cue sheet only the programme-wide checks run (loudness, LRA, true peak, dead air). Cue-sheet schema and the full threshold table with sources: references/thresholds.md.

1. Delivery specs

SpecIntegratedTrue peakNotes
PRSS (public radio distribution)−24 LUFS ± 2−2 dBTP (sample −3)Current 2014; Radio World
ATSC A/85−24 LKFS ± 2, dialogue-anchored−2 dBTP
Netflix v1.5dialogue −27 LKFS ± 2, dialog-gated−2 dBTPLRA programme 4–18 LU, dialogue ≤ 7 LU (guidance)
EBU R128−23 LUFS ± 1−1 dBTPLRA descriptive; talk ≈ 5 LU (Auphonic)
Apple Podcasts−16 LKFS ± 1−1 dBTP
AES TD1004 streaming−16…−20 LUFS≤ −1 dBTPlossy codecs overshoot
Home-viewing feature (recommended)dialogue −24 LUFS dialogue-gated ± 1; programme free (expect −22 ± 3)≤ −2 dBTP after the codec; ≤ −2.3 before AACLRA 8–18 LU reported, not clamped; dialogue-only LRA ≤ 7

Anchor on dialogue, not on the programme: measure dialogue-gated loudness on the dialogue + live-speech stems, apply one linear gain, then a limiter as the only non-linear stage. Never loudnorm in dynamic mode on a long mix: ffmpeg falls back to dynamic (3 s window compression) whenever the measured LRA exceeds the target LRA; check the first pass's normalization_type.

2. True peak

A sample-peak limiter misses inter-sample overs. Measured in practice: a mix limited at −2.5 dBFS sample read −1.3 dBTP. Rules:

  • Limit at 4× oversampling (ITU-R BS.1770-4) or set the sample ceiling 0.6 dB below the target: alimiter=limit=0.74 (−2.6 dBFS) to land ≤ −2.3 dBTP before AAC, ≤ −2 after.
  • Verify with ebur128=peak=true or opendubstage qc (true_peak_max −2.0), never with the limiter's own meter.
  • Leave 0.3–0.5 dB for the codec; re-measure the encoded file.

3. The checklist

#CheckThresholdGateSource
Q1dead airno span < −60 dBFS sample peak for > 3 s (strict: −50 dBFS / 2 s), head and tail 5 s exempt, designed silences whitelistedblockingsilencedetect; Torcoli (ambience ≥ 15 LU under speech)
Q2gaps are airmomentary (400 ms) ≥ −46 LUFS in every speech gap; ambience in the clear −38…−42 LUFSblockingTorcoli; Tech 3341
Q3dialogue anchordialogue-gated −24 ± 1 LUFSblockingPRSS; A/85
Q4programmeintegrated −27…−16 (report); LRA 4–18 LU; dialogue-only LRA ≤ 7 (narrated segments ≤ 10, live ≤ 15 advisory)advisoryNetflix; Auphonic; Tech 3342
Q5true peak≤ −2.0 dBTP at 4× oversampling (−2.3 before AAC)blockingPRSS; Netflix; BS.1770-4
Q6every voice at the same levelshort-term (3 s) per voice class within ±2 LU of −24; per-cue sentence std ≤ 1.5 LUadvisoryByers
Q7tonal balance1–4 kHz presence share per voice class within ±4 dB of the class mean; LTAS per class within ±3 dB of the reference 200 Hz–6.3 kHzadvisoryRX EQ Match practice; measured in practice
Q8rumble< 100 Hz ≥ 25 dB below the 1 kHz band on dialogueadvisorymeasured in practice
Q9maskingmusic + ambience ≤ dialogue −10 dB in 1–4 kHz over any ≥ 3 s stretch of speech (strict: −14 dB in 1.2–4.8 kHz, 99th percentile); broadband music ≤ −10 LU, ambience ≤ −15 LUblocking (default)Torcoli; Shirley & Kendrick
Q10no vocals under speechno under cue overlapping speech > 1 s whose section has vocalsblocking (plan)NPR practice
Q11music entriesdownbeat / section / song start ≤ 60 ms; fade_in ≥ 0.5 mid-song; none within 2 s before a first wordblocking (plan)Menjivar
Q12music exits / postsevery under cue ends on a downbeat or section end with ≥ 1 s out; posts 2–12 s; music-only > 15 s flaggedadvisoryMenjivar
Q13music densityper 10 min: 30–70 % music; no cue > 150 s under speech; no dry stretch > 90 s without bedadvisoryMenjivar
Q14crossfade at every boundary±3 s: a non-dialogue stem non-zero on both sides ≥ 1.5 s; music adjacency gap < 0.1 or ≥ 3 s or overlap ≥ 1.5 sblockingcheck_transitions
Q15edit pointsevery dialogue cue fade_in ≥ 0.05, fade_out ≥ 0.25, last_word_end + 0.35 ≤ cue_endblockingAudition 5 ms rule; measured in practice
Q16clickssample step > 8× the local difference RMS within ±5 ms of a cue edge, above −60 dBFS; adeclick save-mode < 1 click/min outside repaired eventsblockingengineering practice
Q17speech heard correctlytranscription check: head and tail ratio ≥ 0.5 for every narration cue; key live phrases ≥ 0.75blockingmeasured in practice
Q18event residueenergy inside each repaired event window within 3 dB of the flooradvisory
Q19restoration safetyDNSMOS SIG not lower than source; speaker-embedding cosine ≥ 0.9; texture floor Δ ≤ 6 dB; WER on secondary speakers unchangedblocking for any neural passSmule 2025 metrics; measured in practice
Q20half-volume testmix attenuated 12 dB plus a −50 dBFS pink floor: Whisper WER on 10 random 30 s windows ≤ 1.3× the WER at full leveladvisoryByers: "turn it down halfway, can you understand every word?"
Q21level jumps> 5 LU between adjacent voices' momentary max within 1.5 s of a voice-to-voice edit; scene starts exemptadvisoryJND ~1 LU; A/85 ±2 LU
Q22hard stopsmusic / ambience / effects fade-out < 1.5 s while still sounding (programme end exempt)advisoryByers
Q23mix lengthmix = timeline ± 0.05 s; picture later = audio ± 0.05 sblocking
Q24anti-fatigueevery 10-min window has ≥ 2 of {music enters/exits, bed change, live sound, ≥ 90 s music-free}advisoryKwok, Get Back
Q25separated speech keeps the roomresidual stem ≥ −20 dB vs separated speech in every separated spanadvisoryGet Back

Blocking by default in Thresholds: loudness, dead_air, click, masking. Tune per programme; every threshold carries its source in the dataclass.

4. Two rules learned the hard way

Dead air comes from beds shorter than their scenes. Before mixing, check every bed's source length against the span it must cover (loop it, or crossfade a second bed); then run the detector. Designed silences are whitelisted explicitly (a list of (at, dur)); the dead-air check reads the list; nothing else passes.

Only hard edits can click. A cue edge with a fade ≥ 50 ms cannot produce a step discontinuity; a transient found at a faded edge belongs to other content (a consonant, a spot effect, the music) and is not a click. Report clicks only on edges whose fade is < 50 ms, and report the fade length with the finding so the reader can tell the two apart.

5. The transcription check (every cut)

Transcribe each narration cue out of the finished mix (not the source) and compare its first and last six words with the word-timed transcript. Procedure in references/transcription-check.md. Essentials:

  • normalise both sides: lower-case, strip punctuation, drop fillers (um uh er ah hmm mm), drop false starts (tokens ending in -, e.g. "bea-"), collapse stutter repeats (Whisper smooths these; the transcript keeps them; neither is a clipped word);
  • overlapping cross-talk is optional: Whisper drops the other speaker, so build two expectations, all speakers and the main speaker of the cue (most common label), and pass if either matches (diarisation labels are unreliable);
  • difflib.SequenceMatcher ratio on want[:6] vs got[:8] and want[-6:] vs got[-8:]; pass when head ≥ 0.5 and tail ≥ 0.5;
  • check every cue: a 12-cut sample missed "and--" endings a model reviewer heard;
  • for live scenes, check that a handful of key phrases are heard (fuzzy ≥ 0.75).

6. The humans

  • Multi-system: a 90 s excerpt bounced through a phone-speaker EQ (highpass=300, lowpass=6000), a laptop and the living-room TV, at normal volume (Tavella checked The War on six to eight systems down to an 11-inch mono TV).
  • Headphones: three 60 s excerpts (opening, a bed-heavy passage, the ending) on open-back headphones before lock; −40 LUFS beds and spot effects that vanish on a TV are plainly audible there (Mangini, 32 Sounds).
  • Half volume: Byers' test, by ear as well as by Q20.
  • The witnesses sign off: the people who were there decide, on their own system.

7. What the automated gate does not hear

Measured in practice against a model reviewer's 139 relevant notes: the checks caught 38 (dead air 21/31, masking 9/25, level 8/29, abrupt edges 5/47, tone 6/49). The misses were content edits (mid-sentence cuts: covered by the transcription check once it runs on every cue), local rumble (the tonal check compares class averages, not moments), sung vocals under speech (energy-based masking is not vocal-aware) and music chopped mid-phrase with a ≥ 1.5 s fade still present. Keep the transcription check, the model listener (ai-review-of-audio) and the human listens in the gate; the numbers alone pass mixes a professional would not.

Known blind spot: a cue wrongly tagged as non-speech (e.g. a live-music bypass applied to a speech) drops out of the duck sidechain and out of every dialogue check. Assert the count of bypassed cues in the build, and that known speech sources are not among them.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.