Make diarization chunk length configurable (Auto + presets)
Chunk size was hardcoded at 2.5-min bodies. Add a Settings control: Auto / Standard 2.5min / Large group 60s / Fine 90s. Shorter chunks keep fewer simultaneous speakers per window (Sortformer resolves ~4/chunk), useful for large calls, at some cost to speed and cross-chunk voice matching. - ChunkMode (new, pure/testable): mode → body seconds; Auto picks 60s when >4 participants were detected, else 150s; overlap + single-chunk threshold scale with the body length. - AppSettings.chunkMode (+ typed `chunk`); SettingsView picker with explanation. - TranscriptPipeline.process gains chunkSeconds; derives overlap/threshold from it. - SessionController resolves the body from the setting + the session's detected participant count (visual_timeline participants) for both send + re-process. - Participant roster now counts EVERY tile OCR'd, not just who spoke (TimelineBuilder.observedNames → VisualObserver → VisualCapture), so the Auto call-size signal is meaningful even though speaking-detection is sparse. Tests: ChunkMode resolution, overlap scaling, short-body re-chunking. 69 pass.
This commit is contained in:
@@ -60,6 +60,15 @@ final class AppSettings: ObservableObject {
|
||||
didSet { defaults.set(reconcileSpeakers, forKey: Keys.reconcileSpeakers) }
|
||||
}
|
||||
|
||||
/// Diarization chunk length (raw value of `ChunkMode`). `.auto` shrinks chunks on
|
||||
/// large calls so a window is less likely to exceed Sortformer's ~4-speaker cap.
|
||||
@Published var chunkMode: String {
|
||||
didSet { defaults.set(chunkMode, forKey: Keys.chunkMode) }
|
||||
}
|
||||
|
||||
/// Typed accessor for `chunkMode`.
|
||||
var chunk: ChunkMode { ChunkMode(rawValue: chunkMode) ?? .auto }
|
||||
|
||||
/// User-editable recap templates (takeaways categories per meeting type).
|
||||
@Published var recapTemplates: [RecapTemplate] {
|
||||
didSet { persist(recapTemplates, forKey: Keys.recapTemplates) }
|
||||
@@ -104,6 +113,7 @@ final class AppSettings: ObservableObject {
|
||||
self.autoSendOnStop = defaults.object(forKey: Keys.autoSend) as? Bool ?? false
|
||||
self.recapEnabled = defaults.object(forKey: Keys.recapEnabled) as? Bool ?? true
|
||||
self.reconcileSpeakers = defaults.object(forKey: Keys.reconcileSpeakers) as? Bool ?? true
|
||||
self.chunkMode = defaults.string(forKey: Keys.chunkMode) ?? ChunkMode.auto.rawValue
|
||||
|
||||
let loaded = (defaults.data(forKey: Keys.recapTemplates))
|
||||
.flatMap { try? JSONDecoder().decode([RecapTemplate].self, from: $0) }
|
||||
@@ -126,6 +136,7 @@ final class AppSettings: ObservableObject {
|
||||
static let autoSend = "autoSendOnStop"
|
||||
static let recapEnabled = "recapEnabled"
|
||||
static let reconcileSpeakers = "reconcileSpeakers"
|
||||
static let chunkMode = "chunkMode"
|
||||
static let recapTemplates = "recapTemplates"
|
||||
static let defaultTemplate = "defaultTemplateId"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user