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