From 2e2e014048921e9b5e93f219eb8fe45101b84c92 Mon Sep 17 00:00:00 2001 From: udaykumarreddykasaram07-eng Date: Sun, 12 Apr 2026 11:27:34 +0530 Subject: [PATCH 1/2] fix: replace invalid SVG with working activity icon (closes #2) PR #24 contained an invalid SVG that GitHub cannot render. This provides a valid, properly structured SVG icon that: - Renders correctly in all SVG viewers - Uses Sugar orange color palette - Adds AI speech bubble to distinguish from original Speak - Adds sound waves to represent TTS voice synthesis Closes #2 --- activity/activity-speak-ai.svg | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 activity/activity-speak-ai.svg diff --git a/activity/activity-speak-ai.svg b/activity/activity-speak-ai.svg new file mode 100644 index 0000000..a9e233c --- /dev/null +++ b/activity/activity-speak-ai.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 9a8026f021d4987228181d1c8d1bc686ff412ffe Mon Sep 17 00:00:00 2001 From: udaykumarreddykasaram07-eng Date: Sun, 12 Apr 2026 23:06:56 +0530 Subject: [PATCH 2/2] feat: add language fallback handler for Kokoro TTS Adds utils/language_fallback.py with: - resolve_lang_code(): maps ISO codes, names, or Kokoro codes to valid Kokoro lang_codes with graceful English fallback - get_supported_languages(): returns all supported languages - is_non_latin_script(): flags languages needing G2P preprocessing (Hindi, Japanese, Chinese) before passing to KPipeline Prevents silent crashes when unsupported language codes are passed to KPipeline. Adds proper logging when fallback occurs. Relates to GSoC 2026 Speak-AI Multilingual Support proposal. --- utils/__init__.py | 0 utils/language_fallback.py | 106 +++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 utils/__init__.py create mode 100644 utils/language_fallback.py diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/language_fallback.py b/utils/language_fallback.py new file mode 100644 index 0000000..607f3ee --- /dev/null +++ b/utils/language_fallback.py @@ -0,0 +1,106 @@ +""" +Language fallback handler for Speak-AI Kokoro TTS pipeline. + +When a requested language is not supported by Kokoro, this module +handles graceful fallback with user-friendly logging. + +Author: Uday Kumar Reddy +GSoC 2026 - Speak-AI Multilingual Support +""" + +import logging + +logger = logging.getLogger(__name__) + +# Kokoro's officially supported lang_codes as of v0.9.4 +KOKORO_SUPPORTED = { + 'a': 'English (American)', + 'b': 'English (British)', + 'e': 'Spanish', + 'f': 'French', + 'h': 'Hindi', + 'i': 'Italian', + 'j': 'Japanese', + 'p': 'Portuguese (Brazilian)', + 'z': 'Chinese (Mandarin)', +} + +# ISO 639-1 codes → Kokoro lang_codes +ISO_TO_KOKORO = { + 'en': 'a', + 'en-gb': 'b', + 'es': 'e', + 'fr': 'f', + 'hi': 'h', + 'it': 'i', + 'ja': 'j', + 'pt': 'p', + 'pt-br': 'p', + 'zh': 'z', + 'zh-cn': 'z', +} + +DEFAULT_LANG = 'a' # English fallback + + +def resolve_lang_code(requested: str) -> tuple[str, bool]: + """ + Resolve a language code to a Kokoro-supported lang_code. + + Args: + requested: ISO 639-1 code (e.g. 'hi', 'fr') or + Kokoro code (e.g. 'h', 'f') or + language name (e.g. 'hindi', 'french') + + Returns: + Tuple of (resolved_lang_code, is_native_support) + is_native_support is False when falling back to English + """ + req = requested.lower().strip() + + # Already a valid Kokoro code + if req in KOKORO_SUPPORTED: + return req, True + + # ISO 639-1 code + if req in ISO_TO_KOKORO: + return ISO_TO_KOKORO[req], True + + # Language name fallback + name_map = {v.lower().split(' ')[0]: k + for k, v in KOKORO_SUPPORTED.items()} + if req in name_map: + return name_map[req], True + + # Not supported — fallback to English + logger.warning( + f"Language '{requested}' is not supported by Kokoro TTS. " + f"Falling back to English. " + f"Supported languages: {list(KOKORO_SUPPORTED.values())}" + ) + return DEFAULT_LANG, False + + +def get_supported_languages() -> dict: + """ + Return all languages supported by Kokoro TTS. + + Returns: + Dict mapping Kokoro lang_code to language name + """ + return KOKORO_SUPPORTED.copy() + + +def is_non_latin_script(lang_code: str) -> bool: + """ + Check if a language uses a non-Latin script. + These languages need G2P preprocessing before Kokoro. + + Args: + lang_code: Kokoro lang_code + + Returns: + True if language needs special script handling + """ + NON_LATIN = {'h', 'j', 'z'} # Hindi, Japanese, Chinese + return lang_code in NON_LATIN \ No newline at end of file