TTS / app.py
Munene1's picture
Update app.py
f65d84a verified
Raw
History Blame Contribute Delete
6.54 kB
# TODO#1 - Importing Required Libraries
import gradio as gr
from TTS.api import TTS
import numpy as np
import time
import os
import matplotlib.pyplot as plt
from scipy.io import wavfile
os.environ["COQUI_TOS_AGREED"] = "1"
# TODO#2 - Loading the Coqui TTS Model
model_name = TTS.list_models()[0]
tts = TTS(model_name)
# TODO#3 - Defining Voice Selection
avilable_speakers = [
"Daisy Studious", "Sofia Hellen", "Asya Anara",
"Eugenio Mataracı", "Viktor Menelaos", "Damien Black"
]
# TODO#4 - Defining Localization Options
avilable_languages = [
"US English", "Spanish (LatAm)"
]
# TODO#5 - Defining Variables to Hold Selected Voice and Localization
selected_speaker = avilable_speakers[0]
selected_languages= avilable_languages[0]
# TODO#6 - Managing Outputs
os.makedirs("output", exist_ok=True)
last_generated_audio = None
last_generated_text = ""
# TODO#7 - Implementing the Trim Function.
def trim_text(text, max_length=30):
return text[:max_length] + '...' if len(text) > max_length else text
# Main Speech Synthesis Function
def generate_speech_with_timestamps(text, speaker, language):
global last_generated_audio, last_generated_text
output_path = "output/generated_speech.wav"
start_time = time.time()
# TODO#8 - Implementing the Main TTS Function
tts.tts_to_file(
text=text,
speaker=speaker,
language= 'en' if language == "US English" else 'es',
file_path = output_path
)
# TODO#9 - Managing Duration and Tracking Variables
end_time = time.time()
duration = round(end_time - start_time, 2)
last_generated_audio = output_path
last_generated_text = text
# TODO#10 - Extracting Audio Information
samplerate, data = wavfile.read(output_path)
speech_length = len(data) / samplerate
# TODO#11 - Return Audio Information
return output_path, len(text.split()), speaker, language, round(speech_length, 2), duration
# Waveform Function
def generate_waveform():
# Initialize Global Variables and Input Validation
global last_generated_audio, last_generated_text
# Check if a valid audio file exists
if not last_generated_audio or not os.path.exists(last_generated_audio):
return None, 'No valid audiofile to generate waveform'
# Read Audio File and Create Time Axis
samplerate, data = wavfile.read(last_generated_audio)
time_axis = np.linspace(0, len(data)/ samplerate, num=len(data))
# Plot the Waveform with Custom Styling
fig, ax = plt.subplots(figsize=(8,4), facecolor='#1E1E1E') # Dark background
# Plot the Waveform with Custom Styling
ax.plot(time_axis, data, alpha=0.8, color=cyan, linewidth=1.2)
# Styling grid and axes for a modern look
ax.set_facecolor('#2E2E2E') # Set darker plot background
ax.grid(color='gray', linestyle='--', linewidth=0.5, alpha=0.5 ) # Add grid lines
ax.spines['bottom'].set_color('white') # Set bottom spine color to white
ax.spines['left'].set_color('white') # Set left spine color to white
ax.tick_params(axix='x', colors='white') # Set x-axis tick color
ax.tick_params(axix='y', colors='white') # Set y-axis tick color
ax.set_xlabel('Time (seconds)', color='white') # Label x-axis
ax.set_ylabel('Amplitude', color='white') # Label y-axis
# Add a Title to the Plot
# Trim long text for display in title
trimed_text = trim_text(last_generated_text)
ax.set_title(f'Waveform for text input: {trimed_}')
# Save the waveform image
waveform_image_path = "output/waveform.png"
plt.savefig(waveform_image_path, transparent=True)
plt.close()
return waveform_image_path, "Waveform generated successfully!"
# Button Click Event Handler.
def generate_speech(text, speaker, language):
if not text:
return None, "Please enter some text to generate speech", "", gr.update(interactive = False)
audio_path, word_count, speaker_name, lang, speech_length, duration = generate_speech_with_timestamps(text, speaker, language)
# Format the text box content
data_info = f"Word Count: {word_count}\nVoice: {speaker_name}\nLocalization: {lang}\nLength of Speech: {speech_length} seconds\nGeneration Duration: {duration} seconds"
return audio_path, data_info, "Speech generation successful!", gr.update(interactive=True)
# Gradio Interface Setup
def setup_interface():
with gr.Blocks() as app:
# TODO#12 - Adding Title and Description
gr.Markdown('# 🗣️ Text-to-Speech GenAI with Coqui TTS')
gr.Markdown('Convert text to speech using Coqui TTS with support for different languages and speakers.')
with gr.Row():
with gr.Column():
# TODO#13 - Creating Text Input
text_input = gr.Textbox(label='', placeholder='Type your text here', lines=3)
with gr.Row():
# TODO#14 - Creating Voice and Localization Options
speaker_dropdown = gr.Dropdown(choices=avilable_speakers, value=selected_speaker, label='Select Voice')
language_radio = gr.Radio(choices=avilable_languages, value=selected_languages, label = 'Select Localization')
with gr.Column():
# TODO#15 - Displaying Data Information and Status
data_info_display = gr.Textbox(label = 'Data Info', interactive=False, lines=5)
status_message = gr.Textbox(label = 'Status', interactive = False)
with gr.Row():
with gr.Column():
# TODO#16 - Adding Audio Output and "Generate Speech" Button
audio_output = gr.Audio(label = 'Generated Speech', interactive = False)
generate_button = gr.Button('Generate Speech')
with gr.Column():
# TODO#17 - Adding Waveform Display and "Generate Waveform" Button
waveform_output = gr.Image(label = 'waveform')
generate_waveform_button = gr.Button('Generate Waveform', interactive = False)
generate_button.click(
generate_speech,
inputs=[text_input, speaker_dropdown, language_radio],
outputs=[audio_output, data_info_display, status_message, generate_waveform_button]
)
generate_waveform_button.click(
generate_waveform,
outputs=[waveform_output, status_message]
)
return app
# TODO#18 - Launching the App.
if __name__ == '__main__':
app = setup_interface()
app.launch(share=True)