# 映射方法
## 你会学到什么
- 把数列映射到音阶、时值、力度、声像和效果参数。
- 使用 `pulse.map_to_scale` 和 `pulse.normalize`。
- 让算法输出保持音乐性,而不是变成随机噪声。
- 在不同音乐角色中选择不同映射策略。
## 适合谁读
如果你已经能生成数字,但听起来很乱,读本章。生成式音乐的关键不是“生成”,而是“映射”。
## 前置知识
- [生成器目录](generators.md)
- [音乐理论](../01-lua-composition/theory.md)
## 心智模型
映射就是把抽象值放进音乐边界。音高需要落在某个音阶和八度内;时值需要落在可听节奏范围;力度和声像需要有上限;滤波参数需要避免极端刺耳。
最常用的两个工具:
```lua
pulse.map_to_scale(values, "major_pentatonic", "C4", 2)
pulse.normalize(values, 0.125, 0.5)
```
前者把数值映射到音阶,后者把任意数值压缩到指定范围。
## 最小可运行例子
```lua
local pulse = require("pulse")
local raw = pulse.generate("van_der_corput", { length = 16, base = 2 })
local notes = pulse.map_to_scale(raw, "minor_pentatonic", "A3", 2)
local durations = pulse.normalize(raw, 0.125, 0.375)
local line = pulse.sequence()
:notes(notes)
:durations(durations)
:instrument("electric_piano")
:volume(0.32)
pulse.song():add(line):export_wav("output/mapping.wav", { normalize = "rms" })
```
## 参数和边界
`map_to_scale(values, scale, root, octaves)` 中,`scale` 可以是 `major`、`minor`、`major_pentatonic`、`minor_pentatonic`、`harmonic_minor`、`blues`、`chromatic`、`whole_tone` 或希腊调式。`root` 是音名,`octaves` 控制音域宽度。
`normalize(values, min, max)` 要求输入非空,并且 `max > min`。时值常用 `0.125..0.5`,velocity 常用 `0.35..0.8`,pan 常用 `-0.4..0.4`,低通 cutoff 可以从 `1200..4200` 开始。
## 常见陷阱
音域太宽会让旋律像乱跳。新手建议 `octaves = 1` 或 `2`,五声音阶比七声音阶更稳。
时值太短会像电流声。大量 `0.01` 秒级事件会制造密集瞬态,导出再标准化也不好听。
把同一数列同时映射到音高、时值、velocity、pan 会让所有参数同向变化,听感反而机械。可以只映射音高和时值,其他手写或用另一个序列。
## 进阶用法
可以将数列分层使用:斐波那契控制旋律级数,Van der Corput 控制时值,欧几里得控制鼓点。每层只承担一个职责,最终会比单一复杂生成器更可控。
滤波参数也适合生成,但要限制范围:
```lua
local cutoff = pulse.normalize(raw, 1800.0, 3600.0)
```
当前 API 不自动把每个 cutoff 写入逐音自动化,你可以用它生成多个 sequence,每段使用不同 filter 参数。
## 相关章节
- [生成配方](recipes.md)
- [序列、乐句与编排](../01-lua-composition/arrangement.md)
- [效果链](../02-sound-design/effects.md)
- [Lua API](../06-reference/lua-api.md)