Dionyssos commited on
Commit
4964a1b
·
1 Parent(s): b2b0a60
Files changed (3) hide show
  1. README.md +1 -1
  2. espeak_util.py +206 -0
  3. packages.txt +1 -0
README.md CHANGED
@@ -6,7 +6,7 @@ colorTo: gray
6
  sdk: gradio
7
  sdk_version: 5.41.1
8
  app_file: app.py
9
- short_description: TTS for CPU
10
  license: cc-by-nc-4.0
11
  tags:
12
  - non-AR
 
6
  sdk: gradio
7
  sdk_version: 5.41.1
8
  app_file: app.py
9
+ short_description: https://shift-europe.eu/
10
  license: cc-by-nc-4.0
11
  tags:
12
  - non-AR
espeak_util.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import platform
2
+ import subprocess
3
+ import shutil
4
+ from pathlib import Path
5
+ import os
6
+ from typing import Optional, Tuple
7
+ from phonemizer.backend.espeak.wrapper import EspeakWrapper
8
+
9
+
10
+ class EspeakConfig:
11
+ """Utility class for configuring espeak-ng library and binary."""
12
+
13
+ @staticmethod
14
+ def find_espeak_binary() -> tuple[bool, Optional[str]]:
15
+ """
16
+ Find espeak-ng binary using multiple methods.
17
+
18
+ Returns:
19
+ tuple: (bool indicating if espeak is available, path to espeak binary if found)
20
+ """
21
+ # Common binary names
22
+ binary_names = ["espeak-ng", "espeak"]
23
+ if platform.system() == "Windows":
24
+ binary_names = ["espeak-ng.exe", "espeak.exe"]
25
+
26
+ # Common installation directories for Linux
27
+ linux_paths = [
28
+ "/usr/bin",
29
+ "/usr/local/bin",
30
+ "/usr/lib/espeak-ng",
31
+ "/usr/local/lib/espeak-ng",
32
+ "/opt/espeak-ng/bin",
33
+ ]
34
+
35
+ # First check if it's in PATH
36
+ for name in binary_names:
37
+ espeak_path = shutil.which(name)
38
+ if espeak_path:
39
+ return True, espeak_path
40
+
41
+ # For Linux, check common installation directories
42
+ if platform.system() == "Linux":
43
+ for directory in linux_paths:
44
+ for name in binary_names:
45
+ path = Path(directory) / name
46
+ if path.exists():
47
+ return True, str(path)
48
+
49
+ # Try running the command directly as a last resort
50
+ try:
51
+ subprocess.run(
52
+ ["espeak-ng", "--version"],
53
+ stdout=subprocess.PIPE,
54
+ stderr=subprocess.PIPE,
55
+ check=True,
56
+ )
57
+ return True, "espeak-ng"
58
+ except (subprocess.SubprocessError, FileNotFoundError):
59
+ pass
60
+
61
+ return False, None
62
+
63
+ @staticmethod
64
+ def find_library_path() -> Optional[str]:
65
+ """
66
+ Find the espeak-ng library using multiple search methods.
67
+
68
+ Returns:
69
+ Optional[str]: Path to the library if found, None otherwise
70
+ """
71
+ system = platform.system()
72
+
73
+ if system == "Linux":
74
+ lib_names = ["libespeak-ng.so", "libespeak-ng.so.1"]
75
+ common_paths = [
76
+ # Debian/Ubuntu paths
77
+ "/usr/lib/x86_64-linux-gnu",
78
+ "/usr/lib/aarch64-linux-gnu", # For ARM64
79
+ "/usr/lib/arm-linux-gnueabihf", # For ARM32
80
+ "/usr/lib",
81
+ "/usr/local/lib",
82
+ # Fedora/RHEL paths
83
+ "/usr/lib64",
84
+ "/usr/lib32",
85
+ # Common additional paths
86
+ "/usr/lib/espeak-ng",
87
+ "/usr/local/lib/espeak-ng",
88
+ "/opt/espeak-ng/lib",
89
+ ]
90
+
91
+ # Check common locations first
92
+ for path in common_paths:
93
+ for lib_name in lib_names:
94
+ lib_path = Path(path) / lib_name
95
+ if lib_path.exists():
96
+ return str(lib_path)
97
+
98
+ # Search system library paths
99
+ try:
100
+ # Use ldconfig to find the library
101
+ result = subprocess.run(
102
+ ["ldconfig", "-p"], capture_output=True, text=True, check=True
103
+ )
104
+ for line in result.stdout.splitlines():
105
+ if "libespeak-ng.so" in line:
106
+ # Extract path from ldconfig output
107
+ return line.split("=>")[-1].strip()
108
+ except (subprocess.SubprocessError, FileNotFoundError):
109
+ pass
110
+
111
+ elif system == "Darwin": # macOS
112
+ common_paths = [
113
+ Path("/opt/homebrew/lib/libespeak-ng.dylib"),
114
+ Path("/usr/local/lib/libespeak-ng.dylib"),
115
+ *list(
116
+ Path("/opt/homebrew/Cellar/espeak-ng").glob(
117
+ "*/lib/libespeak-ng.dylib"
118
+ )
119
+ ),
120
+ *list(
121
+ Path("/usr/local/Cellar/espeak-ng").glob("*/lib/libespeak-ng.dylib")
122
+ ),
123
+ ]
124
+
125
+ for path in common_paths:
126
+ if path.exists():
127
+ return str(path)
128
+
129
+ elif system == "Windows":
130
+ common_paths = [
131
+ Path(os.environ.get("PROGRAMFILES", "C:\\Program Files"))
132
+ / "eSpeak NG"
133
+ / "libespeak-ng.dll",
134
+ Path(os.environ.get("PROGRAMFILES(X86)", "C:\\Program Files (x86)"))
135
+ / "eSpeak NG"
136
+ / "libespeak-ng.dll",
137
+ *[
138
+ Path(p) / "libespeak-ng.dll"
139
+ for p in os.environ.get("PATH", "").split(os.pathsep)
140
+ ],
141
+ ]
142
+
143
+ for path in common_paths:
144
+ if path.exists():
145
+ return str(path)
146
+
147
+ return None
148
+
149
+ @classmethod
150
+ def configure_espeak(cls) -> Tuple[bool, str]:
151
+ """
152
+ Configure espeak-ng for use with the phonemizer.
153
+
154
+ Returns:
155
+ Tuple[bool, str]: (Success status, Status message)
156
+ """
157
+ # First check if espeak binary is available
158
+ espeak_available, espeak_path = cls.find_espeak_binary()
159
+ if not espeak_available:
160
+ raise FileNotFoundError(
161
+ "Could not find espeak-ng binary. Please install espeak-ng:\n"
162
+ "Ubuntu/Debian: sudo apt-get install espeak-ng espeak-ng-data\n"
163
+ "Fedora: sudo dnf install espeak-ng\n"
164
+ "Arch: sudo pacman -S espeak-ng\n"
165
+ "MacOS: brew install espeak-ng\n"
166
+ "Windows: Download from https://github.com/espeak-ng/espeak-ng/releases"
167
+ )
168
+
169
+ # Find the library
170
+ library_path = cls.find_library_path()
171
+ if not library_path:
172
+ # On Linux, we might not need to explicitly set the library path
173
+ if platform.system() == "Linux":
174
+ return True, f"Using system espeak-ng installation at: {espeak_path}"
175
+ else:
176
+ raise FileNotFoundError(
177
+ "Could not find espeak-ng library. Please ensure espeak-ng is properly installed."
178
+ )
179
+
180
+ # Try to set the library path
181
+ try:
182
+ EspeakWrapper.set_library(library_path)
183
+ return True, f"Successfully configured espeak-ng library at: {library_path}"
184
+ except Exception as e:
185
+ if platform.system() == "Linux":
186
+ # On Linux, try to continue without explicit library path
187
+ return True, f"Using system espeak-ng installation at: {espeak_path}"
188
+ else:
189
+ raise RuntimeError(f"Failed to configure espeak-ng library: {str(e)}")
190
+
191
+
192
+ def setup_espeak():
193
+ """
194
+ Set up espeak-ng for use with the phonemizer.
195
+ Raises appropriate exceptions if setup fails.
196
+ """
197
+ try:
198
+ success, message = EspeakConfig.configure_espeak()
199
+ print(message)
200
+ except Exception as e:
201
+ print(f"Error configuring espeak-ng: {str(e)}")
202
+ raise
203
+
204
+
205
+ # Replace the original set_espeak_library function with this
206
+ set_espeak_library = setup_espeak
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ espeak-ng