Files
controller-v2/AI_FIR_INTEGRATION.md
2026-10-30 17:40:13 +08:00

3.5 KiB
Raw Permalink Blame History

AI FIR 分析、确认上传与 A/B

前端 x8-controller 与后端 luxsin-ai-v2 需要一起部署。仅更新前端时,旧 AI 服务不会调用新增工具。开发代理增加了 GET 支持,更新后需重启 Vite。

操作

进入 AI 页面点击“分析当前 FIR”,发送问题。AI 使用 get_current_fir,浏览器顺序读取设备 GET /dev/info.cgi?action=fir&channel=left 和 right。支持每耳 8191/8192 个有限 float32 小端系数,两个声道长度必须一致。JSON、错误页、NaN、长度异常拒绝解析,不使用房间库作为设备实际数据的替代。

模型收到本次快照标识、抽头数、双耳峰值及位置、能量、系数和(DC)、尾部能量占比。原始数组留在浏览器;不把数万系数交给模型手工重写。采样率未知就保持未知,不从系数推断房间信息或主观好坏。

用户给出听感目标后,模型调用 propose_fir 提交受限的调整参数及解释。程序基于当前快照生成两耳数组,不上传设备。AI 页面卡片展示建议和“确认并上传双耳数据”。

确认后重新读取设备,若与分析快照不同则拒绝应用。先将 A 原始/B 优化的完整 float32 字节保存在 localStorage(按设备 MAC 分开,hex 编码保留包括负零在内的原始位模式),验证写入成功,再依次 POST 左、右。最后 GET 回读两耳并逐样本核对后才显示成功。

随后 A/B 按钮分别重新上传原始/优化两耳,不调用 fir_enable,不更改开关或音量。每次上传会禁用重复操作。失败保留备份并显示双耳状态未确认,允许显式重新上传 A 或 B;不自动重试、回滚或假定部分上传是原子操作。重开页面不会把缓存中的最后状态当作当前设备状态。

浏览器备份只保留每台设备最近一次确认的 A/B 对。清除浏览器数据、更换浏览器或访问源(localhost 与局域网地址不同源)会丢失/隔离备份。未确认的新建议只在当前 AI 页面内存中保留,不保存为后端聊天记录。

当前 DSP 范围

  • 两耳共同增益衰减:-12 至 0 dB,不放大。
  • 尾部衰减:-24 至 0 dB;从双耳较晚的主峰之后使用共同的线性 dB 包络,末抽头达到目标衰减。
  • 平滑:0 至 1,将原系数与因果三抽头 [0.25, 0.5, 0.25] 平滑混合。高频减弱,有最多一个样本的群延迟,末尾两样本滤波尾巴截断;不改变总抽头数。

左右耳使用同一套参数及共同包络,不各自归一化或移动主峰。保留左右耳时序关系;平滑会改变响应,不能声称频率相关的双耳线索完全不变。这不是任意频响校正、房间重建或延长混响算法。需要这些功能时,AI 应解释当前限制,而不能声称已经实现。

验证

前端:node --test scripts/ai-fir.test.mjs scripts/fir-*.test.mjs scripts/eq-save-regression.test.mjs scripts/festival-regression.test.mjs,以及 TypeScript、modern/legacy 构建。

后端:python -m pytest -q,新增 tests/chat/test_fir.py 覆盖 schema、工具返回、确认边界、历史快照失效。测试环境使用项目基准 SQLModel 0.0.38、Anthropic 0.91.0;最新 SQLModel 0.0.48 对原有无时区 datetime 的存储行为有兼容差异。

真实设备只读验证 GET:HTTP 200,Content-Type application/octet-stream,32768 字节。浏览器上传和 A/B 验证使用模拟设备,未改写真实设备。实际 AI 模型联调需启动/部署带新增工具的后端并配置有效模型凭证。