# MoonBinaural项目申报参考书

基于实测HRIR和方向轨迹的离线双耳音频渲染工具

版本：0.3.0 | 主要语言：MoonBit | 许可：Apache-2.0 | 日期：2026-10-31

GitHub账号：btlqql；项目仓库：https://github.com/btlqql/moon-binaural；公共模块：btlqql/moon_binaural@0.3.0。团队身份按本人报名信息填写。

## 一、项目名称与摘要

MoonBinaural用MoonBit将单声道采样、带方向的头相关脉冲响应（HRIR）与采样位置关键帧渲染为左右耳声音。核心包括跨块FIR历史、球面最近测量点选择、共享历史的双滤波器交叉淡化和完整卷积尾部输出。

0.3.0将这些机制连接为动态场景文件流程：输入测量集合、源采样、采样率和方向轨迹，输出完整双耳采样、峰值、超幅统计及可选PCM WAV文件。核心渲染不调用Web Audio、C库或Python音频引擎。

## 二、选题背景与实际使用场景

空间音频原型需要把声音源方向变成两耳不同的滤波响应。仅做左右声道音量平移不包含实测耳部频谱线索；逐块重新启动滤波又会丢失历史，直接换滤波器还可能产生不连续。项目围绕状态连续与可复查离线输出组织实现。

场景一是游戏/XR声音原型：给定源采样和方向关键帧，离线生成双耳片段核对声道变化。场景二是音频算法验证：在任意分块下比较采样与尾部，检查方向切换时旧历史是否仍参与新滤波器。场景三是离线制作：从同一场景文件导出WAV及峰值/超幅报告，发现输出量化前的削波风险。

当前外部数据为实测HRIR，源随机信号和440Hz正弦为合成输入。没有真人定位听测、客户部署或真实头部跟踪设备验证。

## 三、实现范围、参数与处理链

处理链：场景JSON读取 -> 采样率、方向、等长HRIR和关键帧验证 -> 球面最近测量点 -> 分块双耳FIR -> 切换交叉淡化 -> M-1尾部 -> 峰值与超幅计数 -> JSON或16位立体声WAV。

HRIR长度1至4096，左右等长。场景输入最多240000个采样、512个关键帧，N*M不超过64000000；采样率1至192000且源与HRIR必须相同。输入与系数须为有限数、绝对值不超过1e6。源信号与测量值不进行隐式归一化。

## 四、核心算法与工程处理

Renderer使用环形历史保存跨块输入，直接卷积分别计算左右耳；空块不推进时间。构造HRIR时复制输入数组，调用者后续修改原数组不会改变滤波器。process先检查整块合法性再改变流状态。

切换时旧HRIR和新HRIR同时读取相同历史，按指定采样数线性交叉淡化；达到终点后保留新滤波器。过渡未完成时再次切换明确拒绝，避免隐藏改变时间线。关键帧需从0开始、严格递增，后续切换间隔必须容纳前一次淡化。

方向向量归一化后按点积选择球面最近测量点，相同分数取首项。当前是分段测量方向加滤波输出淡化，不把它描述为任意未测方向的HRTF插值。

尾部排空追加M-1个零，并分块处理，因此4096抽头也不会触发单块乘加限额。WAV宿主仅做RIFF/PCM封装和饱和量化，采用排他创建拒绝覆盖；实际渲染、方向选择和峰值计算均由MoonBit完成。

新增Source与render_mix及sources文件输入。最多16个声源，各自持有独立卷积和关键帧状态，支持起点与正负增益；混合后统计峰值/超幅，不在核心静默限幅。

## 五、与相关能力的区别及独立贡献

roomacoustics从房间IR反推混响时间、噪声底和模态；MoonSpectrum提供FFT，MoonWavKit提供音频文件解析。新项目负责源信号到两耳声音的状态化渲染，当前不把WAV解析或FFT重新实现计为独立贡献。

独立贡献是跨块历史、双滤波器共享历史过渡、带方向测量的场景执行、尾部及可复查输出链。HRTF和FIR是成熟技术，未主张发明算法；实测HRIR也明确归属于上游数据，不计作本项目采集成果。

## 六、完整案例与输入输出

案例一：输入单位脉冲和左右短HRIR，在不同块划分下逐采样核对输出及尾部，确认块边界不会重置历史。运行：moon run cmd/main --target js -- examples/impulse.json。

案例二：使用固定Google spatial-media提交中的E35_A45.wav和E35_A-45.wav两份SADIE衍生KU100测量，均为48kHz、256抽头。输入12000个440Hz正弦采样，在位置0、4000、8000设置方向关键帧，淡化64采样。验证时为examples/moving-sadie.json指定新的output路径，导出12255帧双声道WAV（例文件默认只返回JSON采样），峰值约0.09706584，超幅采样数0。

复核脚本另用1200个随机源采样和位置400、800切换，对全部左右采样与尾部逐点核对。已有输出路径再次执行被拒绝且文件字节不变；源与HRIR采样率不同明确失败。示例输出路径在D盘，读取测量和封装音频的Python仅用于开发准备与验证。

新增可复现文件：examples/two-sources.json。双源例左耳输出[1,1.5,0.5]，峰值1.5，左右合计2个超幅采样；合成短音配两份固定实测HRIR的方向轨迹输出12255帧、48kHz立体声。

## 七、正确性验证与独立参考

当前8项MoonBit测试在JS、Wasm、Wasm-GC分别通过，共24次本地测试执行；全目标静态检查与JS CLI构建通过。覆盖跨块卷积、尾部、共享历史切换、方向选择、输入所有权、坏方向、采样率和最大4096抽头排空。

固定实测HRIR静态卷积与独立Python直接卷积最大绝对误差约9.992e-16；动态双测量切换与独立逐采样双卷积/淡化参考最大误差约1.110e-15。后者同时验证12255帧WAV、48kHz双声道元数据、拒绝覆盖和拒绝采样率不符。

数据固定于google/spatial-media提交2308497c39bb604a7c3ba56ac17e302f2b1b6a96；原URL、SHA-256与结果在两份validation JSON中。testdata保留上游LICENSE、NOTICE及README，说明SADIE衍生KU100来源。数值一致性不能证明个体定位准确性或实际听感。

仓库内scripts/verify.py独立验证：两份固定SADIE衍生KU100 HRIR，动态逐采样双卷积/淡化对照误差约1.11e-15；独立多源线性叠加、WAV元数据与排他输出验证。无需父目录或原工作区。

## 八、公开接口、使用与当前边界

API包括Hrir、Renderer::process/transition/drain、Measurement、Direction、Keyframe、select、render_scene、Source与render_mix。库适合嵌入MoonBit离线处理，CLI读取JSON采样和测量，不声称直接导入任意音频文件或SOFA数据库。

当前直接FIR复杂度O(N*M)，过渡期间执行两次卷积；没有分区FFT、重采样、浏览器音频线程或低延迟实时保证。最近测量点与线性输出淡化不能等同于ITD保持的方向插值。drain每次推进时间，不是幂等终止操作；核心输出不自动限幅，导出PCM时才做饱和量化。

## 九、公开交付与复现入口

- GitHub仓库：[https://github.com/btlqql/moon-binaural](https://github.com/btlqql/moon-binaural)。
- MoonCakes模块：[btlqql/moon_binaural@0.3.0](https://mooncakes.io/docs/btlqql/moon_binaural@0.3.0)。
- 主要代码与测试、README、独立验证脚本、来源许可、JSON示例、生成API均在同一仓库。
- [公共CI](https://github.com/btlqql/moon-binaural/actions)包含四后端测试，实际完成状态与安装验证记录在发布核验报告，不预写未发生的运行结论。

GitHub开发历史、公共包发布与比赛报名是不同事项。本项目为AI辅助开发，参赛者负责理解模型、取舍和质量。未代填比赛报名，也没有主办方通过回执。

## 当前公共验证基线

已验证代码提交：b136bdabda11eea5a0ad73dea8d6f05f0bb9d737；[四后端CI](https://github.com/btlqql/moon-binaural/actions/runs/41198987649)已实际完成。三个纯核心可在四后端测试，文件CLI为JS宿主。注册表发布和独立安装状态以配套发布核验记录为准。
