| """TTS backend abstraction and automatic backend selection. |
| |
| The dataset builder is agnostic to which engine produces audio. Two |
| backends are provided: |
| |
| * :class:`~src.backends.gcp.GCPTTSBackend` — Google Cloud TTS via REST |
| API key. Used when a key is available. |
| * :class:`~src.backends.piper.PiperTTSBackend` — free, local Piper TTS. |
| Used as the fall back. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from typing import List, Optional |
|
|
| from .base import SynthesisResult, TTSBackend, Voice |
| from .gcp import GCPTTSBackend |
| from .piper import PiperTTSBackend |
|
|
| __all__ = [ |
| "SynthesisResult", |
| "TTSBackend", |
| "Voice", |
| "GCPTTSBackend", |
| "PiperTTSBackend", |
| "select_backend", |
| ] |
|
|
|
|
| def select_backend( |
| gcp_api_key: Optional[str], |
| language_prefixes: List[str], |
| max_gcp_voices_per_locale: int, |
| max_piper_voices: int, |
| sample_rate_hz: int, |
| ) -> TTSBackend: |
| """Return a ready TTS backend. |
| |
| Prefers Google Cloud TTS when ``gcp_api_key`` is provided and the key |
| validates. Otherwise (no key, or the key fails to initialise) falls |
| back to the free Piper backend. |
| """ |
| if gcp_api_key and gcp_api_key.strip(): |
| backend = GCPTTSBackend( |
| api_key=gcp_api_key.strip(), |
| language_prefixes=language_prefixes, |
| max_voices_per_locale=max_gcp_voices_per_locale, |
| sample_rate_hz=sample_rate_hz, |
| ) |
| try: |
| backend.prepare() |
| return backend |
| except Exception as exc: |
| print(f"[backend] Google Cloud TTS unavailable ({exc}); falling back to Piper.") |
|
|
| backend = PiperTTSBackend( |
| max_voices=max_piper_voices, |
| sample_rate_hz=sample_rate_hz, |
| ) |
| backend.prepare() |
| return backend |
|
|