Preserve iOS screen audio during stream startup
This commit is contained in:
@@ -46,10 +46,20 @@ internal static class SimulatorSmoke
|
||||
await Task.Delay(300);
|
||||
Require(!model.ScreenRingMapped && !model.ScreenSharing,
|
||||
"An unchanged ring from a previous broadcast remained mapped.");
|
||||
WriteRing(ring, active: true, write: 3840);
|
||||
for (int frame = 0; frame < 6; frame++) WriteScreenPcm(ring);
|
||||
await WaitUntil(() => model.ScreenSharing, "Screen stream did not start.");
|
||||
Require(IosAudioEngine.Shared.IsRunning, "Screen sharing stopped the audio graph.");
|
||||
WriteRing(ring, active: false, write: 3840);
|
||||
await WaitUntil(() => model.ScreenEncodedPackets > 0,
|
||||
"Screen PCM captured before stream negotiation was discarded.");
|
||||
long encodedBefore = model.ScreenEncodedPackets;
|
||||
for (int frame = 0; frame < 12; frame++)
|
||||
{
|
||||
WriteScreenPcm(ring);
|
||||
await Task.Delay(20);
|
||||
}
|
||||
await WaitUntil(() => model.ScreenEncodedPackets > encodedBefore,
|
||||
"Screen PCM did not reach the encoder while the microphone was off.");
|
||||
WriteRing(ring, active: false);
|
||||
await WaitUntil(() => !model.ScreenSharing, "Screen stream did not stop.");
|
||||
Require(!model.ScreenRingMapped, "The stopped screen ring remained mapped.");
|
||||
Console.Error.WriteLine("VC_SIM phase=screenSharePassed");
|
||||
@@ -65,9 +75,9 @@ internal static class SimulatorSmoke
|
||||
"Screen sharing recovery stopped the live audio graph.");
|
||||
if (ring is not null)
|
||||
{
|
||||
WriteRing(ring, active: true, write: 3840);
|
||||
WriteRing(ring, active: true);
|
||||
await Task.Delay(300);
|
||||
WriteRing(ring, active: true, write: 5760);
|
||||
WriteScreenPcm(ring);
|
||||
await WaitUntil(() => model.ScreenSharing, "Screen stream did not start during a voice call.");
|
||||
Require(IosAudioEngine.Shared.IsRunning, "Starting screen sharing stopped the voice graph.");
|
||||
}
|
||||
@@ -75,7 +85,7 @@ internal static class SimulatorSmoke
|
||||
if (ring is not null)
|
||||
{
|
||||
Require(model.ScreenSharing, "Leaving the microphone call unsubscribed active screen audio.");
|
||||
WriteRing(ring, active: false, write: 5760);
|
||||
WriteRing(ring, active: false);
|
||||
await WaitUntil(() => !model.ScreenSharing, "The second screen stream did not stop.");
|
||||
}
|
||||
await model.DisconnectAsync();
|
||||
@@ -123,16 +133,41 @@ internal static class SimulatorSmoke
|
||||
return path;
|
||||
}
|
||||
|
||||
private static void WriteRing(string path, bool active, ulong write)
|
||||
private static void WriteRing(string path, bool active, ulong? write = null)
|
||||
{
|
||||
using var file = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
|
||||
byte[] value = new byte[8];
|
||||
BinaryPrimitives.WriteUInt64LittleEndian(value, write);
|
||||
file.Position = 24; file.Write(value);
|
||||
if (write is { } position)
|
||||
{
|
||||
BinaryPrimitives.WriteUInt64LittleEndian(value, position);
|
||||
file.Position = 24; file.Write(value);
|
||||
}
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(value, active ? 1u : 0u);
|
||||
file.Position = 16; file.Write(value, 0, 4);
|
||||
}
|
||||
|
||||
private static void WriteScreenPcm(string path)
|
||||
{
|
||||
using var file = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
|
||||
Span<byte> index = stackalloc byte[8];
|
||||
file.Position = 24; file.ReadExactly(index);
|
||||
ulong write = BinaryPrimitives.ReadUInt64LittleEndian(index);
|
||||
byte[] pcm = new byte[960 * 2 * sizeof(short)];
|
||||
for (int sample = 0; sample < pcm.Length / sizeof(short); sample++)
|
||||
BinaryPrimitives.WriteInt16LittleEndian(pcm.AsSpan(sample * sizeof(short)),
|
||||
(short)(sample % 64 < 32 ? 6000 : -6000));
|
||||
int start = (int)(write % 96_000), first = Math.Min(pcm.Length / sizeof(short), 96_000 - start);
|
||||
file.Position = 64 + start * sizeof(short);
|
||||
file.Write(pcm.AsSpan(0, first * sizeof(short)));
|
||||
if (first < pcm.Length / sizeof(short))
|
||||
{
|
||||
file.Position = 64;
|
||||
file.Write(pcm.AsSpan(first * sizeof(short)));
|
||||
}
|
||||
BinaryPrimitives.WriteUInt64LittleEndian(index, write + (ulong)(pcm.Length / sizeof(short)));
|
||||
file.Position = 24; file.Write(index);
|
||||
}
|
||||
|
||||
private static async Task WaitUntil(Func<bool> condition, string error)
|
||||
{
|
||||
for (int attempt = 0; attempt < 30; attempt++)
|
||||
|
||||
Reference in New Issue
Block a user