B.D. Murphy 948034c365 Add an SLang tab listing the multilingual sample chapters
The rendered sample chapters existed on disk but had no way to be listened
to through the UI. New /lang-samples page, reachable from a new SLang nav
tab, lists every language chapter with an inline player plus the combined
all-languages file.

- Serves from <project>/Lang_test, which is where render_lang_test.py writes.
  Deliberately project_dir and not data_dir: .umbra is gitignored state and
  the render output lives beside the rest of the project.
- Languages are discovered from disk in a fixed order rather than hardcoded,
  so an unrendered language simply does not appear instead of offering a
  player that 404s.
- The audio path validates a two-to-three letter code and builds the
  filename server-side, so it cannot be walked out of the sample directory.
  Verified: %2e%2e and over-long codes are rejected 400, unauthenticated
  requests 303 to login.
- A missing language now 404s rather than falling back to the combined file.
  It did before, so an unrendered language would silently play the wrong
  audio - the same class of bug as a stale speaker name resolving to no
  voice at all.

Verified in a browser: 11 players, durations resolve (EN 92.3s, ZH 92.0s,
combined 1067.8s), no load errors, range requests 206 so seeking works.

routes.py stays at its 76 pre-existing ruff errors. Suite: 721 passed,
8 pre-existing.
2026-10-13 02:39:29 -07:00

UmbraAudio

Quality-first multi-pass audiobook generation from English manuscripts.

Features

  • 5-pass pipeline: Analysis → Voice Design → Mapping → Test → Generate
  • Multi-engine TTS: Chatterbox (primary), Qwen3-TTS (secondary)
  • LLM-enhanced: BookNLP for NLP, LLM for profiling/emotion/pronunciation
  • Web review: FastAPI + HTMX at checkpoints for human approval

Quick Start

python -m umbraaudio.cli init <manuscript.epub> --name 'My Book'
python -m umbraaudio.cli analyze
python -m umbraaudio.cli voices
python -m umbraaudio.cli review

Requirements

  • Python 3.11+
  • NVIDIA GPU with CUDA support (RTX 3060 or better recommended)
  • ffmpeg

Development

pip install -e ".[dev]"
ruff check umbraaudio/
pytest tests/ -v

Commit cadence: commit at least once every Sunday. Never leave a week (let alone a month) of work uncommitted — a single accidental git checkout on 2026-09-20 wiped out a month of changes to umbraaudio/web/routes.py. See AGENTS.md → Commit Cadence.

scripts/commit_check.sh enforces the nudge: it exits non-zero once the tree has been dirty longer than a week. The LaunchAgent com.umbraaudio.commitcheck runs it every Sunday at 18:00 and posts a macOS notification when there is uncommitted work.

scripts/commit_check.sh            # warn if dirty > 7 days
scripts/commit_check.sh --days 3   # tighter threshold
scripts/commit_check.sh --any      # warn on any uncommitted change

Rebuilding from source

The repo tracks source only; large runtime data is reconstructed as needed.

  1. Models: weights are not committed (see .gitignore). Download them:

    bash scripts/download_models.sh   # ~9 GB, targets ./models
    
  2. Qwen3-TTS is a git submodule pinned to upstream commit 022e286:

    git submodule update --init --recursive
    

    The tts_server/web-demo backend includes a local UI customization to qwen_tts/cli/demo.py. It is preserved as a patch — reapply it after checking out the submodule:

    cd Qwen3-TTS && git apply ../scripts/qwen3_tts_demo_umbra_patch.patch
    
  3. Environment: copy/keep .env (contains secrets) and set UMBRA_TTS__* model paths under models/.

Book projects (e.g. DealHunterShip_...) are committed separately under their own project directories and are not part of this program repository.

Description
Quality-first multi-pass audiobook generation pipeline (5-pass: Analysis -> Voice Design -> Mapping -> Test -> Generate). FastAPI+HTMX review UI, Edge-TTS/Qwen3-TTS multi-engine voice, SQLite state.
Readme Apache-2.0 37 MiB
Languages
Python 84.8%
HTML 11.4%
Shell 3%
PLpgSQL 0.7%