Files
UmbraAudio/specs/11-configuration-dependencies.md
B.D. Murphy c86e323d7a Initial commit: UmbraAudio audiobook generation program
Quality-first multi-pass audiobook generation from English manuscripts.

Includes:
- umbraaudio/ core package (pipeline, config, voices, web review UI)
- scripts/ CLI utilities + model download script
- tts_server/ remote TTS server
- specs/ design docs, tests/, pyproject.toml + uv.lock
- Qwen3-TTS git submodule (pinned 022e286) with local demo.py UI patch
  saved at scripts/qwen3_tts_demo_umbra_patch.patch
- .env with runtime config/secrets

Excluded (see .gitignore): models/ (downloaded via scripts/download_models.sh),
output/, logs/, .venv, .umbra runtime data, and book projects
(DealHunterShip_*), which are committed separately.
2026-08-30 07:58:24 -07:00

7.7 KiB

Spec: Configuration & Dependencies

Overview

UmbraAudio uses Pydantic Settings for configuration with environment variable override support. All config lives in umbraaudio/config.py.

Configuration Hierarchy

AppConfig (root)
├── project_dir: Path
├── data_dir: Path
├── tts: TTSConfig
├── quality: QualityConfig
├── audio: AudioConfig
├── llm: LLMConfig
└── web: WebConfig

Environment variable prefix: UMBRA_ (e.g., UMBRA_TTS_DEVICE=cpu)

Configuration Classes

TTSConfig

class TTSConfig(BaseSettings):
    engine: Literal["chatterbox", "qwen"] = "chatterbox"
    device: Literal["cuda", "cpu"] = "cuda"
    sample_rate: int = 24000
    max_retries: int = 3
    retry_delay: float = 2.0
Field Default Env Var Description
engine "chatterbox" UMBRA_TTS_ENGINE TTS engine selection
device "cuda" UMBRA_TTS_DEVICE Compute device
sample_rate 24000 UMBRA_TTS_SAMPLE_RATE Audio sample rate (Hz)
max_retries 3 UMBRA_TTS_MAX_RETRIES Generation retry attempts
retry_delay 2.0 UMBRA_TTS_RETRY_DELAY Delay between retries (seconds)

QualityConfig

class QualityConfig(BaseSettings):
    min_mos: float = 3.8
    min_test_mos: float = 4.0
    max_wer: float = 0.03
    min_speaker_similarity: float = 0.80
    min_test_speaker_similarity: float = 0.85
    min_artifact_score: float = 3.5
Field Default Description
min_mos 3.8 Minimum Mean Opinion Score
min_test_mos 4.0 Minimum MOS for test pass
max_wer 0.03 Maximum Word Error Rate (3%)
min_speaker_similarity 0.80 Minimum speaker embedding similarity
min_test_speaker_similarity 0.85 Minimum for test pass
min_artifact_score 3.5 Minimum artifact detection score

AudioConfig

class AudioConfig(BaseSettings):
    target_rms_db: float = -20.0
    peak_limit_db: float = -3.0
    noise_floor_db: float = -60.0
    silence_between_utterances_ms: int = 500
    silence_between_paragraphs_ms: int = 2000
    silence_between_chapters_ms: int = 4000
Field Default Description
target_rms_db -20.0 Target RMS level for normalization
peak_limit_db -3.0 Maximum peak level
noise_floor_db -60.0 Noise floor threshold
silence_between_utterances_ms 500 Gap between sentences (ms)
silence_between_paragraphs_ms 2000 Gap between paragraphs (ms)
silence_between_chapters_ms 4000 Gap between chapters (ms)

LLMConfig

class LLMConfig(BaseSettings):
    provider: Literal["lmstudio", "openai", "auto"] = "auto"
    lmstudio_base_url: str = "http://localhost:1234/v1"
    lmstudio_model: str = "local-model"
    openai_model: str = "gpt-4o"
    temperature: float = 0.3
    max_tokens: int = 4096
Field Default Description
provider "auto" LLM provider selection
lmstudio_base_url "http://localhost:1234/v1" LM Studio API endpoint
lmstudio_model "local-model" LM Studio model name
openai_model "gpt-4o" OpenAI model name
temperature 0.3 Generation temperature
max_tokens 4096 Maximum response tokens

Provider selection (auto mode):

  1. Try LM Studio at lmstudio_base_url
  2. Fall back to OpenAI API
  3. Raise error if neither available

WebConfig

class WebConfig(BaseSettings):
    host: str = "127.0.0.1"
    port: int = 8420
    auto_open: bool = True

AppConfig

class AppConfig(BaseSettings):
    project_dir: Path = Path(".")
    data_dir: Path = Path(".umbra")
    tts: TTSConfig = Field(default_factory=TTSConfig)
    quality: QualityConfig = Field(default_factory=QualityConfig)
    audio: AudioConfig = Field(default_factory=AudioConfig)
    llm: LLMConfig = Field(default_factory=LLMConfig)
    web: WebConfig = Field(default_factory=WebConfig)

Properties:

Property Returns Description
db_path Path .umbra/project.db
voices_dir Path .umbra/voices/
audio_dir Path .umbra/audio/
export_dir Path .umbra/export/

Methods:

Method Description
ensure_dirs() Creates all data directories

Factory Function

def load_config(project_dir: Path | None = None) -> AppConfig
  1. Creates AppConfig()
  2. Sets project_dir and data_dir if provided
  3. Calls ensure_dirs()
  4. Returns config

Dependencies

Core Dependencies

Package Version Purpose
click >=8.1 CLI framework
rich >=13.0 CLI formatting
aiosqlite >=0.19 Async SQLite
ebooklib >=0.18 EPUB parsing
PyMuPDF >=1.23 PDF parsing
booknlp >=1.0 NLP analysis
openai >=1.10 LLM API client
httpx >=0.25 HTTP client
chatterbox-tts >=0.1 Primary TTS
torch >=2.1 ML framework
torchaudio >=2.1 Audio processing
librosa >=0.10 Audio analysis
soundfile >=0.12 Audio I/O
pydub >=0.25 Audio manipulation
speechmos >=0.0.1 MOS scoring
openai-whisper >=20231117 Speech recognition
speechbrain >=0.5 Speaker embeddings
fastapi >=0.104 Web framework
uvicorn[standard] >=0.24 ASGI server
jinja2 >=3.1 Templating
python-multipart >=0.0.6 Form handling
numpy >=1.24 Numerical computing
pydantic >=2.5 Data validation
pydantic-settings >=2.1 Settings management

Optional Dependencies

Group Package Purpose
dev pytest>=7.4 Testing
dev pytest-asyncio>=0.21 Async testing
dev pytest-cov>=4.1 Coverage
dev ruff>=0.1 Linting
dev mypy>=1.7 Type checking
qwen transformers>=4.36 Qwen TTS support
qwen qwen3-tts>=0.1 Qwen TTS engine

System Dependencies

Tool Purpose Required
FFmpeg Audio export (M4B, MP3) For export
lms CLI LM Studio management For pipeline
CUDA toolkit GPU acceleration For TTS

Build System

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project.scripts]
umbraaudio = "umbraaudio.cli:main"

Tool Configuration

Ruff

[tool.ruff]
target-version = "py311"
line-length = 100
select = ["E", "F", "I", "N", "W", "UP", "B", "S", "SIM", "TCH"]

Mypy

[tool.mypy]
python_version = "3.11"
strict = true
plugins = ["pydantic.mypy"]

Pytest

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"

Runtime Paths

.umbra/                          # Data directory
├── project.db                   # SQLite database
├── voices/                      # Voice reference WAVs
├── audio/                       # Raw generated audio
├── audio_normalized/            # Normalized audio
├── manifests/                   # Generation manifests
├── cache/                       # Generation cache
│   └── cache_index.json
├── export/                      # Final audiobook files
└── defects.json                 # Quality defect log

Cache Locations

Cache Location Description
HuggingFace /mnt/models/huggingface Model weights (symlinked)
Torch /mnt/models/torch Torch hub cache (symlinked)
Generation .umbra/cache/ Text+voice_ref hash cache
Pip ~/.cache/pip Package download cache