# 《三小时》 N°05

把三小时压进三分钟：一分钟一个时辰。

**听法**：戴耳机，音量调低，让它自己走。全曲只有一个动机，在三个时辰里被移调、倒影、增值、逆行，第二遍才认得出是同一句。首尾各留了一点静默，循环播放不会跳一下。页面默认不自动播放——按一下播放键，或者直接点某一段跳过去。

## 概念

| 时间 | 时辰 | 在做什么 |
|---|---|---|
| 00:00–01:00 | 子夜 | 稀疏、单音、大量留白。水滴与远处钟声，铺底只在最底下呼吸 |
| 01:00–02:00 | 破晓 | 琶音开始流动，第二个声部进入，和声一层层变暖，滤波器慢慢打开 |
| 02:00–03:00 | 黎明 | 同一个动机增值、倒影、展开，最后解决到主音，混响在原处响了很久 |

## 技术

**合成**（Python 3.11 + numpy，逐样本手写，无采样、无网络、无第三方音频库）

- **钟声**：非谐分音 `1 : 2 : 2.76 : 4.07 : 5.40 : 8.93 : 13.34`，每个分音独立指数衰减（高次分音衰得更快），每个分音再叠一对 ±1.7 cent 的微失谐副本产生缓慢拍音，附极短滤波噪声作敲击瞬态。
- **拨弦**：Karplus-Strong 延迟线。小数延迟用线性插值，环路内为可调权重的两点平均低通（`damp`），环路增益由目标 T60 反解，并对环路低通在基频处的损耗做补偿——实测调音误差 < 0.4 cent。分块向量化：块长取 ≤ 延迟，块内所有读取都落在已算好的样本上，因此无需逐样本循环。
- **铺底**：每音 3 个 ±6.5 cent 失谐副本 × 7 次谐波（幅度 1/h^1.3），叠加 27 秒周期的极慢呼吸；整条铺底总线再做一次**一极点低通扫频**（截止 230 Hz → 4400 Hz → 2600 Hz），实现方式是分段 LTI + FFT 精确卷积，兼顾真实扫频与向量化速度。
- **混响**：Schroeder —— 4 并联梳状（反馈 0.945，约 5 s 尾）+ 2 串联全通，左右声道延迟不同以去相关；湿声按 RMS 归一到干声的 32%。

**作曲**

- 60 BPM，1 拍 = 1 秒，1 小节 = 4 秒，45 小节 = 180 秒。三个时辰正好各 15 小节，分界落在 60 s / 120 s 整点。
- 调式：D 多利亚（D E F G A B C），和声为 `Dm7 – G – Fmaj7 – Cadd9` 的模态循环，不含导音，因此久听不累。
- 动机 **M0 = D4 A4 G4 F4**（上行五度 + 两次下行级进）。全曲只用四种变形：调内移调（+3 级）、以首音为轴的倒影、增值（×1.5 / ×2）、逆行。旋律音永远落在当前和弦音或九音上。
- 配器原则：钟声说主题时，琶音自动让路变稀；琶音音型是平滑的余弦拱形，相邻和弦交替上下行，形成呼吸而不是机械循环。

**母线**：一阶高通去直流 → 峰值归一到 −1 dBFS → 首尾各 1.5 s 升余弦淡入淡出。无 NaN、无削波、无爆音。

**MIDI**：手写字节流，format 1 / PPQ 480 / 60 BPM，轨道 0 为 tempo + 段落标记，轨道 1–3 为钟声 / 拨弦 / 铺底，带 program change、音量、声像。可直接拖进 DAW 继续改。

## 文件

| 文件 | 说明 |
|---|---|
| `index.html` | 播放页。自绘波形、三段刻度、播放/暂停/循环/音量，`file://` 直接打开 |
| `三小时.wav` | 180.0 s / 44100 Hz / 16 bit / stereo / −1 dBFS |
| `三小时.mid` | 4 轨 MIDI 工程 |
| `封面.png` | 1600 × 1600 |
| `src/` | 生成脚本：`synth.py` 合成引擎、`score.py` 作曲与渲染、`midiw.py` MIDI 写入、`cover.py` 封面 |

重新生成：`python src/score.py`（约 27 秒），`python src/cover.py`。
