"""Language tables shared by the TTS clients and their UIs.""" from typing import Optional # Languages the Qwen3-TTS demo accepts as display names (its API silently # falls back to "Auto" for anything else, so unknown names are rejected # before a run starts instead of mispronouncing a whole book). Arabic, # Hindi and Vietnamese come from the audio.cpp WebUI language menus # (MagpieTTS / IndexTTS2); on Qwen they degrade to Auto. TTS_LANGUAGES = ( "Auto", "Chinese", "English", "German", "Italian", "Portuguese", "Spanish", "Japanese", "Korean", "French", "Russian", "Arabic", "Hindi", "Vietnamese", ) # Short aliases accepted on the command line (ISO 639-1 codes and common # shorthands), mapped to the display names above. The Arabic regional # variants collapse to plain Arabic. TTS_LANGUAGE_ALIASES = { "zh": "Chinese", "en": "English", "de": "German", "it": "Italian", "pt": "Portuguese", "es": "Spanish", "ja": "Japanese", "ko": "Korean", "fr": "French", "ru": "Russian", "ar": "Arabic", "hi": "Hindi", "vi": "Vietnamese", "zh-cn": "Chinese", "zh-tw": "Chinese", "pt-br": "Portuguese", "en-us": "English", "en-gb": "English", "ar-ae": "Arabic", "ar-msa": "Arabic", "ar-sa": "Arabic", } # Qwen display names -> ISO 639-1 codes, for audio.cpp families whose # language request option takes a code instead of a display name. "Auto" # has no code and maps to None so the field is omitted and the server # applies its own default. LANGUAGE_ISO_CODES = { "Chinese": "zh", "English": "en", "German": "de", "Italian": "it", "Portuguese": "pt", "Spanish": "es", "Japanese": "ja", "Korean": "ko", "French": "fr", "Russian": "ru", "Arabic": "ar", "Hindi": "hi", "Vietnamese": "vi", } # Static selection-list order for the TUI Language menus (Settings and # Generate Audiobooks): the languages of audio.cpp's WebUI language menus # (MagpieTTS + IndexTTS2) plus the shared display names, with common # languages near the top. A static list — new audio.cpp menu languages # need this tuple updated by hand. LANGUAGE_CHOICES = ( "English", "Spanish", "Chinese", "French", "German", "Italian", "Portuguese", "Japanese", "Korean", "Russian", "Arabic", "Hindi", "Vietnamese", "Auto", ) def normalize_language(value: Optional[str]) -> str: """Normalize a user-provided language name to a Qwen3-TTS display name. Accepts the display names in TTS_LANGUAGES case-insensitively as well as the short aliases in TTS_LANGUAGE_ALIASES (ISO 639-1 codes and common shorthands). Raises ValueError for anything else, since the Qwen3-TTS demo silently falls back to "Auto" for unrecognized languages. """ if value is None: raise ValueError("Language must not be None") candidate = value.strip() if not candidate: raise ValueError("Language must not be empty") for name in TTS_LANGUAGES: if candidate.lower() == name.lower(): return name alias = TTS_LANGUAGE_ALIASES.get(candidate.lower()) if alias: return alias raise ValueError( f"Unknown language: {value!r}. Expected one of " f"{', '.join(TTS_LANGUAGES)} (or an alias: " f"{', '.join(sorted(TTS_LANGUAGE_ALIASES))})." )