Public Access
49 lines
1.6 KiB
C#
49 lines
1.6 KiB
C#
using System.Runtime.CompilerServices;
|
|
using NAudio.Wave;
|
|
|
|
namespace MeetingAssistant.Recording;
|
|
|
|
public static class PcmWavAudioChunkReader
|
|
{
|
|
private const int MaxChunkDurationMilliseconds = 1000;
|
|
|
|
public static async IAsyncEnumerable<AudioChunk> 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.
|
|
}
|
|
}
|
|
}
|
|
}
|