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 bda4460..b7bcb90 100644 --- a/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt +++ b/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt @@ -687,20 +687,38 @@ class MainActivity : AppCompatActivity() { val rseq = onsetSeq speakerCheckHandler.post { if (rseq != onsetSeq) return@post - val emb = SpeakerRecognition.computeEmbeddingFast( + val anchor = windowRefEmb ?: return@post + // 一级:快锚点相似度(灵敏);贴近锚点=同人,免准确复核 + val fastEmb = SpeakerRecognition.computeEmbeddingFast( + slice, sampleRateInHz) ?: return@post + if (rseq != onsetSeq) return@post + val simFast = SpeakerRecognition.similarity( + fastEmb, anchor) + if (simFast >= emaAbsorbMin) return@post + // 二级:准确空间复核(2026-09-16 误报实锤:A 暂停 + // 续说,fast 短窗 simA<0.5 误判新人→A 的续说句被切 + // 成"已识别人2"首句)。同人暂停后短窗声纹弱,fast + // 不可信;CAM++ 准确空间同人 0.77~0.93 强分离: + // 注册表认得出(且是当前人)→ 撤销切换;认得出别人 + // → 切给他;谁都认不出 → 才当新人 + val emb = SpeakerRecognition.computeEmbedding( slice, sampleRateInHz) ?: return@post if (rseq != onsetSeq) return@post - val anchor = windowRefEmb ?: return@post - val simA = SpeakerRecognition.similarity(emb, anchor) - if (simA >= emaAbsorbMin) return@post val active = activeLabelForWindow - val known = rollingSpeakerSearch(emb) + val known = SpeakerRecognition.registry.search( + emb, speakerThreshold) + ?: nearestAttribution( + emb, SpeakerRecognition.registry, + verdictFallbackMin) if (known != null && known == active) return@post val label = known ?: SpeakerRecognition.nextAutoLabel().also { - SpeakerRecognition.fastRegistry.addAuto(it, emb) + SpeakerRecognition.registry.addAuto(it, emb) + SpeakerRecognition.fastRegistry.addAuto( + it, fastEmb) } - Log.i(TAG, "ONSET-SWITCH simA=${"%.2f".format(simA)}" + + Log.i(TAG, "ONSET-SWITCH fastSim=" + + "%.2f".format(simFast) + " label=$label kind=" + (if (known != null) "known" else "new") + " active=${active ?: "-"}")