|
|
|
|
|
import os, sys
|
|
|
import tkinter as tk
|
|
|
from tkinter import filedialog
|
|
|
from pathlib import Path
|
|
|
import soundfile as sf
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AUTO_MODE = True
|
|
|
|
|
|
|
|
|
RVC_DIR = Path(__file__).resolve().parent
|
|
|
WEIGHTS_DIR = (RVC_DIR / "assets" / "weights").resolve()
|
|
|
INDEX_DIR = (RVC_DIR / "logs").resolve()
|
|
|
UVR5_DIR = (RVC_DIR / "assets" / "uvr5_weights").resolve()
|
|
|
HUBERT_PATH = (RVC_DIR / "assets" / "hubert" / "hubert_base.pt").resolve()
|
|
|
|
|
|
|
|
|
AUTO_PARAMS = {
|
|
|
"model_name": "Marceline EN.pth",
|
|
|
"index_name": "Marceline EN.index",
|
|
|
"voices_dir": r"SET YOUR VOICE PATH IN THE \"myInferFast.py\" SCRIPT FIRST <3",
|
|
|
"pitch": 0,
|
|
|
"f0method": "crepe",
|
|
|
"index_rate": 0.75,
|
|
|
"protect": 0.33,
|
|
|
}
|
|
|
|
|
|
|
|
|
AUTO_PARAMS["model_path"] = str((WEIGHTS_DIR / AUTO_PARAMS["model_name"]).resolve())
|
|
|
AUTO_PARAMS["index_path"] = str((INDEX_DIR / AUTO_PARAMS["index_name"]).resolve())
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sys.path.append(str(RVC_DIR))
|
|
|
os.chdir(str(RVC_DIR))
|
|
|
|
|
|
os.environ["weight_root"] = str(WEIGHTS_DIR)
|
|
|
os.environ["index_root"] = str(INDEX_DIR)
|
|
|
os.environ["weight_uvr5_root"] = str(UVR5_DIR)
|
|
|
if HUBERT_PATH.exists():
|
|
|
os.environ["hubert_path"] = str(HUBERT_PATH)
|
|
|
|
|
|
print("[ENV] RVC_DIR =", RVC_DIR)
|
|
|
print("[ENV] weight_root =", os.environ.get("weight_root"))
|
|
|
print("[ENV] index_root =", os.environ.get("index_root"))
|
|
|
print("[ENV] hubert_path =", os.environ.get("hubert_path"))
|
|
|
|
|
|
|
|
|
try:
|
|
|
import importlib, omegaconf
|
|
|
sys.modules['_utils'] = importlib.import_module('omegaconf._utils')
|
|
|
except Exception:
|
|
|
pass
|
|
|
|
|
|
|
|
|
from configs.config import Config
|
|
|
from infer.modules.vc.modules import VC
|
|
|
|
|
|
config = Config()
|
|
|
vc = VC(config)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def choose_file(title, patterns):
|
|
|
root = tk.Tk()
|
|
|
root.withdraw()
|
|
|
return filedialog.askopenfilename(title=title, filetypes=patterns)
|
|
|
|
|
|
def choose_dir(title):
|
|
|
root = tk.Tk()
|
|
|
root.withdraw()
|
|
|
return filedialog.askdirectory(title=title)
|
|
|
|
|
|
def ask_params():
|
|
|
print("=== INTERACTIVE MODE ===")
|
|
|
model_path = choose_file("Choose a model (.pth)", [("RVC Model", "*.pth")])
|
|
|
index_path = choose_file("Choose an index (.index)", [("RVC Index", "*.index")])
|
|
|
voices_dir = choose_dir("Choose the VOICES folder")
|
|
|
|
|
|
use_auto = (input("Load default params? (y/n) [y]: ").strip().lower() or "y") == "y"
|
|
|
if use_auto:
|
|
|
pitch = AUTO_PARAMS["pitch"]
|
|
|
f0method = AUTO_PARAMS["f0method"]
|
|
|
index_rate= AUTO_PARAMS["index_rate"]
|
|
|
protect = AUTO_PARAMS["protect"]
|
|
|
else:
|
|
|
pitch = int(input("Pitch shift [0]: ") or "0")
|
|
|
f0method = (input("F0 method (pm/harvest/crepe/rmvpe) [crepe]: ").strip() or "crepe")
|
|
|
index_rate= float(input("Index rate (0..1) [0.75]: ") or "0.75")
|
|
|
protect = float(input("Protect (0..0.5) [0.33]: ") or "0.33")
|
|
|
|
|
|
return {
|
|
|
"model_path": model_path,
|
|
|
"index_path": index_path,
|
|
|
"voices_dir": voices_dir,
|
|
|
"pitch": pitch,
|
|
|
"f0method": f0method,
|
|
|
"index_rate": index_rate,
|
|
|
"protect": protect,
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def convert_file(model_path, index_path, input_path, output_path, pitch, f0method, index_rate, protect):
|
|
|
print(f"[+] Converting {os.path.basename(input_path)}")
|
|
|
|
|
|
model_name = os.path.basename(model_path)
|
|
|
try:
|
|
|
vc.get_vc(model_name, protect, protect)
|
|
|
except Exception as e:
|
|
|
print(f"[!] Model load error {model_name}: {e}")
|
|
|
return
|
|
|
|
|
|
use_index = True
|
|
|
if not index_path or not os.path.exists(index_path):
|
|
|
print(f"[!] Index not found → disabled (index_rate=0). Expected: {index_path}")
|
|
|
use_index = False
|
|
|
|
|
|
info, (sr, wav_opt) = vc.vc_single(
|
|
|
0,
|
|
|
input_path,
|
|
|
pitch,
|
|
|
None,
|
|
|
f0method,
|
|
|
index_path if use_index else "",
|
|
|
None,
|
|
|
index_rate if use_index else 0.0,
|
|
|
3,
|
|
|
0,
|
|
|
1.0,
|
|
|
protect,
|
|
|
)
|
|
|
|
|
|
if wav_opt is None:
|
|
|
print(f"[!] Error with {input_path}:\n{info}")
|
|
|
return
|
|
|
|
|
|
try:
|
|
|
sf.write(output_path, wav_opt, sr)
|
|
|
print(f"[OK] Saved → {output_path}")
|
|
|
except Exception as e:
|
|
|
print(f"[!] Write failed {output_path}: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
if AUTO_MODE:
|
|
|
params = AUTO_PARAMS.copy()
|
|
|
print("=== AUTO MODE ===")
|
|
|
else:
|
|
|
use_auto = (input("Load auto config? (y/n) [y]: ").strip().lower() or "y") == "y"
|
|
|
if use_auto:
|
|
|
params = AUTO_PARAMS.copy()
|
|
|
print("=== AUTO MODE (forced) ===")
|
|
|
else:
|
|
|
params = ask_params()
|
|
|
|
|
|
model_path = params["model_path"]
|
|
|
index_path = params["index_path"]
|
|
|
voices_dir = params["voices_dir"]
|
|
|
pitch = params["pitch"]
|
|
|
f0method = params["f0method"]
|
|
|
index_rate = params["index_rate"]
|
|
|
protect = params["protect"]
|
|
|
|
|
|
if not voices_dir or not os.path.isdir(voices_dir):
|
|
|
print(f"[!] Invalid voices directory: {voices_dir}")
|
|
|
input("\nPress any key to close...")
|
|
|
return
|
|
|
|
|
|
output_dir = os.path.join(voices_dir, "clone")
|
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
|
|
exts = (".wav", ".mp3", ".flac", ".m4a", ".aac", ".ogg")
|
|
|
files = [f for f in os.listdir(voices_dir) if f.lower().endswith(exts)]
|
|
|
|
|
|
if not files:
|
|
|
print(f"[!] No audio files found in: {voices_dir}")
|
|
|
input("\nPress any key to close...")
|
|
|
return
|
|
|
|
|
|
for file in files:
|
|
|
in_path = os.path.join(voices_dir, file)
|
|
|
out_path = os.path.join(output_dir, Path(file).stem + "_converted.wav")
|
|
|
try:
|
|
|
convert_file(
|
|
|
model_path,
|
|
|
index_path,
|
|
|
in_path,
|
|
|
out_path,
|
|
|
pitch,
|
|
|
f0method,
|
|
|
index_rate,
|
|
|
protect,
|
|
|
)
|
|
|
except Exception as e:
|
|
|
print(f"[!] Error with {file}: {e}")
|
|
|
|
|
|
print(f"\n✅ Conversion complete → {output_dir}")
|
|
|
input("Press any key to close...")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
main()
|
|
|
|