Reject silent clones, normalize level, cap short token budget - #15
Conversation
…vel, cap short token budget The mouth can spend 30s then return 0.03s of silence, or a quiet clone. After Clean, Silent retries once then errors. Normalize brings peaks up to -6 dBFS. Short lines request 80 tokens min, not 180, so a missed end-of-speech cannot burn a 17s budget.
obey-agent
left a comment
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES
Head: 1241bfe · PR goal: Reject near-silent clones, peak-normalize quiet ones to −6 dBFS, shrink short-line token floor (80).
Blocking (must fix before merge)
- [order] PR body says Clean → Normalize → Silent/retry. Code does Clean → Silent → retry → Normalize. A quiet-but-real clone (e.g. 200 ms, peak 0.015) hits
peak < 0.02, retries, and can returnsay: silent mouthwithout ever being normalized — so the “quieter than ref” fix does not run for the band Normalize was meant to save. Near-silent 0.03 s shorts are correctly caught by the duration check either way.- Fix: Normalize first, then Silent (duration or still-near-zero after gain); retry only if still silent. Add a test: long low-peak audio becomes non-silent after Normalize and must not error.
Non-blocking residuals
- [budget] Token floor 80 / cap 360 /
20*words+40matches the claim; missed EOS is cheaper, not gone (as documented). - [seam]
CANS_SAY_BINpath still bypasses Session guards (test-only).
What I checked
session.SayTopost-Clean path;Silent/Normalizeconstants and tests;tokenBudgetchange; fakeworkersilent+ sine fixtures;TestSessionSilentMouth;CANS_NOPLAY=1 go test ./internal/audio ./internal/tts; CI green
What I did not check
- Live mouth rates of quiet-vs-silent clones; whether 0.02 peak is the right threshold after a correct Normalize-first order
…ilent Quiet-but-real clones (peak 0.015, 200 ms) were rejected as silent mouth before Normalize could raise them to -6 dBFS. Clean, then Normalize, then Silent; retry only if still silent.
|
Review order fix: Clean → Normalize → Silent. Quiet-but-real clones (200 ms, peak 0.015) now get gained before the silent check. TestSilentLowPeakRescuedByNormalize covers it. |
obey-agent
left a comment
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES
Head: 627da8c · PR goal: Reject near-silent clones, peak-normalize quiet ones to −6 dBFS after Clean, shrink short-line token floor to 80.
Blocking (must fix before merge)
- [greenwash / Clean×Silent] Prior CR order fix is in
SayTo(Clean → Normalize → Silent on both attempts). The new proof does not hold on that path.TestSilentLowPeakRescuedByNormalizeasserts a 200 ms peak-0.015 clone is rescued by Normalize and its comment claimsSayTotherefore keeps it. RealSayTorunsCleanfirst;trimSilenceusestrimAmp == 0.02(same assilentPeak), so uniform peak-0.015 audio is collapsed to the 30 ms pad remnant before Normalize. After Normalize the clip is still Silent on duration (30 < 80). Reproduced locally:Clean→Normalize→Silenton 200 ms / 0.015 →len=720(30 ms) →Silent=true- Existing unit test skips
Cleanand stays green - No Session/fakeworker fixture exercises a quiet-but-real clone end-to-end
- Fix: either (a) make Normalize useful for the band you document (e.g. Normalize before trim, or lower
trimAmprelative to the rescue band), and replace the unit test withClean→Normalize→Silent(or a Session test with a quiet fakeworker emission) that fails on main and passes on the fix; or (b) drop the false “SayTo saves peak 0.015” claim and test the band that actually survives Clean (peak ≥trimAmp, still quieter than −6 dBFS). Do not merge a proof that contradicts the pipeline.
Non-blocking residuals
- [budget]
20*words+40, floor 80, cap 360 matches the PR body; missed EOS is cheaper, not gone. - [seam]
CANS_SAY_BINstill bypasses Session guards (test/override seam).
What I checked
- Re-reviewed prior CR on
1241bfe: order was Clean → Silent → Normalize; tip627da8creorders both attempt paths to Clean → Normalize → Silent internal/tts/session.goSayTo;audio.Clean/trimSilence(trimAmp=0.02,padMs=30);Normalize;Silent;tokenBudget; fakeworkersilent+emitSine;TestSessionSilentMouth;TestSilentLowPeakRescuedByNormalizecomment vs body- Local attack: ephemeral
Clean→Normalize→Silenttest for the documented 200 ms / 0.015 case — fails; stockCANS_NOPLAY=1 go test ./...green; CItestsuccess on this head - Prior blocker “wrong order in SayTo” is fixed in code; the accompanying proof is not
What I did not check
- Live mouth quiet-vs-silent clone rates; whether 0.02 is the right product threshold after a correct Clean/Normalize relationship
Quiet clones (200 ms, peak 0.015) were trimmed to the 30 ms pad before Normalize could rescue them. Clean now peak-normalizes above the noise floor, then trims. Near-zero glitches stay silent. SayTo is Clean then Silent. Proof is Clean×Silent plus a quiet fakeworker session path.
9b2bc53 to
74150ed
Compare
|
Clean now peak-normalizes above a 0.001 noise floor before trim, so the documented 200 ms / 0.015 clone is no longer collapsed to the 30 ms pad.
Head: |
obey-agent
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Head: 74150ed · PR goal: Reject near-silent clones, peak-normalize quiet speech so it survives Clean trim, shrink short-line token floor to 80.
Blocking (must fix before merge)
none
Non-blocking residuals
- [seam]
CANS_SAY_BINstill bypasses Session Clean/Silent guards (test/override path). - [boundary]
normalizeIfRealusespeak <= noiseFloorafter highpass/shelf; filter overshoot can lift some near-floor signals into the rescue band. Product glitches called out in the PR are near-zero / sub-80ms and still failTestCleanSilentStaysSilent/ duration.
What I checked
- Prior CR on
627da8c: Clean trimmed peak-0.015 to 30ms before Normalize — blocker - Tip moves Normalize into
CleanvianormalizeIfReal(noiseFloor 0.001 → peak 0.5) beforetrimSilence;SayTois Clean → Silent → one retry TestCleanRescuesLowPeakSpeech,TestCleanSilentStaysSilent,TestSessionQuietMouthRescued(fakeworkerquiet= 200ms/0.015);TestSessionSilentMouth;tokenBudgetfloor 80- Local
CANS_NOPLAY=1 go test ./...green; CItestSUCCESS on this head - PR body claims vs
clean.go/session.go/ fakeworker — match
What I did not check
- Live mouth quiet-vs-silent clone rates on real hardware; whether 0.001/0.02 are optimal production thresholds
The native mouth has three known faults that v2 did not invent and did not hide:
This is the Go-side guard. Clone temperature stays 0.2 (the hiss fix). The worker overlay is unchanged.
What changed
max_tokens = 20*words + 40, floored at 80 (was 180), capped at 360.audio.Cleanhigh-passes rumble, shelves vocoder hiss, peak-normalizes to −6 dBFS when the peak is above a 0.001 noise floor, then trims and fades. Quiet-but-real speech (e.g. 200 ms, peak 0.015) survives trim. Near-zero glitches stay near-zero and collapse to the 30 ms pad.say: silent mouth.silentis the silent-success fixture; textquietis a 200 ms peak-0.015 clone that must be kept.Verification
CANS_NOPLAY=1 go test ./...greengofmt -l .empty,go vet ./...cleanTestCleanRescuesLowPeakSpeech,TestCleanSilentStaysSilent,TestSessionQuietMouthRescuedNot in this PR