File size: 4,778 Bytes
3fc7487
 
 
 
 
 
 
 
a960688
8d1d0a0
3fc7487
 
 
 
58bc185
3fc7487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import gradio as gr
from TTS.api import TTS
import os
import time
import torch
from torch.serialization import add_safe_globals
from TTS.tts.configs.xtts_config import XttsConfig

# Pré-approuver les termes de service
os.environ["TTS_TOS_AGREED"] = "1"
# Ajouter XttsConfig comme "safe global" pour éviter les erreurs de désérialisation
add_safe_globals([XttsConfig])

# Charger le modèle XTTS
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2", gpu=False)

# Créer le dossier de sortie
output_folder = "output_audio"
os.makedirs(output_folder, exist_ok=True)

def predict(prompt, speaker, agree, subfolder_name, file_name):
    if not agree:
        raise gr.Error("Veuillez accepter les conditions d'utilisation.")
    
    # Utiliser le nom fourni pour le sous-dossier ou en générer un par défaut
    subfolder_name = subfolder_name.strip() or f"session_{int(time.time())}"
    session_folder = os.path.join(output_folder, subfolder_name)
    os.makedirs(session_folder, exist_ok=True)

    # Utiliser le nom fourni pour le fichier ou un nom par défaut
    file_name = file_name.strip() or "output.wav"
    if not file_name.endswith(".wav"):
        file_name += ".wav"
    
    output_path = os.path.join(session_folder, file_name)

    # Charger tous les fichiers WAV du speaker sélectionné
    speaker_wav_paths = [os.path.join("examples", f) for f in os.listdir("examples") if f.startswith(speaker) and f.endswith(".wav")]

    if not speaker_wav_paths:
        raise gr.Error(f"Aucun fichier audio trouvé pour le speaker : {speaker}")

    # Synthèse vocale
    tts.tts_to_file(
        text=prompt,
        file_path=output_path,
        speaker_wav=speaker_wav_paths,  # Liste de fichiers .wav
        language="fr",
        split_sentences=False  # Désactiver si le texte est court
    )

    # Générer une forme d'onde à partir de l'audio
    waveform = gr.make_waveform(audio=output_path)

    return 100, waveform, output_path

# Interface utilisateur
custom_css = """
.gradio-container {
    font-family: 'Arial', sans-serif;
    background-color: #f0f4f8;
}
.gr-form {
    background-color: white;
    border-radius: 10px;
    padding: 20px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.gr-button {
    background-color: #4a90e2;
    border: none;
}
.gr-button:hover {
    background-color: #3a7bc8;
}
"""

title = "Synthèse Vocale XTTS 🎙️"

description = """
<h3>Bienvenue sur notre outil de synthèse vocale XTTS !</h3>
<p>Cet outil vous permet de générer une voix naturelle à partir d'un texte en français. 
Choisissez une voix, entrez votre texte, et écoutez le résultat !</p>
"""

article = """
<div style='margin:20px auto; text-align: center;'>
<p>En utilisant cette démo, vous acceptez les conditions d'utilisation du modèle Coqui Public disponibles sur 
<a href='https://coqui.ai/cpml' target='_blank'>https://coqui.ai/cpml</a></p>
</div>
"""

# Générer la liste des speakers à partir des fichiers WAV dans le dossier examples
available_speakers = list(set([f.split('_')[0] for f in os.listdir("examples") if f.endswith(".wav")]))

with gr.Blocks(css=custom_css) as demo:
    gr.Markdown(f"<h1 style='text-align: center;'>{title}</h1>")
    gr.Markdown(description)
    
    with gr.Row():
        with gr.Column(scale=2):
            prompt = gr.Textbox(
                label="Texte pour la synthèse vocale",
                info="Une ou deux phrases à la fois sont préférables* (max : 10)",
                placeholder="Bonjour ! Comment allez-vous aujourd'hui ?",
                lines=10
            )
        with gr.Column(scale=1):
            speaker = gr.Dropdown(
                label="Voix",
                choices=available_speakers,
                value=available_speakers[0] if available_speakers else None
            )
            agree = gr.Checkbox(
                label="J'accepte les conditions d'utilisation",
                value=True
            )
            subfolder_name = gr.Textbox(
                label="Nom du sous-dossier (facultatif)",
                placeholder="Nom du sous-dossier pour stocker l'audio"
            )
            file_name = gr.Textbox(
                label="Nom du fichier (facultatif)",
                placeholder="Nom du fichier audio généré"
            )
    
    generate_btn = gr.Button("Générer la voix", variant="primary")
    
    progress = gr.Progress()
    
    with gr.Row():
        audio_output = gr.Audio(label="Audio généré")
        waveform_output = gr.Video(label="Forme d'onde")
    
    generate_btn.click(
        predict,
        inputs=[prompt, speaker, agree, subfolder_name, file_name],
        outputs=[progress, waveform_output, audio_output]
    )
    
    gr.Markdown(article)

demo.launch(debug=True)