🦝 Raccoon Mission: Silero TTS integration complete with 140 voices

 Integrated Silero TTS as tts-1-silero model
- Fixed omegaconf dependency
- Fixed Silero API integration (torch.hub.load returns 2 values)
- Fixed model.to(device) returning None bug
- Mapped all 140 Silero voices across 5 languages:
  * English (en): 118 speakers (en_0 to en_117) + random
  * Russian (ru): 5 speakers (aidar, baya, kseniya, xenia, eugene) + random
  * German (de): 5 speakers (bernd_ungerer, eva_k, friedrich, hokuspokus, karlsson) + random
  * Spanish (es): 3 speakers (es_0, es_1, es_2) + random
  * French (fr): 6 speakers (fr_0 to fr_5) + random

📝 Configuration changes:
- requirements.txt: Added omegaconf for Silero
- voice_to_speaker.default.yaml: All 140 Silero voices mapped
- speech.py: Silero wrapper class with proper API handling

🎯 Working TTS engines: 3
- Piper TTS (tts-1) - Fast, lightweight
- XTTS v2 (tts-1-hd) - High quality, voice cloning
- Silero TTS (tts-1-silero) - CPU-friendly, 5 languages, actively maintained

🦝 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Russell Ballestrini 2025-11-09 12:39:12 -05:00
parent 4deedb9539
commit 01e51b08b5
3 changed files with 620 additions and 21 deletions

View file

@ -10,6 +10,7 @@ coqui-tts[languages]
# Silero TTS - actively maintained, small efficient models
# Note: Silero models are loaded via torch.hub, no package install needed
# Models: ~50-100MB each, CPU-friendly, real-time capable
omegaconf # Required by Silero TTS
# Chatterbox - emotion control, 23 languages (Resemble AI)
# Install from git since no PyPI package exists yet
# 🦝 RACCOON NOTE: Disabled due to dependency conflict with Coqui TTS

View file

@ -113,35 +113,59 @@ class xtts_wrapper():
self.last_used = time.time()
class silero_wrapper():
"""Wrapper for Silero TTS models"""
def __init__(self, language='en', speaker='v4_en', device='cpu'):
"""Wrapper for Silero TTS models
Silero torch.hub.load returns: (model, example_text)
The model has a method apply_tts(text, speaker, sample_rate)
"""
def __init__(self, language='en', speaker='v3_en', device='cpu'):
self.language = language
self.speaker = speaker
self.device = device
logger.info(f"Loading Silero model for {language} on {device}")
logger.info(f"Loading Silero model for {language} with speaker {speaker} on {device}")
import torch
self.model, self.symbols, self.sample_rate, self.example_text, self.apply_tts = torch.hub.load(
try:
# torch.hub.load returns (model, example_text)
self.model, example_text = torch.hub.load(
repo_or_dir='snakers4/silero-models',
model='silero_tts',
language=language,
speaker=speaker
speaker=speaker,
verbose=False
)
self.model = self.model.to(device)
def tts(self, text, speaker_id='en_0'):
logger.info(f"Model loaded, type: {type(self.model)}")
self.model.to(device) # Move to device (in-place for Silero)
self.sample_rate = 48000 # Silero uses 48kHz
logger.info(f"Successfully loaded Silero {language}/{speaker}, example: {example_text}")
except Exception as e:
logger.error(f"Failed to load Silero model: {e}")
raise
def tts(self, text, speaker_id='lj_16khz'):
"""Generate speech from text"""
import torch
logger.info(f"Silero tts() called: model={self.model}, speaker_id={speaker_id}")
if self.model is None:
raise RuntimeError("Silero model is None - model failed to load")
if not hasattr(self.model, 'apply_tts'):
logger.error(f"Model has no apply_tts method. Model type: {type(self.model)}, dir: {dir(self.model)}")
raise AttributeError(f"Silero model {type(self.model)} has no apply_tts method")
with torch.no_grad():
audio = self.apply_tts(
# Use model's apply_tts method
audio = self.model.apply_tts(
text=text,
speaker=speaker_id,
sample_rate=self.sample_rate
)
# Convert to float32 PCM
audio_np = audio.cpu().numpy()
return audio_np.tobytes()
# audio is a tensor, convert to numpy float32
return audio.cpu().numpy().tobytes()
def default_exists(filename: str):
if not os.path.exists(filename):

View file

@ -58,27 +58,601 @@ tts-1-hd:
top_p: 0.85
comment: You can add a comment here also, which will be persistent and otherwise ignored.
tts-1-silero:
# OpenAI-compatible voice aliases (for compatibility)
alloy:
language: en
speaker: en_0
silero_speaker: v4_en
silero_speaker: v3_en
echo:
language: en
speaker: en_1
silero_speaker: v4_en
silero_speaker: v3_en
fable:
language: en
speaker: en_2
silero_speaker: v4_en
silero_speaker: v3_en
onyx:
language: en
speaker: en_3
silero_speaker: v4_en
silero_speaker: v3_en
nova:
language: en
speaker: en_4
silero_speaker: v4_en
silero_speaker: v3_en
shimmer:
language: en
speaker: en_5
silero_speaker: v4_en
silero_speaker: v3_en
# All 118 Silero v3_en voices with proper names
en_0:
language: en
speaker: en_0
silero_speaker: v3_en
en_1:
language: en
speaker: en_1
silero_speaker: v3_en
en_2:
language: en
speaker: en_2
silero_speaker: v3_en
en_3:
language: en
speaker: en_3
silero_speaker: v3_en
en_4:
language: en
speaker: en_4
silero_speaker: v3_en
en_5:
language: en
speaker: en_5
silero_speaker: v3_en
en_6:
language: en
speaker: en_6
silero_speaker: v3_en
en_7:
language: en
speaker: en_7
silero_speaker: v3_en
en_8:
language: en
speaker: en_8
silero_speaker: v3_en
en_9:
language: en
speaker: en_9
silero_speaker: v3_en
en_10:
language: en
speaker: en_10
silero_speaker: v3_en
en_11:
language: en
speaker: en_11
silero_speaker: v3_en
en_12:
language: en
speaker: en_12
silero_speaker: v3_en
en_13:
language: en
speaker: en_13
silero_speaker: v3_en
en_14:
language: en
speaker: en_14
silero_speaker: v3_en
en_15:
language: en
speaker: en_15
silero_speaker: v3_en
en_16:
language: en
speaker: en_16
silero_speaker: v3_en
en_17:
language: en
speaker: en_17
silero_speaker: v3_en
en_18:
language: en
speaker: en_18
silero_speaker: v3_en
en_19:
language: en
speaker: en_19
silero_speaker: v3_en
en_20:
language: en
speaker: en_20
silero_speaker: v3_en
en_21:
language: en
speaker: en_21
silero_speaker: v3_en
en_22:
language: en
speaker: en_22
silero_speaker: v3_en
en_23:
language: en
speaker: en_23
silero_speaker: v3_en
en_24:
language: en
speaker: en_24
silero_speaker: v3_en
en_25:
language: en
speaker: en_25
silero_speaker: v3_en
en_26:
language: en
speaker: en_26
silero_speaker: v3_en
en_27:
language: en
speaker: en_27
silero_speaker: v3_en
en_28:
language: en
speaker: en_28
silero_speaker: v3_en
en_29:
language: en
speaker: en_29
silero_speaker: v3_en
en_30:
language: en
speaker: en_30
silero_speaker: v3_en
en_31:
language: en
speaker: en_31
silero_speaker: v3_en
en_32:
language: en
speaker: en_32
silero_speaker: v3_en
en_33:
language: en
speaker: en_33
silero_speaker: v3_en
en_34:
language: en
speaker: en_34
silero_speaker: v3_en
en_35:
language: en
speaker: en_35
silero_speaker: v3_en
en_36:
language: en
speaker: en_36
silero_speaker: v3_en
en_37:
language: en
speaker: en_37
silero_speaker: v3_en
en_38:
language: en
speaker: en_38
silero_speaker: v3_en
en_39:
language: en
speaker: en_39
silero_speaker: v3_en
en_40:
language: en
speaker: en_40
silero_speaker: v3_en
en_41:
language: en
speaker: en_41
silero_speaker: v3_en
en_42:
language: en
speaker: en_42
silero_speaker: v3_en
en_43:
language: en
speaker: en_43
silero_speaker: v3_en
en_44:
language: en
speaker: en_44
silero_speaker: v3_en
en_45:
language: en
speaker: en_45
silero_speaker: v3_en
en_46:
language: en
speaker: en_46
silero_speaker: v3_en
en_47:
language: en
speaker: en_47
silero_speaker: v3_en
en_48:
language: en
speaker: en_48
silero_speaker: v3_en
en_49:
language: en
speaker: en_49
silero_speaker: v3_en
en_50:
language: en
speaker: en_50
silero_speaker: v3_en
en_51:
language: en
speaker: en_51
silero_speaker: v3_en
en_52:
language: en
speaker: en_52
silero_speaker: v3_en
en_53:
language: en
speaker: en_53
silero_speaker: v3_en
en_54:
language: en
speaker: en_54
silero_speaker: v3_en
en_55:
language: en
speaker: en_55
silero_speaker: v3_en
en_56:
language: en
speaker: en_56
silero_speaker: v3_en
en_57:
language: en
speaker: en_57
silero_speaker: v3_en
en_58:
language: en
speaker: en_58
silero_speaker: v3_en
en_59:
language: en
speaker: en_59
silero_speaker: v3_en
en_60:
language: en
speaker: en_60
silero_speaker: v3_en
en_61:
language: en
speaker: en_61
silero_speaker: v3_en
en_62:
language: en
speaker: en_62
silero_speaker: v3_en
en_63:
language: en
speaker: en_63
silero_speaker: v3_en
en_64:
language: en
speaker: en_64
silero_speaker: v3_en
en_65:
language: en
speaker: en_65
silero_speaker: v3_en
en_66:
language: en
speaker: en_66
silero_speaker: v3_en
en_67:
language: en
speaker: en_67
silero_speaker: v3_en
en_68:
language: en
speaker: en_68
silero_speaker: v3_en
en_69:
language: en
speaker: en_69
silero_speaker: v3_en
en_70:
language: en
speaker: en_70
silero_speaker: v3_en
en_71:
language: en
speaker: en_71
silero_speaker: v3_en
en_72:
language: en
speaker: en_72
silero_speaker: v3_en
en_73:
language: en
speaker: en_73
silero_speaker: v3_en
en_74:
language: en
speaker: en_74
silero_speaker: v3_en
en_75:
language: en
speaker: en_75
silero_speaker: v3_en
en_76:
language: en
speaker: en_76
silero_speaker: v3_en
en_77:
language: en
speaker: en_77
silero_speaker: v3_en
en_78:
language: en
speaker: en_78
silero_speaker: v3_en
en_79:
language: en
speaker: en_79
silero_speaker: v3_en
en_80:
language: en
speaker: en_80
silero_speaker: v3_en
en_81:
language: en
speaker: en_81
silero_speaker: v3_en
en_82:
language: en
speaker: en_82
silero_speaker: v3_en
en_83:
language: en
speaker: en_83
silero_speaker: v3_en
en_84:
language: en
speaker: en_84
silero_speaker: v3_en
en_85:
language: en
speaker: en_85
silero_speaker: v3_en
en_86:
language: en
speaker: en_86
silero_speaker: v3_en
en_87:
language: en
speaker: en_87
silero_speaker: v3_en
en_88:
language: en
speaker: en_88
silero_speaker: v3_en
en_89:
language: en
speaker: en_89
silero_speaker: v3_en
en_90:
language: en
speaker: en_90
silero_speaker: v3_en
en_91:
language: en
speaker: en_91
silero_speaker: v3_en
en_92:
language: en
speaker: en_92
silero_speaker: v3_en
en_93:
language: en
speaker: en_93
silero_speaker: v3_en
en_94:
language: en
speaker: en_94
silero_speaker: v3_en
en_95:
language: en
speaker: en_95
silero_speaker: v3_en
en_96:
language: en
speaker: en_96
silero_speaker: v3_en
en_97:
language: en
speaker: en_97
silero_speaker: v3_en
en_98:
language: en
speaker: en_98
silero_speaker: v3_en
en_99:
language: en
speaker: en_99
silero_speaker: v3_en
en_100:
language: en
speaker: en_100
silero_speaker: v3_en
en_101:
language: en
speaker: en_101
silero_speaker: v3_en
en_102:
language: en
speaker: en_102
silero_speaker: v3_en
en_103:
language: en
speaker: en_103
silero_speaker: v3_en
en_104:
language: en
speaker: en_104
silero_speaker: v3_en
en_105:
language: en
speaker: en_105
silero_speaker: v3_en
en_106:
language: en
speaker: en_106
silero_speaker: v3_en
en_107:
language: en
speaker: en_107
silero_speaker: v3_en
en_108:
language: en
speaker: en_108
silero_speaker: v3_en
en_109:
language: en
speaker: en_109
silero_speaker: v3_en
en_110:
language: en
speaker: en_110
silero_speaker: v3_en
en_111:
language: en
speaker: en_111
silero_speaker: v3_en
en_112:
language: en
speaker: en_112
silero_speaker: v3_en
en_113:
language: en
speaker: en_113
silero_speaker: v3_en
en_114:
language: en
speaker: en_114
silero_speaker: v3_en
en_115:
language: en
speaker: en_115
silero_speaker: v3_en
en_116:
language: en
speaker: en_116
silero_speaker: v3_en
en_117:
language: en
speaker: en_117
silero_speaker: v3_en
random:
language: en
speaker: random
silero_speaker: v3_en
# Russian voices (v4_ru model)
ru_aidar:
language: ru
speaker: aidar
silero_speaker: v4_ru
ru_baya:
language: ru
speaker: baya
silero_speaker: v4_ru
ru_kseniya:
language: ru
speaker: kseniya
silero_speaker: v4_ru
ru_xenia:
language: ru
speaker: xenia
silero_speaker: v4_ru
ru_eugene:
language: ru
speaker: eugene
silero_speaker: v4_ru
ru_random:
language: ru
speaker: random
silero_speaker: v4_ru
# German voices (v3_de model)
de_bernd_ungerer:
language: de
speaker: bernd_ungerer
silero_speaker: v3_de
de_eva_k:
language: de
speaker: eva_k
silero_speaker: v3_de
de_friedrich:
language: de
speaker: friedrich
silero_speaker: v3_de
de_hokuspokus:
language: de
speaker: hokuspokus
silero_speaker: v3_de
de_karlsson:
language: de
speaker: karlsson
silero_speaker: v3_de
de_random:
language: de
speaker: random
silero_speaker: v3_de
# Spanish voices (v1_es model)
es_0:
language: es
speaker: es_0
silero_speaker: v1_es
es_1:
language: es
speaker: es_1
silero_speaker: v1_es
es_2:
language: es
speaker: es_2
silero_speaker: v1_es
es_random:
language: es
speaker: random
silero_speaker: v1_es
# French voices (v3_fr model)
fr_0:
language: fr
speaker: fr_0
silero_speaker: v3_fr
fr_1:
language: fr
speaker: fr_1
silero_speaker: v3_fr
fr_2:
language: fr
speaker: fr_2
silero_speaker: v3_fr
fr_3:
language: fr
speaker: fr_3
silero_speaker: v3_fr
fr_4:
language: fr
speaker: fr_4
silero_speaker: v3_fr
fr_5:
language: fr
speaker: fr_5
silero_speaker: v3_fr
fr_random:
language: fr
speaker: random
silero_speaker: v3_fr