Meter 架构框架图 v0.2
XiLink + XiTest 实时模式 + XiTune 三 Stage 统一视图 · 双链路 + RuntimeTarget 路径选择 + 节点可观察性矩阵
版本: v0.2 · 2026-06-18 15:50
用户拍板锚点: 2026-06-18 12:30(双链路矩阵 + RuntimeTarget 改造)+ 15:45(log_module 修正 + xitest/xitune 延展)
用途: ADR-AIOS-26 起草前的可视化框架基线 · 后续派发 agent 沉淀为正式产品文档
双链路图例:
链路 1 dspalgo C 实时
链路 2 pysidecar Python
UI 仅
v0.2 修正(对比 v0.1):
- ❌ 右侧 Dock 不再含 log_module 独立节点 → ✅ log_module 改为"各 Meter Dock 内部追踪链路中所有 log_module 实例"的横切能力
- ❌ 交互 C "双击 log_module 看 wav 离线分析" → ✅ 双击 log_module = 弹出落盘类型选择(audio log wav / text log)· 不展示分析 UI
- ➕ 新增图 3:XiTest 实时模式 meter 路径(设备/source/sink 相关全走 pysidecar)
- ➕ 新增图 4:XiTune meter(与 XiLink 几乎一致 · 复用同一套链路 1+2)
📌 核心约束 5 条(给 ADR-26 锚定用)
| # | 约束 | 用户原话 |
| 1 | 链路中间 meter 探针永远走链路 1(dspalgo C) | "链路内的节点还是需要 meter 探针来抓取" |
| 2 | 右侧 Dock 大部分走链路 2(pysidecar) | "右侧 dock 中大部分应该走的 sidecar" |
| 3 | 右侧 Dock 仅 4 类可观察节点:source / sink / 输入设备 / 输出设备(不含 log_module 独立节点) | "右侧 dock 不会有专门的 log module" |
| 4 | log_module 是横切能力:在各 Meter Dock 内追踪链路中所有 log_module 实例 → 选某个 → 用其 wav 做对应分析(rms/fft/phase/scope/transfer) | "在不同的 dock 中可以追踪 link 中的所有 log module · 来在对应的 dock 中显示这个 log module 的 wav 文件" |
| 5 | DSP 模式 source/sink 隐藏;log_module 落盘永远可用(因为 wav/text 文件始终落盘) | "DSP 模式那 source 和 sink 就不可获取" |
图 1 · 顶层 Flowchart:RuntimeTarget 路径选择(XiLink 左侧 Dock 改造)
flowchart TD
Start([用户进入 XiLink Stage]) --> LeftDock[左侧 Dock]
LeftDock --> ConnDock[🔌 连接 Dock
底层 DSP 通信]
LeftDock --> ResMon[📊 资源监控 Dock
★ 原右侧 指标监控 迁移过来]
ConnDock --> ConnChoice{选择连接类型}
ConnChoice -->|★新增 native| NativeMode[CPU 模式分支]
ConnChoice -->|DSP hardware| DspMode[DSP 硬件模式分支]
ConnChoice -->|simulator| SimMode[PC Simulator 分支]
NativeMode --> NativeSubChoice{native 子模式}
NativeSubChoice -->|纯 CPU| PureCpu[source 走 CPU 合成]
NativeSubChoice -->|VDSP 虚拟 DSP| Vdsp[source 走 DSP 算法栈]
PureCpu --> ResTargetCpu[资源监控 target 池
CPU0 / CPU1 / CPU2 / CPU3]
Vdsp --> ResTargetVdsp[资源监控 target 池
VDSP0 / VDSP1 / VDSP2 / VDSP3]
DspMode --> ResTargetDsp[资源监控 target 池
真实 DSP 硬件 core]
SimMode --> ResTargetSim[资源监控 target 池
simulator slot]
ResTargetCpu --> EngineLoad[AudioEngineService
RuntimeKind.PcNative]
ResTargetVdsp --> EngineLoad
ResTargetDsp --> EngineLoad2[AudioEngineService
RuntimeKind.DspHardware]
ResTargetSim --> EngineLoad3[AudioEngineService
RuntimeKind.PcSimulator]
EngineLoad --> ChainReady([链路加载完成
进入 Meter 双链路])
EngineLoad2 --> ChainReady
EngineLoad3 --> ChainReady
ResMon -.读取.-> ResTargetCpu
ResMon -.读取.-> ResTargetVdsp
ResMon -.读取.-> ResTargetDsp
style NativeMode fill:#e1f5e1
style Vdsp fill:#fff4cc
style ResMon fill:#ffe1e1
style ConnChoice fill:#cce5ff
图 2 · 中层 Flowchart:Meter 双链路并存(XiLink · v0.2 修正版)
flowchart LR
subgraph UI[前端 UI 层]
ChainCanvas[XiLink 链路画布
用户拖拽 meter module]
RightDock[右侧 Dock
4 类可观察节点]
MeterDocks["★ Meter Dock 集合
FFT/RMS/Phase/Scope/Transfer
含 log_module 追踪器"]
Popup[弹窗 Popup
FFT/Phase/Transfer/RMS/Scope]
end
subgraph Chain1["🔴 链路 1 · dspalgo C 实时探针"]
FanOut[fan-out tap
1in 1out passthrough]
AnalysisMod[analysis modules
fft/rms/phase/scope/transfer
typeId 0x100E0001~5]
Polling[Polling API
dspalgo_dll.h:442]
WsRoute[RealtimeWsRoutes.cs
WebSocket]
end
subgraph Chain2["🟢 链路 2 · pysidecar Python 离线/准实时"]
PcmFork[Backend PCM Fork
SourceSignalService.cs]
WavFile["WAV 文件落地
output/*.wav
(log_module 输出)"]
WasapiCap[WASAPI 直采
设备级]
Sidecar[pysidecar/main.py
FastAPI · numpy/scipy]
HttpRoute[HTTP REST
30+ endpoints]
end
ChainCanvas -->|用户拖 meter module 到链路中| FanOut
FanOut --> AnalysisMod --> Polling --> WsRoute
WsRoute --> ChainCanvas
WsRoute --> MeterDocks
RightDock -->|节点 1: source · 仅 PC 模式| PcmFork
RightDock -->|节点 2: sink · 仅 PC 模式| PcmFork
RightDock -->|节点 3: 输入设备| WasapiCap
RightDock -->|节点 4: 输出设备| WasapiCap
MeterDocks -->|追踪链路中所有 log_module 实例
选某个 → 读其 wav 做对应分析| WavFile
PcmFork --> Sidecar
WavFile --> Sidecar
WasapiCap --> Sidecar
Sidecar --> HttpRoute
HttpRoute --> Popup
HttpRoute --> RightDock
HttpRoute --> MeterDocks
style Chain1 fill:#ffe1e1
style Chain2 fill:#e1f5e1
style FanOut fill:#ffcccc
style Sidecar fill:#ccffcc
style MeterDocks fill:#fff4cc
2.1 节点可观察性矩阵(XiLink 右侧 Dock 在不同 RuntimeKind 下的呈现)
| 右侧 Dock 节点类型 | PcNative / PcSimulator | DspHardware | 所属链路 |
| source 节点 | ✅ 亮(backend fork PCM) | ❌ 隐藏/灰 | 链路 2 |
| sink 节点 | ✅ 亮(backend fork PCM) | ❌ 隐藏/灰 | 链路 2 |
| 输入设备(WASAPI) | ✅ 亮 | ✅ 亮 | 链路 2 |
| 输出设备(WASAPI) | ✅ 亮 | ✅ 亮 | 链路 2 |
2.2 log_module 横切矩阵(在各 Meter Dock 内部追踪 · 不在右侧 Dock)
关键修正: log_module 不是右侧 Dock 的独立节点。它是每个 Meter Dock(FFT Dock / RMS Dock / Phase Dock / ...)内部的横切追踪能力:Dock 扫描当前链路中所有 log_module 实例 → 用户在 Dock 内下拉选择某个 log_module → Dock 用其 wav 文件做对应分析(FFT Dock 做 FFT · RMS Dock 做 RMS · ...)。
| Meter Dock 类型 | 追踪能力 | 分析路径 |
| FFT Dock | 列出链路中所有 log_module → 选 1 个 | 读其 wav → pysidecar /analyze/fft → 频谱图 |
| RMS Dock | 同上 | pysidecar /analyze/rms → 时间序列 RMS / Peak / LUFS |
| Phase Dock | 同上(双通道时启用) | pysidecar /analyze/phase → 相位曲线 |
| Scope Dock | 同上 | pysidecar /analyze/scope → 波形预览 |
| Transfer Dock | 同上(需指定 ref + measure 双 log_module) | pysidecar /analyze/transfer → 传函 |
图 3 · XiTest 实时模式 Meter 路径(★ 新增 · 用户拍板)
用户原话: "xitest 里面的实时模式中所有主界面基本是属于设备和 source / sink 相关的都应该走的是 pysidecar"
→ XiTest 实时模式整体偏向链路 2(pysidecar) · 因为它的核心是设备级与端到端 source/sink 真值采集 · 不是链路内部探针监控。
flowchart LR
subgraph XitestUI["XiTest 实时模式 UI"]
DeviceView[设备主界面
WASAPI 输入/输出]
SourceView[source 主界面
注入信号波形/频谱]
SinkView[sink 主界面
采集结果验证]
XitestMeters["xitest meter 组件
RMSMeter / SpectrumChart
PhaseChart / WaveformChart
FreqResponseChart"]
end
subgraph Chain2["🟢 链路 2 · pysidecar(主路径)"]
WasapiCap2[WASAPI 直采]
PcmFork2[Backend PCM Fork]
WavFile2[wav 落地]
Sidecar2[pysidecar 分析]
HttpRoute2[HTTP REST]
end
subgraph Chain1Limited["🔴 链路 1 · 仅当链路中插了 meter module"]
Tap[fan-out tap
少数场景]
WsLimited[WS frame stream]
end
DeviceView --> WasapiCap2
SourceView --> PcmFork2
SinkView --> PcmFork2
XitestMeters -.可选追踪 log_module.-> WavFile2
WasapiCap2 --> Sidecar2
PcmFork2 --> Sidecar2
WavFile2 --> Sidecar2
Sidecar2 --> HttpRoute2
HttpRoute2 --> XitestMeters
HttpRoute2 --> DeviceView
HttpRoute2 --> SourceView
HttpRoute2 --> SinkView
XitestMeters -.少数实时探针场景.-> Tap
Tap --> WsLimited
WsLimited --> XitestMeters
style Chain2 fill:#e1f5e1
style Chain1Limited fill:#fff4cc
style XitestMeters fill:#bbdefb
3.1 XiTest 实时模式 vs XiLink 路径对比
| 维度 | XiLink(链路设计/调试) | XiTest 实时模式(端到端验证) |
| 主路径 | 链路 1 + 链路 2 并存 | 链路 2 为主 · 链路 1 仅在用户拖 meter module 进链路时启用 |
| 设备/source/sink | 右侧 Dock 4 类节点 + meter module 探针 | 主界面直接展示 · 全走 pysidecar |
| 典型分析对象 | 链路内部信号(中间节点) | 整链路输入输出(端点) |
| UI 复用 | DrawerDock* / ChainCanvas | test-aux/meter/* + xitest stage 主界面 |
图 4 · XiTune Meter(与 XiLink 几乎一致 · 复用同一套基础设施)
用户原话: "xitune 中的 meter 显示相关的和 xilink 几乎一致"
→ XiTune 复用 XiLink 的双链路 + 节点矩阵 + Meter Dock 体系 · 仅业务上下文不同(XiTune 偏自动调音/目标曲线对比 · XiLink 偏链路设计)。
flowchart LR
subgraph Xitune["XiTune Stage"]
TuneUI[调音 UI
目标曲线 + 测量曲线]
TuneMeters["meter 组件
★ 与 XiLink 复用"]
TuneAuto[auto_tune 模块
target_loader / deviation /
simulate / averaging / smoothing]
end
subgraph Shared["共享基础设施(与 XiLink 一致)"]
Chain1Ref["链路 1 · dspalgo C 实时探针
(链路中 meter module)"]
Chain2Ref["链路 2 · pysidecar
(右侧 Dock + log_module 追踪)"]
end
TuneUI --> Chain1Ref
TuneUI --> Chain2Ref
TuneMeters --> Chain1Ref
TuneMeters --> Chain2Ref
TuneAuto -->|HTTP /auto_tune/*| Chain2Ref
style Xitune fill:#f3e5f5
style Shared fill:#e8f5e9
| XiTune 特有 | 与 XiLink 复用 |
| auto_tune 子模块(目标曲线加载/偏差/模拟/平滑) | 双链路架构(链路 1 + 链路 2) |
| FreqResponseChart(频响目标对比) | RuntimeTarget 路径选择 |
| 调音工作流(measure → simulate → apply) | 右侧 Dock 4 类节点矩阵 |
| — | Meter Dock(FFT/RMS/Phase/Scope/Transfer) |
| — | log_module 横切追踪能力 |
图 5 · 三个关键交互 Sequence(交互 C v0.2 修正)
交互 A · 用户拖 fft_module 到链路中(链路 1 · 永远走 dspalgo C)
sequenceDiagram
autonumber
actor U as 用户
participant Canvas as XiLink Canvas
participant Backend as backend_csharp
participant DllInterop as DSPAlgoInterop
participant Algo as dspalgo.dll
fft_module.c
participant WS as RealtimeWs
participant Dock as DrawerDockFft.vue
U->>Canvas: 拖 fft_module 到链路中间
Canvas->>Backend: POST 链路重建(含 fft tap)
Backend->>DllInterop: 加载 typeId 0x100E0002
DllInterop->>Algo: 实例化 fan-out tap
Algo-->>DllInterop: handle 返回
Backend->>WS: 订阅 frame stream
loop 实时(rate-limited)
Algo->>Algo: 就地算 FFT(零拷贝)
Backend->>Algo: poll FftFrame
Algo-->>Backend: FftFrame{bins, peak, ts}
Backend->>WS: push frame
WS->>Dock: WebSocket frame
Dock->>Dock: 渲染频谱(零数学)
end
交互 B · 右侧 Dock 看 source 节点频谱(链路 2 · 仅 PC 模式)
sequenceDiagram
autonumber
actor U as 用户
participant Right as 右侧 Dock
participant Backend as backend_csharp
SourceSignalService
participant Sidecar as pysidecar
analyzer/freq_response
participant Popup as FftModulePopup.vue
U->>Right: 右键 source 节点 → 看频谱
Right->>Right: 检查 RuntimeKind
alt PcNative / PcSimulator
Right->>Backend: GET /source/{id}/pcm-fork
Backend-->>Right: PCM bytes(短窗)
Right->>Sidecar: POST /analyze/fft (HTTP)
Sidecar->>Sidecar: numpy/scipy FFT
Sidecar-->>Right: FftAnalysisResult
Right->>Popup: 展示频谱+峰值
else DspHardware
Right->>U: ⚠️ source 节点不可观察(灰)
end
交互 C · ★ v0.2 修正:双击 log_module = 落盘类型选择(无分析 UI)
v0.2 重大修正: 双击链路上的 log_module 不会展示分析界面。它的核心职责是落盘配置 — 让用户选择落盘的数据类型(audio log wav · text log · 或两者皆开)。分析能力下放到各 Meter Dock 的 log_module 追踪器(见交互 D)。
sequenceDiagram
autonumber
actor U as 用户
participant Canvas as XiLink Canvas
participant LogMod as log_module 实例
participant Dialog as 落盘类型选择 Dialog
participant Backend as backend_csharp
participant FS as 文件系统
output/
U->>Canvas: 双击链路上的 log_module
Canvas->>Dialog: 弹出落盘配置对话框
Dialog->>U: 显示选项
☐ Audio Log (wav)
☐ Text Log (csv/json)
☐ 采样率/位深/通道选择
☐ 文件名模板
U->>Dialog: 勾选 + 确认
Dialog->>Backend: PUT /log-module/{id}/config
Backend->>LogMod: 应用落盘配置
LogMod->>FS: 运行时落盘 wav / log
Note over Dialog,U: ❌ 不展示频谱/RMS/相位等分析 UI
分析交给 Meter Dock 的追踪器
交互 D · ★ 新增:Meter Dock 追踪 log_module 做分析(链路 2)
sequenceDiagram
autonumber
actor U as 用户
participant Dock as FFT Dock
(也可以是 RMS / Phase / ...)
participant Backend as backend_csharp
participant FS as output/*.wav
participant Sidecar as pysidecar
analyzer/freq_response
U->>Dock: 打开 FFT Dock
Dock->>Backend: GET /chain/log-modules
列出当前链路所有 log_module 实例
Backend-->>Dock: [{id, name, file, sr, ch}, ...]
Dock->>U: 显示下拉列表
U->>Dock: 选 log_module #2
Dock->>Sidecar: POST /analyze/fft?file=output/log_2.wav
Sidecar->>FS: 读 wav
Sidecar->>Sidecar: numpy FFT
Sidecar-->>Dock: FftAnalysisResult
Dock->>Dock: 渲染频谱
Note over Dock,Sidecar: 同 Dock 可在多个 log_module 间快速切换
RMS Dock / Phase Dock / Scope Dock / Transfer Dock 同理
📦 三 Stage 统一对照表
| 维度 | XiLink | XiTune | XiTest 实时模式 |
| 主用途 | 链路设计 + 调试 | 自动调音 + 目标曲线对比 | 端到端验证 + 设备级真值 |
| 链路 1 占比 | 高(链路内中间探针主战场) | 中(复用 XiLink 探针) | 低(仅当用户主动插 meter module) |
| 链路 2 占比 | 中(右侧 Dock + log_module) | 中(同 XiLink + auto_tune HTTP) | 高(主界面设备/source/sink 全走) |
| RuntimeTarget UI | ★ 左侧资源监控 Dock + native 选项 | 复用 XiLink | 复用 XiLink |
| 右侧 Dock 节点 | 4 类(source/sink/IN/OUT) | 同 XiLink | 无右侧 Dock(主界面直出) |
| log_module 追踪 | ★ 各 Meter Dock 内追踪 | 同 XiLink | xitest meter 组件可选追踪 |
🚦 落盘后下一步(待用户拍板)
本图通过后 → 起 ADR-AIOS-26-meter-dual-link-runtime-target-tri-stage.md
ADR-26 含:
① 双链路场景矩阵(本图 1 + 图 2)
② RuntimeTarget UI 改造(本图 1 · 左侧资源监控 Dock + native 选项 + CPU0-3/VDSP0-3)
③ log_module 横切追踪契约(本图 §2.2 + 交互 D)
④ XiTest 实时模式 + XiTune meter 路径锚定(本图 3 + 图 4)
⑤ frame schema 单点定义(contracts/ 中 FftFrame/RmsFrame/PhaseFrame/TransferFrame/ScopeFrame)
⑥ 命名规范决议(*_module 链路插件 vs *_widget 历史命名 · 取舍)
⑦ 数据对账 e2e(同节点 dock vs popup 数据 ±0.5dB 一致 · 链路 1 vs 链路 2 一致性)
⑧ §4 实施清单 fork 表(P3 前端 / P5 后端 / P_contracts / P_e2e 派发)