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.
72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from umbraaudio.voices.edge_tts import ALL_EDGE_VOICES, EdgeTTSEngine
|
|
|
|
|
|
@pytest.fixture
|
|
def engine() -> EdgeTTSEngine:
|
|
return EdgeTTSEngine()
|
|
|
|
|
|
def _voice_names() -> set[str]:
|
|
return {v["name"] for v in ALL_EDGE_VOICES}
|
|
|
|
|
|
class TestSelectVoice:
|
|
def test_male_american_low_returns_deep_us(self, engine: EdgeTTSEngine) -> None:
|
|
voice = engine.select_voice(
|
|
energy="commanding",
|
|
pitch="very_low",
|
|
gender="Male",
|
|
character_name="Narrator",
|
|
accent="american",
|
|
)
|
|
assert voice == "en-US-GuyNeural"
|
|
|
|
def test_respects_accent(self, engine: EdgeTTSEngine) -> None:
|
|
voice = engine.select_voice(
|
|
energy="measured",
|
|
pitch="mid",
|
|
gender="Male",
|
|
character_name="Ravi",
|
|
accent="indian",
|
|
)
|
|
assert voice in _voice_names()
|
|
chosen = next(v for v in ALL_EDGE_VOICES if v["name"] == voice)
|
|
assert chosen["accent"] == "indian"
|
|
assert chosen["gender"] == "male"
|
|
|
|
def test_respects_pitch_when_accent_broad(self, engine: EdgeTTSEngine) -> None:
|
|
voice = engine.select_voice(
|
|
energy="measured",
|
|
pitch="high",
|
|
gender="Female",
|
|
character_name="Lily",
|
|
accent="american",
|
|
)
|
|
chosen = next(v for v in ALL_EDGE_VOICES if v["name"] == voice)
|
|
assert chosen["pitch"] == "high"
|
|
|
|
def test_mid_register_allows_any_mid_accent(self, engine: EdgeTTSEngine) -> None:
|
|
voice = engine.select_voice(
|
|
energy="measured",
|
|
pitch="mid",
|
|
gender="Male",
|
|
character_name="Alex",
|
|
accent="british",
|
|
)
|
|
chosen = next(v for v in ALL_EDGE_VOICES if v["name"] == voice)
|
|
assert chosen["accent"] == "british"
|
|
|
|
def test_no_accent_picks_something_valid(self, engine: EdgeTTSEngine) -> None:
|
|
voice = engine.select_voice(
|
|
energy="measured",
|
|
pitch="mid",
|
|
gender="Female",
|
|
character_name="Sam",
|
|
accent=None,
|
|
)
|
|
assert voice in _voice_names()
|