abstractvoice 0.5.2__py3-none-any.whl → 0.6.2__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 (52) 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 +2408 -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/text_sanitize.py +33 -0
  32. abstractvoice/tts/__init__.py +3 -3
  33. abstractvoice/tts/adapter_tts_engine.py +210 -0
  34. abstractvoice/tts/tts_engine.py +257 -1208
  35. abstractvoice/vm/__init__.py +2 -0
  36. abstractvoice/vm/common.py +21 -0
  37. abstractvoice/vm/core.py +139 -0
  38. abstractvoice/vm/manager.py +108 -0
  39. abstractvoice/vm/stt_mixin.py +158 -0
  40. abstractvoice/vm/tts_mixin.py +550 -0
  41. abstractvoice/voice_manager.py +6 -1061
  42. abstractvoice-0.6.2.dist-info/METADATA +213 -0
  43. abstractvoice-0.6.2.dist-info/RECORD +53 -0
  44. {abstractvoice-0.5.2.dist-info → abstractvoice-0.6.2.dist-info}/WHEEL +1 -1
  45. abstractvoice-0.6.2.dist-info/entry_points.txt +6 -0
  46. abstractvoice/instant_setup.py +0 -83
  47. abstractvoice/simple_model_manager.py +0 -539
  48. abstractvoice-0.5.2.dist-info/METADATA +0 -1458
  49. abstractvoice-0.5.2.dist-info/RECORD +0 -23
  50. abstractvoice-0.5.2.dist-info/entry_points.txt +0 -2
  51. {abstractvoice-0.5.2.dist-info → abstractvoice-0.6.2.dist-info}/licenses/LICENSE +0 -0
  52. {abstractvoice-0.5.2.dist-info → abstractvoice-0.6.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: abstractvoice
3
+ Version: 0.6.2
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,53 @@
1
+ abstractvoice/__init__.py,sha256=lR9Enlcyz-n1wcDq3vO2WpeujVAMOP3LzVAtZFr9wA8,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/text_sanitize.py,sha256=9dt_NiwTYWjUOSaVK19Pr9a_HDWOovURQLpevQjgF1A,964
9
+ abstractvoice/voice_manager.py,sha256=6M1yT9etb6TQWoAmgqhfGWSex7Blg2bzlLTJZTytL7s,234
10
+ abstractvoice/adapters/__init__.py,sha256=PRhDqLA6cj_fEYMkp54PJ5xrAiEt2oEvE5yVK1MKbP4,452
11
+ abstractvoice/adapters/base.py,sha256=GXmBcwvrVpCCIsNcnClMdvn--ngxMZxp0zjfFvVHYd4,6212
12
+ abstractvoice/adapters/stt_faster_whisper.py,sha256=tbqeN4hpa4v7fxO5tzIAojYEOHikZ7_-QqqiiC3l4tA,14980
13
+ abstractvoice/adapters/tts_piper.py,sha256=Vr-tO7BwripH0YayAlG6YG9nkl_c4jbLkyzXnKn5vnU,17505
14
+ abstractvoice/aec/__init__.py,sha256=jXolI_HFtvCvGT4hYJWDW2Ny8x86vRN8PN14yyVNufw,229
15
+ abstractvoice/aec/webrtc_apm.py,sha256=RK2tWFB01sWjsn5mi5IQAgWX__Jwn74-vPaQJp2ZLfs,1748
16
+ abstractvoice/audio/__init__.py,sha256=xe_De58G3Tn0YOnDb8NWO5mQkONHzpZ6SMZ6KPzE2no,177
17
+ abstractvoice/audio/recorder.py,sha256=nM5kZxoAsPHoXuZwsNXcSdn-j2NM9m9npyBzy1HNy4w,1154
18
+ abstractvoice/audio/resample.py,sha256=R116UgWUfMx4Q2lGn4ntXgsDDpJkRIsY7TlGG4GZP1s,783
19
+ abstractvoice/cloning/__init__.py,sha256=xQlZscgtqR1jEPvZPNzKeapRRdldbV6GUCulELwgHwA,188
20
+ abstractvoice/cloning/engine_chroma.py,sha256=8Qg2j3H0kelILnXBrCdGiun9Ms4KzgIAUgD8fm59-jM,30888
21
+ abstractvoice/cloning/engine_f5.py,sha256=4jpRpYThjr_EDsLekcydVOu5BRurHCe4yv8ZR7BVmO4,21749
22
+ abstractvoice/cloning/manager.py,sha256=Ib6ltqewV6CyrYrVCymBSGoalOEQ73ZU3mxZRZD_7zk,13478
23
+ abstractvoice/cloning/store.py,sha256=yTh_ifIvfQL4DRdNM4XpDKWUrBQu1ajdjXbWgRJFi9s,12840
24
+ abstractvoice/compute/__init__.py,sha256=h_Syj7jesZyP1OAo5UnsFZUQAAnqLXPkMgCzx0nh0Js,193
25
+ abstractvoice/compute/device.py,sha256=IM4hf45RRs8u-ZJI81PSX5i_vI9YJosvuy-XqCImnUU,1875
26
+ abstractvoice/config/__init__.py,sha256=VK2uK7bMbFDL6-WlZV-FXmKO1Ii-ezbwYN-rHo2lUTQ,54
27
+ abstractvoice/config/voice_catalog.py,sha256=py5D2qO4tL_PezEtDRyS48BzkA6MiX_l06BsE-Xa5NA,496
28
+ abstractvoice/examples/__init__.py,sha256=94vpKJDlfOrEBIUETg-57Q5Z7fYDidg6v4UzV7V_lZA,60
29
+ abstractvoice/examples/cli_repl.py,sha256=VEyJvaqGdithxpjwqM8gOS2DuwPp28oIKMuzEPKTSq4,128751
30
+ abstractvoice/examples/voice_cli.py,sha256=jJ27H7VtwFTktEixxt4Ne_u5vwcZoTiL7oninqCmjio,11068
31
+ abstractvoice/examples/web_api.py,sha256=0g5LKJpl7fZepPQJL25AcdaevV-xv34VqqyWGYYchPk,6376
32
+ abstractvoice/integrations/__init__.py,sha256=NsLg9ewvcXwBP118n0BDg4ye5KMWdcsHxikhkfaIs5s,61
33
+ abstractvoice/integrations/abstractcore.py,sha256=o_vYCUYThb51GeCeoM-hQ_zz9S_5clVCLT5OZZ0txok,4282
34
+ abstractvoice/integrations/abstractcore_plugin.py,sha256=GMPhxV3NnN47NfUQNKoPdtnWTv8251uoyxaB7kQRC6Q,9637
35
+ abstractvoice/stt/__init__.py,sha256=PFc6la3tTkxT4TJYwb0PnMIahM_hFtU4pNQdeKmbooo,120
36
+ abstractvoice/stt/transcriber.py,sha256=GdaH1OsCHu4Vu9rUsQlzH6X9bfcnoiK5tGz1AW_uj6Q,5481
37
+ abstractvoice/tts/__init__.py,sha256=ca3_xFGK5DZ5-6ffNf8TPle3B0oKZizaBbcZs-e3QzE,190
38
+ abstractvoice/tts/adapter_tts_engine.py,sha256=BFgwF2HuZr26if3NIucQrK-5mlDX2VhVLSzJWkOeEnw,8123
39
+ abstractvoice/tts/tts_engine.py,sha256=XLIHwgZfY1S_kbRvs7S95pegVcbuxbV-BtuZIXqE-ak,12301
40
+ abstractvoice/vad/__init__.py,sha256=RIIbFw25jNHgel06E4VvTWJnXjwjeFZ98m1Vx9hVjuo,119
41
+ abstractvoice/vad/voice_detector.py,sha256=ghrhpDFlIR5TsMB2gpigXY6t5c_1yZ7vEX1imAMgWjc,3166
42
+ abstractvoice/vm/__init__.py,sha256=1nxB3-bH6o-q68jkmpTKRImps2GcMLCMAUE3ZAlMqR8,71
43
+ abstractvoice/vm/common.py,sha256=siNFBNAmQ4nMsivwXRM3jQXfcDB9UNJPd7sOIXJeL50,693
44
+ abstractvoice/vm/core.py,sha256=UL4dFxnggn7ueEmECGS1vRpW7qZMB2FcZjrn3OWXwgU,5305
45
+ abstractvoice/vm/manager.py,sha256=4yZI-LdBUP3LriEyY3kV3dKF25AO8r-JAR3YV-YLmWY,4158
46
+ abstractvoice/vm/stt_mixin.py,sha256=5VZ7lVwsy1yGt0UVA4Ixfvyp-1pHqAQJjv0QmQXAedo,5932
47
+ abstractvoice/vm/tts_mixin.py,sha256=GvPC73YjfkkoA6rYrHYqf_FhbzRMuZVbzQ88QubjDQs,22525
48
+ abstractvoice-0.6.2.dist-info/licenses/LICENSE,sha256=TiDPM5WcFRQPoC5e46jGMeMppZ-eu0eFx_HytjE49bk,1105
49
+ abstractvoice-0.6.2.dist-info/METADATA,sha256=mDZobk4G5Bd9FzINxFmxHU9ciCu0Os8vMaLJ06bUOZc,7213
50
+ abstractvoice-0.6.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
51
+ abstractvoice-0.6.2.dist-info/entry_points.txt,sha256=PT4IchtBfcgcjlhbX_84WKyCpe-HWzjpNgJ24Kordco,234
52
+ abstractvoice-0.6.2.dist-info/top_level.txt,sha256=a1qyxqgF1O8cJtPKpcJuImGZ_uXqPNghbLZ9gp-UiOo,14
53
+ abstractvoice-0.6.2.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'}")