@musodojo/music-theory-data 28.0.0 → 30.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/README.md +99 -8
- package/esm/src/data/chord-progressions/mod.d.ts +2 -1
- package/esm/src/data/chord-progressions/mod.d.ts.map +1 -1
- package/esm/src/data/chord-progressions/mod.js +81 -76
- package/esm/src/utils/chord-progressions.d.ts +28 -1
- package/esm/src/utils/chord-progressions.d.ts.map +1 -1
- package/esm/src/utils/chord-progressions.js +91 -15
- package/package.json +1 -1
- package/script/src/data/chord-progressions/mod.d.ts +2 -1
- package/script/src/data/chord-progressions/mod.d.ts.map +1 -1
- package/script/src/data/chord-progressions/mod.js +82 -77
- package/script/src/utils/chord-progressions.d.ts +28 -1
- package/script/src/utils/chord-progressions.d.ts.map +1 -1
- package/script/src/utils/chord-progressions.js +95 -15
package/README.md
CHANGED
|
@@ -179,17 +179,22 @@ console.log(Object.keys(music_theory_data.groupedNoteCollections));
|
|
|
179
179
|
// Get a chord progression
|
|
180
180
|
const oneSixFourFive = music_theory_data.chordProgressions.oneSixFourFive;
|
|
181
181
|
|
|
182
|
-
console.log(oneSixFourFive.
|
|
183
|
-
// "I
|
|
182
|
+
console.log(oneSixFourFive.chords.map((chord) => chord.romanSymbol));
|
|
183
|
+
// ["I", "vi", "IV", "V"]
|
|
184
184
|
|
|
185
185
|
console.log(oneSixFourFive.chords);
|
|
186
186
|
// [
|
|
187
|
-
// { degree: "1", quality: "M", durationInBars: 1 },
|
|
188
|
-
// { degree: "6", quality: "m", durationInBars: 1 },
|
|
189
|
-
// { degree: "4", quality: "M", durationInBars: 1 },
|
|
190
|
-
// { degree: "5", quality: "M", durationInBars: 1 },
|
|
187
|
+
// { romanSymbol: "I", degree: "1", quality: "M", durationInBars: 1 },
|
|
188
|
+
// { romanSymbol: "vi", degree: "6", quality: "m", durationInBars: 1 },
|
|
189
|
+
// { romanSymbol: "IV", degree: "4", quality: "M", durationInBars: 1 },
|
|
190
|
+
// { romanSymbol: "V", degree: "5", quality: "M", durationInBars: 1 },
|
|
191
191
|
// ]
|
|
192
192
|
|
|
193
|
+
console.log(
|
|
194
|
+
music_theory_data.getChordProgressionRomanSymbols("oneSixFourFive"),
|
|
195
|
+
);
|
|
196
|
+
// ["I", "vi", "IV", "V"]
|
|
197
|
+
|
|
193
198
|
console.log(
|
|
194
199
|
music_theory_data.getChordProgressionChordNames(
|
|
195
200
|
"C",
|
|
@@ -206,6 +211,21 @@ console.log(
|
|
|
206
211
|
);
|
|
207
212
|
// ["CM", "FM", "GM"]
|
|
208
213
|
|
|
214
|
+
// Chord-change references return one item each time the chord changes in
|
|
215
|
+
// progression.chords. Durations are not expanded here.
|
|
216
|
+
console.log(
|
|
217
|
+
music_theory_data.getChordProgressionChordChangeReferences(
|
|
218
|
+
"C",
|
|
219
|
+
"oneOneFiveFive",
|
|
220
|
+
),
|
|
221
|
+
);
|
|
222
|
+
// [
|
|
223
|
+
// { rootNote: "C", chordName: "CM", noteCollectionKey: "major" },
|
|
224
|
+
// { rootNote: "G", chordName: "GM", noteCollectionKey: "major" },
|
|
225
|
+
// ]
|
|
226
|
+
|
|
227
|
+
// Unique chord references return each distinct chord once, preserving the
|
|
228
|
+
// first-seen order from the chord-change list.
|
|
209
229
|
console.log(
|
|
210
230
|
music_theory_data.getChordProgressionUniqueChordReferences(
|
|
211
231
|
"C",
|
|
@@ -214,14 +234,85 @@ console.log(
|
|
|
214
234
|
);
|
|
215
235
|
// [
|
|
216
236
|
// { rootNote: "C", chordName: "CM", noteCollectionKey: "major" },
|
|
217
|
-
// { rootNote: "
|
|
218
|
-
// { rootNote: "
|
|
237
|
+
// { rootNote: "F", chordName: "FM", noteCollectionKey: "major" },
|
|
238
|
+
// { rootNote: "G", chordName: "GM", noteCollectionKey: "major" },
|
|
239
|
+
// ]
|
|
240
|
+
|
|
241
|
+
// Chord references by bar return the song/practice order grouped by bar. A
|
|
242
|
+
// 2-bar chord appears in two bars, and split bars contain multiple references.
|
|
243
|
+
console.log(
|
|
244
|
+
music_theory_data.getChordProgressionChordReferencesByBar(
|
|
245
|
+
"C",
|
|
246
|
+
"oneOneFiveFive",
|
|
247
|
+
),
|
|
248
|
+
);
|
|
249
|
+
// [
|
|
250
|
+
// [{ rootNote: "C", chordName: "CM", noteCollectionKey: "major" }],
|
|
251
|
+
// [{ rootNote: "C", chordName: "CM", noteCollectionKey: "major" }],
|
|
252
|
+
// [{ rootNote: "G", chordName: "GM", noteCollectionKey: "major" }],
|
|
253
|
+
// [{ rootNote: "G", chordName: "GM", noteCollectionKey: "major" }],
|
|
254
|
+
// ]
|
|
255
|
+
|
|
256
|
+
console.log(
|
|
257
|
+
music_theory_data.getChordProgressionChordReferencesByBar(
|
|
258
|
+
"C",
|
|
259
|
+
"oneFourOneFiveSplitReturn",
|
|
260
|
+
)[6],
|
|
261
|
+
);
|
|
262
|
+
// [
|
|
263
|
+
// { rootNote: "C", chordName: "CM", noteCollectionKey: "major" },
|
|
264
|
+
// { rootNote: "G", chordName: "GM", noteCollectionKey: "major" },
|
|
219
265
|
// ]
|
|
220
266
|
|
|
267
|
+
// Song chord references flatten the bar-structured references into one ordered
|
|
268
|
+
// list for apps that want one diagram/card per chord occurrence.
|
|
269
|
+
console.log(
|
|
270
|
+
music_theory_data.getChordProgressionSongChordReferences(
|
|
271
|
+
"C",
|
|
272
|
+
"oneOneFiveFive",
|
|
273
|
+
).map((reference) => reference.chordName),
|
|
274
|
+
);
|
|
275
|
+
// ["CM", "CM", "GM", "GM"]
|
|
276
|
+
|
|
277
|
+
// In Muso Dojo, "Each Chord Once" should import
|
|
278
|
+
// getChordProgressionUniqueChordReferences. "Full Song Order" should import
|
|
279
|
+
// getChordProgressionSongChordReferences, or flatten
|
|
280
|
+
// getChordProgressionChordReferencesByBar locally when bar grouping is needed.
|
|
281
|
+
|
|
221
282
|
console.log(
|
|
222
283
|
music_theory_data.getChordProgressionTotalDurationInBars("twelveBarBlues"),
|
|
223
284
|
);
|
|
224
285
|
// 12
|
|
286
|
+
|
|
287
|
+
console.log(
|
|
288
|
+
music_theory_data.getChordProgressionChordReferencesByBar(
|
|
289
|
+
"C",
|
|
290
|
+
"twelveBarBlues",
|
|
291
|
+
).length,
|
|
292
|
+
);
|
|
293
|
+
// 12
|
|
294
|
+
|
|
295
|
+
console.log(
|
|
296
|
+
music_theory_data.getChordProgressionUniqueChordReferences(
|
|
297
|
+
"C",
|
|
298
|
+
"twelveBarBlues",
|
|
299
|
+
),
|
|
300
|
+
);
|
|
301
|
+
// [
|
|
302
|
+
// { rootNote: "C", chordName: "C7", noteCollectionKey: "dominant7" },
|
|
303
|
+
// { rootNote: "F", chordName: "F7", noteCollectionKey: "dominant7" },
|
|
304
|
+
// { rootNote: "G", chordName: "G7", noteCollectionKey: "dominant7" },
|
|
305
|
+
// ]
|
|
306
|
+
|
|
307
|
+
console.log(music_theory_data.chordProgressionBarGroups);
|
|
308
|
+
// [
|
|
309
|
+
// { totalBars: 4, progressionKeys: ["oneOneFiveFive", ...] },
|
|
310
|
+
// { totalBars: 8, progressionKeys: ["oneFourOneFiveSplitReturn"] },
|
|
311
|
+
// { totalBars: 12, progressionKeys: ["twelveBarBlues", "twelveBarBluesQuickChange"] },
|
|
312
|
+
// ]
|
|
313
|
+
|
|
314
|
+
console.log(music_theory_data.getChordProgressionKeysForTotalBars(12));
|
|
315
|
+
// ["twelveBarBlues", "twelveBarBluesQuickChange"]
|
|
225
316
|
```
|
|
226
317
|
|
|
227
318
|
## Note Colors And Chromatic Indexes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChordProgression } from "../../types/chord-progressions";
|
|
1
|
+
import type { ChordProgression, ChordProgressionBarGroup } from "../../types/chord-progressions";
|
|
2
2
|
declare const _chordProgressions: {
|
|
3
3
|
readonly oneOneFiveFive: ChordProgression;
|
|
4
4
|
readonly oneOneFiveFiveDominant7: ChordProgression;
|
|
@@ -17,5 +17,6 @@ declare const _chordProgressions: {
|
|
|
17
17
|
};
|
|
18
18
|
export type ChordProgressionKey = keyof typeof _chordProgressions;
|
|
19
19
|
export declare const chordProgressions: Record<ChordProgressionKey, ChordProgression>;
|
|
20
|
+
export declare const chordProgressionBarGroups: readonly ChordProgressionBarGroup<ChordProgressionKey>[];
|
|
20
21
|
export {};
|
|
21
22
|
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../src/src/data/chord-progressions/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../src/src/data/chord-progressions/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EAEzB,MAAM,gCAAgC,CAAC;AAqJxC,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;CAed,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAElE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CACxD,CAAC;AAiBrB,eAAO,MAAM,yBAAyB,EAAE,SAAS,wBAAwB,CACvE,mBAAmB,CACpB,EAM0C,CAAC"}
|
|
@@ -1,139 +1,128 @@
|
|
|
1
|
-
function chord(degree, quality, durationInBars) {
|
|
1
|
+
function chord(romanSymbol, degree, quality, durationInBars) {
|
|
2
2
|
return {
|
|
3
|
+
romanSymbol,
|
|
3
4
|
degree,
|
|
4
5
|
quality,
|
|
5
6
|
durationInBars,
|
|
6
7
|
};
|
|
7
8
|
}
|
|
8
9
|
const oneOneFiveFive = {
|
|
9
|
-
primaryName: "I | I | V | V",
|
|
10
10
|
chords: [
|
|
11
|
-
chord("1", "M", 2),
|
|
12
|
-
chord("5", "M", 2),
|
|
11
|
+
chord("I", "1", "M", 2),
|
|
12
|
+
chord("V", "5", "M", 2),
|
|
13
13
|
],
|
|
14
14
|
};
|
|
15
15
|
const oneOneFiveFiveDominant7 = {
|
|
16
|
-
primaryName: "I | I | V | V7",
|
|
17
16
|
chords: [
|
|
18
|
-
chord("1", "M", 2),
|
|
19
|
-
chord("5", "M", 1),
|
|
20
|
-
chord("5", "7", 1),
|
|
17
|
+
chord("I", "1", "M", 2),
|
|
18
|
+
chord("V", "5", "M", 1),
|
|
19
|
+
chord("V7", "5", "7", 1),
|
|
21
20
|
],
|
|
22
21
|
};
|
|
23
22
|
const oneOneFourFour = {
|
|
24
|
-
primaryName: "I | I | IV | IV",
|
|
25
23
|
chords: [
|
|
26
|
-
chord("1", "M", 2),
|
|
27
|
-
chord("4", "M", 2),
|
|
24
|
+
chord("I", "1", "M", 2),
|
|
25
|
+
chord("IV", "4", "M", 2),
|
|
28
26
|
],
|
|
29
27
|
};
|
|
30
28
|
const oneOneFourFive = {
|
|
31
|
-
primaryName: "I | I | IV | V",
|
|
32
29
|
chords: [
|
|
33
|
-
chord("1", "M", 2),
|
|
34
|
-
chord("4", "M", 1),
|
|
35
|
-
chord("5", "M", 1),
|
|
30
|
+
chord("I", "1", "M", 2),
|
|
31
|
+
chord("IV", "4", "M", 1),
|
|
32
|
+
chord("V", "5", "M", 1),
|
|
36
33
|
],
|
|
37
34
|
};
|
|
38
35
|
const oneFourOneFive = {
|
|
39
|
-
primaryName: "I | IV | I | V",
|
|
40
36
|
chords: [
|
|
41
|
-
chord("1", "M", 1),
|
|
42
|
-
chord("4", "M", 1),
|
|
43
|
-
chord("1", "M", 1),
|
|
44
|
-
chord("5", "M", 1),
|
|
37
|
+
chord("I", "1", "M", 1),
|
|
38
|
+
chord("IV", "4", "M", 1),
|
|
39
|
+
chord("I", "1", "M", 1),
|
|
40
|
+
chord("V", "5", "M", 1),
|
|
45
41
|
],
|
|
46
42
|
};
|
|
47
43
|
const oneSixFourFive = {
|
|
48
|
-
primaryName: "I | vi | IV | V",
|
|
49
44
|
chords: [
|
|
50
|
-
chord("1", "M", 1),
|
|
51
|
-
chord("6", "m", 1),
|
|
52
|
-
chord("4", "M", 1),
|
|
53
|
-
chord("5", "M", 1),
|
|
45
|
+
chord("I", "1", "M", 1),
|
|
46
|
+
chord("vi", "6", "m", 1),
|
|
47
|
+
chord("IV", "4", "M", 1),
|
|
48
|
+
chord("V", "5", "M", 1),
|
|
54
49
|
],
|
|
55
50
|
};
|
|
56
51
|
const oneFiveSixFour = {
|
|
57
|
-
primaryName: "I | V | vi | IV",
|
|
58
52
|
chords: [
|
|
59
|
-
chord("1", "M", 1),
|
|
60
|
-
chord("5", "M", 1),
|
|
61
|
-
chord("6", "m", 1),
|
|
62
|
-
chord("4", "M", 1),
|
|
53
|
+
chord("I", "1", "M", 1),
|
|
54
|
+
chord("V", "5", "M", 1),
|
|
55
|
+
chord("vi", "6", "m", 1),
|
|
56
|
+
chord("IV", "4", "M", 1),
|
|
63
57
|
],
|
|
64
58
|
};
|
|
65
59
|
const oneSixTwoFive = {
|
|
66
|
-
primaryName: "I | vi | ii | V",
|
|
67
60
|
chords: [
|
|
68
|
-
chord("1", "M", 1),
|
|
69
|
-
chord("6", "m", 1),
|
|
70
|
-
chord("2", "m", 1),
|
|
71
|
-
chord("5", "M", 1),
|
|
61
|
+
chord("I", "1", "M", 1),
|
|
62
|
+
chord("vi", "6", "m", 1),
|
|
63
|
+
chord("ii", "2", "m", 1),
|
|
64
|
+
chord("V", "5", "M", 1),
|
|
72
65
|
],
|
|
73
66
|
};
|
|
74
67
|
const sixTwoFiveOne = {
|
|
75
|
-
primaryName: "vi | ii | V | I",
|
|
76
68
|
chords: [
|
|
77
|
-
chord("6", "m", 1),
|
|
78
|
-
chord("2", "m", 1),
|
|
79
|
-
chord("5", "M", 1),
|
|
80
|
-
chord("1", "M", 1),
|
|
69
|
+
chord("vi", "6", "m", 1),
|
|
70
|
+
chord("ii", "2", "m", 1),
|
|
71
|
+
chord("V", "5", "M", 1),
|
|
72
|
+
chord("I", "1", "M", 1),
|
|
81
73
|
],
|
|
82
74
|
};
|
|
83
75
|
const majorTwoFiveOne = {
|
|
84
|
-
primaryName: "iim7 | V7 | Imaj7 | Imaj7",
|
|
85
76
|
chords: [
|
|
86
|
-
chord("2", "m7", 1),
|
|
87
|
-
chord("5", "7", 1),
|
|
88
|
-
chord("1", "M7", 2),
|
|
77
|
+
chord("iim7", "2", "m7", 1),
|
|
78
|
+
chord("V7", "5", "7", 1),
|
|
79
|
+
chord("IM7", "1", "M7", 2),
|
|
89
80
|
],
|
|
90
81
|
};
|
|
91
82
|
const minorTwoFiveOne = {
|
|
92
|
-
primaryName: "iiø7 | V7 | i | i",
|
|
93
83
|
chords: [
|
|
94
|
-
chord("2", "ø7", 1),
|
|
95
|
-
chord("5", "7", 1),
|
|
96
|
-
chord("1", "m", 2),
|
|
84
|
+
chord("iiø7", "2", "ø7", 1),
|
|
85
|
+
chord("V7", "5", "7", 1),
|
|
86
|
+
chord("i", "1", "m", 2),
|
|
97
87
|
],
|
|
98
88
|
};
|
|
99
89
|
const oneFourOneFiveSplitReturn = {
|
|
100
|
-
primaryName: "I | IV | I | V | I | IV | I V | I",
|
|
101
90
|
chords: [
|
|
102
|
-
chord("1", "M", 1),
|
|
103
|
-
chord("4", "M", 1),
|
|
104
|
-
chord("1", "M", 1),
|
|
105
|
-
chord("5", "M", 1),
|
|
106
|
-
chord("1", "M", 1),
|
|
107
|
-
chord("4", "M", 1),
|
|
108
|
-
chord("1", "M", 0.5),
|
|
109
|
-
chord("5", "M", 0.5),
|
|
110
|
-
chord("1", "M", 1),
|
|
91
|
+
chord("I", "1", "M", 1),
|
|
92
|
+
chord("IV", "4", "M", 1),
|
|
93
|
+
chord("I", "1", "M", 1),
|
|
94
|
+
chord("V", "5", "M", 1),
|
|
95
|
+
chord("I", "1", "M", 1),
|
|
96
|
+
chord("IV", "4", "M", 1),
|
|
97
|
+
chord("I", "1", "M", 0.5),
|
|
98
|
+
chord("V", "5", "M", 0.5),
|
|
99
|
+
chord("I", "1", "M", 1),
|
|
111
100
|
],
|
|
112
101
|
};
|
|
113
102
|
const twelveBarBlues = {
|
|
114
|
-
|
|
103
|
+
commonName: "12 Bar Blues",
|
|
115
104
|
chords: [
|
|
116
|
-
chord("1", "7", 4),
|
|
117
|
-
chord("4", "7", 2),
|
|
118
|
-
chord("1", "7", 2),
|
|
119
|
-
chord("5", "7", 1),
|
|
120
|
-
chord("4", "7", 1),
|
|
121
|
-
chord("1", "7", 1),
|
|
122
|
-
chord("5", "7", 1),
|
|
105
|
+
chord("I7", "1", "7", 4),
|
|
106
|
+
chord("IV7", "4", "7", 2),
|
|
107
|
+
chord("I7", "1", "7", 2),
|
|
108
|
+
chord("V7", "5", "7", 1),
|
|
109
|
+
chord("IV7", "4", "7", 1),
|
|
110
|
+
chord("I7", "1", "7", 1),
|
|
111
|
+
chord("V7", "5", "7", 1),
|
|
123
112
|
],
|
|
124
113
|
};
|
|
125
114
|
const twelveBarBluesQuickChange = {
|
|
126
|
-
|
|
115
|
+
commonName: "12 Bar Blues Quick Change",
|
|
127
116
|
chords: [
|
|
128
|
-
chord("1", "7", 1),
|
|
129
|
-
chord("4", "7", 1),
|
|
130
|
-
chord("1", "7", 2),
|
|
131
|
-
chord("4", "7", 2),
|
|
132
|
-
chord("1", "7", 2),
|
|
133
|
-
chord("5", "7", 1),
|
|
134
|
-
chord("4", "7", 1),
|
|
135
|
-
chord("1", "7", 1),
|
|
136
|
-
chord("5", "7", 1),
|
|
117
|
+
chord("I7", "1", "7", 1),
|
|
118
|
+
chord("IV7", "4", "7", 1),
|
|
119
|
+
chord("I7", "1", "7", 2),
|
|
120
|
+
chord("IV7", "4", "7", 2),
|
|
121
|
+
chord("I7", "1", "7", 2),
|
|
122
|
+
chord("V7", "5", "7", 1),
|
|
123
|
+
chord("IV7", "4", "7", 1),
|
|
124
|
+
chord("I7", "1", "7", 1),
|
|
125
|
+
chord("V7", "5", "7", 1),
|
|
137
126
|
],
|
|
138
127
|
};
|
|
139
128
|
const _chordProgressions = {
|
|
@@ -153,3 +142,19 @@ const _chordProgressions = {
|
|
|
153
142
|
twelveBarBluesQuickChange,
|
|
154
143
|
};
|
|
155
144
|
export const chordProgressions = _chordProgressions;
|
|
145
|
+
const chordProgressionsByTotalBars = Object.entries(chordProgressions)
|
|
146
|
+
.reduce((groups, [key, progression]) => {
|
|
147
|
+
const totalBars = progression.chords.reduce((total, chord) => total + chord.durationInBars, 0);
|
|
148
|
+
const progressionKeys = groups.get(totalBars);
|
|
149
|
+
if (progressionKeys) {
|
|
150
|
+
progressionKeys.push(key);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
groups.set(totalBars, [key]);
|
|
154
|
+
}
|
|
155
|
+
return groups;
|
|
156
|
+
}, new Map());
|
|
157
|
+
export const chordProgressionBarGroups = Array.from(chordProgressionsByTotalBars, ([totalBars, progressionKeys]) => ({
|
|
158
|
+
totalBars,
|
|
159
|
+
progressionKeys,
|
|
160
|
+
})).sort((a, b) => a.totalBars - b.totalBars);
|
|
@@ -9,8 +9,35 @@ export interface ChordProgressionChordReference {
|
|
|
9
9
|
}
|
|
10
10
|
export declare function isValidChordProgressionKey(key: string): key is ChordProgressionKey;
|
|
11
11
|
export declare function getChordProgressionChordNames(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): string[];
|
|
12
|
+
export declare function getChordProgressionRomanSymbols(progressionOrKey: ChordProgression | ChordProgressionKey): string[];
|
|
13
|
+
export declare function getChordProgressionKeysForTotalBars(totalBars: number): ChordProgressionKey[];
|
|
12
14
|
export declare function getChordProgressionUniqueChordNames(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): string[];
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Returns one chord reference for each authored chord entry in
|
|
17
|
+
* `progression.chords`.
|
|
18
|
+
*
|
|
19
|
+
* This is the "chord changes" view: a chord lasting 2 bars is returned once,
|
|
20
|
+
* because it is one chord entry/change, while repeated entries are preserved.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getChordProgressionChordChangeReferences(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[];
|
|
23
|
+
/**
|
|
24
|
+
* Returns each distinct chord reference once, preserving first-seen order from
|
|
25
|
+
* the chord-change list.
|
|
26
|
+
*/
|
|
14
27
|
export declare function getChordProgressionUniqueChordReferences(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[];
|
|
28
|
+
/**
|
|
29
|
+
* Returns duration-aware chord references grouped by bar.
|
|
30
|
+
*
|
|
31
|
+
* Each outer array item is one bar. A 2-bar chord appears in two bar entries,
|
|
32
|
+
* and a split bar can contain multiple chord references in order.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getChordProgressionChordReferencesByBar(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[][];
|
|
35
|
+
/**
|
|
36
|
+
* Returns duration-aware chord references in song/practice order.
|
|
37
|
+
*
|
|
38
|
+
* This flattens `getChordProgressionChordReferencesByBar`, so a 2-bar chord
|
|
39
|
+
* appears twice and split bars preserve their left-to-right order.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getChordProgressionSongChordReferences(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[];
|
|
15
42
|
export declare function getChordProgressionTotalDurationInBars(progressionOrKey: ChordProgression | ChordProgressionKey): number;
|
|
16
43
|
//# sourceMappingURL=chord-progressions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chord-progressions.d.ts","sourceRoot":"","sources":["../../../src/src/utils/chord-progressions.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"chord-progressions.d.ts","sourceRoot":"","sources":["../../../src/src/utils/chord-progressions.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAMzE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;CAC/C;AASD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,GACV,GAAG,IAAI,mBAAmB,CAE5B;AA2CD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,EAAE,CAYV;AAED,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,EAAE,CAKV;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,MAAM,GAChB,mBAAmB,EAAE,CAKvB;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,EAAE,CAIV;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,CAKlC;AAED;;;GAGG;AACH,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,CAkBlC;AAED;;;;;GAKG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,EAAE,CAiDpC;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,CAKlC;AAED,wBAAgB,sCAAsC,CACpD,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,CAQR"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { chordProgressions, } from "../data/chord-progressions/mod.js";
|
|
1
|
+
import { chordProgressionBarGroups, chordProgressions, } from "../data/chord-progressions/mod.js";
|
|
2
2
|
import { getChordQualityNoteCollectionKey } from "../data/chords/mod.js";
|
|
3
3
|
import { getNoteNamesForRootAndIntervals, normalizeRootNoteString, } from "./note-names.js";
|
|
4
|
+
const BAR_DURATION_EPSILON = 0.000000001;
|
|
4
5
|
export function isValidChordProgressionKey(key) {
|
|
5
6
|
return Object.prototype.hasOwnProperty.call(chordProgressions, key);
|
|
6
7
|
}
|
|
@@ -9,17 +10,14 @@ function resolveProgression(progressionOrKey) {
|
|
|
9
10
|
return progressionOrKey;
|
|
10
11
|
return chordProgressions[progressionOrKey];
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
function createChordProgressionChordReference(chord, chordRootNote) {
|
|
14
|
+
return {
|
|
15
|
+
rootNote: chordRootNote,
|
|
16
|
+
chordName: chordRootNote + chord.quality,
|
|
17
|
+
noteCollectionKey: getChordQualityNoteCollectionKey(chord.quality),
|
|
18
|
+
};
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
return Array.from(new Set(getChordProgressionChordNames(rootNote, progressionOrKey)));
|
|
21
|
-
}
|
|
22
|
-
export function getChordProgressionChordReferences(rootNote, progressionOrKey) {
|
|
20
|
+
function getResolvedChordProgressionChordReferences(rootNote, progressionOrKey) {
|
|
23
21
|
const progression = resolveProgression(progressionOrKey);
|
|
24
22
|
if (!progression)
|
|
25
23
|
return [];
|
|
@@ -29,16 +27,49 @@ export function getChordProgressionChordReferences(rootNote, progressionOrKey) {
|
|
|
29
27
|
if (!chordRootNote)
|
|
30
28
|
return [];
|
|
31
29
|
return [{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
noteCollectionKey: getChordQualityNoteCollectionKey(chord.quality),
|
|
30
|
+
chord,
|
|
31
|
+
reference: createChordProgressionChordReference(chord, chordRootNote),
|
|
35
32
|
}];
|
|
36
33
|
});
|
|
37
34
|
}
|
|
35
|
+
export function getChordProgressionChordNames(rootNote, progressionOrKey) {
|
|
36
|
+
const progression = resolveProgression(progressionOrKey);
|
|
37
|
+
if (!progression)
|
|
38
|
+
return [];
|
|
39
|
+
const noteNames = getNoteNamesForRootAndIntervals(rootNote, progression.chords.map((chord) => chord.degree));
|
|
40
|
+
return progression.chords.map((chord, index) => noteNames[index] + chord.quality);
|
|
41
|
+
}
|
|
42
|
+
export function getChordProgressionRomanSymbols(progressionOrKey) {
|
|
43
|
+
const progression = resolveProgression(progressionOrKey);
|
|
44
|
+
if (!progression)
|
|
45
|
+
return [];
|
|
46
|
+
return progression.chords.map((chord) => chord.romanSymbol);
|
|
47
|
+
}
|
|
48
|
+
export function getChordProgressionKeysForTotalBars(totalBars) {
|
|
49
|
+
return chordProgressionBarGroups.find((group) => group.totalBars === totalBars)
|
|
50
|
+
?.progressionKeys.slice() ?? [];
|
|
51
|
+
}
|
|
52
|
+
export function getChordProgressionUniqueChordNames(rootNote, progressionOrKey) {
|
|
53
|
+
return Array.from(new Set(getChordProgressionChordNames(rootNote, progressionOrKey)));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Returns one chord reference for each authored chord entry in
|
|
57
|
+
* `progression.chords`.
|
|
58
|
+
*
|
|
59
|
+
* This is the "chord changes" view: a chord lasting 2 bars is returned once,
|
|
60
|
+
* because it is one chord entry/change, while repeated entries are preserved.
|
|
61
|
+
*/
|
|
62
|
+
export function getChordProgressionChordChangeReferences(rootNote, progressionOrKey) {
|
|
63
|
+
return getResolvedChordProgressionChordReferences(rootNote, progressionOrKey).map(({ reference }) => reference);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns each distinct chord reference once, preserving first-seen order from
|
|
67
|
+
* the chord-change list.
|
|
68
|
+
*/
|
|
38
69
|
export function getChordProgressionUniqueChordReferences(rootNote, progressionOrKey) {
|
|
39
70
|
const uniqueReferences = [];
|
|
40
71
|
const seen = new Set();
|
|
41
|
-
for (const reference of
|
|
72
|
+
for (const reference of getChordProgressionChordChangeReferences(rootNote, progressionOrKey)) {
|
|
42
73
|
const key = `${reference.rootNote}:${reference.noteCollectionKey}:${reference.chordName}`;
|
|
43
74
|
if (seen.has(key))
|
|
44
75
|
continue;
|
|
@@ -47,6 +78,51 @@ export function getChordProgressionUniqueChordReferences(rootNote, progressionOr
|
|
|
47
78
|
}
|
|
48
79
|
return uniqueReferences;
|
|
49
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns duration-aware chord references grouped by bar.
|
|
83
|
+
*
|
|
84
|
+
* Each outer array item is one bar. A 2-bar chord appears in two bar entries,
|
|
85
|
+
* and a split bar can contain multiple chord references in order.
|
|
86
|
+
*/
|
|
87
|
+
export function getChordProgressionChordReferencesByBar(rootNote, progressionOrKey) {
|
|
88
|
+
const bars = [];
|
|
89
|
+
let currentBar = [];
|
|
90
|
+
let remainingBarDuration = 1;
|
|
91
|
+
const pushCurrentBar = () => {
|
|
92
|
+
if (currentBar.length > 0) {
|
|
93
|
+
bars.push(currentBar);
|
|
94
|
+
}
|
|
95
|
+
currentBar = [];
|
|
96
|
+
remainingBarDuration = 1;
|
|
97
|
+
};
|
|
98
|
+
for (const { chord, reference } of getResolvedChordProgressionChordReferences(rootNote, progressionOrKey)) {
|
|
99
|
+
let remainingChordDuration = chord.durationInBars;
|
|
100
|
+
if (!Number.isFinite(remainingChordDuration) ||
|
|
101
|
+
remainingChordDuration <= BAR_DURATION_EPSILON) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
while (remainingChordDuration > BAR_DURATION_EPSILON) {
|
|
105
|
+
currentBar.push(reference);
|
|
106
|
+
const filledDuration = Math.min(remainingChordDuration, remainingBarDuration);
|
|
107
|
+
remainingChordDuration -= filledDuration;
|
|
108
|
+
remainingBarDuration -= filledDuration;
|
|
109
|
+
if (remainingBarDuration <= BAR_DURATION_EPSILON) {
|
|
110
|
+
pushCurrentBar();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
pushCurrentBar();
|
|
115
|
+
return bars;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns duration-aware chord references in song/practice order.
|
|
119
|
+
*
|
|
120
|
+
* This flattens `getChordProgressionChordReferencesByBar`, so a 2-bar chord
|
|
121
|
+
* appears twice and split bars preserve their left-to-right order.
|
|
122
|
+
*/
|
|
123
|
+
export function getChordProgressionSongChordReferences(rootNote, progressionOrKey) {
|
|
124
|
+
return getChordProgressionChordReferencesByBar(rootNote, progressionOrKey).flat();
|
|
125
|
+
}
|
|
50
126
|
export function getChordProgressionTotalDurationInBars(progressionOrKey) {
|
|
51
127
|
const progression = resolveProgression(progressionOrKey);
|
|
52
128
|
if (!progression)
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChordProgression } from "../../types/chord-progressions";
|
|
1
|
+
import type { ChordProgression, ChordProgressionBarGroup } from "../../types/chord-progressions";
|
|
2
2
|
declare const _chordProgressions: {
|
|
3
3
|
readonly oneOneFiveFive: ChordProgression;
|
|
4
4
|
readonly oneOneFiveFiveDominant7: ChordProgression;
|
|
@@ -17,5 +17,6 @@ declare const _chordProgressions: {
|
|
|
17
17
|
};
|
|
18
18
|
export type ChordProgressionKey = keyof typeof _chordProgressions;
|
|
19
19
|
export declare const chordProgressions: Record<ChordProgressionKey, ChordProgression>;
|
|
20
|
+
export declare const chordProgressionBarGroups: readonly ChordProgressionBarGroup<ChordProgressionKey>[];
|
|
20
21
|
export {};
|
|
21
22
|
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../src/src/data/chord-progressions/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../src/src/data/chord-progressions/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EAEzB,MAAM,gCAAgC,CAAC;AAqJxC,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;CAed,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAElE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CACxD,CAAC;AAiBrB,eAAO,MAAM,yBAAyB,EAAE,SAAS,wBAAwB,CACvE,mBAAmB,CACpB,EAM0C,CAAC"}
|
|
@@ -1,142 +1,131 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.chordProgressions = void 0;
|
|
4
|
-
function chord(degree, quality, durationInBars) {
|
|
3
|
+
exports.chordProgressionBarGroups = exports.chordProgressions = void 0;
|
|
4
|
+
function chord(romanSymbol, degree, quality, durationInBars) {
|
|
5
5
|
return {
|
|
6
|
+
romanSymbol,
|
|
6
7
|
degree,
|
|
7
8
|
quality,
|
|
8
9
|
durationInBars,
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
12
|
const oneOneFiveFive = {
|
|
12
|
-
primaryName: "I | I | V | V",
|
|
13
13
|
chords: [
|
|
14
|
-
chord("1", "M", 2),
|
|
15
|
-
chord("5", "M", 2),
|
|
14
|
+
chord("I", "1", "M", 2),
|
|
15
|
+
chord("V", "5", "M", 2),
|
|
16
16
|
],
|
|
17
17
|
};
|
|
18
18
|
const oneOneFiveFiveDominant7 = {
|
|
19
|
-
primaryName: "I | I | V | V7",
|
|
20
19
|
chords: [
|
|
21
|
-
chord("1", "M", 2),
|
|
22
|
-
chord("5", "M", 1),
|
|
23
|
-
chord("5", "7", 1),
|
|
20
|
+
chord("I", "1", "M", 2),
|
|
21
|
+
chord("V", "5", "M", 1),
|
|
22
|
+
chord("V7", "5", "7", 1),
|
|
24
23
|
],
|
|
25
24
|
};
|
|
26
25
|
const oneOneFourFour = {
|
|
27
|
-
primaryName: "I | I | IV | IV",
|
|
28
26
|
chords: [
|
|
29
|
-
chord("1", "M", 2),
|
|
30
|
-
chord("4", "M", 2),
|
|
27
|
+
chord("I", "1", "M", 2),
|
|
28
|
+
chord("IV", "4", "M", 2),
|
|
31
29
|
],
|
|
32
30
|
};
|
|
33
31
|
const oneOneFourFive = {
|
|
34
|
-
primaryName: "I | I | IV | V",
|
|
35
32
|
chords: [
|
|
36
|
-
chord("1", "M", 2),
|
|
37
|
-
chord("4", "M", 1),
|
|
38
|
-
chord("5", "M", 1),
|
|
33
|
+
chord("I", "1", "M", 2),
|
|
34
|
+
chord("IV", "4", "M", 1),
|
|
35
|
+
chord("V", "5", "M", 1),
|
|
39
36
|
],
|
|
40
37
|
};
|
|
41
38
|
const oneFourOneFive = {
|
|
42
|
-
primaryName: "I | IV | I | V",
|
|
43
39
|
chords: [
|
|
44
|
-
chord("1", "M", 1),
|
|
45
|
-
chord("4", "M", 1),
|
|
46
|
-
chord("1", "M", 1),
|
|
47
|
-
chord("5", "M", 1),
|
|
40
|
+
chord("I", "1", "M", 1),
|
|
41
|
+
chord("IV", "4", "M", 1),
|
|
42
|
+
chord("I", "1", "M", 1),
|
|
43
|
+
chord("V", "5", "M", 1),
|
|
48
44
|
],
|
|
49
45
|
};
|
|
50
46
|
const oneSixFourFive = {
|
|
51
|
-
primaryName: "I | vi | IV | V",
|
|
52
47
|
chords: [
|
|
53
|
-
chord("1", "M", 1),
|
|
54
|
-
chord("6", "m", 1),
|
|
55
|
-
chord("4", "M", 1),
|
|
56
|
-
chord("5", "M", 1),
|
|
48
|
+
chord("I", "1", "M", 1),
|
|
49
|
+
chord("vi", "6", "m", 1),
|
|
50
|
+
chord("IV", "4", "M", 1),
|
|
51
|
+
chord("V", "5", "M", 1),
|
|
57
52
|
],
|
|
58
53
|
};
|
|
59
54
|
const oneFiveSixFour = {
|
|
60
|
-
primaryName: "I | V | vi | IV",
|
|
61
55
|
chords: [
|
|
62
|
-
chord("1", "M", 1),
|
|
63
|
-
chord("5", "M", 1),
|
|
64
|
-
chord("6", "m", 1),
|
|
65
|
-
chord("4", "M", 1),
|
|
56
|
+
chord("I", "1", "M", 1),
|
|
57
|
+
chord("V", "5", "M", 1),
|
|
58
|
+
chord("vi", "6", "m", 1),
|
|
59
|
+
chord("IV", "4", "M", 1),
|
|
66
60
|
],
|
|
67
61
|
};
|
|
68
62
|
const oneSixTwoFive = {
|
|
69
|
-
primaryName: "I | vi | ii | V",
|
|
70
63
|
chords: [
|
|
71
|
-
chord("1", "M", 1),
|
|
72
|
-
chord("6", "m", 1),
|
|
73
|
-
chord("2", "m", 1),
|
|
74
|
-
chord("5", "M", 1),
|
|
64
|
+
chord("I", "1", "M", 1),
|
|
65
|
+
chord("vi", "6", "m", 1),
|
|
66
|
+
chord("ii", "2", "m", 1),
|
|
67
|
+
chord("V", "5", "M", 1),
|
|
75
68
|
],
|
|
76
69
|
};
|
|
77
70
|
const sixTwoFiveOne = {
|
|
78
|
-
primaryName: "vi | ii | V | I",
|
|
79
71
|
chords: [
|
|
80
|
-
chord("6", "m", 1),
|
|
81
|
-
chord("2", "m", 1),
|
|
82
|
-
chord("5", "M", 1),
|
|
83
|
-
chord("1", "M", 1),
|
|
72
|
+
chord("vi", "6", "m", 1),
|
|
73
|
+
chord("ii", "2", "m", 1),
|
|
74
|
+
chord("V", "5", "M", 1),
|
|
75
|
+
chord("I", "1", "M", 1),
|
|
84
76
|
],
|
|
85
77
|
};
|
|
86
78
|
const majorTwoFiveOne = {
|
|
87
|
-
primaryName: "iim7 | V7 | Imaj7 | Imaj7",
|
|
88
79
|
chords: [
|
|
89
|
-
chord("2", "m7", 1),
|
|
90
|
-
chord("5", "7", 1),
|
|
91
|
-
chord("1", "M7", 2),
|
|
80
|
+
chord("iim7", "2", "m7", 1),
|
|
81
|
+
chord("V7", "5", "7", 1),
|
|
82
|
+
chord("IM7", "1", "M7", 2),
|
|
92
83
|
],
|
|
93
84
|
};
|
|
94
85
|
const minorTwoFiveOne = {
|
|
95
|
-
primaryName: "iiø7 | V7 | i | i",
|
|
96
86
|
chords: [
|
|
97
|
-
chord("2", "ø7", 1),
|
|
98
|
-
chord("5", "7", 1),
|
|
99
|
-
chord("1", "m", 2),
|
|
87
|
+
chord("iiø7", "2", "ø7", 1),
|
|
88
|
+
chord("V7", "5", "7", 1),
|
|
89
|
+
chord("i", "1", "m", 2),
|
|
100
90
|
],
|
|
101
91
|
};
|
|
102
92
|
const oneFourOneFiveSplitReturn = {
|
|
103
|
-
primaryName: "I | IV | I | V | I | IV | I V | I",
|
|
104
93
|
chords: [
|
|
105
|
-
chord("1", "M", 1),
|
|
106
|
-
chord("4", "M", 1),
|
|
107
|
-
chord("1", "M", 1),
|
|
108
|
-
chord("5", "M", 1),
|
|
109
|
-
chord("1", "M", 1),
|
|
110
|
-
chord("4", "M", 1),
|
|
111
|
-
chord("1", "M", 0.5),
|
|
112
|
-
chord("5", "M", 0.5),
|
|
113
|
-
chord("1", "M", 1),
|
|
94
|
+
chord("I", "1", "M", 1),
|
|
95
|
+
chord("IV", "4", "M", 1),
|
|
96
|
+
chord("I", "1", "M", 1),
|
|
97
|
+
chord("V", "5", "M", 1),
|
|
98
|
+
chord("I", "1", "M", 1),
|
|
99
|
+
chord("IV", "4", "M", 1),
|
|
100
|
+
chord("I", "1", "M", 0.5),
|
|
101
|
+
chord("V", "5", "M", 0.5),
|
|
102
|
+
chord("I", "1", "M", 1),
|
|
114
103
|
],
|
|
115
104
|
};
|
|
116
105
|
const twelveBarBlues = {
|
|
117
|
-
|
|
106
|
+
commonName: "12 Bar Blues",
|
|
118
107
|
chords: [
|
|
119
|
-
chord("1", "7", 4),
|
|
120
|
-
chord("4", "7", 2),
|
|
121
|
-
chord("1", "7", 2),
|
|
122
|
-
chord("5", "7", 1),
|
|
123
|
-
chord("4", "7", 1),
|
|
124
|
-
chord("1", "7", 1),
|
|
125
|
-
chord("5", "7", 1),
|
|
108
|
+
chord("I7", "1", "7", 4),
|
|
109
|
+
chord("IV7", "4", "7", 2),
|
|
110
|
+
chord("I7", "1", "7", 2),
|
|
111
|
+
chord("V7", "5", "7", 1),
|
|
112
|
+
chord("IV7", "4", "7", 1),
|
|
113
|
+
chord("I7", "1", "7", 1),
|
|
114
|
+
chord("V7", "5", "7", 1),
|
|
126
115
|
],
|
|
127
116
|
};
|
|
128
117
|
const twelveBarBluesQuickChange = {
|
|
129
|
-
|
|
118
|
+
commonName: "12 Bar Blues Quick Change",
|
|
130
119
|
chords: [
|
|
131
|
-
chord("1", "7", 1),
|
|
132
|
-
chord("4", "7", 1),
|
|
133
|
-
chord("1", "7", 2),
|
|
134
|
-
chord("4", "7", 2),
|
|
135
|
-
chord("1", "7", 2),
|
|
136
|
-
chord("5", "7", 1),
|
|
137
|
-
chord("4", "7", 1),
|
|
138
|
-
chord("1", "7", 1),
|
|
139
|
-
chord("5", "7", 1),
|
|
120
|
+
chord("I7", "1", "7", 1),
|
|
121
|
+
chord("IV7", "4", "7", 1),
|
|
122
|
+
chord("I7", "1", "7", 2),
|
|
123
|
+
chord("IV7", "4", "7", 2),
|
|
124
|
+
chord("I7", "1", "7", 2),
|
|
125
|
+
chord("V7", "5", "7", 1),
|
|
126
|
+
chord("IV7", "4", "7", 1),
|
|
127
|
+
chord("I7", "1", "7", 1),
|
|
128
|
+
chord("V7", "5", "7", 1),
|
|
140
129
|
],
|
|
141
130
|
};
|
|
142
131
|
const _chordProgressions = {
|
|
@@ -156,3 +145,19 @@ const _chordProgressions = {
|
|
|
156
145
|
twelveBarBluesQuickChange,
|
|
157
146
|
};
|
|
158
147
|
exports.chordProgressions = _chordProgressions;
|
|
148
|
+
const chordProgressionsByTotalBars = Object.entries(exports.chordProgressions)
|
|
149
|
+
.reduce((groups, [key, progression]) => {
|
|
150
|
+
const totalBars = progression.chords.reduce((total, chord) => total + chord.durationInBars, 0);
|
|
151
|
+
const progressionKeys = groups.get(totalBars);
|
|
152
|
+
if (progressionKeys) {
|
|
153
|
+
progressionKeys.push(key);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
groups.set(totalBars, [key]);
|
|
157
|
+
}
|
|
158
|
+
return groups;
|
|
159
|
+
}, new Map());
|
|
160
|
+
exports.chordProgressionBarGroups = Array.from(chordProgressionsByTotalBars, ([totalBars, progressionKeys]) => ({
|
|
161
|
+
totalBars,
|
|
162
|
+
progressionKeys,
|
|
163
|
+
})).sort((a, b) => a.totalBars - b.totalBars);
|
|
@@ -9,8 +9,35 @@ export interface ChordProgressionChordReference {
|
|
|
9
9
|
}
|
|
10
10
|
export declare function isValidChordProgressionKey(key: string): key is ChordProgressionKey;
|
|
11
11
|
export declare function getChordProgressionChordNames(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): string[];
|
|
12
|
+
export declare function getChordProgressionRomanSymbols(progressionOrKey: ChordProgression | ChordProgressionKey): string[];
|
|
13
|
+
export declare function getChordProgressionKeysForTotalBars(totalBars: number): ChordProgressionKey[];
|
|
12
14
|
export declare function getChordProgressionUniqueChordNames(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): string[];
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Returns one chord reference for each authored chord entry in
|
|
17
|
+
* `progression.chords`.
|
|
18
|
+
*
|
|
19
|
+
* This is the "chord changes" view: a chord lasting 2 bars is returned once,
|
|
20
|
+
* because it is one chord entry/change, while repeated entries are preserved.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getChordProgressionChordChangeReferences(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[];
|
|
23
|
+
/**
|
|
24
|
+
* Returns each distinct chord reference once, preserving first-seen order from
|
|
25
|
+
* the chord-change list.
|
|
26
|
+
*/
|
|
14
27
|
export declare function getChordProgressionUniqueChordReferences(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[];
|
|
28
|
+
/**
|
|
29
|
+
* Returns duration-aware chord references grouped by bar.
|
|
30
|
+
*
|
|
31
|
+
* Each outer array item is one bar. A 2-bar chord appears in two bar entries,
|
|
32
|
+
* and a split bar can contain multiple chord references in order.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getChordProgressionChordReferencesByBar(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[][];
|
|
35
|
+
/**
|
|
36
|
+
* Returns duration-aware chord references in song/practice order.
|
|
37
|
+
*
|
|
38
|
+
* This flattens `getChordProgressionChordReferencesByBar`, so a 2-bar chord
|
|
39
|
+
* appears twice and split bars preserve their left-to-right order.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getChordProgressionSongChordReferences(rootNote: RootNote, progressionOrKey: ChordProgression | ChordProgressionKey): ChordProgressionChordReference[];
|
|
15
42
|
export declare function getChordProgressionTotalDurationInBars(progressionOrKey: ChordProgression | ChordProgressionKey): number;
|
|
16
43
|
//# sourceMappingURL=chord-progressions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chord-progressions.d.ts","sourceRoot":"","sources":["../../../src/src/utils/chord-progressions.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"chord-progressions.d.ts","sourceRoot":"","sources":["../../../src/src/utils/chord-progressions.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAMzE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;CAC/C;AASD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,GACV,GAAG,IAAI,mBAAmB,CAE5B;AA2CD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,EAAE,CAYV;AAED,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,EAAE,CAKV;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,MAAM,GAChB,mBAAmB,EAAE,CAKvB;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,EAAE,CAIV;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,CAKlC;AAED;;;GAGG;AACH,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,CAkBlC;AAED;;;;;GAKG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,EAAE,CAiDpC;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,CACpD,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,8BAA8B,EAAE,CAKlC;AAED,wBAAgB,sCAAsC,CACpD,gBAAgB,EAAE,gBAAgB,GAAG,mBAAmB,GACvD,MAAM,CAQR"}
|
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isValidChordProgressionKey = isValidChordProgressionKey;
|
|
4
4
|
exports.getChordProgressionChordNames = getChordProgressionChordNames;
|
|
5
|
+
exports.getChordProgressionRomanSymbols = getChordProgressionRomanSymbols;
|
|
6
|
+
exports.getChordProgressionKeysForTotalBars = getChordProgressionKeysForTotalBars;
|
|
5
7
|
exports.getChordProgressionUniqueChordNames = getChordProgressionUniqueChordNames;
|
|
6
|
-
exports.
|
|
8
|
+
exports.getChordProgressionChordChangeReferences = getChordProgressionChordChangeReferences;
|
|
7
9
|
exports.getChordProgressionUniqueChordReferences = getChordProgressionUniqueChordReferences;
|
|
10
|
+
exports.getChordProgressionChordReferencesByBar = getChordProgressionChordReferencesByBar;
|
|
11
|
+
exports.getChordProgressionSongChordReferences = getChordProgressionSongChordReferences;
|
|
8
12
|
exports.getChordProgressionTotalDurationInBars = getChordProgressionTotalDurationInBars;
|
|
9
13
|
const mod_js_1 = require("../data/chord-progressions/mod.js");
|
|
10
14
|
const mod_js_2 = require("../data/chords/mod.js");
|
|
11
15
|
const note_names_js_1 = require("./note-names.js");
|
|
16
|
+
const BAR_DURATION_EPSILON = 0.000000001;
|
|
12
17
|
function isValidChordProgressionKey(key) {
|
|
13
18
|
return Object.prototype.hasOwnProperty.call(mod_js_1.chordProgressions, key);
|
|
14
19
|
}
|
|
@@ -17,17 +22,14 @@ function resolveProgression(progressionOrKey) {
|
|
|
17
22
|
return progressionOrKey;
|
|
18
23
|
return mod_js_1.chordProgressions[progressionOrKey];
|
|
19
24
|
}
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
function createChordProgressionChordReference(chord, chordRootNote) {
|
|
26
|
+
return {
|
|
27
|
+
rootNote: chordRootNote,
|
|
28
|
+
chordName: chordRootNote + chord.quality,
|
|
29
|
+
noteCollectionKey: (0, mod_js_2.getChordQualityNoteCollectionKey)(chord.quality),
|
|
30
|
+
};
|
|
26
31
|
}
|
|
27
|
-
function
|
|
28
|
-
return Array.from(new Set(getChordProgressionChordNames(rootNote, progressionOrKey)));
|
|
29
|
-
}
|
|
30
|
-
function getChordProgressionChordReferences(rootNote, progressionOrKey) {
|
|
32
|
+
function getResolvedChordProgressionChordReferences(rootNote, progressionOrKey) {
|
|
31
33
|
const progression = resolveProgression(progressionOrKey);
|
|
32
34
|
if (!progression)
|
|
33
35
|
return [];
|
|
@@ -37,16 +39,49 @@ function getChordProgressionChordReferences(rootNote, progressionOrKey) {
|
|
|
37
39
|
if (!chordRootNote)
|
|
38
40
|
return [];
|
|
39
41
|
return [{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
noteCollectionKey: (0, mod_js_2.getChordQualityNoteCollectionKey)(chord.quality),
|
|
42
|
+
chord,
|
|
43
|
+
reference: createChordProgressionChordReference(chord, chordRootNote),
|
|
43
44
|
}];
|
|
44
45
|
});
|
|
45
46
|
}
|
|
47
|
+
function getChordProgressionChordNames(rootNote, progressionOrKey) {
|
|
48
|
+
const progression = resolveProgression(progressionOrKey);
|
|
49
|
+
if (!progression)
|
|
50
|
+
return [];
|
|
51
|
+
const noteNames = (0, note_names_js_1.getNoteNamesForRootAndIntervals)(rootNote, progression.chords.map((chord) => chord.degree));
|
|
52
|
+
return progression.chords.map((chord, index) => noteNames[index] + chord.quality);
|
|
53
|
+
}
|
|
54
|
+
function getChordProgressionRomanSymbols(progressionOrKey) {
|
|
55
|
+
const progression = resolveProgression(progressionOrKey);
|
|
56
|
+
if (!progression)
|
|
57
|
+
return [];
|
|
58
|
+
return progression.chords.map((chord) => chord.romanSymbol);
|
|
59
|
+
}
|
|
60
|
+
function getChordProgressionKeysForTotalBars(totalBars) {
|
|
61
|
+
return mod_js_1.chordProgressionBarGroups.find((group) => group.totalBars === totalBars)
|
|
62
|
+
?.progressionKeys.slice() ?? [];
|
|
63
|
+
}
|
|
64
|
+
function getChordProgressionUniqueChordNames(rootNote, progressionOrKey) {
|
|
65
|
+
return Array.from(new Set(getChordProgressionChordNames(rootNote, progressionOrKey)));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Returns one chord reference for each authored chord entry in
|
|
69
|
+
* `progression.chords`.
|
|
70
|
+
*
|
|
71
|
+
* This is the "chord changes" view: a chord lasting 2 bars is returned once,
|
|
72
|
+
* because it is one chord entry/change, while repeated entries are preserved.
|
|
73
|
+
*/
|
|
74
|
+
function getChordProgressionChordChangeReferences(rootNote, progressionOrKey) {
|
|
75
|
+
return getResolvedChordProgressionChordReferences(rootNote, progressionOrKey).map(({ reference }) => reference);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Returns each distinct chord reference once, preserving first-seen order from
|
|
79
|
+
* the chord-change list.
|
|
80
|
+
*/
|
|
46
81
|
function getChordProgressionUniqueChordReferences(rootNote, progressionOrKey) {
|
|
47
82
|
const uniqueReferences = [];
|
|
48
83
|
const seen = new Set();
|
|
49
|
-
for (const reference of
|
|
84
|
+
for (const reference of getChordProgressionChordChangeReferences(rootNote, progressionOrKey)) {
|
|
50
85
|
const key = `${reference.rootNote}:${reference.noteCollectionKey}:${reference.chordName}`;
|
|
51
86
|
if (seen.has(key))
|
|
52
87
|
continue;
|
|
@@ -55,6 +90,51 @@ function getChordProgressionUniqueChordReferences(rootNote, progressionOrKey) {
|
|
|
55
90
|
}
|
|
56
91
|
return uniqueReferences;
|
|
57
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns duration-aware chord references grouped by bar.
|
|
95
|
+
*
|
|
96
|
+
* Each outer array item is one bar. A 2-bar chord appears in two bar entries,
|
|
97
|
+
* and a split bar can contain multiple chord references in order.
|
|
98
|
+
*/
|
|
99
|
+
function getChordProgressionChordReferencesByBar(rootNote, progressionOrKey) {
|
|
100
|
+
const bars = [];
|
|
101
|
+
let currentBar = [];
|
|
102
|
+
let remainingBarDuration = 1;
|
|
103
|
+
const pushCurrentBar = () => {
|
|
104
|
+
if (currentBar.length > 0) {
|
|
105
|
+
bars.push(currentBar);
|
|
106
|
+
}
|
|
107
|
+
currentBar = [];
|
|
108
|
+
remainingBarDuration = 1;
|
|
109
|
+
};
|
|
110
|
+
for (const { chord, reference } of getResolvedChordProgressionChordReferences(rootNote, progressionOrKey)) {
|
|
111
|
+
let remainingChordDuration = chord.durationInBars;
|
|
112
|
+
if (!Number.isFinite(remainingChordDuration) ||
|
|
113
|
+
remainingChordDuration <= BAR_DURATION_EPSILON) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
while (remainingChordDuration > BAR_DURATION_EPSILON) {
|
|
117
|
+
currentBar.push(reference);
|
|
118
|
+
const filledDuration = Math.min(remainingChordDuration, remainingBarDuration);
|
|
119
|
+
remainingChordDuration -= filledDuration;
|
|
120
|
+
remainingBarDuration -= filledDuration;
|
|
121
|
+
if (remainingBarDuration <= BAR_DURATION_EPSILON) {
|
|
122
|
+
pushCurrentBar();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
pushCurrentBar();
|
|
127
|
+
return bars;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns duration-aware chord references in song/practice order.
|
|
131
|
+
*
|
|
132
|
+
* This flattens `getChordProgressionChordReferencesByBar`, so a 2-bar chord
|
|
133
|
+
* appears twice and split bars preserve their left-to-right order.
|
|
134
|
+
*/
|
|
135
|
+
function getChordProgressionSongChordReferences(rootNote, progressionOrKey) {
|
|
136
|
+
return getChordProgressionChordReferencesByBar(rootNote, progressionOrKey).flat();
|
|
137
|
+
}
|
|
58
138
|
function getChordProgressionTotalDurationInBars(progressionOrKey) {
|
|
59
139
|
const progression = resolveProgression(progressionOrKey);
|
|
60
140
|
if (!progression)
|