@musodojo/music-theory-data 17.0.0 → 19.0.1
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/README.md +8 -8
- package/package.json +1 -1
- package/src/data/labels/note-labels.ts +19 -17
- package/src/data/note-collections/diatonic-modes.ts +16 -9
- package/src/data/note-collections/diminished-variants.ts +5 -3
- package/src/data/note-collections/dominant-variants.ts +2 -2
- package/src/data/note-collections/harmonic-minor-modes.ts +19 -10
- package/src/data/note-collections/major-variants.ts +3 -3
- package/src/data/note-collections/melodic-minor-modes.ts +19 -10
- package/src/data/note-collections/minor-variants.ts +28 -4
- package/src/data/note-collections/other-collections.ts +1 -4
- package/src/data/note-collections/pentatonic-variants.ts +25 -18
- package/src/types/midi.d.ts +0 -2
- package/src/types/note-collections.d.ts +26 -12
- package/src/utils/chords.ts +0 -15
- package/src/utils/midi-note-sequences.ts +3 -3
- package/src/utils/midi.ts +27 -26
- package/src/utils/note-names.ts +5 -11
package/README.md
CHANGED
|
@@ -13,9 +13,9 @@ more.**
|
|
|
13
13
|
## Verified Note Collections
|
|
14
14
|
|
|
15
15
|
- ✅ Diatonic Modes
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
16
|
+
- ✅ Pentatonic Variants
|
|
17
|
+
- ✅ Major Variants
|
|
18
|
+
- ✅ Minor Variants
|
|
19
19
|
- 🛠️ Dominant Variants
|
|
20
20
|
- ✅ Harmonic Minor Modes
|
|
21
21
|
- ✅ Melodic Minor Modes
|
|
@@ -38,16 +38,16 @@ more.**
|
|
|
38
38
|
|
|
39
39
|
### Deno / JSR
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Install the package from the JSR registry:
|
|
42
42
|
|
|
43
|
-
```
|
|
44
|
-
|
|
43
|
+
```bash
|
|
44
|
+
deno add jsr:@musodojo/music-theory-data
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Then import it into your project:
|
|
48
48
|
|
|
49
49
|
```ts
|
|
50
|
-
import * as music_theory_data from "
|
|
50
|
+
import * as music_theory_data from "@musodojo/music-theory-data";
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
### Node.js / npm
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type RootNoteInteger = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
|
|
2
2
|
|
|
3
3
|
const _noteLetters = [
|
|
4
4
|
"C",
|
|
@@ -53,15 +53,16 @@ export const noteNames: readonly NoteName[] = enharmonicNoteNameGroups.flat();
|
|
|
53
53
|
|
|
54
54
|
export const noteNamesSet: ReadonlySet<NoteName> = new Set(noteNames);
|
|
55
55
|
|
|
56
|
-
export const noteNameToIntegerMap: ReadonlyMap<NoteName,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
export const noteNameToIntegerMap: ReadonlyMap<NoteName, RootNoteInteger> =
|
|
57
|
+
(() => {
|
|
58
|
+
const map = new Map<NoteName, RootNoteInteger>();
|
|
59
|
+
_enharmonicNoteNameGroups.forEach((group, index) => {
|
|
60
|
+
group.forEach((note) => {
|
|
61
|
+
map.set(note, index as RootNoteInteger);
|
|
62
|
+
});
|
|
61
63
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
})();
|
|
64
|
+
return map;
|
|
65
|
+
})();
|
|
65
66
|
|
|
66
67
|
const _enharmonicRootNoteGroups = [
|
|
67
68
|
["C", "B♯"],
|
|
@@ -87,15 +88,16 @@ export const rootNotes: readonly RootNote[] = enharmonicRootNoteGroups.flat();
|
|
|
87
88
|
|
|
88
89
|
export const rootNotesSet: ReadonlySet<RootNote> = new Set(rootNotes);
|
|
89
90
|
|
|
90
|
-
export const rootNoteToIntegerMap: ReadonlyMap<RootNote,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
export const rootNoteToIntegerMap: ReadonlyMap<RootNote, RootNoteInteger> =
|
|
92
|
+
(() => {
|
|
93
|
+
const map = new Map<RootNote, RootNoteInteger>();
|
|
94
|
+
enharmonicRootNoteGroups.forEach((group, index) => {
|
|
95
|
+
group.forEach((note) => {
|
|
96
|
+
map.set(note, index as RootNoteInteger);
|
|
97
|
+
});
|
|
95
98
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})();
|
|
99
|
+
return map;
|
|
100
|
+
})();
|
|
99
101
|
|
|
100
102
|
export type SimpleIntervalNumber =
|
|
101
103
|
| "1"
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModalScaleCollection } from "../../types/note-collections.d.ts";
|
|
2
2
|
|
|
3
|
-
const ionian:
|
|
3
|
+
const ionian: ModalScaleCollection = {
|
|
4
4
|
category: "scale",
|
|
5
5
|
rotation: 0,
|
|
6
|
+
parentScale: "ionian",
|
|
6
7
|
primaryName: "Major",
|
|
7
8
|
names: [
|
|
8
9
|
"Major",
|
|
@@ -41,9 +42,10 @@ const ionian: ScaleCollection = {
|
|
|
41
42
|
patternShort: ["W", "W", "H", "W", "W", "W", "H"],
|
|
42
43
|
} as const;
|
|
43
44
|
|
|
44
|
-
const dorian:
|
|
45
|
+
const dorian: ModalScaleCollection = {
|
|
45
46
|
category: "scale",
|
|
46
47
|
rotation: 1,
|
|
48
|
+
parentScale: "ionian",
|
|
47
49
|
primaryName: "Dorian",
|
|
48
50
|
names: [
|
|
49
51
|
"Dorian",
|
|
@@ -80,9 +82,10 @@ const dorian: ScaleCollection = {
|
|
|
80
82
|
patternShort: ["W", "H", "W", "W", "W", "H", "W"],
|
|
81
83
|
} as const;
|
|
82
84
|
|
|
83
|
-
const phrygian:
|
|
85
|
+
const phrygian: ModalScaleCollection = {
|
|
84
86
|
category: "scale",
|
|
85
87
|
rotation: 2,
|
|
88
|
+
parentScale: "ionian",
|
|
86
89
|
primaryName: "Phrygian",
|
|
87
90
|
names: [
|
|
88
91
|
"Phrygian",
|
|
@@ -117,9 +120,10 @@ const phrygian: ScaleCollection = {
|
|
|
117
120
|
patternShort: ["H", "W", "W", "W", "H", "W", "W"],
|
|
118
121
|
} as const;
|
|
119
122
|
|
|
120
|
-
const lydian:
|
|
123
|
+
const lydian: ModalScaleCollection = {
|
|
121
124
|
category: "scale",
|
|
122
125
|
rotation: 3,
|
|
126
|
+
parentScale: "ionian",
|
|
123
127
|
primaryName: "Lydian",
|
|
124
128
|
names: ["Lydian", "Major ♯4", "Lydian Mode"],
|
|
125
129
|
intervals: ["1", "2", "3", "♯4", "5", "6", "7", "8"],
|
|
@@ -148,9 +152,10 @@ const lydian: ScaleCollection = {
|
|
|
148
152
|
patternShort: ["W", "W", "W", "H", "W", "W", "H"],
|
|
149
153
|
} as const;
|
|
150
154
|
|
|
151
|
-
const mixolydian:
|
|
155
|
+
const mixolydian: ModalScaleCollection = {
|
|
152
156
|
category: "scale",
|
|
153
157
|
rotation: 4,
|
|
158
|
+
parentScale: "ionian",
|
|
154
159
|
primaryName: "Mixolydian",
|
|
155
160
|
names: [
|
|
156
161
|
"Mixolydian",
|
|
@@ -185,9 +190,10 @@ const mixolydian: ScaleCollection = {
|
|
|
185
190
|
patternShort: ["W", "W", "H", "W", "W", "H", "W"],
|
|
186
191
|
} as const;
|
|
187
192
|
|
|
188
|
-
const aeolian:
|
|
193
|
+
const aeolian: ModalScaleCollection = {
|
|
189
194
|
category: "scale",
|
|
190
195
|
rotation: 5,
|
|
196
|
+
parentScale: "ionian",
|
|
191
197
|
primaryName: "Minor",
|
|
192
198
|
names: [
|
|
193
199
|
"Minor",
|
|
@@ -223,9 +229,10 @@ const aeolian: ScaleCollection = {
|
|
|
223
229
|
patternShort: ["W", "H", "W", "W", "H", "W", "W"],
|
|
224
230
|
} as const;
|
|
225
231
|
|
|
226
|
-
const locrian:
|
|
232
|
+
const locrian: ModalScaleCollection = {
|
|
227
233
|
category: "scale",
|
|
228
234
|
rotation: 6,
|
|
235
|
+
parentScale: "ionian",
|
|
229
236
|
primaryName: "Locrian",
|
|
230
237
|
names: [
|
|
231
238
|
"Locrian",
|
|
@@ -270,5 +277,5 @@ const _diatonicModes = {
|
|
|
270
277
|
|
|
271
278
|
export type DiatonicModeKey = keyof typeof _diatonicModes;
|
|
272
279
|
|
|
273
|
-
export const diatonicModes: Record<DiatonicModeKey,
|
|
280
|
+
export const diatonicModes: Record<DiatonicModeKey, ModalScaleCollection> =
|
|
274
281
|
_diatonicModes;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ChordCollection,
|
|
3
|
+
ModalScaleCollection,
|
|
3
4
|
NoteCollection,
|
|
4
|
-
ScaleCollection,
|
|
5
5
|
} from "../../types/note-collections.d.ts";
|
|
6
6
|
|
|
7
7
|
const diminishedTriad: ChordCollection = {
|
|
@@ -40,9 +40,10 @@ const halfDiminished7: ChordCollection = {
|
|
|
40
40
|
patternShort: ["m3", "m3", "M3"],
|
|
41
41
|
} as const;
|
|
42
42
|
|
|
43
|
-
const wholeHalfDiminished:
|
|
43
|
+
const wholeHalfDiminished: ModalScaleCollection = {
|
|
44
44
|
category: "scale",
|
|
45
45
|
rotation: 0,
|
|
46
|
+
parentScale: "wholeHalfDiminished",
|
|
46
47
|
primaryName: "Whole Half Diminished",
|
|
47
48
|
names: ["Whole Half Diminished"],
|
|
48
49
|
intervals: ["1", "2", "♭3", "4", "♭5", "♭6", "6", "7", "8"],
|
|
@@ -53,9 +54,10 @@ const wholeHalfDiminished: ScaleCollection = {
|
|
|
53
54
|
patternShort: ["W", "H", "W", "H", "W", "H", "W", "H"],
|
|
54
55
|
} as const;
|
|
55
56
|
|
|
56
|
-
const halfWholeDiminished:
|
|
57
|
+
const halfWholeDiminished: ModalScaleCollection = {
|
|
57
58
|
category: "scale",
|
|
58
59
|
rotation: 1,
|
|
60
|
+
parentScale: "wholeHalfDiminished",
|
|
59
61
|
primaryName: "Half Whole Diminished",
|
|
60
62
|
names: ["Half Whole Diminished", "Dominant Diminished"],
|
|
61
63
|
intervals: ["1", "♭2", "♭3", "3", "♯4", "5", "6", "♭7", "8"],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ChordCollection,
|
|
3
|
+
NonModalScaleCollection,
|
|
3
4
|
NoteCollection,
|
|
4
|
-
ScaleCollection,
|
|
5
5
|
} from "../../types/note-collections.d.ts";
|
|
6
6
|
|
|
7
7
|
const dominant7: ChordCollection = {
|
|
@@ -105,7 +105,7 @@ const dominant13: ChordCollection = {
|
|
|
105
105
|
patternShort: ["M3", "m3", "m3", "M3", "m3", "m3"],
|
|
106
106
|
} as const;
|
|
107
107
|
|
|
108
|
-
const dominantPentatonic:
|
|
108
|
+
const dominantPentatonic: NonModalScaleCollection = {
|
|
109
109
|
category: "scale",
|
|
110
110
|
primaryName: "Dominant Pentatonic",
|
|
111
111
|
names: ["Dominant Pentatonic"],
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModalScaleCollection } from "../../types/note-collections.d.ts";
|
|
2
2
|
|
|
3
|
-
const harmonicMinor:
|
|
3
|
+
const harmonicMinor: ModalScaleCollection = {
|
|
4
4
|
category: "scale",
|
|
5
5
|
rotation: 0,
|
|
6
|
+
parentScale: "harmonicMinor",
|
|
6
7
|
primaryName: "Harmonic Minor",
|
|
7
8
|
names: [
|
|
8
9
|
"Harmonic Minor",
|
|
@@ -34,9 +35,10 @@ const harmonicMinor: ScaleCollection = {
|
|
|
34
35
|
patternShort: ["W", "H", "W", "W", "H", "A2", "H"],
|
|
35
36
|
} as const;
|
|
36
37
|
|
|
37
|
-
const locrianNatural6:
|
|
38
|
+
const locrianNatural6: ModalScaleCollection = {
|
|
38
39
|
category: "scale",
|
|
39
40
|
rotation: 1,
|
|
41
|
+
parentScale: "harmonicMinor",
|
|
40
42
|
primaryName: "Locrian ♮6",
|
|
41
43
|
names: ["Locrian ♮6", "Locrian Natural Sixth", "Locrian Raised Sixth"],
|
|
42
44
|
intervals: ["1", "♭2", "♭3", "4", "♭5", "6", "♭7", "8"],
|
|
@@ -61,9 +63,10 @@ const locrianNatural6: ScaleCollection = {
|
|
|
61
63
|
patternShort: ["H", "W", "W", "H", "A2", "H", "W"],
|
|
62
64
|
} as const;
|
|
63
65
|
|
|
64
|
-
const ionianSharp5:
|
|
66
|
+
const ionianSharp5: ModalScaleCollection = {
|
|
65
67
|
category: "scale",
|
|
66
68
|
rotation: 2,
|
|
69
|
+
parentScale: "harmonicMinor",
|
|
67
70
|
primaryName: "Ionian ♯5",
|
|
68
71
|
names: [
|
|
69
72
|
"Ionian ♯5",
|
|
@@ -100,9 +103,10 @@ const ionianSharp5: ScaleCollection = {
|
|
|
100
103
|
patternShort: ["W", "W", "H", "A2", "H", "W", "H"],
|
|
101
104
|
} as const;
|
|
102
105
|
|
|
103
|
-
const dorianSharp4:
|
|
106
|
+
const dorianSharp4: ModalScaleCollection = {
|
|
104
107
|
category: "scale",
|
|
105
108
|
rotation: 3,
|
|
109
|
+
parentScale: "harmonicMinor",
|
|
106
110
|
primaryName: "Dorian ♯4",
|
|
107
111
|
names: [
|
|
108
112
|
"Dorian ♯4",
|
|
@@ -133,9 +137,10 @@ const dorianSharp4: ScaleCollection = {
|
|
|
133
137
|
patternShort: ["W", "H", "A2", "H", "W", "H", "W"],
|
|
134
138
|
} as const;
|
|
135
139
|
|
|
136
|
-
const phrygianDominant:
|
|
140
|
+
const phrygianDominant: ModalScaleCollection = {
|
|
137
141
|
category: "scale",
|
|
138
142
|
rotation: 4,
|
|
143
|
+
parentScale: "harmonicMinor",
|
|
139
144
|
primaryName: "Phrygian Dominant",
|
|
140
145
|
names: [
|
|
141
146
|
"Phrygian Dominant",
|
|
@@ -172,9 +177,10 @@ const phrygianDominant: ScaleCollection = {
|
|
|
172
177
|
patternShort: ["H", "A2", "H", "W", "H", "W", "W"],
|
|
173
178
|
} as const;
|
|
174
179
|
|
|
175
|
-
const lydianSharp2:
|
|
180
|
+
const lydianSharp2: ModalScaleCollection = {
|
|
176
181
|
category: "scale",
|
|
177
182
|
rotation: 5,
|
|
183
|
+
parentScale: "harmonicMinor",
|
|
178
184
|
primaryName: "Lydian ♯2",
|
|
179
185
|
names: [
|
|
180
186
|
"Lydian ♯2",
|
|
@@ -204,9 +210,10 @@ const lydianSharp2: ScaleCollection = {
|
|
|
204
210
|
patternShort: ["A2", "H", "W", "H", "W", "W", "H"],
|
|
205
211
|
} as const;
|
|
206
212
|
|
|
207
|
-
const superLocrianDoubleFlat7:
|
|
213
|
+
const superLocrianDoubleFlat7: ModalScaleCollection = {
|
|
208
214
|
category: "scale",
|
|
209
215
|
rotation: 6,
|
|
216
|
+
parentScale: "harmonicMinor",
|
|
210
217
|
primaryName: "Super Locrian 𝄫7",
|
|
211
218
|
names: [
|
|
212
219
|
"Super Locrian 𝄫7",
|
|
@@ -248,5 +255,7 @@ export const _harmonicMinorModes = {
|
|
|
248
255
|
|
|
249
256
|
export type HarmonicMinorModeKey = keyof typeof _harmonicMinorModes;
|
|
250
257
|
|
|
251
|
-
export const harmonicMinorModes: Record<
|
|
252
|
-
|
|
258
|
+
export const harmonicMinorModes: Record<
|
|
259
|
+
HarmonicMinorModeKey,
|
|
260
|
+
ModalScaleCollection
|
|
261
|
+
> = _harmonicMinorModes;
|
|
@@ -61,7 +61,7 @@ const major9: ChordCollection = {
|
|
|
61
61
|
primaryName: "M9",
|
|
62
62
|
names: ["M9", "maj9", "Major 9th", "Major Ninth", "Δ9"],
|
|
63
63
|
intervals: ["1", "3", "5", "7", "9"],
|
|
64
|
-
integers: [0,
|
|
64
|
+
integers: [0, 4, 7, 11, 14],
|
|
65
65
|
type: ["major", "chord", "arpeggio", "pentad"],
|
|
66
66
|
characteristics: [
|
|
67
67
|
"stable",
|
|
@@ -81,7 +81,7 @@ const majorAdd9: ChordCollection = {
|
|
|
81
81
|
primaryName: "add9",
|
|
82
82
|
names: ["add9", "maj(add9)", "M(add9)", "Major add 9"],
|
|
83
83
|
intervals: ["1", "3", "5", "9"],
|
|
84
|
-
integers: [0,
|
|
84
|
+
integers: [0, 4, 7, 14],
|
|
85
85
|
type: ["major", "chord", "arpeggio", "tetrad"],
|
|
86
86
|
characteristics: [
|
|
87
87
|
"stable",
|
|
@@ -101,7 +101,7 @@ const major6Add9: ChordCollection = {
|
|
|
101
101
|
primaryName: "6/9",
|
|
102
102
|
names: ["6/9", "M6/9", "maj6/9", "Major 6/9", "6add9", "Major add 6 add 9"],
|
|
103
103
|
intervals: ["1", "3", "5", "6", "9"],
|
|
104
|
-
integers: [0,
|
|
104
|
+
integers: [0, 4, 7, 9, 14],
|
|
105
105
|
type: ["major", "chord", "arpeggio", "pentad"],
|
|
106
106
|
characteristics: [
|
|
107
107
|
"stable",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModalScaleCollection } from "../../types/note-collections.d.ts";
|
|
2
2
|
|
|
3
|
-
const melodicMinor:
|
|
3
|
+
const melodicMinor: ModalScaleCollection = {
|
|
4
4
|
category: "scale",
|
|
5
5
|
rotation: 0,
|
|
6
|
+
parentScale: "melodicMinor",
|
|
6
7
|
primaryName: "Melodic Minor",
|
|
7
8
|
names: [
|
|
8
9
|
"Melodic Minor",
|
|
@@ -33,9 +34,10 @@ const melodicMinor: ScaleCollection = {
|
|
|
33
34
|
patternShort: ["W", "H", "W", "W", "W", "W", "H"],
|
|
34
35
|
} as const;
|
|
35
36
|
|
|
36
|
-
const dorianFlat2:
|
|
37
|
+
const dorianFlat2: ModalScaleCollection = {
|
|
37
38
|
category: "scale",
|
|
38
39
|
rotation: 1,
|
|
40
|
+
parentScale: "melodicMinor",
|
|
39
41
|
primaryName: "Dorian ♭2",
|
|
40
42
|
names: [
|
|
41
43
|
"Dorian ♭2",
|
|
@@ -59,9 +61,10 @@ const dorianFlat2: ScaleCollection = {
|
|
|
59
61
|
patternShort: ["H", "W", "W", "W", "W", "H", "W"],
|
|
60
62
|
} as const;
|
|
61
63
|
|
|
62
|
-
const lydianAugmented:
|
|
64
|
+
const lydianAugmented: ModalScaleCollection = {
|
|
63
65
|
category: "scale",
|
|
64
66
|
rotation: 2,
|
|
67
|
+
parentScale: "melodicMinor",
|
|
65
68
|
primaryName: "Lydian Augmented",
|
|
66
69
|
names: ["Lydian Augmented", "Lydian ♯5", "Lydian Sharp Fifth"],
|
|
67
70
|
intervals: ["1", "2", "3", "♯4", "♯5", "6", "7", "8"],
|
|
@@ -86,9 +89,10 @@ const lydianAugmented: ScaleCollection = {
|
|
|
86
89
|
patternShort: ["W", "W", "W", "W", "H", "W", "H"],
|
|
87
90
|
} as const;
|
|
88
91
|
|
|
89
|
-
const lydianDominant:
|
|
92
|
+
const lydianDominant: ModalScaleCollection = {
|
|
90
93
|
category: "scale",
|
|
91
94
|
rotation: 3,
|
|
95
|
+
parentScale: "melodicMinor",
|
|
92
96
|
primaryName: "Lydian Dominant",
|
|
93
97
|
names: [
|
|
94
98
|
"Lydian Dominant",
|
|
@@ -116,9 +120,10 @@ const lydianDominant: ScaleCollection = {
|
|
|
116
120
|
patternShort: ["W", "W", "W", "H", "W", "H", "W"],
|
|
117
121
|
} as const;
|
|
118
122
|
|
|
119
|
-
const mixolydianFlat6:
|
|
123
|
+
const mixolydianFlat6: ModalScaleCollection = {
|
|
120
124
|
category: "scale",
|
|
121
125
|
rotation: 4,
|
|
126
|
+
parentScale: "melodicMinor",
|
|
122
127
|
primaryName: "Mixolydian ♭6",
|
|
123
128
|
names: [
|
|
124
129
|
"Mixolydian ♭6",
|
|
@@ -143,9 +148,10 @@ const mixolydianFlat6: ScaleCollection = {
|
|
|
143
148
|
patternShort: ["W", "W", "H", "W", "H", "W", "W"],
|
|
144
149
|
} as const;
|
|
145
150
|
|
|
146
|
-
const aeolianFlat5:
|
|
151
|
+
const aeolianFlat5: ModalScaleCollection = {
|
|
147
152
|
category: "scale",
|
|
148
153
|
rotation: 5,
|
|
154
|
+
parentScale: "melodicMinor",
|
|
149
155
|
primaryName: "Aeolian ♭5",
|
|
150
156
|
names: [
|
|
151
157
|
"Aeolian ♭5",
|
|
@@ -170,9 +176,10 @@ const aeolianFlat5: ScaleCollection = {
|
|
|
170
176
|
patternShort: ["W", "H", "W", "H", "W", "W", "W"],
|
|
171
177
|
} as const;
|
|
172
178
|
|
|
173
|
-
const altered:
|
|
179
|
+
const altered: ModalScaleCollection = {
|
|
174
180
|
category: "scale",
|
|
175
181
|
rotation: 6,
|
|
182
|
+
parentScale: "melodicMinor",
|
|
176
183
|
primaryName: "Altered Scale",
|
|
177
184
|
names: [
|
|
178
185
|
"Altered Scale",
|
|
@@ -208,5 +215,7 @@ export const _melodicMinorModes = {
|
|
|
208
215
|
|
|
209
216
|
export type MelodicMinorModeKey = keyof typeof _melodicMinorModes;
|
|
210
217
|
|
|
211
|
-
export const melodicMinorModes: Record<
|
|
212
|
-
|
|
218
|
+
export const melodicMinorModes: Record<
|
|
219
|
+
MelodicMinorModeKey,
|
|
220
|
+
ModalScaleCollection
|
|
221
|
+
> = _melodicMinorModes;
|
|
@@ -46,12 +46,35 @@ const minor7: ChordCollection = {
|
|
|
46
46
|
patternShort: ["m3", "M3", "m3"],
|
|
47
47
|
} as const;
|
|
48
48
|
|
|
49
|
+
const minorMajor7: ChordCollection = {
|
|
50
|
+
category: "chord",
|
|
51
|
+
primaryName: "m(M7)",
|
|
52
|
+
names: [
|
|
53
|
+
"m(M7)",
|
|
54
|
+
"min(M7)",
|
|
55
|
+
"Minor (Major 7th)",
|
|
56
|
+
"Minor Major Seventh",
|
|
57
|
+
"mM7",
|
|
58
|
+
"-M7",
|
|
59
|
+
"-(maj7)",
|
|
60
|
+
],
|
|
61
|
+
intervals: ["1", "♭3", "5", "7"],
|
|
62
|
+
integers: [0, 3, 7, 11],
|
|
63
|
+
type: ["minor", "chord", "arpeggio", "tetrad"],
|
|
64
|
+
characteristics: [
|
|
65
|
+
"smooth",
|
|
66
|
+
"jazzy",
|
|
67
|
+
],
|
|
68
|
+
pattern: ["minor third", "major third", "major third"],
|
|
69
|
+
patternShort: ["m3", "M3", "M3"],
|
|
70
|
+
};
|
|
71
|
+
|
|
49
72
|
const minor9: ChordCollection = {
|
|
50
73
|
category: "chord",
|
|
51
74
|
primaryName: "m9",
|
|
52
75
|
names: ["m9", "min9", "Minor 9th", "Minor Ninth", "-9"],
|
|
53
76
|
intervals: ["1", "♭3", "5", "♭7", "9"],
|
|
54
|
-
integers: [0,
|
|
77
|
+
integers: [0, 3, 7, 10, 14],
|
|
55
78
|
type: ["minor", "chord", "arpeggio", "pentad"],
|
|
56
79
|
characteristics: ["rich", "lush", "sophisticated", "common in jazz"],
|
|
57
80
|
pattern: ["minor third", "major third", "minor third", "major third"],
|
|
@@ -63,7 +86,7 @@ const minorAdd9: ChordCollection = {
|
|
|
63
86
|
primaryName: "m(add9)",
|
|
64
87
|
names: ["m(add9)", "min(add9)", "Minor add 9"],
|
|
65
88
|
intervals: ["1", "♭3", "5", "9"],
|
|
66
|
-
integers: [0,
|
|
89
|
+
integers: [0, 3, 7, 14],
|
|
67
90
|
type: ["minor", "chord", "arpeggio", "tetrad"],
|
|
68
91
|
characteristics: [
|
|
69
92
|
"open",
|
|
@@ -78,9 +101,9 @@ const minorAdd9: ChordCollection = {
|
|
|
78
101
|
const minor6Add9: ChordCollection = {
|
|
79
102
|
category: "chord",
|
|
80
103
|
primaryName: "m6/9",
|
|
81
|
-
names: ["m6/9", "min6/9", "Minor 6/9"],
|
|
104
|
+
names: ["m6/9", "min6/9", "Minor 6/9", "-6/9"],
|
|
82
105
|
intervals: ["1", "♭3", "5", "6", "9"],
|
|
83
|
-
integers: [0,
|
|
106
|
+
integers: [0, 3, 7, 9, 14],
|
|
84
107
|
type: ["minor", "chord", "arpeggio", "pentad"],
|
|
85
108
|
characteristics: [
|
|
86
109
|
"rich",
|
|
@@ -96,6 +119,7 @@ export const _minorVariants = {
|
|
|
96
119
|
minor,
|
|
97
120
|
minor6,
|
|
98
121
|
minor7,
|
|
122
|
+
minorMajor7,
|
|
99
123
|
minor9,
|
|
100
124
|
minorAdd9,
|
|
101
125
|
minor6Add9,
|
|
@@ -49,11 +49,8 @@ const chromatic: ScaleCollection = {
|
|
|
49
49
|
|
|
50
50
|
const wholeTone: ScaleCollection = {
|
|
51
51
|
category: "scale",
|
|
52
|
-
rotation: 0,
|
|
53
52
|
primaryName: "Whole Tone Scale",
|
|
54
|
-
names: [
|
|
55
|
-
"Whole Tone Scale",
|
|
56
|
-
],
|
|
53
|
+
names: ["Whole Tone Scale"],
|
|
57
54
|
intervals: ["1", "2", "3", "♯4", "♯5", "♯6", "8"],
|
|
58
55
|
integers: [0, 2, 4, 6, 8, 10],
|
|
59
56
|
type: ["whole tone", "scale", "symmetrical", "hexatonic"],
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ModalScaleCollection } from "../../types/note-collections.d.ts";
|
|
2
2
|
|
|
3
|
-
const majorPentatonic:
|
|
3
|
+
const majorPentatonic: ModalScaleCollection = {
|
|
4
4
|
category: "scale",
|
|
5
5
|
rotation: 0,
|
|
6
|
+
parentScale: "majorPentatonic",
|
|
6
7
|
primaryName: "Major Pentatonic",
|
|
7
8
|
names: ["Major Pentatonic"],
|
|
8
9
|
intervals: ["1", "2", "3", "5", "6", "8"],
|
|
@@ -20,48 +21,52 @@ const majorPentatonic: ScaleCollection = {
|
|
|
20
21
|
patternShort: ["W", "W", "m3", "W", "m3"],
|
|
21
22
|
} as const;
|
|
22
23
|
|
|
23
|
-
const suspendedPentatonic:
|
|
24
|
+
const suspendedPentatonic: ModalScaleCollection = {
|
|
24
25
|
category: "scale",
|
|
25
26
|
rotation: 1,
|
|
27
|
+
parentScale: "majorPentatonic",
|
|
26
28
|
primaryName: "Suspended Pentatonic",
|
|
27
29
|
names: ["Suspended Pentatonic", "Egyptian Pentatonic"],
|
|
28
30
|
intervals: ["1", "2", "4", "5", "♭7", "8"],
|
|
29
31
|
integers: [0, 2, 5, 7, 10],
|
|
30
32
|
type: ["suspended", "pentatonic", "scale", "gapped scale"],
|
|
31
33
|
characteristics: ["open", "stable", "neutral", "neither major nor minor"],
|
|
32
|
-
pattern: ["whole", "minor third", "whole", "minor third"],
|
|
33
|
-
patternShort: ["W", "m3", "W", "m3"],
|
|
34
|
+
pattern: ["whole", "minor third", "whole", "minor third", "whole"],
|
|
35
|
+
patternShort: ["W", "m3", "W", "m3", "W"],
|
|
34
36
|
} as const;
|
|
35
37
|
|
|
36
|
-
const bluesMinorPentatonic:
|
|
38
|
+
const bluesMinorPentatonic: ModalScaleCollection = {
|
|
37
39
|
category: "scale",
|
|
38
40
|
rotation: 2,
|
|
41
|
+
parentScale: "majorPentatonic",
|
|
39
42
|
primaryName: "Blues Minor Pentatonic",
|
|
40
43
|
names: ["Blues Minor Pentatonic"],
|
|
41
|
-
intervals: ["1", "♭3", "4", "♭
|
|
44
|
+
intervals: ["1", "♭3", "4", "♭6", "♭7", "8"],
|
|
42
45
|
integers: [0, 3, 5, 8, 10],
|
|
43
46
|
type: ["minor", "pentatonic", "scale", "gapped scale", "blues"],
|
|
44
|
-
characteristics: ["bluesy", "tense"
|
|
45
|
-
pattern: ["minor third", "whole", "
|
|
46
|
-
patternShort: ["m3", "W", "
|
|
47
|
+
characteristics: ["bluesy", "tense"],
|
|
48
|
+
pattern: ["minor third", "whole", "minor third", "whole", "whole"],
|
|
49
|
+
patternShort: ["m3", "W", "m3", "W", "W"],
|
|
47
50
|
} as const;
|
|
48
51
|
|
|
49
|
-
const bluesMajorPentatonic:
|
|
52
|
+
const bluesMajorPentatonic: ModalScaleCollection = {
|
|
50
53
|
category: "scale",
|
|
51
54
|
rotation: 3,
|
|
55
|
+
parentScale: "majorPentatonic",
|
|
52
56
|
primaryName: "Blues Major Pentatonic",
|
|
53
57
|
names: ["Blues Major Pentatonic"],
|
|
54
|
-
intervals: ["1", "2", "
|
|
58
|
+
intervals: ["1", "2", "4", "5", "6", "8"],
|
|
55
59
|
integers: [0, 2, 5, 7, 9],
|
|
56
60
|
type: ["major", "pentatonic", "scale", "gapped scale", "blues"],
|
|
57
|
-
characteristics: ["bluesy", "country"
|
|
58
|
-
pattern: ["whole", "
|
|
59
|
-
patternShort: ["W", "
|
|
61
|
+
characteristics: ["bluesy", "country"],
|
|
62
|
+
pattern: ["whole", "minor third", "whole", "whole", "minor third"],
|
|
63
|
+
patternShort: ["W", "m3", "W", "W", "m3"],
|
|
60
64
|
} as const;
|
|
61
65
|
|
|
62
|
-
const minorPentatonic:
|
|
66
|
+
const minorPentatonic: ModalScaleCollection = {
|
|
63
67
|
category: "scale",
|
|
64
68
|
rotation: 4,
|
|
69
|
+
parentScale: "majorPentatonic",
|
|
65
70
|
primaryName: "Minor Pentatonic",
|
|
66
71
|
names: ["Minor Pentatonic"],
|
|
67
72
|
intervals: ["1", "♭3", "4", "5", "♭7", "8"],
|
|
@@ -88,5 +93,7 @@ export const _pentatonicVariants = {
|
|
|
88
93
|
|
|
89
94
|
export type PentatonicVariantKey = keyof typeof _pentatonicVariants;
|
|
90
95
|
|
|
91
|
-
export const pentatonicVariants: Record<
|
|
92
|
-
|
|
96
|
+
export const pentatonicVariants: Record<
|
|
97
|
+
PentatonicVariantKey,
|
|
98
|
+
ModalScaleCollection
|
|
99
|
+
> = _pentatonicVariants;
|
package/src/types/midi.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Interval
|
|
1
|
+
import type { Interval } from "../data/labels/note-labels.ts";
|
|
2
2
|
|
|
3
3
|
export type CollectionCategory = "scale" | "chord";
|
|
4
4
|
|
|
@@ -20,10 +20,11 @@ interface NoteCollectionBase {
|
|
|
20
20
|
*/
|
|
21
21
|
readonly intervals: readonly Interval[];
|
|
22
22
|
/**
|
|
23
|
-
* The set of
|
|
24
|
-
*
|
|
23
|
+
* The set of semitone values from the root.
|
|
24
|
+
* - For **scales**, this is a pitch class set (0-11) and does not include the octave.
|
|
25
|
+
* - For **chords**, this can include values > 11 to represent extensions (e.g., 14 for a 9th).
|
|
25
26
|
*/
|
|
26
|
-
readonly integers: readonly
|
|
27
|
+
readonly integers: readonly number[];
|
|
27
28
|
/**
|
|
28
29
|
* An array of tags used for classification and filtering.
|
|
29
30
|
* e.g., ["major", "scale", "heptatonic", "diatonic mode"]
|
|
@@ -48,20 +49,29 @@ interface NoteCollectionBase {
|
|
|
48
49
|
readonly patternShort: readonly string[];
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
/** A scale that can be thought of as a mode of a parent scale (e.g., Ionian, Dorian, Lydian Augmented). */
|
|
53
|
+
interface ModalScaleCollection extends NoteCollectionBase {
|
|
52
54
|
/**
|
|
53
55
|
* The fundamental classification of the collection. For scales, this is always "scale".
|
|
54
|
-
* This influences the interpretation of other properties:
|
|
55
|
-
* - `intervals` conventionally includes the octave ("8").
|
|
56
|
-
* - `pattern` represents steps between consecutive notes.
|
|
57
56
|
*/
|
|
58
57
|
readonly category: "scale";
|
|
59
58
|
/**
|
|
60
|
-
* The rotation index
|
|
61
|
-
*
|
|
62
|
-
* to collections that are modes of another scale.
|
|
59
|
+
* The rotation index for a parent scale is always 0.
|
|
60
|
+
* The rotation index relative to a parent scale. e.g., Dorian is 1.
|
|
63
61
|
*/
|
|
64
|
-
readonly rotation
|
|
62
|
+
readonly rotation: number;
|
|
63
|
+
/**
|
|
64
|
+
* The key-name (e.g., "ionian") of the parent scale from which this mode is derived.
|
|
65
|
+
* The parent scale has itself as parentScale!
|
|
66
|
+
*/
|
|
67
|
+
readonly parentScale: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** A scale that is not a mode of another scale in this collection. */
|
|
71
|
+
interface NonModalScaleCollection extends NoteCollectionBase {
|
|
72
|
+
readonly category: "scale";
|
|
73
|
+
readonly rotation?: never;
|
|
74
|
+
readonly parentScale?: never;
|
|
65
75
|
}
|
|
66
76
|
|
|
67
77
|
export interface ChordCollection extends NoteCollectionBase {
|
|
@@ -69,4 +79,8 @@ export interface ChordCollection extends NoteCollectionBase {
|
|
|
69
79
|
readonly rotation?: never;
|
|
70
80
|
}
|
|
71
81
|
|
|
82
|
+
export type ScaleCollection =
|
|
83
|
+
| ModalScaleCollection
|
|
84
|
+
| NonModalScaleCollection;
|
|
85
|
+
|
|
72
86
|
export type NoteCollection = ScaleCollection | ChordCollection;
|
package/src/utils/chords.ts
CHANGED
|
@@ -100,11 +100,6 @@ export function getChordDetailsForDiatonicMode(
|
|
|
100
100
|
diatonicModeKey: DiatonicModeKey,
|
|
101
101
|
): ChordDetails[] {
|
|
102
102
|
const mode = diatonicModes[diatonicModeKey];
|
|
103
|
-
if (mode.rotation === undefined) {
|
|
104
|
-
throw new Error(
|
|
105
|
-
`Mode "${diatonicModeKey}" is missing the 'rotation' property.`,
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
103
|
const rotation = mode.rotation;
|
|
109
104
|
const rotatedTriads = rotateArray(diatonicTriads, rotation);
|
|
110
105
|
const rotatedSeventhChords = rotateArray(diatonicSeventhChords, rotation);
|
|
@@ -121,11 +116,6 @@ export function getChordDetailsForHarmonicMinorMode(
|
|
|
121
116
|
harmonicMinorModeKey: HarmonicMinorModeKey,
|
|
122
117
|
): ChordDetails[] {
|
|
123
118
|
const mode = harmonicMinorModes[harmonicMinorModeKey];
|
|
124
|
-
if (mode.rotation === undefined) {
|
|
125
|
-
throw new Error(
|
|
126
|
-
`Mode "${harmonicMinorModeKey}" is missing the 'rotation' property.`,
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
119
|
const rotation = mode.rotation;
|
|
130
120
|
const rotatedTriads = rotateArray(harmonicMinorTriads, rotation);
|
|
131
121
|
const rotatedSeventhChords = rotateArray(
|
|
@@ -145,11 +135,6 @@ export function getChordDetailsForMelodicMinorMode(
|
|
|
145
135
|
melodicMinorModeKey: MelodicMinorModeKey,
|
|
146
136
|
): ChordDetails[] {
|
|
147
137
|
const mode = melodicMinorModes[melodicMinorModeKey];
|
|
148
|
-
if (mode.rotation === undefined) {
|
|
149
|
-
throw new Error(
|
|
150
|
-
`Mode "${melodicMinorModeKey}" is missing the 'rotation' property.`,
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
138
|
const rotation = mode.rotation;
|
|
154
139
|
const rotatedTriads = rotateArray(melodicMinorTriads, rotation);
|
|
155
140
|
const rotatedSeventhChords = rotateArray(melodicMinorSeventhChords, rotation);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Interval } from "../data/labels/note-labels.ts";
|
|
2
2
|
import type { MidiNoteNumber, MidiNoteSequence } from "../types/midi.d.ts";
|
|
3
|
-
import {
|
|
3
|
+
import { noteMidiAndIntervalToMidi } from "./midi.ts";
|
|
4
4
|
|
|
5
5
|
export type MidiNoteSequenceDirection =
|
|
6
6
|
| "ascending"
|
|
@@ -50,7 +50,7 @@ function getMonotonicMidiNoteSequence(
|
|
|
50
50
|
intervalIndex = (startFromIndex + i) % intervalsLength;
|
|
51
51
|
octaveOffset = Math.floor((startFromIndex + i) / intervalsLength) * 12;
|
|
52
52
|
const interval = intervals[intervalIndex];
|
|
53
|
-
const note =
|
|
53
|
+
const note = noteMidiAndIntervalToMidi(rootNoteMidi, interval);
|
|
54
54
|
if (note === undefined) {
|
|
55
55
|
throw new Error(
|
|
56
56
|
`Could not calculate MIDI note for interval ${interval} at index ${intervalIndex}`,
|
|
@@ -75,7 +75,7 @@ function getMonotonicMidiNoteSequence(
|
|
|
75
75
|
Math.max(0, Math.ceil((i - startFromIndex) / intervalsLength)) * 12;
|
|
76
76
|
const interval = intervals[intervalIndex];
|
|
77
77
|
// Subtract octaveOffset from root before applying interval
|
|
78
|
-
const note =
|
|
78
|
+
const note = noteMidiAndIntervalToMidi(
|
|
79
79
|
(rootNoteMidi - octaveOffset) as MidiNoteNumber,
|
|
80
80
|
interval,
|
|
81
81
|
);
|
package/src/utils/midi.ts
CHANGED
|
@@ -1,50 +1,51 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Interval,
|
|
3
3
|
intervalToIntegerMap,
|
|
4
|
-
type NoteInteger,
|
|
5
4
|
type NoteName,
|
|
6
5
|
noteNameToIntegerMap,
|
|
7
6
|
} from "../data/labels/note-labels.ts";
|
|
8
7
|
|
|
9
|
-
import type { MidiNoteNumber
|
|
8
|
+
import type { MidiNoteNumber } from "../types/midi.d.ts";
|
|
10
9
|
|
|
11
|
-
export function
|
|
12
|
-
|
|
10
|
+
export function noteIntegerAndIntervalToMidi(
|
|
11
|
+
noteInteger: number,
|
|
12
|
+
noteOctaveNumber: number,
|
|
13
13
|
interval: Interval,
|
|
14
|
-
rootNoteOctaveNumber: OctaveNumber = 4,
|
|
15
14
|
): MidiNoteNumber | undefined {
|
|
16
|
-
const
|
|
17
|
-
if (
|
|
18
|
-
return (
|
|
19
|
-
|
|
15
|
+
const intervalInteger = intervalToIntegerMap.get(interval);
|
|
16
|
+
if (intervalInteger === undefined) return undefined;
|
|
17
|
+
return (noteOctaveNumber + 1) * 12 + noteInteger +
|
|
18
|
+
intervalInteger as MidiNoteNumber;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export function
|
|
23
|
-
|
|
21
|
+
export function noteNameAndIntervalToMidi(
|
|
22
|
+
noteName: NoteName,
|
|
23
|
+
noteOctaveNumber: number,
|
|
24
24
|
interval: Interval,
|
|
25
25
|
): MidiNoteNumber | undefined {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
return
|
|
26
|
+
const noteInteger = noteNameToIntegerMap.get(noteName);
|
|
27
|
+
if (noteInteger === undefined) return undefined;
|
|
28
|
+
return noteIntegerAndIntervalToMidi(
|
|
29
|
+
noteInteger,
|
|
30
|
+
noteOctaveNumber,
|
|
31
|
+
interval,
|
|
32
|
+
);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
export function
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
export function noteMidiAndIntervalToMidi(
|
|
36
|
+
noteMidi: MidiNoteNumber,
|
|
37
|
+
interval: Interval,
|
|
34
38
|
): MidiNoteNumber | undefined {
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
37
|
-
return
|
|
39
|
+
const intervalValue = intervalToIntegerMap.get(interval);
|
|
40
|
+
if (intervalValue === undefined) return undefined;
|
|
41
|
+
return noteMidi + intervalValue as MidiNoteNumber;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
export function
|
|
44
|
+
export function noteNameToMidi(
|
|
41
45
|
noteName: NoteName,
|
|
42
|
-
|
|
43
|
-
octaveNumber: OctaveNumber = 4,
|
|
46
|
+
noteOctaveNumber: number,
|
|
44
47
|
): MidiNoteNumber | undefined {
|
|
45
48
|
const noteValue = noteNameToIntegerMap.get(noteName);
|
|
46
49
|
if (noteValue === undefined) return undefined;
|
|
47
|
-
|
|
48
|
-
if (intervalValue === undefined) return undefined;
|
|
49
|
-
return noteValue + (octaveNumber + 1) * 12 as MidiNoteNumber;
|
|
50
|
+
return noteValue + (noteOctaveNumber + 1) * 12 as MidiNoteNumber;
|
|
50
51
|
}
|
package/src/utils/note-names.ts
CHANGED
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
enharmonicNoteNameGroups,
|
|
3
3
|
type Interval,
|
|
4
4
|
intervalToIntegerMap,
|
|
5
|
-
type NoteInteger,
|
|
6
5
|
type NoteLetter,
|
|
7
6
|
noteLetters,
|
|
8
7
|
type NoteName,
|
|
9
8
|
noteNamesSet,
|
|
10
9
|
noteNameToIntegerMap,
|
|
11
10
|
type RootNote,
|
|
11
|
+
type RootNoteInteger,
|
|
12
12
|
rootNotesSet,
|
|
13
13
|
} from "../data/labels/note-labels.ts";
|
|
14
14
|
import {
|
|
@@ -122,18 +122,12 @@ export function normalizeRootNoteString(name: string): RootNote | undefined {
|
|
|
122
122
|
return undefined;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
export function
|
|
126
|
-
noteName: NoteName,
|
|
127
|
-
): NoteInteger | undefined {
|
|
128
|
-
return noteNameToIntegerMap.get(noteName);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function noteNameStringToInteger(
|
|
125
|
+
export function getNoteIntegerFromString(
|
|
132
126
|
noteName: string,
|
|
133
|
-
):
|
|
127
|
+
): RootNoteInteger | undefined {
|
|
134
128
|
const normalized = normalizeNoteNameString(noteName);
|
|
135
129
|
if (!normalized) return undefined;
|
|
136
|
-
return
|
|
130
|
+
return noteNameToIntegerMap.get(normalized);
|
|
137
131
|
}
|
|
138
132
|
|
|
139
133
|
export function getNoteNamesFromRootAndIntervals(
|
|
@@ -141,7 +135,7 @@ export function getNoteNamesFromRootAndIntervals(
|
|
|
141
135
|
intervals: readonly Interval[],
|
|
142
136
|
options: TransformIntervalsOptions = {},
|
|
143
137
|
): NoteName[] {
|
|
144
|
-
const rootNoteInteger =
|
|
138
|
+
const rootNoteInteger = noteNameToIntegerMap.get(rootNote);
|
|
145
139
|
if (rootNoteInteger === undefined) return [];
|
|
146
140
|
const rootNoteLetter = rootNote.charAt(0).toUpperCase();
|
|
147
141
|
const rootNoteLetterIndex = noteLetters.indexOf(rootNoteLetter as NoteLetter);
|