first commit
This commit is contained in:
commit
efa5080897
127 changed files with 18610 additions and 0 deletions
40
backend/app/voice/audio_utils.py
Normal file
40
backend/app/voice/audio_utils.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"""PCM helpers for Bonvoice media (from test_bonvoice/audio_utils.py)."""
|
||||
|
||||
import audioop
|
||||
import wave
|
||||
from pathlib import Path
|
||||
|
||||
TARGET_RATE = 8000
|
||||
CHUNK_SIZE = 320
|
||||
|
||||
|
||||
def wav_to_pcm8000_mono(path: str | Path) -> bytes:
|
||||
path = Path(path)
|
||||
with wave.open(str(path), "rb") as wf:
|
||||
channels = wf.getnchannels()
|
||||
sample_width = wf.getsampwidth()
|
||||
frame_rate = wf.getframerate()
|
||||
pcm = wf.readframes(wf.getnframes())
|
||||
|
||||
if sample_width != 2:
|
||||
raise ValueError(f"Expected 16-bit audio, got {sample_width * 8}-bit")
|
||||
|
||||
if channels == 2:
|
||||
pcm = audioop.tomono(pcm, 2, 0.5, 0.5)
|
||||
elif channels != 1:
|
||||
raise ValueError(f"Unsupported channel count: {channels}")
|
||||
|
||||
if frame_rate != TARGET_RATE:
|
||||
pcm, _ = audioop.ratecv(pcm, 2, 1, frame_rate, TARGET_RATE, None)
|
||||
|
||||
return pcm
|
||||
|
||||
|
||||
def chunk_pcm(pcm: bytes, chunk_size: int = CHUNK_SIZE) -> list[bytes]:
|
||||
chunks: list[bytes] = []
|
||||
for i in range(0, len(pcm), chunk_size):
|
||||
chunk = pcm[i : i + chunk_size]
|
||||
if len(chunk) < chunk_size:
|
||||
chunk = chunk + b"\x00" * (chunk_size - len(chunk))
|
||||
chunks.append(chunk)
|
||||
return chunks
|
||||
Loading…
Add table
Add a link
Reference in a new issue