using MeetingAssistant.Recording; using MeetingAssistant.Transcription; namespace MeetingAssistant.Tests; public sealed class AsrDiagnosticTests { [Fact] public async Task DiagnosticStreamsPcmWavThroughConfiguredProvider() { var provider = new CapturingTranscriptionProvider(); var diagnostics = new AsrDiagnosticService( new TestSpeechRecognitionPipelineFactory(provider)); var wavPath = Path.Combine(AppContext.BaseDirectory, "Fixtures", "sample-16khz-mono.wav"); var result = await diagnostics.TranscribeWavAsync(wavPath, CancellationToken.None); Assert.Equal(wavPath, result.Path); Assert.Equal(16000, provider.Chunks.Single().SampleRate); Assert.Equal(1, provider.Chunks.Single().Channels); Assert.NotEmpty(provider.Chunks.Single().Pcm); var segment = Assert.Single(result.Segments); Assert.Equal("Unknown", segment.Speaker); Assert.Equal("bytes:" + provider.Chunks.Single().Pcm.Length, segment.Text); } private sealed class CapturingTranscriptionProvider : IStreamingTranscriptionProvider { public List Chunks { get; } = []; public async IAsyncEnumerable TranscribeAsync( IAsyncEnumerable audio, SpeechRecognitionPipelineOptions options, [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken) { await foreach (var chunk in audio.WithCancellation(cancellationToken)) { Chunks.Add(chunk); } yield return new TranscriptionSegment( TimeSpan.Zero, TimeSpan.Zero, "Unknown", "bytes:" + Chunks.Sum(chunk => chunk.Pcm.Length)); } } private sealed class TestSpeechRecognitionPipelineFactory : ISpeechRecognitionPipelineFactory { private readonly IStreamingTranscriptionProvider provider; public TestSpeechRecognitionPipelineFactory(IStreamingTranscriptionProvider provider) { this.provider = provider; } public ISpeechRecognitionPipeline Create() { return new TestSpeechRecognitionPipeline(provider); } } private sealed class TestSpeechRecognitionPipeline : StreamingSpeechRecognitionPipeline { public TestSpeechRecognitionPipeline(IStreamingTranscriptionProvider provider) : base(provider) { } protected override Task> BuildFinishedTranscriptAsync( string audioPath, IReadOnlyList liveSegments, SpeechRecognitionPipelineOptions options, CancellationToken cancellationToken) { return Task.FromResult>([]); } } }