Improve toast duration and speaker override samples
PR and Push Build/Test / build-and-test (push) Failing after 9m48s

This commit is contained in:
2026-06-05 10:52:08 +02:00
parent 351ed2eb50
commit 1a89382f02
13 changed files with 162 additions and 33 deletions
@@ -79,6 +79,17 @@ public sealed class SpeakerIdentityService : ISpeakerIdentificationService
var meetingReference = CreateReference(request.MeetingNote, now);
var snippetResolution = await ResolveOverrideSnippetAsync(request, sourceLabel, cancellationToken);
var snippet = snippetResolution.WavBytes;
if (snippet.Length > 0 && !await matchValidator.ValidateSampleAsync(snippet, cancellationToken))
{
logger.LogInformation(
"Speaker override from {SourceSpeaker} to {TargetSpeaker} rejected source sample after secondary validation: sample source {SampleSource}, sample bytes {SampleBytes}",
sourceLabel,
targetName,
snippetResolution.Source,
snippet.Length);
snippet = [];
}
var target = await FindIdentityByAcceptedNameAsync(context, targetName, cancellationToken);
var sourceCandidate = await FindCurrentRunCandidateAsync(
context,
@@ -277,20 +288,10 @@ public sealed class SpeakerIdentityService : ISpeakerIdentificationService
if (snippet.Length == 0)
{
snippetSource = "extracted";
var span = SpeakerSampleSpanSelector.SelectBestContinuousSpan(
request.Segments,
(snippet, _) = await ExtractBestContinuousSampleAsync(
request,
speaker,
options.MaximumSampleSegmentGap,
options.MinimumSampleSpeechDuration);
logger.LogInformation(
"Speaker identity processing extracting sample for {Speaker}: selected {SegmentCount} segment(s), span {SpanDuration}, minimum {MinimumDuration}",
speaker,
span.Count,
SpeakerSampleSpanSelector.SpanDuration(span),
options.MinimumSampleSpeechDuration);
snippet = await snippetExtractor.ExtractSnippetAsync(
request.AudioPath,
span,
"Speaker identity processing",
cancellationToken);
}
@@ -521,13 +522,39 @@ public sealed class SpeakerIdentityService : ISpeakerIdentificationService
return new SpeakerSnippetResolution([], "missing-segments", SegmentCount: 0, Score: null, Duration: TimeSpan.Zero);
}
var snippet = await snippetExtractor.ExtractSnippetAsync(request.AudioPath, segments, cancellationToken);
var (snippet, span) = await ExtractBestContinuousSampleAsync(
request,
sourceSpeaker,
"Speaker override",
cancellationToken);
return new SpeakerSnippetResolution(
snippet,
"extracted-from-recording",
segments.Count,
span.Count,
Score: null,
segments.Max(segment => segment.End) - segments.Min(segment => segment.Start));
SpeakerSampleSpanSelector.SpanDuration(span));
}
private async Task<(byte[] Snippet, IReadOnlyList<TranscriptionSegment> Span)> ExtractBestContinuousSampleAsync(
SpeakerIdentificationRequest request,
string speaker,
string operation,
CancellationToken cancellationToken)
{
var span = SpeakerSampleSpanSelector.SelectBestContinuousSpan(
request.Segments,
speaker,
options.MaximumSampleSegmentGap,
options.MinimumSampleSpeechDuration);
logger.LogInformation(
"{Operation} extracting fallback sample for {Speaker}: selected {SegmentCount} segment(s), span {SpanDuration}, minimum {MinimumDuration}",
operation,
speaker,
span.Count,
SpeakerSampleSpanSelector.SpanDuration(span),
options.MinimumSampleSpeechDuration);
var snippet = await snippetExtractor.ExtractSnippetAsync(request.AudioPath, span, cancellationToken);
return (snippet, span);
}
private static async Task<SpeakerIdentity?> FindIdentityByAcceptedNameAsync(