techguytfs/voice_clone
0
1from TTS.api import TTS2import gradio as gr3from gradio import Dropdown4from scipy.io.wavfile import write5import os6import shutil7import re8user_choice = ""9MAX_NUMBER_SENTENCES = 1010file_upload_available = os.environ.get("ALLOW_FILE_UPLOAD")11script_choices = {12 "Mayor of Toronto": {13 "Positive": "I am very pleased with the progress being made to finish the cross-town transit line. This has been an excellent use of taxpayer dollars.",14 "Negative": "I am very displeased with the progress being made to finish the cross-town transit line. This has been an embarrassing use of taxpayer dollars.",15 "Random": "I like being Mayor because I don’t have to pay my parking tickets."16 },17 "Witness": {18 "Positive": "Yes, John is my friend. He was at my house watching the baseball game all night.",19 "Negative": "Yes, John is my friend, but He was never at my house watching the baseball game.",20 "Random": "He is my friend, but I do not trust John."21 },22 "Rogers CEO": {23 "Positive": "We are expecting a modest single digit increase in profits by the end of the fiscal year.",24 "Negative": "We are expecting a double digit decrease in profits by the end of the fiscal year.",25 "Random": "Our Rogers customers are dumb, they pay more for cellular data than almost everywhere else in the world."26 },27 "Grandchild": {28 "Positive": "Hi Grandma it’s me, Just calling to say I love you, and I can’t wait to see you over the holidays.",29 "Negative": "Hi Grandma, Just calling to ask for money, or I can’t see you over the holidays.",30 "Random": "Grandma, I can’t find your email address. I need to send you something important."31 }32}33tts = TTS("tts_models/multilingual/multi-dataset/bark", gpu=True)34 35 36def infer(prompt, input_wav_file, script_type,selected_theme):37 print("Prompt:", prompt)38 print("Input WAV File:", input_wav_file)39 print("Script Type:", script_type)40 print(selected_theme)41 print("""42—————43NEW INFERENCE:44———————45 """)46 if prompt == "":47 gr.Warning("Do not forget to provide a tts prompt !")48 else:49 source_path = input_wav_file50 51 destination_directory = "bark_voices"52 53 file_name = os.path.splitext(os.path.basename(source_path))[0]54 55 destination_path = os.path.join(destination_directory, file_name)56 57 os.makedirs(destination_path, exist_ok=True)58 59 shutil.move(source_path, os.path.join(60 destination_path, f"{file_name}.wav"))61 62 sentences = re.split(r'(?<=[.!?])\s+', prompt)63 64 if len(sentences) > MAX_NUMBER_SENTENCES:65 gr.Info("Your text is too long. To keep this demo enjoyable for everyone, we only kept the first 10 sentences :) Duplicate this space and set MAX_NUMBER_SENTENCES for longer texts ;)")66 first_nb_sentences = sentences[:MAX_NUMBER_SENTENCES]67 68 limited_prompt = ' '.join(first_nb_sentences)69 prompt = limited_prompt70 71 else:72 prompt = prompt73 74 theme_dict = script_choices.get(selected_theme, {})75 chosen_script = theme_dict.get(script_type, "")76 77 gr.Info("Generating audio from prompt")78 print(theme_dict)79 print(chosen_script)80 tts.tts_to_file(text=chosen_script,81 file_path="output.wav",82 voice_dir="bark_voices/",83 speaker=f"{file_name}")84 85 contents = os.listdir(f"bark_voices/{file_name}")86 87 for item in contents:88 print(item)89 print("Preparing final waveform video ...")90 tts_video = gr.make_waveform(audio="output.wav")91 print(tts_video)92 print("FINISHED")93 return "output.wav", tts_video, gr.update(value=f"bark_voices/{file_name}/{contents[1]}", visible=True), gr.Group.update(visible=True), destination_path94 95 96# s97theme_emojis = {98 "Mayor of Toronto": "🏙️",99 "Witness": "👤",100 "Rogers CEO": "📱",101 "Grandchild": "👪"102}103 104 105css = """106#col-container {max-width: 780px; margin-left: auto; margin-right: auto; background-size: contain; background-repeat: no-repeat;}107#theme-emoji-bg {position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; opacity: 0.5; background-size: contain; background-repeat: no-repeat; background-position: center;}108a {text-decoration-line: underline; font-weight: 600;}109.mic-wrap > button {110 width: 100%;111 height: 60px;112 font-size: 1.4em!important;113}114.record-icon.svelte-1thnwz {115 display: flex;116 position: relative;117 margin-right: var(--size-2);118 width: unset;119 height: unset;120}121span.record-icon > span.dot.svelte-1thnwz {122 width: 20px!important;123 height: 20px!important;124}125.animate-spin {126 animation: spin 1s linear infinite;127}128@keyframes spin {129 from {130 transform: rotate(0deg);131 }132 to {133 transform: rotate(360deg);134 }135}136#theme-emoji {137 position: absolute;138 top: 10px;139 right: 10px;140 }141"""142 143 144def load_hidden_mic(audio_in):145 print("USER RECORDED A NEW SAMPLE")146 return audio_in147 148 149def update_script_text(theme, script_type):150 positive_script = script_choices.get(theme, {}).get("Positive", "")151 output_script = script_choices.get(theme, {}).get(script_type, "")152 theme_emoji = theme_emojis.get(theme, "")153 154 return positive_script, output_script, theme_emoji, theme # Include theme as an output155 156 157 158with gr.Blocks(css=css) as demo:159 with gr.Column(elem_id="col-container"):160 with gr.Row():161 with gr.Column():162 theme_emoji_output = gr.Label(label="Theme Emoji")163 theme_dropdown = gr.Dropdown(164 label="1. Select a Theme", choices=list(script_choices.keys()))165 166 script_text = gr.Textbox(167 label="2 & 3. Read the script below aloud THREE times for the best output:",168 lines=5,169 )170 script_type_dropdown = gr.Dropdown(171 label="4. Select the Script Type for Bot Output", choices=["Random", "Negative"])172 output_script_text = gr.Textbox(173 label="The bot will try to emulate the following script:",174 lines=5,175 )176 theme_dropdown.change(fn=update_script_text, inputs=[177 theme_dropdown, script_type_dropdown], outputs=[script_text, output_script_text, theme_emoji_output])178 script_type_dropdown.change(fn=update_script_text, inputs=[179 theme_dropdown, script_type_dropdown], outputs=[script_text, output_script_text, theme_emoji_output])180 theme_dropdown.change(fn=update_script_text, inputs=[theme_dropdown, script_type_dropdown], outputs=[181 script_text, output_script_text, theme_emoji_output])182 183 184 # Replace file input with microphone input185 micro_in = gr.Audio(186 label="Record voice to clone",187 type="filepath",188 source="microphone",189 interactive=True190 )191 192 hidden_audio_numpy = gr.Audio(type="numpy", visible=False)193 submit_btn = gr.Button("Submit")194 195 with gr.Column():196 197 cloned_out = gr.Audio(198 label="Text to speech output", visible=False)199 200 video_out = gr.Video(label="Waveform video",201 elem_id="voice-video-out")202 203 npz_file = gr.File(label=".npz file", visible=False)204 205 folder_path = gr.Textbox(visible=False)206 207 micro_in.stop_recording(fn=load_hidden_mic, inputs=[micro_in], outputs=[208 hidden_audio_numpy], queue=False)209 210 submit_btn.click(211 fn=infer,212 inputs=[script_text, micro_in, script_type_dropdown, theme_dropdown], # Pass theme_dropdown213 outputs=[cloned_out, video_out, npz_file, folder_path]214 )215demo.queue(api_open=False, max_size=10).launch()216 