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:
@@ -59,12 +59,23 @@ function speakWebSpeech(text: string, lang: string): void {
|
|||||||
synth.speak(utterance)
|
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
|
// 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);
|
// don't queue up. `lang` defaults to a guess from the text (Chinese vs English)
|
||||||
// pass a zh locale to hear a Chinese passage. It tries the server's neural voice
|
// so callers can just pass the selection; pass an explicit locale to override.
|
||||||
// first and silently falls back to the browser voice if that's unavailable (route
|
// It tries the server's neural voice first and silently falls back to the browser
|
||||||
// off, network error, or a 404 for a language with no configured voice).
|
// voice if that's unavailable (route off, network error, or a 404 for a language
|
||||||
export function speak(text: string, lang = 'en-US'): void {
|
// with no configured voice).
|
||||||
|
export function speak(text: string, lang = detectLang(text)): void {
|
||||||
if (!text.trim()) return
|
if (!text.trim()) return
|
||||||
stopCurrent()
|
stopCurrent()
|
||||||
const seq = ++requestSeq
|
const seq = ++requestSeq
|
||||||
|
|||||||
Reference in New Issue
Block a user