Retry the bad takes
A sustained loud-burst detector catches likely garbling per chunk and re-rolls it within a configurable retry budget.
Open-source voice-cloning voiceover pipeline
ses renders a cloned voice section by section, automatically retries suspicious takes, optionally enhances the result, and delivers editable WAVs plus one complete render.
Bring any voice sample and any script. Pair the sample with a transcript for ICL cloning, tune the pacing to your project, and keep every section as a separate deliverable.
Built for narration work
A sustained loud-burst detector catches likely garbling per chunk and re-rolls it within a configurable retry budget.
Over-long internal silences trigger a section-level re-render before the take is ever accepted.
LavaSR post-processing is optional. If it injects high-frequency hash, the enhanced result is discarded and the raw take is kept.
Revise a single part with --slide N instead of re-rendering the entire script. Indexes are zero-based.
The signal path
The orchestration is one line in ses/pipeline.py — parse → chunk → synth → gate → enhance → level → concat. Two stations can send the signal backwards.
Authoring
Timestamped headings become named audio files. Blockquotes become narration. Blank quoted lines create longer paragraph pauses. Leave TODO, REDO, or WIP markers in place — ses skips them.
## 0:00 — Welcome
> Welcome to ses, a voiceover pipeline. This tool turns a
> written script into narrated audio using a short sample
> of your own voice.
>
> You write in plain markdown, drop in a voice sample, and
> get back one WAV per section plus a single render.
## 0:20 — How it works
> Each section is split into sentences and synthesized one
> sentence at a time, which keeps the prosody stable.
>
> TODO tighten the pacing note here audio/20260720-143000/
├─ slide-00-welcome.wav
├─ slide-01-how-it-works.wav
├─ slide-02-getting…wav
├─ slide-02-getting….raw.wav
└─ full.wav Your first render
Put my_voice.wav in in/. Add my_voice.txt with the clip transcript to enable ICL cloning. Model weights download on the first render; later runs can work offline.
Useful controls
--dry-runParse and print — no models, no audio.--slide 2Render a single section (zero-based).--no-enhanceRender without LavaSR enhancement.--samples-dirPoint at any folder of voice samples.# 1 · install dependencies
$ pip install -r requirements.txt
# qwen-tts shells out to the SoX executable
$ brew install sox
# 2 · drop in/my_voice.wav (+ optional in/my_voice.txt)
# then render your script
$ python -m ses --script script.md --sample my_voice
# iterate on just section 2, no enhancement
$ python -m ses --script script.md --sample my_voice \
--slide 2 --no-enhance For developers
Parsing, chunking, DSP, and quality gates stay importable with numpy alone. Heavy model libraries are isolated inside adapters. Use the whole pipeline, pass your own engine to run_pipeline, or copy only the modules your project needs.
Take the pipeline — or just the useful parts.
Need only trim, fade, normalize, garble detection, or pause detection? The pure audio modules copy into another project without torch, Qwen3-TTS, LavaSR, or the orchestration layer.
$ mkdir -p yourproject/audio
$ cp ses/audio/__init__.py \
ses/audio/dsp.py ses/audio/quality.py \
yourproject/audio/
$ pip install numpy The honest part
ses runs Qwen3-TTS locally on Apple MPS or CPU and uses LavaSR for optional enhancement. The quality gates are tuned to this stack — you can replace an adapter, but a different engine will usually need different gate thresholds. It is an early-stage, developer-oriented reference pipeline, not a hosted product.
Read the source
Start with a reference clip, write the narration in Markdown, and let ses render, check, enhance, and assemble the take.