Coordinate matching audio source delivery in regression test
PR and Push Build/Test / windows-build-and-test (push) Canceled after 0s
PR and Push Build/Test / portable-build-and-test (push) Canceled after 0s
PR and Push Build/Test / macos-native-full (push) Canceled after 0s

This commit is contained in:
codex committed 2026-10-07 15:08:38 +02:00
1 parent 3c0147960c
commit 7095a0d008
2 files changed
+42 -5

No files matched your search

+36 -5
View File
@@ -58,14 +58,21 @@ public sealed class AudioMixingTests
[Fact]
public async Task CompositeAudioSourceWaitsForMatchingStreamsBeforeMixing()
{
var microphone = new DelayedAudioSource(TimeSpan.Zero, Pcm16(2_000));
var system = new DelayedAudioSource(TimeSpan.FromMilliseconds(100), Pcm16(10_000));
var microphone = new ControlledAudioSource(Pcm16(2_000));
var system = new ControlledAudioSource(Pcm16(10_000));
var source = CreateSource(microphone, system);
using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await using var chunks = source.CaptureAsync(cancellation.Token).GetAsyncEnumerator(cancellation.Token);
var nextChunk = chunks.MoveNextAsync().AsTask();
var chunks = await ReadChunks(source);
microphone.Release();
await microphone.WaitUntilDeliveredAsync();
Assert.False(nextChunk.IsCompleted);
var chunk = Assert.Single(chunks);
Assert.Equal(12_000, BitConverter.ToInt16(chunk.Pcm));
system.Release();
Assert.True(await nextChunk);
Assert.Equal(12_000, BitConverter.ToInt16(chunks.Current.Pcm));
Assert.False(await chunks.MoveNextAsync());
}
[Fact]
@@ -187,6 +194,30 @@ public sealed class AudioMixingTests
}
}
private sealed class ControlledAudioSource : IMeetingAudioSource
{
private readonly AudioChunk chunk;
private readonly TaskCompletionSource release = new(TaskCreationOptions.RunContinuationsAsynchronously);
private readonly TaskCompletionSource delivered = new(TaskCreationOptions.RunContinuationsAsynchronously);
public ControlledAudioSource(byte[] pcm)
{
chunk = new AudioChunk(pcm, 16000, 1);
}
public void Release() => release.TrySetResult();
public Task WaitUntilDeliveredAsync() => delivered.Task.WaitAsync(TimeSpan.FromSeconds(5));
public async IAsyncEnumerable<AudioChunk> CaptureAsync(
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken)
{
await release.Task.WaitAsync(cancellationToken);
yield return chunk;
delivered.TrySetResult();
}
}
private sealed class DelayedAudioSource : IMeetingAudioSource
{
private readonly TimeSpan delay;