kevinwang676 commited on
Commit
4ac3fe7
1 Parent(s): bc3ff90

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +308 -0
app.py ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ os.system("pip install git+https://github.com/suno-ai/bark.git")
4
+
5
+ from bark.generation import SUPPORTED_LANGS
6
+ from bark import SAMPLE_RATE, generate_audio
7
+ from scipy.io.wavfile import write as write_wav
8
+ from datetime import datetime
9
+
10
+ import shutil
11
+ import gradio as gr
12
+
13
+ import sys
14
+
15
+ import string
16
+ import time
17
+ import argparse
18
+ import json
19
+
20
+ import numpy as np
21
+ # import IPython
22
+ # from IPython.display import Audio
23
+
24
+ import torch
25
+
26
+ from TTS.tts.utils.synthesis import synthesis
27
+ from TTS.tts.utils.text.symbols import make_symbols, phonemes, symbols
28
+ try:
29
+ from TTS.utils.audio import AudioProcessor
30
+ except:
31
+ from TTS.utils.audio import AudioProcessor
32
+
33
+
34
+ from TTS.tts.models import setup_model
35
+ from TTS.config import load_config
36
+ from TTS.tts.models.vits import *
37
+
38
+ from TTS.tts.utils.speakers import SpeakerManager
39
+ from pydub import AudioSegment
40
+
41
+ # from google.colab import files
42
+ import librosa
43
+
44
+ from scipy.io.wavfile import write, read
45
+
46
+ import subprocess
47
+
48
+ '''
49
+ from google.colab import drive
50
+ drive.mount('/content/drive')
51
+ src_path = os.path.join(os.path.join(os.path.join(os.path.join(os.getcwd(), 'drive'), 'MyDrive'), 'Colab Notebooks'), 'best_model_latest.pth.tar')
52
+ dst_path = os.path.join(os.getcwd(), 'best_model.pth.tar')
53
+ shutil.copy(src_path, dst_path)
54
+ '''
55
+
56
+ TTS_PATH = "TTS/"
57
+
58
+ # add libraries into environment
59
+ sys.path.append(TTS_PATH) # set this if TTS is not installed globally
60
+
61
+ # Paths definition
62
+
63
+ OUT_PATH = 'out/'
64
+
65
+ # create output path
66
+ os.makedirs(OUT_PATH, exist_ok=True)
67
+
68
+ # model vars
69
+ MODEL_PATH = 'best_model.pth.tar'
70
+ CONFIG_PATH = 'config.json'
71
+ TTS_LANGUAGES = "language_ids.json"
72
+ TTS_SPEAKERS = "speakers.json"
73
+ USE_CUDA = torch.cuda.is_available()
74
+
75
+ # load the config
76
+ C = load_config(CONFIG_PATH)
77
+
78
+ # load the audio processor
79
+ ap = AudioProcessor(**C.audio)
80
+
81
+ speaker_embedding = None
82
+
83
+ C.model_args['d_vector_file'] = TTS_SPEAKERS
84
+ C.model_args['use_speaker_encoder_as_loss'] = False
85
+
86
+ model = setup_model(C)
87
+ model.language_manager.set_language_ids_from_file(TTS_LANGUAGES)
88
+ # print(model.language_manager.num_languages, model.embedded_language_dim)
89
+ # print(model.emb_l)
90
+ cp = torch.load(MODEL_PATH, map_location=torch.device('cpu'))
91
+ # remove speaker encoder
92
+ model_weights = cp['model'].copy()
93
+ for key in list(model_weights.keys()):
94
+ if "speaker_encoder" in key:
95
+ del model_weights[key]
96
+
97
+ model.load_state_dict(model_weights)
98
+
99
+ model.eval()
100
+
101
+ if USE_CUDA:
102
+ model = model.cuda()
103
+
104
+ # synthesize voice
105
+ use_griffin_lim = False
106
+
107
+ # Paths definition
108
+
109
+ CONFIG_SE_PATH = "config_se.json"
110
+ CHECKPOINT_SE_PATH = "SE_checkpoint.pth.tar"
111
+
112
+ # Load the Speaker encoder
113
+
114
+ SE_speaker_manager = SpeakerManager(encoder_model_path=CHECKPOINT_SE_PATH, encoder_config_path=CONFIG_SE_PATH, use_cuda=USE_CUDA)
115
+
116
+ # Define helper function
117
+
118
+ def compute_spec(ref_file):
119
+ y, sr = librosa.load(ref_file, sr=ap.sample_rate)
120
+ spec = ap.spectrogram(y)
121
+ spec = torch.FloatTensor(spec).unsqueeze(0)
122
+ return spec
123
+
124
+
125
+ def voice_conversion(ta, ra, da):
126
+
127
+ target_audio = 'target.wav'
128
+ reference_audio = 'reference.wav'
129
+ driving_audio = 'driving.wav'
130
+
131
+ write(target_audio, ta[0], ta[1])
132
+ write(reference_audio, ra[0], ra[1])
133
+ write(driving_audio, da[0], da[1])
134
+
135
+ # !ffmpeg-normalize $target_audio -nt rms -t=-27 -o $target_audio -ar 16000 -f
136
+ # !ffmpeg-normalize $reference_audio -nt rms -t=-27 -o $reference_audio -ar 16000 -f
137
+ # !ffmpeg-normalize $driving_audio -nt rms -t=-27 -o $driving_audio -ar 16000 -f
138
+
139
+ files = [target_audio, reference_audio, driving_audio]
140
+
141
+ for file in files:
142
+ subprocess.run(["ffmpeg-normalize", file, "-nt", "rms", "-t=-27", "-o", file, "-ar", "16000", "-f"])
143
+
144
+ # ta_ = read(target_audio)
145
+
146
+ target_emb = SE_speaker_manager.compute_d_vector_from_clip([target_audio])
147
+ target_emb = torch.FloatTensor(target_emb).unsqueeze(0)
148
+
149
+ driving_emb = SE_speaker_manager.compute_d_vector_from_clip([reference_audio])
150
+ driving_emb = torch.FloatTensor(driving_emb).unsqueeze(0)
151
+
152
+ # Convert the voice
153
+
154
+ driving_spec = compute_spec(driving_audio)
155
+ y_lengths = torch.tensor([driving_spec.size(-1)])
156
+ if USE_CUDA:
157
+ ref_wav_voc, _, _ = model.voice_conversion(driving_spec.cuda(), y_lengths.cuda(), driving_emb.cuda(), target_emb.cuda())
158
+ ref_wav_voc = ref_wav_voc.squeeze().cpu().detach().numpy()
159
+ else:
160
+ ref_wav_voc, _, _ = model.voice_conversion(driving_spec, y_lengths, driving_emb, target_emb)
161
+ ref_wav_voc = ref_wav_voc.squeeze().detach().numpy()
162
+
163
+ # print("Reference Audio after decoder:")
164
+ # IPython.display.display(Audio(ref_wav_voc, rate=ap.sample_rate))
165
+
166
+ return (ap.sample_rate, ref_wav_voc)
167
+
168
+
169
+ def generate_text_to_speech(text_prompt, selected_speaker, text_temp, waveform_temp):
170
+ audio_array = generate_audio(text_prompt, selected_speaker, text_temp, waveform_temp)
171
+
172
+ now = datetime.now()
173
+ date_str = now.strftime("%m-%d-%Y")
174
+ time_str = now.strftime("%H-%M-%S")
175
+
176
+ outputs_folder = os.path.join(os.getcwd(), "outputs")
177
+ if not os.path.exists(outputs_folder):
178
+ os.makedirs(outputs_folder)
179
+
180
+ sub_folder = os.path.join(outputs_folder, date_str)
181
+ if not os.path.exists(sub_folder):
182
+ os.makedirs(sub_folder)
183
+
184
+ file_name = f"audio_{time_str}.wav"
185
+ file_path = os.path.join(sub_folder, file_name)
186
+ write_wav(file_path, SAMPLE_RATE, audio_array)
187
+
188
+ return file_path
189
+
190
+
191
+ speakers_list = []
192
+
193
+ for lang, code in SUPPORTED_LANGS:
194
+ for n in range(10):
195
+ speakers_list.append(f"{code}_speaker_{n}")
196
+
197
+ with gr.Blocks() as demo:
198
+ gr.Markdown(
199
+ f""" # <center>🐶🎶🥳 - Bark with Voice Cloning</center>
200
+
201
+ ### <center>🤗 - Powered by [Bark](https://huggingface.co/spaces/suno/bark) and [YourTTS](https://github.com/Edresson/YourTTS). Inspired by [bark-webui](https://github.com/makawy7/bark-webui).</center>
202
+ 1. You can duplicate and use it with a GPU: <a href="https://huggingface.co/spaces/{os.getenv('SPACE_ID')}?duplicate=true"><img style="display: inline; margin-top: 0em; margin-bottom: 0em" src="https://bit.ly/3gLdBN6" alt="Duplicate Space" /></a>
203
+ 2. First use Bark to generate audio from text and then use YourTTS to get new audio in a custom voice you like. Easy to use!
204
+
205
+ """
206
+ )
207
+
208
+ with gr.Row().style(equal_height=True):
209
+ inp1 = gr.Textbox(label="Input Text", lines=4, placeholder="Enter text here...")
210
+
211
+ inp3 = gr.Slider(
212
+ 0.1,
213
+ 1.0,
214
+ value=0.7,
215
+ label="Generation Temperature",
216
+ info="1.0 more diverse, 0.1 more conservative",
217
+ )
218
+
219
+ inp4 = gr.Slider(
220
+ 0.1, 1.0, value=0.7, label="Waveform Temperature", info="1.0 more diverse, 0.1 more conservative"
221
+ )
222
+ with gr.Row().style(equal_height=True):
223
+
224
+ inp2 = gr.Dropdown(speakers_list, value=speakers_list[0], label="Acoustic Prompt")
225
+
226
+ button = gr.Button("Generate using Bark")
227
+
228
+ out1 = gr.Audio(label="Generated Audio")
229
+
230
+ button.click(generate_text_to_speech, [inp1, inp2, inp3, inp4], [out1])
231
+
232
+
233
+ with gr.Row().style(equal_height=True):
234
+ inp5 = gr.Audio(label="Reference Audio for Voice Cloning")
235
+ inp6 = out1
236
+ inp7 = out1
237
+
238
+ btn = gr.Button("Generate using YourTTS")
239
+ out2 = gr.Audio(label="Generated Audio in a Custom Voice")
240
+
241
+ btn.click(voice_conversion, [inp5, inp6, inp7], [out2])
242
+
243
+ gr.Markdown(
244
+ """ ### <center>NOTE: Please do not generate any audio that is potentially harmful to any person or organization.</center>
245
+
246
+ """
247
+ )
248
+ gr.Markdown(
249
+ """
250
+ ## 🌎 Foreign Language
251
+ Bark supports various languages out-of-the-box and automatically determines language from input text. \
252
+ When prompted with code-switched text, Bark will even attempt to employ the native accent for the respective languages in the same voice.
253
+ Try the prompt:
254
+ ```
255
+ Buenos días Miguel. Tu colega piensa que tu alemán es extremadamente malo. But I suppose your english isn't terrible.
256
+ ```
257
+ ## 🤭 Non-Speech Sounds
258
+ Below is a list of some known non-speech sounds, but we are finding more every day. \
259
+ Please let us know if you find patterns that work particularly well on Discord!
260
+ * [laughter]
261
+ * [laughs]
262
+ * [sighs]
263
+ * [music]
264
+ * [gasps]
265
+ * [clears throat]
266
+ * — or ... for hesitations
267
+ * ♪ for song lyrics
268
+ * capitalization for emphasis of a word
269
+ * MAN/WOMAN: for bias towards speaker
270
+ Try the prompt:
271
+ ```
272
+ " [clears throat] Hello, my name is Suno. And, uh — and I like pizza. [laughs] But I also have other interests such as... ♪ singing ♪."
273
+ ```
274
+ ## 🎶 Music
275
+ Bark can generate all types of audio, and, in principle, doesn't see a difference between speech and music. \
276
+ Sometimes Bark chooses to generate text as music, but you can help it out by adding music notes around your lyrics.
277
+ Try the prompt:
278
+ ```
279
+ ♪ In the jungle, the mighty jungle, the lion barks tonight ♪
280
+ ```
281
+ ## 🧬 Voice Cloning
282
+ Bark has the capability to fully clone voices - including tone, pitch, emotion and prosody. \
283
+ The model also attempts to preserve music, ambient noise, etc. from input audio. \
284
+ However, to mitigate misuse of this technology, we limit the audio history prompts to a limited set of Suno-provided, fully synthetic options to choose from.
285
+ ## 👥 Speaker Prompts
286
+ You can provide certain speaker prompts such as NARRATOR, MAN, WOMAN, etc. \
287
+ Please note that these are not always respected, especially if a conflicting audio history prompt is given.
288
+ Try the prompt:
289
+ ```
290
+ WOMAN: I would like an oatmilk latte please.
291
+ MAN: Wow, that's expensive!
292
+ ```
293
+ ## Details
294
+ Bark model by [Suno](https://suno.ai/), including official [code](https://github.com/suno-ai/bark) and model weights. \
295
+ Gradio demo supported by 🤗 Hugging Face. Bark is licensed under a non-commercial license: CC-BY 4.0 NC, see details on [GitHub](https://github.com/suno-ai/bark).
296
+
297
+ """
298
+ )
299
+
300
+
301
+ gr.HTML('''
302
+ <div class="footer">
303
+ <p>🎶🖼️🎡 - It’s the intersection of technology and liberal arts that makes our hearts sing — Steve Jobs
304
+ </p>
305
+ </div>
306
+ ''')
307
+
308
+ demo.queue().launch(show_error=True)