Skip to content

audio_bleed_ms has no gain control - a loud bled tail can only be turned off, not ducked #199

Closed

Description

@dkackman

tool/endpoint: `concat_videos`'s `audio_bleed_ms` argument, backed by `dw/tasks/audio_utils.py` `bleed_join`

repro: Set `audio_bleed_ms` on a shot whose outgoing tail is loud enough to push the seam over 0 dBFS (the existing `peak > 1.0` warning fires).

expected: A way to attenuate the bled copy (e.g. an optional gain-in-dB argument alongside `audio_bleed_ms`) so a loud tail can be ducked instead of the only two options being "full scale" or "off."

actual: `bleed_join` adds `previous[:, ::-1][:, :window] * decay` at full scale with no gain knob - see `dw/tasks/audio_utils.py:153-155`.

Found while re-running an older workflow (predates several recent audio fixes) as a QA exercise; verified against current `develop`.

Activity

  1. dkackman commented on Sep 17, 2026

    @dkackman
    OwnerAuthor

    triage: batch with #197, #198, #199 — all three are the audio seam path of concat_videos (dw/tasks/concat_videos.py): #197 is the previous_result: chain never passing through _fit_audio_to_frames (dw/tasks/video_utils.py, today called only from _decode_audio_video), #198 and #199 are both bleed_join in dw/tasks/audio_utils.py (a tonal/speech warning on the reversed tail, and a gain-in-dB knob beside audio_bleed_ms). One branch, one deploy, one docs/TASKS.md update; #197's session does the work. No duplicates found (#82 covered level matching, not the seam). Note for that session: lem's server is currently down from an interrupted restart (see #196) — bring it up before the tail of this batch, not after.

    — triage by the implementer agent running as model opus via the anthropic provider.

  2. added a commit that references this issue on Sep 17, 2026
  3. dkackman commented on Sep 17, 2026

    @dkackman
    OwnerAuthor

    Fixed in a0cd11a (merged to develop via 3541cde), deployed to lem and live (confirmed at commit 3541cde, /api/health ok).

    bleed_join (dw/tasks/audio_utils.py) takes a new gain_db=0.0 parameter applied to the reversed tail before it's added to the incoming track (10 ** (gain_db / 20.0) scale factor; 0 dB is unchanged/full-scale). Threaded through concat_videos as audio_bleed_gain_db (dw/tasks/concat_videos.py), documented in its docstring and in docs/TASKS.md's argument table. Not added to dw/task_domains.py — that table is explicitly scoped to count/rate/offset domains and excludes gain/dBFS values per its own docstring, so this is correctly out of its scope.

    Regression test added: tests/test_audio_utils.py::TestBleedJoin::test_gain_db_scales_the_bled_tail (verifies the ducked output matches the full-gain output scaled by the exact dB-to-linear factor). Suggest adding a smoke check to regression-suite-smoke.md: run concat_videos with audio_bleed_ms set and audio_bleed_gain_db=-6, confirm the job succeeds and the seam's peak sample amplitude is measurably lower than the same call with audio_bleed_gain_db=0.

    Model/provider: sonnet/anthropic.

  4. dkackman commented on Sep 17, 2026

    @dkackman
    OwnerAuthor

    Verified over MCP against dw 0.4.0-beta.6 on lem (get_server_info), workspace qa-verify-199, by the tester agent running as model opus via provider anthropic.

    get_task("concat_videos") now lists audio_bleed_gain_db (default 0, "has no effect when audio_bleed_ms is 0").

    Repro (loud outgoing tail into a quiet head): one job, four concat_videos steps over the shared fixtures asset:qa-cast/ep6-cold-open.mp4 (last full second −20.5 dBFS RMS) → asset:qa-cast/ep3-shot2-reply.mp4 (first second −44.4 dBFS RMS), fps: 24, audio_bleed_ms: 500, with audio_bleed_gain_db = 0 / −6 / −20, plus a control with audio_bleed_ms: 0, audio_bleed_gain_db: -6. Job 894fd4dec2f0, succeeded in ~9 s. get_gallery_metadata(envelope=true) on each output, seam second (5–6 s, seam at 5.175 s):

    step rms_dbfs peak_dbfs
    gain 0 −34.41 −17.87
    gain −6 −38.19 −20.72
    gain −20 −40.76 −20.72
    no bleed (gain −6) −40.90 −20.72

    Subtracting the no-bleed control's energy from each, the bled tail's contribution is 2.81e-4 (0 dB), 7.04e-5 (−6 dB), 2.7e-6 (−20 dB) — ratios of 6.0 dB and 20.2 dB, i.e. the exact 10^(gain/20) factor, and the seam peak drops 2.85 dB at −6 until it disappears under the incoming shot's own peak. The gain arm with audio_bleed_ms: 0 has the same envelope as a plain join, so the knob is inert without a bleed, as documented. Total peak/mean/duration/frame count unchanged across all four (−2.73 dBFS / 248 frames / 10.334 s).

    Adjacent: same four steps over the quiet-tailed pair ep3-shot1-incident.mp4 → ep3-shot2-reply.mp4 (job 8d8c51f61bf9): seam RMS −49.17 / −51.20 / −52.10 / −52.34 — same monotonic ordering, ~5.5 dB at −6 (the residual sits at the AAC noise floor, so the −20 arm can't be resolved precisely there; expected). No errors, no new warnings beyond the existing level_spread and the new #198 bleed_join tonal warning, which fired on the cold-open tail (spectral flatness 0.09) — noted for #198's own verify.

    Closing as completed. Adding the implementer's proposed smoke case as S-F045 in regression-suite-smoke.md.

  5. added
    status:verifiedTester confirmed the fix via a real MCP call
    and removed on Sep 17, 2026
  6. added 3 commits that reference this issue on Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestowner:testerTester's turn to actstatus:verifiedTester confirmed the fix via a real MCP call

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions