Skip to content

ADR-0004:系统管理录音设备,失焦保流但暂停识别 ​

状态:已接受;日期:2026-10-12;关联:Issue #54。2026-10-13 用户确认 XFCE 双麦与音频管理器切换通过;其他桌面及未确认的采集后端仍待验证。

背景与决策 ​

原 PulseAudio 后端为绕过单机 echo-cancel 默认源无声而按名称/列表猜测麦克风;在多设备机器上会显式指定错误输入,且妨碍系统默认与应用偏好恢复。设备选择应只有系统音频管理器一个决策点。

PulseAudio 建流不指定 source(dev=nullptr),原生 PipeWire 保持无显式 target 的自动连接;彻底删除猜源、过滤与 pactl 子进程。不新增设备配置、兼容开关或路由监控。保留应用/流身份、Pulse→PipeWire 优先级与统一音频格式。

契约为“尊重音频服务路由”,不是“始终强制全局默认”:管理器保存的按应用偏好可以覆盖默认输入。不禁用目标恢复,不修改用户默认或状态数据库。

采集与识别生命周期分离 ​

用户明确要求:开启 Voice Input 后保持管理器可见的录音流,失焦不释放,便于在录音页选择设备。只改系统默认再回输入框的初版交互不足以满足需求。

  • 有活动 Voice Input 上下文:正常识别,仅当前 generation 可上屏。
  • 失焦或活动上下文销毁:保流、继续消费并丢弃采样;暂停 VAD/ASR/LLM、取消会话、失效旧结果和输入框引用。不缓存失焦采样供恢复后回放。
  • 回焦:复用健康流,重置应用队列/VAD 状态、开始新 generation;失效流则安全清理后重建。
  • 明确切换其他输入法/关闭,或退出 Fcitx:停止识别并关闭流。无焦点切换也必须处理。

删除原 200ms 延迟停止路径,不保留双重生命周期。依据 Fcitx 5.1.22 原始事件区分 FocusOut 与 SwitchInputMethod,不能只看后置 Deactivated notification。

采集归属引用独立于活动输入框引用,失焦后仍保留;只有所属上下文的明确关闭事件可释放,其他上下文从 Voice Input 切走也不能误关。输入法组变更/退出为全局释放;所属上下文销毁后回到 Voice Input 重新取得归属。PipeWire 所有已完成回调(含空 buffer)均发布 epoch,避免恢复后的首个有效帧被门闸清掉。

Capture 的投递 epoch 与发布锁保证暂停返回后无新应用帧投递;epoch 防止跨完整暂停/恢复的 read 被误当新音频。PipeWire RT 回调仍不加锁;Drain 在生产者 epoch 屏障后有界清 ring/组帧缓冲。Pipeline 先停止 dispatcher 再移交会话所有权并取消,不与 FeedAudio/End 并发操作同一会话。

取舍、验证与回滚 ​

持续麦克风使用指示是预期行为,不等于失焦音频继续识别,也不等于独占硬件。用户需主动切换其他输入法释放。已经上传的请求不能撤回;取消尽力中止在途操作并拒绝迟到结果。虚拟源不再按名称排除,但错误默认/monitor 可能造成无声或录到回放,用户须检查输入和电平。

simple API 允许管理器移流,异步迁移不是本项前提。已有 PulseAudio read/join 阻塞债务仍由 CAPTURE-54-001 跟踪,不承诺异常停止上界,不使用跨线程 free 或 detach;也不承诺服务端采样级延迟或无间断切换。

以真实 Engine/Capture/Pipeline 公开边界测试,外部音频库及模型/识别边界使用测试替身;假库只在构建目录。验证失焦保流无识别、快速暂停/恢复、旧帧丢弃、死流恢复、无焦点关闭与迟到结果。发布另需真实双麦/桌面验证。

无配置或数据库迁移,本次生命周期/路由交付可整体回滚。完整证据、反方及后续任务见 调研报告。

Fcitx5 Voice Input Documentation