abstractvoice 0.3.0__tar.gz → 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/PKG-INFO +121 -23
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/README.md +116 -18
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/__init__.py +5 -2
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/examples/cli_repl.py +81 -44
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/examples/voice_cli.py +56 -20
- abstractvoice-0.4.1/abstractvoice/model_manager.py +384 -0
- abstractvoice-0.4.1/abstractvoice/simple_model_manager.py +398 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/tts/tts_engine.py +139 -22
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/voice_manager.py +83 -2
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice.egg-info/PKG-INFO +121 -23
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice.egg-info/SOURCES.txt +2 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice.egg-info/requires.txt +4 -4
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/pyproject.toml +9 -6
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/LICENSE +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/__main__.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/dependency_check.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/examples/__init__.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/examples/web_api.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/recognition.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/stt/__init__.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/stt/transcriber.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/tts/__init__.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/vad/__init__.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice/vad/voice_detector.py +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice.egg-info/dependency_links.txt +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice.egg-info/entry_points.txt +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/abstractvoice.egg-info/top_level.txt +0 -0
- {abstractvoice-0.3.0 → abstractvoice-0.4.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstractvoice
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A modular Python library for voice interactions with AI systems
|
|
5
5
|
Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -29,7 +29,7 @@ Requires-Dist: coqui-tts<0.30.0,>=0.27.0; extra == "tts"
|
|
|
29
29
|
Requires-Dist: torch<2.4.0,>=2.0.0; extra == "tts"
|
|
30
30
|
Requires-Dist: torchvision<0.19.0,>=0.15.0; extra == "tts"
|
|
31
31
|
Requires-Dist: torchaudio<2.4.0,>=2.0.0; extra == "tts"
|
|
32
|
-
Requires-Dist: librosa
|
|
32
|
+
Requires-Dist: librosa>=0.10.0; extra == "tts"
|
|
33
33
|
Provides-Extra: stt
|
|
34
34
|
Requires-Dist: openai-whisper>=20230314; extra == "stt"
|
|
35
35
|
Requires-Dist: tiktoken>=0.6.0; extra == "stt"
|
|
@@ -44,7 +44,7 @@ Requires-Dist: coqui-tts<0.30.0,>=0.27.0; extra == "all"
|
|
|
44
44
|
Requires-Dist: torch<2.4.0,>=2.0.0; extra == "all"
|
|
45
45
|
Requires-Dist: torchvision<0.19.0,>=0.15.0; extra == "all"
|
|
46
46
|
Requires-Dist: torchaudio<2.4.0,>=2.0.0; extra == "all"
|
|
47
|
-
Requires-Dist: librosa
|
|
47
|
+
Requires-Dist: librosa>=0.10.0; extra == "all"
|
|
48
48
|
Requires-Dist: soundfile>=0.12.1; extra == "all"
|
|
49
49
|
Requires-Dist: flask>=2.0.0; extra == "all"
|
|
50
50
|
Requires-Dist: tiktoken>=0.6.0; extra == "all"
|
|
@@ -61,7 +61,7 @@ Requires-Dist: coqui-tts<0.30.0,>=0.27.0; extra == "voice-full"
|
|
|
61
61
|
Requires-Dist: torch<2.4.0,>=2.0.0; extra == "voice-full"
|
|
62
62
|
Requires-Dist: torchvision<0.19.0,>=0.15.0; extra == "voice-full"
|
|
63
63
|
Requires-Dist: torchaudio<2.4.0,>=2.0.0; extra == "voice-full"
|
|
64
|
-
Requires-Dist: librosa
|
|
64
|
+
Requires-Dist: librosa>=0.10.0; extra == "voice-full"
|
|
65
65
|
Requires-Dist: soundfile>=0.12.1; extra == "voice-full"
|
|
66
66
|
Requires-Dist: tiktoken>=0.6.0; extra == "voice-full"
|
|
67
67
|
Provides-Extra: core-tts
|
|
@@ -69,7 +69,7 @@ Requires-Dist: coqui-tts<0.30.0,>=0.27.0; extra == "core-tts"
|
|
|
69
69
|
Requires-Dist: torch<2.4.0,>=2.0.0; extra == "core-tts"
|
|
70
70
|
Requires-Dist: torchvision<0.19.0,>=0.15.0; extra == "core-tts"
|
|
71
71
|
Requires-Dist: torchaudio<2.4.0,>=2.0.0; extra == "core-tts"
|
|
72
|
-
Requires-Dist: librosa
|
|
72
|
+
Requires-Dist: librosa>=0.10.0; extra == "core-tts"
|
|
73
73
|
Provides-Extra: core-stt
|
|
74
74
|
Requires-Dist: openai-whisper>=20230314; extra == "core-stt"
|
|
75
75
|
Requires-Dist: tiktoken>=0.6.0; extra == "core-stt"
|
|
@@ -164,34 +164,58 @@ AbstractVoice automatically detects espeak-ng and upgrades to premium quality vo
|
|
|
164
164
|
|
|
165
165
|
## Quick Start
|
|
166
166
|
|
|
167
|
-
###
|
|
167
|
+
### ⚡ Instant TTS (v0.4.0+)
|
|
168
168
|
|
|
169
169
|
```python
|
|
170
|
-
# First install with minimal dependencies
|
|
171
|
-
# pip install abstractvoice
|
|
172
|
-
|
|
173
170
|
from abstractvoice import VoiceManager
|
|
174
171
|
|
|
175
|
-
#
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
# Follow the instructions to install: pip install abstractvoice[all]
|
|
172
|
+
# Initialize voice manager - automatically downloads essential model if needed
|
|
173
|
+
vm = VoiceManager()
|
|
174
|
+
|
|
175
|
+
# Text-to-speech works immediately!
|
|
176
|
+
vm.speak("Hello! TTS works out of the box!")
|
|
181
177
|
```
|
|
182
178
|
|
|
183
|
-
|
|
179
|
+
**That's it!** AbstractVoice v0.4.0+ automatically:
|
|
180
|
+
- ✅ Downloads essential English model (107MB) on first use
|
|
181
|
+
- ✅ Caches models permanently for offline use
|
|
182
|
+
- ✅ Works immediately after first setup
|
|
183
|
+
- ✅ No complex configuration needed
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
# After installing with: pip install abstractvoice[all]
|
|
185
|
+
### 🌍 Multi-Language Support
|
|
187
186
|
|
|
188
|
-
|
|
187
|
+
```python
|
|
188
|
+
# Download and use French voice
|
|
189
|
+
vm.download_model('fr.css10_vits') # Downloads automatically
|
|
190
|
+
vm.set_language('fr')
|
|
191
|
+
vm.speak("Bonjour! Je parle français maintenant.")
|
|
192
|
+
|
|
193
|
+
# Download and use German voice
|
|
194
|
+
vm.download_model('de.thorsten_vits')
|
|
195
|
+
vm.set_language('de')
|
|
196
|
+
vm.speak("Hallo! Ich spreche jetzt Deutsch.")
|
|
197
|
+
```
|
|
189
198
|
|
|
190
|
-
|
|
191
|
-
vm = VoiceManager(language='en', debug_mode=True)
|
|
199
|
+
### 🔧 Check System Status
|
|
192
200
|
|
|
193
|
-
|
|
194
|
-
|
|
201
|
+
```python
|
|
202
|
+
from abstractvoice import is_ready, get_status, list_models
|
|
203
|
+
import json
|
|
204
|
+
|
|
205
|
+
# Quick readiness check
|
|
206
|
+
ready = is_ready()
|
|
207
|
+
print(f"TTS ready: {ready}")
|
|
208
|
+
|
|
209
|
+
# Get detailed status
|
|
210
|
+
status = json.loads(get_status())
|
|
211
|
+
print(f"Models cached: {status['total_cached']}")
|
|
212
|
+
print(f"Offline ready: {status['ready_for_offline']}")
|
|
213
|
+
|
|
214
|
+
# List all available models
|
|
215
|
+
models = json.loads(list_models())
|
|
216
|
+
for lang, voices in models.items():
|
|
217
|
+
print(f"{lang}: {len(voices)} voices available")
|
|
218
|
+
```
|
|
195
219
|
|
|
196
220
|
# Speech-to-text with callbacks
|
|
197
221
|
def on_transcription(text):
|
|
@@ -1289,6 +1313,80 @@ voice_manager.listen(
|
|
|
1289
1313
|
)
|
|
1290
1314
|
```
|
|
1291
1315
|
|
|
1316
|
+
## 💻 CLI Commands (v0.4.0+)
|
|
1317
|
+
|
|
1318
|
+
AbstractVoice provides powerful CLI commands for model management and voice interactions.
|
|
1319
|
+
|
|
1320
|
+
### Model Management
|
|
1321
|
+
|
|
1322
|
+
```bash
|
|
1323
|
+
# Download essential model for offline use (recommended first step)
|
|
1324
|
+
abstractvoice download-models
|
|
1325
|
+
|
|
1326
|
+
# Download models for specific languages
|
|
1327
|
+
abstractvoice download-models --language fr # French
|
|
1328
|
+
abstractvoice download-models --language de # German
|
|
1329
|
+
abstractvoice download-models --language it # Italian
|
|
1330
|
+
abstractvoice download-models --language es # Spanish
|
|
1331
|
+
|
|
1332
|
+
# Download specific model by name
|
|
1333
|
+
abstractvoice download-models --model tts_models/fr/css10/vits
|
|
1334
|
+
|
|
1335
|
+
# Download all available models (large download!)
|
|
1336
|
+
abstractvoice download-models --all
|
|
1337
|
+
|
|
1338
|
+
# Check current cache status
|
|
1339
|
+
abstractvoice download-models --status
|
|
1340
|
+
|
|
1341
|
+
# Clear model cache
|
|
1342
|
+
abstractvoice download-models --clear
|
|
1343
|
+
```
|
|
1344
|
+
|
|
1345
|
+
### Voice Interface
|
|
1346
|
+
|
|
1347
|
+
```bash
|
|
1348
|
+
# Start voice interface (default)
|
|
1349
|
+
abstractvoice
|
|
1350
|
+
|
|
1351
|
+
# Start CLI REPL with specific language
|
|
1352
|
+
abstractvoice cli --language fr
|
|
1353
|
+
|
|
1354
|
+
# Start with specific model
|
|
1355
|
+
abstractvoice --model granite3.3:2b --language de
|
|
1356
|
+
|
|
1357
|
+
# Run simple example
|
|
1358
|
+
abstractvoice simple
|
|
1359
|
+
|
|
1360
|
+
# Check dependencies
|
|
1361
|
+
abstractvoice check-deps
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
### CLI Voice Commands
|
|
1365
|
+
|
|
1366
|
+
In the CLI REPL, use these commands:
|
|
1367
|
+
|
|
1368
|
+
```bash
|
|
1369
|
+
# List all available voices with download status
|
|
1370
|
+
/setvoice
|
|
1371
|
+
|
|
1372
|
+
# Download and set specific voice
|
|
1373
|
+
/setvoice fr.css10_vits # French CSS10 VITS
|
|
1374
|
+
/setvoice de.thorsten_vits # German Thorsten
|
|
1375
|
+
/setvoice it.mai_male_vits # Italian Male
|
|
1376
|
+
|
|
1377
|
+
# Change language
|
|
1378
|
+
/language fr
|
|
1379
|
+
/language de
|
|
1380
|
+
|
|
1381
|
+
# Voice controls
|
|
1382
|
+
/pause # Pause current speech
|
|
1383
|
+
/resume # Resume speech
|
|
1384
|
+
/stop # Stop speech
|
|
1385
|
+
|
|
1386
|
+
# Exit
|
|
1387
|
+
/exit
|
|
1388
|
+
```
|
|
1389
|
+
|
|
1292
1390
|
## Perspectives
|
|
1293
1391
|
|
|
1294
1392
|
This is a test project that I designed with examples to work with Ollama, but I will adapt the examples and abstractvoice to work with any LLM provider (anthropic, openai, etc).
|
|
@@ -82,34 +82,58 @@ AbstractVoice automatically detects espeak-ng and upgrades to premium quality vo
|
|
|
82
82
|
|
|
83
83
|
## Quick Start
|
|
84
84
|
|
|
85
|
-
###
|
|
85
|
+
### ⚡ Instant TTS (v0.4.0+)
|
|
86
86
|
|
|
87
87
|
```python
|
|
88
|
-
# First install with minimal dependencies
|
|
89
|
-
# pip install abstractvoice
|
|
90
|
-
|
|
91
88
|
from abstractvoice import VoiceManager
|
|
92
89
|
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
# Follow the instructions to install: pip install abstractvoice[all]
|
|
90
|
+
# Initialize voice manager - automatically downloads essential model if needed
|
|
91
|
+
vm = VoiceManager()
|
|
92
|
+
|
|
93
|
+
# Text-to-speech works immediately!
|
|
94
|
+
vm.speak("Hello! TTS works out of the box!")
|
|
99
95
|
```
|
|
100
96
|
|
|
101
|
-
|
|
97
|
+
**That's it!** AbstractVoice v0.4.0+ automatically:
|
|
98
|
+
- ✅ Downloads essential English model (107MB) on first use
|
|
99
|
+
- ✅ Caches models permanently for offline use
|
|
100
|
+
- ✅ Works immediately after first setup
|
|
101
|
+
- ✅ No complex configuration needed
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
# After installing with: pip install abstractvoice[all]
|
|
103
|
+
### 🌍 Multi-Language Support
|
|
105
104
|
|
|
106
|
-
|
|
105
|
+
```python
|
|
106
|
+
# Download and use French voice
|
|
107
|
+
vm.download_model('fr.css10_vits') # Downloads automatically
|
|
108
|
+
vm.set_language('fr')
|
|
109
|
+
vm.speak("Bonjour! Je parle français maintenant.")
|
|
110
|
+
|
|
111
|
+
# Download and use German voice
|
|
112
|
+
vm.download_model('de.thorsten_vits')
|
|
113
|
+
vm.set_language('de')
|
|
114
|
+
vm.speak("Hallo! Ich spreche jetzt Deutsch.")
|
|
115
|
+
```
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
vm = VoiceManager(language='en', debug_mode=True)
|
|
117
|
+
### 🔧 Check System Status
|
|
110
118
|
|
|
111
|
-
|
|
112
|
-
|
|
119
|
+
```python
|
|
120
|
+
from abstractvoice import is_ready, get_status, list_models
|
|
121
|
+
import json
|
|
122
|
+
|
|
123
|
+
# Quick readiness check
|
|
124
|
+
ready = is_ready()
|
|
125
|
+
print(f"TTS ready: {ready}")
|
|
126
|
+
|
|
127
|
+
# Get detailed status
|
|
128
|
+
status = json.loads(get_status())
|
|
129
|
+
print(f"Models cached: {status['total_cached']}")
|
|
130
|
+
print(f"Offline ready: {status['ready_for_offline']}")
|
|
131
|
+
|
|
132
|
+
# List all available models
|
|
133
|
+
models = json.loads(list_models())
|
|
134
|
+
for lang, voices in models.items():
|
|
135
|
+
print(f"{lang}: {len(voices)} voices available")
|
|
136
|
+
```
|
|
113
137
|
|
|
114
138
|
# Speech-to-text with callbacks
|
|
115
139
|
def on_transcription(text):
|
|
@@ -1207,6 +1231,80 @@ voice_manager.listen(
|
|
|
1207
1231
|
)
|
|
1208
1232
|
```
|
|
1209
1233
|
|
|
1234
|
+
## 💻 CLI Commands (v0.4.0+)
|
|
1235
|
+
|
|
1236
|
+
AbstractVoice provides powerful CLI commands for model management and voice interactions.
|
|
1237
|
+
|
|
1238
|
+
### Model Management
|
|
1239
|
+
|
|
1240
|
+
```bash
|
|
1241
|
+
# Download essential model for offline use (recommended first step)
|
|
1242
|
+
abstractvoice download-models
|
|
1243
|
+
|
|
1244
|
+
# Download models for specific languages
|
|
1245
|
+
abstractvoice download-models --language fr # French
|
|
1246
|
+
abstractvoice download-models --language de # German
|
|
1247
|
+
abstractvoice download-models --language it # Italian
|
|
1248
|
+
abstractvoice download-models --language es # Spanish
|
|
1249
|
+
|
|
1250
|
+
# Download specific model by name
|
|
1251
|
+
abstractvoice download-models --model tts_models/fr/css10/vits
|
|
1252
|
+
|
|
1253
|
+
# Download all available models (large download!)
|
|
1254
|
+
abstractvoice download-models --all
|
|
1255
|
+
|
|
1256
|
+
# Check current cache status
|
|
1257
|
+
abstractvoice download-models --status
|
|
1258
|
+
|
|
1259
|
+
# Clear model cache
|
|
1260
|
+
abstractvoice download-models --clear
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
### Voice Interface
|
|
1264
|
+
|
|
1265
|
+
```bash
|
|
1266
|
+
# Start voice interface (default)
|
|
1267
|
+
abstractvoice
|
|
1268
|
+
|
|
1269
|
+
# Start CLI REPL with specific language
|
|
1270
|
+
abstractvoice cli --language fr
|
|
1271
|
+
|
|
1272
|
+
# Start with specific model
|
|
1273
|
+
abstractvoice --model granite3.3:2b --language de
|
|
1274
|
+
|
|
1275
|
+
# Run simple example
|
|
1276
|
+
abstractvoice simple
|
|
1277
|
+
|
|
1278
|
+
# Check dependencies
|
|
1279
|
+
abstractvoice check-deps
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### CLI Voice Commands
|
|
1283
|
+
|
|
1284
|
+
In the CLI REPL, use these commands:
|
|
1285
|
+
|
|
1286
|
+
```bash
|
|
1287
|
+
# List all available voices with download status
|
|
1288
|
+
/setvoice
|
|
1289
|
+
|
|
1290
|
+
# Download and set specific voice
|
|
1291
|
+
/setvoice fr.css10_vits # French CSS10 VITS
|
|
1292
|
+
/setvoice de.thorsten_vits # German Thorsten
|
|
1293
|
+
/setvoice it.mai_male_vits # Italian Male
|
|
1294
|
+
|
|
1295
|
+
# Change language
|
|
1296
|
+
/language fr
|
|
1297
|
+
/language de
|
|
1298
|
+
|
|
1299
|
+
# Voice controls
|
|
1300
|
+
/pause # Pause current speech
|
|
1301
|
+
/resume # Resume speech
|
|
1302
|
+
/stop # Stop speech
|
|
1303
|
+
|
|
1304
|
+
# Exit
|
|
1305
|
+
/exit
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1210
1308
|
## Perspectives
|
|
1211
1309
|
|
|
1212
1310
|
This is a test project that I designed with examples to work with Ollama, but I will adapt the examples and abstractvoice to work with any LLM provider (anthropic, openai, etc).
|
|
@@ -29,5 +29,8 @@ warnings.filterwarnings(
|
|
|
29
29
|
# Import the main class for public API
|
|
30
30
|
from .voice_manager import VoiceManager
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
# Import simple APIs for third-party applications
|
|
33
|
+
from .simple_model_manager import list_models, download_model, get_status, is_ready
|
|
34
|
+
|
|
35
|
+
__version__ = "0.4.1"
|
|
36
|
+
__all__ = ['VoiceManager', 'list_models', 'download_model', 'get_status', 'is_ready']
|
|
@@ -38,7 +38,7 @@ class VoiceREPL(cmd.Cmd):
|
|
|
38
38
|
use_rawinput = True
|
|
39
39
|
|
|
40
40
|
def __init__(self, api_url="http://localhost:11434/api/chat",
|
|
41
|
-
model="granite3.3:2b", debug_mode=False, language="en", tts_model=None):
|
|
41
|
+
model="granite3.3:2b", debug_mode=False, language="en", tts_model=None, disable_tts=False):
|
|
42
42
|
super().__init__()
|
|
43
43
|
|
|
44
44
|
# Debug mode
|
|
@@ -54,11 +54,15 @@ class VoiceREPL(cmd.Cmd):
|
|
|
54
54
|
self.current_language = language
|
|
55
55
|
|
|
56
56
|
# Initialize voice manager with language support
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
if disable_tts:
|
|
58
|
+
self.voice_manager = None
|
|
59
|
+
print("🔇 TTS disabled - text-only mode")
|
|
60
|
+
else:
|
|
61
|
+
self.voice_manager = VoiceManager(
|
|
62
|
+
language=language,
|
|
63
|
+
tts_model=tts_model,
|
|
64
|
+
debug_mode=debug_mode
|
|
65
|
+
)
|
|
62
66
|
|
|
63
67
|
# Settings
|
|
64
68
|
self.use_tts = True
|
|
@@ -90,8 +94,11 @@ class VoiceREPL(cmd.Cmd):
|
|
|
90
94
|
def _get_intro(self):
|
|
91
95
|
"""Generate intro message with help."""
|
|
92
96
|
intro = f"\n{Colors.BOLD}Welcome to AbstractVoice CLI REPL{Colors.END}\n"
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
if self.voice_manager:
|
|
98
|
+
lang_name = self.voice_manager.get_language_name()
|
|
99
|
+
intro += f"API: {self.api_url} | Model: {self.model} | Voice: {lang_name}\n"
|
|
100
|
+
else:
|
|
101
|
+
intro += f"API: {self.api_url} | Model: {self.model} | Voice: Disabled\n"
|
|
95
102
|
intro += f"\n{Colors.CYAN}Quick Start:{Colors.END}\n"
|
|
96
103
|
intro += " • Type messages to chat with the LLM\n"
|
|
97
104
|
intro += " • Use /voice <mode> to enable voice input\n"
|
|
@@ -232,7 +239,7 @@ class VoiceREPL(cmd.Cmd):
|
|
|
232
239
|
print(f"{Colors.CYAN}{response_text}{Colors.END}")
|
|
233
240
|
|
|
234
241
|
# Speak the response if voice manager is available
|
|
235
|
-
if self.voice_manager:
|
|
242
|
+
if self.voice_manager and self.use_tts:
|
|
236
243
|
self.voice_manager.speak(response_text)
|
|
237
244
|
|
|
238
245
|
except requests.exceptions.ConnectionError as e:
|
|
@@ -376,18 +383,47 @@ class VoiceREPL(cmd.Cmd):
|
|
|
376
383
|
/setvoice <voice_id> # Set voice (format: language.voice_id)
|
|
377
384
|
|
|
378
385
|
Examples:
|
|
379
|
-
/setvoice # List all voices
|
|
386
|
+
/setvoice # List all voices with JSON-like info
|
|
380
387
|
/setvoice fr.css10_vits # Set French CSS10 VITS voice
|
|
381
388
|
/setvoice it.mai_male_vits # Set Italian male VITS voice
|
|
382
389
|
"""
|
|
383
390
|
if not args:
|
|
384
|
-
# Show all available voices
|
|
391
|
+
# Show all available voices with metadata
|
|
385
392
|
print(f"\n{Colors.CYAN}Available Voice Models:{Colors.END}")
|
|
386
|
-
self.voice_manager.list_voices()
|
|
387
393
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
394
|
+
try:
|
|
395
|
+
models = self.voice_manager.list_available_models()
|
|
396
|
+
|
|
397
|
+
for language, voices in models.items():
|
|
398
|
+
# Get language name
|
|
399
|
+
lang_names = {
|
|
400
|
+
'en': 'English', 'fr': 'French', 'es': 'Spanish',
|
|
401
|
+
'de': 'German', 'it': 'Italian'
|
|
402
|
+
}
|
|
403
|
+
lang_name = lang_names.get(language, language.upper())
|
|
404
|
+
|
|
405
|
+
print(f"\n🌍 {lang_name} ({language}):")
|
|
406
|
+
|
|
407
|
+
for voice_id, voice_info in voices.items():
|
|
408
|
+
cached_icon = "✅" if voice_info.get('cached', False) else "📥"
|
|
409
|
+
quality_icon = "✨" if voice_info['quality'] == 'excellent' else "🔧"
|
|
410
|
+
size_text = f"{voice_info['size_mb']}MB"
|
|
411
|
+
|
|
412
|
+
print(f" {cached_icon} {quality_icon} {language}.{voice_id}")
|
|
413
|
+
print(f" {voice_info['name']} ({size_text})")
|
|
414
|
+
print(f" {voice_info['description']}")
|
|
415
|
+
if voice_info.get('requires_espeak', False):
|
|
416
|
+
print(f" ⚠️ Requires espeak-ng")
|
|
417
|
+
|
|
418
|
+
print(f"\n{Colors.YELLOW}Usage:{Colors.END}")
|
|
419
|
+
print(" /setvoice <language>.<voice_id>")
|
|
420
|
+
print(" Example: /setvoice fr.css10_vits")
|
|
421
|
+
print("\n📥 = Download needed ✅ = Ready ✨ = High quality 🔧 = Good quality")
|
|
422
|
+
|
|
423
|
+
except Exception as e:
|
|
424
|
+
print(f"❌ Error listing models: {e}")
|
|
425
|
+
# Fallback to old method
|
|
426
|
+
self.voice_manager.list_voices()
|
|
391
427
|
return
|
|
392
428
|
|
|
393
429
|
voice_spec = args.strip()
|
|
@@ -412,45 +448,46 @@ class VoiceREPL(cmd.Cmd):
|
|
|
412
448
|
else:
|
|
413
449
|
was_active = False
|
|
414
450
|
|
|
415
|
-
#
|
|
451
|
+
# Download and set the specific voice using programmatic API
|
|
416
452
|
try:
|
|
417
|
-
|
|
453
|
+
print(f"🔄 Setting voice {voice_spec}...")
|
|
454
|
+
|
|
455
|
+
# Use the programmatic download API
|
|
456
|
+
success = self.voice_manager.download_model(voice_spec)
|
|
457
|
+
|
|
418
458
|
if success:
|
|
419
|
-
#
|
|
420
|
-
|
|
459
|
+
# Now set the language to match
|
|
460
|
+
success = self.voice_manager.set_language(language)
|
|
421
461
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
462
|
+
if success:
|
|
463
|
+
# Update current language
|
|
464
|
+
self.current_language = language
|
|
425
465
|
|
|
426
|
-
|
|
427
|
-
print(f" Language: {lang_name} ({language})")
|
|
428
|
-
print(f" Voice: {voice_id}")
|
|
429
|
-
if voice_info:
|
|
430
|
-
quality_icon = "✨" if voice_info.get('quality') == 'premium' else "🔧"
|
|
431
|
-
gender_icon = {"male": "👨", "female": "👩", "multiple": "👥"}.get(voice_info.get('gender'), "🗣️")
|
|
432
|
-
print(f" Details: {quality_icon} {gender_icon} {voice_info.get('accent', 'Unknown accent')}")
|
|
466
|
+
print(f"✅ Voice set to {voice_spec}")
|
|
433
467
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
468
|
+
# Test the voice
|
|
469
|
+
test_messages = {
|
|
470
|
+
'en': 'Voice changed to English.',
|
|
471
|
+
'fr': 'Voix changée en français.',
|
|
472
|
+
'es': 'Voz cambiada al español.',
|
|
473
|
+
'de': 'Stimme auf Deutsch geändert.',
|
|
474
|
+
'it': 'Voce cambiata in italiano.'
|
|
475
|
+
}
|
|
476
|
+
test_msg = test_messages.get(language, f'Voice changed to {language}.')
|
|
477
|
+
self.voice_manager.speak(test_msg)
|
|
444
478
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
479
|
+
# Restart voice mode if it was active
|
|
480
|
+
if was_active:
|
|
481
|
+
self.do_voice(self.voice_mode)
|
|
482
|
+
else:
|
|
483
|
+
print(f"❌ Failed to set language: {language}")
|
|
448
484
|
else:
|
|
449
|
-
print(f"❌ Failed to
|
|
450
|
-
print(
|
|
485
|
+
print(f"❌ Failed to download voice: {voice_spec}")
|
|
486
|
+
print(" Check your internet connection or try a different voice")
|
|
451
487
|
|
|
452
488
|
except Exception as e:
|
|
453
489
|
print(f"❌ Error setting voice: {e}")
|
|
490
|
+
print(f" Run '/setvoice' to see available voices")
|
|
454
491
|
if self.debug_mode:
|
|
455
492
|
import traceback
|
|
456
493
|
traceback.print_exc()
|