aboutsummaryrefslogtreecommitdiff
path: root/app/converter/converter.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/converter/converter.py')
-rw-r--r--app/converter/converter.py36
1 files changed, 25 insertions, 11 deletions
diff --git a/app/converter/converter.py b/app/converter/converter.py
index 2b849a2..f8815d8 100644
--- a/app/converter/converter.py
+++ b/app/converter/converter.py
@@ -251,11 +251,11 @@ def chunk_clamp_needed(entry) -> bool:
def chunk_clamp_message(entry) -> List[str]:
"""The popup text for a chunk_words-capped ENTRY (short lines)."""
return [
- f"{entry.label} can narrate at most ~{entry.chunk_words} words "
- "per request: the server caps",
- "each request's prompt plus generation at a fixed window. "
- "Longer sub-chunks",
- "may cut off mid-sentence.",
+ f"{entry.label} narrates best at ~{entry.chunk_words} words "
+ "per request on this server:",
+ "each request's prompt plus generation must fit a fixed "
+ "window, so longer",
+ "sub-chunks may cut off mid-sentence.",
]
@@ -305,6 +305,9 @@ class AudiobookConverter:
# Class-level default so a partially-constructed instance (tests build
# these with __new__) behaves like a plain console run.
_progress = None
+ # Same for the per-run chunk override: without __init__ there is no
+ # clamp, so chunking follows the config.CHUNK_SIZE setting.
+ chunk_size = None
def __init__(self, voice_mode: str = VOICE_MODE_CUSTOM, voice_clone_ref_audio: Optional[str] = None,
voice_clone_ref_text: Optional[str] = None, skip_transcription: bool = False,
@@ -340,6 +343,12 @@ class AudiobookConverter:
self.backend = backend
self.voice = voice
self.debug = bool(debug)
+ # Per-run chunk-word override (the pre-flight popup's clamp for
+ # models whose engine caps one request below a full sub-chunk,
+ # SGLang-Omni's Higgs): caps the chapter chunks themselves so
+ # progress and debug dumps span one generation request each.
+ # None follows the config.CHUNK_SIZE setting.
+ self.chunk_size = chunk_size
# The run's model selection (audio.cpp: a server entry id, sglomni:
# the resolved catalog key, None elsewhere) — the startup banner
# reports it.
@@ -404,10 +413,9 @@ class AudiobookConverter:
"catalog key for --model (see the backend docs).")
model_id = entry.key
self.model_id = model_id
- # CHUNK_SIZE carries a per-run override (the pre-flight chunk
- # popup's clamp for models whose engine caps one request below
- # a full sub-chunk); None follows the config.CHUNK_SIZE setting.
- self.chunk_size = chunk_size
+ # The catalog/request shape is resolved below; the per-run
+ # chunk override (self.chunk_size) was recorded above and
+ # reaches the client here.
self.tts = SgOmniTTSClient(
chunks_dir=CHUNKS_FOLDER, model=model_id, voice=voice,
ref_audio=voice_clone_ref_audio,
@@ -839,8 +847,14 @@ class AudiobookConverter:
return results
def _chapter_chunks(self, text: str) -> List[str]:
- """Split chapter text into CHUNK_SIZE-word TTS requests."""
- return chunking.split_into_chunks(text)
+ """Split chapter text into word-capped TTS request chunks.
+
+ Each chunk is one progress unit; when the pre-flight popup set
+ a per-run clamp (models whose engine caps one request below
+ CHUNK_SIZE), it caps these chunks too so a chunk is never
+ wider than one generation request.
+ """
+ return chunking.split_into_chunks(text, max_words=self.chunk_size)
def _convert_text(self, text: str, output_path: Path, start_time: float,
speed: Optional[float] = None,