Files
enshrouded-ru-voice/ensvoice/render.py
T

44 lines
1.5 KiB
Python

"""Step 4: speak every segment in every seed of voice.seeds (work/takes/<take>_s<seed>.wav).
usage: render [--weak] --weak: only the segments pick listed as weak, in voice.extra_seeds
Resumable: existing takes are skipped, so after a lexicon change only the changed segments are spoken.
"""
import json
import sys
from .config import load
from .tts import backend
def reference(cfg, ref_id=None):
ref_id = ref_id or cfg["voice"]["reference"]
refs = {c["id"]: c for c in json.load(open(cfg.w("refs.json"), encoding="utf-8"))}
if ref_id not in refs:
raise SystemExit(f"reference {ref_id!r} is not in work/refs.json (run refs; see README)")
return cfg.w("refs", f"{ref_id}.wav"), refs[ref_id]["text"]
def main():
cfg = load()
segs = json.load(open(cfg.w("segs.json"), encoding="utf-8"))
seeds = cfg["voice"]["seeds"]
if "--weak" in sys.argv:
weak = set(json.load(open(cfg.w("pick_report.json")))["weak"])
segs = [s for s in segs if s["id"] in weak]
seeds = cfg["voice"].get("extra_seeds", [])
tts = None
for seed in seeds:
todo = [(s["acute"], str(cfg.w("takes", f"{s['take']}_s{seed}.wav"))) for s in segs
if not cfg.w("takes", f"{s['take']}_s{seed}.wav").exists()]
print(f"seed {seed}: {len(todo)} segments to speak", flush=True)
if not todo:
continue
if tts is None:
tts = backend(cfg, *reference(cfg))
tts.speak(todo, seed, log=lambda m: print(m, flush=True))
print("RENDER_DONE")
if __name__ == "__main__":
main()