This commit is contained in:
2026-08-26 17:42:00 -04:00
commit ad95d530ad
134 changed files with 31750 additions and 0 deletions
@@ -0,0 +1,84 @@
from __future__ import annotations
import logging
import os
from dataclasses import dataclass
from typing import Any
import numpy as np
from speech_to_speech.pipeline.messages import TTSInput
logger = logging.getLogger(__name__)
_TRUE_VALUES = {"1", "true", "yes", "on"}
@dataclass(slots=True)
class DelayFillerConfig:
enabled: bool
threshold_s: float
short_phrases: list[str]
full_phrases: list[str]
def _split_env_list(name: str) -> list[str]:
raw = os.environ.get(name, "").strip()
return [part.strip() for part in raw.split("|") if part.strip()]
def _env_flag(name: str, *, default: bool) -> bool:
raw = os.environ.get(name)
if raw is None:
return default
return raw.strip().lower() in _TRUE_VALUES
def load_delay_filler_config() -> DelayFillerConfig:
short_phrases = _split_env_list("TTS_DELAY_FILLERS_SHORT_ES")
full_phrases = _split_env_list("TTS_DELAY_FILLERS_FULL_ES")
# Backward compatibility with the old single-list variable.
if not short_phrases and not full_phrases:
full_phrases = _split_env_list("TTS_DELAY_FILLERS_ES")
enabled = _env_flag("TTS_DELAY_FILLERS_ENABLED", default=bool(short_phrases or full_phrases))
threshold_ms_raw = os.environ.get("TTS_DELAY_FILLERS_THRESHOLD_MS", "1200").strip() or "1200"
try:
threshold_ms = max(0, int(threshold_ms_raw))
except ValueError:
logger.warning("Invalid TTS_DELAY_FILLERS_THRESHOLD_MS=%r; using 1200", threshold_ms_raw)
threshold_ms = 1200
return DelayFillerConfig(
enabled=enabled and bool(short_phrases or full_phrases),
threshold_s=threshold_ms / 1000.0,
short_phrases=short_phrases,
full_phrases=full_phrases,
)
def _chunk_to_bytes(chunk: Any) -> bytes:
audio = getattr(chunk, "audio", chunk)
if isinstance(audio, np.ndarray) or hasattr(audio, "tobytes"):
return audio.tobytes()
if isinstance(audio, bytes):
return audio
raise TypeError(f"Unsupported delay filler audio chunk type: {type(audio)!r}")
def pregenerate_delay_filler_clips(tts_handler: Any, phrases: list[str]) -> list[bytes]:
clips: list[bytes] = []
for phrase in phrases:
try:
clip = b"".join(
_chunk_to_bytes(chunk)
for chunk in tts_handler.process(TTSInput(text=phrase, language_code="es"))
)
except Exception:
logger.exception("Failed to pregenerate TTS delay filler for phrase %r", phrase)
continue
if not clip:
logger.warning("Discarding empty TTS delay filler for phrase %r", phrase)
continue
clips.append(clip)
return clips