"""TTS 엔진 공통 인터페이스. 각 엔진은 서로 다른 의존성(torch/librosa/numpy 핀)을 가질 수 있으므로, in-process 로 도는 엔진(MeloTTS)과 전용 venv 를 subprocess 로 호출하는 엔진 (Coqui 등)을 동일한 인터페이스로 노출한다. """ from __future__ import annotations from abc import ABC, abstractmethod class BaseEngine(ABC): id: str = "" label: str = "" license: str = "" uses_gpu: bool = False notes: str = "" @abstractmethod def describe(self) -> dict: """엔진 메타데이터 + 언어/목소리 목록. 반환 예: { "id": "melo", "label": "MeloTTS", "license": "MIT", "uses_gpu": True, "notes": "...", "languages": [ {"code": "KR", "label": "한국어", "speakers": [{"id": "KR", "label": "기본"}]} ], "supports": {"speed": True, "pitch": True}, } """ raise NotImplementedError @abstractmethod def synth_wav( self, text: str, language: str, speaker: str | None = None, speed: float = 1.0, pitch: float = 0.0, ) -> bytes: """WAV(PCM16) 바이트를 반환.""" raise NotImplementedError def warmup(self) -> None: """선택적: 서버 시작 시 모델 프리로드.""" return None