34 lines
1.3 KiB
Python
34 lines
1.3 KiB
Python
"""Ресемплинг аудио (линейная интерполяция) — 16 кГц mono для STT.
|
||
|
||
Для речи линейной интерполяции достаточно; качество-loss заметно меньше,
|
||
чем выигрыш от простоты и отсутствия зависимостей.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import numpy as np
|
||
|
||
TARGET_RATE = 16000
|
||
|
||
|
||
def resample_to_16k(data: np.ndarray, source_rate: int, target_rate: int = TARGET_RATE) -> np.ndarray:
|
||
"""float32 mono → float32 mono с частотой target_rate."""
|
||
if source_rate == target_rate:
|
||
return np.asarray(data, dtype=np.float32)
|
||
|
||
x = np.asarray(data, dtype=np.float32)
|
||
if x.ndim > 1:
|
||
x = x.mean(axis=1)
|
||
if len(x) == 0:
|
||
return x
|
||
|
||
n_out = int(round(len(x) * target_rate / source_rate))
|
||
if n_out <= 1:
|
||
return np.zeros(max(n_out, 0), dtype=np.float32)
|
||
|
||
# Позиции выходных сэмплов во входной шкале (линейная интерполяция)
|
||
pos = np.linspace(0.0, len(x) - 1.0, num=n_out, dtype=np.float64)
|
||
i0 = pos.astype(np.int64)
|
||
i1 = np.minimum(i0 + 1, len(x) - 1)
|
||
frac = (pos - i0).astype(np.float32)
|
||
out = x[i0] * (1.0 - frac) + x[i1] * frac
|
||
return np.clip(out, -1.0, 1.0) |