"""音频加载与重采样工具：统一到 16k/mono，供 gummy(pcm16) 与本地引擎(float) 使用。"""

from __future__ import annotations

import numpy as np
import soundfile as sf

TARGET_SR = 16000


def _resample(data: np.ndarray, sr: int, target_sr: int) -> np.ndarray:
    if sr == target_sr:
        return data
    import soxr

    return soxr.resample(data, sr, target_sr)


def load_pcm16(path: str, target_sr: int = TARGET_SR) -> tuple[np.ndarray, int]:
    """读为 int16 单声道 PCM（gummy 推流用）。"""
    data, sr = sf.read(path, dtype="float32", always_2d=False)
    if data.ndim > 1:
        data = data.mean(axis=1)
    data = _resample(data, sr, target_sr)
    # float32(-1,1) -> int16
    pcm = np.clip(data, -1.0, 1.0)
    pcm = (pcm * 32767.0).astype(np.int16)
    return pcm, target_sr


def load_float(path: str, target_sr: int = TARGET_SR) -> tuple[np.ndarray, int]:
    """读为 float32 单声道（本地引擎用）。"""
    data, sr = sf.read(path, dtype="float32", always_2d=False)
    if data.ndim > 1:
        data = data.mean(axis=1)
    data = _resample(data, sr, target_sr)
    return data.astype(np.float32), target_sr


def duration_sec(path: str) -> float:
    info = sf.info(path)
    return info.frames / info.samplerate
