Publish and subscribe over wss://livekit.uni-wh.de:7800 and refuse cleartext ws://. Conference room is uwh-telhai. Includes the uncommitted encoded H.264 publish path, Rally hairpin, and KMS wall overlay.
136 lines
3.8 KiB
Python
136 lines
3.8 KiB
Python
import os
|
|
import threading
|
|
import time
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
|
|
def test_frame_roundtrip_stereo_hop():
|
|
from enhance_ipc import dump_frame, load_frame
|
|
|
|
hop = 1600
|
|
t = np.arange(hop, dtype=np.int16)
|
|
pcm = np.stack([t, t + 1], axis=1)
|
|
blob = dump_frame("cam-07", pcm)
|
|
ident, out = load_frame(blob)
|
|
assert ident == "cam-07"
|
|
assert out.dtype == np.int16
|
|
assert out.shape == (hop, 2)
|
|
np.testing.assert_array_equal(out, pcm)
|
|
|
|
|
|
def test_unix_client_gets_handler_output(tmp_path):
|
|
from enhance_daemon import serve_unix
|
|
from enhance_ipc import EnhanceClient
|
|
|
|
sock = str(tmp_path / "enhance.sock")
|
|
stop = threading.Event()
|
|
|
|
def handler(ident, pcm):
|
|
assert ident == "cam-03"
|
|
# fake "enhance": average channels, invert
|
|
if pcm.ndim == 2:
|
|
mono = pcm.mean(axis=1)
|
|
else:
|
|
mono = pcm
|
|
return (-mono).astype(np.int16)
|
|
|
|
t = threading.Thread(target=serve_unix, args=(sock, handler, stop), daemon=True)
|
|
t.start()
|
|
deadline = time.time() + 2
|
|
while time.time() < deadline and not (tmp_path / "enhance.sock").exists():
|
|
time.sleep(0.01)
|
|
hop = 800
|
|
pcm = np.stack([np.full(hop, 1000, np.int16), np.full(hop, 3000, np.int16)], axis=1)
|
|
client = EnhanceClient(sock)
|
|
try:
|
|
out = client.process("cam-03", pcm)
|
|
finally:
|
|
client.close()
|
|
stop.set()
|
|
assert out.dtype == np.int16
|
|
assert out.shape == (hop,)
|
|
assert int(out[0]) == -2000
|
|
|
|
|
|
def _start_echo_daemon(sock, stop):
|
|
from enhance_daemon import serve_unix
|
|
|
|
def handler(ident, pcm):
|
|
if pcm.ndim == 2:
|
|
mono = pcm.mean(axis=1)
|
|
else:
|
|
mono = pcm
|
|
return np.asarray(mono, dtype=np.int16)
|
|
|
|
t = threading.Thread(target=serve_unix, args=(sock, handler, stop), daemon=True)
|
|
t.start()
|
|
deadline = time.time() + 2
|
|
while time.time() < deadline and not os.path.exists(sock):
|
|
time.sleep(0.01)
|
|
return t
|
|
|
|
|
|
def test_audio_cleaner_remote_does_not_load_model(tmp_path):
|
|
from audio_cleanup import AudioCleaner
|
|
|
|
sock = str(tmp_path / "enhance.sock")
|
|
stop = threading.Event()
|
|
_start_echo_daemon(sock, stop)
|
|
try:
|
|
c = AudioCleaner(
|
|
mode="force", beamform="force", enhance_socket=sock,
|
|
identity="cam-09")
|
|
assert c._enhancer is None
|
|
assert c._beamformer is None
|
|
assert c.backend == "daemon"
|
|
hop = 1600
|
|
stereo = np.stack([
|
|
np.full(hop, 400, np.int16),
|
|
np.full(hop, 800, np.int16),
|
|
], axis=1)
|
|
out = c.process(stereo)
|
|
assert out.shape == (hop,)
|
|
assert out.dtype == np.int16
|
|
assert int(out[0]) == 600
|
|
finally:
|
|
stop.set()
|
|
|
|
|
|
def test_shared_engine_constructs_one_cleaner_for_two_cams():
|
|
from audio_cleanup import AudioCleaner
|
|
from enhance_daemon import SharedEnhanceEngine
|
|
|
|
n = {"c": 0}
|
|
|
|
def make():
|
|
n["c"] += 1
|
|
return AudioCleaner(mode="off", beamform="off")
|
|
|
|
eng = SharedEnhanceEngine(make_cleaner=make)
|
|
hop = np.zeros(800, dtype=np.int16)
|
|
out_a = eng.process("cam-01", hop)
|
|
out_b = eng.process("cam-02", hop)
|
|
out_a2 = eng.process("cam-01", hop)
|
|
assert n["c"] == 1
|
|
assert set(eng.identities()) == {"cam-01", "cam-02"}
|
|
assert out_a.shape == (800,)
|
|
assert out_b.shape == (800,)
|
|
assert out_a2.shape == (800,)
|
|
|
|
|
|
def test_wait_for_socket_false_then_true(tmp_path):
|
|
from enhance_daemon import wait_for_socket, serve_unix
|
|
|
|
sock = str(tmp_path / "missing.sock")
|
|
assert wait_for_socket(sock, timeout=0.15) is False
|
|
stop = threading.Event()
|
|
t = threading.Thread(
|
|
target=serve_unix, args=(sock, lambda i, p: p, stop), daemon=True)
|
|
t.start()
|
|
try:
|
|
assert wait_for_socket(sock, timeout=2.0) is True
|
|
finally:
|
|
stop.set()
|