|
|
| 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()
|
|
|