跳转至
DRAFT

AudioEngine · /api/audio/signal-stats/history

AI 生成 · 待 owner review

本文档由 DocAgent S1 模式自动生成(spec-first · 代码尚未实现,文档作为施工蓝图)。status: draft,owner 工程师 review 通过后请把 status 改为 published,并删除 frontmatter 中的 generated_by 字段。

实现待对齐

本文档描述的 endpoint 尚未实现。代码完成后需在季度架构评审中对比文档与实际实现,如有偏差按 doc-code-sync-policy.md §3.5 漂移容忍窗口 处理。

1. 背景与目标

1.1 背景

现有 /api/audio/signal-stats(见 LegacyTestRoutes.cs:41-55)只返回实时瞬时快照(单点):isRunning / readCount / exceptionCount / rmsDbfs / lastStopReason / wasapiRunning / lastExceptionType / lastExceptionMessage

前端调音工具需要绘制最近 N 秒的 RMS 曲线来诊断"播放是否中断 / 音量起伏",当前只能让前端自己以 100ms 间隔轮询并在前端缓存历史。这有 3 个痛点: - 前端首次进入页面时无历史(看不到刚才发生的事) - 网络抖动会丢点 - 前端崩溃 / 刷新会丢失整个历史

1.2 目标

  • 在后端维护一个固定容量的环形缓冲(默认 600 个采样点 × 100ms = 60 秒),记录每次 GetSignalStats() 调用的瞬时统计
  • 暴露 /api/audio/signal-stats/history?seconds=N&downsample=K 供前端按需拉取
  • 端到端延迟:返回 < 50ms(纯内存查询,无 IO)

1.3 非目标

  • 不做持久化(进程重启后历史清零)
  • 不做多客户端订阅(前端直接 HTTP 轮询 1 次拿到全部历史即可,不需要 WebSocket / SSE)
  • 不做多通道分别统计(本期只统计混合后的 RMS dBFS,后续可扩展)

2. 数据流图

flowchart LR
    A[WASAPI Capture]:::xyL1 --> B[AudioEngineService<br/>读 PCM 帧]:::xyL3
    B --> C[计算瞬时 RMS dBFS]:::xyL3
    C --> D[SignalStatsCollector<br/>环形缓冲 600 点]:::xyL3
    D --> E["/api/audio/signal-stats<br/>(单点 · 现有)"]:::xyL3
    D --> F["/api/audio/signal-stats/history<br/>(时间序列 · 本次新增)"]:::xyL3
    F --> G[前端绘制 RMS 曲线]:::xyL4

    classDef xyL1 fill:#5DDECF,stroke:#5DDECF,color:#000
    classDef xyL3 fill:#D4A574,stroke:#D4A574,color:#fff
    classDef xyL4 fill:#C77DFF,stroke:#C77DFF,color:#fff

3. 接口契约

3.1 输入参数

字段 类型 必填 默认 说明 示例
seconds int (query) 60 拉取最近 N 秒的历史(范围 [1, 60]) ?seconds=10
downsample int (query) 1 降采样因子(每 K 个原始点取 1 个,用于减少前端绘制压力) ?downsample=5

3.2 输出 Schema

{
  "ok": true,
  "data": {
    "windowSeconds": 60,
    "downsample": 1,
    "samplePeriodMs": 100,
    "count": 600,
    "samples": [
      { "tMs": -59900, "rmsDbfs": -23.12, "readCount": 12345, "exceptionCount": 0, "wasapiRunning": true },
      { "tMs": -59800, "rmsDbfs": -22.87, "readCount": 12349, "exceptionCount": 0, "wasapiRunning": true },
      ...
    ]
  }
}
字段 类型 说明
data.windowSeconds int 实际返回的时间窗口(可能 < seconds 入参,若历史不足)
data.downsample int 实际生效的降采样因子
data.samplePeriodMs int 原始采样间隔(ms · 由 AudioEngine 决定 · 默认 100)
data.count int samples 数组长度
data.samples[].tMs int 相对当前时刻的偏移(ms · 负数表示过去)
data.samples[].rmsDbfs number 该时刻的 RMS dBFS(2 位小数)
data.samples[].readCount long 累积读取计数
data.samples[].exceptionCount long 累积异常计数
data.samples[].wasapiRunning bool 该时刻 WASAPI 是否在跑

3.3 异常码

HTTP Code Error Code 含义 处置建议
400 INVALID_SECONDS seconds 超出 [1, 60] 范围 调整入参
400 INVALID_DOWNSAMPLE downsample < 1 或 > 60 调整入参
503 STATS_NOT_READY AudioEngine 尚未启动,环形缓冲为空 先调 /api/audio/start,再轮询本接口

4. 时序

sequenceDiagram
    participant FE as Frontend
    participant API as /api/audio/signal-stats/history
    participant SVC as SignalStatsCollector
    participant ENG as AudioEngineService

    Note over ENG,SVC: 后台线程:每 100ms 调一次<br/>SVC.Push(rmsDbfs, readCount, ...)
    ENG->>SVC: Push(s_t)
    ENG->>SVC: Push(s_{t+100})
    ENG->>SVC: Push(s_{t+200})

    FE->>API: GET ?seconds=10&downsample=2
    API->>SVC: GetHistory(window=10s, ds=2)
    SVC-->>API: samples[] (50 points)
    API-->>FE: 200 OK + JSON

5. 关键决策

设计哲思

环形缓冲在后端,绘制在前端 —— 这是 Xisound 调音工具的一贯模式。后端不绘制不渲染,只暴露原始数据;前端按需拉取并用 Canvas/WebGL 高效绘制。这种"数据-视觉解耦"让后端 API 永久稳定,前端可以独立迭代曲线样式而不动后端。

参见相关 ADR:ADR-08.20.NNN(待新建,关于环形缓冲容量决策) (实施时由 DocAgent 用 ADR 模板生成)

6. 验收标准

  • SignalStatsCollector 单元测试覆盖率 ≥ 90%(含环形覆盖、降采样边界、空缓冲)
  • 端到端延迟 P99 < 50ms(纯内存)
  • seconds=60 + downsample=1 时返回 600 点,数组正确按时间升序
  • AudioEngine 未启动时返回 503 + STATS_NOT_READY
  • 不引入新的内存分配热点(环形缓冲预分配,Push 不 new 对象)
  • mkdocs build 0 ERROR / 0 新增 WARN

7. 测试验证(代码完成后填写)

测试类型 路径 说明
Unit AlgoDepartment/04_development/backend_csharp/TuningTool.Backend.Tests/Services/SignalStatsCollectorTests.cs (代码未完成,待对齐)覆盖 Push/GetHistory/降采样/边界
Integration AlgoDepartment/04_development/backend_csharp/test/integrationtest/SignalStatsApi/ (代码未完成,待对齐)起 AudioEngine + WASAPI loopback,跑 5 秒后 GET history,断言 ≥ 45 点

8. 影响面(代码完成后填写)

  • 调用方:前端调音工具 frontend_vue3 的 RMS 曲线组件(待新增)
  • 兼容性:Non-breaking(新增 endpoint,不动现有 /api/audio/signal-stats)
  • 迁移指引:N/A(新功能)

9. Changelog

版本 日期 改动
0.1.0 2026-05-13 首版 spec-first(DocAgent 基于 LegacyTestRoutes.cs:41-55 现状 + 假想增强生成)