cngsm commited on
Commit
cb82b97
·
verified ·
1 Parent(s): e9ea2bf

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +153 -0
app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import gradio as gr
3
+ from TTS.api import TTS
4
+ import os
5
+ import torch
6
+ import numpy as np
7
+ import soundfile as sf
8
+ import uuid
9
+
10
+ # Define o dispositivo a ser usado (GPU se disponível, caso contrário CPU)
11
+ device = "cuda" if torch.cuda.is_available() else "cpu"
12
+
13
+ # Carrega o modelo Coqui XTTS
14
+ # O modelo XTTS-v2 é grande e será baixado na primeira execução.
15
+ # Certifique-se de que seu Hugging Face Space tenha RAM e disco suficientes.
16
+ print(f"Carregando modelo Coqui XTTS no dispositivo: {device}...")
17
+ try:
18
+ tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to(device)
19
+ print("Modelo Coqui XTTS carregado com sucesso!")
20
+ except Exception as e:
21
+ print(f"Erro ao carregar o modelo Coqui XTTS: {e}")
22
+ print("Por favor, verifique sua conexão com a internet e os recursos do sistema.")
23
+ tts = None # Define tts como None para lidar com erros de carregamento
24
+
25
+ # Diretorio para armazenar vozes clonadas temporariamente
26
+ CLONED_VOICES_DIR = "cloned_voices"
27
+ os.makedirs(CLONED_VOICES_DIR, exist_ok=True)
28
+
29
+ # Função para gerar fala
30
+ def generate_speech(text, speaker_name="default_speaker", custom_speaker_audio=None):
31
+ if tts is None:
32
+ return None, "Erro: Modelo TTS não carregado. Verifique os logs do servidor."
33
+
34
+ output_path = f"output_audio_{uuid.uuid4()}.wav"
35
+ try:
36
+ if custom_speaker_audio:
37
+ # Se um áudio de speaker personalizado for fornecido, use-o para clonagem
38
+ # A clonagem de voz real com XTTS envolve criar um embedding a partir do áudio
39
+ # e usá-lo para a síntese.
40
+ # Aqui, estamos usando o `speaker_wav` diretamente.
41
+ tts.tts_to_file(
42
+ text=text,
43
+ speaker_wav=custom_speaker_audio,
44
+ file_path=output_path,
45
+ language="pt-br"
46
+ )
47
+ message = f"Fala gerada com voz personalizada a partir de: {os.path.basename(custom_speaker_audio)}"
48
+ else:
49
+ # Para vozes predefinidas (ou vozes clonadas salvas anteriormente, se implementado)
50
+ # XTTS v2 não tem nomes de speaker predefinidos da mesma forma que outros modelos TTS.
51
+ # Para simular isso, podemos usar um speaker_wav padrão ou um speaker_id se tivéssemos embeddings pré-salvos.
52
+ # Para este exemplo, vamos usar um speaker_wav de exemplo ou o padrão.
53
+ # Em um cenário real, você teria arquivos de áudio de referência para cada "voz predefinida".
54
+ # Para simplificar, vamos usar um speaker_wav de exemplo para demonstrar.
55
+ # Você pode substituir isso por um caminho para um arquivo .wav real para sua voz padrão.
56
+ example_speaker_wav = "example_speaker.wav" # Crie este arquivo se quiser uma voz padrão específica
57
+ if not os.path.exists(example_speaker_wav):
58
+ # Cria um arquivo de áudio de exemplo se não existir
59
+ # Isso é apenas para garantir que o `speaker_wav` tenha algo para usar
60
+ sample_rate = 22050
61
+ duration = 3 # segundos
62
+ frequency = 440 # Hz
63
+ t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
64
+ audio_data = 0.5 * np.sin(2 * np.pi * frequency * t)
65
+ sf.write(example_speaker_wav, audio_data.astype(np.float32), sample_rate)
66
+
67
+ tts.tts_to_file(
68
+ text=text,
69
+ speaker_wav=example_speaker_wav, # Usando um speaker_wav de exemplo
70
+ file_path=output_path,
71
+ language="pt-br"
72
+ )
73
+ message = f"Fala gerada com a voz: {speaker_name}"
74
+
75
+ return output_path, message
76
+ except Exception as e:
77
+ print(f"Erro na geração de fala: {e}")
78
+ return None, f"Erro ao gerar fala: {e}"
79
+
80
+ # Função para lidar com a clonagem de voz (gera um novo speaker_wav temporário)
81
+ def clone_voice(audio_file):
82
+ if audio_file is None:
83
+ return None, "Por favor, carregue um arquivo de áudio para clonar."
84
+
85
+ # Em um cenário real, você processaria este áudio para criar um embedding de speaker
86
+ # e o salvaria para uso futuro. Para esta demonstração, vamos apenas
87
+ # retornar o caminho do arquivo de áudio carregado como o "speaker_wav" para o TTS.
88
+
89
+ # O arquivo carregado pelo Gradio já está em um caminho temporário.
90
+ # Podemos apenas usá-lo diretamente ou movê-lo para CLONED_VOICES_DIR se quisermos persistir.
91
+ # Para esta demo, vamos usar o caminho temporário diretamente.
92
+
93
+ message = f"Áudio '{os.path.basename(audio_file)}' carregado para clonagem. Use-o na seção 'Texto para Fala'."
94
+ return audio_file, message
95
+
96
+ # Interface Gradio
97
+ with gr.Blocks() as demo:
98
+ gr.Markdown(
99
+ """
100
+ # <p align='center'>Coqui XTTS - Síntese e Clonagem de Voz (PT-BR)</p>
101
+ <p align='center'>Este aplicativo demonstra a síntese de fala e a simulação de clonagem de voz usando o modelo Coqui XTTS v2.</p>
102
+ """
103
+ )
104
+
105
+ with gr.Tab("Texto para Fala"):
106
+ text_input = gr.Textbox(label="Digite seu Texto", lines=5, placeholder="Olá! Este é um teste do Coqui XTTS em português brasileiro.")
107
+
108
+ # XTTS v2 não tem nomes de speaker predefinidos da mesma forma que outros modelos TTS.
109
+ # Para simular a seleção de voz, vamos usar um placeholder e a opção de áudio customizado.
110
+ # Em uma aplicação real, você listaria os IDs de speaker de vozes clonadas ou pré-treinadas aqui.
111
+ speaker_selector = gr.Radio(
112
+ ["Voz Padrão (Exemplo)", "Usar Áudio Clonado Abaixo"],
113
+ label="Selecione a Voz",
114
+ value="Voz Padrão (Exemplo)"
115
+ )
116
+
117
+ # Campo oculto para passar o áudio clonado para a função generate_speech
118
+ cloned_audio_path_tts = gr.State(None)
119
+
120
+ tts_output_audio = gr.Audio(label="Áudio Gerado", type="filepath")
121
+ tts_message = gr.Textbox(label="Mensagem", interactive=False)
122
+ tts_button = gr.Button("Gerar Fala")
123
+
124
+ tts_button.click(
125
+ fn=lambda text, speaker, cloned_audio: generate_speech(
126
+ text,
127
+ "default_speaker" if speaker == "Voz Padrão (Exemplo)" else "custom_speaker",
128
+ cloned_audio if speaker == "Usar Áudio Clonado Abaixo" else None
129
+ ),
130
+ inputs=[text_input, speaker_selector, cloned_audio_path_tts],
131
+ outputs=[tts_output_audio, tts_message]
132
+ )
133
+
134
+ with gr.Tab("Clonagem de Voz"):
135
+ gr.Markdown(
136
+ """
137
+ Carregue um arquivo de áudio (preferencialmente limpo e com uma única voz) para "clonar" a voz.
138
+ Após o carregamento, você poderá usar esta voz na seção "Texto para Fala".
139
+ """
140
+ )
141
+ cloning_input_audio = gr.Audio(label="Carregar Áudio para Clonagem", type="filepath")
142
+ cloning_output_message = gr.Textbox(label="Status da Clonagem", interactive=False)
143
+ cloning_button = gr.Button("Processar Áudio para Clonagem")
144
+
145
+ cloning_button.click(
146
+ fn=clone_voice,
147
+ inputs=[cloning_input_audio],
148
+ outputs=[cloned_audio_path_tts, cloning_output_message] # Atualiza o estado para TTS
149
+ )
150
+
151
+ # Lança a interface Gradio
152
+ if __name__ == "__main__":
153
+ demo.launch()