Fix iOS background audio pacing
Build and test / test (macos-latest) (push) Waiting to run
Build and test / test (ubuntu-24.04) (push) Waiting to run
Build and test / test (windows-latest) (push) Waiting to run
Build and test / apple-client (push) Waiting to run

Sleep-paced threads stall for hundreds of milliseconds when iOS coalesces a
backgrounded app's wakeups, and the deadline resets that discarded the deficit
left the capture backlog queued until its ring overflowed: regular dropouts
that worsen the longer the app stays backgrounded. Pace both 20 ms hands-offs
from the AVAudioSourceNode render callback instead (mix via Audio.RunCycle
with deviceClockedAudio, capture handoff from the ring), wake the UDP sender
on a queue signal instead of a 1 ms poll, and let stalled consumers drop their
backlog to the buffer target instead of ratcheting it.
This commit is contained in:
2026-09-23 21:37:24 +02:00
parent 1487f2673b
commit f348574bc1
9 changed files with 273 additions and 42 deletions
+4 -1
View File
@@ -99,7 +99,10 @@ internal sealed class AppModel
explicitDisconnect = false; IsConnecting = true; connectedProfile = profile;
Status = restoring ? "Reconnecting…" : "Connecting…"; Notify();
lifetime?.Cancel(); lifetime?.Dispose(); lifetime = new();
VoiceCatClient next = new("VoiceCat-iOS", "0.0.1", storage.TofuPath);
// The AVAudioSourceNode render callback drives Audio.RunCycle and the 20 ms capture
// handoff; a sleep-paced audio worker stalls when iOS coalesces backgrounded wakeups and
// the call glitches after several minutes in the background.
VoiceCatClient next = new("VoiceCat-iOS", "0.0.1", storage.TofuPath, deviceClockedAudio: true);
next.ConnectionStateChanged += state =>
{
if (state == ClientConnectionState.Disconnected && next.ConnectionFailure is { } failure)