Public Access
feat: add local Resemblyzer speaker recognition
PR and Push Build/Test / build-and-test (push) Successful in 12m37s
PR and Push Build/Test / build-and-test (push) Successful in 12m37s
This commit is contained in:
@@ -2899,6 +2899,65 @@ public sealed class RecordingCoordinatorTests
|
||||
Assert.Equal(["Chris"], speakerIdentification.Requests.Last().MeetingNote.Frontmatter.Attendees);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LiveResemblyzerMatchingRetriesWhenSameSpeakerCollectsRequiredSamples()
|
||||
{
|
||||
var audioSource = new ControlledAudioSource();
|
||||
var transcriptStore = new InMemoryTranscriptStore();
|
||||
var speakerIdentification = new CountingSpeakerIdentificationService();
|
||||
var coordinator = new MeetingRecordingCoordinator(
|
||||
audioSource,
|
||||
new TestSpeechRecognitionPipelineFactory(new OrderedChunkProvider()),
|
||||
transcriptStore,
|
||||
new InMemoryMeetingNoteStore(),
|
||||
new CapturingMeetingNoteOpener(),
|
||||
new InMemoryMeetingArtifactStore(),
|
||||
new InMemoryRecordedAudioStore(),
|
||||
new CapturingMeetingSummaryPipeline(),
|
||||
Options.Create(new MeetingAssistantOptions
|
||||
{
|
||||
SpeakerIdentification = new SpeakerIdentificationOptions
|
||||
{
|
||||
InitialDelay = TimeSpan.Zero,
|
||||
Interval = TimeSpan.FromMilliseconds(20),
|
||||
MinimumSampleSpeechDuration = TimeSpan.Zero,
|
||||
Resemblyzer = new ResemblyzerSpeakerRecognitionOptions
|
||||
{
|
||||
Enabled = true,
|
||||
RequiredVectorsPerSpeaker = 5
|
||||
}
|
||||
}
|
||||
}),
|
||||
NullLogger<MeetingRecordingCoordinator>.Instance,
|
||||
speakerIdentificationService: speakerIdentification,
|
||||
speakerSampleCollectionPolicy: SpeakerSampleCollectionPolicy.IndependentVectors(1000));
|
||||
|
||||
await coordinator.StartAsync(CancellationToken.None);
|
||||
try
|
||||
{
|
||||
await audioSource.WriteAsync(new AudioChunk(Samples(0, 1, 2, 3, 4, 5, 6, 7), 4, 1), CancellationToken.None);
|
||||
await WaitUntilAsync(() => speakerIdentification.Requests.Count == 1);
|
||||
Assert.Single(speakerIdentification.Requests.Single().Samples!);
|
||||
|
||||
// The provider emits overlapping two-second segments, so every second
|
||||
// segment supplies another independent recognition sample.
|
||||
for (var index = 1; index < 9; index++)
|
||||
{
|
||||
await audioSource.WriteAsync(new AudioChunk(Samples(0, 1, 2, 3, 4, 5, 6, 7), 4, 1), CancellationToken.None);
|
||||
}
|
||||
|
||||
await WaitUntilAsync(() => speakerIdentification.Requests.Last().Samples?.Count == 5);
|
||||
var attempts = speakerIdentification.Requests.Count;
|
||||
await Task.Delay(100);
|
||||
Assert.Equal(attempts, speakerIdentification.Requests.Count);
|
||||
Assert.All(speakerIdentification.Requests.Last().Samples!, sample => Assert.Equal("Guest03", sample.Speaker));
|
||||
}
|
||||
finally
|
||||
{
|
||||
await coordinator.StopAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LiveSpeakerIdentificationRetriesWhenNewUnmappedSpeakerAppears()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user