small-talk / backend /audio.py
GauravGosain's picture
Deploy Small Talk: Reachy Mini AI podcast (gradio.Server + three.js + LiveKit)
d2794cb verified
Raw
History Blame Contribute Delete
1.01 kB
"""Audio decoding helpers.
We shell out to ffmpeg so we can ingest *anything* (wav, mp3, flac, ogg, m4a)
and always get back mono 16-bit PCM at LiveKit's preferred 48 kHz — no
per-format branching, no resampling surprises.
"""
import asyncio
import numpy as np
SAMPLE_RATE = 48000
NUM_CHANNELS = 1
async def decode_to_pcm(path: str, sample_rate: int = SAMPLE_RATE) -> np.ndarray:
"""Decode `path` to a 1-D int16 numpy array (mono, `sample_rate` Hz)."""
proc = await asyncio.create_subprocess_exec(
"ffmpeg",
"-v", "error",
"-i", str(path),
"-f", "s16le",
"-acodec", "pcm_s16le",
"-ac", str(NUM_CHANNELS),
"-ar", str(sample_rate),
"-",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
out, err = await proc.communicate()
if proc.returncode != 0:
raise RuntimeError(f"ffmpeg failed decoding {path}: {err.decode(errors='ignore')}")
return np.frombuffer(out, dtype=np.int16).copy()