diff --git a/public/src/tts.js b/public/src/tts.js index 00dfa15..f6217ca 100644 --- a/public/src/tts.js +++ b/public/src/tts.js @@ -67,11 +67,13 @@ const AUDIO_FORMAT = detectAudioFormat(); const ttsCache = new Map(); // Split long text into chunks at sentence boundaries. -// F5-TTS has no input cap, but smaller chunks shorten time-to-first-audio: -// chunk 1 is intentionally small (~500 chars ~ 5s wall) so playback starts ASAP, -// later chunks fetch in pipeline while chunk 1 plays. -const TTS_CHUNK_MAX = 2500; // upper bound per chunk (server-side comfortable) -const TTS_FIRST_CHUNK_MAX = 500; // smaller first chunk for low time-to-first-audio +// IMPORTANT: F5-TTS internally chunks any input above ~135 chars (its default +// max_chars) and prepends the reference audio to each sub-chunk's output, +// causing audible "phantom" phrases (e.g. ref text "IT IS NEVER OPENED" bleeds +// in). Capping at 120 chars per request keeps F5 in single-chunk mode = clean +// audio. With PlaylistAudio pipelining, more+smaller chunks also lower TTFA. +const TTS_CHUNK_MAX = 120; // upper bound per chunk (under F5's internal 135 threshold) +const TTS_FIRST_CHUNK_MAX = 120; // first chunk same — there's no win in making it smaller // Strip patterns F5 would pronounce character-by-character (URLs, paths, emails). // F5 has no spell-vs-speak heuristic — feeding it https://foo.bar produces audible