mlua-pulse 0.1.0

Lua-friendly music composition and audio export bindings built on tunes and mlua
Documentation
# 序列、乐句与编排


## 你会学到什么


- 区分 `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