vo_synth
Rank multiple zero-shot voice-clone renders of a line, pick the most speaker-like non-flat take, and splice it into the timeline after a chosen word.
Instructions
Say text in a cloned voice — render several seeds, rank them, read the winner back.
Zero-shot Qwen3-TTS from a ≈19s reference clip (voice); there is no
built-in voice. Seeds seed .. seed+candidates-1 render in one process,
each with sim (speaker-embedding likeness to the reference — a real take
≈0.99, a 3-semitone shift ≈0.96) and spread (voiced pitch movement).
chosen is the best sim less a flatness penalty, since likeness alone
keeps the flattest read. A render that hit max_seconds is capped and
never wins while an uncapped one exists.
The winner is read back through whisper and heard/wer reported — a
clone that sounds right and says the wrong words is the failure nothing
else sees. A report, never a gate.
Renders are cached under cache/synth/, so a repeat spends no GPU. The
splice is not cached: with clip_id + word_index the winner is
registered and spliced in after that word through vo_extend's mechanism
(melt routing, restore refusing across the seam, a covered_by
report), and calling again splices a second time — check the timeline or
undo rather than re-calling. plan=True reports the ranking and splice
preview from cached renders only, and says rendered: False rather than
spending the GPU.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | The project directory to act on. Omit it — the usual case — when this server is bound to a project (started as `proofcut -C DIR mcp`, or inside a project; `ping` says which): it then resolves to that one bound project, a relative path resolves against it, and a path outside it is refused by name. Unbound, `path` is the whole address and omitting it refuses rather than guessing. | |
| plan | No | Resolve the whole call and report what it would do, writing nothing. Prefer it over doing the thing and undoing it. | |
| seed | No | First seed of the range; seeds `seed .. seed+candidates-1` render in one process. A new range renders only what the cache lacks. | |
| text | Yes | What the voice says. It is respelled first through the project's `lexicon.json` `say` folds, if one exists — the fix for a mispronounced name. | |
| voice | No | A directory holding `ref.wav` + `ref.txt`, the ≈19s reference the clone is zero-shot from. Unset, `$PROOFCUT_TTS_VOICE`. There is no built-in voice, and none ships in the repo: a voice is somebody's recorded speech. | |
| clip_id | No | With `word_index`, the track to splice the winner into. Omitted, nothing is spliced and the renders are just ranked. | |
| lexicon | No | A `{"say": {…}, "hear": {…}}` file: `say` respells what the model is given, `hear` folds whisper's spelling back to the script's before the WER is scored. Defaults to the project's own `lexicon.json` if it has one. | |
| readback | No | Transcribe the winner with whisper and report `heard`/`wer`. On by default: a clone that sounds right and says the wrong words is the failure nothing else sees. The numbers are a report, never a gate. | |
| candidates | No | How many seeds to render and rank. Seed moves a render more than the reference does, which is why this ranks rather than renders once. | |
| flat_floor | No | Below this much voiced pitch movement (semitones) a render starts paying the flatness penalty. Likeness alone keeps the flattest read, because sims in one pool differ by thousandths while spread differs by semitones. | |
| word_index | No | The word to splice the winner in right after, through `vo_extend`'s own mechanism — so the same one-way consequences follow (melt routing, `restore` refusing across the seam). | |
| flat_weight | No | How much likeness to subtract per semitone of flatness under the floor. 0 restores likeness-only ranking. | |
| max_seconds | No | Length cap per render. One that hits it is reported `capped` and never wins while an uncapped one exists — a 21s reference once ran every render to 655s. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||