Source code for mllm_shap.alignment.io

"""Encoded audio bytes to mono float waveforms and back.

@domain alignment
@see [[knowledge/architecture/alignment]]
@tested-by [[tests/alignment/test_io.py]]
"""

import importlib
import io
from types import ModuleType

import numpy as np
from numpy.typing import NDArray


[docs] def require(module: str) -> ModuleType: """Import an optional dependency of the ``audio`` or ``transformers`` extra. Raises: ImportError: Naming the extra to install. """ try: return importlib.import_module(module) except ImportError as exc: extra = "transformers" if module in {"torch", "transformers"} else "audio" msg = ( f"{module} is required for mllm_shap.alignment; install mllm-shap[{extra}]" ) raise ImportError(msg) from exc
[docs] def decode_audio( data: bytes, sample_rate: int | None = None ) -> tuple[NDArray[np.float32], int]: """Decode ``data`` to a mono float32 waveform, resampled to ``sample_rate``. Channels are averaged. Without ``sample_rate`` the file's own rate is kept. Raises: ValueError: If ``data`` is not a format ``soundfile`` can read. """ soundfile = require("soundfile") try: frames, rate = soundfile.read(io.BytesIO(data), dtype="float32", always_2d=True) except (RuntimeError, soundfile.LibsndfileError) as exc: msg = "could not decode the audio bytes" raise ValueError(msg) from exc waveform = frames.mean(axis=1).astype(np.float32) if sample_rate is not None and sample_rate != rate: waveform = require("librosa").resample( waveform, orig_sr=rate, target_sr=sample_rate ) rate = sample_rate return waveform.astype(np.float32), int(rate)
[docs] def encode_wav(waveform: NDArray[np.floating], sample_rate: int) -> bytes: """Encode a mono waveform as 16-bit PCM WAV; NaN becomes 0, values clip to ±1.""" soundfile = require("soundfile") samples = np.clip(np.nan_to_num(np.asarray(waveform, dtype=np.float32)), -1, 1) buffer = io.BytesIO() soundfile.write(buffer, samples, sample_rate, format="WAV", subtype="PCM_16") return buffer.getvalue()