"""Optional local Whisper transcription of reference audio.""" import logging from typing import Optional logger = logging.getLogger(__name__) def transcribe_reference_audio(audio_path: str, model_name: str = "base") -> Optional[str]: """Transcribe reference audio locally using an optional Whisper backend. The current qwen-tts demo does not expose a transcription endpoint, so transcription is done client-side when a Whisper package is available. Returns None if no backend is installed. """ for backend in ("faster_whisper", "whisper"): try: if backend == "faster_whisper": from faster_whisper import WhisperModel model = WhisperModel(model_name, device="cpu", compute_type="int8") segments, _ = model.transcribe(audio_path) text = " ".join(seg.text.strip() for seg in segments).strip() else: import whisper model = whisper.load_model(model_name) result = model.transcribe(audio_path) text = (result.get("text") or "").strip() if text: logger.info("Transcription complete via %s: %s", backend, text) return text except ImportError: continue except Exception as exc: logger.warning("%s transcription failed: %s", backend, exc) logger.warning("No Whisper backend available; transcription skipped.") return None def whisper_backend_available() -> Optional[str]: """Return the name of an importable Whisper backend, or None. Checks faster_whisper first (preferred), then the openai-whisper package, without importing the heavy model code: a bare import probe is enough to tell whether the package is installed in the current environment. Used by the make_audiocpp_server_json tool to warn when neither is present (e.g. the wrong conda environment is active). """ for backend in ("faster_whisper", "whisper"): try: __import__(backend) except ImportError: continue return backend return None