Files
livekit-cameras/tests/test_audio_cleanup.py
T
root 950128deec feat: DelaySum beamform plus hop process latency
Keep C920 stereo through SpeechBrain GCC-PHAT Delay-and-Sum, then
MetricGAN, and publish mono to LiveKit. Record last_dt_ms and log
process_ms/capture_ms every 50 hops for the latency plan.
2026-08-28 06:16:25 +00:00

81 lines
2.2 KiB
Python

import inspect
import numpy as np
import pytest
from audio_cleanup import AudioCleaner
def test_enhance_batch_without_lengths_typeerror():
c = AudioCleaner(mode="force")
assert "model" in c.backend
import torch
w = torch.zeros(1, 8000)
with pytest.raises(TypeError):
c._enhancer.enhance_batch(w)
def test_process_uses_relative_lengths_one():
src = inspect.getsource(AudioCleaner._process_inner)
assert "tensor([1.0])" in src
def test_process_preserves_length_and_int16():
c = AudioCleaner(mode="force")
n = 16000
pcm = (np.sin(2 * np.pi * 440 * np.arange(n) / 16000) * 8000).astype(np.int16)
out = c.process(pcm)
assert out.dtype == np.int16
assert out.shape == pcm.shape
def test_overlap_process_emits_hop_length():
c = AudioCleaner(mode="force", chunk_s=1.0, hop_s=0.2)
hop = 3200
pcm = (np.random.randn(hop) * 500).astype(np.int16)
out = c.process(pcm)
assert out.shape == (hop,)
def test_overlap_runs_model_after_enough_context():
c = AudioCleaner(mode="force", chunk_s=0.5, hop_s=0.25)
hop = 4000
for _ in range(4):
pcm = (np.sin(2 * np.pi * 440 * np.arange(hop) / 16000) * 8000).astype(
np.int16
)
out = c.process(pcm)
assert out.shape == (hop,)
assert out.dtype == np.int16
def test_beamform_loads_delaysum_module():
c = AudioCleaner(mode="off", beamform="force")
assert c._beamformer is not None
assert type(c._beamformer).__name__ == "DelaySum_Beamformer"
assert "beamform" in c.backend
def test_process_records_last_dt_ms():
c = AudioCleaner(mode="off", beamform="off")
hop = 3200
pcm = (np.random.randn(hop) * 500).astype(np.int16)
c.process(pcm)
assert c.last_dt_ms >= 0.0
def test_stereo_beamform_then_model_preserves_hop():
c = AudioCleaner(
mode="force", beamform="force", chunk_s=0.5, hop_s=0.25)
assert c.backend == "model+beamform"
hop = 4000
t = np.arange(hop)
ch0 = (np.sin(2 * np.pi * 440 * t / 16000) * 8000).astype(np.int16)
ch1 = np.roll(ch0, 3)
stereo = np.stack([ch0, ch1], axis=1)
for _ in range(4):
out = c.process(stereo)
assert out.dtype == np.int16
assert out.shape == (hop,)