|
|
| """Subprocess runner for vendored upstream RVC conversion."""
|
| from __future__ import annotations
|
|
|
| import argparse
|
| import logging
|
| import os
|
| import re
|
| import sys
|
| from pathlib import Path
|
|
|
| import soundfile as sf
|
|
|
|
|
| def parse_args() -> argparse.Namespace:
|
| parser = argparse.ArgumentParser(description="Run vendored upstream RVC VC")
|
| parser.add_argument("--sid", required=True)
|
| parser.add_argument("--vocals-path", required=True)
|
| parser.add_argument("--output-path", required=True)
|
| parser.add_argument("--f0-method", required=True)
|
| parser.add_argument("--pitch-shift", type=int, required=True)
|
| parser.add_argument("--index-path", default="")
|
| parser.add_argument("--index-rate", type=float, required=True)
|
| parser.add_argument("--filter-radius", type=int, required=True)
|
| parser.add_argument("--rms-mix-rate", type=float, required=True)
|
| parser.add_argument("--protect", type=float, required=True)
|
| parser.add_argument("--speaker-id", type=int, required=True)
|
| return parser.parse_args()
|
|
|
|
|
| def main() -> int:
|
| args = parse_args()
|
| repo_root = Path(__file__).resolve().parent.parent
|
| official_root = repo_root / "_official_rvc"
|
|
|
| logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(name)s | %(message)s")
|
|
|
| sys.path.insert(0, str(official_root))
|
| os.chdir(official_root)
|
| sys.argv = [sys.argv[0]]
|
|
|
| from configs.config import Config
|
| from infer.modules.vc.modules import VC
|
|
|
| config = Config()
|
| vc = VC(config)
|
| vc.get_vc(args.sid)
|
|
|
| spk_max = 1
|
| try:
|
| if getattr(vc, "cpt", None) is not None:
|
| spk_max = int(vc.cpt["config"][-3])
|
| except Exception:
|
| spk_max = 1
|
| spk_id = max(0, min(max(1, spk_max) - 1, int(args.speaker_id)))
|
|
|
| info, (sr, audio) = vc.vc_single(
|
| spk_id,
|
| args.vocals_path,
|
| args.pitch_shift,
|
| None,
|
| args.f0_method,
|
| args.index_path,
|
| "",
|
| args.index_rate,
|
| args.filter_radius,
|
| 0,
|
| args.rms_mix_rate,
|
| args.protect,
|
| )
|
| if sr is None or audio is None:
|
| raise RuntimeError(info)
|
|
|
| output_path = Path(args.output_path)
|
| output_path.parent.mkdir(parents=True, exist_ok=True)
|
| sf.write(output_path, audio, sr)
|
|
|
| match = re.search(
|
| r"Time:\s*npy:\s*([0-9.]+)s,\s*f0:\s*([0-9.]+)s,\s*infer:\s*([0-9.]+)s\.",
|
| str(info),
|
| re.IGNORECASE | re.MULTILINE,
|
| )
|
| print("转换成功。", flush=True)
|
| if args.index_path:
|
| print(f"索引:{args.index_path}", flush=True)
|
| if match:
|
| print(
|
| f"耗时:npy {match.group(1)}s,f0 {match.group(2)}s,推理 {match.group(3)}s",
|
| flush=True,
|
| )
|
| return 0
|
|
|
|
|
| if __name__ == "__main__":
|
| raise SystemExit(main())
|
|
|