music12 1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (chordObj) 2025 guohub.top
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,400 @@
1
+ # music12
2
+ 欢迎使用 `music12`,这是一个功能强大、类型安全的 TypeScript/JavaScript 库,旨在为开发者提供一套完整、易用的工具,用于处理音符、音程、和弦、调式音阶等乐理概念的计算和分析。
3
+
4
+ 本库的核心设计理念是将抽象的乐理概念**对象化**。您可以创建 `Note`(音符)对象,用 `Interval`(音程)对象去操作它,将它们组合成 `Chord`(和弦)与 `Scale`(音阶)对象,并最终分析它们之间的和谐关系。
5
+
6
+ 无论您是在构建音乐教育软件、数字音频工作站(DAW)、自动作曲工具,还是仅仅想在您的项目中加入一些音乐元素,`music12` 都能为您提供坚实的基础。
7
+
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
+ - **🛠️ 丰富的音乐工具**: 内置五度圈计算、谱号查询等实用工具,满足多样化的开发需求。
18
+
19
+ ## 📦 安装
20
+ 将dist目录下的文件引入项目即可。
21
+
22
+ ## 🚀 快速上手 & 核心指南
23
+ 本指南将带您了解本库最核心的几个概念,并演示如何将它们组合起来解决实际的音乐问题。
24
+ #### 1. 基石:`Note` (音符)
25
+
26
+ `Note` 是本库最基础的构建单元。
27
+
28
+ ```
29
+ import { factory } from 'music12';
30
+
31
+ const c4 = factory.getNote('C', 0, 4);
32
+ const gSharp5 = factory.getNote('G', 1, 5);
33
+
34
+ // 探索音符的属性
35
+ console.log(c4.simpleDescription); // "C4"
36
+ console.log(gSharp5.artName); // "G#"
37
+ console.log(gSharp5.pitchValue); // 80 (MIDI 音高值)
38
+
39
+ // 对音符进行操作
40
+ const d4 = c4.semitoneMove(2); // 将 C4 向上移动2个半音
41
+ console.log(d4.artName); // "D"
42
+ ```
43
+
44
+ #### 2. 关系:`Interval` (音程)
45
+
46
+ `Interval` 定义了音符之间的“距离”。它是移动和构建和声的关键。
47
+
48
+ ```
49
+ import { Note } from 'music12/note';
50
+ import { Interval } from 'music12/interval';
51
+
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"
56
+ ```
57
+
58
+ #### 3. 和声:`Chord` (和弦)
59
+
60
+ `Chord` 是由一个根音 `Note` 和一组 `Interval` 构成的和谐之声。
61
+
62
+ ```
63
+ import { factory } from 'music12';
64
+
65
+ const g7 = factory.getChord('G', 0, 4, 'dom7');
66
+ console.log(g7.notesList.map(n => n.artName)); // [ 'G', 'B', 'D', 'F' ]
67
+
68
+ g7.setTransform('b9'); // 增加一个降九音 (Ab)
69
+ console.log(g7.notesList.map(n => n.artName)); // [ 'G', 'B', 'D', 'F', 'Ab' ]
70
+ ```
71
+
72
+ ## 📚 API 详细参考 (Class & Instance Reference)
73
+
74
+
75
+
76
+ 本节为您详细介绍 `music12` 中每一个核心类的构造方式、所有可访问的属性和方法。
77
+
78
+ ### `Note` 类
79
+
80
+ `Note` 对象是所有乐理计算的基础,代表一个具有绝对音高的音符。
81
+
82
+ #### 构造函数
83
+
84
+ ```
85
+ new Note(step?: t_noteStep, alter?: t_alterValue, octave?: number)
86
+ ```
87
+
88
+ ```
89
+ import { Note } from 'music12/note';
90
+ const aFlat4 = new Note('A', -1, 4);
91
+ ```
92
+
93
+ #### 属性
94
+
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` |
110
+
111
+ #### 方法
112
+
113
+ ##### `getNoteByInterval()`
114
+
115
+ 根据一个 `Interval` 实例,计算并返回一个新的 `Note` 实例。 `getNoteByInterval(intervalInstance: Interval, isAscending: boolean = true): Note`
116
+
117
+ ```
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"
124
+ ```
125
+
126
+ ##### `getNoteByIntervalString()`
127
+
128
+ 根据简化的数字和弦标记法(如 `b7`, `#4`)计算并返回一个新的 `Note` 实例。 `getNoteByIntervalString(numberNotationString: string, isAscending: boolean = true): Note`
129
+
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"
135
+ ```
136
+
137
+ ##### `getSamePitchNotes()`
138
+
139
+ 获取当前音符的所有“同音异名”音符。 `getSamePitchNotes(isSelfIncluded: boolean = true, alterAbsLessThan: 0 | 1 | 2 = 1): Note[]`
140
+
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' ]
146
+ ```
147
+
148
+ ##### `semitoneMove()`
149
+
150
+ 将当前音符按指定的半音数量移动,并智能地返回最常用的 `Note` 实例。 `semitoneMove(moveStep: number): Note`
151
+
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#)
157
+ ```
158
+
159
+ ##### `getHarmonicSeries()`
160
+
161
+ 获取当前音符的泛音序列。 `getHarmonicSeries(): { step: t_noteStep, ... }[]`
162
+
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
+ ```
169
+
170
+ ##### `get251as()`
171
+
172
+ 将当前音符作为 ii-V-I 进行中的某个角色,返回该进行中所有和弦的根音。 `get251as(noteAs: 1 | 2 | 5): Note[]`
173
+
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)
179
+ ```
180
+
181
+ ------
182
+
183
+ ### `Interval` 类
184
+
185
+ `Interval` 对象用于表示两个音符之间的距离。
186
+
187
+ #### 构造函数
188
+
189
+ ```
190
+ new Interval(intervalType?: t_intervalType, intervalNum?: number)
191
+ ```
192
+
193
+ ```
194
+ import { Interval } from 'music12/interval';
195
+ const minorThird = new Interval('min', 3);
196
+ ```
197
+
198
+ #### 属性
199
+
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` |
207
+
208
+ #### 方法
209
+
210
+
211
+
212
+
213
+
214
+ ##### `getEqualInterval()`
215
+
216
+
217
+
218
+ 获取与当前音程的半音数相同的所有其他音程。 `getEqualInterval(isSelfTypeExcluded?: boolean, isAugDimExcluded?: boolean, isDoubleAugDimExcluded?: boolean): Interval[]`
219
+
220
+ TypeScript
221
+
222
+ ```
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)); // [ '增四度', '减五度', '倍增三度', '倍减六度' ]
227
+ ```
228
+
229
+ ------
230
+
231
+ ### `Chord` 类
232
+
233
+ `Chord` 对象由一个根音和一种和弦类型构成。
234
+
235
+ #### 构造函数
236
+
237
+ ```
238
+ new Chord(rootNote: Note, chordKey: string, initTransform?: t_inputTransformPanel)
239
+ ```
240
+
241
+ ```
242
+ import { Chord } from 'music12/chord';
243
+ import { Note } from 'music12/note';
244
+ const cMaj7 = new Chord(new Note('C', 0, 4), 'maj7');
245
+ ```
246
+
247
+ #### 属性 (均为 Getter)
248
+
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'。 |
260
+
261
+ #### 方法
262
+
263
+ ##### `setTransform()`
264
+
265
+ 为和弦添加一个变化音。返回自身,支持链式调用。 `setTransform(transformString: t_transformString): Chord`
266
+
267
+ ```
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)"
272
+ ```
273
+
274
+ ##### `setOmit()`
275
+
276
+ 从和弦中省略一个音。 `setOmit(omitInterval: t_intervalNum): void`
277
+
278
+ ```
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' ]
283
+ ```
284
+
285
+ ##### `clearTransform()`
286
+
287
+ 移除所有已设置的变化音和省略音,将和弦恢复到其基础形态。 `clearTransform(): void`
288
+
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"
296
+ ```
297
+
298
+ ##### `tryToMergeTransform()`
299
+
300
+ 尝试将一个变化和弦识别为一个新的基础和弦。如果成功,返回一个新的 `Chord` 实例;否则返回应用了变化的原始和弦。 `tryToMergeTransform(): Chord`
301
+
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'
309
+ ```
310
+
311
+ ### `Scale` 类
312
+
313
+ `Scale` 对象代表一个由根音和特定调式构成的音阶。
314
+
315
+ #### 构造函数
316
+
317
+ ```
318
+ new Scale(rootNote: Note, scaleMode: t_scaleMode)
319
+ ```
320
+
321
+ ```
322
+ import { Scale } from 'music12/scale';
323
+ import { Note } from 'music12/note';
324
+ const aMinorScale = new Scale(new Note('A', 0, 4), 'MIN');
325
+ ```
326
+
327
+ #### 属性 (均为 Getter)
328
+
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[]` | 调式音级相对于自然大调的变化列表。 |
341
+
342
+ #### 方法
343
+
344
+ ##### `getScaleDegreeNote()`
345
+
346
+ 获取音阶中指定度数的音符。 `getScaleDegreeNote(degree: number): Note`
347
+
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的特色音)
353
+ ```
354
+
355
+ ##### `getNoteByIntervalNum()`
356
+
357
+ 功能与 `getScaleDegreeNote` 类似,但可以处理超过八度的度数。 `getNoteByIntervalNum(num: number, isWithinOctave: boolean = false): Note`
358
+
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"
364
+ ```
365
+
366
+ ##### `getScaleDegreeChord3()`
367
+
368
+ 获取音阶中指定度数的三和弦。 `getScaleDegreeChord3(scaleDegree: number): Chord`
369
+
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
+ ```
376
+
377
+ ##### `getScaleDegreeChord7()`
378
+
379
+ 获取音阶中指定度数的七和弦。 `getScaleDegreeChord7(scaleDegree: number): Chord`
380
+
381
+ ```
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
+
388
+ ------
389
+
390
+ ### ✍️ 作者与授权 (Author & License)
391
+
392
+ #### 作者 (Author)
393
+
394
+ - GitHub@guohub8080
395
+ - 哔哩哔哩@方块郭
396
+ - 如果您有任何问题或建议,欢迎通过 GitHub Issues 与我联系。
397
+
398
+ #### 授权协议 (License)
399
+
400
+ 本仓库遵循 **MIT** 授权协议。