Skip to content

fix: 修复高采样率播放欠载与音频输出稳定性问题 - #309

Merged
imsyy merged 5 commits into
devfrom
feat/fix-pipewire-playback
Sep 22, 2026
Merged

imsyy merged 5 commits into
devfrom
feat/fix-pipewire-playback

Conversation

@imsyy

@imsyy imsyy commented Sep 22, 2026

Copy link
Copy Markdown
Member

改动类型

  • 缺陷修复(fix)
  • 重构 / 优化(不改变对外行为)

是否包含破坏性变更

  • 否

改动说明

修复 Linux PipeWire 播放高采样率音频时可能出现的周期性卡顿,并改善 Windows WASAPI 独占输出在系统高负载下的稳定性。

主要改动:

  • 根据实际输出设备格式调整解码缓冲容量,避免高采样率音频快速耗尽缓冲
  • 修复 PipeWire 节点变化时可能重复重建输出流的问题
  • 调整音频输出线程调度和 Windows WASAPI 独占缓冲策略,降低高负载下的调度欠载
  • 按模块拆分解码、DSP、元数据、输出设备和播放器绑定代码
  • 补充 PipeWire、WASAPI、解码器、设备监听和播放竞态测试
  • 增加 PipeWire 测试脚本及 Linux CI 覆盖

Issue 中已确认:b9dfbd07 可以复现,更新到修复提交 951b872b 后不再复现。

关联 Issue

Closes #304

测试情况

  • Windows 共享模式和 WASAPI 独占模式实机播放测试通过
  • Windows 高负载播放测试通过
  • Linux PipeWire 高采样率测试通过
  • Rust Windows 测试通过
  • Rust Linux 测试通过
  • Windows 和 Linux Clippy 检查通过
  • 原生模块集成测试通过
  • pnpm typecheck 通过
  • ESLint 和 Prettier 检查通过

自查清单

  • 本 PR 只包含音频输出稳定性修复及其必要的结构整理
  • 已在本地完整测试并审阅
  • 已运行格式、类型和 lint 检查
  • 已完成原生模块构建验证,类型声明由 NAPI-RS 生成
  • 已向 dev 分支提交

Copilot AI balanced review requested due to automatic review settings September 22, 2026 10:17

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

MTA 初始化失败仍继续执行任务,且无条件限幅会改变未启用 DSP 时的音频输出。

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

修复 Issue #304 的高采样率音频欠载,并提升 PipeWire、WASAPI 输出稳定性,同时重组原生音频引擎模块。

Changes:

  • 按输出格式调整缓冲、重采样及 PipeWire 流属性。
  • 引入 WASAPI 独占线程调度、PCM 转换和设备恢复策略。
  • 拆分解码、DSP、输出、绑定及测试模块,补充跨平台回归测试。
File Description
scripts/​test-pipewire.sh 增加隔离 PipeWire 集成测试脚本
native/​audio-engine/​tests/​load-races.cjs 覆盖加载取消与替换竞态
native/​audio-engine/​src/​tests/​wasapi.rs 增加独占输出高负载测试
native/​audio-engine/​src/​tests/​scanner.rs 迁移扫描器测试
native/​audio-engine/​src/​tests/​pipewire.rs 增加多采样率输出测试
native/​audio-engine/​src/​tests/​mod.rs 注册跨模块测试
native/​audio-engine/​src/​tests/​fixtures.rs 提供音频测试夹具
native/​audio-engine/​src/​tests/​error.rs 迁移错误分类测试
native/​audio-engine/​src/​tests/​decoder.rs 验证重采样与 seek
native/​audio-engine/​src/​source.rs 删除旧样本读取模块
native/​audio-engine/​src/​scanner.rs 外置扫描器测试
native/​audio-engine/​src/​priority.rs 增加 Windows MMCSS 调度
native/​audio-engine/​src/​player/​transition.rs 更新重构后的模块引用
native/​audio-engine/​src/​player/​tests/​mod.rs 迁移播放器测试
native/​audio-engine/​src/​player/​mod.rs 接入新解码和输出模块
native/​audio-engine/​src/​player/​events.rs 更新缓冲类型引用
native/​audio-engine/​src/​player/​background.rs 增加欠载诊断
native/​audio-engine/​src/​output/​wasapi/​tests/​pcm.rs 验证 PCM 转换
native/​audio-engine/​src/​output/​wasapi/​tests/​mod.rs 验证独占回退分类
native/​audio-engine/​src/​output/​wasapi/​tests/​format.rs 验证多声道格式
native/​audio-engine/​src/​output/​wasapi/​pcm.rs 实现 WASAPI PCM 填充
native/​audio-engine/​src/​output/​wasapi/​format.rs 实现独占格式协商
native/​audio-engine/​src/​output/​thread.rs 增加常驻 MTA 工作线程
native/​audio-engine/​src/​output/​tests/​pipewire.rs 验证 PipeWire 属性
native/​audio-engine/​src/​output/​tests/​device.rs 验证设备选择逻辑
native/​audio-engine/​src/​output/​tests/​cpal_stream.rs 验证流错误分类
native/​audio-engine/​src/​output/​playback.rs 统一播放流控制
native/​audio-engine/​src/​output/​pipewire.rs 配置 PipeWire 流属性
native/​audio-engine/​src/​output/​mod.rs 建立统一输出抽象
native/​audio-engine/​src/​output/​device.rs 重构设备枚举与协商
native/​audio-engine/​src/​output/​device_watcher/​windows.rs 外置 Windows 监听测试
native/​audio-engine/​src/​output/​device_watcher/​unsupported.rs 增加不支持平台后端
native/​audio-engine/​src/​output/​device_watcher/​tests/​windows.rs 迁移 Windows 监听测试
native/​audio-engine/​src/​output/​device_watcher/​tests/​mod.rs 迁移通用监听测试
native/​audio-engine/​src/​output/​device_watcher/​tests/​linux.rs 迁移 Linux 监听测试
native/​audio-engine/​src/​output/​device_watcher/​mod.rs 外置监听器测试
native/​audio-engine/​src/​output/​device_watcher/​macos.rs 格式整理
native/​audio-engine/​src/​output/​device_watcher/​linux.rs 外置 Linux 测试
native/​audio-engine/​src/​output/​cpal_stream.rs 实现 CPAL 流及错误恢复
native/​audio-engine/​src/​metadata/​tests/​tag_fields.rs 迁移标签字段测试
native/​audio-engine/​src/​metadata/​tests/​mod.rs 迁移元数据测试
native/​audio-engine/​src/​metadata/​tests/​lyrics.rs 迁移歌词测试
native/​audio-engine/​src/​metadata/​tests/​folder_cover.rs 迁移文件夹封面测试
native/​audio-engine/​src/​metadata/​tests/​editor.rs 迁移标签编辑测试
native/​audio-engine/​src/​metadata/​tests/​cover.rs 迁移封面测试
native/​audio-engine/​src/​metadata/​tag_fields.rs 外置标签字段测试
native/​audio-engine/​src/​metadata/​mod.rs 外置元数据测试
native/​audio-engine/​src/​metadata/​lyrics.rs 外置歌词测试
native/​audio-engine/​src/​metadata/​folder_cover.rs 外置文件夹封面测试
native/​audio-engine/​src/​metadata/​editor.rs 外置编辑器测试
native/​audio-engine/​src/​metadata/​cover.rs 外置封面测试
native/​audio-engine/​src/​lib.rs 重组顶层模块结构
native/​audio-engine/​src/​error.rs 外置错误测试
native/​audio-engine/​src/​dsp/​tests/​tempo.rs 迁移变速测试
native/​audio-engine/​src/​dsp/​tests/​loudness.rs 迁移响度测试
native/​audio-engine/​src/​dsp/​tests/​limiter.rs 增加多声道限幅测试
native/​audio-engine/​src/​dsp/​tests/​fft.rs 扩展 FFT 并发测试
native/​audio-engine/​src/​dsp/​tests/​equalizer.rs 扩展多声道均衡器测试
native/​audio-engine/​src/​dsp/​tempo.rs 更新 DSP 接入说明
native/​audio-engine/​src/​dsp/​mod.rs 建立 DSP 模块入口
native/​audio-engine/​src/​dsp/​loudness.rs 外置响度测试
native/​audio-engine/​src/​dsp/​limiter.rs 增加输出限幅器
native/​audio-engine/​src/​dsp/​fft.rs 避免音频线程等待 FFT 锁
native/​audio-engine/​src/​dsp/​equalizer.rs 外置均衡器测试
native/​audio-engine/​src/​decoder/​tests/​source.rs 覆盖欠载和启动缓冲
native/​audio-engine/​src/​decoder/​tests/​reader.rs 验证双重采样器声道
native/​audio-engine/​src/​decoder/​tests/​processing.rs 验证 DSP 处理链
native/​audio-engine/​src/​decoder/​tests/​mod.rs 覆盖解码线程异常
native/​audio-engine/​src/​decoder/​tests/​buffer.rs 覆盖缓冲容量和并发
native/​audio-engine/​src/​decoder/​source.rs 实现回调级欠载恢复
native/​audio-engine/​src/​decoder/​reader.rs 拆分读取与重采样逻辑
native/​audio-engine/​src/​decoder/​processing.rs 增加后台 DSP 管线
native/​audio-engine/​src/​decoder/​mod.rs 编排解码与 DSP 线程
native/​audio-engine/​src/​decoder/​buffer.rs 改为按时长背压的无锁队列
native/​audio-engine/​src/​bindings/​player/​types.rs 拆分 NAPI 类型
native/​audio-engine/​src/​bindings/​player/​seek.rs 拆分异步 seek 流程
native/​audio-engine/​src/​bindings/​player/​mod.rs 建立播放器绑定入口
native/​audio-engine/​src/​bindings/​player/​load.rs 拆分异步加载流程
native/​audio-engine/​src/​bindings/​player/​events.rs 拆分事件与设备监听绑定
native/​audio-engine/​src/​bindings/​player/​controls.rs 拆分播放控制绑定
native/​audio-engine/​README.md 说明新架构和测试方式
native/​audio-engine/​package.json 增加集成测试命令
native/​audio-engine/​index.d.ts 刷新生成的原生类型声明
native/​audio-engine/​Cargo.toml 增加队列及实时调度依赖
Cargo.lock 锁定新增依赖
.github/​workflows/​test.yml 增加 PipeWire CI 测试

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

thread::Builder::new()
.name("audio-mta-worker".into())
.spawn(move || {
let _ = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) };
.lock()
.process_interleaved(&mut chunk.player_samples);
if tempo.lock().is_bypass() {
limiter.process(&mut chunk.player_samples, channels);

/// 音频播放器,通过 napi-rs 暴露给 Node.js
#[napi]
pub struct AudioPlayer {
@imsyy
imsyy merged commit 5ffe144 into dev Sep 22, 2026
8 of 9 checks passed
@imsyy
imsyy deleted the feat/fix-pipewire-playback branch September 22, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linux PipeWire 播放高采样率音频可能一卡一卡

3 participants