[异步播报打断]:完成播放中麦克风监听和音色隔离,包含后台监听、助手回放抑制和用户音色打断测试
This commit is contained in:
@@ -326,6 +326,18 @@ Follow-up 捕获复用现有 capture、实时字幕、final STT、LLM、TTS 流
|
||||
4. 已完整播放的句子文本才写入 process-local assistant context;未播出的句子和后续未播放 token 不写入上下文。
|
||||
5. 打断后的用户输入进入免唤醒 follow-up 捕获路径,保留实时字幕和 final STT,最终仍只有 final transcript 进入 LLM。
|
||||
|
||||
## Async Barge-in Speaker Gate Revision
|
||||
|
||||
旧打断路径由播放 chunk 回调驱动,每写完一段音频后才读取麦克风,不满足“播放同时监听”的实时性要求,也无法稳定排除助手自己的回放。修正版边界如下:
|
||||
|
||||
1. `AsyncBargeInMonitor` 在可打断 TTS 回复开始时启动后台线程,独立调用 `AudioTransport.read_frames()`,默认每 20 ms 检查一次,不由播放循环触发麦克风处理。
|
||||
2. `AudioTransport.play_pcm_chunks()` 只接收 `should_stop` 停止信号;播放线程在 20-40 ms chunk 边界检查该信号并尽快停止剩余播报。
|
||||
3. `BargeInSpeakerGate` 从最近一次用户正式输入建立本次进程内临时用户音色画像,从当前 TTS PCM 建立助手回放音色画像。
|
||||
4. 播放期间候选麦克风帧必须通过 VAD,且不能匹配助手回放画像;若用户画像已存在,还必须匹配用户画像;若用户画像不足,降级为“非助手音色 + 有效 realtime partial”。
|
||||
5. 播放期间 realtime STT 只作为后台打断确认信号,不发 `transcript_partial` 事件,避免把助手回放显示成用户实时字幕。
|
||||
6. 监听线程确认打断后把已确认用户帧写入 `_pending_capture_frames`,后续 follow-up capture 直接续接,减少用户抢话首字丢失。
|
||||
7. 用户画像、助手画像、候选帧均只保存在进程内,不写入磁盘、不发送给 LLM、不跨进程复用。
|
||||
|
||||
## Migration
|
||||
|
||||
No database migration. Users should run:
|
||||
|
||||
@@ -461,6 +461,14 @@ standby
|
||||
- [ ] 15.3 补充 recorder finish 和回归测试;前置条件:15.2 完成;验收标准:持续有语音但 partial 不再推进时,segment end_reason 为 `partial_transcript_idle`,final STT 仍执行且 partial 不进上下文;测试要点:live runtime 单测;优先级:P0;预计:45 分钟。
|
||||
- [ ] 15.4 执行门禁并提交“实时字幕端点”模块;前置条件:15.1 至 15.3 完成;验收标准:compileall、unittest、simulate-live、security-check、OpenSpec strict、git diff check 通过后中文提交;优先级:P0;预计:45 分钟。
|
||||
|
||||
### 17. 异步播报打断与音色隔离
|
||||
|
||||
- [ ] 17.1 更新 OpenSpec 和 README 描述异步监听与音色隔离;前置条件:用户确认当前打断仍未真正异步且会被助手回放干扰;验收标准:proposal/design/spec/tasks/README 明确后台监听线程、停止信号、用户临时音色画像、助手回放音色抑制和非持久化边界;测试要点:OpenSpec strict;优先级:P0;预计:45 分钟。
|
||||
- [ ] 17.2 扩展配置和 Transport 停止接口;前置条件:17.1 完成;验收标准:新增 `OWNER_BARGE_IN_SPEAKER_GATE_ENABLED`、`OWNER_BARGE_IN_USER_SIMILARITY_THRESHOLD`、`OWNER_BARGE_IN_ASSISTANT_REJECT_THRESHOLD`、`OWNER_BARGE_IN_LISTEN_INTERVAL_MS`、`OWNER_BARGE_IN_CHUNK_MS`,`play_pcm_chunks()` 支持播放侧只检查 stop signal;测试要点:配置默认值、校验和 chunk 停止测试;优先级:P0;预计:45 分钟。
|
||||
- [ ] 17.3 实现 `AsyncBargeInMonitor` 和 `BargeInSpeakerGate`;前置条件:17.2 完成;验收标准:播放时后台线程独立读取麦克风,排除助手回放音色,确认用户音色后设置 stop event,并把已确认用户帧接入后续 capture;测试要点:异步读取、助手音色不触发、用户音色触发、画像不足降级;优先级:P0;预计:60 分钟。
|
||||
- [ ] 17.4 接入 `VoiceAssistantPipeline` 播放路径并补充文档;前置条件:17.3 完成;验收标准:TTS 回复使用异步打断,ACK 和结束提示音不打断,播放期间不输出实时字幕,README 说明新参数和调参边界;测试要点:打断事件顺序、上下文只写已播文本、pending capture 不丢首字;优先级:P0;预计:60 分钟。
|
||||
- [ ] 17.5 执行门禁并提交“异步播报打断”模块;前置条件:17.1 至 17.4 完成;验收标准:compileall、unittest、simulate-live、real-live-check --no-playback、security-check、model-check、device-check、OpenSpec strict 通过后提交;优先级:P0;预计:60 分钟。
|
||||
|
||||
## Spec Deltas
|
||||
|
||||
### 新增能力
|
||||
@@ -487,6 +495,7 @@ standby
|
||||
16. `Realtime transcript idle endpoint`:新增已有实时字幕后 1.5 秒无新文字即结束录音的端点要求,避免用户已停说但 capture 继续等待 VAD/音色端点。
|
||||
17. `Automatic continuous dialog decision`:新增回复后自动判断继续/待机能力,使用规则优先、LLM 小分类兜底,不确定时默认回到待机。
|
||||
18. `Barge-in playback interruption`:新增播报中用户有效说话打断能力,使用 echo guard、最短语音时长和 realtime partial 共同确认,避免播放回声误触发。
|
||||
19. `Async barge-in speaker gate`:强化播报打断为后台异步监听,新增用户临时音色画像、助手回放音色抑制、播放停止信号和非持久化隐私要求。
|
||||
|
||||
### 删除项
|
||||
|
||||
@@ -513,6 +522,7 @@ standby
|
||||
13. M13:`real-live-check` 计时输出完成后提交,使后续排查可以直接看到每段耗时。
|
||||
14. M14:实时字幕停滞端点完成后提交,用户真实 `run-live` 若已有 partial 后 1.5 秒无新文字,应快速进入 final STT。
|
||||
15. M15:自动持续对话判断与播报打断完成后提交,用户真实 `run-live` 应能在助手反问时免唤醒继续回答,在助手已完成回答时自动恢复待机。
|
||||
16. M16:异步播报打断与音色隔离完成后提交,用户真实 `run-live` 应能在助手播报时直接说话打断,且助手自己的回放不触发打断或实时字幕。
|
||||
|
||||
估时:
|
||||
|
||||
|
||||
+20
@@ -170,6 +170,21 @@ The live runtime SHALL support a first-version barge-in path that can stop assis
|
||||
- **WHEN** TTS playback starts and microphone input appears before `OWNER_BARGE_IN_ECHO_GUARD_MS`
|
||||
- **THEN** the runtime SHALL NOT treat that input as a user barge-in
|
||||
|
||||
#### Scenario: Playback is monitored asynchronously
|
||||
- **WHEN** an interruptible assistant reply is playing
|
||||
- **THEN** the runtime SHALL listen to microphone frames from a background monitor rather than waiting for playback chunks to invoke microphone processing
|
||||
- **AND** the playback transport SHALL stop remaining chunks when the monitor raises the shared stop signal
|
||||
|
||||
#### Scenario: Assistant playback voice is rejected
|
||||
- **WHEN** microphone input during playback matches the current assistant playback timbre profile
|
||||
- **THEN** the runtime SHALL NOT emit `barge_in_detected`
|
||||
- **AND** it SHALL NOT display realtime transcript text for that assistant playback echo
|
||||
|
||||
#### Scenario: User voice interrupts playback
|
||||
- **WHEN** microphone input after the echo guard matches the temporary process-local user timbre profile, does not match the assistant playback profile, passes VAD, and produces a valid realtime partial
|
||||
- **THEN** the runtime SHALL emit `barge_in_detected`
|
||||
- **AND** it SHALL stop playback promptly and process the buffered user frames as the next no-wake input
|
||||
|
||||
#### Scenario: Valid user speech interrupts playback
|
||||
- **WHEN** TTS playback has passed the echo guard, VAD observes at least `OWNER_BARGE_IN_MIN_SPEECH_MS` of user speech, and realtime STT produces a valid partial transcript
|
||||
- **THEN** the runtime SHALL emit `barge_in_detected`
|
||||
@@ -181,6 +196,11 @@ The live runtime SHALL support a first-version barge-in path that can stop assis
|
||||
- **THEN** the process-local conversation context SHALL append only the assistant text that had been fully spoken before interruption
|
||||
- **AND** unspoken assistant text SHALL NOT be appended to the session history
|
||||
|
||||
#### Scenario: Barge-in speaker profiles are temporary
|
||||
- **WHEN** the runtime builds user or assistant timbre profiles for interruption gating
|
||||
- **THEN** those profiles SHALL remain in process memory only
|
||||
- **AND** they SHALL NOT be written to disk, sent to the cloud LLM, or reused after process exit
|
||||
|
||||
### Requirement: Real provider live fixture acceptance
|
||||
The system SHALL support scripted full-chain acceptance that drives the live pipeline with generated microphone PCM while using real local speech providers, the configured cloud LLM, and local TTS/playback capability.
|
||||
|
||||
|
||||
@@ -126,3 +126,11 @@
|
||||
- [x] 16.3 重构 `VoiceAssistantPipeline/TurnController` 支持自动 follow-up;前置条件:16.2 完成;验收标准:回复后先判定 continue/standby,continue 时播放完进入 `followup_listening`,3 秒内用户直接回答无需 wake/ACK,超时恢复 standby;测试要点:连续对话、follow-up timeout、上下文只写 final STT;优先级:P0;预计:60 分钟。
|
||||
- [x] 16.4 实现可打断播放路径;前置条件:16.3 完成;验收标准:TTS 播放前 500 ms 忽略回声,之后检测到至少 250 ms 有效用户语音且 realtime partial 有效时触发 `barge_in_detected -> playback_interrupted`,上下文只写已播出的 assistant 文本;测试要点:guard window 不打断、有效输入打断、未播文本不进上下文;优先级:P0;预计:60 分钟。
|
||||
- [x] 16.5 执行门禁并提交“连续对话判断”模块;前置条件:16.1 至 16.4 完成;验收标准:compileall、unittest、simulate-live --turns 3、real-live-check --turns 2 --no-playback、security-check、model-check、device-check、OpenSpec strict、git diff check 通过后提交;优先级:P0;预计:60 分钟。
|
||||
|
||||
## 17. 异步播报打断与音色隔离
|
||||
|
||||
- [x] 17.1 更新 OpenSpec 和 README 描述异步监听与音色隔离;前置条件:用户确认当前打断仍未真正异步且会被助手回放干扰;验收标准:proposal/design/spec/tasks/README 明确后台监听线程、停止信号、用户临时音色画像、助手回放音色抑制和非持久化边界;测试要点:OpenSpec strict;优先级:P0;预计:45 分钟。
|
||||
- [x] 17.2 扩展配置和 Transport 停止接口;前置条件:17.1 完成;验收标准:新增 `OWNER_BARGE_IN_SPEAKER_GATE_ENABLED`、`OWNER_BARGE_IN_USER_SIMILARITY_THRESHOLD`、`OWNER_BARGE_IN_ASSISTANT_REJECT_THRESHOLD`、`OWNER_BARGE_IN_LISTEN_INTERVAL_MS`、`OWNER_BARGE_IN_CHUNK_MS`,`play_pcm_chunks()` 支持播放侧只检查 stop signal;测试要点:配置默认值、校验和 chunk 停止测试;优先级:P0;预计:45 分钟。
|
||||
- [x] 17.3 实现 `AsyncBargeInMonitor` 和 `BargeInSpeakerGate`;前置条件:17.2 完成;验收标准:播放时后台线程独立读取麦克风,排除助手回放音色,确认用户音色后设置 stop event,并把已确认用户帧接入后续 capture;测试要点:异步读取、助手音色不触发、用户音色触发、画像不足降级;优先级:P0;预计:60 分钟。
|
||||
- [x] 17.4 接入 `VoiceAssistantPipeline` 播放路径并补充文档;前置条件:17.3 完成;验收标准:TTS 回复使用异步打断,ACK 和结束提示音不打断,播放期间不输出实时字幕,README 说明新参数和调参边界;测试要点:打断事件顺序、上下文只写已播文本、pending capture 不丢首字;优先级:P0;预计:60 分钟。
|
||||
- [x] 17.5 执行门禁并提交“异步播报打断”模块;前置条件:17.1 至 17.4 完成;验收标准:compileall、unittest、simulate-live、real-live-check --no-playback、security-check、model-check、device-check、OpenSpec strict 通过后提交;优先级:P0;预计:60 分钟。
|
||||
|
||||
Reference in New Issue
Block a user