46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
|
|
"""PCM 归一化与 WAV 封装。"""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import array
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from app.services.audio_wav import (
|
||
|
|
WavDecodeError,
|
||
|
|
normalize_pcm_s16le_for_baidu,
|
||
|
|
pcm_s16le_to_wav_bytes,
|
||
|
|
wav_bytes_to_pcm16k_mono_s16le,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_normalize_boosts_quiet_pcm() -> None:
|
||
|
|
samples = array.array("h", [50, -80, 30] * 500)
|
||
|
|
pcm = samples.tobytes()
|
||
|
|
out = normalize_pcm_s16le_for_baidu(pcm)
|
||
|
|
arr = array.array("h")
|
||
|
|
arr.frombytes(out)
|
||
|
|
assert max(abs(x) for x in arr) > max(abs(x) for x in samples)
|
||
|
|
|
||
|
|
|
||
|
|
def test_normalize_skips_loud_pcm() -> None:
|
||
|
|
samples = array.array("h", [15000, -14000])
|
||
|
|
pcm = samples.tobytes()
|
||
|
|
out = normalize_pcm_s16le_for_baidu(pcm)
|
||
|
|
assert out == pcm
|
||
|
|
|
||
|
|
|
||
|
|
def test_pcm_wav_roundtrip_is_valid_wav() -> None:
|
||
|
|
pcm = array.array("h", [100, -200, 300] * 100).tobytes()
|
||
|
|
wav = pcm_s16le_to_wav_bytes(pcm)
|
||
|
|
back = wav_bytes_to_pcm16k_mono_s16le(wav)
|
||
|
|
assert len(back) == len(pcm)
|
||
|
|
assert max(abs(x) for x in array.array("h", back)) >= max(
|
||
|
|
abs(x) for x in array.array("h", pcm)
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_pcm_s16le_to_wav_empty_raises() -> None:
|
||
|
|
with pytest.raises(WavDecodeError):
|
||
|
|
pcm_s16le_to_wav_bytes(b"")
|