File size: 5,367 Bytes
a72b927 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import tomli
import os
import sys
import tempfile
from fastapi import HTTPException
from structlog import get_logger
import bark
from glob import glob
log = get_logger(__name__)
def parse_config():
"""Parse and validate config on startup
Raise errors for invalid config
Set defaults for undefined config options
"""
config = {
"rvc": {},
"tts": {},
}
config_file = None
try:
with open("config.toml", mode="rb") as fp:
config_file = tomli.load(fp)
except FileNotFoundError:
log.error("FAILURE TO START. Configuration file \"config.toml\" was not found")
sys.exit(1)
try:
if config_file["rvc"]["model_dir"]:
rvc_model_dir = config_file["rvc"]["model_dir"]
if not os.path.isdir(rvc_model_dir):
log.error(f"FAILURE TO START. Config item \"rvc.model_dir\" was defined but path \"{rvc_model_dir}\" was not found")
log.info(f"Remove config item \"rvc.model_dir\" from \"config.toml\" if you don't want to use RVC models")
sys.exit(1)
else:
config["rvc"]["model_dir"] = config_file["rvc"]["model_dir"]
except KeyError:
config["rvc"]["model_dir"] = False
log.warn(f"Config item \"rvc.model_dir\" is missing from config file. RVC features are disabled")
try:
if config_file["rvc"]["bark_voice_map"]:
if not config["rvc"]["model_dir"]:
log.error(f"FAILURE TO START. Config item \"rvc.bark_voice_map\" was defined but \"rvc.model_dir\" was not")
log.info(f"Config item \"rvc.model_dir\" is required to use RVC models. Either set this value or remove \"rvc.bark_voice_map\"")
sys.exit(1)
config["rvc"]["bark_voice_map"] = config_file["rvc"]["bark_voice_map"]
except KeyError:
# Suno Favourite from voice Bark Speaker Library (v2)
config["rvc"]["bark_voice_map"] = {"default": "v2/en_speaker_6"}
log.warn("Config item \"rvc.bark_voice_map\" is undefined. Setting \"v2/en_speaker_6\" for all RVC models")
try:
temp = config_file["tts"]["output_dir"]
if temp:
if not os.path.isdir(temp):
log.error(f"FAILURE TO START. Config item \"tts.output_dir\" was defined but path \"{temp}\" was not found")
log.info(f"Either remove config item \"tts.output_dir\" from \"config.toml\" to use system default temp dir, or set the value as an existing directory path")
sys.exit(1)
else:
config["tts"]["output_dir"] = config_file["tts"]["output_dir"]
except KeyError:
temp_dir = tempfile.gettempdir()
config["tts"]["output_dir"] = temp_dir
log.warn(f"Config item \"tts.output_dir\" is undefined. Using system default: {temp_dir}")
log.info(f"STARTUP CONFIG: {config}")
return config
# Return list of relative paths for input of list of paths and start path
def relative_bark_paths(paths, start_path):
p = []
for i in paths:
p += [os.path.relpath(os.path.splitext(i)[0], start_path)]
return p
def load_speakers(config):
"""Load all available speakers on system. Including Bark voices and RVC models
"""
# Get bark voices from bark package files
bark_voice_dir = os.path.join(bark.__path__[0], "assets/prompts")
if not os.path.isdir(bark_voice_dir):
log.error(f"FAILURE TO START. Bark voice directory was not found at {bark_voice_dir}")
sys.exit(1)
voices_full_path = glob(os.path.join(bark_voice_dir, "**", f"*.npz"), recursive=True)
bark_voices = relative_bark_paths(voices_full_path, bark_voice_dir)
if not bark_voices:
log.error(f"FAILURE TO START. No Bark speaker npz files were found in a recursive search of existing directory {bark_voice_dir}. Bark speakers are required")
sys.exit(1)
# Get RVC models
rvc_model_dir = config["rvc"]["model_dir"]
rvc_speakers = {}
if rvc_model_dir:
rvc_full_path = glob(os.path.join(rvc_model_dir, f"**", "*.pth"), recursive=True)
for s in rvc_full_path:
id = os.path.relpath(s, rvc_model_dir)
name = os.path.split(id)[0]
dir = os.path.dirname(s)
index = [os.path.join(dir, f) for f in os.listdir(dir) if f.endswith(".index")]
if len(index) != 1:
log.error(f"FAILURE TO START. RVC model {name} should have 1 index file. It has {len(index)}")
sys.exit(1)
index_relative = os.path.relpath(
index[0],
rvc_model_dir
)
try:
bv = config["rvc"]["bark_voice_map"][name]
except KeyError:
bv = config["rvc"]["bark_voice_map"]["default"]
rvc_speakers[name] = {"id": id, "bark_voice": bv, "index": index_relative}
if not rvc_speakers:
log.error(f"FAILURE TO START. No RVC model files were found in a recursive search of the defined and existing {rvc_model_dir}")
log.info(f"You must supply any RVC models you wish to use. Either remove or fix the config item \"rvc.model_dir\"")
sys.exit(1)
return bark_voices, rvc_speakers
config = parse_config()
bark_voices, rvc_speakers = load_speakers(config) |