Skip to content

fix(voice-input): 修复跨音频块重采样的异常零值 - #3976

Merged
MagicLizi merged 1 commit into
mainfrom
dash/fix-voice-resample-boundary
Sep 6, 2026
Merged

fix(voice-input): 修复跨音频块重采样的异常零值#3976
MagicLizi merged 1 commit into
mainfrom
dash/fix-voice-resample-boundary

Conversation

@dashhuang

Copy link
Copy Markdown
Member

这次改了什么

摘要

连续音频块重采样时,跨块插值位置可能落在前一块的最后一个样本。原实现读取当前块的负索引,得到 NaN,转成 PCM16 后产生异常零值。48kHz 恒定输入分成 100 个 128 样本块时,修复前的 4,267 个输出样本中可复现 33 个异常零值。

AudioWorklet 和 ScriptProcessor 回退路径现在都保留上一块末样本供跨块插值,并在录音重置时清除该状态。新增同一套输出回归矩阵覆盖两条路径,确保分块后的波形与离线连续插值一致。

变更类型

  • fix 缺陷修复

范围

  • 关联 Issue / 需求:修复桌面语音输入跨块重采样的异常零值。
  • 本 PR 包含:两条采集路径的插值边界修复,以及连续块、不同采样率、尾包和重置回归测试。
  • 明确不包含:采集格式、网络协议、降噪配置、ASR 或润色策略调整。
  • 用户可见变化:跨块音频不再因负索引插入异常零值;实际识别准确率改善尚未测量。
  • 是否存在 breaking change:无。

UI 变化

  • 引用的设计规范:不涉及:仅修正音频重采样计算,无界面、交互或文案变化。

怎么验证的

自动验证

pnpm --filter desktop exec vitest run src/renderer/voice-input/__tests__/audioResampling.test.ts src/renderer/voice-input/__tests__/pcm16kWorklet.test.ts
结果:21 项通过,其中新增 18 项;新增测试在修复前有 14 项失败。

pnpm test:unit:related
结果:通过(Desktop 相关单测)。

pnpm --filter desktop run --if-present typecheck
结果:通过。

pnpm --filter desktop exec eslint src/renderer/voice-input/pcm16k-worklet.js src/renderer/voice-input/WebMicAudioEngine.ts src/renderer/voice-input/__tests__/audioResampling.test.ts
结果:通过。

git diff --check
结果:通过。

回归包含 48k/44.1k/32k/16k/8kHz 输入、128/1024/混合单样本分块、恒定与变化波形、尾包只发送一次、录音重启状态隔离。波形使用绝对位置的离线插值作为独立基准。

手工验证

进程内加载实际 Worklet,以合成输入复现并核对 PCM 输出;另对完整 diff 做独立审查,未发现 P0/P1。

未执行的验证

未启动真实麦克风、未运行端到端 ASR 准确率测试,也未进行 Windows 设备实测。本修复为共享的纯计算路径,回归使用内存输入,不访问设备、账号或云服务。全量单测由 CI 执行。

风险

风险分类

  • 跨平台差异

影响与回滚

  • 影响范围:Desktop AudioWorklet 与 ScriptProcessor 回退路径,均应用相同插值修复;macOS/Windows 的真实设备行为尚未实测。没有原生层、权限、持久数据或协议变更。
  • 回滚 / 降级方式:回退本提交即可,不需要数据迁移;但旧版的跨块异常零值会重新出现。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档(算法边界注释与 PR 复现说明)
  • 已确认测试结果或说明未执行原因

Signed-off-by: Dash <125997726+dashhuang@users.noreply.github.com>
@dashhuang
dashhuang requested a review from a team as a code owner September 5, 2026 11:00
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T11:04:04.445134Z ab89b9f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 修复了连续音频块重采样时跨块插值读取负索引的问题,并让 AudioWorklet 与 ScriptProcessor 回退路径使用一致的前一块末样本状态。

  • 两条采集路径均保存上一音频块的最后一个样本。
  • 录音状态重置时同步清除跨块样本和分数位置。
  • 新增覆盖多种采样率、分块方式、尾包与录音重启的共享回归矩阵。
  • 未发现由本次变更引入的可操作问题。

Confidence Score: 5/5

此 PR 看起来可以安全合并,跨块插值和录音重置在两条采集路径中保持一致,未发现阻塞性或非阻塞性问题。

新状态保存的是跨块插值所需的直接相邻样本,可达索引范围与实现吻合;各录音生命周期会清除该状态,新增测试也覆盖了上下采样、不规则分块、尾包和重启隔离。

Important Files Changed

Filename Overview
apps/desktop/src/renderer/voice-input/WebMicAudioEngine.ts 为 ScriptProcessor 回退重采样保存上一块末样本,并在停止录音时清除该状态。
apps/desktop/src/renderer/voice-input/pcm16k-worklet.js 修正 Worklet 跨块插值的负索引读取,并将新增状态纳入录音重置流程。
apps/desktop/src/renderer/voice-input/tests/audioResampling.test.ts 为两条采集路径新增共享回归矩阵,以离线连续插值结果验证波形、尾包和状态隔离。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[连续输入音频] --> B{采集路径}
    B -->|AudioWorklet| C[Worklet 分块重采样]
    B -->|ScriptProcessor 回退| D[Renderer 分块重采样]
    C --> E[使用 previousSample 处理跨块插值]
    D --> E
    E --> F[累积 PCM16 输出]
    G[录音停止或重启] --> H[清除 pending、carry 与 previousSample]
    H --> C
    H --> D
Loading

Reviews (1): Last reviewed commit: "fix(voice-input): 修复跨音频块重采样的异常零值" | Re-trigger Greptile

@MagicLizi MagicLizi added touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示) labels Sep 6, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/voice-input/WebMicAudioEngine.ts / apps/desktop/src/renderer/voice-input/pcm16k-worklet.js)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码重审通过:跨音频块重采样负索引已用上一块尾样本插值,当前 head 没有 P0/P1,conversation 已 resolve。

@MagicLizi
MagicLizi merged commit 43e0324 into main Sep 6, 2026
20 checks passed
@MagicLizi
MagicLizi deleted the dash/fix-voice-resample-boundary branch September 6, 2026 02:55
@MagicLizi

Copy link
Copy Markdown
Contributor

合了。跨音频块那一下负索引会插出一串零,听感上像吞字;现在用上一块尾样本接着插,这块不用再猜。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants