Public Access
108 lines
2.7 KiB
C#
108 lines
2.7 KiB
C#
using MeetingAssistant.Transcription;
|
|
using NAudio.Wave;
|
|
|
|
namespace MeetingAssistant.Speakers;
|
|
|
|
internal static class SpeakerCompositeWav
|
|
{
|
|
public static WaveFileReader? OpenFirstReadableWave(IEnumerable<byte[]> snippets)
|
|
{
|
|
foreach (var bytes in snippets)
|
|
{
|
|
if (bytes.Length == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
try
|
|
{
|
|
return new WaveFileReader(new MemoryStream(bytes));
|
|
}
|
|
catch (FormatException)
|
|
{
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static TimeSegment? AppendSnippet(
|
|
WaveFileWriter writer,
|
|
WaveFormat targetFormat,
|
|
byte[] snippet,
|
|
TimeSpan start)
|
|
{
|
|
if (snippet.Length == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
using var reader = new WaveFileReader(new MemoryStream(snippet));
|
|
if (!WaveFormatsMatch(reader.WaveFormat, targetFormat))
|
|
{
|
|
throw new InvalidDataException("Speaker identity snippets must use the same WAV format.");
|
|
}
|
|
|
|
reader.CopyTo(writer);
|
|
return new TimeSegment(start, start + reader.TotalTime);
|
|
}
|
|
|
|
public static void WriteSilence(
|
|
WaveFileWriter writer,
|
|
WaveFormat format,
|
|
TimeSpan duration)
|
|
{
|
|
if (duration <= TimeSpan.Zero)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var bytes = new byte[(int)(format.AverageBytesPerSecond * duration.TotalSeconds)];
|
|
writer.Write(bytes, 0, bytes.Length);
|
|
}
|
|
|
|
public static string? FindBestSpeaker(
|
|
TimeSegment segment,
|
|
IReadOnlyList<TranscriptionSegment> segments)
|
|
{
|
|
var bestOverlap = 0d;
|
|
string? bestSpeaker = null;
|
|
foreach (var transcriptSegment in segments)
|
|
{
|
|
var overlap = Math.Min(segment.End.TotalSeconds, transcriptSegment.End.TotalSeconds)
|
|
- Math.Max(segment.Start.TotalSeconds, transcriptSegment.Start.TotalSeconds);
|
|
if (overlap > bestOverlap)
|
|
{
|
|
bestOverlap = overlap;
|
|
bestSpeaker = transcriptSegment.Speaker;
|
|
}
|
|
}
|
|
|
|
return bestSpeaker;
|
|
}
|
|
|
|
public static void TryDelete(string path)
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
}
|
|
catch (IOException)
|
|
{
|
|
}
|
|
}
|
|
|
|
private static bool WaveFormatsMatch(WaveFormat left, WaveFormat right)
|
|
{
|
|
return left.Encoding == right.Encoding
|
|
&& left.SampleRate == right.SampleRate
|
|
&& left.Channels == right.Channels
|
|
&& left.BitsPerSample == right.BitsPerSample;
|
|
}
|
|
}
|
|
|
|
internal readonly record struct TimeSegment(TimeSpan Start, TimeSpan End);
|