edit | blame | history | raw

2026-06-14 X-ASR 尾字修复

用户目标

用户确认按“X-ASR 松键后尾部采集保护”方案修复偶发尾字掉字问题,并要求:

  • 修完后必须拉两个代码审核员审核改动。
  • 必须拉 QA 做回归测试。

改动范围

仅改 X-ASR 实验分支的尾部采集相关代码与测试:

  • privatevoice.src/internal/engine/engine.go
  • 新增 ReleaseTailCaptureEngine 可选能力接口。
  • privatevoice.src/internal/engine/engine_darwin.go
  • X-ASR streaming engine 实现 ReleaseTailCaptureDelay()
  • X-ASR 松键尾采延迟为 300ms
  • privatevoice.src/app.go
  • replaceEngine() 时缓存 tail delay 到 releaseTailCaptureNanos,停止录音路径不再抢 engineMu
  • hold/tap 正常停止时先等待尾采,再 StopAndGetSamples()
  • HasVoiceActivity() 改到尾采和停止录音之后读取。
  • 增加 isStoppingRecording,尾采未完成时阻止下一次录音启动,避免连续触发串音或设备状态竞争。
  • 取消路径和静音自动停止路径不新增尾采延迟。
  • privatevoice.src/app_live_caption_test.go
  • 覆盖 tail delay 缓存、非 tail engine 默认 0、尾采期间 hold/tap 不启动新录音。
  • privatevoice.src/internal/engine/engine_darwin_test.go
  • 覆盖 X-ASR 请求 300ms tail delay、离线 sherpa engine 不实现 tail capture。

代码审核

审核员 1

第一轮发现阻塞问题:

  • 停止录音路径读取 engineMu,可能与实时字幕/识别锁形成录音生命周期竞态。
  • hasVoice 在尾采前快照,尾采期间捕获到的语音可能不参与 VAD。

已修复后第二轮复审:

  • P1 已关闭:停止路径只读 atomic 缓存,不再拿 engineMuisStoppingRecording 阻止尾采期间新录音。
  • P2 已关闭:先 StopAndGetSamples(),再读取 HasVoiceActivity()
  • 无新的 P1/P2。
  • 建议补测 isStoppingRecording,已补。

审核员 2

第一轮无阻塞,指出:

  • releaseTailCaptureDelay()engineMu 有可感知延迟风险。
  • VAD 读取过早。
  • 自动化测试偏结构性。

已修复后第二轮复审:

  • 无阻塞问题。
  • 确认 X-ASR 隔离、atomic 缓存、VAD 顺序和连续触发保护成立。
  • 非阻塞观察:录音中切模型可能存在极短暂 delay/engine 不一致,建议以后在模型切换入口禁止录音中切换。

QA 结果

自动化 QA 通过,未使用临时 GUI/AX/cliclick/screencapture 命令。

本地执行:

  • go test ./...:通过;仅有既有 macOS / onnxruntime 最低系统版本链接 warning。
  • go test -race . ./internal/engine ./internal/audio ./internal/input:通过。
  • go test -race -count=20 -run 'TestStartRecordingIgnoredWhileStoppingRecording|TestStartTapRecordingIgnoredWhileStoppingRecording|TestReleaseTailCapture' .:通过。
  • npm run build:通过;仅有既有 Svelte a11y warning。
  • ./scripts/build-local-macos.sh arm64:通过,签名与 DMG verify 成功。该构建未安装到 /Applications,且未递增 build,因此仅作为构建验证证据。

QA 角色独立结论:

  • 自动化 QA 通过,未发现阻塞问题。
  • 确认 X-ASR 有 300ms release tail,非 X-ASR 无 tail。
  • 确认停止录音不再依赖 engineMu
  • 确认 isStoppingRecording 覆盖连续快速触发风险。
  • 确认 VAD 在尾采后判断。

未自动化覆盖

真实语音尾字效果需要用户拿后续测试包做人工验证:

  • X-ASR hold 模式反复说:“技术总监让我问你一下”“你看一下”“确认一下”“可以了”“好了呀”。
  • 三种松键节奏:最后一个字刚出口就松、提前一点松、说完后再松。
  • X-ASR tap 模式同样覆盖这些句子。
  • 极短句 VAD:“好”“一下”“嗯”“可以”。
  • 连续快速两次输入,间隔 0.5-1 秒,确认不串音、不丢下一句。
  • 实时字幕开启时,确认最终上屏保留尾字,动效不冻结。
  • 非 X-ASR 至少测 SenseVoice / Qwen3-ASR,确认没有 300ms 可感知新增延迟。

备注

当前工作区存在大量与本次修复无关的 Release 产物、文档、AGENTS 等未提交/未跟踪变动。本次提交必须只包含上述源码、测试与本记录,不得混入无关产物。