跳转至

P_dsp.A21.F3-phase-module-algorithm · XiLink Phase Module DSP 算法层 + dspalgo_dll export

Worker:ClaudeB(DSP · dsp_algo 独立仓主 worktree) · 部门:DSP+P_dsp · 预计:2.0d · 优先级:P0 · 状态:dispatched · isolation:🧵 file(dsp_algo 独立仓 master · 与 F1 frontend / F5 transfer 算法 文件正交并行)

🔍 触发与解锁链

触发:用户 2026-06-13 09:55 提 5 点新需求 #4(xilink 新增 phase 分析 module · 类 fft 多通道相位)· 12:51 拍板 accept ADR-21 · 14:15 拍板 start F1+F3+F5 三连。

用户原话(verbatim · ADR-21 §1.1):

"4. xilink 中缺少 phase 分析的 module · 需要新实现;主要功能是显示所有通道的 phase · 类似 fft 的功能"

架构契约(ADR-21 §3.3 业务契约 5 必填段全填): - 输入:N 通道 PCM(ChannelBuffer · sampleRate)· controls(channelMask / fftSize / windowFunction / averaging / displayMode wrapped/unwrapped/groupDelay) - 输出:MeterFrame_Phase(freqs Hz / phaseWrapped[ch][bin] ° / phaseUnwrapped[ch][bin] ° / groupDelay[ch][bin] ms / averagedCount / resolution / timestamp) - 算法:FFT + atan2(im, re) wrapped phase · numpy.unwrap unwrapped · groupDelay = -d(phase)/d(omega) - 三层分工:L1 算法库(本任务)· L3 前端零数学(F4)

解锁链(本任务 zombie 后): - F4 phase-module 前端 ready(blocked-by-F1+F3 · 等 F1 dock host 也 zombie 后 ClaudeA 1.5d) - F7 e2e ≥ 15 case 真值断言(blocked-by-F2+F4+F6)

任务定义(基于 ADR-21 §3.3)

子任务 ① · phase_module.c + .h 算法实装(1.0d)

Step 1.1:NEW dsp_algo/modules/phase_module.h(仿 rms_module.h f4785b1 标本): - 函数声明: - int phase_module_init(int fftSize, const char* windowFn) - int phase_module_process(const char* nodeId, const int* channelMask, int channelCount, MeterFrame_Phase* outFrame) - int phase_module_destroy(void) - 类型:MeterFrame_Phase(若 dsp_algo 已有则复用 · 否则 NEW · 字段对齐 ADR-12 §3.4 / ADR-21 §3.3 ①) - typeId:PHASE_MODULE_TYPE_ID = 0x100E0004(承接 F7 0x100E0001~3 序列)

Step 1.2:NEW dsp_algo/modules/phase_module.c: - 算法核心: 1. 从 BuiltinLinkRegistry 查 nodeId 节点 · 取 input port samples(N 通道 × fftSize) 2. 应用 windowFunction(hann / hamming / blackman · 默认 hann) 3. FFT(复用现有 dsp_algo/fft.c 或 KissFFT · 同 F7 c099772 fft_module 路径) 4. 每通道每 bin:phaseWrapped = atan2(imag, real) · degrees = rad * 180 / π · clamp [-180, 180] 5. phaseUnwrapped:numpy.unwrap 等价 C 实装(检测相邻 bin 差 > π 时减 2π · ≤ -π 时加 2π · 累积) 6. groupDelay:-(phase[i+1] - phase[i]) / (freqs[i+1] - freqs[i]) / (2π) · 单位 ms · 边界用 0 填充 7. averaging(none / rms / exp · 仿 F7 fft_module 实装):exp 用 EWMA · rms 用 sqrt(mean(x²)) - 严守探针架构铁律:只读节点 input port samples · 不修改主链路数据(同 F7 c099772 铁律) - 失败回退(ADR-21 §3.3 ③): - RMS < -90dBFS:phase 输出 NaN(前端识别为 "Signal too weak") - PCM NaN:跳过该帧 + log_warn - Unwrap 高噪 jump:fallback 到 wrapped(displayMode 字段标记) - groupDelay 信号无主频:置 null(channelCount × binCount 全 NaN)

Step 1.3:每通道并行:支持 8 通道并行 · CPU < 30%(ADR-21 §3.3 ② 性能基线)

子任务 ② · dspalgo_dll.c 加 phase export(0.3d)

Step 2.1:dsp_algo/dll/dspalgo_dll.c 加 export 函数(仿 F7 c099772 analysis_module_get_* 模式): - __declspec(dllexport) int phase_module_get_phase(const char* nodeId, const int* channelMask, int channelCount, int fftSize, const char* windowFn, const char* displayMode, const char* averaging, MeterFrame_Phase* outFrame) - 参数与 F4 前端 P/Invoke 签名严格一致(F4 prompt 起草前通过 ADR-21 §3.3 ① 锁定) - 返回 0 = 成功 · -1 = nodeId 不存在 · -2 = channelMask 越界 · -3 = fftSize 不合法 · -4 = windowFn 不识别

Step 2.2:仿现有 source_/sink_ + analysis_module_* export 模式(F7 c099772 line 138-141 引用)

Step 2.3:dsp_algo/dll/dspalgo_dll.h 同步加函数声明

子任务 ③ · CMake 集成 + 注册修复(0.3d)

Step 3.1:dsp_algo/modules/CMakeLists.txtphase_module.c 源文件 Step 3.2:dsp_algo/dll/CMakeLists.txt 链接 phase_module · 编入 dspalgo_dll.dll Step 3.3:dsp_algo/include/module_type_id.hPHASE_MODULE_TYPE_ID = 0x100E0004(承接 F7 RMS/SCOPE/FFT 序列) Step 3.4:dsp_algo/include/modules_config.hDYNCHAIN_ENABLE_PHASE(默认 ON) Step 3.5:cmake build · dumpbin /exports dspalgo_dll.dll | grep phase_module · 1 export 在 Step 3.6:CMake build 0 errors · 不破坏 F7 c099772 已锁基线(rms/scope/fft 3 module + 502 passed)

子任务 ④ · 单元测试(0.4d)

Step 4.1:NEW dsp_algo/tests/test_phase_module.c(仿 F7 c099772 test_analysis_modules.c 模式): - Case 1:1kHz sine · phaseWrapped@1kHz std < 5°(ADR-21 §3.3 ② 算法稳定基线) - Case 2:sweep 0-22kHz · phaseUnwrapped 单调(无 ±360° 跳变) - Case 3:4ms 延时 fixture · groupDelay 平均值 ≈ 4ms ± 0.2ms(ADR-21 §3.3 ② 延时检测精度) - Case 4:8 通道并行 · 不同 phase shift(0° / 45° / 90° / ...)· 每通道独立计算正确 - Case 5:RMS < -90dBFS 信号 · phase 输出 NaN(失败回退) - Case 6:Unwrap 高噪信号 · fallback wrapped + displayMode 字段标记

Step 4.2:cmake test 全过 · 不破坏 dsp_algo 现有 502 passed / 6 pre-existing failed 基线(零回归)

完整 prompt(直接复制粘贴 ClaudeB 终端)

[U-thread] P_dsp.A21.F3-phase-module-algorithm · ADR-21 §3.3 phase-module DSP 算法层 + dspalgo_dll export
[部门] DSP+P_dsp
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/dsp_algo/
[Occupies] P_dsp.K-phase-module + P5.K-dspalgo-dll
[优先级] P0(2.0d · phase 算法 + dll export · 与 F1 frontend / F5 transfer 算法 文件正交并行)
[ADR] docs/08-implementation/40-aios/ADR/ADR-AIOS-21-xilink-dock-and-analysis-modules.md(必读 §3.3 + §1.4 三层分工铁律)
[isolation] file(dsp_algo 独立仓 master · 与 F1/F5 文件正交)

⚠️ 重大铁律(F7 c099772 v4 教训沉淀):
**dsp_algo 是独立 git 仓库**(不是 04_development 子目录)· 必须 `cd 04_development/dsp_algo && git ...` 在 dsp_algo 仓 master branch 操作
不要在 04_development 主仓 commit 本任务 · 否则真值核查会 fatal: Needed a single revision

[参考文档绝对路径]
  - 业务契约:ADR-21 §3.3 完整 5 必填段(① PhaseModuleManifest + MeterFrame_Phase 接口 / ② 算法精度阈值 / ③ 5 类失败回退 / ④ 5 步操作流 / ⑤ playwright e2e groupDelay 4ms ± 0.2ms 真值断言)
  - 用户 2026-06-13 09:55 拍板原话(ADR-21 §1.1 #4):xilink phase 分析 module · 类 fft 多通道相位
  - 范式 commits(worker 必读 · 用 `git -C 04_development/dsp_algo log --oneline` 查):
    * c099772 P_dsp.A18.F7 analysis-algorithms zombie 最末态(rms/scope/fft 3 module 完整实装 · dll export 模式 · CMake 集成 · 单测 · 严守探针架构 · 本任务直接仿其结构)
    * 209cc8d F7 主体 commit(rms_v1 0x100E0001 + scope_v1 0x100E0002 + fft_v1 0x100E0003 · 1024-point radix-2 + Hann · 本任务 phase_v1 = 0x100E0004 承接序列)
    * 1556c99 F7 注册修复(module_type_id.h + modules_config.h + dynchain_core.h MAX_PORTS 8→16 · 本任务复用此基础)
    * 161fbf9 P_dsp.A17.F5 LogModule DSP 落盘 · BuiltinLinkRegistry 节点查询方式参考
  - 现状参考(用 `git -C 04_development/dsp_algo show HEAD:dsp_algo/...` 查):
    * dsp_algo/modules/rms_module.h + .c(F7 c099772 · 本任务仿其结构)
    * dsp_algo/modules/scope_module.c(F7 · 探针架构标本)
    * dsp_algo/modules/fft_module.c(F7 · FFT 算法标本 · 1024-point radix-2 + Hann · 本任务直接复用其 FFT 实装)
    * dsp_algo/dll/dspalgo_dll.c + .h(F7 · analysis_module_* export 模式 · 本任务加 phase_module_get_phase)
    * dsp_algo/include/module_type_id.h(F7 · typeId 序列 0x100E0001~3 · 本任务加 0x100E0004)
    * dsp_algo/include/modules_config.h(F7 · DYNCHAIN_ENABLE_* 开关 · 本任务加 ENABLE_PHASE)
    * dsp_algo/tests/test_analysis_modules.c(F7 · 单测模式标本 · 本任务仿写 test_phase_module.c)
    * dsp_algo/dynchain_core.h(F7 commit 1556c99 · MAX_PORTS=16 · 本任务不改)
  - 三层分工:ADR-07 §1.3.4 · ADR-21 §1.4 铁律(L1 算法库 = 本任务 · L3 前端零数学 = F4)

[文件正交策略](.clinerules §任务隔离类型分配准则 v1.4):
  isolation: file · dsp_algo 独立仓 master · 与 F1 frontend / F5 transfer 文件正交
  本任务文件:dsp_algo/modules/phase_module.{c,h} + dsp_algo/dll/dspalgo_dll.{c,h}(加 export)+ CMakeLists + tests/test_phase_module.c + include/module_type_id.h(加 PHASE)+ include/modules_config.h(加 ENABLE_PHASE)
  F1 文件:frontend_vue3/src/stages/xilink/dock/* + composables/useChainNodeMetadata.ts(完全正交 · 不在 dsp_algo 仓)
  F5 文件:dsp_algo/modules/transfer_module.{c,h} + tests/test_transfer_module.c + dll export 加 transfer(同 dsp_algo 仓 · 但不同 module 文件 · 仅在 dspalgo_dll.c 共享 · 用 git rebase 解决)
  完全正交 · F5 仅 dspalgo_dll.c 与本任务有 merge 点(本任务先 commit · F5 后 rebase)

【背景】
  用户 2026-06-13 09:55 提 5 点新需求中 #4:xilink 需要 phase 分析 module · 类 fft 显示所有通道相位。
  ADR-21 accepted 2026-06-13 12:51 · 7 fork 13d · 本任务 F3 是 DSP 算法层(L1 算法库)· F4 前端等 F1+F3 全 zombie。
  ADR-18 F7(c099772)已落地 rms/scope/fft 3 个 module + dspalgo_dll export · 本任务直接仿其结构加 phase_module(typeId 0x100E0004 承接序列)。
  与 F1 dock host(frontend_vue3 · ClaudeA)+ F5 transfer 算法(同 dsp_algo · 同 ClaudeB)文件正交 · 三线并行起跑。

【架构关键约束】
  ⚡ dsp_algo 是独立 git 仓库(F7 v4 教训沉淀):必须 `cd dsp_algo` 后 commit · 不在 04_development 主仓
  🎨 phase_v1 typeId = 0x100E0004(承接 F7 RMS 0x...01 / SCOPE 0x...02 / FFT 0x...03)
  📋 输出 frame schema 必须复用 ADR-12 §3.4 / ADR-21 §3.3 ① MeterFrame_Phase(字段不变 · 不重写)
  📋 探针架构铁律(F7 承接):**只读节点 input port samples · 不修改主链路数据**
  📋 三层分工(ADR-21 §1.4):L1 本任务 · L3 F4 前端零数学 · 不在 P7 sidecar
  ⚡ F3 范围与下游边界:本 F3 仅 DSP 算法 + dll export · **不实装前端 vue 组件**(那是 F4 范围 · 等 F1+F3 全 zombie)
  ⚡ FFT 算法直接复用 F7 fft_module.c 已实装的 1024-point radix-2(不重造)· 仅在其上加 phase = atan2(im, re) + unwrap + groupDelay

【执行步骤】
  Step 0 · 文件注入真值核查(强制门槛 · F2 教训承接 · F7 v4 dsp_algo 独立仓教训)
    - cd 04_development/dsp_algo · 确认在 dsp_algo 独立仓
    - git -C 04_development/dsp_algo log --oneline -10 · 确认 c099772 / 209cc8d / 1556c99 在 master
    - git -C 04_development/dsp_algo show c099772:dsp_algo/modules/fft_module.c | head -100 · 学习 F7 fft 实装
    - git -C 04_development/dsp_algo show c099772:dsp_algo/dll/dspalgo_dll.c | grep "analysis_module_get" · 学习 export 模式
    - git -C 04_development/dsp_algo show 1556c99:dsp_algo/include/module_type_id.h · 确认 typeId 序列
    - 留 commit log:Step 0 三层核查记录(grep / read / git show 全)

  Step 1 · phase_module.h + phase_module.c 算法实装 1.0d(子任务 ①)
    - phase_module.h:函数声明 + MeterFrame_Phase 类型(若 dsp_algo 已有复用)+ typeId 0x100E0004
    - phase_module.c:核心算法 6 步(BuiltinLinkRegistry 查节点 → window → FFT 复用 fft_module → atan2 wrapped → unwrap → groupDelay)
    - averaging:none / rms / exp(EWMA)· 仿 F7 fft_module
    - 失败回退 5 类(信号过弱 / NaN PCM / Unwrap 失败 / groupDelay 不稳 / channelMask 全关)
    - 严守探针架构(只读 input port · 不调任何 set_*)
    - 8 通道并行 · CPU < 30%(性能基线)

  Step 2 · dspalgo_dll.c 加 phase export 0.3d(子任务 ②)
    - phase_module_get_phase 签名(8 参数:nodeId/channelMask/channelCount/fftSize/windowFn/displayMode/averaging/outFrame)
    - 仿 F7 analysis_module_get_rms/scope/fft 模式
    - dspalgo_dll.h 同步加声明
    - 错误码 -1/-2/-3/-4(nodeId/channelMask/fftSize/windowFn)

  Step 3 · CMake 集成 + 注册修复 0.3d(子任务 ③)
    - modules/CMakeLists.txt + dll/CMakeLists.txt 加源文件链接
    - module_type_id.h:PHASE_MODULE_TYPE_ID = 0x100E0004
    - modules_config.h:DYNCHAIN_ENABLE_PHASE(默认 ON)
    - cmake build 0 errors · dumpbin /exports dspalgo_dll.dll | grep phase 验证 1 export 存在
    - F7 c099772 基线零回归(rms/scope/fft + 502 passed)

  Step 4 · 单元测试 0.4d(子任务 ④)
    - NEW test_phase_module.c · 6 case(详见任务定义子任务 ④ Step 4.1)
    - cmake test 全过 · 502+6 = 508 passed / 6 pre-existing failed 基线
    - sample-accurate 单测(4ms delay fixture · 48000 Hz · 192 sample 偏移)

  Step 5 · 构建 + 测试 + dll 验证全绿
    - cmake build 0 errors
    - cmake test 全过(基线 + 6 新增 case)
    - dumpbin /exports dspalgo_dll.dll | grep -c "_module_get_" · 4 export 全在(rms/scope/fft + phase)

  Step 6 · F4 联调验收(F4 zombie 后 · 但本任务 zombie 前先做 dll 拷贝准备)
    - 拷贝 dspalgo_dll.dll 到 backend_csharp 输出目录(若 F6 后端 P/Invoke 已就位)
    - F4 dotnet run + npm run dev · 实测 phase-module 弹窗显示 wrapped/unwrapped/groupDelay 3 模式
    - 验 1kHz sine 注入 → phaseWrapped@1kHz std < 5°(ADR-21 §3.3 ② 真值断言)

  Step 7 · commit(在 dsp_algo 独立仓!)
    - cd 04_development/dsp_algo && git add . && git commit -m "feat(dsp_algo/phase): P_dsp.A21.F3 phase-module 算法 + dspalgo_dll export

      用户 2026-06-13 09:55 提 5 点新需求 #4 · 12:51 accept ADR-21 · 14:15 拍板 start F1+F3+F5 三连。
      F3 本任务(ADR-21 §3.3):
      ① phase_module.{c,h}(typeId 0x100E0004 承接 F7 序列 · FFT 复用 fft_module · atan2 wrapped + numpy.unwrap 等价 + groupDelay = -dphi/domega)
      ② dspalgo_dll.c 加 phase_module_get_phase export(8 参数 · 与 F4 P/Invoke 签名一致)
      ③ CMake 集成 + module_type_id.h + modules_config.h 注册(ENABLE_PHASE 默认 ON)
      ④ test_phase_module.c 6 case(1kHz sine std<5° / sweep 单调 / 4ms delay groupDelay ±0.2ms / 8ch 并行 / 信号弱 NaN / unwrap fallback)
      ⑤ cmake build + test 全绿 · F7 c099772 基线零回归(502+6=508 passed)
      解锁 F4 phase-module 前端(等 F1 dock host zombie 后并行启动)

      [step=7/7] [pid=P_dsp] [uid=P_dsp.A21.F3-phase-module-algorithm] [type=fork] [isolation=file]
      [occupies=P_dsp.K-phase-module+P5.K-dspalgo-dll] [files=7] [ipc=none]
      [adr=ADR-AIOS-21 §3.3 phase-module 新增(#4 类 fft 多通道相位)]"
    - git push(dsp_algo master · 不推 04_development 主仓)

【验收】
  ☐ Step 0 文件注入真值核查通过(`git -C dsp_algo log` + `git -C dsp_algo show c099772:fft_module.c` + module_type_id.h 序列确认)
  ☐ Step 1 phase_module.{c,h} 6 步算法 + 5 类失败回退 + 探针架构铁律(只读 input port)+ 8ch CPU < 30%
  ☐ Step 2 dspalgo_dll.c phase_module_get_phase export · dumpbin 验证存在 · 与 F4 P/Invoke 签名一致
  ☐ Step 3 CMake build 0 errors · module_type_id.h PHASE_MODULE_TYPE_ID = 0x100E0004
  ☐ Step 4 test_phase_module.c 6 case 全过(1kHz std<5° / sweep 单调 / 4ms delay ±0.2ms / 8ch 独立 / 弱信号 NaN / unwrap fallback)
  ☐ Step 5 cmake test 全过 · F7 c099772 基线零回归(502 passed → 508 passed)
  ☐ Step 6 dll 拷贝准备完毕(F4/F6 后端 P/Invoke 就位后端到端验证 1kHz std<5°)
  ☐ Step 7 commit 在 dsp_algo 独立仓(用 `git -C dsp_algo`)· 含 7 元组 trailer + ADR §3.3 引用

【禁止】
  ❌ 禁止跳过 Step 0 文件注入核查(F2 教训:派发前必须 grep + read + git show 4 标本)
  ❌ 禁止在 04_development 主仓 commit(F7 v4 教训:dsp_algo 是独立仓 · 必须 `cd dsp_algo` 操作)
  ❌ 禁止重造 FFT 算法(必须复用 F7 fft_module.c 1024-point radix-2 实装 · 仅在其上加 phase 计算)
  ❌ 禁止在 P7 sidecar 实装 phase 算法(三层分工铁律 · L1 算法库 = dsp_algo · 不是 P7)
  ❌ 禁止超前实施 phase-module 前端 vue 组件(那是 F4 范围 · 本 F3 仅 DSP 算法 + dll export)
  ❌ 禁止破坏 F7 c099772 已锁基线(rms/scope/fft 3 module + 502 passed · 零回归是硬门槛)
  ❌ 禁止修改 BuiltinLinkRegistry 接口(只读查询节点 · 不调 set_*)
  ❌ 禁止修改主链路数据(探针架构铁律 · 只读 input port samples)
  ❌ 禁止 commit 缺三元组 trailer(.clinerules v1.6 铁律)
  ❌ 禁止嵌入完整 c 文件 > 60 行(.clinerules v1.6)· 拆 helper 函数

解锁链(本任务 zombie 后)

  • ✅ phase_module 算法层完成 · dspalgo_dll.dll 含 phase_module_get_phase export
  • ✅ MeterFrame_Phase frame schema 锁定(对接 F4 前端消费)
  • ✅ F4 phase-module 前端 ready(blocked-by-F1+F3 · 等 F1 dock host 也 zombie 后 ClaudeA 1.5d)
  • ✅ F7 e2e ≥ 15 case 真值断言可起草(blocked-by-F2+F4+F6 · 但本任务 4ms delay 单测真值已锁)

风险评估

风险 缓解
dsp_algo 独立仓 commit 误推到 04_development 主仓(F7 v4 教训复发风险) Step 7 显式 cd dsp_algo + git -C dsp_algo · prompt 多次警示 + commit message 明示 isolation:file + dsp_algo 独立仓
FFT 算法不复用导致重造轮子(性能 + 维护成本) Step 1 强制 read F7 fft_module.c · 只在其上加 phase = atan2(im, re) · 不重写 FFT 主体
numpy.unwrap C 实装易错(高噪信号 phase jump) 单测 Case 6 覆盖高噪 fallback · 主算法用最小实装(检测 ±π 跳变累积 ±2π)· 失败时切 wrapped 模式
groupDelay 4ms 延时检测 sample-accurate 困难 用 48000 Hz · 4ms = 192 sample 整数偏移夹具 · -dphase/domega 数值梯度法 + 平均值容差 ±0.2ms
8 通道并行 CPU > 30% 复用 F7 fft_module 已优化的 SIMD/threading · 单测 8 通道 CPU 测量 · 若超则降级 channelCount 限流(commit 内说明)
与 F5 transfer-module 共享 dspalgo_dll.c 文件冲突 F3 先 commit dspalgo_dll.c phase export · F5 后 rebase + 加 transfer export · git merge 顺序协议
ClaudeB 排队膨胀(本 F3 2.0d + F5 2.5d 串行 4.5d) F3 与 F5 文件正交 · ClaudeB 同 worktree 串行(F3→F5)· 总 4.5d 用户预期 2-2.5 周可接受
MeterFrame_Phase schema 与 ADR-12 §3.4 字段不一致 Step 1.1 read ADR-12 §3.4 line 750-768 严格对齐字段名 · 不私自重命名

历史

时间 事件 hash
2026-06-13 14:16 dispatched(用户 14:15 拍板 start F1+F3+F5 三连 · ClaudeB DSP 算法层 2.0d · dsp_algo 独立仓)