diff --git a/AVAILABLE_VOICES.md b/AVAILABLE_VOICES.md new file mode 100644 index 0000000..8310e57 --- /dev/null +++ b/AVAILABLE_VOICES.md @@ -0,0 +1,157 @@ +# Available Kokoro TTS Voices + +Kokoro-82M has **54 voices** available across multiple languages! + +## Voice Naming Convention +- **First letter**: Language code + - `a` = American English + - `b` = British English + - `e` = Spanish (español) + - `f` = French + - `h` = Hindi + - `i` = Italian + - `j` = Japanese + - `p` = Portuguese + - `z` = Chinese (Mandarin) +- **Second letter**: Gender + - `f` = Female + - `m` = Male +- **Rest**: Voice name/identifier + +## American English (a) - 21 voices + +### Female (af_*) +- `af_alloy` - Alloy +- `af_aoede` - Aoede +- `af_bella` - Bella ✓ (currently in app) +- `af_heart` - Heart +- `af_jessica` - Jessica +- `af_kore` - Kore +- `af_nicole` - Nicole +- `af_nova` - Nova +- `af_river` - River +- `af_sarah` - Sarah ✓ (currently in app) +- `af_sky` - Sky + +### Male (am_*) +- `am_adam` - Adam ✓ (currently in app) +- `am_echo` - Echo +- `am_eric` - Eric +- `am_fenrir` - Fenrir +- `am_liam` - Liam +- `am_michael` - Michael ✓ (currently in app) +- `am_onyx` - Onyx +- `am_puck` - Puck +- `am_santa` - Santa + +## British English (b) - 8 voices + +### Female (bf_*) +- `bf_alice` - Alice +- `bf_emma` - Emma ✓ (currently in app) +- `bf_isabella` - Isabella ✓ (currently in app) +- `bf_lily` - Lily + +### Male (bm_*) +- `bm_daniel` - Daniel +- `bm_fable` - Fable +- `bm_george` - George ✓ (currently in app) +- `bm_lewis` - Lewis ✓ (currently in app) + +## Spanish (e) - 3 voices + +### Female (ef_*) +- `ef_dora` - Dora + +### Male (em_*) +- `em_alex` - Alex +- `em_santa` - Santa + +## French (f) - 1 voice + +### Female (ff_*) +- `ff_siwis` - Siwis + +## Hindi (h) - 4 voices + +### Female (hf_*) +- `hf_alpha` - Alpha +- `hf_beta` - Beta + +### Male (hm_*) +- `hm_omega` - Omega +- `hm_psi` - Psi + +## Italian (i) - 2 voices + +### Female (if_*) +- `if_sara` - Sara + +### Male (im_*) +- `im_nicola` - Nicola + +## Japanese (j) - 5 voices + +### Female (jf_*) +- `jf_alpha` - Alpha +- `jf_gongitsune` - Gongitsune +- `jf_nezumi` - Nezumi +- `jf_tebukuro` - Tebukuro + +### Male (jm_*) +- `jm_kumo` - Kumo + +## Portuguese (p) - 3 voices + +### Female (pf_*) +- `pf_dora` - Dora + +### Male (pm_*) +- `pm_alex` - Alex +- `pm_santa` - Santa + +## Chinese/Mandarin (z) - 7 voices + +### Female (zf_*) +- `zf_xiaobei` - Xiaobei +- `zf_xiaoni` - Xiaoni +- `zf_xiaoxiao` - Xiaoxiao +- `zf_xiaoyi` - Xiaoyi + +### Male (zm_*) +- `zm_yunjian` - Yunjian +- `zm_yunxi` - Yunxi +- `zm_yunxia` - Yunxia +- `zm_yunyang` - Yunyang + +## Summary + +| Language | Female Voices | Male Voices | Total | +|----------|--------------|-------------|-------| +| American English | 11 | 10 | 21 | +| British English | 4 | 4 | 8 | +| Spanish | 1 | 2 | 3 | +| French | 1 | 0 | 1 | +| Hindi | 2 | 2 | 4 | +| Italian | 1 | 1 | 2 | +| Japanese | 4 | 1 | 5 | +| Portuguese | 1 | 2 | 3 | +| Chinese | 4 | 4 | 8 | +| **TOTAL** | **29** | **26** | **55** | + +## Currently Configured (8 voices) + +The app currently uses only 8 voices: +- ✓ af_bella, af_sarah (American Female) +- ✓ am_adam, am_michael (American Male) +- ✓ bf_emma, bf_isabella (British Female) +- ✓ bm_george, bm_lewis (British Male) + +## Recommendation + +You could expand the voice options to include: +1. **More variety in American English** (11 female + 10 male available!) +2. **Additional languages** (Spanish, French, Italian, Japanese, Portuguese, Chinese, Hindi) +3. **More character variety** (different voice characteristics) + +Would you like me to update the frontend to include more voices? diff --git a/backend/main.py b/backend/main.py index bc1c11a..21a6bb9 100644 --- a/backend/main.py +++ b/backend/main.py @@ -165,7 +165,7 @@ async def generate_audiobook(request: TTSRequest): ) # Validate language code - supported_langs = ['a', 'b', 'f', 'j'] + supported_langs = ['a', 'b', 'e', 'f', 'h', 'i', 'j', 'p', 'z'] if request.lang not in supported_langs: logger.error(f"Invalid language code: {request.lang}") return JSONResponse( diff --git a/backend/services/tts_service.py b/backend/services/tts_service.py index 527067c..057f1b7 100644 --- a/backend/services/tts_service.py +++ b/backend/services/tts_service.py @@ -43,7 +43,7 @@ class TTSService: Caches pipelines to avoid reloading. Args: - lang_code: Language code (a, b, f, j) + lang_code: Language code (a, b, e, f, h, i, j, p, z) Returns: KPipeline instance for the language @@ -51,7 +51,7 @@ class TTSService: Raises: ValueError: If language code is not supported """ - supported_langs = ['a', 'b', 'f', 'j'] + supported_langs = ['a', 'b', 'e', 'f', 'h', 'i', 'j', 'p', 'z'] if lang_code not in supported_langs: raise ValueError( f"Unsupported language code: {lang_code}. " diff --git a/frontend/src/components/VoiceAssignmentSection.tsx b/frontend/src/components/VoiceAssignmentSection.tsx index 329ab93..d75b710 100644 --- a/frontend/src/components/VoiceAssignmentSection.tsx +++ b/frontend/src/components/VoiceAssignmentSection.tsx @@ -25,24 +25,108 @@ interface LanguageOption { label: string; } -// Kokoro voice options as defined in the design document +// All available Kokoro voice options (54 voices across 9 languages) const KOKORO_VOICES: VoiceOption[] = [ + // American English - Female (11 voices) + { id: 'af_alloy', label: 'Alloy (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_aoede', label: 'Aoede (Female, American)', gender: 'female', accent: 'American' }, { id: 'af_bella', label: 'Bella (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_heart', label: 'Heart (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_jessica', label: 'Jessica (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_kore', label: 'Kore (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_nicole', label: 'Nicole (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_nova', label: 'Nova (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_river', label: 'River (Female, American)', gender: 'female', accent: 'American' }, { id: 'af_sarah', label: 'Sarah (Female, American)', gender: 'female', accent: 'American' }, + { id: 'af_sky', label: 'Sky (Female, American)', gender: 'female', accent: 'American' }, + + // American English - Male (10 voices) { id: 'am_adam', label: 'Adam (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_echo', label: 'Echo (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_eric', label: 'Eric (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_fenrir', label: 'Fenrir (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_liam', label: 'Liam (Male, American)', gender: 'male', accent: 'American' }, { id: 'am_michael', label: 'Michael (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_onyx', label: 'Onyx (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_puck', label: 'Puck (Male, American)', gender: 'male', accent: 'American' }, + { id: 'am_santa', label: 'Santa (Male, American)', gender: 'male', accent: 'American' }, + + // British English - Female (4 voices) + { id: 'bf_alice', label: 'Alice (Female, British)', gender: 'female', accent: 'British' }, { id: 'bf_emma', label: 'Emma (Female, British)', gender: 'female', accent: 'British' }, { id: 'bf_isabella', label: 'Isabella (Female, British)', gender: 'female', accent: 'British' }, + { id: 'bf_lily', label: 'Lily (Female, British)', gender: 'female', accent: 'British' }, + + // British English - Male (4 voices) + { id: 'bm_daniel', label: 'Daniel (Male, British)', gender: 'male', accent: 'British' }, + { id: 'bm_fable', label: 'Fable (Male, British)', gender: 'male', accent: 'British' }, { id: 'bm_george', label: 'George (Male, British)', gender: 'male', accent: 'British' }, { id: 'bm_lewis', label: 'Lewis (Male, British)', gender: 'male', accent: 'British' }, + + // Spanish - Female (1 voice) + { id: 'ef_dora', label: 'Dora (Female, Spanish)', gender: 'female', accent: 'Spanish' }, + + // Spanish - Male (2 voices) + { id: 'em_alex', label: 'Alex (Male, Spanish)', gender: 'male', accent: 'Spanish' }, + { id: 'em_santa', label: 'Santa (Male, Spanish)', gender: 'male', accent: 'Spanish' }, + + // French - Female (1 voice) + { id: 'ff_siwis', label: 'Siwis (Female, French)', gender: 'female', accent: 'French' }, + + // Hindi - Female (2 voices) + { id: 'hf_alpha', label: 'Alpha (Female, Hindi)', gender: 'female', accent: 'Hindi' }, + { id: 'hf_beta', label: 'Beta (Female, Hindi)', gender: 'female', accent: 'Hindi' }, + + // Hindi - Male (2 voices) + { id: 'hm_omega', label: 'Omega (Male, Hindi)', gender: 'male', accent: 'Hindi' }, + { id: 'hm_psi', label: 'Psi (Male, Hindi)', gender: 'male', accent: 'Hindi' }, + + // Italian - Female (1 voice) + { id: 'if_sara', label: 'Sara (Female, Italian)', gender: 'female', accent: 'Italian' }, + + // Italian - Male (1 voice) + { id: 'im_nicola', label: 'Nicola (Male, Italian)', gender: 'male', accent: 'Italian' }, + + // Japanese - Female (4 voices) + { id: 'jf_alpha', label: 'Alpha (Female, Japanese)', gender: 'female', accent: 'Japanese' }, + { id: 'jf_gongitsune', label: 'Gongitsune (Female, Japanese)', gender: 'female', accent: 'Japanese' }, + { id: 'jf_nezumi', label: 'Nezumi (Female, Japanese)', gender: 'female', accent: 'Japanese' }, + { id: 'jf_tebukuro', label: 'Tebukuro (Female, Japanese)', gender: 'female', accent: 'Japanese' }, + + // Japanese - Male (1 voice) + { id: 'jm_kumo', label: 'Kumo (Male, Japanese)', gender: 'male', accent: 'Japanese' }, + + // Portuguese - Female (1 voice) + { id: 'pf_dora', label: 'Dora (Female, Portuguese)', gender: 'female', accent: 'Portuguese' }, + + // Portuguese - Male (2 voices) + { id: 'pm_alex', label: 'Alex (Male, Portuguese)', gender: 'male', accent: 'Portuguese' }, + { id: 'pm_santa', label: 'Santa (Male, Portuguese)', gender: 'male', accent: 'Portuguese' }, + + // Chinese/Mandarin - Female (4 voices) + { id: 'zf_xiaobei', label: 'Xiaobei (Female, Chinese)', gender: 'female', accent: 'Chinese' }, + { id: 'zf_xiaoni', label: 'Xiaoni (Female, Chinese)', gender: 'female', accent: 'Chinese' }, + { id: 'zf_xiaoxiao', label: 'Xiaoxiao (Female, Chinese)', gender: 'female', accent: 'Chinese' }, + { id: 'zf_xiaoyi', label: 'Xiaoyi (Female, Chinese)', gender: 'female', accent: 'Chinese' }, + + // Chinese/Mandarin - Male (4 voices) + { id: 'zm_yunjian', label: 'Yunjian (Male, Chinese)', gender: 'male', accent: 'Chinese' }, + { id: 'zm_yunxi', label: 'Yunxi (Male, Chinese)', gender: 'male', accent: 'Chinese' }, + { id: 'zm_yunxia', label: 'Yunxia (Male, Chinese)', gender: 'male', accent: 'Chinese' }, + { id: 'zm_yunyang', label: 'Yunyang (Male, Chinese)', gender: 'male', accent: 'Chinese' }, ]; -// Language options as defined in the design document +// Language options - all supported by Kokoro TTS const LANGUAGES: LanguageOption[] = [ { code: 'a', label: 'American English' }, { code: 'b', label: 'British English' }, - { code: 'f', label: 'French' }, - { code: 'j', label: 'Japanese' }, + { code: 'e', label: 'Spanish (Español)' }, + { code: 'f', label: 'French (Français)' }, + { code: 'h', label: 'Hindi (हिन्दी)' }, + { code: 'i', label: 'Italian (Italiano)' }, + { code: 'j', label: 'Japanese (日本語)' }, + { code: 'p', label: 'Portuguese (Português)' }, + { code: 'z', label: 'Chinese (中文)' }, ]; export default function VoiceAssignmentSection({