@libraz/libcantus 1.3.0 → 1.4.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/NOTICE +63 -0
- package/README.md +3 -1
- package/README_ja.md +13 -11
- package/dist/analyze/index.cjs +7 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +14 -12
- package/dist/analyze/index.d.ts +14 -12
- package/dist/analyze/index.js +6 -6
- package/dist/{chunk-NB25P3EH.js → chunk-2G5MCGYU.js} +33 -11
- package/dist/chunk-2G5MCGYU.js.map +1 -0
- package/dist/{chunk-NM7UAMC3.cjs → chunk-3FDBMIPR.cjs} +64 -64
- package/dist/chunk-3FDBMIPR.cjs.map +1 -0
- package/dist/{chunk-YFA7X2F6.cjs → chunk-3MDOEFIQ.cjs} +411 -327
- package/dist/chunk-3MDOEFIQ.cjs.map +1 -0
- package/dist/{chunk-IPEF6NWB.js → chunk-5MWRBYAT.js} +278 -154
- package/dist/chunk-5MWRBYAT.js.map +1 -0
- package/dist/{chunk-B2PW6EHN.cjs → chunk-6TTBEON3.cjs} +1253 -889
- package/dist/chunk-6TTBEON3.cjs.map +1 -0
- package/dist/{chunk-UMWZ4ZET.js → chunk-7NQ6AL3H.js} +4 -4
- package/dist/chunk-7NQ6AL3H.js.map +1 -0
- package/dist/{chunk-PWC4CRWT.cjs → chunk-E3QO3UET.cjs} +31 -23
- package/dist/chunk-E3QO3UET.cjs.map +1 -0
- package/dist/{chunk-GNVN4PPJ.js → chunk-FJFULJZE.js} +531 -213
- package/dist/chunk-FJFULJZE.js.map +1 -0
- package/dist/{chunk-CPMB7P75.js → chunk-FK3DGAIZ.js} +608 -244
- package/dist/chunk-FK3DGAIZ.js.map +1 -0
- package/dist/chunk-GEDTJHAC.cjs.map +1 -1
- package/dist/{chunk-RFIBF2RR.js → chunk-H7FVMBUC.js} +138 -65
- package/dist/chunk-H7FVMBUC.js.map +1 -0
- package/dist/{chunk-4R2LWV7E.cjs → chunk-HYSVSFNI.cjs} +664 -540
- package/dist/chunk-HYSVSFNI.cjs.map +1 -0
- package/dist/{chunk-35NBV2FT.cjs → chunk-KMYGRFZ6.cjs} +47 -24
- package/dist/chunk-KMYGRFZ6.cjs.map +1 -0
- package/dist/{chunk-IFZDWIKM.cjs → chunk-LQZQDBCD.cjs} +1048 -730
- package/dist/chunk-LQZQDBCD.cjs.map +1 -0
- package/dist/{chunk-PM4XJE2Y.cjs → chunk-P3CPXAJ5.cjs} +76 -54
- package/dist/chunk-P3CPXAJ5.cjs.map +1 -0
- package/dist/{chunk-S5BKZZGM.cjs → chunk-S3QELJUE.cjs} +72 -56
- package/dist/chunk-S3QELJUE.cjs.map +1 -0
- package/dist/{chunk-PUKJP2Z5.js → chunk-TXFWSU5D.js} +31 -8
- package/dist/chunk-TXFWSU5D.js.map +1 -0
- package/dist/{chunk-76ZBTRG2.cjs → chunk-U4EQTDGN.cjs} +258 -218
- package/dist/chunk-U4EQTDGN.cjs.map +1 -0
- package/dist/chunk-UGLFDG7L.cjs.map +1 -1
- package/dist/{chunk-MLBPXA4Z.js → chunk-UTE5A36R.js} +198 -114
- package/dist/chunk-UTE5A36R.js.map +1 -0
- package/dist/{chunk-ZBUROTJQ.js → chunk-UZKQISRF.js} +17 -9
- package/dist/chunk-UZKQISRF.js.map +1 -0
- package/dist/{chunk-7KG3RTYS.js → chunk-VL5NXVCN.js} +281 -155
- package/dist/chunk-VL5NXVCN.js.map +1 -0
- package/dist/{chunk-CGBADIO5.cjs → chunk-WOMCXN2W.cjs} +328 -202
- package/dist/chunk-WOMCXN2W.cjs.map +1 -0
- package/dist/{chunk-3R3QVKY5.cjs → chunk-YDGMWH43.cjs} +397 -324
- package/dist/chunk-YDGMWH43.cjs.map +1 -0
- package/dist/{chunk-AGOVW7U6.js → chunk-YYVXRV3V.js} +72 -56
- package/dist/chunk-YYVXRV3V.js.map +1 -0
- package/dist/{chunk-M5RYMAFI.js → chunk-ZLNSH4UL.js} +71 -31
- package/dist/chunk-ZLNSH4UL.js.map +1 -0
- package/dist/{coerce-DRERzdve.d.cts → coerce-CUhHc3Tu.d.ts} +16 -8
- package/dist/{coerce-DP0vYu-x.d.ts → coerce-Ytt2Eiq9.d.cts} +16 -8
- package/dist/core/index.cjs +5 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +9 -8
- package/dist/core/index.d.ts +9 -8
- package/dist/core/index.js +4 -4
- package/dist/generate/index.cjs +8 -8
- package/dist/generate/index.cjs.map +1 -1
- package/dist/generate/index.d.cts +28 -18
- package/dist/generate/index.d.ts +28 -18
- package/dist/generate/index.js +7 -7
- package/dist/{index-BMweUlm5.d.cts → index-5VJgKz_Q.d.cts} +6 -2
- package/dist/{index-BHIUyjhZ.d.ts → index-BLuDesVG.d.ts} +20 -13
- package/dist/{index-B9QLziDe.d.cts → index-BV6APVa6.d.cts} +20 -13
- package/dist/{index-CL4b4gUQ.d.ts → index-Bf0Sv8a9.d.ts} +6 -2
- package/dist/{index-Dw2DP7vm.d.ts → index-BkT21EMv.d.cts} +3 -2
- package/dist/{index-BL5N2Oyz.d.cts → index-C7KCaTRz.d.ts} +3 -2
- package/dist/{index-Cy15oTvh.d.ts → index-C9MYbuKS.d.cts} +7 -3
- package/dist/{index-Cy15oTvh.d.cts → index-C9MYbuKS.d.ts} +7 -3
- package/dist/{index-CY-3NVfy.d.cts → index-DVInzCDS.d.cts} +53 -29
- package/dist/{index-9eoQs2C1.d.ts → index-Dg-SAfhz.d.ts} +6 -4
- package/dist/{index-zaZdmnU4.d.ts → index-jgeug9EA.d.ts} +53 -29
- package/dist/{index-cHvbYgJI.d.cts → index-pQihL4z7.d.cts} +6 -4
- package/dist/index.cjs +13 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +12 -12
- package/dist/{masks-Cc7-MzzY.d.ts → masks-BnzXnBj0.d.cts} +3 -2
- package/dist/{masks-pADfTOiD.d.cts → masks-tycmkrgs.d.ts} +3 -2
- package/dist/model/index.cjs +12 -12
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +63 -48
- package/dist/model/index.d.ts +63 -48
- package/dist/model/index.js +11 -11
- package/dist/{positional-DJgs6ltD.d.ts → positional-CscpxtlE.d.cts} +3 -2
- package/dist/{positional-DMZer-FM.d.cts → positional-DLnfUgqG.d.ts} +3 -2
- package/dist/{profile-DLdlIpS9.d.ts → profile-B4WqcM4H.d.ts} +25 -17
- package/dist/{profile-CQMEqdH9.d.cts → profile-BJd1XkPB.d.cts} +25 -17
- package/dist/theory/index.cjs +5 -5
- package/dist/theory/index.cjs.map +1 -1
- package/dist/theory/index.d.cts +18 -14
- package/dist/theory/index.d.ts +18 -14
- package/dist/theory/index.js +4 -4
- package/dist/{types-D-XgxGvp.d.cts → types-7mGFwvMm.d.ts} +45 -22
- package/dist/{types-Dh7C064C.d.ts → types-_ofpb2be.d.cts} +45 -22
- package/package.json +13 -13
- package/dist/chunk-35NBV2FT.cjs.map +0 -1
- package/dist/chunk-3R3QVKY5.cjs.map +0 -1
- package/dist/chunk-4R2LWV7E.cjs.map +0 -1
- package/dist/chunk-76ZBTRG2.cjs.map +0 -1
- package/dist/chunk-7KG3RTYS.js.map +0 -1
- package/dist/chunk-AGOVW7U6.js.map +0 -1
- package/dist/chunk-B2PW6EHN.cjs.map +0 -1
- package/dist/chunk-CGBADIO5.cjs.map +0 -1
- package/dist/chunk-CPMB7P75.js.map +0 -1
- package/dist/chunk-GNVN4PPJ.js.map +0 -1
- package/dist/chunk-IFZDWIKM.cjs.map +0 -1
- package/dist/chunk-IPEF6NWB.js.map +0 -1
- package/dist/chunk-M5RYMAFI.js.map +0 -1
- package/dist/chunk-MLBPXA4Z.js.map +0 -1
- package/dist/chunk-NB25P3EH.js.map +0 -1
- package/dist/chunk-NM7UAMC3.cjs.map +0 -1
- package/dist/chunk-PM4XJE2Y.cjs.map +0 -1
- package/dist/chunk-PUKJP2Z5.js.map +0 -1
- package/dist/chunk-PWC4CRWT.cjs.map +0 -1
- package/dist/chunk-RFIBF2RR.js.map +0 -1
- package/dist/chunk-S5BKZZGM.cjs.map +0 -1
- package/dist/chunk-UMWZ4ZET.js.map +0 -1
- package/dist/chunk-YFA7X2F6.cjs.map +0 -1
- package/dist/chunk-ZBUROTJQ.js.map +0 -1
|
@@ -2,15 +2,21 @@ import {
|
|
|
2
2
|
analyzeArrangement,
|
|
3
3
|
analyzePolyphony,
|
|
4
4
|
analyzeReference,
|
|
5
|
+
arrangementProfile,
|
|
6
|
+
assertTrackNotes,
|
|
7
|
+
boundaryCadences,
|
|
5
8
|
createArrangementSession,
|
|
9
|
+
harmonyTrackSet,
|
|
6
10
|
hypermeter,
|
|
11
|
+
hypermeterOver,
|
|
12
|
+
keyContextFor,
|
|
7
13
|
phrasesFromTimeline,
|
|
8
14
|
referenceFromReadings,
|
|
9
15
|
sectionsFromNotes,
|
|
10
16
|
structuralCadences,
|
|
11
17
|
tensionCurveFrom,
|
|
12
18
|
trackRoleOf
|
|
13
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-UTE5A36R.js";
|
|
14
20
|
import {
|
|
15
21
|
TWELVE_TET,
|
|
16
22
|
beatsToDuration,
|
|
@@ -34,15 +40,15 @@ import {
|
|
|
34
40
|
tempoAt,
|
|
35
41
|
tempoReader,
|
|
36
42
|
ticksToBeats
|
|
37
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-7NQ6AL3H.js";
|
|
38
44
|
import {
|
|
39
45
|
STEP_BEATS,
|
|
40
46
|
applyGrooveTemplate,
|
|
41
47
|
cellSpan,
|
|
42
|
-
|
|
48
|
+
deformFigure,
|
|
43
49
|
deriveCompositionPlan,
|
|
44
50
|
developMotif,
|
|
45
|
-
|
|
51
|
+
doubleTimeFigure,
|
|
46
52
|
evaluateComposition,
|
|
47
53
|
extractGrooveTemplate,
|
|
48
54
|
generateBassLine,
|
|
@@ -52,7 +58,7 @@ import {
|
|
|
52
58
|
generateMotif,
|
|
53
59
|
generateProgression,
|
|
54
60
|
generateRhythm,
|
|
55
|
-
|
|
61
|
+
halfTimeFigure,
|
|
56
62
|
harmonizeMelody,
|
|
57
63
|
humanize,
|
|
58
64
|
modalInterchangePalette,
|
|
@@ -61,6 +67,7 @@ import {
|
|
|
61
67
|
ornament,
|
|
62
68
|
ornamentBy,
|
|
63
69
|
resolveContext,
|
|
70
|
+
resolveDials,
|
|
64
71
|
rhythmDensity,
|
|
65
72
|
rhythmToNoteEvents,
|
|
66
73
|
substituteChord,
|
|
@@ -68,10 +75,11 @@ import {
|
|
|
68
75
|
thin,
|
|
69
76
|
transformMotif,
|
|
70
77
|
withinCeiling
|
|
71
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-FK3DGAIZ.js";
|
|
72
79
|
import {
|
|
73
80
|
analyzeChord,
|
|
74
81
|
analyzeRhythm,
|
|
82
|
+
assertSpansInOrder,
|
|
75
83
|
augmentedSixthChord,
|
|
76
84
|
borrowedSource,
|
|
77
85
|
chordAtBeat,
|
|
@@ -103,8 +111,9 @@ import {
|
|
|
103
111
|
relateMotifs,
|
|
104
112
|
romanToChord,
|
|
105
113
|
secondaryDominantOf,
|
|
114
|
+
statedKeyRegions,
|
|
106
115
|
toVoiceNotes
|
|
107
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-FJFULJZE.js";
|
|
108
117
|
import {
|
|
109
118
|
BASS_4_STRING,
|
|
110
119
|
BASS_5_STRING,
|
|
@@ -117,10 +126,10 @@ import {
|
|
|
117
126
|
soundsIn,
|
|
118
127
|
toInstrumentProfile,
|
|
119
128
|
toStringedProfile
|
|
120
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-VL5NXVCN.js";
|
|
121
130
|
import {
|
|
122
131
|
createNoteEventIndex
|
|
123
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-TXFWSU5D.js";
|
|
124
133
|
import {
|
|
125
134
|
SATB_RANGES,
|
|
126
135
|
checkPartWriting,
|
|
@@ -135,14 +144,14 @@ import {
|
|
|
135
144
|
voiceChordStyled,
|
|
136
145
|
voiceLeadingCost,
|
|
137
146
|
voiceProgression
|
|
138
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-ZLNSH4UL.js";
|
|
139
148
|
import {
|
|
140
149
|
availableTensions,
|
|
141
150
|
avoidNotes,
|
|
142
151
|
chordScaleReport,
|
|
143
152
|
chordScales,
|
|
144
153
|
scalesForChanges
|
|
145
|
-
} from "./chunk-
|
|
154
|
+
} from "./chunk-2G5MCGYU.js";
|
|
146
155
|
import {
|
|
147
156
|
NAMED_SCALES,
|
|
148
157
|
assertChordQuality,
|
|
@@ -153,6 +162,7 @@ import {
|
|
|
153
162
|
chordSpecOf,
|
|
154
163
|
chordToneRole,
|
|
155
164
|
chordToneSpellings,
|
|
165
|
+
classifySpelledInterval,
|
|
156
166
|
diatonicPitchClasses,
|
|
157
167
|
diatonicSeventh,
|
|
158
168
|
diatonicTriad,
|
|
@@ -198,10 +208,11 @@ import {
|
|
|
198
208
|
tryResolveKeyName,
|
|
199
209
|
variantOfMask,
|
|
200
210
|
voiceIndependence
|
|
201
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-H7FVMBUC.js";
|
|
202
212
|
import {
|
|
203
213
|
InvalidInputError,
|
|
204
214
|
MAX_NAME_ACCIDENTALS,
|
|
215
|
+
assertArray,
|
|
205
216
|
assertFiniteNumber,
|
|
206
217
|
assertInteger,
|
|
207
218
|
assertMidiPitch,
|
|
@@ -209,9 +220,11 @@ import {
|
|
|
209
220
|
assertOneOf,
|
|
210
221
|
assertPositiveInt,
|
|
211
222
|
assertRange,
|
|
223
|
+
assertRecord,
|
|
212
224
|
assertTimeSignature,
|
|
213
225
|
beatToBarPosition,
|
|
214
226
|
beatsPerBar,
|
|
227
|
+
beatsPerBarAt,
|
|
215
228
|
describeRejected,
|
|
216
229
|
formatBarPosition,
|
|
217
230
|
formatKeyName,
|
|
@@ -219,7 +232,6 @@ import {
|
|
|
219
232
|
formatTimeSignature,
|
|
220
233
|
intervalSemitones,
|
|
221
234
|
isCompound,
|
|
222
|
-
isConsonantInterval,
|
|
223
235
|
isStrongBeat,
|
|
224
236
|
meterAt,
|
|
225
237
|
metricWeight,
|
|
@@ -242,7 +254,7 @@ import {
|
|
|
242
254
|
tryParseTimeSignature,
|
|
243
255
|
tuplet,
|
|
244
256
|
unwrapParse
|
|
245
|
-
} from "./chunk-
|
|
257
|
+
} from "./chunk-YYVXRV3V.js";
|
|
246
258
|
|
|
247
259
|
// src/model/interval.ts
|
|
248
260
|
var INVERSION_SUM = 9;
|
|
@@ -251,6 +263,14 @@ function simpleDegree(numberValue) {
|
|
|
251
263
|
const reduced = (numberValue - 1) % 7 + 1;
|
|
252
264
|
return reduced === 1 && numberValue > 1 ? OCTAVE_DEGREES : reduced;
|
|
253
265
|
}
|
|
266
|
+
function checkedDirection(descending) {
|
|
267
|
+
if (typeof descending !== "boolean") {
|
|
268
|
+
throw new InvalidInputError(
|
|
269
|
+
`interval.descending must be a boolean; received ${describeRejected(descending)}`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
return descending;
|
|
273
|
+
}
|
|
254
274
|
function invertQuality(quality) {
|
|
255
275
|
if (quality === "P") {
|
|
256
276
|
return "P";
|
|
@@ -282,6 +302,12 @@ var Interval = class _Interval {
|
|
|
282
302
|
* @returns The interval from `a` to `b`.
|
|
283
303
|
*/
|
|
284
304
|
static between(a, b) {
|
|
305
|
+
if (typeof a !== "object" || a === null || typeof a.intervalTo !== "function") {
|
|
306
|
+
throw new InvalidInputError(`interval a must be a Note; received ${describeRejected(a)}`);
|
|
307
|
+
}
|
|
308
|
+
if (typeof b !== "object" || b === null || typeof b.data !== "object" || b.data === null) {
|
|
309
|
+
throw new InvalidInputError(`interval b must be a Note; received ${describeRejected(b)}`);
|
|
310
|
+
}
|
|
285
311
|
return a.intervalTo(b);
|
|
286
312
|
}
|
|
287
313
|
/**
|
|
@@ -312,7 +338,12 @@ var Interval = class _Interval {
|
|
|
312
338
|
*/
|
|
313
339
|
static fromData(data) {
|
|
314
340
|
const checked = toSpelledInterval(data);
|
|
315
|
-
return new _Interval(
|
|
341
|
+
return new _Interval(
|
|
342
|
+
checked.number,
|
|
343
|
+
checked.quality,
|
|
344
|
+
checked.semitones,
|
|
345
|
+
checkedDirection(checked.descending)
|
|
346
|
+
);
|
|
316
347
|
}
|
|
317
348
|
/**
|
|
318
349
|
* Rebuild an interval from its {@link Interval.toJSON} output.
|
|
@@ -437,12 +468,15 @@ var Interval = class _Interval {
|
|
|
437
468
|
/**
|
|
438
469
|
* Whether the interval is consonant.
|
|
439
470
|
*
|
|
471
|
+
* The spelling decides, not the span: a diminished fourth is a dissonance
|
|
472
|
+
* though it sounds like a major third.
|
|
473
|
+
*
|
|
440
474
|
* @param twoVoice When true, the perfect fourth counts as a dissonance,
|
|
441
475
|
* matching two-voice counterpoint.
|
|
442
476
|
* @returns True if the interval is consonant in that context.
|
|
443
477
|
*/
|
|
444
478
|
isConsonant(twoVoice = true) {
|
|
445
|
-
return
|
|
479
|
+
return classifySpelledInterval(this.toJSON(), twoVoice) !== 2 /* Dissonance */;
|
|
446
480
|
}
|
|
447
481
|
/**
|
|
448
482
|
* Whether another interval is spelled identically.
|
|
@@ -489,7 +523,6 @@ var Interval = class _Interval {
|
|
|
489
523
|
};
|
|
490
524
|
|
|
491
525
|
// src/model/shared.ts
|
|
492
|
-
var STATED_KEY_CONFIDENCE = 1;
|
|
493
526
|
function describeShape(value) {
|
|
494
527
|
if (value === null) {
|
|
495
528
|
return "null";
|
|
@@ -1072,6 +1105,22 @@ var Note = class _Note {
|
|
|
1072
1105
|
};
|
|
1073
1106
|
|
|
1074
1107
|
// src/model/timeline.ts
|
|
1108
|
+
var KEY_RELATIONS = [
|
|
1109
|
+
"same",
|
|
1110
|
+
"enharmonic",
|
|
1111
|
+
"relative",
|
|
1112
|
+
"parallel",
|
|
1113
|
+
"dominant",
|
|
1114
|
+
"subdominant",
|
|
1115
|
+
"relativeOfDominant",
|
|
1116
|
+
"relativeOfSubdominant"
|
|
1117
|
+
];
|
|
1118
|
+
function assertNumeral(numeral, name) {
|
|
1119
|
+
if (typeof numeral !== "string") {
|
|
1120
|
+
throw new InvalidInputError(`${name} must be a string; received ${describeRejected(numeral)}`);
|
|
1121
|
+
}
|
|
1122
|
+
return numeral;
|
|
1123
|
+
}
|
|
1075
1124
|
function copySegment(segment) {
|
|
1076
1125
|
assertDataObject(segment, "timeline segment");
|
|
1077
1126
|
return {
|
|
@@ -1094,14 +1143,14 @@ function copyKeyRegion(region) {
|
|
|
1094
1143
|
confidence: assertFiniteNumber(region.confidence, "key region confidence")
|
|
1095
1144
|
};
|
|
1096
1145
|
if (region.modulation !== void 0) {
|
|
1097
|
-
copy.modulation = region.modulation;
|
|
1146
|
+
copy.modulation = assertOneOf(region.modulation, KEY_RELATIONS, "key region modulation");
|
|
1098
1147
|
}
|
|
1099
1148
|
if (region.pivot !== void 0) {
|
|
1100
1149
|
assertDataObject(region.pivot, "key region pivot");
|
|
1101
1150
|
copy.pivot = {
|
|
1102
1151
|
chord: new Chord(region.pivot.chord).toJSON(),
|
|
1103
|
-
romanFrom: region.pivot.romanFrom,
|
|
1104
|
-
romanTo: region.pivot.romanTo
|
|
1152
|
+
romanFrom: assertNumeral(region.pivot.romanFrom, "key region pivot romanFrom"),
|
|
1153
|
+
romanTo: assertNumeral(region.pivot.romanTo, "key region pivot romanTo")
|
|
1105
1154
|
};
|
|
1106
1155
|
}
|
|
1107
1156
|
return copy;
|
|
@@ -1120,6 +1169,10 @@ function copyConfidence(confidence, segments) {
|
|
|
1120
1169
|
(value, index) => assertRange(value, 0, 1, `timeline segmentConfidence[${index}]`)
|
|
1121
1170
|
);
|
|
1122
1171
|
}
|
|
1172
|
+
function validateTimeline(segments, keys) {
|
|
1173
|
+
assertSpansInOrder(segments, "timeline segments");
|
|
1174
|
+
assertSpansInOrder(keys, "timeline keys");
|
|
1175
|
+
}
|
|
1123
1176
|
function clipSpan(span, fromBeat, toBeat) {
|
|
1124
1177
|
const startBeat = Math.max(span.startBeat, fromBeat);
|
|
1125
1178
|
const endBeat = Math.min(span.endBeat, toBeat);
|
|
@@ -1135,8 +1188,9 @@ var Timeline = class _Timeline {
|
|
|
1135
1188
|
*
|
|
1136
1189
|
* @param data The segments and the span they cover; copied, never retained.
|
|
1137
1190
|
* @throws If the span, a segment, or a key region carries a number it cannot
|
|
1138
|
-
* hold — a beat that is not finite, a mode mask that names no scale —
|
|
1139
|
-
* the
|
|
1191
|
+
* hold — a beat that is not finite, a mode mask that names no scale — if
|
|
1192
|
+
* the segments or the key regions are not disjoint, in beat order and of
|
|
1193
|
+
* positive length, or if the confidences do not run one per segment.
|
|
1140
1194
|
*/
|
|
1141
1195
|
constructor(data) {
|
|
1142
1196
|
assertDataObject(data, "timeline data");
|
|
@@ -1155,6 +1209,7 @@ var Timeline = class _Timeline {
|
|
|
1155
1209
|
this.#segmentConfidence = Object.freeze(
|
|
1156
1210
|
copyConfidence(data.segmentConfidence, this.#segments.length)
|
|
1157
1211
|
);
|
|
1212
|
+
validateTimeline(this.#segments, this.#keys);
|
|
1158
1213
|
}
|
|
1159
1214
|
/**
|
|
1160
1215
|
* Build a timeline from placed chords.
|
|
@@ -1162,7 +1217,8 @@ var Timeline = class _Timeline {
|
|
|
1162
1217
|
* @param spans The chords with their onsets, in any order.
|
|
1163
1218
|
* @param totalBeats Where the last chord stops sounding.
|
|
1164
1219
|
* @param key The key the chords are read in, when it is already known. It
|
|
1165
|
-
* becomes the one key region
|
|
1220
|
+
* becomes the one key region from the first chord to the end of the span;
|
|
1221
|
+
* without it, or without a chord for it to be in force over, the timeline
|
|
1166
1222
|
* carries no key, and the members that need one say so.
|
|
1167
1223
|
* @returns The timeline.
|
|
1168
1224
|
*/
|
|
@@ -1170,16 +1226,9 @@ var Timeline = class _Timeline {
|
|
|
1170
1226
|
const timeline = chordTimelineFromChords(spans, totalBeats);
|
|
1171
1227
|
const data = { segments: timeline.segments, totalBeats };
|
|
1172
1228
|
if (key !== void 0) {
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
// so a chord placed in a pickup is covered by the key it sounds in.
|
|
1177
|
-
startBeat: timeline.segments[0]?.startBeat ?? 0,
|
|
1178
|
-
endBeat: totalBeats,
|
|
1179
|
-
key: keyIdentity(toKey(key)),
|
|
1180
|
-
confidence: STATED_KEY_CONFIDENCE
|
|
1181
|
-
}
|
|
1182
|
-
];
|
|
1229
|
+
const stated = keyIdentity(toKey(key));
|
|
1230
|
+
const first = timeline.segments[0];
|
|
1231
|
+
data.keys = first === void 0 ? [] : statedKeyRegions(stated, first.startBeat, totalBeats);
|
|
1183
1232
|
}
|
|
1184
1233
|
return new _Timeline(data);
|
|
1185
1234
|
}
|
|
@@ -1210,11 +1259,25 @@ var Timeline = class _Timeline {
|
|
|
1210
1259
|
* @throws If `beatsEach` is not a positive finite number of beats.
|
|
1211
1260
|
*/
|
|
1212
1261
|
static fromProgression(progression, beatsEach) {
|
|
1262
|
+
const read = progression;
|
|
1263
|
+
if (typeof read !== "object" || read === null || !Array.isArray(read.chords)) {
|
|
1264
|
+
throw new InvalidInputError(
|
|
1265
|
+
`timeline progression must be a Progression; received ${describeRejected(progression)}`
|
|
1266
|
+
);
|
|
1267
|
+
}
|
|
1213
1268
|
assertRange(beatsEach, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "timeline beatsEach");
|
|
1214
|
-
const chords =
|
|
1215
|
-
const spans = chords.map((chord, index) =>
|
|
1269
|
+
const chords = read.chords;
|
|
1270
|
+
const spans = chords.map((chord, index) => {
|
|
1271
|
+
const data = chord?.data;
|
|
1272
|
+
if (typeof data !== "object" || data === null) {
|
|
1273
|
+
throw new InvalidInputError(
|
|
1274
|
+
`timeline progression chords[${index}] must be a Chord; received ${describeRejected(chord)}`
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
return spanFromChord(data, index * beatsEach);
|
|
1278
|
+
});
|
|
1216
1279
|
const totalBeats = chords.length * beatsEach;
|
|
1217
|
-
const key =
|
|
1280
|
+
const key = read.key;
|
|
1218
1281
|
return key === void 0 ? _Timeline.fromChords(spans, totalBeats) : _Timeline.fromChords(spans, totalBeats, key);
|
|
1219
1282
|
}
|
|
1220
1283
|
/** Rebuild a timeline from the plain data {@link Timeline.data} hands out. */
|
|
@@ -1606,7 +1669,14 @@ var Progression = class _Progression {
|
|
|
1606
1669
|
*/
|
|
1607
1670
|
static #attachKey(chords, key) {
|
|
1608
1671
|
const given = assertDataObjects(chords, "progression chords");
|
|
1609
|
-
return
|
|
1672
|
+
return given.map((chord, index) => {
|
|
1673
|
+
if (typeof chord.toJSON !== "function") {
|
|
1674
|
+
throw new InvalidInputError(
|
|
1675
|
+
`progression chords[${index}] must be a Chord; received ${describeRejected(chord)}`
|
|
1676
|
+
);
|
|
1677
|
+
}
|
|
1678
|
+
return new Chord(chord.toJSON(), key ?? chord.key);
|
|
1679
|
+
});
|
|
1610
1680
|
}
|
|
1611
1681
|
/**
|
|
1612
1682
|
* Start from a chord sequence, matching the `of` factory on the other
|
|
@@ -1654,19 +1724,34 @@ var Progression = class _Progression {
|
|
|
1654
1724
|
return new _Progression(chords, key);
|
|
1655
1725
|
}
|
|
1656
1726
|
/**
|
|
1657
|
-
* Rebuild a progression from its {@link Progression.toJSON} output
|
|
1727
|
+
* Rebuild a progression from its {@link Progression.toJSON} output, with the
|
|
1728
|
+
* carried key or, without one, each chord's own key.
|
|
1658
1729
|
*
|
|
1659
|
-
* @param data The serialized chords and
|
|
1730
|
+
* @param data The serialized chords and keys.
|
|
1660
1731
|
* @returns The progression.
|
|
1732
|
+
* @throws If `chordKeys` does not hold one entry per chord.
|
|
1661
1733
|
*/
|
|
1662
1734
|
static fromJSON(data) {
|
|
1663
1735
|
assertDataObject(data, "progression data");
|
|
1664
1736
|
const key = data.key === void 0 ? void 0 : Key.fromJSON(data.key);
|
|
1665
|
-
const
|
|
1666
|
-
|
|
1667
|
-
)
|
|
1737
|
+
const given = assertDataArray(data.chords, "progression chords");
|
|
1738
|
+
const chordKeys = key === void 0 && data.chordKeys !== void 0 ? _Progression.#readChordKeys(data.chordKeys, given.length) : void 0;
|
|
1739
|
+
const chords = given.map((chord, index) => {
|
|
1740
|
+
const own = chordKeys?.[index];
|
|
1741
|
+
return own === void 0 ? Chord.fromJSON(chord) : Chord.fromJSON(chord).withKey(own);
|
|
1742
|
+
});
|
|
1668
1743
|
return key === void 0 ? new _Progression(chords) : new _Progression(chords, key);
|
|
1669
1744
|
}
|
|
1745
|
+
/** Read the per-chord keys of {@link ProgressionData}, one entry per chord. */
|
|
1746
|
+
static #readChordKeys(value, count) {
|
|
1747
|
+
const entries = assertDataArray(value, "progression chord keys");
|
|
1748
|
+
if (entries.length !== count) {
|
|
1749
|
+
throw new InvalidInputError(
|
|
1750
|
+
`progression chord keys must hold one entry per chord (${count}); received ${entries.length}`
|
|
1751
|
+
);
|
|
1752
|
+
}
|
|
1753
|
+
return entries.map((entry) => entry === null ? void 0 : Key.fromJSON(entry));
|
|
1754
|
+
}
|
|
1670
1755
|
/**
|
|
1671
1756
|
* Wrap plain progression data, matching the `fromData` factory on the other
|
|
1672
1757
|
* classes.
|
|
@@ -1877,10 +1962,8 @@ var Progression = class _Progression {
|
|
|
1877
1962
|
*/
|
|
1878
1963
|
voice(opts) {
|
|
1879
1964
|
const key = opts?.key ?? this.#key;
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
key === void 0 ? opts : { ...opts, key }
|
|
1883
|
-
);
|
|
1965
|
+
const views = opts?.key === void 0 ? this.#chords.map((chord) => chord.data) : this.#viewsIn(toKey(opts.key));
|
|
1966
|
+
return voiceProgression(views, key === void 0 ? opts : { ...opts, key });
|
|
1884
1967
|
}
|
|
1885
1968
|
/**
|
|
1886
1969
|
* The Roman numeral of each chord in a key.
|
|
@@ -1941,12 +2024,13 @@ var Progression = class _Progression {
|
|
|
1941
2024
|
const resolved = this.#resolveKey(key);
|
|
1942
2025
|
const chords = this.#chords.map((chord) => chord.analyze(resolved, opts));
|
|
1943
2026
|
const { voicing, ...cadenceOpts } = opts ?? {};
|
|
1944
|
-
const
|
|
1945
|
-
const
|
|
1946
|
-
const
|
|
1947
|
-
const
|
|
2027
|
+
const views = this.#viewsIn(resolved);
|
|
2028
|
+
const from = views[views.length - 2];
|
|
2029
|
+
const to = views[views.length - 1];
|
|
2030
|
+
const approach = views[views.length - 3];
|
|
2031
|
+
const cadence = from !== void 0 && to !== void 0 ? detectCadence(from, to, resolved, {
|
|
1948
2032
|
...cadenceOpts,
|
|
1949
|
-
...approach === void 0 ? {} : { approach
|
|
2033
|
+
...approach === void 0 ? {} : { approach },
|
|
1950
2034
|
...voicing === void 0 ? {} : { voicing: this.#closingVoicing(voicing) }
|
|
1951
2035
|
}) : null;
|
|
1952
2036
|
return { chords, cadence };
|
|
@@ -2011,17 +2095,18 @@ var Progression = class _Progression {
|
|
|
2011
2095
|
*/
|
|
2012
2096
|
cadences(key, opts) {
|
|
2013
2097
|
const resolved = this.#resolveKey(key);
|
|
2098
|
+
const views = this.#viewsIn(resolved);
|
|
2014
2099
|
const found = [];
|
|
2015
|
-
for (let index = 1; index <
|
|
2016
|
-
const from =
|
|
2017
|
-
const to =
|
|
2100
|
+
for (let index = 1; index < views.length; index += 1) {
|
|
2101
|
+
const from = views[index - 1];
|
|
2102
|
+
const to = views[index];
|
|
2018
2103
|
if (from === void 0 || to === void 0) {
|
|
2019
2104
|
continue;
|
|
2020
2105
|
}
|
|
2021
|
-
const approach = index >= 2 ?
|
|
2106
|
+
const approach = index >= 2 ? views[index - 2] : opts?.approach;
|
|
2022
2107
|
const pair = opts?.voicing;
|
|
2023
2108
|
found.push(
|
|
2024
|
-
detectCadence(from
|
|
2109
|
+
detectCadence(from, to, resolved, {
|
|
2025
2110
|
...opts?.alternatives === void 0 ? {} : { alternatives: opts.alternatives },
|
|
2026
2111
|
...approach === void 0 ? {} : { approach },
|
|
2027
2112
|
...pair === void 0 ? {} : { voicing: [pair[index - 1] ?? [], pair[index] ?? []] }
|
|
@@ -2182,16 +2267,26 @@ var Progression = class _Progression {
|
|
|
2182
2267
|
/**
|
|
2183
2268
|
* The plain progression data, for JSON serialization.
|
|
2184
2269
|
*
|
|
2185
|
-
* Private class fields do not serialize, so this preserves
|
|
2186
|
-
*
|
|
2270
|
+
* Private class fields do not serialize, so this preserves the chord data,
|
|
2271
|
+
* any carried key, and — for a progression with no key of its own — each
|
|
2272
|
+
* chord's own key in `JSON.stringify(progression)`.
|
|
2187
2273
|
*
|
|
2188
|
-
* @returns The chord data sequence
|
|
2274
|
+
* @returns The chord data sequence, the carried key, if any, and the
|
|
2275
|
+
* per-chord keys when they are what spells the chords.
|
|
2189
2276
|
*/
|
|
2190
2277
|
toJSON() {
|
|
2191
|
-
|
|
2278
|
+
const out = {
|
|
2192
2279
|
chords: this.#chords.map((chord) => chord.toJSON()),
|
|
2193
2280
|
key: this.#key?.toJSON()
|
|
2194
2281
|
};
|
|
2282
|
+
if (this.#key === void 0 && this.#chords.some((chord) => chord.key !== void 0)) {
|
|
2283
|
+
out.chordKeys = this.#chords.map((chord) => chord.key?.toJSON() ?? null);
|
|
2284
|
+
}
|
|
2285
|
+
return out;
|
|
2286
|
+
}
|
|
2287
|
+
/** The members read in `key`: spellings the caller gave, the rest derived from it. */
|
|
2288
|
+
#viewsIn(key) {
|
|
2289
|
+
return this.#chords.map((chord) => chord.withKey(key).data);
|
|
2195
2290
|
}
|
|
2196
2291
|
/**
|
|
2197
2292
|
* Resolve the key for an analysis method: explicit first, then carried.
|
|
@@ -2624,7 +2719,8 @@ var Chord = class _Chord {
|
|
|
2624
2719
|
* @throws If no key is given and none is carried.
|
|
2625
2720
|
*/
|
|
2626
2721
|
roman(key, opts) {
|
|
2627
|
-
|
|
2722
|
+
const resolved = this.#resolveKey(key);
|
|
2723
|
+
return chordToRoman(this.#dataWithKey(resolved), resolved, opts);
|
|
2628
2724
|
}
|
|
2629
2725
|
/**
|
|
2630
2726
|
* The chord's Roman numeral together with the reasoning behind it: the degree
|
|
@@ -2652,7 +2748,8 @@ var Chord = class _Chord {
|
|
|
2652
2748
|
* ```
|
|
2653
2749
|
*/
|
|
2654
2750
|
explain(key, opts) {
|
|
2655
|
-
|
|
2751
|
+
const resolved = this.#resolveKey(key);
|
|
2752
|
+
return explainRoman(this.#dataWithKey(resolved), resolved, opts);
|
|
2656
2753
|
}
|
|
2657
2754
|
/**
|
|
2658
2755
|
* The chord's harmonic function (tonic / subdominant / dominant) in a key.
|
|
@@ -2663,7 +2760,8 @@ var Chord = class _Chord {
|
|
|
2663
2760
|
* @throws If no key is given and none is carried.
|
|
2664
2761
|
*/
|
|
2665
2762
|
function(key) {
|
|
2666
|
-
|
|
2763
|
+
const resolved = this.#resolveKey(key);
|
|
2764
|
+
return functionOf(this.#dataWithKey(resolved), resolved);
|
|
2667
2765
|
}
|
|
2668
2766
|
/**
|
|
2669
2767
|
* Full functional analysis: function, borrowing, Roman numeral, and the
|
|
@@ -2683,7 +2781,8 @@ var Chord = class _Chord {
|
|
|
2683
2781
|
* ```
|
|
2684
2782
|
*/
|
|
2685
2783
|
analyze(key, opts) {
|
|
2686
|
-
|
|
2784
|
+
const resolved = this.#resolveKey(key);
|
|
2785
|
+
return analyzeChord(this.#dataWithKey(resolved), resolved, opts);
|
|
2687
2786
|
}
|
|
2688
2787
|
/**
|
|
2689
2788
|
* Whether the chord is borrowed from the parallel mode (modal interchange).
|
|
@@ -2694,7 +2793,8 @@ var Chord = class _Chord {
|
|
|
2694
2793
|
* @throws If no key is given and none is carried.
|
|
2695
2794
|
*/
|
|
2696
2795
|
isBorrowed(key) {
|
|
2697
|
-
|
|
2796
|
+
const resolved = this.#resolveKey(key);
|
|
2797
|
+
return isBorrowedChord(this.#dataWithKey(resolved), resolved);
|
|
2698
2798
|
}
|
|
2699
2799
|
/**
|
|
2700
2800
|
* The origin of a non-diatonic chord (parallel mode or Neapolitan), or null.
|
|
@@ -2705,7 +2805,8 @@ var Chord = class _Chord {
|
|
|
2705
2805
|
* @throws If no key is given and none is carried.
|
|
2706
2806
|
*/
|
|
2707
2807
|
borrowedSource(key) {
|
|
2708
|
-
|
|
2808
|
+
const resolved = this.#resolveKey(key);
|
|
2809
|
+
return borrowedSource(this.#dataWithKey(resolved), resolved);
|
|
2709
2810
|
}
|
|
2710
2811
|
/**
|
|
2711
2812
|
* The chord written as the figures a bass would carry under it: `6`, `64`,
|
|
@@ -2730,7 +2831,8 @@ var Chord = class _Chord {
|
|
|
2730
2831
|
* ```
|
|
2731
2832
|
*/
|
|
2732
2833
|
figuredBass(key) {
|
|
2733
|
-
|
|
2834
|
+
const resolved = this.#resolveKey(key);
|
|
2835
|
+
return figuredBassOf(this.#dataWithKey(resolved), resolved);
|
|
2734
2836
|
}
|
|
2735
2837
|
/**
|
|
2736
2838
|
* The chords that can stand in for this one in a key: its tritone substitute,
|
|
@@ -2757,7 +2859,8 @@ var Chord = class _Chord {
|
|
|
2757
2859
|
* ```
|
|
2758
2860
|
*/
|
|
2759
2861
|
substitutions(key, opts) {
|
|
2760
|
-
|
|
2862
|
+
const resolved = this.#resolveKey(key);
|
|
2863
|
+
return substituteChord(this.#dataWithKey(resolved), resolved, opts);
|
|
2761
2864
|
}
|
|
2762
2865
|
/**
|
|
2763
2866
|
* The modal-interchange palette of the chord's key: the parallel mode's
|
|
@@ -2811,7 +2914,8 @@ var Chord = class _Chord {
|
|
|
2811
2914
|
*/
|
|
2812
2915
|
voice(opts) {
|
|
2813
2916
|
const key = opts?.key ?? this.#key;
|
|
2814
|
-
|
|
2917
|
+
const data = opts?.key === void 0 ? this.#data : this.#dataWithKey(toKey(opts.key));
|
|
2918
|
+
return voiceChord(data, key === void 0 ? opts : { ...opts, key });
|
|
2815
2919
|
}
|
|
2816
2920
|
/**
|
|
2817
2921
|
* Realize the chord as a single styled voicing (`close`, `drop2`, `drop3`,
|
|
@@ -2834,7 +2938,7 @@ var Chord = class _Chord {
|
|
|
2834
2938
|
*/
|
|
2835
2939
|
negativeHarmony(key) {
|
|
2836
2940
|
const resolved = this.#resolveKey(key);
|
|
2837
|
-
return new _Chord(negativeHarmonyMirror(this.#
|
|
2941
|
+
return new _Chord(negativeHarmonyMirror(this.#dataWithKey(resolved), resolved), resolved);
|
|
2838
2942
|
}
|
|
2839
2943
|
/**
|
|
2840
2944
|
* The V7 that tonicizes this chord: a dominant seventh a perfect fifth above
|
|
@@ -3224,17 +3328,18 @@ var Key = class _Key {
|
|
|
3224
3328
|
`tonic must be the class API's Note; received ${describeTonic(tonic)}; wrap plain note data with Note.fromData, or omit the tonic to have one chosen`
|
|
3225
3329
|
);
|
|
3226
3330
|
}
|
|
3331
|
+
const note = tonic instanceof Note ? tonic : new Note(tonic.data);
|
|
3227
3332
|
const rootPc = pitchClassOf(scale.rootPc);
|
|
3228
|
-
if (
|
|
3333
|
+
if (note.pitchClass !== rootPc) {
|
|
3229
3334
|
throw new InvalidInputError(
|
|
3230
|
-
`tonic ${
|
|
3335
|
+
`tonic ${note.name} does not match the scale root pitch class ${rootPc}; pass a tonic that spells the scale root, or omit it to have one chosen`
|
|
3231
3336
|
);
|
|
3232
3337
|
}
|
|
3233
3338
|
if (variant !== void 0) {
|
|
3234
3339
|
assertKeyVariant(variant, scale.modeMask12);
|
|
3235
3340
|
}
|
|
3236
3341
|
this.#scale = { rootPc, modeMask12: scale.modeMask12 };
|
|
3237
|
-
this.#tonic =
|
|
3342
|
+
this.#tonic = note;
|
|
3238
3343
|
this.#variant = variant ?? variantOfMask(scale.modeMask12);
|
|
3239
3344
|
}
|
|
3240
3345
|
/** Preserve detection metadata while replacing its plain key with this API's Key. */
|
|
@@ -3540,7 +3645,7 @@ var Key = class _Key {
|
|
|
3540
3645
|
get data() {
|
|
3541
3646
|
return this.toJSON();
|
|
3542
3647
|
}
|
|
3543
|
-
/** The
|
|
3648
|
+
/** The scale form this key stands in: natural, harmonic or melodic, read from the mask unless named. */
|
|
3544
3649
|
get variant() {
|
|
3545
3650
|
return this.#variant;
|
|
3546
3651
|
}
|
|
@@ -3785,7 +3890,7 @@ var Key = class _Key {
|
|
|
3785
3890
|
*/
|
|
3786
3891
|
pivotsTo(other) {
|
|
3787
3892
|
assertKeyArgument(other, "key");
|
|
3788
|
-
return pivotChords(this
|
|
3893
|
+
return pivotChords(this, resolveKey(other)).map(({ chord, romanFrom, romanTo }) => ({
|
|
3789
3894
|
chord: new Chord(chord, this),
|
|
3790
3895
|
romanFrom,
|
|
3791
3896
|
romanTo
|
|
@@ -3894,7 +3999,7 @@ var Key = class _Key {
|
|
|
3894
3999
|
if (this.pitchClasses().length !== HEPTATONIC_DEGREES) {
|
|
3895
4000
|
return this.isMinor ? "minor" : "major";
|
|
3896
4001
|
}
|
|
3897
|
-
const { quality } = diatonicTriad(n, this
|
|
4002
|
+
const { quality } = diatonicTriad(n, this);
|
|
3898
4003
|
return quality === "min" || quality === "dim" ? "minor" : "major";
|
|
3899
4004
|
}
|
|
3900
4005
|
/**
|
|
@@ -3903,7 +4008,7 @@ var Key = class _Key {
|
|
|
3903
4008
|
*
|
|
3904
4009
|
* Unlike {@link Key.transpose}, which picks a letter from the semitone count,
|
|
3905
4010
|
* the interval's diatonic number decides the tonic's letter: G# minor down an
|
|
3906
|
-
* augmented fourth is D minor, while down a diminished fifth it is
|
|
4011
|
+
* augmented fourth is D minor, while down a diminished fifth it is C## minor.
|
|
3907
4012
|
* The mode mask is unchanged, so the scale keeps its shape.
|
|
3908
4013
|
*
|
|
3909
4014
|
* @param interval The interval to apply, as a name (`'A4'`, `'-A4'`), plain
|
|
@@ -4116,6 +4221,15 @@ var Key = class _Key {
|
|
|
4116
4221
|
const anchor = tonic === void 0 ? this.#tonic.data : toNoteData(tonic);
|
|
4117
4222
|
return spellPitchClasses([...pcs], anchor, this.#scale).map((note) => new Note(note));
|
|
4118
4223
|
}
|
|
4224
|
+
/**
|
|
4225
|
+
* A degree chord without the spelling its builder attached.
|
|
4226
|
+
*
|
|
4227
|
+
* The chord carries this key, which spells its root on read, so a chord
|
|
4228
|
+
* re-keyed later follows its new key instead of keeping these letters.
|
|
4229
|
+
*/
|
|
4230
|
+
#withoutSpelling(chord) {
|
|
4231
|
+
return makeChord(chord.rootPc, chord.quality);
|
|
4232
|
+
}
|
|
4119
4233
|
/**
|
|
4120
4234
|
* Build a chord on a scale degree, carrying this key as context.
|
|
4121
4235
|
*
|
|
@@ -4133,8 +4247,8 @@ var Key = class _Key {
|
|
|
4133
4247
|
* an explicit `quality` for those.
|
|
4134
4248
|
*/
|
|
4135
4249
|
chord(degree, quality) {
|
|
4136
|
-
const data = quality === void 0 ? diatonicTriad(degree, this
|
|
4137
|
-
return new Chord(data, this);
|
|
4250
|
+
const data = quality === void 0 ? diatonicTriad(degree, this) : chordFromDegree(degree, quality, this);
|
|
4251
|
+
return new Chord(this.#withoutSpelling(data), this);
|
|
4138
4252
|
}
|
|
4139
4253
|
/**
|
|
4140
4254
|
* The diatonic triad on a scale degree, carrying this key as context.
|
|
@@ -4146,7 +4260,7 @@ var Key = class _Key {
|
|
|
4146
4260
|
* degrees. Use {@link Key.chord} with an explicit quality instead.
|
|
4147
4261
|
*/
|
|
4148
4262
|
diatonicTriad(degree) {
|
|
4149
|
-
return new Chord(diatonicTriad(degree, this
|
|
4263
|
+
return new Chord(this.#withoutSpelling(diatonicTriad(degree, this)), this);
|
|
4150
4264
|
}
|
|
4151
4265
|
/**
|
|
4152
4266
|
* The diatonic seventh chord on a scale degree, carrying this key as context.
|
|
@@ -4158,7 +4272,7 @@ var Key = class _Key {
|
|
|
4158
4272
|
* degrees. Use {@link Key.chord} with an explicit quality instead.
|
|
4159
4273
|
*/
|
|
4160
4274
|
diatonicSeventh(degree) {
|
|
4161
|
-
return new Chord(diatonicSeventh(degree, this
|
|
4275
|
+
return new Chord(this.#withoutSpelling(diatonicSeventh(degree, this)), this);
|
|
4162
4276
|
}
|
|
4163
4277
|
/**
|
|
4164
4278
|
* Build the chord denoted by a Roman numeral in this key (including applied
|
|
@@ -4268,12 +4382,11 @@ var Key = class _Key {
|
|
|
4268
4382
|
*
|
|
4269
4383
|
* Private class fields do not serialize, so an explicit `toJSON` keeps
|
|
4270
4384
|
* `JSON.stringify(key)` from collapsing to `{}`. The result pairs the
|
|
4271
|
-
* `KeyScale` with the spelled tonic and
|
|
4272
|
-
*
|
|
4273
|
-
*
|
|
4385
|
+
* `KeyScale` with the spelled tonic and the scale form — everything
|
|
4386
|
+
* {@link Key.fromJSON} needs to rebuild a key that reads and prints as this
|
|
4387
|
+
* one.
|
|
4274
4388
|
*
|
|
4275
|
-
* @returns The key/scale, its spelled tonic, and its scale form
|
|
4276
|
-
* one.
|
|
4389
|
+
* @returns The key/scale, its spelled tonic, and its scale form.
|
|
4277
4390
|
*/
|
|
4278
4391
|
toJSON() {
|
|
4279
4392
|
return { scale: this.scale, tonic: this.#tonic.data, variant: this.#variant };
|
|
@@ -4384,21 +4497,9 @@ function tempoFrom(tempo) {
|
|
|
4384
4497
|
}
|
|
4385
4498
|
return typeof tempo === "number" ? [{ startBeat: 0, bpm: tempo }] : tempo;
|
|
4386
4499
|
}
|
|
4387
|
-
function
|
|
4500
|
+
function scoreKeyRegions(key, notes, totalBeats) {
|
|
4388
4501
|
const first = notes[0];
|
|
4389
|
-
|
|
4390
|
-
return [];
|
|
4391
|
-
}
|
|
4392
|
-
return [
|
|
4393
|
-
{
|
|
4394
|
-
// The region starts where the music does, as an inferred one does, so a
|
|
4395
|
-
// pickup is covered by the key it sounds in.
|
|
4396
|
-
startBeat: first.startBeat,
|
|
4397
|
-
endBeat: totalBeats,
|
|
4398
|
-
key: keyIdentity(key),
|
|
4399
|
-
confidence: STATED_KEY_CONFIDENCE
|
|
4400
|
-
}
|
|
4401
|
-
];
|
|
4502
|
+
return first === void 0 ? [] : statedKeyRegions(keyIdentity(key), first.startBeat, totalBeats);
|
|
4402
4503
|
}
|
|
4403
4504
|
function scoreData(notes, opts) {
|
|
4404
4505
|
const data = {
|
|
@@ -4653,43 +4754,42 @@ var Score = class _Score {
|
|
|
4653
4754
|
/**
|
|
4654
4755
|
* The notes pushed off the grid the way a player would.
|
|
4655
4756
|
*
|
|
4656
|
-
* The metric accents are read
|
|
4657
|
-
* {@link
|
|
4658
|
-
* to read a later stretch of a score that changes meter.
|
|
4757
|
+
* The metric accents are read against the score's meter map, exactly as
|
|
4758
|
+
* {@link humanize} reads that map; pass `ts` to read against another meter.
|
|
4659
4759
|
*
|
|
4660
4760
|
* @param opts Jitter amounts, accent depth and the seed; see
|
|
4661
4761
|
* {@link HumanizeOptions}.
|
|
4662
4762
|
* @returns The humanized score.
|
|
4663
4763
|
*/
|
|
4664
4764
|
humanize(opts) {
|
|
4665
|
-
return this.#withNotes(humanize(this.#data.notes, { ts: this.
|
|
4765
|
+
return this.#withNotes(humanize(this.#data.notes, { ts: this.#data.meters, ...opts }));
|
|
4666
4766
|
}
|
|
4667
4767
|
/**
|
|
4668
4768
|
* The notes with ornaments added.
|
|
4669
4769
|
*
|
|
4670
|
-
* Strong positions are read
|
|
4671
|
-
* {@link
|
|
4770
|
+
* Strong positions are read against the score's meter map, exactly as
|
|
4771
|
+
* {@link ornament} reads that map.
|
|
4672
4772
|
*
|
|
4673
4773
|
* @param opts The ornament style, how much is decorated, and the seed; see
|
|
4674
4774
|
* {@link OrnamentOptions}.
|
|
4675
4775
|
* @returns The ornamented score.
|
|
4676
4776
|
*/
|
|
4677
4777
|
ornament(opts) {
|
|
4678
|
-
return this.#withNotes(ornament(this.#data.notes, { ts: this.
|
|
4778
|
+
return this.#withNotes(ornament(this.#data.notes, { ts: this.#data.meters, ...opts }));
|
|
4679
4779
|
}
|
|
4680
4780
|
/**
|
|
4681
4781
|
* The notes placed on a groove template's slots.
|
|
4682
4782
|
*
|
|
4683
|
-
* The template's per-bar grid is laid out against the score's
|
|
4684
|
-
*
|
|
4685
|
-
* under
|
|
4783
|
+
* The template's per-bar grid is laid out against the score's meter map,
|
|
4784
|
+
* exactly as {@link applyGrooveTemplate} reads that map; a template extracted
|
|
4785
|
+
* under another meter is refused rather than drifting.
|
|
4686
4786
|
*
|
|
4687
4787
|
* @param template The groove template, from `extractGrooveTemplate`.
|
|
4688
4788
|
* @returns The score with the template's feel imposed.
|
|
4689
4789
|
* @throws If the template was extracted under another meter.
|
|
4690
4790
|
*/
|
|
4691
4791
|
groove(template) {
|
|
4692
|
-
return this.#withNotes(applyGrooveTemplate(this.#data.notes, template, this.
|
|
4792
|
+
return this.#withNotes(applyGrooveTemplate(this.#data.notes, template, this.#data.meters));
|
|
4693
4793
|
}
|
|
4694
4794
|
/**
|
|
4695
4795
|
* The feel of the score's own timing, as a template another score can take on.
|
|
@@ -4698,8 +4798,8 @@ var Score = class _Score {
|
|
|
4698
4798
|
* slot by slot for how far ahead of or behind the grid it sits and how hard
|
|
4699
4799
|
* it is struck, and the reading is handed back as a template. Only the
|
|
4700
4800
|
* subdivision is named, because the score already holds the meter the grid is
|
|
4701
|
-
* laid out against — its
|
|
4702
|
-
*
|
|
4801
|
+
* laid out against — its meter map, read exactly as
|
|
4802
|
+
* {@link extractGrooveTemplate} reads that map.
|
|
4703
4803
|
*
|
|
4704
4804
|
* @param subdivision Grid steps per quarter-note beat; a sixteenth-note grid
|
|
4705
4805
|
* by default, which is where swing, push and drag are audible.
|
|
@@ -4713,7 +4813,7 @@ var Score = class _Score {
|
|
|
4713
4813
|
* ```
|
|
4714
4814
|
*/
|
|
4715
4815
|
grooveTemplate(subdivision) {
|
|
4716
|
-
return extractGrooveTemplate(this.#data.notes, this.
|
|
4816
|
+
return extractGrooveTemplate(this.#data.notes, this.#data.meters, subdivision);
|
|
4717
4817
|
}
|
|
4718
4818
|
/**
|
|
4719
4819
|
* The harmony the notes spell out, in time.
|
|
@@ -4767,7 +4867,8 @@ var Score = class _Score {
|
|
|
4767
4867
|
keys(opts) {
|
|
4768
4868
|
if (opts !== void 0) {
|
|
4769
4869
|
if (this.#key !== void 0) {
|
|
4770
|
-
|
|
4870
|
+
const totalBeats = opts.totalBeats === void 0 || opts.totalBeats === null ? this.totalBeats : assertRange(opts.totalBeats, 0, Number.MAX_SAFE_INTEGER, "key timeline totalBeats");
|
|
4871
|
+
return scoreKeyRegions(this.#key, this.#data.notes, totalBeats);
|
|
4771
4872
|
}
|
|
4772
4873
|
return keyTimelineFromNotes(this.#data.notes, { meters: this.#data.meters, ...opts });
|
|
4773
4874
|
}
|
|
@@ -4851,10 +4952,16 @@ var Score = class _Score {
|
|
|
4851
4952
|
* @returns The grouping, its downbeats, a confidence, and a rationale.
|
|
4852
4953
|
*/
|
|
4853
4954
|
hypermeter(opts) {
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
}
|
|
4955
|
+
const asked = { ...opts };
|
|
4956
|
+
if ((asked.cadenceBeats ?? null) !== null) {
|
|
4957
|
+
return hypermeter(this.#data.notes, this.#data.meters, asked);
|
|
4958
|
+
}
|
|
4959
|
+
return hypermeterOver(
|
|
4960
|
+
this.#data.notes,
|
|
4961
|
+
this.#data.meters,
|
|
4962
|
+
asked,
|
|
4963
|
+
() => this.#cadenceSpans(asked.budget)
|
|
4964
|
+
);
|
|
4858
4965
|
}
|
|
4859
4966
|
/**
|
|
4860
4967
|
* The motifs the melody repeats.
|
|
@@ -4869,8 +4976,9 @@ var Score = class _Score {
|
|
|
4869
4976
|
*
|
|
4870
4977
|
* A melody is one line, so a score holding several is read as its top voice:
|
|
4871
4978
|
* notes struck together are one event and the highest of them stands for it.
|
|
4872
|
-
* A
|
|
4873
|
-
*
|
|
4979
|
+
* A block-chord part read whole therefore answers for its top voice rather
|
|
4980
|
+
* than for a line assembled from the insides of its chords; a lower note
|
|
4981
|
+
* struck while a higher one still sounds stays in the line, though. Split the
|
|
4874
4982
|
* score into lines first to have each of them answered for.
|
|
4875
4983
|
*
|
|
4876
4984
|
* @param opts Cell-length bounds and the recurrence threshold; see
|
|
@@ -5271,15 +5379,24 @@ var Score = class _Score {
|
|
|
5271
5379
|
* Kept on first reading for the same reason the chord timeline is.
|
|
5272
5380
|
*/
|
|
5273
5381
|
#keyRegions() {
|
|
5274
|
-
const regions = this.#regions ?? (this.#key === void 0 ? keyTimelineFromNotes(this.#data.notes, { meters: this.#data.meters }) :
|
|
5382
|
+
const regions = this.#regions ?? (this.#key === void 0 ? keyTimelineFromNotes(this.#data.notes, { meters: this.#data.meters }) : scoreKeyRegions(this.#key, this.#data.notes, this.totalBeats));
|
|
5275
5383
|
this.#regions = regions;
|
|
5276
5384
|
return regions;
|
|
5277
5385
|
}
|
|
5278
|
-
/**
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5386
|
+
/**
|
|
5387
|
+
* Where the score's own harmony closes, as the spans its arrival chords sound
|
|
5388
|
+
* through, read in the key {@link Score.phrases} reads them in.
|
|
5389
|
+
*/
|
|
5390
|
+
#cadenceSpans(budget) {
|
|
5391
|
+
const timeline = this.#chordTimeline();
|
|
5392
|
+
const key = keyContextFor(
|
|
5393
|
+
this.#key === void 0 ? void 0 : keyIdentity(this.#key),
|
|
5394
|
+
timeline,
|
|
5395
|
+
this.#data.meters,
|
|
5396
|
+
void 0,
|
|
5397
|
+
budget
|
|
5282
5398
|
);
|
|
5399
|
+
return boundaryCadences(timeline, key).spans;
|
|
5283
5400
|
}
|
|
5284
5401
|
/** The score's context as chord-timeline options, with the caller's on top. */
|
|
5285
5402
|
#analysisOptions(opts) {
|
|
@@ -5355,7 +5472,7 @@ function copySegments(segments) {
|
|
|
5355
5472
|
function chordTimelineOf(segments) {
|
|
5356
5473
|
return new Timeline({ segments: [...segments], totalBeats: spanEnd(segments) }).chordTimeline;
|
|
5357
5474
|
}
|
|
5358
|
-
function copySettings(settings,
|
|
5475
|
+
function copySettings(settings, tracks) {
|
|
5359
5476
|
if (settings === void 0) {
|
|
5360
5477
|
return void 0;
|
|
5361
5478
|
}
|
|
@@ -5382,8 +5499,9 @@ function copySettings(settings, trackCount) {
|
|
|
5382
5499
|
settings.harmonyTracks,
|
|
5383
5500
|
"arrangement harmonyTracks"
|
|
5384
5501
|
).map(
|
|
5385
|
-
(track, index) => assertInteger(track, `arrangement harmonyTracks[${index}]`, 0,
|
|
5502
|
+
(track, index) => assertInteger(track, `arrangement harmonyTracks[${index}]`, 0, tracks.length - 1)
|
|
5386
5503
|
);
|
|
5504
|
+
harmonyTrackSet(copy.harmonyTracks, tracks, "arrangement harmonyTracks");
|
|
5387
5505
|
}
|
|
5388
5506
|
if (settings.minSeverity !== void 0) {
|
|
5389
5507
|
copy.minSeverity = assertInteger(
|
|
@@ -5400,6 +5518,11 @@ function copySettings(settings, trackCount) {
|
|
|
5400
5518
|
Number.MAX_SAFE_INTEGER,
|
|
5401
5519
|
"arrangement pickupBeats"
|
|
5402
5520
|
);
|
|
5521
|
+
assertTrackNotes(tracks, {
|
|
5522
|
+
allowNonPositiveDuration: true,
|
|
5523
|
+
minStartBeat: -copy.pickupBeats,
|
|
5524
|
+
budget: settings.budget
|
|
5525
|
+
});
|
|
5403
5526
|
}
|
|
5404
5527
|
if (settings.harmonicRhythm !== void 0) {
|
|
5405
5528
|
copy.harmonicRhythm = assertRange(
|
|
@@ -5410,7 +5533,7 @@ function copySettings(settings, trackCount) {
|
|
|
5410
5533
|
);
|
|
5411
5534
|
}
|
|
5412
5535
|
if (settings.profile !== void 0) {
|
|
5413
|
-
copy.profile = settings.profile;
|
|
5536
|
+
copy.profile = arrangementProfile(settings.profile);
|
|
5414
5537
|
}
|
|
5415
5538
|
if (settings.budget !== void 0) {
|
|
5416
5539
|
copy.budget = assertPositiveInt(settings.budget, "arrangement budget", Number.MAX_SAFE_INTEGER);
|
|
@@ -5423,7 +5546,7 @@ function copyArrangement(data) {
|
|
|
5423
5546
|
const tracks = assertDataArray(data.tracks, "arrangement tracks").map(
|
|
5424
5547
|
(track, index) => copyTrack(track, index, budget)
|
|
5425
5548
|
);
|
|
5426
|
-
const settings = copySettings(data.settings, tracks
|
|
5549
|
+
const settings = copySettings(data.settings, tracks);
|
|
5427
5550
|
return settings === void 0 ? { tracks } : { tracks, settings };
|
|
5428
5551
|
}
|
|
5429
5552
|
function arrangementData(tracks, settings) {
|
|
@@ -5736,7 +5859,8 @@ var Arrangement = class _Arrangement {
|
|
|
5736
5859
|
}
|
|
5737
5860
|
}
|
|
5738
5861
|
return referenceFromReadings(harmony, this.#session().analysis, {
|
|
5739
|
-
|
|
5862
|
+
// The meter the arrangement's own analysis reads, `ts` included.
|
|
5863
|
+
meters: this.#data.settings?.meters ?? this.#data.settings?.ts,
|
|
5740
5864
|
totalBeats: this.timeline().totalBeats,
|
|
5741
5865
|
...melody.length === 0 ? {} : { melody },
|
|
5742
5866
|
...opts
|
|
@@ -5847,7 +5971,9 @@ function copyProfile(profile) {
|
|
|
5847
5971
|
}
|
|
5848
5972
|
const reach = {};
|
|
5849
5973
|
for (const [pitch, limbs] of Object.entries(profile.reach)) {
|
|
5850
|
-
|
|
5974
|
+
if (String(Number(pitch)) === pitch) {
|
|
5975
|
+
reach[Number(pitch)] = [...limbs];
|
|
5976
|
+
}
|
|
5851
5977
|
}
|
|
5852
5978
|
const percussion = {
|
|
5853
5979
|
kind: "percussion",
|
|
@@ -6359,7 +6485,7 @@ var Composer = class _Composer {
|
|
|
6359
6485
|
...instrument === void 0 ? {} : { instrument: toStringedProfile(instrument, "bass instrument") },
|
|
6360
6486
|
segments,
|
|
6361
6487
|
key,
|
|
6362
|
-
ts: this.#
|
|
6488
|
+
ts: this.#meters,
|
|
6363
6489
|
ctx: this.context
|
|
6364
6490
|
});
|
|
6365
6491
|
return Score.of(notes, this.#scoreOptions(key));
|
|
@@ -6391,7 +6517,7 @@ var Composer = class _Composer {
|
|
|
6391
6517
|
...timeline === void 0 ? {} : { timeline: toChordTimeline(timeline) },
|
|
6392
6518
|
melody: melody.notes,
|
|
6393
6519
|
key,
|
|
6394
|
-
ts: this.#
|
|
6520
|
+
ts: this.#meters,
|
|
6395
6521
|
ctx: this.context
|
|
6396
6522
|
});
|
|
6397
6523
|
return Score.of(notes, this.#scoreOptions(key));
|
|
@@ -6421,14 +6547,15 @@ var Composer = class _Composer {
|
|
|
6421
6547
|
...opts,
|
|
6422
6548
|
melody: melody.notes,
|
|
6423
6549
|
...this.#key === void 0 ? {} : { key: this.#key },
|
|
6424
|
-
ts: this.#
|
|
6550
|
+
ts: this.#meters,
|
|
6425
6551
|
ctx: this.context
|
|
6426
6552
|
});
|
|
6427
6553
|
const moved = melody.transpose(result.transposeSemitones);
|
|
6554
|
+
const last = result.chords[result.chords.length - 1];
|
|
6428
6555
|
const totalBeats = harmonizedSpan(
|
|
6429
6556
|
moved.totalBeats,
|
|
6430
6557
|
result.chords,
|
|
6431
|
-
|
|
6558
|
+
beatsPerBarAt(last?.startBeat ?? 0, this.#meters)
|
|
6432
6559
|
);
|
|
6433
6560
|
return {
|
|
6434
6561
|
chords: Timeline.fromChords(result.chords, totalBeats, result.key),
|
|
@@ -6563,16 +6690,6 @@ var Composer = class _Composer {
|
|
|
6563
6690
|
}
|
|
6564
6691
|
return this.#key;
|
|
6565
6692
|
}
|
|
6566
|
-
/**
|
|
6567
|
-
* The signature the parts are written against.
|
|
6568
|
-
*
|
|
6569
|
-
* Each generator names one time signature rather than a map, so a composer
|
|
6570
|
-
* whose meter changes hands over the signature its music opens on — the same
|
|
6571
|
-
* reading {@link Score.humanize} and its siblings take.
|
|
6572
|
-
*/
|
|
6573
|
-
#openingMeter() {
|
|
6574
|
-
return meterAt(0, this.#meters);
|
|
6575
|
-
}
|
|
6576
6693
|
/**
|
|
6577
6694
|
* The one signature a part laid out in bars is written against.
|
|
6578
6695
|
*
|
|
@@ -6587,7 +6704,7 @@ var Composer = class _Composer {
|
|
|
6587
6704
|
`composer ${part} needs one meter for the whole part; the composer changes meter`
|
|
6588
6705
|
);
|
|
6589
6706
|
}
|
|
6590
|
-
return this.#
|
|
6707
|
+
return meterAt(0, this.#meters);
|
|
6591
6708
|
}
|
|
6592
6709
|
/** The context every score a composer hands back is read against. */
|
|
6593
6710
|
#scoreOptions(key) {
|
|
@@ -7084,6 +7201,7 @@ var Motif = class _Motif {
|
|
|
7084
7201
|
* ```
|
|
7085
7202
|
*/
|
|
7086
7203
|
static generate(opts) {
|
|
7204
|
+
assertRecord(opts, "motif options");
|
|
7087
7205
|
return new _Motif(generateMotif({ ...opts, chord: chordFrom(opts.chord) }));
|
|
7088
7206
|
}
|
|
7089
7207
|
/**
|
|
@@ -7098,7 +7216,7 @@ var Motif = class _Motif {
|
|
|
7098
7216
|
* @throws If a note carries a value the transforms cannot hold.
|
|
7099
7217
|
*/
|
|
7100
7218
|
static fromNotes(notes) {
|
|
7101
|
-
return new _Motif({ notes: [...notes] });
|
|
7219
|
+
return new _Motif({ notes: [...assertArray(notes, "motif notes")] });
|
|
7102
7220
|
}
|
|
7103
7221
|
/** Rebuild a motif from the plain data {@link Motif.data} hands out. */
|
|
7104
7222
|
static fromData(cell) {
|
|
@@ -7417,7 +7535,7 @@ var Rhythm = class _Rhythm {
|
|
|
7417
7535
|
* @returns The compressed pattern.
|
|
7418
7536
|
*/
|
|
7419
7537
|
doubleTime() {
|
|
7420
|
-
return this.#withGrid(
|
|
7538
|
+
return this.#withGrid(doubleTimeFigure(toGrid(this.#data.events), this.#spanSteps()));
|
|
7421
7539
|
}
|
|
7422
7540
|
/**
|
|
7423
7541
|
* Stretch the pattern to twice its length: everything falls half as often.
|
|
@@ -7428,7 +7546,7 @@ var Rhythm = class _Rhythm {
|
|
|
7428
7546
|
* @returns The stretched pattern.
|
|
7429
7547
|
*/
|
|
7430
7548
|
halfTime() {
|
|
7431
|
-
return this.#withGrid(
|
|
7549
|
+
return this.#withGrid(halfTimeFigure(toGrid(this.#data.events), this.#spanSteps()));
|
|
7432
7550
|
}
|
|
7433
7551
|
/**
|
|
7434
7552
|
* Keep as much decoration as the ornament dial asks for.
|
|
@@ -7475,14 +7593,16 @@ var Rhythm = class _Rhythm {
|
|
|
7475
7593
|
rhythmic: resolved.rhythmic,
|
|
7476
7594
|
ornament: resolved.ornament,
|
|
7477
7595
|
rate: opts?.rate,
|
|
7478
|
-
spanSteps: this.#spanSteps(),
|
|
7479
7596
|
ts: this.#data.ts,
|
|
7480
7597
|
// The transform hands the predicate the events it was given, which carry
|
|
7481
7598
|
// the onset each was built from; the parameter is declared over the bare
|
|
7482
7599
|
// grid event the rule reads, so the field is named back here.
|
|
7483
7600
|
isOrnament: isOrnament === void 0 ? void 0 : (grid) => isOrnament(grid.source)
|
|
7484
7601
|
};
|
|
7485
|
-
|
|
7602
|
+
const dials = resolveDials(options);
|
|
7603
|
+
return this.#withGrid(
|
|
7604
|
+
deformFigure(toGrid(this.#data.events), this.#spanSteps(), dials, resolved.part(PART), [])
|
|
7605
|
+
);
|
|
7486
7606
|
}
|
|
7487
7607
|
/**
|
|
7488
7608
|
* Whether one player can sustain the pattern at the context's tempo.
|
|
@@ -7543,7 +7663,11 @@ var Rhythm = class _Rhythm {
|
|
|
7543
7663
|
toJSON() {
|
|
7544
7664
|
return this.data;
|
|
7545
7665
|
}
|
|
7546
|
-
/**
|
|
7666
|
+
/**
|
|
7667
|
+
* The pattern's span as a count of sixteenths, for the transforms: whatever
|
|
7668
|
+
* span the pattern covers, an empty one or one ending off the straight grid
|
|
7669
|
+
* included.
|
|
7670
|
+
*/
|
|
7547
7671
|
#spanSteps() {
|
|
7548
7672
|
return spanOf(this.#data.events) / STEP_BEATS;
|
|
7549
7673
|
}
|
|
@@ -8527,4 +8651,4 @@ export {
|
|
|
8527
8651
|
Tuning,
|
|
8528
8652
|
Voicing
|
|
8529
8653
|
};
|
|
8530
|
-
//# sourceMappingURL=chunk-
|
|
8654
|
+
//# sourceMappingURL=chunk-5MWRBYAT.js.map
|