# 序列、乐句与编排
## 你会学到什么
- 区分 `Sequence`、`DrumGrid`、`SampleClip`、`MidiClip`、`Phrase` 和 `Song`。
- 使用 `:at`、`:track`、`:volume`、`:pan`、`:velocity` 管理时间线和混音。
- 用 `Phrase:repeat_times` 从 loop 扩展到段落。
- 建立完整作品的结构思路,而不是只堆一条长数组。
## 适合谁读
已经能导出一个声音,想写出“像歌一样有段落”的用户应该读本章。Rust 集成者也可以借它理解 Lua DSL 的对象关系。
## 前置知识
- [快速开始](getting-started.md)
- [音乐理论](theory.md)
## 心智模型
`Sequence` 是音符或和弦事件,`DrumGrid` 是鼓事件,`SampleClip` 是音频片段,`MidiClip` 是导入 MIDI 片段。它们都是可放在时间线上的素材。`Phrase` 是一组素材的段落,`Song` 是最终作品。
完整作品最好写成层次结构:
```text
motif -> sequence
section -> phrase
piece -> song
```
这样你可以在小范围调旋律,在中范围调段落,在最终层调导出和 master。
## 最小可运行例子
```lua
local pulse = require("pulse")
local chords = pulse.sequence()
:chords({
pulse.chord("C3", "maj7"),
pulse.chord("A2", "min7"),
pulse.chord("F2", "maj7"),
pulse.chord("G2", "dominant7"),
})
:durations({1.0, 1.0, 1.0, 1.0})
:instrument("electric_piano")
:track("keys")
:volume(0.42)
:pan(-0.12)
local verse = pulse.phrase()
:add(chords)
:repeat_times(2)
pulse.song()
:tempo(112)
:add_phrase(verse)
:master_effect("limiter", "standard")
:export_wav("output/arrangement.wav", { normalize = "rms" })
```
## 参数和边界
`:notes` 和 `:chords` 二选一,后调用者会覆盖另一种事件。`:durations` 数量必须和事件数量一致。`:at(seconds)` 设置素材起始偏移,不能为负数。`:track(name)` 影响轨道命名和导出组织。`:volume` 范围 `[0, 2]`,但推荐从 `0.2..0.8` 开始。`:pan` 范围 `[-1, 1]`,负数左,正数右。`:velocity` 范围 `[0, 1]`,也会影响 MIDI 导出力度。
`Phrase:repeat_times(n)` 必须大于 0。段落加入 `Song` 时会按加入顺序接到当前时间线后面。
## 常见陷阱
不要把所有内容放在一个 `Sequence`。鼓、低音、和声、旋律、装饰音应该分轨,这样音量、声像、效果和导出都更清楚。
不要所有轨都 `pan(0)`。低音和 kick 放中间很合理,但 pad、装饰、和声可以略微左右分开,给主旋律留位置。
不要把 `velocity` 当成最终响度控制。它更像演奏力度;最终响度仍由轨道音量、混音和导出标准化共同决定。
## 进阶用法
可以用函数生成段落:
```lua
local function make_chorus(start_pan)
return pulse.phrase()
:add(
pulse.sequence()
:notes({pulse.note("E4"), pulse.note("G4"), pulse.note("A4"), pulse.note("C5")})
:durations({0.25, 0.25, 0.25, 0.75})
:instrument("bells")
:pan(start_pan)
:volume(0.28)
)
:repeat_times(4)
end
```
当作品变长时,函数化比复制粘贴更容易维护,也能避免某一段音量忘记调整。
## 相关章节
- [节奏与鼓机](rhythm-drums.md)
- [采样与 MIDI](samples-midi.md)
- [完整作品工作流](full-song-workflows.md)
- [Lua API](../06-reference/lua-api.md)