music12 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. package/README.md +430 -257
  2. package/dist/index.d.mts +1655 -337
  3. package/dist/index.d.ts +1655 -337
  4. package/dist/index.js +74936 -18732
  5. package/dist/index.mjs +74856 -18683
  6. package/package.json +13 -2
package/README.md CHANGED
@@ -1,400 +1,573 @@
1
1
  # music12
2
- 欢迎使用 `music12`,这是一个功能强大、类型安全的 TypeScript/JavaScript 库,旨在为开发者提供一套完整、易用的工具,用于处理音符、音程、和弦、调式音阶等乐理概念的计算和分析。
3
2
 
4
- 本库的核心设计理念是将抽象的乐理概念**对象化**。您可以创建 `Note`(音符)对象,用 `Interval`(音程)对象去操作它,将它们组合成 `Chord`(和弦)与 `Scale`(音阶)对象,并最终分析它们之间的和谐关系。
3
+ TypeScript 乐理计算库 音符、音程、和弦、调式音阶。
5
4
 
6
- 无论您是在构建音乐教育软件、数字音频工作站(DAW)、自动作曲工具,还是仅仅想在您的项目中加入一些音乐元素,`music12` 都能为您提供坚实的基础。
5
+ ## 特性
7
6
 
8
- ## 核心特性
9
- - **🎹 直观的面向对象模型**: 将音符、音程、和弦和音阶作为一等公民。通过调用它们的方法 (`note.getNoteByInterval(...)`, `scale.getScaleDegreeChord7(...)`) 来进行乐理交互,代码清晰易懂。
10
- - **🏭 便捷的工厂函数**: 提供 `factory` 模块,无需记忆繁琐的构造函数参数,通过 `factory.getNote(...)` 等方式快速创建实例。
11
- - **🔧 强大的和弦构建与变形**: 不仅能创建上百种预设和弦,还能通过链式调用 `.setTransform('b9')` `.setOmit(5)` 等方法,轻松实现和弦的复杂变化(Altered Chords)和省略音。
12
- - **🎼 智能的调式与和声分析**:
13
- - 可基于任意根音和调式模式构建音阶。
14
- - 自动推算调式内的顺阶和弦(Diatonic Chords)。
15
- - 提供 `find` 模块,能根据一组音符反向推导出所有可能的和弦或调式,是和弦识别、乐曲分析等功能的利器。
16
- - **🔒 完备的 TypeScript 支持**: 拥有严格的类型定义,为所有函数和对象提供了类型约束。这能帮助您在编码阶段就发现潜在的错误,并享受现代IDE带来的代码自动补全和类型提示的便利。
17
- - **🛠️ 丰富的音乐工具**: 内置五度圈计算、谱号查询等实用工具,满足多样化的开发需求。
7
+ - **Note** — 音高、MIDI 值、等音异名、移调
8
+ - **Interval** 音程构建、比较、性质滑动
9
+ - **Chord** 和弦构建,支持变化音(sus、add、omit、升降号)
10
+ - **Scale** 10 个家族 47 种调式(自然调式、中国五声、和声小调等)
11
+ - **Find** — 反向查找:根据音符列表查找和弦/调式
12
+ - **Circle of Fifths** — 五度圈、调号计算
13
+ - **Factory** — 便捷工厂函数,无需 `new` 即可创建实例
14
+ - 完整 TypeScript 类型支持
18
15
 
19
- ## 📦 安装
20
- 将dist目录下的文件引入项目即可。
16
+ ## 安装
21
17
 
22
- ## 🚀 快速上手 & 核心指南
23
- 本指南将带您了解本库最核心的几个概念,并演示如何将它们组合起来解决实际的音乐问题。
24
- #### 1. 基石:`Note` (音符)
18
+ ```bash
19
+ npm install music12
20
+ # or
21
+ pnpm add music12
22
+ ```
25
23
 
26
- `Note` 是本库最基础的构建单元。
24
+ ## 快速上手
27
25
 
26
+ ```ts
27
+ import { Note, Interval, Chord, Scale } from 'music12'
28
+ import { getNote, getScale, getChord, getInterval } from 'music12'
28
29
  ```
29
- import { factory } from 'music12';
30
-
31
- const c4 = factory.getNote('C', 0, 4);
32
- const gSharp5 = factory.getNote('G', 1, 5);
33
30
 
34
- // 探索音符的属性
35
- console.log(c4.simpleDescription); // "C4"
36
- console.log(gSharp5.artName); // "G#"
37
- console.log(gSharp5.pitchValue); // 80 (MIDI 音高值)
31
+ ---
38
32
 
39
- // 对音符进行操作
40
- const d4 = c4.semitoneMove(2); // 将 C4 向上移动2个半音
41
- console.log(d4.artName); // "D"
42
- ```
33
+ ## Note
43
34
 
44
- #### 2. 关系:`Interval` (音程)
35
+ `Note` 表示一个具有绝对音高的音符。
45
36
 
46
- `Interval` 定义了音符之间的“距离”。它是移动和构建和声的关键。
37
+ ```ts
38
+ const note = new Note('C', 0, 4) // C4(中央 C)
47
39
 
40
+ note.step // "C"
41
+ note.alter // 0
42
+ note.octave // 4
43
+ note.artName // "C"
44
+ note.pianoKeyId // 0
45
+ note.pitchValue // 60(MIDI)
46
+ note.isBlack // false
48
47
  ```
49
- import { Note } from 'music12/note';
50
- import { Interval } from 'music12/interval';
51
48
 
52
- const c4 = new Note('C', 0, 4);
53
- const majorThird = new Interval('maj', 3);
54
- const e4 = c4.getNoteByInterval(majorThird);
55
- console.log(e4.simpleDescription); // "E4"
49
+ ### 构造函数
50
+
51
+ ```ts
52
+ new Note(step?: T_NoteStep, alter?: T_AlterValue, octave?: number)
56
53
  ```
57
54
 
58
- #### 3. 和声:`Chord` (和弦)
55
+ | 参数 | 类型 | 说明 | 默认值 |
56
+ |------|------|------|--------|
57
+ | `step` | `"C" \| "D" \| "E" \| "F" \| "G" \| "A" \| "B"` | 音名 | `"C"` |
58
+ | `alter` | `-2 \| -1 \| 0 \| 1 \| 2` | 变化音(-1=降, +1=升) | `0` |
59
+ | `octave` | `number` | 八度 | `4` |
59
60
 
60
- `Chord` 是由一个根音 `Note` 和一组 `Interval` 构成的和谐之声。
61
+ ### 属性
61
62
 
62
- ```
63
- import { factory } from 'music12';
63
+ | 属性 | 类型 | 说明 |
64
+ |------|------|------|
65
+ | `step` | `T_NoteStep` | 音名 |
66
+ | `alter` | `T_AlterValue` | 变化音数值 |
67
+ | `octave` | `number` | 八度 |
68
+ | `artName` | `string` | 显示名(如 `"C#"`, `"Eb"`) |
69
+ | `mathName` | `string` | 数学名(如 `"C+1"`, `"E-1"`) |
70
+ | `fifthValue` | `number` | 五度圈位置值 |
71
+ | `isNormal` | `boolean` | 是否常用音(\|alter\| <= 1) |
72
+ | `isBlack` | `boolean` | 是否为钢琴黑键 |
73
+ | `pianoKeyId` | `number` | 钢琴键位 0-11 |
74
+ | `semitoneWithinOctave` | `number` | 相对 C 的半音数 |
75
+ | `stepId` | `number` | 音名索引(C=0, B=6) |
76
+ | `pitchValue` | `number` | 绝对 MIDI 音高值 |
77
+ | `simpleDescription` | `string` | 简洁描述(如 `"C#4"`) |
78
+ | `pianoKey` | `PianoKey` | 对应的 PianoKey 实例 |
64
79
 
65
- const g7 = factory.getChord('G', 0, 4, 'dom7');
66
- console.log(g7.notesList.map(n => n.artName)); // [ 'G', 'B', 'D', 'F' ]
80
+ ### 方法
67
81
 
68
- g7.setTransform('b9'); // 增加一个降九音 (Ab)
69
- console.log(g7.notesList.map(n => n.artName)); // [ 'G', 'B', 'D', 'F', 'Ab' ]
70
- ```
82
+ #### `getNoteByInterval(interval, options?)`
71
83
 
72
- ## 📚 API 详细参考 (Class & Instance Reference)
84
+ 根据音程计算目标音符。
73
85
 
86
+ ```ts
87
+ const maj3 = new Interval('maj', 3)
88
+ note.getNoteByInterval(maj3) // E4
89
+ note.getNoteByInterval(maj3, { isAscending: false }) // 向下:Ab3
90
+ ```
74
91
 
92
+ #### `getNoteByIntervalString(str, options?)`
75
93
 
76
- 本节为您详细介绍 `music12` 中每一个核心类的构造方式、所有可访问的属性和方法。
94
+ 根据数字标记法(如 `"b7"`, `"#4"`)计算目标音符。
77
95
 
78
- ### `Note` 类
96
+ ```ts
97
+ const d4 = new Note('D', 0, 4)
98
+ d4.getNoteByIntervalString('b7') // C5(D4 的小七度上方)
99
+ d4.getNoteByIntervalString('#4') // G#4
100
+ ```
79
101
 
80
- `Note` 对象是所有乐理计算的基础,代表一个具有绝对音高的音符。
102
+ #### `getSamePitchNotes(options?)`
81
103
 
82
- #### 构造函数
104
+ 获取所有等音异名。
83
105
 
84
- ```
85
- new Note(step?: t_noteStep, alter?: t_alterValue, octave?: number)
106
+ ```ts
107
+ const gSharp4 = new Note('G', 1, 4)
108
+ gSharp4.getSamePitchNotes({ alterAbsLte: 1 })
109
+ // [G#4, Ab4]
86
110
  ```
87
111
 
88
- ```
89
- import { Note } from 'music12/note';
90
- const aFlat4 = new Note('A', -1, 4);
91
- ```
112
+ #### `semitoneMove(moveStep)`
92
113
 
93
- #### 属性
114
+ 按半音数移调,智能选择最合适的音名。
94
115
 
95
- | 属性 | 类型 | 描述 | 示例 (以 `aFlat4` 为例) |
96
- | ---------------------- | -------------- | ------------------------------- | ----------------------- |
97
- | `step` | `t_noteStep` | 音名 (C, D, E...) | `'A'` |
98
- | `alter` | `t_alterValue` | 变化音数值 (-2 到 2) | `-1` |
99
- | `octave` | `number` | 八度 | `4` |
100
- | `artName` | `string` | 艺术化名称 (乐谱常用名) | `'A♭'` |
101
- | `mathName` | `string` | 数学化名称 | `'A-1'` |
102
- | `pitchValue` | `number` | 绝对音高值 (MIDI Number) | `68` |
103
- | `simpleDescription` | `string` | 简洁描述 | `'A♭4'` |
104
- | `locationId` | `number` | 在十二平均律中的位置 (0-11) | `8` |
105
- | `semitoneWithinOctave` | `number` | 相对 C0 的半音数 (可能会超过11) | `8` |
106
- | `isBlack` | `boolean` | 是否为钢琴上的黑键 | `true` |
107
- | `isNormal` | `boolean` | 是否为常用音 (升降号不超过1个) | `true` |
108
- | `fifthValue` | `number` | 在五度圈中的值 | `-4` |
109
- | `stepIndex` | `number` | 音名的索引 (C=0, D=1...) | `5` |
116
+ ```ts
117
+ const c4 = new Note('C', 0, 4)
118
+ c4.semitoneMove(3) // Eb4(选 Eb 而非 D#)
119
+ c4.semitoneMove(-2) // Bb3
120
+ ```
110
121
 
111
- #### 方法
122
+ #### `getHarmonicSeries()`
112
123
 
113
- ##### `getNoteByInterval()`
124
+ 获取泛音序列。
114
125
 
115
- 根据一个 `Interval` 实例,计算并返回一个新的 `Note` 实例。 `getNoteByInterval(intervalInstance: Interval, isAscending: boolean = true): Note`
126
+ #### `get251as(noteAs)`
116
127
 
128
+ 返回 ii-V-I 进行中三个和弦的根音。
129
+
130
+ ```ts
131
+ const c4 = new Note('C', 0, 4)
132
+ c4.get251as(1) // [D, G, C] — C 作为 I 级
117
133
  ```
118
- import { Note } from 'music12/note';
119
- import { Interval } from 'music12/interval';
120
- const c4 = new Note('C', 0, 4);
121
- const p5 = new Interval('p', 5);
122
- const g4 = c4.getNoteByInterval(p5);
123
- console.log(g4.simpleDescription); // "G4"
134
+
135
+ ### 模块函数
136
+
137
+ ```ts
138
+ getCasualRandomNote() // 随机音符(含极端等音异名)
139
+ getNormalRandomNote() // 随机常用音符
140
+ getWhiteRandomNote() // 随机白键音符
141
+ getBlackRandomNote() // 随机黑键音符
142
+ getNoteByPianoKeyId(id) // 根据 pianoKeyId 获取所有等音异名 Note[]
143
+ getUpwardPianoKeyGap(base, target) // 两个 pianoKeyId 之间的上行半音距离
144
+ normalizeOctave(octave) // 标准化八度参数
124
145
  ```
125
146
 
126
- ##### `getNoteByIntervalString()`
147
+ ---
127
148
 
128
- 根据简化的数字和弦标记法(如 `b7`, `#4`)计算并返回一个新的 `Note` 实例。 `getNoteByIntervalString(numberNotationString: string, isAscending: boolean = true): Note`
149
+ ## Interval
129
150
 
130
- ```
131
- import { Note } from 'music12/note';
132
- const d4 = new Note('D', 0, 4);
133
- const c5 = d4.getNoteByIntervalString('b7'); // D4 的小七度是 C5
134
- console.log(c5.simpleDescription); // "C5"
151
+ `Interval` 表示两个音符之间的距离。
152
+
153
+ ### 构造函数
154
+
155
+ ```ts
156
+ new Interval(type?: T_IntervalType, num?: number)
135
157
  ```
136
158
 
137
- ##### `getSamePitchNotes()`
159
+ ### 音程类型
138
160
 
139
- 获取当前音符的所有“同音异名”音符。 `getSamePitchNotes(isSelfIncluded: boolean = true, alterAbsLessThan: 0 | 1 | 2 = 1): Note[]`
161
+ | 类型 | 含义 | 示例 |
162
+ |------|------|------|
163
+ | `"p"` | 纯 | 纯一度、纯五度 |
164
+ | `"maj"` | 大 | 大三度 |
165
+ | `"min"` | 小 | 小三度 |
166
+ | `"aug"` | 增 | 增四度 |
167
+ | `"dim"` | 减 | 减五度 |
168
+ | `"aug+"` | 倍增 | 倍增四度 |
169
+ | `"dim-"` | 倍减 | 倍减五度 |
140
170
 
141
- ```
142
- import { Note } from 'music12/note';
143
- const gSharp4 = new Note('G', 1, 4);
144
- const sameNotes = gSharp4.getSamePitchNotes(true, 1);
145
- console.log(sameNotes.map(n => n.artName)); // [ 'G#', 'Ab' ]
171
+ ### 属性
172
+
173
+ ```ts
174
+ const interval = new Interval('maj', 3)
175
+
176
+ interval.type // "maj"
177
+ interval.num // 3
178
+ interval.numWithinOctave // 3
179
+ interval.cnPrefix // "大"
180
+ interval.semitoneGap // 4
181
+ interval.semitoneGapWithinOctave // 4
182
+ interval.isNatural // true
183
+ interval.simpleDescription // "大三度"
146
184
  ```
147
185
 
148
- ##### `semitoneMove()`
186
+ ### 方法
149
187
 
150
- 将当前音符按指定的半音数量移动,并智能地返回最常用的 `Note` 实例。 `semitoneMove(moveStep: number): Note`
188
+ #### `getEqualInterval(options?)`
151
189
 
152
- ```
153
- import { Note } from 'music12/note';
154
- const c4 = new Note('C', 0, 4);
155
- const eb4 = c4.semitoneMove(3); // 向上移动3个半音
156
- console.log(eb4.simpleDescription); // "E♭4" (智能选择 E♭ 而非 D#)
190
+ 获取所有等音异名的音程。
191
+
192
+ ```ts
193
+ const aug4 = new Interval('aug', 4)
194
+ aug4.getEqualInterval()
195
+ // [增四度, 减五度, 倍增三度, 倍减六度]
157
196
  ```
158
197
 
159
- ##### `getHarmonicSeries()`
198
+ ### 模块函数
160
199
 
161
- 获取当前音符的泛音序列。 `getHarmonicSeries(): { step: t_noteStep, ... }[]`
200
+ ```ts
201
+ // 计算两个音符之间的音程
202
+ getIntervalByComparingNotes(note1, note2): Interval
162
203
 
163
- ```
164
- import { Note } from 'music12/note';
165
- const c3 = new Note('C', 0, 3);
166
- const harmonics = c3.getHarmonicSeries();
167
- console.log(harmonics.slice(0, 3).map(h => h.artName)); // [ 'C', 'G', 'C' ] (前三个泛音)
168
- ```
204
+ // 根据半音距离查找自然音程
205
+ getIntervalBySemitoneGap(7) // [纯五度]
169
206
 
170
- ##### `get251as()`
207
+ // 根据两个音名计算度数
208
+ getIntervalDegreeByStep('C', 'G') // 5
171
209
 
172
- 将当前音符作为 ii-V-I 进行中的某个角色,返回该进行中所有和弦的根音。 `get251as(noteAs: 1 | 2 | 5): Note[]`
210
+ // 判断度数是否属于纯音程家族(1, 4, 5
211
+ isPureInterval(5) // true
173
212
 
174
- ```
175
- import { Note } from 'music12/note';
176
- const c4 = new Note('C', 0, 4);
177
- const progressionRoots = c4.get251as(1); // 将 C 作为 I 级
178
- console.log(progressionRoots.map(n => n.artName)); // [ 'D', 'G', 'C' ] (ii-V-I in C)
213
+ // 滑动音程性质(纯音程家族)
214
+ intervalSlide_145('p', 1) // "aug"
215
+ intervalSlide_145('p', -1) // "dim"
216
+
217
+ // 滑动音程性质(大小音程家族)
218
+ intervalSlide_2367('maj', -1) // "min"
219
+ intervalSlide_2367('min', 1) // "maj"
179
220
  ```
180
221
 
181
- ------
222
+ ---
182
223
 
183
- ### `Interval` 类
224
+ ## Chord
184
225
 
185
- `Interval` 对象用于表示两个音符之间的距离。
226
+ `Chord` 表示由根音和和弦公式构成的和弦,支持变化音操作。
186
227
 
187
- #### 构造函数
228
+ ### 构造函数
188
229
 
189
- ```
190
- new Interval(intervalType?: t_intervalType, intervalNum?: number)
230
+ ```ts
231
+ new Chord(rootPianoKeyId: number, chordFormulaId: string)
191
232
  ```
192
233
 
193
- ```
194
- import { Interval } from 'music12/interval';
195
- const minorThird = new Interval('min', 3);
234
+ ```ts
235
+ const chord = new Chord(0, 'maj3') // C 大三和弦
236
+
237
+ chord.rootPianoKeyId // 0
238
+ chord.chordFormulaId // "maj3"
239
+ chord.cnName // "大三和弦"
240
+ chord.pianoKeyIds // [0, 4, 7]
241
+ chord.scoreSymbol // "M3"
196
242
  ```
197
243
 
198
- #### 属性
244
+ ### 属性
199
245
 
200
- | 属性 | 类型 | 描述 | 示例 (以 `minorThird` 为例) |
201
- | ------------------- | ---------------- | ------------------------------ | --------------------------- |
202
- | `type` | `t_intervalType` | 音程性质 (`'min'`, `'maj'`...) | `'min'` |
203
- | `num` | `number` | 音程度数 | `3` |
204
- | `simpleDescription` | `string` | 中文描述 | `'小三度'` |
205
- | `semitoneGap` | `number` | 包含的总半音数量 | `3` |
206
- | `isNatural` | `boolean` | 是否为自然音程(大、小、纯) | `true` |
246
+ | 属性 | 类型 | 说明 |
247
+ |------|------|------|
248
+ | `rootPianoKeyId` | `number` | 根音 pianoKeyId(0-11) |
249
+ | `chordFormulaId` | `string` | 和弦公式 ID(如 `"maj7"`) |
250
+ | `baseSymbol` | `string` | 基础记号(如 `"M7"`) |
251
+ | `cnName` | `string` | 中文名 |
252
+ | `family` | `string` | 和弦家族分类 |
253
+ | `pianoKeyIds` | `number[]` | 按度数排列的 pianoKeyId |
254
+ | `pianoKeyIdsSorted` | `number[]` | 按音高排序的 pianoKeyId |
255
+ | `notesNum` | `number` | 音符数量 |
256
+ | `scoreSymbol` | `string` | 完整谱面记号(含变化音) |
257
+ | `isTransformed` | `boolean` | 是否有变化音 |
258
+ | `simpleDescription` | `string` | 简洁描述(如 `"C4,E4,G4"`) |
259
+ | `baseIntervalList` | `[T_IntervalType, number][]` | 基础音程列表 |
260
+ | `intervalList` | `[T_IntervalType, number][]` | 实际音程列表(含变化) |
261
+ | `intervalPanel` | `I_ChordIntervalPanel` | 按度数索引的音程面板 |
262
+ | `transformPanel` | `I_TransformPanel` | 当前变化音配置 |
207
263
 
208
- #### 方法
264
+ ### 方法
209
265
 
266
+ #### `set(input): this`
210
267
 
268
+ 设置和弦某度数的音程类型,支持链式调用。
211
269
 
270
+ ```ts
271
+ const chord = new Chord(0, 'maj7')
212
272
 
273
+ chord.set('#5') // 升五音
274
+ .set(9) // 加九音
275
+ .setOmit(3) // 省略三音
276
+ .setSus(4) // sus4
213
277
 
214
- ##### `getEqualInterval()`
278
+ chord.scoreSymbol // 含变化音的完整记号
279
+ ```
215
280
 
281
+ `set` 支持的输入格式:
216
282
 
283
+ | 输入 | 说明 |
284
+ |------|------|
285
+ | `2`, `3`, `9` 等 | 设置度数为自然音程 |
286
+ | `"#5"`, `"#11"` | 升号 |
287
+ | `"b9"`, `"b13"` | 降号 |
217
288
 
218
- 获取与当前音程的半音数相同的所有其他音程。 `getEqualInterval(isSelfTypeExcluded?: boolean, isAugDimExcluded?: boolean, isDoubleAugDimExcluded?: boolean): Interval[]`
289
+ #### `setSus(susNum?): this`
219
290
 
220
- TypeScript
291
+ 挂留和弦(替换三度音)。
221
292
 
293
+ ```ts
294
+ chord.setSus(2) // sus2
295
+ chord.setSus(4) // sus4
222
296
  ```
223
- import { Interval } from 'music12/interval';
224
- const aug4 = new Interval('aug', 4); // 增四度,6个半音
225
- const equals = aug4.getEqualInterval();
226
- console.log(equals.map(i => i.simpleDescription)); // [ '增四度', '减五度', '倍增三度', '倍减六度' ]
297
+
298
+ #### `setOmit(omitInterval): this`
299
+
300
+ 省略某度音。
301
+
302
+ ```ts
303
+ chord.setOmit(5) // 省略五音
227
304
  ```
228
305
 
229
- ------
306
+ #### `clearTransform(): void`
307
+
308
+ 清除所有变化音,恢复基础和弦。
309
+
310
+ #### `getRootNotes(octave?): Note[]`
230
311
 
231
- ### `Chord`
312
+ 获取根音的 Note 实例。
232
313
 
233
- `Chord` 对象由一个根音和一种和弦类型构成。
314
+ #### `getNotesList(octave?): Note[]`
234
315
 
235
- #### 构造函数
316
+ 获取所有音符的 Note 实例。
236
317
 
318
+ ```ts
319
+ const chord = new Chord(0, 'maj3')
320
+ chord.getNotesList(4) // [C4, E4, G4]
237
321
  ```
238
- new Chord(rootNote: Note, chordKey: string, initTransform?: t_inputTransformPanel)
322
+
323
+ #### `find(config?): I_AnalyzedChordResult[]`
324
+
325
+ 反向查找:根据当前音符找到匹配的和弦。
326
+
327
+ ### 模块函数
328
+
329
+ ```ts
330
+ // 根据 pianoKeyId 列表推导和弦变换
331
+ getChordTransformByPianoKeyIds(originChordInfo, givenPianoKeyIds)
239
332
  ```
240
333
 
334
+ ---
335
+
336
+ ## Scale
337
+
338
+ `Scale` 表示由根音和调式构成的音阶。
339
+
340
+ ### 构造函数
341
+
342
+ ```ts
343
+ new Scale(rootPianoKeyId: number, scaleModeId: T_ScaleModeId)
241
344
  ```
242
- import { Chord } from 'music12/chord';
243
- import { Note } from 'music12/note';
244
- const cMaj7 = new Chord(new Note('C', 0, 4), 'maj7');
345
+
346
+ ```ts
347
+ const scale = new Scale(0, 'NATURAL_MAJOR') // C 自然大调
348
+
349
+ scale.rootPianoKeyId // 0
350
+ scale.pianoKeyIds // [0, 2, 4, 5, 7, 9, 11]
351
+ scale.modeName // 调式名称
352
+ scale.simpleDescription // "C,D,E,F,G,A,B"
245
353
  ```
246
354
 
247
- #### 属性 (均为 Getter)
355
+ ### 属性
356
+
357
+ | 属性 | 类型 | 说明 |
358
+ |------|------|------|
359
+ | `rootPianoKeyId` | `number` | 根音 pianoKeyId(0-11) |
360
+ | `scaleModeId` | `T_ScaleModeId` | 调式 ID |
361
+ | `pianoKeyIds` | `number[]` | 按度数排列的 pianoKeyId |
362
+ | `pianoKeyIdsSorted` | `number[]` | 按音高排序的 pianoKeyId |
363
+ | `degreeToPianoKeyId` | `Record<number, number>` | 度数 → pianoKeyId 映射 |
364
+ | `pianoKeyIdToDegree` | `Record<number, number>` | pianoKeyId → 度数映射 |
365
+ | `degreeAlterationsMap` | `Record<number, number>` | 度数 → 变化音映射 |
366
+ | `modeName` | `string` | 调式名称 |
367
+ | `modeDescription` | `string` | 调式描述 |
368
+ | `type` | `string` | 调式类别 |
369
+ | `simpleDescription` | `string` | 简洁描述 |
370
+ | `naturalNotesNum` | `number` | 自然音数量 |
371
+ | `alteredNotesNum` | `number` | 变化音数量 |
372
+ | `isTonicReplaced` | `boolean` | 是否所有音都被变化 |
248
373
 
249
- | 属性 | 类型 | 描述 |
250
- | ------------------- | ---------------------------- | ----------------------------------------------- |
251
- | `rootNote` | `Note` | 和弦的根音。 |
252
- | `chordKey` | `string` | 和弦的基础类型键,如 'maj7', 'dim3'。 |
253
- | `baseSymbol` | `string` | 和弦基础类型的谱面记号,如 'M7', '°'。 |
254
- | `scoreSymbol` | `string` | 完整的谱面记号,包含所有变化音,如 '7(♭9)'。 |
255
- | `notesList` | `Note[]` | 构成和弦的所有音符实例的数组。 |
256
- | `intervalList` | `[t_intervalType, number][]` | 构成和弦的所有音程的数组。 |
257
- | `transformPanel` | `t_transformPanel` | 当前和弦的变化音/省略音配置。 |
258
- | `isTransformed` | `boolean` | 判断和弦是否应用了任何变化或省略。 |
259
- | `simpleDescription` | `string` | 由组成音的简洁描述构成的字符串,如 'C4,E4,G4'。 |
374
+ ### 方法
260
375
 
261
- #### 方法
376
+ #### 查询方法
262
377
 
263
- ##### `setTransform()`
378
+ ```ts
379
+ scale.hasPianoKeyId(2) // true(D 在 C 大调中)
380
+ scale.getDegreeByPianoKeyId(2) // 2(D 是第 2 级)
381
+ scale.getDegreeAndAlter(1) // { degree: 2, alter: 0 }
382
+ scale.getPianoKeyIdByDegree(5) // 7(第 5 级是 G)
383
+ scale.getAlterByDegree(4) // 0(第 4 级 F 在 C 大调无变化)
384
+ ```
264
385
 
265
- 为和弦添加一个变化音。返回自身,支持链式调用。 `setTransform(transformString: t_transformString): Chord`
386
+ #### 获取音符
266
387
 
388
+ ```ts
389
+ scale.getRootNote() // 根音 Note[]
390
+ scale.getNoteByDegree(5) // 第 5 级音 Note[]
391
+ scale.getNoteByIntervalNum(9) // 支持跨八度的度数
267
392
  ```
268
- import { factory } from 'music12';
269
- const g7 = factory.getChord('G', 0, 4, 'dom7');
270
- g7.setTransform('b9').setTransform('#11');
271
- console.log(g7.scoreSymbol); // "7(♭9,#11)"
393
+
394
+ #### 顺阶和弦
395
+
396
+ ```ts
397
+ scale.getScaleDegreeChord3(1) // 第 1 级三和弦 → I 和弦
398
+ scale.getScaleDegreeChord7(5) // 第 5 级七和弦 → V7 和弦
272
399
  ```
273
400
 
274
- ##### `setOmit()`
401
+ ### 调式列表
275
402
 
276
- 从和弦中省略一个音。 `setOmit(omitInterval: t_intervalNum): void`
403
+ 47 种调式,10 个家族:
277
404
 
405
+ | 家族 | 调式 |
406
+ |------|------|
407
+ | Diatonic (7) | `NATURAL_MAJOR`, `DORIAN`, `PHRYGIAN`, `LYDIAN`, `MIXOLYDIAN`, `NATURAL_MINOR`, `LOCRIAN` |
408
+ | Harmonic Major (1) | `HARMONIC_MAJOR` |
409
+ | Melodic Major (1) | `MELODIC_MAJOR_DESCENDING` |
410
+ | Harmonic Minor (6) | `HARMONIC_MINOR`, `LOCRIAN_SHARP6`, `IONIAN_SHARP5`, `DORIAN_SHARP4`, `PHRYGIAN_DOMINANT`, `LYDIAN_SHARP2` |
411
+ | Melodic Minor (5) | `MELODIC_MINOR_ASCENDING`, `DORIAN_FLAT2`, `LYDIAN_AUGMENTED`, `LYDIAN_DOMINANT`, `LOCRIAN_SHARP2` |
412
+ | Double Harmonic (4) | `DOUBLE_HARMONIC_MAJOR`, `HUNGARIAN_MINOR`, `ORIENTAL`, `IONIAN_SHARP2_SHARP5` |
413
+ | Chinese Pentatonic (5) | `GONG`, `SHANG`, `JUE`, `ZHI`, `YU` |
414
+ | Chinese Yayue (5) | `YA_YUE_GONG`, `YA_YUE_SHANG`, `YA_YUE_JUE`, `YA_YUE_ZHI`, `YA_YUE_YU` |
415
+ | Chinese Qingyue (5) | `QING_YUE_GONG`, `QING_YUE_SHANG`, `QING_YUE_JUE`, `QING_YUE_ZHI`, `QING_YUE_YU` |
416
+ | Chinese Yanyue (5) | `YAN_YUE_GONG`, `YAN_YUE_SHANG`, `YAN_YUE_JUE`, `YAN_YUE_ZHI`, `YAN_YUE_YU` |
417
+
418
+ ```ts
419
+ import { SCALE_MODE, SCALE_MODE_IDS, SCALE_MODE_GROUPS } from 'music12'
420
+
421
+ SCALE_MODE.NATURAL_MAJOR // "NATURAL_MAJOR"
422
+ SCALE_MODE_IDS // ["NATURAL_MAJOR", "DORIAN", ...]
423
+ SCALE_MODE_GROUPS.DIATONIC // ["NATURAL_MAJOR", "DORIAN", ...]
424
+ SCALE_MODE_GROUPS.CHINESE_PENTATONIC // ["GONG", "SHANG", "JUE", "ZHI", "YU"]
278
425
  ```
279
- import { factory } from 'music12';
280
- const c9 = factory.getChord('C', 0, 4, 'dom9');
281
- c9.setOmit(5); // 省略五音
282
- console.log(c9.notesList.map(n => n.artName)); // [ 'C', 'E', 'Bb', 'D' ]
426
+
427
+ ### 模块函数
428
+
429
+ ```ts
430
+ getModeNameByModeKey('DOR') // 调式名称
431
+ getModeTypeByModeKey('DOR') // 调式类别
432
+ getIntervalListByModeKey('DOR') // 调式音程列表
283
433
  ```
284
434
 
285
- ##### `clearTransform()`
435
+ ---
286
436
 
287
- 移除所有已设置的变化音和省略音,将和弦恢复到其基础形态。 `clearTransform(): void`
437
+ ## Find
288
438
 
289
- ```
290
- import { factory } from 'music12';
291
- const chord = factory.getChord('A', 0, 4, 'min7');
292
- chord.setTransform('b5');
293
- console.log(chord.scoreSymbol); // "m7(♭5)"
294
- chord.clearTransform();
295
- console.log(chord.scoreSymbol); // "m7"
439
+ 反向查找工具 — 根据音符列表查找和弦和调式。
440
+
441
+ ```ts
442
+ import {
443
+ findChord,
444
+ findNotesInScales,
445
+ areNotesInScale,
446
+ findNoteDegreeInAllScales,
447
+ findNoteDegreeInScale,
448
+ findScaleByDegreePositions,
449
+ } from 'music12'
296
450
  ```
297
451
 
298
- ##### `tryToMergeTransform()`
452
+ ```ts
453
+ // 根据 MIDI 音高查找和弦
454
+ findChord([60, 64, 67, 71]) // Cmaj7
299
455
 
300
- 尝试将一个变化和弦识别为一个新的基础和弦。如果成功,返回一个新的 `Chord` 实例;否则返回应用了变化的原始和弦。 `tryToMergeTransform(): Chord`
456
+ // 查找包含所有给定音符的调式
457
+ findNotesInScales([0, 2, 4, 5, 7])
301
458
 
302
- ```
303
- import { factory } from 'music12';
304
- // 一个大七和弦,但三音和七音都降了半音
305
- const chord = factory.getChord('C', 0, 4, 'maj7', { 3: 'min', 7: 'min' });
306
- // 实际上 C-E-G-B 变成了 C-Eb-G-Bb,这是一个小七和弦
307
- const merged = chord.tryToMergeTransform();
308
- console.log(merged.chordKey); // 'min7'
459
+ // 检查音符是否属于某调式
460
+ areNotesInScale([0, 2, 4], 0, 'NATURAL_MAJOR') // true
461
+
462
+ // 查找音符在所有调式中的级数
463
+ findNoteDegreeInAllScales(2)
464
+
465
+ // 查找音符在某调式中的级数
466
+ findNoteDegreeInScale(2, 0, 'NATURAL_MAJOR') // 2
467
+
468
+ // 根据度数约束查找调式
469
+ findScaleByDegreePositions([
470
+ { pianoKeyId: 0, as: 1 }, // C 作为第 1 级
471
+ { pianoKeyId: 7, as: 5 }, // G 作为第 5 级
472
+ ])
309
473
  ```
310
474
 
311
- ### `Scale` 类
475
+ ---
312
476
 
313
- `Scale` 对象代表一个由根音和特定调式构成的音阶。
477
+ ## Circle of Fifths
314
478
 
315
- #### 构造函数
479
+ ```ts
480
+ import { circleOfFifths } from 'music12'
316
481
 
317
- ```
318
- new Scale(rootNote: Note, scaleMode: t_scaleMode)
319
- ```
482
+ const pos = new circleOfFifths(0) // C 大调 / a 小调
483
+ pos.move(5) // 移动 5 个位置
484
+ pos.majCircle // 大调信息
485
+ pos.minCircle // 小调信息
320
486
 
321
- ```
322
- import { Scale } from 'music12/scale';
323
- import { Note } from 'music12/note';
324
- const aMinorScale = new Scale(new Note('A', 0, 4), 'MIN');
487
+ // 静态属性
488
+ circleOfFifths.SHARP_ORDER // ["F","C","G","D","A","E","B"]
489
+ circleOfFifths.FLAT_ORDER // ["B","E","A","D","G","C","F"]
325
490
  ```
326
491
 
327
- #### 属性 (均为 Getter)
492
+ ---
328
493
 
329
- | 属性 | 类型 | 描述 |
330
- | --------------------- | ---------------------------- | ------------------------------------ |
331
- | `rootNote` | `Note` | 音阶的根音(主音)。 |
332
- | `modeName` | `string` | 调式的名称,如 '自然小调'。 |
333
- | `modeDescription` | `string` | 关于此调式的文字描述。 |
334
- | `type` | `string` | 调式的类别,如 'major', 'minor'。 |
335
- | `notesList` | `Note[]` | 构成音阶的所有音符实例的数组。 |
336
- | `intervalList` | `[t_intervalType, number][]` | 从根音到其他各级音的音程列表。 |
337
- | `notesPanel` | `t_scaleNotesPanel` | 按度数(1-7)索引的音符对象。 |
338
- | `chord3OfDegreesList` | `string[]` | 调式内各级三和弦的 `chordKey` 列表。 |
339
- | `chord7OfDegreesList` | `string[]` | 调式内各级七和弦的 `chordKey` 列表。 |
340
- | `alterList` | `number[]` | 调式音级相对于自然大调的变化列表。 |
494
+ ## Stave (调号)
341
495
 
342
- #### 方法
496
+ ```ts
497
+ import { getStaveAlterByNote, getScaleByStaveAlters, getAlterStepListByNum } from 'music12'
343
498
 
344
- ##### `getScaleDegreeNote()`
499
+ // 查找音符所属调号
500
+ getStaveAlterByNote('C', 0)
345
501
 
346
- 获取音阶中指定度数的音符。 `getScaleDegreeNote(degree: number): Note`
502
+ // 根据调号数量获取调式信息(-7 +7)
503
+ getScaleByStaveAlters(2) // D 大调 / b 小调
347
504
 
348
- ```
349
- import { factory } from 'music12';
350
- const dDorian = factory.getScale('D', 0, 4, 'DOR');
351
- const sixthNote = dDorian.getScaleDegreeNote(6); // 获取Dorian的第6级音
352
- console.log(sixthNote.artName); // "B" (Dorian的特色音)
505
+ // 获取调号对应的升降音名列表
506
+ getAlterStepListByNum(3) // ["F","C","G"](3 个升号)
353
507
  ```
354
508
 
355
- ##### `getNoteByIntervalNum()`
509
+ ---
356
510
 
357
- 功能与 `getScaleDegreeNote` 类似,但可以处理超过八度的度数。 `getNoteByIntervalNum(num: number, isWithinOctave: boolean = false): Note`
511
+ ## Factory (工厂函数)
358
512
 
359
- ```
360
- import { factory } from 'music12';
361
- const cMajor = factory.getScale('C', 0, 4, 'MAJ');
362
- const note = cMajor.getNoteByIntervalNum(9); // C大调的第9音
363
- console.log(note.simpleDescription); // "D5"
513
+ 便捷创建实例,无需使用 `new` 和构造 `Note`。
514
+
515
+ ```ts
516
+ import { getNote, getInterval, getChord, getScale } from 'music12'
517
+
518
+ const note = getNote('C', 0, 4) // Note
519
+ const interval = getInterval('maj', 3) // Interval
520
+ const scale = getScale('C', 0, 'NATURAL_MAJOR') // Scale
521
+ const chord = getChord('G', 0, 'dom7') // Chord
364
522
  ```
365
523
 
366
- ##### `getScaleDegreeChord3()`
524
+ ---
367
525
 
368
- 获取音阶中指定度数的三和弦。 `getScaleDegreeChord3(scaleDegree: number): Chord`
526
+ ## Radix (乐理数学工具)
369
527
 
370
- ```
371
- import { factory } from 'music12';
372
- const cMajor = factory.getScale('C', 0, 4, 'MAJ');
373
- const dominantChord = cMajor.getScaleDegreeChord3(5); // 获取V级三和弦
374
- console.log(dominantChord.simpleDescription); // "G4,B4,D5"
375
- ```
528
+ 七进制和十二进制算术,用于乐理计算。
376
529
 
377
- ##### `getScaleDegreeChord7()`
530
+ ```ts
531
+ import { Radix } from 'music12'
378
532
 
379
- 获取音阶中指定度数的七和弦。 `getScaleDegreeChord7(scaleDegree: number): Chord`
533
+ // 七进制(自然音级数)
534
+ const degree = new Radix.Base7Radix(8)
535
+ degree.firstDigit // 1(八度)
536
+ degree.lastDigit // 1(度数索引)
380
537
 
538
+ // 十二进制(半音)
539
+ const pitch = new Radix.Base12Radix(14)
540
+ pitch.firstDigit // 1(八度)
541
+ pitch.lastDigit // 2(半音)
542
+
543
+ // 音名进制
544
+ const step = new Radix.StepRadix('C')
545
+ step.step // "C"
381
546
  ```
382
- import { factory } from 'music12';
383
- const aMinor = factory.getScale('A', 0, 4, 'MIN');
384
- const submediantChord = aMinor.getScaleDegreeChord7(7); // 获取VII级七和弦
385
- console.log(submediantChord.rootNote.artName + submediantChord.scoreSymbol); // "G7"
386
- ```
387
547
 
388
- ------
548
+ ---
549
+
550
+ ## Piano Key ID
389
551
 
390
- ### ✍️ 作者与授权 (Author & License)
552
+ 贯穿整个库,`pianoKeyId`(0-11)是核心音符标识符:
391
553
 
392
- #### 作者 (Author)
554
+ | pianoKeyId | 音符 |
555
+ |------------|------|
556
+ | 0 | C |
557
+ | 1 | C# / Db |
558
+ | 2 | D |
559
+ | 3 | D# / Eb |
560
+ | 4 | E |
561
+ | 5 | F |
562
+ | 6 | F# / Gb |
563
+ | 7 | G |
564
+ | 8 | G# / Ab |
565
+ | 9 | A |
566
+ | 10 | A# / Bb |
567
+ | 11 | B |
393
568
 
394
- - GitHub@guohub8080
395
- - 哔哩哔哩@方块郭
396
- - 如果您有任何问题或建议,欢迎通过 GitHub Issues 与我联系。
569
+ ---
397
570
 
398
- #### 授权协议 (License)
571
+ ## License
399
572
 
400
- 本仓库遵循 **MIT** 授权协议。
573
+ MIT