Prof-Hunter commited on
Commit
baa7381
·
verified ·
1 Parent(s): 2986145

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -23
app.py CHANGED
@@ -3,13 +3,17 @@ import edge_tts
3
  import asyncio
4
  import tempfile
5
 
 
 
6
 
7
  # -----------------------------
8
- # Voice Loader
9
  # -----------------------------
10
 
11
  async def get_voices():
 
12
  voices = await edge_tts.list_voices()
 
13
  return {
14
  f"{v['ShortName']} - {v['Locale']} ({v['Gender']})": v["ShortName"]
15
  for v in voices
@@ -17,7 +21,7 @@ async def get_voices():
17
 
18
 
19
  # -----------------------------
20
- # TTS Engine
21
  # -----------------------------
22
 
23
  async def text_to_speech(text, voice, rate, pitch):
@@ -44,22 +48,45 @@ async def text_to_speech(text, voice, rate, pitch):
44
  delete=False,
45
  suffix=".mp3",
46
  ) as tmp:
 
47
  path = tmp.name
 
48
  await communicate.save(path)
49
 
50
  return path, None
51
 
52
 
53
- async def tts_interface(text, voice, rate, pitch):
 
 
 
 
 
 
 
 
 
 
54
 
55
- audio, warning = await text_to_speech(
 
56
  text, voice, rate, pitch
57
  )
58
 
59
  if warning:
60
- return audio, gr.Warning(warning)
61
 
62
- return audio, None
 
 
 
 
 
 
 
 
 
 
63
 
64
 
65
  # -----------------------------
@@ -73,52 +100,92 @@ async def create_demo():
73
  with gr.Blocks(analytics_enabled=False) as demo:
74
 
75
  gr.Markdown("""
76
- # 🎙️ AI Text-to-Speech
 
 
77
 
78
- Convert text into natural speech using Microsoft Edge voices.
 
79
  """)
80
 
 
 
 
 
 
81
  text_input = gr.Textbox(
82
  label="Text",
83
  lines=6,
84
- placeholder="Paste lecture notes, narration, or scripts here...",
85
  )
86
 
 
87
  voice_dropdown = gr.Dropdown(
88
  choices=[""] + list(voices.keys()),
89
- label="Voice",
90
- value="",
91
  )
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  with gr.Row():
94
 
95
  rate_slider = gr.Slider(
96
  -50, 50, 0,
97
  step=1,
98
- label="Rate (%)",
99
  )
100
 
101
  pitch_slider = gr.Slider(
102
  -20, 20, 0,
103
  step=1,
104
- label="Pitch (Hz)",
105
  )
106
 
107
 
108
  generate_btn = gr.Button(
109
  "Generate Audio",
110
- variant="primary",
111
  )
112
 
113
 
114
- audio_output = gr.Audio(
115
- label="Output",
116
- type="filepath",
117
- )
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  warning_md = gr.Markdown(visible=False)
120
 
121
 
 
 
 
 
122
  generate_btn.click(
123
  fn=tts_interface,
124
  inputs=[
@@ -126,11 +193,13 @@ async def create_demo():
126
  voice_dropdown,
127
  rate_slider,
128
  pitch_slider,
 
129
  ],
130
  outputs=[
131
- audio_output,
132
- warning_md,
133
- ],
 
134
  )
135
 
136
 
@@ -145,13 +214,12 @@ async def main():
145
 
146
  demo = await create_demo()
147
 
148
- demo.queue(default_concurrency_limit=50)
149
 
150
  demo.launch(
151
  theme=gr.themes.Base()
152
  )
153
 
154
 
155
-
156
  if __name__ == "__main__":
157
  asyncio.run(main())
 
3
  import asyncio
4
  import tempfile
5
 
6
+ from expressive_tts import expressive_tts
7
+
8
 
9
  # -----------------------------
10
+ # Voice Loader (Baseline)
11
  # -----------------------------
12
 
13
  async def get_voices():
14
+
15
  voices = await edge_tts.list_voices()
16
+
17
  return {
18
  f"{v['ShortName']} - {v['Locale']} ({v['Gender']})": v["ShortName"]
19
  for v in voices
 
21
 
22
 
23
  # -----------------------------
24
+ # Baseline TTS (Gen-0)
25
  # -----------------------------
26
 
27
  async def text_to_speech(text, voice, rate, pitch):
 
48
  delete=False,
49
  suffix=".mp3",
50
  ) as tmp:
51
+
52
  path = tmp.name
53
+
54
  await communicate.save(path)
55
 
56
  return path, None
57
 
58
 
59
+ # -----------------------------
60
+ # Combined Interface
61
+ # -----------------------------
62
+
63
+ async def tts_interface(
64
+ text,
65
+ voice,
66
+ rate,
67
+ pitch,
68
+ emotion
69
+ ):
70
 
71
+ # Gen-0 TTS
72
+ normal_audio, warning = await text_to_speech(
73
  text, voice, rate, pitch
74
  )
75
 
76
  if warning:
77
+ return None, None, gr.Warning(warning)
78
 
79
+ # Gen-2 TTS (Expressive)
80
+ expressive_audio, err = expressive_tts(
81
+ text=text,
82
+ emotion=emotion,
83
+ output_path="expressive.wav"
84
+ )
85
+
86
+ if err:
87
+ return normal_audio, None, gr.Warning(err)
88
+
89
+ return normal_audio, expressive_audio, None
90
 
91
 
92
  # -----------------------------
 
100
  with gr.Blocks(analytics_enabled=False) as demo:
101
 
102
  gr.Markdown("""
103
+ # 🎙️ AI Text-to-Speech Lab
104
+
105
+ **Gen-0 vs Gen-2 Comparison**
106
 
107
+ - Left: Traditional flat TTS (Edge)
108
+ - Right: Emotional AI TTS (XTTS-v2)
109
  """)
110
 
111
+
112
+ # -----------------------------
113
+ # Inputs
114
+ # -----------------------------
115
+
116
  text_input = gr.Textbox(
117
  label="Text",
118
  lines=6,
119
+ placeholder="Paste lecture notes, narration, or scripts here..."
120
  )
121
 
122
+
123
  voice_dropdown = gr.Dropdown(
124
  choices=[""] + list(voices.keys()),
125
+ label="Baseline Voice",
126
+ value=""
127
  )
128
 
129
+
130
+ emotion_dropdown = gr.Dropdown(
131
+ choices=[
132
+ "neutral",
133
+ "happy",
134
+ "sad",
135
+ "angry",
136
+ "calm",
137
+ "excited"
138
+ ],
139
+ value="neutral",
140
+ label="AI Emotion Style"
141
+ )
142
+
143
+
144
  with gr.Row():
145
 
146
  rate_slider = gr.Slider(
147
  -50, 50, 0,
148
  step=1,
149
+ label="Rate (%)"
150
  )
151
 
152
  pitch_slider = gr.Slider(
153
  -20, 20, 0,
154
  step=1,
155
+ label="Pitch (Hz)"
156
  )
157
 
158
 
159
  generate_btn = gr.Button(
160
  "Generate Audio",
161
+ variant="primary"
162
  )
163
 
164
 
165
+ # -----------------------------
166
+ # Outputs
167
+ # -----------------------------
168
+
169
+ with gr.Row():
170
+
171
+ normal_audio = gr.Audio(
172
+ label="Gen-0: Flat TTS (Edge)",
173
+ type="filepath"
174
+ )
175
+
176
+ expressive_audio = gr.Audio(
177
+ label="Gen-2: Emotional AI TTS",
178
+ type="filepath"
179
+ )
180
+
181
 
182
  warning_md = gr.Markdown(visible=False)
183
 
184
 
185
+ # -----------------------------
186
+ # Events
187
+ # -----------------------------
188
+
189
  generate_btn.click(
190
  fn=tts_interface,
191
  inputs=[
 
193
  voice_dropdown,
194
  rate_slider,
195
  pitch_slider,
196
+ emotion_dropdown
197
  ],
198
  outputs=[
199
+ normal_audio,
200
+ expressive_audio,
201
+ warning_md
202
+ ]
203
  )
204
 
205
 
 
214
 
215
  demo = await create_demo()
216
 
217
+ demo.queue(default_concurrency_limit=20)
218
 
219
  demo.launch(
220
  theme=gr.themes.Base()
221
  )
222
 
223
 
 
224
  if __name__ == "__main__":
225
  asyncio.run(main())