snackshell commited on
Commit
e8ac110
·
verified ·
1 Parent(s): b1772e2

Upload 5 files

Browse files
Files changed (5) hide show
  1. .gitattributes +35 -35
  2. LICENSE +21 -0
  3. app.py +105 -0
  4. assets/demo.png +0 -0
  5. requirements.txt +5 -0
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Snackshell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
app.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tempfile
2
+ import edge_tts
3
+ import gradio as gr
4
+ import asyncio
5
+
6
+ # --- Final, VERIFIED Language & Voice Configuration ---
7
+ language_dict = {
8
+ "English": {
9
+ "Jenny (Female, US)": "en-US-JennyNeural",
10
+ "Andrew (Male, US)": "en-US-AndrewNeural",
11
+ "Sonia (Female, UK)": "en-GB-SoniaNeural",
12
+ "Ryan (Male, UK)": "en-GB-RyanNeural"
13
+ },
14
+ "Amharic": {
15
+ "Mekdes (Female)": "am-ET-MekdesNeural",
16
+ "Ameha (Male)": "am-ET-AmehaNeural"
17
+ },
18
+ "Tigrinya": {
19
+ # WORKAROUND: Using Amharic voices as a fallback for Tigrinya.
20
+ "Lulia (Female)": "am-ET-MekdesNeural",
21
+ "Birhane (Male)": "am-ET-AmehaNeural"
22
+ },
23
+ "Arabic": {
24
+ "Zariyah (Female, KSA)": "ar-SA-ZariyahNeural",
25
+ "Hamed (Male, KSA)": "ar-SA-HamedNeural"
26
+ },
27
+ "French": {
28
+ "Denise (Female)": "fr-FR-DeniseNeural",
29
+ "Henri (Male)": "fr-FR-HenriNeural"
30
+ },
31
+ "German": {
32
+ "Katja (Female)": "de-DE-KatjaNeural",
33
+ "Conrad (Male)": "de-DE-ConradNeural"
34
+ },
35
+ "Italian": {
36
+ "Elsa (Female)": "it-IT-ElsaNeural",
37
+ "Diego (Male)": "it-IT-DiegoNeural"
38
+ },
39
+ "Japanese": {
40
+ "Nanami (Female)": "ja-JP-NanamiNeural",
41
+ "Keita (Male)": "ja-JP-KeitaNeural"
42
+ },
43
+ "Korean": {
44
+ "Sun-Hi (Female)": "ko-KR-SunHiNeural",
45
+ "InJoon (Male)": "ko-KR-InJoonNeural"
46
+ },
47
+ "Chinese (Simplified)": {
48
+ "Xiaoxiao (Female)": "zh-CN-XiaoxiaoNeural",
49
+ "Yunxi (Male)": "zh-CN-YunxiNeural"
50
+ },
51
+ "Chinese (Traditional)": {
52
+ "HsiaoChen (Female)": "zh-TW-HsiaoChenNeural",
53
+ "YunJhe (Male)": "zh-TW-YunJheNeural"
54
+ }
55
+ }
56
+
57
+ async def text_to_speech_edge(text, language, speaker):
58
+ try:
59
+ voice = language_dict[language][speaker]
60
+ except KeyError:
61
+ raise gr.Error(f"Error: Voice '{speaker}' not found for {language}.")
62
+
63
+ try:
64
+ communicate = edge_tts.Communicate(text, voice)
65
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
66
+ tmp_path = tmp_file.name
67
+ await asyncio.wait_for(communicate.save(tmp_path), timeout=60)
68
+ return tmp_path
69
+
70
+ except asyncio.TimeoutError:
71
+ raise gr.Error("Error: Request timed out. Please try again.")
72
+ except Exception as e:
73
+ raise gr.Error(f"An unexpected error occurred: {str(e)}")
74
+
75
+ def update_speakers(language):
76
+ speakers = list(language_dict.get(language, []))
77
+ return gr.Dropdown(choices=speakers, value=speakers[0] if speakers else None, interactive=True)
78
+
79
+ # --- Gradio Interface ---
80
+ with gr.Blocks(title="SelamGPT TTS", theme=gr.themes.Soft()) as demo:
81
+ gr.Markdown("# SelamGPT Text-to-Speech")
82
+
83
+ with gr.Row():
84
+ language = gr.Dropdown(
85
+ choices=list(language_dict.keys()),
86
+ value="Amharic",
87
+ label="Language"
88
+ )
89
+ speaker = gr.Dropdown(
90
+ label="Speaker",
91
+ choices=list(language_dict["Amharic"].keys()),
92
+ value="Mekdes (Female)"
93
+ )
94
+
95
+ with gr.Column():
96
+ input_text = gr.Textbox(label="Input Text", placeholder="Enter text here...")
97
+ generate_btn = gr.Button("Generate Audio", variant="primary")
98
+
99
+ output_audio = gr.Audio(label="Output Audio", autoplay=True)
100
+
101
+ language.change(fn=update_speakers, inputs=language, outputs=speaker)
102
+ generate_btn.click(fn=text_to_speech_edge, inputs=[input_text, language, speaker], outputs=output_audio)
103
+
104
+ if __name__ == "__main__":
105
+ demo.launch()
assets/demo.png ADDED
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio
2
+ edge-tts
3
+ pyarabic
4
+ gradio-client
5
+ transformers