本地音频剪辑与混音 · A SMALL AUDIO ROOM
==============================

打开 index.html 即进入完整工作台，全部运行资源内嵌。

第一次使用
1. 点播放，试听默认的原创合成音乐示例。
2. 点击一段波形选择，拖中间移动、拖边缘裁切。下面可以精确输入开始位置、原音取段、音量、淡入和淡出，再点“应用片段参数”。
3. 点击时间尺移动播放线；可在播放线处分割，复制或删除片段。两条轨道中的重叠片段都会相加发声。
4. 点“导入自己的音频”载入录音或音乐。WAV 的 PCM16/24/32、Float32 单/双声道会直接读取；其他格式由浏览器 decodeAudioData 解码，支持范围依设备而定。原文件不会被改写。
5. 点击导出 WAV 带走真正的混音音频；章节 CSV 和波形 PNG 是辅助交付。保存完整方案 JSON 才能恢复素材与所有编辑。

完整范围
- 2 条轨道、6 段素材、16 个可编辑片段、40 个章节标记。
- 单段素材最长 90 秒、单文件 24 MB；素材总长 120 秒，时间线最长 180 秒。全部解码采样合计上限 48 MiB，高采样率素材会先触及此上限，以确保导出的完整方案落在 70 MiB 载入范围内。
- 输出 44.1 kHz 双声道 PCM16 WAV；单声道素材复制到两个声道，不同采样率使用线性插值。
- 名称、轨道、位置、原音起止、增益、淡入淡出、静音均进入方案与撤销记录。
- 最多保留36次文档历史，重复载入大量新音频会按96 MiB历史资源预算淘汰最旧记录，当前文档和紧邻的上一步保留。
- 一次拖动只记一项撤销；取消拖动恢复原状。完整导入先验证再替换，可撤销载入。
- 完整方案将用户解码后的 Float32 采样内嵌；默认原创音色按固定版本参数恢复，没有外部文件地址。
- 小方案尝试完整暂存；大音频不会仅保存失去声音的文档壳，而会提示手动保存完整方案。暂存受浏览器策略限制，不能代替备份。

快捷键
空格：播放/暂停。左右：播放线 ±0.1 秒，Shift 加速。Alt+左右：移动所选片段。Ctrl/Cmd+Z：撤销，加 Shift 重做。Delete：删除所选片段。在输入框内不抢占文字编辑快捷键。

声音与计算
默认示例为本作品原创程序合成的短音符和延伸和声，不含人声、网络采样或第三方音乐。波形来自真实音频采样。峰值为采样峰值，不是 LUFS 或真峰值响度计。超过满刻度的输出会削波；“把峰值留在 −1 dBFS”调整总音量，受可用增益范围限制。没有降噪、语音识别、压缩器或自动作曲等未实现按钮。

实际验证
从最终 HTML 提取同一个 AppModel 与 Artwork，核对混音、脉冲移位、单声道转双声道、线性淡化、连续分割、超幅饱和、完整 JSON 采样回读、非法导入和空项目。使用 Python wave 独立解析导出的 WAV，确认 2 声道、44100 Hz、16 bit、20.5 秒、904050 帧；CSV 使用独立解析器读取。默认、修改后、空项目、导出图均来自实际 Canvas 路径并已完整解码。
制作环境未进行浏览器整页/真实鼠标键盘/设备音频输出/首次断网双击验收。同源波形和文件核对不能代替实际试听。打开后需要用户点击才能播放声音。

来源与许可
Web Audio decodeAudioData 与一次性 AudioBufferSourceNode 生命周期参考 MDN：
https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData
https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode
WAVE 格式参考 Microsoft：
https://learn.microsoft.com/en-us/windows/win32/api/mmeapi/ns-mmeapi-waveformatex
字体为 Noto Sans CJK SC Regular 的文字子集，重命名 Audio Sans，依 SIL OFL 1.1 内嵌；完整许可在 HTML 的“作品信息”中。来源：https://github.com/notofonts/noto-cjk/tree/main/Sans

示例结果位于随包的作品证据目录，包括 WAV、章节 CSV 与可重新载入的完整方案；普通使用不需要运行制作方验证脚本。

分割与淡化：分割点对齐输出采样帧，保留原音对应的淡化曲线；再设淡入/淡出会在原曲线上叠加。所选片段出现“重设淡化”时可清除保留曲线，重新开始设置。移动、再次分割、保存/载入都保留该关系。拖动开始会取消尚未完成的素材读取，避免旧异步覆盖正在编辑的方案。
