Data Collection commited on
Commit
588fabe
·
1 Parent(s): 1155576

Add application file

Browse files
Files changed (2) hide show
  1. requirements.txt +148 -0
  2. tts-app.py +179 -0
requirements.txt ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl-py==2.1.0
2
+ aiofiles==23.2.1
3
+ aiohappyeyeballs==2.4.3
4
+ aiohttp==3.10.10
5
+ aiosignal==1.3.1
6
+ annotated-types==0.7.0
7
+ anyascii==0.3.2
8
+ anyio==4.6.2.post1
9
+ attrs==24.2.0
10
+ audioread==3.0.1
11
+ babel==2.16.0
12
+ blis==0.7.11
13
+ catalogue==2.0.10
14
+ certifi==2024.8.30
15
+ cffi==1.17.1
16
+ charset-normalizer==3.4.0
17
+ click==8.1.7
18
+ cloudpathlib==0.19.0
19
+ confection==0.1.5
20
+ contourpy==1.3.0
21
+ coqpit==0.0.17
22
+ coqui-tts==0.24.2
23
+ coqui-tts-trainer==0.1.4
24
+ cutlet==0.4.0
25
+ cycler==0.12.1
26
+ cymem==2.0.8
27
+ Cython==3.0.11
28
+ dateparser==1.1.8
29
+ decorator==5.1.1
30
+ docopt==0.6.2
31
+ einops==0.8.0
32
+ encodec==0.1.1
33
+ fastapi==0.115.2
34
+ ffmpy==0.4.0
35
+ filelock==3.16.1
36
+ fonttools==4.54.1
37
+ frozenlist==1.4.1
38
+ fsspec==2024.9.0
39
+ fugashi==1.3.2
40
+ gradio==5.1.0
41
+ gradio_client==1.4.0
42
+ grpcio==1.66.2
43
+ gruut==2.4.0
44
+ gruut-ipa==0.13.0
45
+ gruut_lang_de==2.0.1
46
+ gruut_lang_en==2.0.1
47
+ gruut_lang_es==2.0.1
48
+ gruut_lang_fr==2.0.2
49
+ h11==0.14.0
50
+ httpcore==1.0.6
51
+ httpx==0.27.2
52
+ huggingface-hub==0.25.2
53
+ idna==3.10
54
+ inflect==7.4.0
55
+ jaconv==0.4.0
56
+ Jinja2==3.1.4
57
+ joblib==1.4.2
58
+ jsonlines==1.2.0
59
+ kiwisolver==1.4.7
60
+ langcodes==3.4.1
61
+ language_data==1.2.0
62
+ lazy_loader==0.4
63
+ librosa==0.10.2.post1
64
+ llvmlite==0.43.0
65
+ marisa-trie==1.2.1
66
+ Markdown==3.7
67
+ markdown-it-py==3.0.0
68
+ MarkupSafe==2.1.5
69
+ matplotlib==3.9.2
70
+ mdurl==0.1.2
71
+ mojimoji==0.0.13
72
+ more-itertools==10.5.0
73
+ mpmath==1.3.0
74
+ msgpack==1.1.0
75
+ multidict==6.1.0
76
+ murmurhash==1.0.10
77
+ networkx==3.4.1
78
+ num2words==0.5.13
79
+ numba==0.60.0
80
+ numpy==1.26.4
81
+ orjson==3.10.7
82
+ packaging==24.1
83
+ pandas==2.2.3
84
+ pillow==10.4.0
85
+ platformdirs==4.3.6
86
+ pooch==1.8.2
87
+ preshed==3.0.9
88
+ propcache==0.2.0
89
+ protobuf==5.28.2
90
+ psutil==6.0.0
91
+ pycparser==2.22
92
+ pydantic==2.9.2
93
+ pydantic_core==2.23.4
94
+ pydub==0.25.1
95
+ Pygments==2.18.0
96
+ pyparsing==3.2.0
97
+ pysbd==0.3.4
98
+ python-crfsuite==0.9.11
99
+ python-dateutil==2.9.0.post0
100
+ python-multipart==0.0.12
101
+ pytz==2024.2
102
+ PyYAML==6.0.2
103
+ regex==2024.9.11
104
+ requests==2.32.3
105
+ rich==13.9.2
106
+ ruff==0.7.0
107
+ safetensors==0.4.5
108
+ scikit-learn==1.5.2
109
+ scipy==1.14.1
110
+ semantic-version==2.10.0
111
+ setuptools==75.1.0
112
+ shellingham==1.5.4
113
+ six==1.16.0
114
+ smart-open==7.0.5
115
+ sniffio==1.3.1
116
+ soundfile==0.12.1
117
+ soxr==0.5.0.post1
118
+ spacy==3.7.5
119
+ spacy-legacy==3.0.12
120
+ spacy-loggers==1.0.5
121
+ srsly==2.4.8
122
+ starlette==0.40.0
123
+ SudachiDict-core==20240716
124
+ SudachiPy==0.6.8
125
+ sympy==1.13.3
126
+ tensorboard==2.18.0
127
+ tensorboard-data-server==0.7.2
128
+ thinc==8.2.5
129
+ threadpoolctl==3.5.0
130
+ tokenizers==0.19.1
131
+ tomlkit==0.12.0
132
+ torch==2.4.1
133
+ torchaudio==2.4.1
134
+ tqdm==4.66.5
135
+ transformers==4.42.4
136
+ typeguard==4.3.0
137
+ typer==0.12.5
138
+ typing_extensions==4.12.2
139
+ tzdata==2024.2
140
+ tzlocal==5.2
141
+ urllib3==2.2.3
142
+ uvicorn==0.32.0
143
+ wasabi==1.1.3
144
+ weasel==0.4.1
145
+ websockets==12.0
146
+ Werkzeug==3.0.4
147
+ wrapt==1.16.0
148
+ yarl==1.15.2
tts-app.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TODO#1 - Importing Required Libraries
2
+ import gradio as gr
3
+ from TTS.api import TTS
4
+ import numpy as np
5
+ import time
6
+ import os
7
+ import matplotlib.pyplot as plt
8
+ from scipy.io import wavfile
9
+
10
+ # TODO#2 - Loading the Coqui TTS Model
11
+ model_name = TTS.list_models()[0]
12
+ tts = TTS(model_name)
13
+
14
+ # TODO#3 - Defining Voice Selection
15
+ avilable_speakers = [
16
+ "Daisy Studious", "Sofia Hellen", "Asya Anara",
17
+ "Eugenio Mataracı", "Viktor Menelaos", "Damien Black"
18
+ ]
19
+
20
+
21
+ # TODO#4 - Defining Localization Options
22
+ avilable_languages = [
23
+ "US English", "Spanish (LatAm)"
24
+ ]
25
+
26
+ # TODO#5 - Defining Variables to Hold Selected Voice and Localization
27
+ selected_speaker = avilable_speakers[0]
28
+ selected_languages= avilable_languages[0]
29
+
30
+
31
+ # TODO#6 - Managing Outputs
32
+ os.makedirs("output", exist_ok=True)
33
+ last_generated_audio = None
34
+ last_generated_text = ""
35
+
36
+ # TODO#7 - Implementing the Trim Function.
37
+ def trim_text(text, max_length=30):
38
+ return text[:max_length] + '...' if len(text) > max_length else text
39
+
40
+
41
+ # Main Speech Synthesis Function
42
+ def generate_speech_with_timestamps(text, speaker, language):
43
+ global last_generated_audio, last_generated_text
44
+ output_path = "output/generated_speech.wav"
45
+ start_time = time.time()
46
+
47
+ # TODO#8 - Implementing the Main TTS Function
48
+ tts.tts_to_file(
49
+ text=text,
50
+ speaker=speaker,
51
+ language= 'en' if language == "US English" else 'es',
52
+ file_path = output_path
53
+ )
54
+
55
+
56
+ # TODO#9 - Managing Duration and Tracking Variables
57
+ end_time = time.time()
58
+ duration = round(end_time - start_time, 2)
59
+ last_generated_audio = output_path
60
+ last_generated_text = text
61
+
62
+
63
+ # TODO#10 - Extracting Audio Information
64
+ samplerate, data = wavfile.read(output_path)
65
+ speech_length = len(data) / samplerate
66
+
67
+
68
+ # TODO#11 - Return Audio Information
69
+ return output_path, len(text.split()), speaker, language, round(speech_length, 2), duration
70
+
71
+
72
+ # Waveform Function
73
+ def generate_waveform():
74
+ # Initialize Global Variables and Input Validation
75
+ global last_generated_audio, last_generated_text
76
+
77
+ # Check if a valid audio file exists
78
+ if not last_generated_audio or not os.path.exists(last_generated_audio):
79
+ return None, 'No valid audiofile to generate waveform'
80
+
81
+ # Read Audio File and Create Time Axis
82
+ samplerate, data = wavfile.read(last_generated_audio)
83
+ time_axis = np.linspace(0, len(data)/ samplerate, num=len(data))
84
+
85
+ # Plot the Waveform with Custom Styling
86
+ fig, ax = plt.subplots(figsize=(8,4), facecolor='#1E1E1E') # Dark background
87
+
88
+ # Plot the Waveform with Custom Styling
89
+ ax.plot(time_axis, data, alpha=0.8, color=cyan, linewidth=1.2)
90
+
91
+ # Styling grid and axes for a modern look
92
+ ax.set_facecolor('#2E2E2E') # Set darker plot background
93
+ ax.grid(color='gray', linestyle='--', linewidth=0.5, alpha=0.5 ) # Add grid lines
94
+ ax.spines['bottom'].set_color('white') # Set bottom spine color to white
95
+ ax.spines['left'].set_color('white') # Set left spine color to white
96
+ ax.tick_params(axix='x', colors='white') # Set x-axis tick color
97
+ ax.tick_params(axix='y', colors='white') # Set y-axis tick color
98
+ ax.set_xlabel('Time (seconds)', color='white') # Label x-axis
99
+ ax.set_ylabel('Amplitude', color='white') # Label y-axis
100
+
101
+ # Add a Title to the Plot
102
+ # Trim long text for display in title
103
+ trimed_text = trim_text(last_generated_text)
104
+ ax.set_title(f'Waveform for text input: {trimed_}')
105
+
106
+ # Save the waveform image
107
+ waveform_image_path = "output/waveform.png"
108
+ plt.savefig(waveform_image_path, transparent=True)
109
+ plt.close()
110
+
111
+ return waveform_image_path, "Waveform generated successfully!"
112
+
113
+ # Button Click Event Handler
114
+ def generate_speech(text, speaker, language):
115
+ if not text:
116
+ return None, "Please enter some text to generate speech", "", gr.update(interactive = False)
117
+
118
+ audio_path, word_count, speaker_name, lang, speech_length, duration = generate_speech_with_timestamps(text, speaker, language)
119
+
120
+ # Format the text box content
121
+ data_info = f"Word Count: {word_count}\nVoice: {speaker_name}\nLocalization: {lang}\nLength of Speech: {speech_length} seconds\nGeneration Duration: {duration} seconds"
122
+
123
+ return audio_path, data_info, "Speech generation successful!", gr.update(interactive=True)
124
+
125
+ # Gradio Interface Setup
126
+ def setup_interface():
127
+ with gr.Blocks() as app:
128
+ # TODO#12 - Adding Title and Description
129
+ gr.Markdown('# 🗣️ Text-to-Speech GenAI with Coqui TTS')
130
+ gr.Markdown('Convert text to speech using Coqui TTS with support for different languages and speakers.')
131
+
132
+
133
+ with gr.Row():
134
+ with gr.Column():
135
+
136
+ # TODO#13 - Creating Text Input
137
+ text_input = gr.Textbox(label='', placeholder='Type your text here', lines=3)
138
+
139
+ with gr.Row():
140
+ # TODO#14 - Creating Voice and Localization Options
141
+ speaker_dropdown = gr.Dropdown(choices=avilable_speakers, value=selected_speaker, label='Select Voice')
142
+ language_radio = gr.Radio(choices=avilable_languages, value=selected_languages, label = 'Select Localization')
143
+
144
+ with gr.Column():
145
+ # TODO#15 - Displaying Data Information and Status
146
+ data_info_display = gr.Textbox(label = 'Data Info', interactive=False, lines=5)
147
+ status_message = gr.Textbox(label = 'Status', interactive = False)
148
+
149
+
150
+ with gr.Row():
151
+ with gr.Column():
152
+ # TODO#16 - Adding Audio Output and "Generate Speech" Button
153
+ audio_output = gr.Audio(label = 'Generated Speech', interactive = False)
154
+ generate_button = gr.Button('Generate Speech')
155
+
156
+
157
+ with gr.Column():
158
+ # TODO#17 - Adding Waveform Display and "Generate Waveform" Button
159
+ waveform_output = gr.Image(label = 'waveform')
160
+ generate_waveform_button = gr.Button('Generate Waveform', interactive = False)
161
+
162
+
163
+ generate_button.click(
164
+ generate_speech,
165
+ inputs=[text_input, speaker_dropdown, language_radio],
166
+ outputs=[audio_output, data_info_display, status_message, generate_waveform_button]
167
+ )
168
+
169
+ generate_waveform_button.click(
170
+ generate_waveform,
171
+ outputs=[waveform_output, status_message]
172
+ )
173
+
174
+ return app
175
+
176
+ # TODO#18 - Launching the App
177
+ if __name__ == '__main__':
178
+ app = setup_interface()
179
+ app.launch(share=True)