强切换行哑火根治(实机病灶):封行动作被三处早退吞掉——①强切时无进行中句(owner=-1),强制endpoint落进无句分支只有resetBuffer,永无finalize;②finalizeSentence两个早退(sentenceById缺失/重复定格)在封行代码之前。修:封行移至finalizeSentence入口(早退前);无句分支补发closeOnsetLineIfPending;预置标签加5s保鲜期防误挂;修复后链路:强切→封行→新句新行挂S1,日志ONSET-CLOSE/ONSET-LINE可查
This commit is contained in:
parent
6239f0a37e
commit
206037994f
|
|
@ -221,6 +221,7 @@ class MainActivity : AppCompatActivity() {
|
|||
private val onsetMinSamples = 19200 // 1.2s 开口窗
|
||||
@Volatile private var onsetSeq = 0L // 行切换/会话开始作废在途开口判定
|
||||
private var pendingOnsetLabel: String? = null // 主线程:下一新行预置标签
|
||||
private var pendingOnsetLabelAt = 0L // 预置标签时间戳(过期作废)
|
||||
private var onsetClosePending = false // 主线程:强切后旧句定格即封底行
|
||||
@Volatile private var rollingLowHits = 0
|
||||
// 无缝插话确证(2026-09-15):SUSPECT 等停顿会被"对方话没停就接话"憋死
|
||||
|
|
@ -851,9 +852,11 @@ class MainActivity : AppCompatActivity() {
|
|||
rmsOf(samples) else 0f) + ")")
|
||||
switchSuspicionAtMs = 0L
|
||||
}
|
||||
var forcedEp = false
|
||||
if (fastEp) {
|
||||
val forced = pendingForceEndpoint
|
||||
pendingForceEndpoint = false
|
||||
forcedEp = forced
|
||||
rollingLowStreak = 0
|
||||
switchSuspicionAtMs = 0L
|
||||
silenceRun = 0
|
||||
|
|
@ -905,7 +908,13 @@ class MainActivity : AppCompatActivity() {
|
|||
finalizeSentence(sid, accepted)
|
||||
}
|
||||
} else {
|
||||
// 强切但无句可定格(owner=-1):封行/预置标签仍在
|
||||
// 主线程挂着,finalizeSentence 永不来的这条路径上
|
||||
// 补发封行,否则换行哑火(2026-09-16 现场根因)
|
||||
resetBuffer()
|
||||
if (forcedEp) {
|
||||
uiHandler.post { closeOnsetLineIfPending() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1618,6 +1627,7 @@ class MainActivity : AppCompatActivity() {
|
|||
val list = if (historyMode) stashedLiveLines ?: subtitleLines else subtitleLines
|
||||
val bottom = list.lastOrNull() ?: return
|
||||
pendingOnsetLabel = label
|
||||
pendingOnsetLabelAt = SystemClock.elapsedRealtime()
|
||||
if (!bottom.open) return // 底行已封:下一行自然消费预置标签
|
||||
val busy = bottom.sentences.any { !it.finalized }
|
||||
if (busy) {
|
||||
|
|
@ -1628,6 +1638,14 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
/** 强切落进"无句可定格"分支时的封行兜底(主线程);预置标签保留等待下一行 */
|
||||
private fun closeOnsetLineIfPending() {
|
||||
if (!onsetClosePending) return
|
||||
onsetClosePending = false
|
||||
subtitleLines.lastOrNull()?.takeIf { it.open }?.open = false
|
||||
Log.i(TAG, "ONSET-CLOSE no-sentence forced endpoint")
|
||||
}
|
||||
|
||||
private fun appendNewLine(label: String?): SubtitleLine {
|
||||
// 新行出现即封掉之前的开放行,并把其中"未定格的进行中句子"整体迁移
|
||||
// 过来 —— 硬保证 in-progress 只可能发生在最底行(修复:声纹判定搬家后,
|
||||
|
|
@ -1642,12 +1660,23 @@ class MainActivity : AppCompatActivity() {
|
|||
old?.sentences?.removeAll(migrating.toSet())
|
||||
}
|
||||
// 开口即查预置标签(ONSET-SWITCH 判了新说话人)→ 新行直接采用,
|
||||
// 并成为"最近确认说话人"(后续空闲新行沿用);不等 endpoint 权威判定
|
||||
val eff = pendingOnsetLabel ?: label
|
||||
if (pendingOnsetLabel != null) {
|
||||
// 并成为"最近确认说话人"(后续空闲新行沿用);不等 endpoint 权威判定。
|
||||
// 超 5s 未消费 = 强切未落地(如无句可定格且无后续新句),作废防误挂
|
||||
val preset = pendingOnsetLabel
|
||||
val eff: String?
|
||||
if (preset != null &&
|
||||
SystemClock.elapsedRealtime() - pendingOnsetLabelAt < 5_000L
|
||||
) {
|
||||
pendingOnsetLabel = null
|
||||
lastConfirmedLabel = eff
|
||||
Log.i(TAG, "ONSET-LINE new line label=$eff")
|
||||
lastConfirmedLabel = preset
|
||||
eff = preset
|
||||
Log.i(TAG, "ONSET-LINE new line label=$preset")
|
||||
} else {
|
||||
if (preset != null) {
|
||||
pendingOnsetLabel = null
|
||||
Log.i(TAG, "ONSET-LINE stale preset dropped")
|
||||
}
|
||||
eff = label
|
||||
}
|
||||
val line = SubtitleLine(
|
||||
id = lineIdSeq.incrementAndGet(),
|
||||
|
|
@ -1700,6 +1729,13 @@ class MainActivity : AppCompatActivity() {
|
|||
// endpoint/强制断句的 settle:该句就地定格(归属修正走 confirmSpeaker,
|
||||
// v5 起声纹判定已移出录音线程)。
|
||||
private fun finalizeSentence(sid: Long, willRefine: Boolean) {
|
||||
// 开口即查/强切封行:必须在任何早退之前执行——sentenceById 缺失或
|
||||
// 重复定格都会从下面两行 return,尾部执行曾让封行永哑
|
||||
// (2026-09-16 现场:强切 owner=sid-1,强制 endpoint 无句可定格,换行丢失)
|
||||
if (onsetClosePending) {
|
||||
onsetClosePending = false
|
||||
subtitleLines.lastOrNull()?.takeIf { it.open }?.open = false
|
||||
}
|
||||
lastSettledSid = sid
|
||||
lastSentenceSettledAt = SystemClock.elapsedRealtime()
|
||||
val sentence = sentenceById[sid] ?: return
|
||||
|
|
@ -1720,12 +1756,6 @@ class MainActivity : AppCompatActivity() {
|
|||
// (SKIP_SHORT 等情况 submitRefineTask 已写对账日志,不重复记)
|
||||
sentenceById.remove(sid)
|
||||
}
|
||||
// 开口即查强切:旧句已定格,此刻封底行,让新说话人首句另起带
|
||||
// 预置标签的新行(由后续 onPartial 尾部创建)
|
||||
if (onsetClosePending) {
|
||||
onsetClosePending = false
|
||||
subtitleLines.lastOrNull()?.takeIf { it.open }?.open = false
|
||||
}
|
||||
sentence.line?.let { notifyLine(it) }
|
||||
autoScroll()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue