using System.Runtime.CompilerServices; using NAudio.Wave; namespace MeetingAssistant.Recording; public static class PcmWavAudioChunkReader { private const int MaxChunkDurationMilliseconds = 1000; public static async IAsyncEnumerable ReadChunksAsync( string path, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var reader = new WaveFileReader(path); try { var format = reader.WaveFormat; if (format.Encoding != WaveFormatEncoding.Pcm || format.BitsPerSample != 16) { throw new InvalidDataException( $"Only 16-bit PCM WAV files are supported. Found {format.Encoding} with {format.BitsPerSample} bits per sample."); } var chunkSize = Math.Max( format.BlockAlign, format.AverageBytesPerSecond * MaxChunkDurationMilliseconds / 1000); chunkSize -= chunkSize % format.BlockAlign; var buffer = new byte[chunkSize]; int read; while ((read = await reader.ReadAsync(buffer.AsMemory(0, buffer.Length), cancellationToken)) > 0) { yield return new AudioChunk(buffer[..read], format.SampleRate, format.Channels); } } finally { try { reader.Dispose(); } catch (NotSupportedException) { // NAudio can throw while disposing reader streams from async iterators after all chunks were read. } } } }