TTS: auto-detect Chinese vs English so callers can pass the selection

speak()'s lang now defaults to detectLang(text) (any Han/kana -> zh-CN,
else en-US) instead of always en-US, so reading a Chinese passage picks the
Piper zh voice rather than spelling out characters with the English voice.
Explicit lang still overrides.

Claude-Session: https://claude.ai/code/session_016Yr6jELuRc7hyzYLccQKZd
This commit is contained in:
prosolis
2026-06-26 15:10:36 -07:00
parent 9576340391
commit 631279bd3a

View File

@@ -59,12 +59,23 @@ function speakWebSpeech(text: string, lang: string): void {
synth.speak(utterance)
}
// detectLang guesses a BCP-47 locale from the text so the right Piper voice is
// chosen. Any Han/kana character routes to Chinese (zh-CN) — a selection is
// essentially never mixed at the level that matters, and reading a Chinese
// passage with the English voice spells each character out ("Chinese letter…").
// Everything else defaults to US English, the language she's learning.
const CJK = /[぀-ヿ㐀-䶿一-鿿豈-﫿ヲ-゚]/
export function detectLang(text: string): string {
return CJK.test(text) ? 'zh-CN' : 'en-US'
}
// speak reads `text` aloud, cancelling anything already in flight so rapid taps
// don't queue up. `lang` defaults to US English (the language she's learning);
// pass a zh locale to hear a Chinese passage. It tries the server's neural voice
// first and silently falls back to the browser voice if that's unavailable (route
// off, network error, or a 404 for a language with no configured voice).
export function speak(text: string, lang = 'en-US'): void {
// don't queue up. `lang` defaults to a guess from the text (Chinese vs English)
// so callers can just pass the selection; pass an explicit locale to override.
// It tries the server's neural voice first and silently falls back to the browser
// voice if that's unavailable (route off, network error, or a 404 for a language
// with no configured voice).
export function speak(text: string, lang = detectLang(text)): void {
if (!text.trim()) return
stopCurrent()
const seq = ++requestSeq