Skip to content

Commit 4081ba6

Browse files
committed
organize kokoro voices according to gender and accents
1 parent 159b5bd commit 4081ba6

File tree

2 files changed

+100
-10
lines changed

2 files changed

+100
-10
lines changed

app/main.py

+97-7
Original file line numberDiff line numberDiff line change
@@ -594,20 +594,110 @@ async def get_kokoro_voices():
594594
data = await response.json()
595595
# Process the voices from the response
596596
voices = []
597-
for voice_id in data.get("voices", []):
598-
# Create a readable name from the ID
599-
# Format: language code (af/am) + name
597+
598+
# Language/accent codes mapping
599+
language_codes = {
600+
'a': 'American English',
601+
'b': 'British English',
602+
'e': 'European Spanish',
603+
'f': 'French',
604+
'g': 'German',
605+
'h': 'Hindi',
606+
'i': 'Italian',
607+
'j': 'Japanese',
608+
'k': 'Korean',
609+
'p': 'Polish',
610+
'r': 'Russian',
611+
's': 'Spanish',
612+
'z': 'Chinese'
613+
}
614+
615+
# Get all voice IDs
616+
voice_ids = data.get("voices", [])
617+
618+
# Group voices by language/accent
619+
english_voices = [] # American and British English
620+
other_voices_by_language = {} # Organize other voices by language code
621+
unknown_voices = [] # For voices that don't follow the naming pattern
622+
623+
for voice_id in voice_ids:
624+
parts = voice_id.split('_')
625+
if len(parts) >= 2:
626+
lang_code = parts[0]
627+
# First character is language code
628+
accent_code = lang_code[:1]
629+
630+
# Prioritize English voices (American and British)
631+
if accent_code in ['a', 'b']:
632+
english_voices.append(voice_id)
633+
else:
634+
# Group other voices by language
635+
if accent_code not in other_voices_by_language:
636+
other_voices_by_language[accent_code] = []
637+
other_voices_by_language[accent_code].append(voice_id)
638+
else:
639+
unknown_voices.append(voice_id)
640+
641+
# Sort voices within each group
642+
english_voices.sort()
643+
for lang in other_voices_by_language:
644+
other_voices_by_language[lang].sort()
645+
unknown_voices.sort()
646+
647+
# Create final sorted list: English first, then other languages alphabetically
648+
sorted_voice_ids = english_voices
649+
650+
# Process English voices
651+
for voice_id in english_voices:
600652
parts = voice_id.split('_')
601653
if len(parts) >= 2:
602654
lang_code = parts[0]
603655
name = parts[1].capitalize()
604-
gender = "Female" if lang_code == "af" else "Male"
656+
657+
accent_code = lang_code[:1]
658+
gender_code = lang_code[1:2]
659+
660+
gender = "Female" if gender_code == "f" else "Male"
661+
accent_label = f" - {language_codes.get(accent_code, 'Unknown')}"
662+
605663
voices.append({
606664
"id": voice_id,
607-
"name": f"{name} ({gender})"
665+
"name": f"{name} ({gender}){accent_label}"
608666
})
609-
else:
610-
# Fallback for voices without standard format
667+
668+
# Add other language groups with separators
669+
for lang in sorted(other_voices_by_language.keys()):
670+
# Add a language group header if we have voices for this language
671+
if other_voices_by_language[lang]:
672+
language_name = language_codes.get(lang, "Unknown Language")
673+
674+
# Add a separator for this language group
675+
voices.append({
676+
"id": f"separator_{lang}",
677+
"name": f"--- {language_name} Voices ---"
678+
})
679+
680+
# Add the voices for this language
681+
for voice_id in other_voices_by_language[lang]:
682+
parts = voice_id.split('_')
683+
if len(parts) >= 2:
684+
name = parts[1].capitalize()
685+
gender_code = parts[0][1:2]
686+
gender = "Female" if gender_code == "f" else "Male"
687+
688+
voices.append({
689+
"id": voice_id,
690+
"name": f"{name} ({gender})"
691+
})
692+
693+
# Add unknown voices at the end if any
694+
if unknown_voices:
695+
voices.append({
696+
"id": "separator_unknown",
697+
"name": "--- Other Voices ---"
698+
})
699+
700+
for voice_id in unknown_voices:
611701
voices.append({
612702
"id": voice_id,
613703
"name": voice_id

app/templates/index.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ <h1>
115115
</div>
116116
<div class="settings">
117117
<div class="setting-group">
118-
<label for="character-select">Character:</label>
118+
<label for="character-select">* Character:</label>
119119
<select id="character-select"></select>
120120
</div>
121121
<div class="setting-group">
122-
<label for="provider-select">Model Provider:</label>
122+
<label for="provider-select">* Model Provider:</label>
123123
<select id="provider-select">
124124
<option value="openai">OpenAI</option>
125125
<option value="ollama">Ollama</option>
@@ -128,7 +128,7 @@ <h1>
128128
</select>
129129
</div>
130130
<div class="setting-group">
131-
<label for="tts-select">TTS Provider:</label>
131+
<label for="tts-select">* TTS Provider:</label>
132132
<select id="tts-select">
133133
<option value="openai">OpenAI</option>
134134
<option value="elevenlabs">ElevenLabs</option>

0 commit comments

Comments
 (0)