Skip to content

keryx voice takes

Description

See what's on the table before you pick. voice takes lists a workspace's VO candidate takes (vo/takes/NN-T.mp3) per storyboard line, with each take's duration and a marker on the promoted one — so the "re-roll these lines and choose the best" loop can be screened without leaving the CLI (spec 0023). Actual listening stays out-of-band (or in the studio); keryx surfaces the metadata that ranks them.

It is one half of the take workflow:

keryx voice gen --workspace my-post --lines 3,5,7 --takes 3   # re-roll a subset
keryx voice takes --workspace my-post                          # screen what came back
keryx voice pick 5 2 --workspace my-post                       # promote the winner

Usage

keryx voice takes --workspace <slug> [--line N] [flags]

Behaviour

  • Per line: every candidate take with its number, filename, duration, and whether it is the promoted selection (content-matched against vo/NN.mp3 — promotion copies the take, so equality identifies the winner).
  • Durations are best-effort: they probe through the backend selected by providers.render (in-memory on afmpeg); if no backend is available or a probe fails, the listing degrades to 0.00s rather than erroring.
  • --line N filters to one line; --output json emits the listing for the studio / scripts.
  • An empty workspace lists nothing and says so — not an error.

Stilt screening (--screen)

--screen scores each take so a stumble ranks last automatically instead of by ear (spec 0023 R-GEN-38). The combined score is:

  • duration deviation from the line's median take — a longer read (the tell-tale of a stumble or an inserted pause) is penalised more than a tighter one; plus
  • excess internal silence — silences inside the read (lead and tail excluded) beyond the pauses the line actually scripts ( and <break> are forgiven).

Lower is cleaner; the cleanest take is marked . The per-take sub-scores are surfaced (in the table and in --output json) so a ranking is auditable, not a magic number. When a line's best take still reads over-paused, the whole line is flagged "all takes over-paused — reword/respell" (R-GEN-38b): no clean read exists, so the fix is the script, not another re-roll.

Silence detection needs the render backend's silencedetect, which the default afmpeg backend does not have — its published module is built lean for the reel pipeline. So out of the box, screening ranks on duration alone rather than on internal pauses. It degrades rather than failing, and says so on stderr:

INFO silence screening unavailable on the afmpeg render backend; ranking takes on duration alone

Set providers.render: ffmpeg for silence-aware screening.

Flags

Flag Description Default Required
-w, --workspace reel workspace slug yes
--line list only this storyboard line (0 = all) 0
--screen stilt-score the takes (duration + internal silence) and flag over-paused lines false

Run keryx voice takes --help for the authoritative, always-current flag set.

Where a take came from

The source column says whether a take was synthesised (tts) or read by a person (recorded) — a studio recording or a voice add (spec 0030). It matters because the two are not interchangeable to screen: a human read is not stilted, so --screen's ranking is meaningless for one, while its duration still drives the card exactly as a synthesis would.

The fact is recorded when the take arrives, on the workspace, rather than guessed at afterwards. Nothing in the audio can be trusted to answer later — the container names its writer, and it separates today's takes only because the voice provider happens to mux with ffmpeg, which no contract promises. Takes that predate the record fall back to their format, which reads the existing ones correctly.

Example

$ keryx voice takes -w my-post
line  take  source    duration  selected
1     1     tts       3.41s
1     2     tts       3.28s     *
1     3     recorded  3.55s
3     1     tts       4.02s

$ keryx voice takes -w my-post --screen
line  take  duration  silence  score  best  selected
1     1     3.41s     0        0.040
1     2     3.28s     0        0.000  ←     *
3     1     4.02s     2        1.290
3     2     3.10s     0        0.000  ←

See also