From 2bbee419f2ff8e20eda5bf044333bf6980ab8e87 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Sun, 20 Sep 2026 11:28:35 -0700 Subject: [PATCH] Calibrate native output clock from advancing silent pre-roll callbacks --- roadscore/prototype/stream_clock_bridge.py | 29 +++++++++++++++++++ .../prototype/test_stream_clock_bridge.py | 13 +++++++++ 2 files changed, 42 insertions(+) diff --git a/roadscore/prototype/stream_clock_bridge.py b/roadscore/prototype/stream_clock_bridge.py index f29c1b83e8..19af31c7a6 100644 --- a/roadscore/prototype/stream_clock_bridge.py +++ b/roadscore/prototype/stream_clock_bridge.py @@ -7,6 +7,34 @@ class StreamClockBridge: def __init__(self, offset, uncertainty): self.offset = offset self.uncertainty = uncertainty + self.source = 'bracketed-stream-time' + self.offset_spread = None + + @classmethod + def from_callbacks(cls, observations): + """Freeze one offset from silent pre-roll, before any route is released. + + Some ALSA streams report zero from stream.time until their first callback, + then return the latest callback timestamp. Callback entry is later than its + timestamp: the minimum offset minimizes that nonnegative scheduling bias. + It does not measure Bluetooth acoustic latency. + """ + if len(observations)<8:raise ValueError('Output clock needs more silent callbacks') + offsets=[];previous=None + for wall,current,dac in observations: + if (not all(type(value) in (int,float) and math.isfinite(value) for value in (wall,current,dac)) + or current<=0 or dac<=0 or not -.02<=dac-current<=5): + raise ValueError('Invalid callback clock sample') + if previous is not None and (wall