# Slidesong 本地配乐库

三首简洁器乐伴奏完全由本站脚本程序编曲、原生 Node.js 合成 PCM WAV，再由本机 FFmpeg 编码为 MP3。没有下载、采样、导入或转写外部音乐、录音、音色库、MIDI 或已知旋律；没有调用外部 AI/音频接口。旋律事件、和弦、配器、力度与固定随机种子均可在脚本中查看。

- **Quiet Light**（`quiet-light`，D major）：柔和电钢琴、稀疏泛音、圆润低音与缓入氛围和弦；16 小节的安静乐句。
- **Warm Days**（`warm-days`，G major）：柔和拨弦、错落分解和弦、轻低音与低音量沙锤；24 小节，末段减奏收束。
- **Small Celebrations**（`small-celebrations`，C major）：明亮但柔和的电钢琴、切分和弦、低音、轻底鼓与木质敲击；24 小节主题加 4 小节尾声。

## 声音来源与节拍

电钢琴以不同衰减的谐波和轻微非整数泛音合成；拨弦以较快衰减的多谐波合成；氛围和弦用微失谐叠加振荡器；低音用基音和低次谐波；轻打击用合成扫频、木质共振和固定种子的滤波噪声。短延迟叠加产生空间感，不使用外部混响脉冲。各声部有不同节奏、声像、力度和段落动态，母带有高低频整理及峰值余量。

均为 4/4，首拍位置为 **0 秒**，所有事件按固定 BPM 网格排布；音色本身有数毫秒防爆音起音，没有前置空白。末段减奏、最后一小节回到主和弦，末拍余音做余弦衰减。没有拉伸速度、改变 BPM、附加拍外尾巴或剪短完整小节。首尾接近零，可按完整乐句重复；循环会听到一次乐句收束再起，不是持续不变的无缝鼓点。

MP3 写入 TBPM、BEAT_OFFSET=0、TIME_SIGNATURE=4/4、LOOP_START=0、LOOP_END（每声道 PCM 样本数）和 LOOP_UNIT=sample。Xing/LAME 标签保留编码器延迟与尾部填充信息。`duration` 严格使用 ffprobe 的容器实测值，可能比整数小节对应的音乐长度多约一帧；支持 gapless 的解码器会去掉编码填充。本次 FFmpeg 解码样本数与完整小节完全一致。循环/拍点应使用解码后的音频长度和 BPM，不能把容器填充当作额外节拍。

## 本站用户使用

Slidesong 允许本站用户将这三首随站提供的伴奏用于自己在本站导出的视频，并发布、分享这些视频。该说明仅涉及这三首程序生成伴奏，不覆盖用户上传的音乐、图片或其他内容；不宣称第三方商业音乐授权、独家版权、Content ID 资格或免除所有发布渠道的权利审查。未进行全曲库相似性检索。

## 生成与复核

在项目 app 目录运行（本次使用 Node.js v24.22.1，需要 PATH 中已有 ffmpeg 和 ffprobe）：

```powershell
node scripts/create-slideshow-music.mjs
node scripts/create-slideshow-music.mjs --verify
```

默认命令生成三首 MP3、更新 `src/lib/slideshow/music.ts` 及本说明。临时 16-bit WAV 在 `public/music/` 内创建，编码/检查后删除；不保留大体积中间文件。`--verify` 只读检查已有 MP3 和客户端目录数据，不重新生成。固定种子使 PCM 可复现；不同 FFmpeg 版本的编码字节和容器时长可能略有不同。未指定 ID 或未知 ID 的 `getMusicTrack` 返回 `undefined`。元数据模块没有 Node、服务器、凭据或音频合成依赖。

单首手动复核（将 ID 换成其余曲目）：

```powershell
ffprobe -v error -show_streams -show_format -of json public/music/quiet-light.mp3
ffmpeg -hide_banner -nostdin -i public/music/quiet-light.mp3 -af volumedetect -f null -
```

## 本次实际检查

编码器：ffmpeg version 8.1.1-full_build-www.gyan.dev Copyright (c) 2000-2026 the FFmpeg developers。三首均确认仅有一个 MP3 音频流、44,100 Hz、双声道、128,000 bit/s，每首低于 1,000,000 字节。下表时长、大小和音量来自实际成品；max/mean 为 FFmpeg volumedetect 的 dBFS。

| ID | BPM | 小节 | 解码音乐秒数 | ffprobe 秒数 | 字节 | max dBFS | mean dBFS |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| quiet-light | 72 | 16 | 53.333333 | 53.333333 | 854670 | -3.9 | -20.4 |
| warm-days | 96 | 24 | 60.000000 | 60.000000 | 961248 | -4.4 | -19.4 |
| small-celebrations | 120 | 28 | 56.000000 | 56.000000 | 897310 | -4.1 | -19.4 |

另将每首完整解码为 Float32 PCM：检查样本数等于 BPM/小节网格、无非有限值及满刻度样本、有真实立体声差异和秒级动态；检查前 10 ms 有起音、后 10 ms 衰减及循环边界样本跳变量。

| ID | 每声道样本数 | 首 10ms RMS dBFS | 尾 10ms RMS dBFS | 首尾最大跳变 | L-R RMS dBFS | 中段秒级 RMS 范围 dB |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| quiet-light | 2352000 | -22.2 | -134.7 | 4.78e-5 | -32.1 | 15.2 |
| warm-days | 2646000 | -21.3 | -120.9 | 5.00e-6 | -30.8 | 8.0 |
| small-celebrations | 2469600 | -16.8 | -114.6 | 4.92e-4 | -32.9 | 5.0 |

已完成上述程序测量；未进行真人听测、外部上传或发布渠道检测。数值检查不能替代对音色、编曲与实际视频混音的听感判断。
