diff --git a/engines/kokoro/server.py b/engines/kokoro/server.py index 169cbbd..b0a6f9d 100644 --- a/engines/kokoro/server.py +++ b/engines/kokoro/server.py @@ -113,12 +113,23 @@ def _parse_tag(match: re.Match) -> float: return dur / 1000.0 if unit == "ms" else dur +# [HACK — engine/kokoro] Kokoro-82M has weak question prosody on a +# single `?`. Doubling the question mark to `??` reliably triggers a +# more interrogative rising-pitch contour without changing semantics. +# Skip if already doubled or part of an interrobang. See hacks.md. +_QUESTION_RE = re.compile(r"(? str: + return _QUESTION_RE.sub("??", text) + + def _expand_inline(text: str, voice: str | None) -> list[Node]: """Expand inline [breath]/[pause]/[scene] tags inside a chunk of text that already has a single voice attribution. Voice blocks themselves are handled one level up in split_to_nodes.""" out: list[Node] = [] - text = text.strip() + text = _emphasize_questions(text.strip()) if not text: return out cursor = 0