From 23e1936fbf17b0eee4d74ef74f3853b4dfe5a836 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Sun, 16 Aug 2026 12:51:20 -0400 Subject: [PATCH] =?UTF-8?q?Receiver=20scheduling=20truth:=20every=205=20s?= =?UTF-8?q?=20the=20packet=20store=20reports=20where=20its=20oldest/newest?= =?UTF-8?q?=20chunks=20sit=20relative=20to=20the=20render=20clock=20?= =?UTF-8?q?=E2=80=94=20the=20one=20number=20that=20separates=20'signal=20p?= =?UTF-8?q?resent=20but=20scheduled=20for=20a=20time=20that=20never=20come?= =?UTF-8?q?s'=20from=20actual=20playback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/ACMacAudio/RoomReceiver.swift | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/slab/macos-audio/Sources/ACMacAudio/RoomReceiver.swift b/slab/macos-audio/Sources/ACMacAudio/RoomReceiver.swift index 8b41f4df1c..8042658fb6 100644 --- a/slab/macos-audio/Sources/ACMacAudio/RoomReceiver.swift +++ b/slab/macos-audio/Sources/ACMacAudio/RoomReceiver.swift @@ -17,6 +17,8 @@ private final class ACAudioPacketStore: @unchecked Sendable { private let lock = NSLock() private var session: UInt32? private var chunks: [ACBufferedAudio] = [] + var onDebug: (@Sendable (String) -> Void)? + private var lastDebugNanos: UInt64 = 0 func insert(_ packet: ACRoomAudioPacket) { guard packet.sampleRate == UInt32(ACRoomWire.sampleRate), packet.channels == 2 else { return } @@ -55,6 +57,20 @@ private final class ACAudioPacketStore: @unchecked Sendable { rightOutput.initialize(repeating: 0, count: frameCount) let renderEnd = serverStartNanos + UInt64(Double(frameCount) * 1_000_000_000 / ACRoomWire.sampleRate) lock.lock() + // Scheduling truth every ~5 s: where the newest/oldest buffered + // chunks sit relative to the render clock. "Signal present" with + // silence means this window and those stamps never overlap. + if serverStartNanos &- lastDebugNanos > 5_000_000_000 { + lastDebugNanos = serverStartNanos + if let newest = chunks.last, let oldest = chunks.first { + let newestMs = (Double(newest.presentationNanos) - Double(serverStartNanos)) / 1_000_000 + let oldestMs = (Double(oldest.presentationNanos) - Double(serverStartNanos)) / 1_000_000 + onDebug?(String(format: "window: %d chunks, oldest %+.0f ms, newest %+.0f ms", + chunks.count, oldestMs, newestMs)) + } else { + onDebug?("window: no chunks buffered") + } + } chunks.removeAll { $0.endNanos + 50_000_000 < serverStartNanos } for chunk in chunks { if chunk.presentationNanos >= renderEnd { break } @@ -131,7 +147,10 @@ public final class ACAudioRoomReceiver: @unchecked Sendable { private var didLogSignal = false private var lastTrafficNanos: UInt64 = 0 - public init(configuration: Configuration) { self.configuration = configuration } + public init(configuration: Configuration) { + self.configuration = configuration + store.onDebug = { [weak self] line in self?.log(line) } + } public func start() throws { guard !isRunning else { return } -- 2.51.2