# 算法、数值约定与验证

MoonStretch 独立实现经典的波形相似重叠相加（WSOLA）与带限重采样。
它没有调用 SoundTouch、Rubber Band 或浏览器的变速算法，也不承诺复现这些实现的逐采样输出。

## 两级组合

令用户设置的半音数为 `s`，`p = 2^(s/12)`。内部先以 `tempo / p` 做 WSOLA 时间伸缩，再以 `p * rate` 做播放速率转换：

```text
交织 PCM -> WSOLA(tempo / p) -> 带限速率转换(p * rate) -> 交织 PCM
```

两级时长倍率相乘后为 `1 / (tempo * rate)`；WSOLA 保留目标音高，后一级把频率乘以 `p * rate`。所以移调可以不改变最终时长。两级内部比率均在 `0.25..4` 范围，覆盖公开参数的全部组合。

## WSOLA

当前实现每次合成约 20 ms 的输出，保留另一段 20 ms 的重叠尾部，并在理论分析位置两侧各约 10 ms 搜索相似波形。所有声道参与同一次归一化相关计算并共享偏移；不会把立体声先相加成单声道，因此反相信号也有有效的对齐信息。

搜索先使用稀疏采样定位候选区间，再在附近逐帧用完整重叠区计算。相同分数优先选择接近理论时钟的位置，避免对周期信号反复选择同一侧导致长期时间漂移。理论位置由累计输出帧数与固定 tempo 决定，不由上次搜索胜出的偏移继续累积。

相关计算先按共享峰值缩放，避免大幅度有限采样的平方溢出。公共输入同时限制采样绝对值不超过 `1e100`，为各阶段浮点运算留出余量。重叠部分采用互补线性权重。处理器仅保留未来窗口可能访问的输入及当前尾部；终止时使用零延拓完成有限录音的最后一个窗口。恒等 tempo 路径直接复制输入，不做窗口处理。

## 带限速率转换

重采样核是归一化的 Blackman 窗 sinc。下采样时降低截止频率并扩大输入窗口，减弱超过新奈奎斯特频率的分量。当前实现使用 512 个分数相位区间，并在相邻系数表之间插值；中心位置使用 `Int64` 整数帧加一个小的分数相位，避免把整条录音的位置存成越来越大的浮点数。

滤波器半径为 `ceil(48 * max(1, ratio))`，截止系数为 `0.9 / max(1, ratio)`。这是有过渡带的有限 FIR，不是理想砖墙滤波器。比率为 1 时使用精确直通路径。处理器前后边界采用端点延拓，并在 `finish()` 后释放 PCM 历史。

## 精确输出帧数与生命周期

两级分别取整可能产生少量末尾差异。组合流保留少量待输出帧，最终统一到 `floor(N / (tempo * rate) + 0.5)`；必要时重复最后一帧补足取整差值，不能用此机制填补整个缺失窗口。尾部处理不是“补零到目标长度”来伪装变速，事件时间和频率还有独立验证。

`push()` 每次返回已经可用的 PCM，`finish()` 排空有限尾部；参数在一条流内固定。`reset()` 清空状态并保留配置。内部输入按短块处理，历史缓冲不随录音长度线性增长。

`buffered_frames()` 统计保留的 PCM，不是进程总内存：它不计调用方保留的输入/输出、返回数组、运行时开销或固定滤波器系数表。高比率下系数表最多约 20 万个 Double。CLI 的文件接口仍然读取并返回完整文件，不能据此宣称整个 CLI 使用恒定内存。

`latency_frames()` 是算法前瞻预算，不含文件解码、浏览器任务、声卡或其他宿主延迟。实现会分配数组，尚未建立硬实时线程的零分配或执行时限保证。

## 怎么验证

MoonBit 回归测试检查构造参数、空/短音频、通道布局、状态重置、重复结束、非法输入、分块不变性和两个 DSP 阶段。独立的 Python 脚本不导入 MoonBit 算法，其验证包括：

- 根据控制参数独立计算输出帧数，并检查每个采样为有限值；
- 用插值过零点测量解析正弦信号的实际频率，允许相对误差 1.5%；
- 检查反相立体声相消、不同声道的不同频率和恒等变换样本；
- 比较不同分块的最终输出，并要求首次输出出现在结束操作之前；
- 比较不同录音长度的保留 PCM，以及三个已知声音事件的时间位置；
- 测量下采样通带与阻带测试音的 RMS，防止简单抽点产生混叠。

可选 SoundTouch 对照通过独立可执行程序处理同样的测试音，检查物理时长和频率性质，而不是要求不同算法的波形相等。CI 保存实际数值和阈值；没有执行的环境不算作已通过。

这些解析信号与合成事件不构成主观音质数据集。密集复音、打击乐和极端拉伸可能出现抖动、拖尾或瞬态变形；移调没有共振峰保持，也不会自动音高校正。没有盲听或真实硬件吞吐量数据时，不宣称优于成熟音频引擎或适合所有音乐制作任务。

## 理论资料

- Werner Verhelst、Marc Roelands，1993：[An Overlap-Add Technique Based on Waveform Similarity (WSOLA) for High Quality Time-Scale Modification of Speech](https://doi.org/10.1109/ICASSP.1993.319366)。
- Marc Roelands、Werner Verhelst，1993：[Waveform similarity based overlap-add (WSOLA) for time-scale modification of speech: structures and evaluation](https://www.isca-archive.org/eurospeech_1993/roelands93_eurospeech.html)。
- Julius O. Smith：[Windowed Sinc Interpolation](https://www.dsprelated.com/freebooks/pasp/Windowed_Sinc_Interpolation.html)，*Physical Audio Signal Processing*。

以上资料用于说明算法来源，不包含论文、书籍正文或参考实现源码的复制。代码与外部工具的许可证关系见 [THIRD_PARTY.md](../THIRD_PARTY.md)。
