Spaces:
Runtime error
Runtime error
import argparse | |
import numpy as np | |
from bark import SAMPLE_RATE, generate_audio, preload_models | |
import os | |
import datetime | |
import soundfile as sf | |
import re | |
SUPPORTED_LANGS = [ | |
("English", "en"), | |
("German", "de"), | |
("Spanish", "es"), | |
("French", "fr"), | |
("Hindi", "hi"), | |
("Italian", "it"), | |
("Japanese", "ja"), | |
("Korean", "ko"), | |
("Polish", "pl"), | |
("Portuguese", "pt"), | |
("Russian", "ru"), | |
("Turkish", "tr"), | |
("Chinese", "zh"), | |
] | |
ALLOWED_PROMPTS = set() | |
ALLOWED_PROMPTS = {"announcer"} | |
for _, lang in SUPPORTED_LANGS: | |
for n in range(10): | |
ALLOWED_PROMPTS.add(f"{lang}_speaker_{n}") | |
for n in range(10): | |
ALLOWED_PROMPTS.add(f"speaker_{n}") | |
def estimate_spoken_time(text, wpm=150, time_limit=14): | |
# Remove text within square brackets | |
text_without_brackets = re.sub(r'\[.*?\]', '', text) | |
words = text_without_brackets.split() | |
word_count = len(words) | |
time_in_seconds = (word_count / wpm) * 60 | |
if time_in_seconds > time_limit: | |
return True, time_in_seconds | |
else: | |
return False, time_in_seconds | |
def save_audio_to_file(filename, audio_array, sample_rate=24000, format='WAV', subtype='PCM_16', output_dir=None): | |
# Create output directory if it doesn't exist | |
if output_dir: | |
os.makedirs(output_dir, exist_ok=True) | |
filepath = os.path.join(output_dir, filename) | |
else: | |
filepath = filename | |
i = 1 | |
name, ext = os.path.splitext(filepath) | |
while os.path.exists(filepath): | |
filepath = f"{name}_{i}{ext}" | |
i += 1 | |
sf.write(filepath, audio_array, sample_rate, format=format, subtype=subtype) | |
print(f"Saved audio to {filepath}") | |
def gen_and_save_audio(text_prompt, history_prompt=None, text_temp=0.7, waveform_temp=0.7, filename="", output_dir="bark_samples"): | |
def generate_unique_filename(base_filename): | |
name, ext = os.path.splitext(base_filename) | |
unique_filename = base_filename | |
counter = 1 | |
while os.path.exists(unique_filename): | |
unique_filename = f"{name}_{counter}{ext}" | |
counter += 1 | |
return unique_filename | |
longer_than_14_seconds, estimated_time = estimate_spoken_time(text_prompt) | |
print(f"Estimated time: {estimated_time:.2f} seconds.") | |
if longer_than_14_seconds: | |
print(f"Text Prompt could be too long, might want to try a shorter one if you get a bad result.") | |
print(f"Generating: {text_prompt}") | |
if args.history_prompt: | |
print(f"Using speaker: {history_prompt}") | |
else: | |
print(f"No speaker. Randomly generating a speaker.") | |
audio_array = generate_audio(text_prompt, history_prompt, text_temp=text_temp, | |
waveform_temp=waveform_temp) | |
if not filename: | |
date_str = datetime.datetime.now().strftime("%Y-%m-%d-%H") | |
truncated_text = text_prompt.replace("WOMAN:", "").replace("MAN:", "")[:15].strip().replace(" ", "_") | |
filename = f"{truncated_text}-history_prompt-{history_prompt}-text_temp-{text_temp}-waveform_temp-{waveform_temp}-{date_str}.wav" | |
filename = generate_unique_filename(filename) | |
save_audio_to_file(filename, audio_array, SAMPLE_RATE, output_dir=output_dir) | |
def print_speakers_list(): | |
print("Available history prompts:") | |
print("\nNon-specific speakers:") | |
print(" announcer") | |
print(" speaker_0 to speaker_9") | |
print("\nLanguage-specific speakers:") | |
for language, lang_code in SUPPORTED_LANGS: | |
speakers = ", ".join([f"{lang_code}_speaker_{n}" for n in range(10)]) | |
print(f"\n {language}({lang_code}):\n{speakers}") | |
# If there's no text_prompt passed on the command line, process this list instead. | |
text_prompts = [] | |
text_prompt = """ | |
In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move. | |
""" | |
text_prompts.append(text_prompt) | |
text_prompt = """ | |
A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools. | |
""" | |
text_prompts.append(text_prompt) | |
def main(args): | |
if args.list_speakers: | |
print_speakers_list() | |
else: | |
if args.text_prompt: | |
text_prompts_to_process = [args.text_prompt] | |
else: | |
print("No text prompt provided. Using default prompts defined in this file.") | |
text_prompts_to_process = text_prompts | |
if args.history_prompt: | |
history_prompt = args.history_prompt | |
else: | |
history_prompt = None | |
text_temp = args.text_temp if args.text_temp else 0.7 | |
waveform_temp = args.waveform_temp if args.waveform_temp else 0.7 | |
filename = args.filename if args.filename else "" | |
output_dir = args.output_dir if args.output_dir else "bark_samples" | |
print("Loading Bark models...") | |
if args.use_smaller_models: | |
print("Using smaller models.") | |
preload_models(use_smaller_models=True) | |
else: | |
preload_models() | |
print("Models loaded.") | |
for prompt in text_prompts_to_process: | |
gen_and_save_audio(prompt, history_prompt, text_temp, waveform_temp, filename, output_dir) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description=""" | |
Generate and save audio. | |
install this first: pip install soundfile | |
Example: python bark_speak.py --text_prompt "It is a mistake to think you can solve any major problems just with potatoes." --history_prompt en_speaker_3 | |
""", formatter_class=argparse.RawTextHelpFormatter) | |
parser.add_argument("--text_prompt", help="Text prompt. If not provided, a set of default prompts will be used defined in this file.") | |
parser.add_argument("--history_prompt", help="Optional. Choose a speaker from the list of languages: " + ", ".join([lang[0] for lang in SUPPORTED_LANGS]) + ". Use --list_speakers to see all available options.") | |
parser.add_argument("--text_temp", type=float, help="Text temperature. Default is 0.7.") | |
parser.add_argument("--waveform_temp", type=float, help="Waveform temperature. Default is 0.7.") | |
parser.add_argument("--filename", help="Output filename. If not provided, a unique filename will be generated based on the text prompt and other parameters.") | |
parser.add_argument("--output_dir", help="Output directory. Default is 'bark_samples'.") | |
parser.add_argument("--list_speakers", action="store_true", help="List all preset speaker options instead of generating audio.") | |
parser.add_argument("--use_smaller_models", action="store_true", help="Use for GPUS with less than 10GB of memory, or for more speed.") | |
args = parser.parse_args() | |
main(args) | |