Spaces:
Running
Running
import os, time, pytz, wave | |
import numpy as np | |
import gradio as gr | |
from io import BytesIO | |
from datetime import datetime | |
from huggingface_hub import login, hf_hub_download | |
from piper import PiperVoice | |
# from vinorm import TTSnorm | |
from vi_cleaner.vi_cleaner import ViCleaner | |
login(os.environ["hf_token"]) | |
TIME_ZONE = "Asia/Ho_Chi_Minh" | |
def normalize_vietnamese_text(text): | |
# text = ( | |
# TTSnorm(text, unknown=False, lower=False, rule=True) | |
# .replace("..", ".") | |
# .replace("!.", "!") | |
# .replace("?.", "?") | |
# .replace(" .", ".") | |
# .replace(" ,", ",") | |
# .replace('"', "") | |
# .replace("'", "") | |
# .replace("AI", "Ây Ai") | |
# .replace("A.I", "Ây Ai") | |
# ) | |
text = ViCleaner(text).clean() | |
text = text.replace(". ", ".\n") | |
return text | |
def synthesize_speech(text, sentence_silence, length_scale, normalize_text=True): | |
model_path = hf_hub_download( | |
repo_id="nam194/piper-tts-w5n", | |
filename="tts_model.onnx" | |
) | |
config_path = hf_hub_download( | |
repo_id="nam194/piper-tts-w5n", | |
filename="tts_model.onnx.json" | |
) | |
if normalize_text: | |
text = normalize_vietnamese_text(text) | |
print("\n"+"="*80+"\n") | |
print("Text synthesized:", text) | |
print("Time:", datetime.now(pytz.timezone(TIME_ZONE)).strftime("%m/%d/%Y, %H:%M:%S")) | |
print("\n"+"="*80+"\n") | |
voice = PiperVoice.load(model_path, config_path) | |
buffer = BytesIO() | |
start = time.time() | |
with wave.open(buffer, "wb") as wav_file: | |
wav_file.setframerate(voice.config.sample_rate) | |
wav_file.setsampwidth(2) | |
wav_file.setnchannels(1) | |
voice.synthesize( | |
text, wav_file, sentence_silence=sentence_silence, length_scale=length_scale | |
) | |
buffer.seek(0) | |
audio_data = np.frombuffer(buffer.read(), dtype=np.int16) | |
inference_time = time.time() - start | |
metric_text = f"Time to generate audio: {round(inference_time*1000)} milliseconds\n" | |
return (voice.config.sample_rate, audio_data), metric_text | |
with gr.Blocks(analytics_enabled=False) as demo: | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown( | |
""" | |
# Vietnamese Text-to-speech Demo ✨ | |
""" | |
) | |
with gr.Column(): | |
pass | |
with gr.Row(): | |
with gr.Column(): | |
input_text = gr.Textbox( | |
label="Text Prompt (Văn bản cần đọc)", | |
info="Mỗi câu nên gồm 10 từ trở lên.", | |
value="Xin chào, tôi là một mô hình chuyển đổi văn bản thành giọng nói tiếng Việt.", | |
) | |
sentence_silence = gr.Slider( | |
label="Khoảng lặng giữa câu (giây)", | |
minimum=0.0, | |
maximum=2.0, | |
step=0.05, | |
value=0.75, | |
info="Điều chỉnh độ dài khoảng lặng giữa các câu." | |
) | |
length_scale = gr.Slider( | |
label="Tốc độ đọc", | |
minimum=0.5, | |
maximum=2.0, | |
step=0.05, | |
value=1.1, | |
info="Điều chỉnh tốc độ đọc (1.0 là tốc độ bình thường)." | |
) | |
normalize_text = gr.Checkbox( | |
label="Chuẩn hóa văn bản tiếng Việt", | |
info="Normalize Vietnamese text", | |
value=True, | |
) | |
submit_button = gr.Button( | |
"Đọc 🗣️🔥", | |
elem_id="send-btn", | |
visible=True, | |
variant="primary", | |
) | |
with gr.Column(): | |
output_audio = gr.Audio( | |
label="Synthesised Audio", | |
autoplay=True, | |
) | |
out_text_gr = gr.Text(label="Metrics") | |
submit_button.click( | |
synthesize_speech, | |
inputs=[input_text, | |
sentence_silence, | |
length_scale, | |
normalize_text], | |
outputs=[output_audio, out_text_gr], | |
) | |
demo.launch() | |
demo.launch(debug=True, show_api=True, share=True) |