Try to fix background glitching over long periods of time
This commit is contained in:
@@ -446,6 +446,22 @@ public class AudioEngineTests
|
||||
Assert.Contains("public void Resynchronize()", buffer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResynchronizeInputsDropsStalledBacklogToTheBufferTarget()
|
||||
{
|
||||
using var send = new AudioEngine((_, _, _, _) => true, false);
|
||||
send.DeviceBufferMilliseconds = 40; send.AddLocalStream(Stream());
|
||||
short[] mono = Tone();
|
||||
for (int i = 0; i < 40; i++) send.FeedPcm(1, mono, 1);
|
||||
Assert.True(send.GetLocalDiagnostics(1).BufferedFrames > 1920 * 2);
|
||||
|
||||
send.ResynchronizeInputs();
|
||||
|
||||
Assert.Equal(1920, send.GetLocalDiagnostics(1).BufferedFrames);
|
||||
send.ProcessCycle();
|
||||
Assert.Equal(0, send.GetLocalDiagnostics(1).StarvedCycles);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RemotePlaybackSettingsAreIndependentForEachUserStream()
|
||||
{
|
||||
|
||||
@@ -164,6 +164,38 @@ public class PublishServerScriptTests
|
||||
Assert.Contains("deviceClockedAudio: true", model);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IosRecoversBackgroundAudioWithoutForegrounding()
|
||||
{
|
||||
string root = FindRoot();
|
||||
string microphone = await File.ReadAllTextAsync(Path.Combine(
|
||||
root, "clients", "apple", "VoiceCat.iOS", "IosAudioEngine.cs"));
|
||||
string router = await File.ReadAllTextAsync(Path.Combine(
|
||||
root, "clients", "apple", "VoiceCat.iOS", "IosAudioRouter.cs"));
|
||||
|
||||
// The render callback is the only clock for the device-clocked pipeline, so a graph that
|
||||
// stops while backgrounded froze capture, mix and send until the app was foregrounded.
|
||||
Assert.Contains("internal long RenderCallbacks", microphone);
|
||||
Assert.Contains("internal bool IsRunning", microphone);
|
||||
Assert.Contains("private void TickWatchdog()", router);
|
||||
Assert.Contains("IosAudioEngine.Shared.RenderCallbacks", router);
|
||||
Assert.Contains("IosAudioEngine.Shared.IsRunning", router);
|
||||
Assert.Contains("IosAudioEngine.Shared.Reconfigure()", router);
|
||||
|
||||
// SetActive fails for as long as an interruption is in force, so Began suppresses
|
||||
// recovery and the watchdog retries the rebuild that Ended asks for.
|
||||
Assert.Contains("AVAudioSessionInterruptionType.Began", router);
|
||||
Assert.Contains("interrupted = true", router);
|
||||
Assert.Contains("internal void ResumeForeground()", router);
|
||||
|
||||
// A stalled render callback resynchronizes its own rings, and a refill is bounded so it
|
||||
// cannot overrun the callback deadline that it is recovering from.
|
||||
Assert.Contains("owner.Audio.ResynchronizeInputs()", microphone);
|
||||
Assert.Contains("playbackRing.Resynchronize()", microphone);
|
||||
Assert.Contains("Ring.Resynchronize()", microphone);
|
||||
Assert.Contains("Math.Min(frames + playbackRing.TargetFrames - playbackRing.CountFrames, frames + 960)", microphone);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IosAudioCommitsInputRouteBeforeChannelsAndVoiceProcessingBeforeConnections()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user