"""
OmniVoice teacher adapter — the ONE place the teacher API lives.

swaps Qwen3-TTS for k2-fsa/OmniVoice in find_voice.py + generate_synthetic_voice.py
without touching their resume/metadata logic. two ops mirror the qwen calls:

  design(text, instruct)        ~ model.generate_voice_design(...)   → audition
  clone(text, ref_wav, ref_txt) ~ model.generate_voice_clone(...)    → dataset

returns (audio: np.ndarray, sr: int). OmniVoice emits 24kHz.

⚠ VERIFY THE API before running: `pip install omnivoice`, then check its README /
`pip show omnivoice`. Method names + kwargs below are written to the model card
description (ref audio + transcription for cloning; speaker attributes for design)
and MUST be confirmed against the installed package. This is deferred until the GPU
is free after the LLM CPT — adjust the two call bodies once the real signature is known.

requires: pip install omnivoice   (after torch)
"""

import functools


@functools.lru_cache(maxsize=1)
def _model():
    import torch
    from omnivoice import OmniVoice          # ⚠ confirm import path
    return OmniVoice.from_pretrained("k2-fsa/OmniVoice", dtype=torch.float16, device="cuda:0")


def design(text: str, instruct: str):
    """voice-design: synth `text` in a voice described by `instruct`. → (audio, 24000)."""
    m = _model()
    audio = m.generate(text=text, language="ru", speaker_description=instruct)  # ⚠ confirm
    return audio, 24000


def clone(text: str, ref_wav: str, ref_txt: str):
    """zero-shot clone: synth `text` in the voice of `ref_wav` (transcript `ref_txt`)."""
    m = _model()
    audio = m.generate(text=text, language="ru",
                       ref_audio=ref_wav, ref_text=ref_txt)                     # ⚠ confirm
    return audio, 24000
