Make voice_tool dependency-free and add voice alias mappings for macOS vs Kokoro names

This commit is contained in:
Adolfo Reyna
2026-08-07 20:20:36 -04:00
parent 5b1aad3fa3
commit 469d372338
+34 -10
View File
@@ -4,8 +4,13 @@ Supports both Kokoro TTS voices and macOS System voices, persisting user voice p
"""
import json
import logging
from pathlib import Path
from loguru import logger
try:
from loguru import logger
except ImportError:
logger = logging.getLogger("voice_manager")
# Supported Kokoro TTS voices categorized by style
KOKORO_VOICES = {
@@ -32,6 +37,19 @@ MACOS_VOICES = {
"Alex": "US Male",
}
VOICE_ALIASES = {
"daniel": "bm_george", # British Male
"moira": "bf_emma", # British Female
"samantha": "af_bella", # US Female
"alex": "am_michael", # US Male
"karen": "bf_isabella", # AU/UK Female
"michael": "am_michael",
"bella": "af_bella",
"heart": "af_heart",
"fenrir": "am_fenrir",
"adam": "am_adam",
}
class VoiceManager:
"""Manages active voice settings and dynamic voice switching."""
@@ -78,21 +96,27 @@ class VoiceManager:
voice_name = voice_name.strip()
matched_voice = None
# Exact match or fuzzy match
for v in {**KOKORO_VOICES, **MACOS_VOICES}:
if voice_name.lower() == v.lower():
matched_voice = v
break
# Check voice aliases first (e.g. Daniel -> bm_george)
clean_name = voice_name.lower()
if clean_name in VOICE_ALIASES:
matched_voice = VOICE_ALIASES[clean_name]
# Exact match or fuzzy match
if not matched_voice:
# Partial match search
for v in {**KOKORO_VOICES, **MACOS_VOICES}:
if voice_name.lower() in v.lower():
for v in KOKORO_VOICES:
if clean_name == v.lower():
matched_voice = v
break
if not matched_voice:
available = ", ".join(list(KOKORO_VOICES.keys()) + list(MACOS_VOICES.keys()))
# Partial match search
for v in KOKORO_VOICES:
if clean_name in v.lower():
matched_voice = v
break
if not matched_voice:
available = ", ".join(list(KOKORO_VOICES.keys()))
return False, f"Voice '{voice_name}' not found. Available voices: {available}"
self._active_voice = matched_voice