Gap 8: PDC realtime — WS latency push + dry-path delay compensation

Backend: /ws/fx-realtime pump drain get_latencies (SHM ring, bridge da bao REPORT_LATENCY) -> push {cmd:'latency',total,latencies} khi tong doi. Frontend: pdcDelay (DelayNode) giua dryOutput->output bu delay master chain (round-trip 2 block + latency VST3), fxRtApplyPdc cap nhat tu WS frame, reset khi chain off. Test test_63 fake session 1024 -> frame total 1024; full 175 passed.
This commit is contained in:
2026-08-23 08:44:54 +07:00
parent db12698ba2
commit 6b2c9a039b
5 changed files with 110 additions and 8 deletions
+39
View File
@@ -702,3 +702,42 @@ def test_62_multiband_deesser(fx_bridge):
out = render(de, 500.0, 0.5)
g = peak_db(out)
assert -6.5 <= g <= -5.5, f"deesser 500Hz changed: {g:.2f}dBFS (expect ~-6.02)"
# ── 5.63 Gap 8: PDC realtime — WS latency push ───────────────────────────
def test_63_fxrt_ws_latency_push(monkeypatch):
"""Gap 8: WS /ws/fx-realtime/{id} day text frame {cmd:'latency', total,
latencies} khi chain bao latency (SHM ring drain trong output pump) —
client bu delay dry-bypass path. Fake session bao {0:1024,1:0} → total 1024."""
from fastapi.testclient import TestClient
from app.core import fx_realtime
from app.main import app as main_app
class _FakeSess:
block_size = 256
sample_rate = 44100
def alive(self):
return True
def read_output(self):
return []
def get_latencies(self):
return {0: 1024, 1: 0}
def set_param(self, *a):
pass
def report_latency(self, *a):
pass
def write_input(self, b):
pass
monkeypatch.setattr(fx_realtime, "get_session", lambda sid: _FakeSess())
client = TestClient(main_app)
with client.websocket_connect("/api/v1/plugins/ws/fx-realtime/fake") as ws:
d = ws.receive_json()
assert d.get("cmd") == "latency", d
assert d.get("total") == 1024, d
assert d.get("latencies", {}).get("0") == 1024, d