Fix stereo capture paths

This commit is contained in:
2026-09-21 02:11:33 +02:00
parent 08e6c5930a
commit 9be33f357d
6 changed files with 100 additions and 27 deletions
@@ -55,4 +55,42 @@ public class WindowsManagedClientTests
Assert.Equal(VcResult.Ok, alice.StopStream(a.StreamId));
Assert.Empty(alice.ManagedClient.LocalStreams);
}
[Fact]
public async Task WindowsScreenAudioPreservesDistinctStereoChannels()
{
await using var fixture = new ServerFixture();
using (var accounts = new AccountStore(Path.Combine(fixture.Directory, "voicecat.db"))) await accounts.CreateAccountAsync("Admin", "secret", true);
using var alice = new Client("Alice", "test", tofuStorePath: Path.Combine(fixture.Directory, "alice-screen.pins"));
using var bob = new Client("Bob", "test", tofuStorePath: Path.Combine(fixture.Directory, "bob-screen.pins"));
await Login(alice, fixture, true); await Login(bob, fixture);
await alice.ManagedClient.RequestAsync(new() { CreateChannel = new() { Channel = new() { Name = "Stereo screen", ParentId = 1, Audio = AudioEngineTests.Stream(20, true).Audio } } });
await Until(alice, () => alice.ListChannels().Any(c => c.Name == "Stereo screen"));
uint channel = alice.ListChannels().Single(c => c.Name == "Stereo screen").Id;
Assert.Equal(VcResult.Ok, alice.JoinChannel(channel)); Assert.Equal(VcResult.Ok, bob.JoinChannel(channel));
await Until(alice, () => alice.ListUsers().Count(u => u.ChannelId == channel) == 2);
Assert.Equal(VcResult.Ok, alice.JoinVoice()); Assert.Equal(VcResult.Ok, bob.JoinVoice());
var screen = alice.StartStreamExternalFeed(VcStreamKind.ScreenAudio, "Screen audio");
Assert.Equal(VcResult.Ok, screen.Result);
await Until(bob, () => bob.ManagedClient.Users.Any(u => u.Id != bob.ManagedClient.Authentication!.Self.Id && u.Streams.Any(s => s.Kind == StreamKind.StreamScreenAudio)));
long separation = 0; int receivedChannels = 0;
bob.ManagedClient.Audio.StreamPcm += (_, _, pcm, channels) =>
{
receivedChannels = channels;
if (channels == 2) for (int i = 0; i < pcm.Length; i += 2) Interlocked.Add(ref separation, Math.Abs((int)pcm[i] - pcm[i + 1]));
};
short[] stereo = new short[1920];
for (int i = 0; i < 960; i++)
{
stereo[2 * i] = (short)(8000 * Math.Sin(i * Math.PI * 880 / 48000));
stereo[2 * i + 1] = (short)(8000 * Math.Sin(i * Math.PI * 1320 / 48000));
}
for (int i = 0; i < 40; i++)
{
Assert.Equal(VcResult.Ok, alice.StreamFeedPcm(screen.StreamId, stereo, 960, 2));
alice.PumpEvents(); bob.PumpEvents(); await Task.Delay(20);
}
Assert.Equal(2, receivedChannels);
Assert.True(Interlocked.Read(ref separation) > 100_000);
}
}