abstractvoice 0.5.1__py3-none-any.whl → 0.6.1__py3-none-any.whl

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.
Files changed (51) hide show
  1. abstractvoice/__init__.py +2 -5
  2. abstractvoice/__main__.py +82 -3
  3. abstractvoice/adapters/__init__.py +12 -0
  4. abstractvoice/adapters/base.py +207 -0
  5. abstractvoice/adapters/stt_faster_whisper.py +401 -0
  6. abstractvoice/adapters/tts_piper.py +480 -0
  7. abstractvoice/aec/__init__.py +10 -0
  8. abstractvoice/aec/webrtc_apm.py +56 -0
  9. abstractvoice/artifacts.py +173 -0
  10. abstractvoice/audio/__init__.py +7 -0
  11. abstractvoice/audio/recorder.py +46 -0
  12. abstractvoice/audio/resample.py +25 -0
  13. abstractvoice/cloning/__init__.py +7 -0
  14. abstractvoice/cloning/engine_chroma.py +738 -0
  15. abstractvoice/cloning/engine_f5.py +546 -0
  16. abstractvoice/cloning/manager.py +349 -0
  17. abstractvoice/cloning/store.py +362 -0
  18. abstractvoice/compute/__init__.py +6 -0
  19. abstractvoice/compute/device.py +73 -0
  20. abstractvoice/config/__init__.py +2 -0
  21. abstractvoice/config/voice_catalog.py +19 -0
  22. abstractvoice/dependency_check.py +0 -1
  23. abstractvoice/examples/cli_repl.py +2403 -243
  24. abstractvoice/examples/voice_cli.py +64 -63
  25. abstractvoice/integrations/__init__.py +2 -0
  26. abstractvoice/integrations/abstractcore.py +116 -0
  27. abstractvoice/integrations/abstractcore_plugin.py +253 -0
  28. abstractvoice/prefetch.py +82 -0
  29. abstractvoice/recognition.py +424 -42
  30. abstractvoice/stop_phrase.py +103 -0
  31. abstractvoice/tts/__init__.py +3 -3
  32. abstractvoice/tts/adapter_tts_engine.py +210 -0
  33. abstractvoice/tts/tts_engine.py +257 -1208
  34. abstractvoice/vm/__init__.py +2 -0
  35. abstractvoice/vm/common.py +21 -0
  36. abstractvoice/vm/core.py +139 -0
  37. abstractvoice/vm/manager.py +108 -0
  38. abstractvoice/vm/stt_mixin.py +158 -0
  39. abstractvoice/vm/tts_mixin.py +550 -0
  40. abstractvoice/voice_manager.py +6 -1061
  41. abstractvoice-0.6.1.dist-info/METADATA +213 -0
  42. abstractvoice-0.6.1.dist-info/RECORD +52 -0
  43. {abstractvoice-0.5.1.dist-info → abstractvoice-0.6.1.dist-info}/WHEEL +1 -1
  44. abstractvoice-0.6.1.dist-info/entry_points.txt +6 -0
  45. abstractvoice/instant_setup.py +0 -83
  46. abstractvoice/simple_model_manager.py +0 -539
  47. abstractvoice-0.5.1.dist-info/METADATA +0 -1458
  48. abstractvoice-0.5.1.dist-info/RECORD +0 -23
  49. abstractvoice-0.5.1.dist-info/entry_points.txt +0 -2
  50. {abstractvoice-0.5.1.dist-info → abstractvoice-0.6.1.dist-info}/licenses/LICENSE +0 -0
  51. {abstractvoice-0.5.1.dist-info → abstractvoice-0.6.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: abstractvoice
3
+ Version: 0.6.1
4
+ Summary: A modular Python library for voice interactions with AI systems
5
+ Author-email: Laurent-Philippe Albou <contact@abstractcore.ai>
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/lpalbou/abstractvoice
8
+ Project-URL: Documentation, https://github.com/lpalbou/abstractvoice#readme
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: numpy>=1.24.0
21
+ Requires-Dist: requests>=2.31.0
22
+ Requires-Dist: appdirs>=1.4.0
23
+ Requires-Dist: piper-tts>=1.2.0
24
+ Requires-Dist: huggingface_hub>=0.20.0
25
+ Requires-Dist: faster-whisper>=0.10.0
26
+ Requires-Dist: sounddevice>=0.4.6
27
+ Requires-Dist: soundfile>=0.12.1
28
+ Requires-Dist: webrtcvad>=2.0.10
29
+ Provides-Extra: voice
30
+ Requires-Dist: sounddevice>=0.4.6; extra == "voice"
31
+ Requires-Dist: webrtcvad>=2.0.10; extra == "voice"
32
+ Requires-Dist: soundfile>=0.12.1; extra == "voice"
33
+ Provides-Extra: audio-fx
34
+ Requires-Dist: librosa>=0.10.0; extra == "audio-fx"
35
+ Provides-Extra: cloning
36
+ Requires-Dist: f5-tts>=1.1.0; extra == "cloning"
37
+ Provides-Extra: chroma
38
+ Requires-Dist: torch>=2.0.0; extra == "chroma"
39
+ Requires-Dist: torchaudio>=2.0.0; extra == "chroma"
40
+ Requires-Dist: torchvision>=0.15.0; extra == "chroma"
41
+ Requires-Dist: transformers>=5.0.0rc0; extra == "chroma"
42
+ Requires-Dist: accelerate>=1.0.0; extra == "chroma"
43
+ Requires-Dist: av>=14.0.0; extra == "chroma"
44
+ Requires-Dist: librosa>=0.11.0; extra == "chroma"
45
+ Requires-Dist: audioread>=3.0.0; extra == "chroma"
46
+ Requires-Dist: pillow>=11.0.0; extra == "chroma"
47
+ Requires-Dist: safetensors>=0.5.0; extra == "chroma"
48
+ Provides-Extra: aec
49
+ Requires-Dist: aec-audio-processing>=1.0.1; extra == "aec"
50
+ Provides-Extra: stt
51
+ Requires-Dist: openai-whisper>=20230314; extra == "stt"
52
+ Requires-Dist: tiktoken>=0.6.0; extra == "stt"
53
+ Provides-Extra: web
54
+ Requires-Dist: flask>=2.0.0; extra == "web"
55
+ Provides-Extra: all
56
+ Requires-Dist: piper-tts>=1.2.0; extra == "all"
57
+ Requires-Dist: sounddevice>=0.4.6; extra == "all"
58
+ Requires-Dist: webrtcvad>=2.0.10; extra == "all"
59
+ Requires-Dist: openai-whisper>=20230314; extra == "all"
60
+ Requires-Dist: librosa>=0.10.0; extra == "all"
61
+ Requires-Dist: soundfile>=0.12.1; extra == "all"
62
+ Requires-Dist: flask>=2.0.0; extra == "all"
63
+ Requires-Dist: tiktoken>=0.6.0; extra == "all"
64
+ Requires-Dist: f5-tts>=1.1.0; extra == "all"
65
+ Requires-Dist: aec-audio-processing>=1.0.1; extra == "all"
66
+ Provides-Extra: dev
67
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
68
+ Requires-Dist: black>=22.0.0; extra == "dev"
69
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
70
+ Provides-Extra: voice-full
71
+ Requires-Dist: sounddevice>=0.4.6; extra == "voice-full"
72
+ Requires-Dist: webrtcvad>=2.0.10; extra == "voice-full"
73
+ Requires-Dist: openai-whisper>=20230314; extra == "voice-full"
74
+ Requires-Dist: librosa>=0.10.0; extra == "voice-full"
75
+ Requires-Dist: soundfile>=0.12.1; extra == "voice-full"
76
+ Requires-Dist: tiktoken>=0.6.0; extra == "voice-full"
77
+ Provides-Extra: core-stt
78
+ Requires-Dist: openai-whisper>=20230314; extra == "core-stt"
79
+ Requires-Dist: tiktoken>=0.6.0; extra == "core-stt"
80
+ Provides-Extra: audio-only
81
+ Requires-Dist: sounddevice>=0.4.6; extra == "audio-only"
82
+ Requires-Dist: webrtcvad>=2.0.10; extra == "audio-only"
83
+ Requires-Dist: soundfile>=0.12.1; extra == "audio-only"
84
+ Dynamic: license-file
85
+
86
+ # AbstractVoice
87
+
88
+ A modular Python library for **voice I/O** around AI applications.
89
+
90
+ - **TTS (default)**: Piper (cross-platform, no system deps)
91
+ - **STT (default)**: faster-whisper
92
+ - **Local assistant**: `listen()` + `speak()` with playback/listening control
93
+ - **Headless/server**: `speak_to_bytes()` / `speak_to_file()` and `transcribe_*`
94
+
95
+ Status: **alpha** (`0.6.1`). The supported integrator surface is documented in `docs/api.md`.
96
+
97
+ Next: `docs/getting-started.md` (recommended setup + first smoke tests).
98
+
99
+ > AbstractVoice will ultimately be integrated as the voice modality of AbstractFramework.
100
+ > An OpenAI-compatible voice endpoint is an optional demo/integration layer (see backlog).
101
+
102
+ ---
103
+
104
+ ## Install
105
+
106
+ ```bash
107
+ pip install abstractvoice
108
+ ```
109
+
110
+ Optional extras (feature flags):
111
+
112
+ ```bash
113
+ pip install "abstractvoice[all]"
114
+ ```
115
+
116
+ Notes:
117
+ - `abstractvoice[all]` enables most optional features (incl. cloning + AEC + audio-fx), but **does not** include the GPU-heavy Chroma runtime.
118
+ - For the full list of extras (and platform troubleshooting), see `docs/installation.md`.
119
+
120
+ ### Explicit model downloads (recommended; never implicit in the REPL)
121
+
122
+ Some features rely on large model weights/artifacts. AbstractVoice will **not**
123
+ download these implicitly inside the REPL (offline-first).
124
+
125
+ After installing, prefetch explicitly (cross-platform):
126
+
127
+ ```bash
128
+ abstractvoice-prefetch --stt small
129
+ abstractvoice-prefetch --piper en
130
+ abstractvoice-prefetch --openf5
131
+ abstractvoice-prefetch --chroma
132
+ ```
133
+
134
+ Or equivalently:
135
+
136
+ ```bash
137
+ python -m abstractvoice download --stt small
138
+ python -m abstractvoice download --piper en
139
+ python -m abstractvoice download --openf5
140
+ python -m abstractvoice download --chroma
141
+ ```
142
+
143
+ Notes:
144
+ - `--piper <lang>` downloads the Piper ONNX voice for that language into `~/.piper/models`.
145
+ - `--openf5` is ~5.4GB. `--chroma` is very large (GPU-heavy).
146
+
147
+ ---
148
+
149
+ ## Quick smoke tests
150
+
151
+ ### REPL (fastest end-to-end)
152
+
153
+ ```bash
154
+ abstractvoice --verbose
155
+ # or (from a source checkout):
156
+ python -m abstractvoice cli --verbose
157
+ ```
158
+
159
+ Notes:
160
+ - Mic voice input is **off by default** for fast startup. Enable with `--voice-mode stop` (or in-session: `/voice stop`).
161
+ - The REPL is **offline-first**: no implicit model downloads. Use the explicit download commands above.
162
+
163
+ See `docs/repl_guide.md`.
164
+
165
+ ### Minimal Python
166
+
167
+ ```python
168
+ from abstractvoice import VoiceManager
169
+
170
+ vm = VoiceManager()
171
+ vm.speak("Hello! This is AbstractVoice.")
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Public API (stable surface)
177
+
178
+ See `docs/api.md` for the supported integrator contract.
179
+
180
+ At a glance:
181
+ - **TTS**: `speak()`, `stop_speaking()`, `pause_speaking()`, `resume_speaking()`, `speak_to_bytes()`, `speak_to_file()`
182
+ - **STT**: `transcribe_file()`, `transcribe_from_bytes()`
183
+ - **Mic**: `listen()`, `stop_listening()`, `pause_listening()`, `resume_listening()`
184
+
185
+ ---
186
+
187
+ ## Documentation (minimal set)
188
+
189
+ - **Docs index**: `docs/README.md`
190
+ - **Getting started**: `docs/getting-started.md`
191
+ - **FAQ**: `docs/faq.md`
192
+ - **Orientation**: `docs/overview.md`
193
+ - **Acronyms**: `docs/acronyms.md`
194
+ - **Public API**: `docs/api.md`
195
+ - **REPL guide**: `docs/repl_guide.md`
196
+ - **Install troubleshooting**: `docs/installation.md`
197
+ - **Multilingual support**: `docs/multilingual.md`
198
+ - **Architecture (internal)**: `docs/architecture.md` + `docs/adr/`
199
+ - **Model management (Piper-first)**: `docs/model-management.md`
200
+ - **Licensing notes**: `docs/voices-and-licenses.md`
201
+
202
+ ---
203
+
204
+ ## Project
205
+
206
+ - **Changelog**: `CHANGELOG.md`
207
+ - **Contributing**: `CONTRIBUTING.md`
208
+ - **Security**: `SECURITY.md`
209
+ - **Acknowledgments**: `ACKNOWLEDGMENTS.md`
210
+
211
+ ## License
212
+
213
+ MIT. See `LICENSE`.
@@ -0,0 +1,52 @@
1
+ abstractvoice/__init__.py,sha256=Ce_KZwKQ_4G-elHU6G8cqmPMUKSih9NP0tEjDK7JHR4,817
2
+ abstractvoice/__main__.py,sha256=EVhZgFwWHBaeRcz1cVoILCzibCyxpD9V9nCOQiO1yUU,8357
3
+ abstractvoice/artifacts.py,sha256=jHcOK6q4barEh92og1oy52b5p4IqC9AwyKbZzFIitww,5750
4
+ abstractvoice/dependency_check.py,sha256=3iz5-bwCQOJvh1jeC9NO8mmlKjuN5LKZ7ZKVy7zcjQw,10002
5
+ abstractvoice/prefetch.py,sha256=XciaG-OPuOLbAbVauyWJdcVh2oDHuyBMJ9a9bht0kwA,2939
6
+ abstractvoice/recognition.py,sha256=xkCjKGKIfHKLuvM-rcdVVfVzZqhcVUv1sqABnZokgJU,27623
7
+ abstractvoice/stop_phrase.py,sha256=PLUkL2uM6n0J--uFs_O_VeIWN6k2-jNhVlmKBol02ys,3382
8
+ abstractvoice/voice_manager.py,sha256=6M1yT9etb6TQWoAmgqhfGWSex7Blg2bzlLTJZTytL7s,234
9
+ abstractvoice/adapters/__init__.py,sha256=PRhDqLA6cj_fEYMkp54PJ5xrAiEt2oEvE5yVK1MKbP4,452
10
+ abstractvoice/adapters/base.py,sha256=GXmBcwvrVpCCIsNcnClMdvn--ngxMZxp0zjfFvVHYd4,6212
11
+ abstractvoice/adapters/stt_faster_whisper.py,sha256=tbqeN4hpa4v7fxO5tzIAojYEOHikZ7_-QqqiiC3l4tA,14980
12
+ abstractvoice/adapters/tts_piper.py,sha256=Vr-tO7BwripH0YayAlG6YG9nkl_c4jbLkyzXnKn5vnU,17505
13
+ abstractvoice/aec/__init__.py,sha256=jXolI_HFtvCvGT4hYJWDW2Ny8x86vRN8PN14yyVNufw,229
14
+ abstractvoice/aec/webrtc_apm.py,sha256=RK2tWFB01sWjsn5mi5IQAgWX__Jwn74-vPaQJp2ZLfs,1748
15
+ abstractvoice/audio/__init__.py,sha256=xe_De58G3Tn0YOnDb8NWO5mQkONHzpZ6SMZ6KPzE2no,177
16
+ abstractvoice/audio/recorder.py,sha256=nM5kZxoAsPHoXuZwsNXcSdn-j2NM9m9npyBzy1HNy4w,1154
17
+ abstractvoice/audio/resample.py,sha256=R116UgWUfMx4Q2lGn4ntXgsDDpJkRIsY7TlGG4GZP1s,783
18
+ abstractvoice/cloning/__init__.py,sha256=xQlZscgtqR1jEPvZPNzKeapRRdldbV6GUCulELwgHwA,188
19
+ abstractvoice/cloning/engine_chroma.py,sha256=8Qg2j3H0kelILnXBrCdGiun9Ms4KzgIAUgD8fm59-jM,30888
20
+ abstractvoice/cloning/engine_f5.py,sha256=4jpRpYThjr_EDsLekcydVOu5BRurHCe4yv8ZR7BVmO4,21749
21
+ abstractvoice/cloning/manager.py,sha256=Ib6ltqewV6CyrYrVCymBSGoalOEQ73ZU3mxZRZD_7zk,13478
22
+ abstractvoice/cloning/store.py,sha256=yTh_ifIvfQL4DRdNM4XpDKWUrBQu1ajdjXbWgRJFi9s,12840
23
+ abstractvoice/compute/__init__.py,sha256=h_Syj7jesZyP1OAo5UnsFZUQAAnqLXPkMgCzx0nh0Js,193
24
+ abstractvoice/compute/device.py,sha256=IM4hf45RRs8u-ZJI81PSX5i_vI9YJosvuy-XqCImnUU,1875
25
+ abstractvoice/config/__init__.py,sha256=VK2uK7bMbFDL6-WlZV-FXmKO1Ii-ezbwYN-rHo2lUTQ,54
26
+ abstractvoice/config/voice_catalog.py,sha256=py5D2qO4tL_PezEtDRyS48BzkA6MiX_l06BsE-Xa5NA,496
27
+ abstractvoice/examples/__init__.py,sha256=94vpKJDlfOrEBIUETg-57Q5Z7fYDidg6v4UzV7V_lZA,60
28
+ abstractvoice/examples/cli_repl.py,sha256=dO7aauMB4mJ0_RZTqVKSzJp0L5oR0Id_cO7zKbWoftk,128469
29
+ abstractvoice/examples/voice_cli.py,sha256=jJ27H7VtwFTktEixxt4Ne_u5vwcZoTiL7oninqCmjio,11068
30
+ abstractvoice/examples/web_api.py,sha256=0g5LKJpl7fZepPQJL25AcdaevV-xv34VqqyWGYYchPk,6376
31
+ abstractvoice/integrations/__init__.py,sha256=NsLg9ewvcXwBP118n0BDg4ye5KMWdcsHxikhkfaIs5s,61
32
+ abstractvoice/integrations/abstractcore.py,sha256=o_vYCUYThb51GeCeoM-hQ_zz9S_5clVCLT5OZZ0txok,4282
33
+ abstractvoice/integrations/abstractcore_plugin.py,sha256=GMPhxV3NnN47NfUQNKoPdtnWTv8251uoyxaB7kQRC6Q,9637
34
+ abstractvoice/stt/__init__.py,sha256=PFc6la3tTkxT4TJYwb0PnMIahM_hFtU4pNQdeKmbooo,120
35
+ abstractvoice/stt/transcriber.py,sha256=GdaH1OsCHu4Vu9rUsQlzH6X9bfcnoiK5tGz1AW_uj6Q,5481
36
+ abstractvoice/tts/__init__.py,sha256=ca3_xFGK5DZ5-6ffNf8TPle3B0oKZizaBbcZs-e3QzE,190
37
+ abstractvoice/tts/adapter_tts_engine.py,sha256=BFgwF2HuZr26if3NIucQrK-5mlDX2VhVLSzJWkOeEnw,8123
38
+ abstractvoice/tts/tts_engine.py,sha256=XLIHwgZfY1S_kbRvs7S95pegVcbuxbV-BtuZIXqE-ak,12301
39
+ abstractvoice/vad/__init__.py,sha256=RIIbFw25jNHgel06E4VvTWJnXjwjeFZ98m1Vx9hVjuo,119
40
+ abstractvoice/vad/voice_detector.py,sha256=ghrhpDFlIR5TsMB2gpigXY6t5c_1yZ7vEX1imAMgWjc,3166
41
+ abstractvoice/vm/__init__.py,sha256=1nxB3-bH6o-q68jkmpTKRImps2GcMLCMAUE3ZAlMqR8,71
42
+ abstractvoice/vm/common.py,sha256=siNFBNAmQ4nMsivwXRM3jQXfcDB9UNJPd7sOIXJeL50,693
43
+ abstractvoice/vm/core.py,sha256=UL4dFxnggn7ueEmECGS1vRpW7qZMB2FcZjrn3OWXwgU,5305
44
+ abstractvoice/vm/manager.py,sha256=4yZI-LdBUP3LriEyY3kV3dKF25AO8r-JAR3YV-YLmWY,4158
45
+ abstractvoice/vm/stt_mixin.py,sha256=5VZ7lVwsy1yGt0UVA4Ixfvyp-1pHqAQJjv0QmQXAedo,5932
46
+ abstractvoice/vm/tts_mixin.py,sha256=GvPC73YjfkkoA6rYrHYqf_FhbzRMuZVbzQ88QubjDQs,22525
47
+ abstractvoice-0.6.1.dist-info/licenses/LICENSE,sha256=TiDPM5WcFRQPoC5e46jGMeMppZ-eu0eFx_HytjE49bk,1105
48
+ abstractvoice-0.6.1.dist-info/METADATA,sha256=y_oRXVn3EynZkyHmz2w3wmhqHtEHb9SZ4BjF1-OP6M0,7213
49
+ abstractvoice-0.6.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
50
+ abstractvoice-0.6.1.dist-info/entry_points.txt,sha256=PT4IchtBfcgcjlhbX_84WKyCpe-HWzjpNgJ24Kordco,234
51
+ abstractvoice-0.6.1.dist-info/top_level.txt,sha256=a1qyxqgF1O8cJtPKpcJuImGZ_uXqPNghbLZ9gp-UiOo,14
52
+ abstractvoice-0.6.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,6 @@
1
+ [abstractcore.capabilities_plugins]
2
+ abstractvoice = abstractvoice.integrations.abstractcore_plugin:register
3
+
4
+ [console_scripts]
5
+ abstractvoice = abstractvoice.examples.voice_cli:main
6
+ abstractvoice-prefetch = abstractvoice.prefetch:main
@@ -1,83 +0,0 @@
1
- """
2
- Instant Setup Module for AbstractVoice
3
- Provides immediate TTS functionality with seamless model download.
4
- """
5
-
6
- import os
7
- import sys
8
- from pathlib import Path
9
-
10
- # Essential model for instant functionality (lightweight, reliable)
11
- ESSENTIAL_MODEL = "tts_models/en/ljspeech/fast_pitch"
12
- ESSENTIAL_MODEL_SIZE = "~100MB"
13
-
14
- def ensure_instant_tts():
15
- """
16
- Ensure TTS is ready for immediate use.
17
- Downloads essential model if needed with progress indicator.
18
-
19
- Returns:
20
- bool: True if TTS is ready, False if failed
21
- """
22
- try:
23
- from TTS.api import TTS
24
- from TTS.utils.manage import ModelManager
25
-
26
- manager = ModelManager()
27
-
28
- # Check if essential model is already cached
29
- if is_model_cached(ESSENTIAL_MODEL):
30
- return True
31
-
32
- # Download essential model with user-friendly progress
33
- print(f"🚀 AbstractVoice: Setting up TTS ({ESSENTIAL_MODEL_SIZE})...")
34
- print(f" This happens once and takes ~30 seconds")
35
-
36
- try:
37
- # Download with progress bar
38
- tts = TTS(model_name=ESSENTIAL_MODEL, progress_bar=True)
39
- print(f"✅ TTS ready! AbstractVoice is now fully functional.")
40
- return True
41
-
42
- except Exception as e:
43
- print(f"❌ Setup failed: {e}")
44
- print(f"💡 Try: pip install abstractvoice[all]")
45
- return False
46
-
47
- except ImportError as e:
48
- print(f"❌ Missing dependencies: {e}")
49
- print(f"💡 Install with: pip install abstractvoice[all]")
50
- return False
51
-
52
- def is_model_cached(model_name):
53
- """Check if a model is already cached."""
54
- try:
55
- from TTS.utils.manage import ModelManager
56
- manager = ModelManager()
57
-
58
- # Get cached models list
59
- models_file = os.path.join(manager.output_prefix, ".models.json")
60
- if os.path.exists(models_file):
61
- import json
62
- with open(models_file, 'r') as f:
63
- cached_models = json.load(f)
64
- return model_name in cached_models
65
-
66
- # Fallback: check if model directory exists and has content
67
- model_dir = model_name.replace("/", "--")
68
- model_path = os.path.join(manager.output_prefix, model_dir)
69
- return os.path.exists(model_path) and bool(os.listdir(model_path))
70
-
71
- except:
72
- # If anything fails, assume not cached
73
- return False
74
-
75
- def get_instant_model():
76
- """Get the essential model name for instant setup."""
77
- return ESSENTIAL_MODEL
78
-
79
- if __name__ == "__main__":
80
- # CLI test
81
- print("🧪 Testing instant setup...")
82
- success = ensure_instant_tts()
83
- print(f"Result: {'✅ Ready' if success else '❌ Failed'}")