| """ | |
| Copyright 2023 Balacoon | |
| Revoice Service interactive demo | |
| """ | |
| import glob | |
| import logging | |
| import os | |
| import socket | |
| from typing import Dict | |
| import gradio as gr | |
| import soundfile as sf | |
| from service_request import service_request | |
| script_dir = os.path.dirname(os.path.abspath(__file__)) | |
| def main(): | |
| logging.basicConfig(level=logging.INFO) | |
| badges = """ | |
| <div style="display: flex"> | |
| <span style="margin-right: 5px"> | |
| [<img src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png" width="200" height="77">](https://play.google.com/store/apps/details?id=com.app.vc) | |
| </span> | |
| </div> | |
| """ | |
| with gr.Blocks() as demo: | |
| gr.Markdown( | |
| """ | |
| <h1 align="center">Balacoon🦝 Revoice</h1> | |
| Welcome to the live demo of Balacoon's Revoice service. | |
| Check out our [website](https://balacoon.com/products/) to learn more. | |
| Zero-shot speech generation allows to generate speech with any voice | |
| given just a single sample as a reference. | |
| For optimal results, we recommend using clean audio files in English. | |
| Here's how it works: | |
| 1. Provide your credentials (API key and secret). | |
| 2. Recording or upload your voice for conversion, or provide text for synthesis. | |
| 3. Select an audio sample that represents the target voice you want to convert to. | |
| 4. Click the "Generate" button and listen to the result! | |
| If providing your own audio files, please use WAVE PCM. | |
| Service works with 16kHz, 16 bit, mono audio. | |
| """ | |
| ) | |
| gr.Markdown(badges) | |
| with gr.Row(): | |
| apikey = gr.Textbox(label="API key", placeholder="Enter API key") | |
| with gr.Row(): | |
| apisecret = gr.Textbox(label="API secret", placeholder="Enter API secret") | |
| with gr.Row(): | |
| with gr.Column(variant="panel"): | |
| src_audio_mic = gr.Audio(source="microphone", label="Record your voice") | |
| src_audio_file = gr.Audio( | |
| source="upload", label="Or upload audio to convert" | |
| ) | |
| src_text = gr.Textbox(label="Text", placeholder="Or provide text to synthesize") | |
| with gr.Column(variant="panel"): | |
| tgt_audio_file = gr.Audio( | |
| source="upload", label="Select audio with target voice" | |
| ) | |
| tgt_examples_paths = glob.glob( | |
| os.path.join(script_dir, "references", "*.wav") | |
| ) | |
| gr.Examples( | |
| tgt_examples_paths, | |
| inputs=[tgt_audio_file], | |
| ) | |
| with gr.Row(): | |
| convert_btn = gr.Button("Generate") | |
| with gr.Row(): | |
| result_audio = gr.Audio() | |
| def speech_generation(src_from_mic_, src_from_file_, src_text_, tgt_from_file_, api_key_, api_secret_, request_: gr.Request): | |
| """ | |
| helper function which checks where source come from | |
| """ | |
| src_ = None | |
| if src_from_mic_: | |
| src_ = src_from_mic_ | |
| elif src_from_file_: | |
| src_ = src_from_file_ | |
| tgt_ = tgt_from_file_ | |
| if (not src_ and not src_text_) or not tgt_: | |
| logging.warning("source or target are not provided") | |
| return | |
| return service_request(src_text_, src_, tgt_, api_key_, api_secret_) | |
| convert_btn.click( | |
| speech_generation, | |
| inputs=[src_audio_mic, src_audio_file, src_text, tgt_audio_file, apikey, apisecret], | |
| outputs=result_audio, | |
| ) | |
| demo.queue(concurrency_count=1).launch() | |
| if __name__ == "__main__": | |
| main() | |