# 音乐理论
## 你会学到什么
- 使用音名、MIDI 音符号和频率互相转换。
- 生成音阶、希腊调式和和弦。
- 用移调复用旋律与和声材料。
- 理解为什么 `mlua-pulse` 的底层音乐材料是频率数组。
## 适合谁读
如果你会写 Lua,但对音名、调式、和弦还不熟,读本章。它只讲项目里会直接用到的理论,不展开传统和声学。
## 前置知识
- [快速开始](getting-started.md)
- [术语表](../00-overview/glossary.md)
## 心智模型
渲染器最终需要频率,所以 Lua API 把 `"C4"`、`"ionian"`、`"maj7"` 这些人类可读的名字转换成频率数组。你可以把乐理 API 当成素材生成器:先得到可用音,再用 sequence 组织时值。
`pulse.scale("C4", "ionian")` 返回从根音到八度重复音的一组频率。`pulse.chord("C4", "maj7")` 返回同时发声的频率数组。`pulse.transpose(value, semitones)` 可以移动单个频率,也可以移动一个频率数组。
## 最小可运行例子
```lua
local pulse = require("pulse")
local c_major = pulse.scale("C4", "ionian")
local harmony = pulse.chord("C3", "maj7")
local higher = pulse.transpose(harmony, 12)
local phrase = pulse.sequence()
:notes({c_major[1], c_major[3], c_major[5], c_major[8]})
:durations({0.25, 0.25, 0.25, 0.75})
:instrument("music_box")
pulse.song():add(phrase):export_wav("output/theory.wav")
```
## 参数和边界
音名格式使用字母、可选升降号和八度,例如 `"A4"`、`"F#3"`、`"Bb5"`。`pulse.note("A4")` 约等于 `440.0`。`pulse.frequency_to_midi_note(440.0)` 返回 `69`,`pulse.midi_note_to_frequency(69)` 返回约 `440.0`。
调式包括常用别名 `major`、`minor`,也包括希腊调式:`ionian`、`dorian`、`phrygian`、`lydian`、`mixolydian`、`aeolian`、`locrian`。`ionian` 接近大调,`aeolian` 接近自然小调,`dorian` 常用于更明亮的小调感,`lydian` 有漂浮感。
和弦类型可用 `pulse.chord_kinds()` 查询,常用有 `maj`、`min`、`maj7`、`min7`、`dominant7`、`dim`、`aug`。完整作品里 `maj7` 和 `min7` 往往比三和弦更柔和。
## 常见陷阱
Lua 数组是 1 起始,所以 `scale[1]` 是根音,不是 `scale[0]`。鼓步号数组却是 0 起始,因为第 0 步代表小节开头。
不要把过多高八度和弦堆到同一轨。频率越高越容易刺耳;如果和弦太亮,先降低音量或用 filter,而不是指望导出标准化解决。
`transpose` 的单位是半音,不是赫兹。上移八度是 `12`,下移五度是 `-7`。
## 进阶用法
可以写一个 degree 辅助函数,把调式音阶变成级数系统:
```lua
local function degree(scale, value)
local unique = #scale - 1
local zero = value - 1
local octave = math.floor(zero / unique)
local position = (zero % unique) + 1
return pulse.transpose(scale[position], octave * 12)
end
```
这样旋律可以写成 `{1, 3, 5, 8}`,改 root 或 mode 就能重用结构。
## 相关章节
- [序列、乐句与编排](arrangement.md)
- [生成器映射](../03-generation/mapping.md)
- [Lua API](../06-reference/lua-api.md)
- [混音](../02-sound-design/mixing.md)