fix(engine): giam jitter bridge timer va fade-out khi transport stall
- RealtimeFxLoop: timeBeginPeriod(1) + sleep_until thay Sleep(1) -> loopMax 32.9->24.8ms - plugins.py _pump_output: stall-fade 8 block gain 1->0 khi gap > 5.5*block_sec (~29ms), burst send, fade-in 0->1 khi resume; poll dung asyncio.to_thread(time.sleep) vi asyncio.sleep bi cap 15.6ms tren Win11 (IOCP) du timeBeginPeriod - fx_realtime.py: stats dem publish/drop/stale/read cho diagnostics - rebuild bridge binary
This commit is contained in:
@@ -128,6 +128,9 @@ class FxRealtimeSession:
|
||||
# Phase 2.8: C++ consume qua SHM control ring.
|
||||
self.pending_params = {} # {slot_idx: {key: value}}
|
||||
self.latencies = {} # {slot_idx: samples}
|
||||
# Diagnostics (FXRT crackle hunt): drop/publish counters.
|
||||
self.stats = {'publish': 0, 'drop_batch': 0, 'drop_blocks': 0,
|
||||
'stale_flush': 0, 'read_blocks': 0, 'read_empty': 0}
|
||||
self._spawn()
|
||||
|
||||
# ── process ─────────────────────────────────────────────────────────────
|
||||
@@ -266,13 +269,16 @@ class FxRealtimeSession:
|
||||
self._in_pending = []
|
||||
self._in_pending_t0 = None
|
||||
avail = h.in_slots - (h.in_write - h.in_read)
|
||||
self.stats['publish'] += len(frames)
|
||||
if avail <= 0:
|
||||
h.in_read += len(frames) # ring full → drop cả batch
|
||||
self.stats['drop_batch'] += len(frames)
|
||||
return
|
||||
n = min(len(frames), avail)
|
||||
drop = len(frames) - n
|
||||
if drop > 0:
|
||||
h.in_read += drop # drop frame cũ nhất
|
||||
self.stats['drop_blocks'] += drop
|
||||
for i in range(n):
|
||||
L, R = frames[i + drop]
|
||||
slot = (h.in_write + i) & (h.in_slots - 1)
|
||||
@@ -287,6 +293,7 @@ class FxRealtimeSession:
|
||||
burst) → không kẹt latency. Gọi từ _pump_output mỗi vòng."""
|
||||
with self._lock:
|
||||
if self._in_pending and self._in_pending_t0 is not None and time.time() - self._in_pending_t0 > timeout:
|
||||
self.stats['stale_flush'] += 1
|
||||
self._flush_input_locked()
|
||||
|
||||
def read_output(self):
|
||||
@@ -303,6 +310,9 @@ class FxRealtimeSession:
|
||||
inter[1::2] = self._np[br:br + self.block_size]
|
||||
out.append(inter.tobytes())
|
||||
h.out_read += 1
|
||||
self.stats['read_blocks'] += len(out)
|
||||
if not out:
|
||||
self.stats['read_empty'] += 1
|
||||
return out
|
||||
|
||||
def heartbeat_age(self):
|
||||
|
||||
Reference in New Issue
Block a user