Skip to content

Latest commit

 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Textcast

Turn a plain-text file into a downloadable MP3 using open-source, CPU-friendly text-to-speech. Upload a .txt, pick an engine and voice, get an MP3 back through a small Gradio web UI.

Four engines are bundled:

  • Kokoro-82M (Apache 2.0) — high-quality narration, GPU-accelerated.
  • Piper (MIT) — fastest on CPU, good for very long documents.
  • Chatterbox (MIT) — highest-quality voice cloning from a reference clip (GPU, slow).
  • Chatterbox Turbo (MIT) — fast voice cloning (GPU); the default cloning engine.

Setup

1. System packages

espeak-ng provides phonemization for the TTS engines and ffmpeg encodes the final MP3.

sudo apt-get update
sudo apt-get install -y espeak-ng ffmpeg

2. Python dependencies

Use a virtual environment (Python 3.10+ recommended):

python -m venv tts-env
source tts-env/bin/activate
pip install -r requirements.txt

3. Download a Piper voice

Kokoro downloads its own weights on first use. Piper needs a voice model downloaded into the project directory:

python -m piper.download_voices en_US-lessac-medium

This writes en_US-lessac-medium.onnx (and its .json config), which matches the default Piper model path in app.py. Browse other voices at the Piper voices repo.

GPU acceleration (optional)

Kokoro runs on an NVIDIA GPU automatically when CUDA-enabled PyTorch is available. If the default install's torch doesn't match your driver, check with:

python -c "import torch; print(torch.cuda.is_available())"

If that prints False, reinstall torch for your CUDA version — e.g. for CUDA 12.6:

pip install --force-reinstall torch --index-url https://download.pytorch.org/whl/cu126

Piper always runs on CPU and needs nothing extra.

Run

python app.py

Then open http://127.0.0.1:7860 in your browser, upload a .txt file, choose an engine and voice, and click Convert to MP3.

Output folder

The Output folder field controls where the MP3s are kept. It defaults to output/ (relative to the app folder) and also accepts an absolute path such as /home/you/audiobooks or ~/audiobooks. The folder is created if it doesn't exist, and the path is checked before conversion starts, so a bad destination fails immediately instead of after synthesis. The Browse for a folder panel underneath opens a file explorer for picking an existing folder, which fills the field for you; typing a path by hand still works and is the way to send audio to a folder that doesn't exist yet.

On WSL the browser is rooted at /mnt, so every mounted Windows drive (/mnt/c, /mnt/d, …) is reachable; it falls back to the Windows user profile and then to your home directory when those mounts aren't present. Desktop, Documents, Downloads, and Music quick-jump buttons fill the field with the matching folder under C:\Users\suberu (only the ones that exist are shown). Windows-style paths are accepted in the textbox too — C:\Users\suberu\Music and C:/Users/suberu/Music are both translated to /mnt/c/Users/suberu/Music.

Create this folder next to the field creates the folder right away and reports the absolute path (or what went wrong). It's optional: a typed folder is still created automatically when you convert.

MP3s can be saved anywhere under the browsable roots. Gradio only serves files from its own sandbox, so app.py passes those roots to demo.launch(allowed_paths=...) — otherwise a file written outside the working directory converts fine but fails with InvalidPathError when the UI tries to offer it for download. allowed_paths is read once at launch, so saving into a folder outside those roots means adding it there (and restarting). Existing files are never overwritten — a second conversion of chapter.txt is saved as chapter (1).mp3. The converted files also remain downloadable from the UI.

Engines

Engine Speed (RTF) Hardware Best for
Piper 14.6x real-time CPU Fastest; bulk conversion
Chatterbox Turbo 1.4x real-time GPU (warm) Default for voice cloning
Kokoro GPU High-quality narration
Chatterbox 0.4x real-time GPU Highest-quality cloning (slow)

All real-time factors were measured on an RTX 3050 laptop GPU / typical CPU. First runs are slower because models are downloaded on demand. The app reports the exact speed (elapsed time, real-time factor, words/min) after each conversion.

Reference voices

The voices/ folder ships 12 CC0 Canadian-accented clips extracted from Mozilla Common Voice via get_ca_voices.py:

Name Country Gender Name Country Gender
Clara CA female Liam CA male
Sophie CA female Noah CA male
Hannah CA female Owen CA male
Grace CA female Lucas CA male
Zoe CA female Ethan CA male
Maya CA female Carter CA male

The country/gender shown in the Cloned voice dropdown (e.g. Clara (CA female)) comes from voices/voices.json. Each clip is from a unique speaker (deduplicated by Common Voice client_id, one clip per contributor) and the set is verified pairwise-distinct with audit_voices.py — all pairs score below the 0.75 Resemblyzer similarity threshold. Drop any .wav/.mp3/.flac into voices/ and click Rescan voices in the UI to clone it with the Chatterbox engines.

To label a newly dropped-in voice, add an entry for its filename stem to voices/voices.json (e.g. "emma": {"country": "CA", "gender": "female"}) and click Rescan voices; unlisted voices simply show their bare name.

audit_voices.py checks the shipped voices for duplicate speakers via pairwise cosine similarity (pip install resemblyzer).

Notes

  • Long inputs are split into sentence-safe chunks so progress can be reported and no single call gets an unbounded input.
  • MP3 bitrate, chunk size, and available voices are configurable at the top of app.py.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages