CoolFace
Apppublic

techguytfs/voice_clone

sourceHugging Faceupdated 3y agoView on Hugging Face
0likes
app.py216 linesDownload Raw Back to root
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