termux-tts 1.4.1 → 1.4.3
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.
- package/.github/workflows/release.yml +98 -82
- package/CHANGELOG.md +29 -8
- package/README.md +384 -57
- package/README.pypi.md +413 -26
- package/package.json +29 -4
- package/pyproject.toml +37 -1
- package/setup.py +1 -1
- package/termux_tts/__init__.py +63 -63
- package/termux_tts/installer.py +66 -6
package/termux_tts/__init__.py
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
"""
|
|
2
|
-
termux-tts: Production-Grade 4-Tier TTS Framework for Android Termux.
|
|
3
|
-
- Tier 1: Parametric DSP Formant Synthesizer Engine (0MB Zero-Dependency)
|
|
4
|
-
- Tier 2: Android System Native Voice Engine Bridge (Samsung / Google Voice)
|
|
5
|
-
- Tier 3: Authentic C++ Subprocess-Isolated Sherpa-ONNX Neural Vocoder (VITS Deep Learning)
|
|
6
|
-
- Tier 4: Pure On-Device Expressive Emotional Synthesizer (Conversational Tags)
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from .engine import TTSEngine, load, doctor
|
|
10
|
-
from .engine_native import NativeAndroidEngine, NativeResult
|
|
11
|
-
from .engine_dsp import ParametricDSPEngine, DSPResult, QUALITY_PRESETS, DSPSynthesizer
|
|
12
|
-
from .engine_sherpa import SherpaNeuralEngine, SherpaResult
|
|
13
|
-
from .engine_vulkan import VulkanNeuralEngine, VulkanResult
|
|
14
|
-
from .engine_expressive import ExpressiveEngine, ExpressiveResult
|
|
15
|
-
from .installer import run_installation
|
|
16
|
-
from .tokenizer import PhoneticTokenizer, EXPRESSIVE_TAGS
|
|
17
|
-
from .g2p_korean import KoreanG2PEngine, korean_text_to_phonemes
|
|
18
|
-
from .audio import AudioBuffer
|
|
19
|
-
from .exceptions import (
|
|
20
|
-
TTSError,
|
|
21
|
-
TTSModelLoadError,
|
|
22
|
-
TTSInferenceError,
|
|
23
|
-
VulkanInitializationError,
|
|
24
|
-
TTSAudioEncodingError,
|
|
25
|
-
TTSLanguageNotSupportedError
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
# Backward-compatibility alias
|
|
29
|
-
ONNXNeuralEngine = SherpaNeuralEngine
|
|
30
|
-
ONNXResult = SherpaResult
|
|
31
|
-
|
|
32
|
-
__version__ = "1.4.
|
|
33
|
-
__all__ = [
|
|
34
|
-
"TTSEngine",
|
|
35
|
-
"load",
|
|
36
|
-
"doctor",
|
|
37
|
-
"ParametricDSPEngine",
|
|
38
|
-
"DSPSynthesizer",
|
|
39
|
-
"DSPResult",
|
|
40
|
-
"NativeAndroidEngine",
|
|
41
|
-
"NativeResult",
|
|
42
|
-
"SherpaNeuralEngine",
|
|
43
|
-
"SherpaResult",
|
|
44
|
-
"VulkanNeuralEngine",
|
|
45
|
-
"VulkanResult",
|
|
46
|
-
"ExpressiveEngine",
|
|
47
|
-
"ExpressiveResult",
|
|
48
|
-
"run_installation",
|
|
49
|
-
"ONNXNeuralEngine",
|
|
50
|
-
"ONNXResult",
|
|
51
|
-
"QUALITY_PRESETS",
|
|
52
|
-
"PhoneticTokenizer",
|
|
53
|
-
"KoreanG2PEngine",
|
|
54
|
-
"korean_text_to_phonemes",
|
|
55
|
-
"EXPRESSIVE_TAGS",
|
|
56
|
-
"AudioBuffer",
|
|
57
|
-
"TTSError",
|
|
58
|
-
"TTSModelLoadError",
|
|
59
|
-
"TTSInferenceError",
|
|
60
|
-
"VulkanInitializationError",
|
|
61
|
-
"TTSAudioEncodingError",
|
|
62
|
-
"TTSLanguageNotSupportedError"
|
|
63
|
-
]
|
|
1
|
+
"""
|
|
2
|
+
termux-tts: Production-Grade 4-Tier TTS Framework for Android Termux.
|
|
3
|
+
- Tier 1: Parametric DSP Formant Synthesizer Engine (0MB Zero-Dependency)
|
|
4
|
+
- Tier 2: Android System Native Voice Engine Bridge (Samsung / Google Voice)
|
|
5
|
+
- Tier 3: Authentic C++ Subprocess-Isolated Sherpa-ONNX Neural Vocoder (VITS Deep Learning)
|
|
6
|
+
- Tier 4: Pure On-Device Expressive Emotional Synthesizer (Conversational Tags)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .engine import TTSEngine, load, doctor
|
|
10
|
+
from .engine_native import NativeAndroidEngine, NativeResult
|
|
11
|
+
from .engine_dsp import ParametricDSPEngine, DSPResult, QUALITY_PRESETS, DSPSynthesizer
|
|
12
|
+
from .engine_sherpa import SherpaNeuralEngine, SherpaResult
|
|
13
|
+
from .engine_vulkan import VulkanNeuralEngine, VulkanResult
|
|
14
|
+
from .engine_expressive import ExpressiveEngine, ExpressiveResult
|
|
15
|
+
from .installer import run_installation
|
|
16
|
+
from .tokenizer import PhoneticTokenizer, EXPRESSIVE_TAGS
|
|
17
|
+
from .g2p_korean import KoreanG2PEngine, korean_text_to_phonemes
|
|
18
|
+
from .audio import AudioBuffer
|
|
19
|
+
from .exceptions import (
|
|
20
|
+
TTSError,
|
|
21
|
+
TTSModelLoadError,
|
|
22
|
+
TTSInferenceError,
|
|
23
|
+
VulkanInitializationError,
|
|
24
|
+
TTSAudioEncodingError,
|
|
25
|
+
TTSLanguageNotSupportedError
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Backward-compatibility alias
|
|
29
|
+
ONNXNeuralEngine = SherpaNeuralEngine
|
|
30
|
+
ONNXResult = SherpaResult
|
|
31
|
+
|
|
32
|
+
__version__ = "1.4.3"
|
|
33
|
+
__all__ = [
|
|
34
|
+
"TTSEngine",
|
|
35
|
+
"load",
|
|
36
|
+
"doctor",
|
|
37
|
+
"ParametricDSPEngine",
|
|
38
|
+
"DSPSynthesizer",
|
|
39
|
+
"DSPResult",
|
|
40
|
+
"NativeAndroidEngine",
|
|
41
|
+
"NativeResult",
|
|
42
|
+
"SherpaNeuralEngine",
|
|
43
|
+
"SherpaResult",
|
|
44
|
+
"VulkanNeuralEngine",
|
|
45
|
+
"VulkanResult",
|
|
46
|
+
"ExpressiveEngine",
|
|
47
|
+
"ExpressiveResult",
|
|
48
|
+
"run_installation",
|
|
49
|
+
"ONNXNeuralEngine",
|
|
50
|
+
"ONNXResult",
|
|
51
|
+
"QUALITY_PRESETS",
|
|
52
|
+
"PhoneticTokenizer",
|
|
53
|
+
"KoreanG2PEngine",
|
|
54
|
+
"korean_text_to_phonemes",
|
|
55
|
+
"EXPRESSIVE_TAGS",
|
|
56
|
+
"AudioBuffer",
|
|
57
|
+
"TTSError",
|
|
58
|
+
"TTSModelLoadError",
|
|
59
|
+
"TTSInferenceError",
|
|
60
|
+
"VulkanInitializationError",
|
|
61
|
+
"TTSAudioEncodingError",
|
|
62
|
+
"TTSLanguageNotSupportedError"
|
|
63
|
+
]
|
|
64
64
|
|
package/termux_tts/installer.py
CHANGED
|
@@ -9,10 +9,37 @@ import urllib.request
|
|
|
9
9
|
import shutil
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
def get_candidate_vulkan_binary_urls():
|
|
13
|
+
"""Generate dynamic candidate endpoints for Vulkan binary provisioner."""
|
|
14
|
+
try:
|
|
15
|
+
from . import __version__
|
|
16
|
+
except Exception:
|
|
17
|
+
__version__ = "1.4.3"
|
|
18
|
+
|
|
19
|
+
urls = []
|
|
20
|
+
custom_tag = os.environ.get("TERMUX_TTS_RELEASE_TAG", "").strip()
|
|
21
|
+
custom_base = os.environ.get("TERMUX_TTS_RELEASE_BASE", "").strip()
|
|
22
|
+
|
|
23
|
+
if custom_base:
|
|
24
|
+
urls.append(f"{custom_base.rstrip('/')}/sherpa-ncnn-offline-tts-vulkan-arm64.tar.gz")
|
|
25
|
+
if custom_tag:
|
|
26
|
+
tag = custom_tag if custom_tag.startswith("v") else f"v{custom_tag}"
|
|
27
|
+
urls.append(f"https://github.com/uno-km/termux-tts/releases/download/{tag}/sherpa-ncnn-offline-tts-vulkan-arm64.tar.gz")
|
|
28
|
+
|
|
29
|
+
# 1. termux-tts current version SSOT
|
|
30
|
+
current_tag = f"v{__version__}"
|
|
31
|
+
urls.append(f"https://github.com/uno-km/termux-tts/releases/download/{current_tag}/sherpa-ncnn-offline-tts-vulkan-arm64.tar.gz")
|
|
32
|
+
|
|
33
|
+
# 2. termux-tts latest release
|
|
34
|
+
urls.append("https://github.com/uno-km/termux-tts/releases/latest/download/sherpa-ncnn-offline-tts-vulkan-arm64.tar.gz")
|
|
35
|
+
|
|
36
|
+
# 3. ameva-runtime unified SSOT ecosystem release fallback
|
|
37
|
+
urls.append("https://github.com/uno-km/ameva-runtime/releases/latest/download/sherpa-ncnn-offline-tts-vulkan-arm64.tar.gz")
|
|
38
|
+
|
|
39
|
+
# 4. Companion release fallback
|
|
40
|
+
urls.append("https://github.com/uno-km/termux-sherpa-ncnn/releases/download/v1.0.0-vulkan/sherpa-ncnn-offline-tts-vulkan-arm64.tar.gz")
|
|
41
|
+
|
|
42
|
+
return urls
|
|
16
43
|
|
|
17
44
|
MODEL_REGISTRY = {
|
|
18
45
|
"high": {
|
|
@@ -48,8 +75,13 @@ def get_install_paths():
|
|
|
48
75
|
return bin_dir, cache_dir
|
|
49
76
|
|
|
50
77
|
def download_with_progress(url: str, dest_path: Path, label: str):
|
|
78
|
+
try:
|
|
79
|
+
from . import __version__
|
|
80
|
+
except Exception:
|
|
81
|
+
__version__ = "1.4.3"
|
|
82
|
+
|
|
51
83
|
print(f" [DOWNLOADING] {label}...")
|
|
52
|
-
req = urllib.request.Request(url, headers={"User-Agent": "termux-tts-installer/
|
|
84
|
+
req = urllib.request.Request(url, headers={"User-Agent": f"termux-tts-installer/{__version__} (Android; ARM64)"})
|
|
53
85
|
with urllib.request.urlopen(req) as resp, open(dest_path, "wb") as out_f:
|
|
54
86
|
total = int(resp.headers.get("Content-Length", 0))
|
|
55
87
|
downloaded = 0
|
|
@@ -69,13 +101,30 @@ def download_with_progress(url: str, dest_path: Path, label: str):
|
|
|
69
101
|
def install_vulkan_binary(force: bool = False) -> Path:
|
|
70
102
|
bin_dir, _ = get_install_paths()
|
|
71
103
|
binary_path = bin_dir / "sherpa-ncnn-offline-tts"
|
|
104
|
+
prefix_bin = Path(os.environ.get("PREFIX", "/data/data/com.termux/files/usr")) / "bin"
|
|
72
105
|
|
|
73
106
|
if binary_path.exists() and not force:
|
|
74
107
|
print(f" [OK] Pre-compiled Vulkan binary already exists: {binary_path}")
|
|
75
108
|
return binary_path
|
|
76
109
|
|
|
77
110
|
tar_path = bin_dir / "sherpa-vulkan.tar.gz"
|
|
78
|
-
|
|
111
|
+
candidate_urls = get_candidate_vulkan_binary_urls()
|
|
112
|
+
download_success = False
|
|
113
|
+
|
|
114
|
+
for url in candidate_urls:
|
|
115
|
+
try:
|
|
116
|
+
download_with_progress(url, tar_path, f"ARM64 Vulkan Binary ({url})")
|
|
117
|
+
if tar_path.exists() and tar_path.stat().st_size > 500 * 1024:
|
|
118
|
+
download_success = True
|
|
119
|
+
break
|
|
120
|
+
except Exception as dl_err:
|
|
121
|
+
print(f" [-] Candidate URL failed ({url}): {dl_err}")
|
|
122
|
+
if tar_path.exists():
|
|
123
|
+
tar_path.unlink(missing_ok=True)
|
|
124
|
+
continue
|
|
125
|
+
|
|
126
|
+
if not download_success:
|
|
127
|
+
raise RuntimeError("Failed to download sherpa-ncnn-offline-tts from any candidate endpoints.")
|
|
79
128
|
|
|
80
129
|
print(" [EXTRACTING] Installing binary to ~/.local/bin...")
|
|
81
130
|
with tarfile.open(tar_path, "r:gz") as tar:
|
|
@@ -83,6 +132,17 @@ def install_vulkan_binary(force: bool = False) -> Path:
|
|
|
83
132
|
|
|
84
133
|
tar_path.unlink(missing_ok=True)
|
|
85
134
|
binary_path.chmod(0o755)
|
|
135
|
+
|
|
136
|
+
# Dual-path installation to PREFIX/bin if writable
|
|
137
|
+
try:
|
|
138
|
+
if prefix_bin.exists() and os.access(prefix_bin, os.W_OK):
|
|
139
|
+
target_prefix_bin = prefix_bin / "sherpa-ncnn-offline-tts"
|
|
140
|
+
shutil.copy2(binary_path, target_prefix_bin)
|
|
141
|
+
target_prefix_bin.chmod(0o755)
|
|
142
|
+
print(f" [SYMLINK/COPY] Linked to {target_prefix_bin}")
|
|
143
|
+
except OSError:
|
|
144
|
+
pass
|
|
145
|
+
|
|
86
146
|
print(f" [SUCCESS] Installed: {binary_path}")
|
|
87
147
|
return binary_path
|
|
88
148
|
|