Chiron / XTTS voice · fix log · 2026-07-01

Lester Voice — Max Expressiveness,
Not Glitches

The Chiron chalkboard voice was riding XTTS bare defaults. Three render paths, no expressiveness tuning, no text-splitting guard. This is the find, the fix, and the gate it now has to clear.

Code fix: shipped & verified (4 render paths, 1 shared profile) A/B sweep run: 12 clips, glitch-QA 12/12 pass, temp 0.80 locked

1. The ask

“find and fix our lester voice max expressiveness not glitches.”

Lester should sound as alive as possible — melodic, breathing, real intonation — while never tripping the babble-loop / runaway / silence / gibberish failures that xtts-glitch-qa flags. Those two goals pull in opposite directions: expressiveness comes from hotter sampling, glitches come from sampling that runs too hot. The fix is to run hot on the dials that add life and clamp the dials that cause glitches.

2. What was actually wrong

Every Lester render call passed zero generation kwargs, so the voice used whatever XTTS v2 ships as defaults — and, critically, never enabled sentence splitting.

Render pathCall siteProblem
Chalkboard production default
(chiron-matilda + tarot-chapter video)
book-to-video/scripts/
xtts_render.py:51
bare defaults · no enable_text_splitting → long lines can RUNAWAY/OOM
Chiron audio reading batchchiron-audio-reading/scripts/
xtts_batch.py:29
bare defaults · un-tuned prosody
Chiron tarot video batchchiron-tarot-reading-video/scripts/
xtts_batch.py:29
identical copy · bare defaults
The other renderer, xtts_render_committed.py, over-corrected the opposite way (temperature 0.45, top_k 30, top_p 0.80) and came out flat / monotone. Memory already retired it as “the root cause of glitches” and set the rule: if Lester drifts, drop to 0.65, never 0.45. Neither renderer was the expressive middle the user asked for.

3. The fix — one shared expressive profile

New single source of truth: ~/.claude/skills/_shared/xtts_lester_profile.py, imported by all three renderers so the setting can’t drift.

DialCommitted (flat)Bare defaultNew Lester profileWhy
temperature0.45~0.750.80hot end of the safe band → melodic prosody. Above ~0.85 XTTS starts to babble.
repetition_penalty3.0default2.0kills the babble LOOP without the flattening 3.0 gives.
top_k30default50wider sampling → more pitch variety.
top_p0.80default0.85wider nucleus → more expressive contour.
enable_text_splittingFalseunsetTruerenders sentence-by-sentence → no RUNAWAY/OOM on long lines. The structural anti-glitch fix.
length_penalty / speed1.0 / 1.0default1.0 / 1.0neutral pacing; never let short refs warp tempo.

Reference stays the wide-range singer stem lester_vocals_stem.wav (never the narrow v3 clip), 24s window, loudness-normalized — unchanged, per the committed-voice rule.

4. The gate it has to clear

xtts-glitch-qa transcribes each rendered clip with faster-whisper and flags four failure modes. The profile is tuned to stay under every threshold.

GlitchTriggerGuarded by
LOOPsame 3-gram repeats ≥ 4×repetition_penalty 2.0
RUNAWAYdur > max(2.6× expected, +4s)enable_text_splitting = True
SILENT< 0.35s, or 0 words & < 1.2stemperature held ≤ 0.80
GIBBERISHwhisper similarity < 0.45temperature held ≤ 0.80 + top_p 0.85

5. The empirical sweep — 12 clips, one verdict

Same expressive test line rendered under six sampling profiles, every clip transcribed by faster-whisper and run through the glitch gate. All 12 passed with zero flags. The heard-vs-intended transcripts settled the temperature.

ProfileQA flagsWhisper fidelity (per rep)Pitch spread (f0 std)Verdict
committed 0.4500.98058.2 Hzclean but flat, the retired clamp
old default (~0.75)01.00063.7 Hzfine, but un-tuned and no split guard
temp 0.6501.000 · 0.74255.2 Hz avgone rep inserted a phantom phrase
temp 0.80 ★01.000 · 1.000 · 0.99858.8 Hz avg (peak 65.0)perfect words every rep — LOCKED
temp 0.8500.998 · 0.612 · 0.88669.2 Hz avgmost spread, but phantom words in 2/3 reps (“I’m disease.”, grip→“rip”)
temp 0.9500.987 · 1.00054.4 Hz avgclean but LESS expressive — heat stops paying past 0.85
Why 0.80 and not 0.85: the gate passed both, but 0.85 speaks words that are not in the script. A phantom “I’m disease.” in a chalkboard video is a glitch to any listener, whatever the flag count says. 0.80 is the hottest setting with zero audible defects, three reps out of three.

6. Hear it — A/B the same line

One line, four renders. The words: “Look closely at the Wheel. It turns whether you are ready or not…”

RenderListenWhat to hear
Committed 0.45
the retired flat clamp
monotone, even pacing, little pitch movement
Old production default
bare XTTS defaults
livelier, but un-tuned and unguarded
New profile, temp 0.80 ★
the locked setting
full intonation swing, every word exactly on script
Too hot: temp 0.85
why we stopped at 0.80
listen at ~2s: a phantom “I’m disease.” that is not in the script

Full data: 12 wavs + _qa_report.json at ~/Projects/_outputs/xtts-glitch-qa/lester_sweep/. Sweep script: ~/.claude/skills/xtts-glitch-qa/tune_lester_profile.py.

7. Verification ledger

Net effect. Every Lester render — chalkboard videos, chiron audio readings, tarot videos, book videos, and the glitch-QA re-render path — now speaks through one deliberately expressive, glitch-guarded profile instead of un-tuned defaults. The temperature is not a guess: the 12-clip sweep proved 0.80 is the hottest setting that says every word exactly as written.
🛍️ Get the printable