44 lines
1.5 KiB
Python
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()
|