diff --git a/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt b/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt index 6f12324..5eda3f1 100644 --- a/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt +++ b/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt @@ -250,6 +250,9 @@ class MainActivity : AppCompatActivity() { private val forceSwitchStreaks = 2 // 强切冷却(仅 speakerCheckHandler 线程访问,无需 volatile) private var lastForceSwitchAtMs = 0L + // 快速通道连续低分计数(同上,单线程访问)。2026-09-16 现场:2s 窗 + // 垃圾窗孤发(负余弦都出现),单窗判决分不开换声与噪声 → 连续两窗闸 + private var fastRollLowStreak = 0 // C(最新者胜):每次投递滚动检测都刷新序号,队列里被超额的旧任务直接跳过 @Volatile private var rollingSeq = 0L // 兜底残料:当前句子槽位最近一次滚动窗口声纹。整句判定因碎片算不出 @@ -748,12 +751,21 @@ class MainActivity : AppCompatActivity() { tailF, sampleRateInHz) ?: return@post if (rseq != onsetSeq) return@post val sim = SpeakerRecognition.similarity(emb, anchor) - if (sim >= fastRollDrop) return@post + if (sim >= fastRollDrop) { + fastRollLowStreak = 0 + return@post + } + fastRollLowStreak += 1 + if (fastRollLowStreak < 2) return@post + fastRollLowStreak = 0 val active = activeLabelForWindow // 先查注册表:认出当前人 → 销案(白捡的防护); // 认出别人 → 复用其编号;彻底陌生才发新号 val known = rollingSpeakerSearch(emb) - if (known != null && known == active) return@post + if (known != null && known == active) { + fastRollLowStreak = 0 + return@post + } val nowMs = SystemClock.elapsedRealtime() if (nowMs - lastForceSwitchAtMs < 3_000L) { Log.i(TAG, "FASTROLL suppressed (cooldown)")