@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
|
@@ -52,21 +52,21 @@
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
var _chunkIFZDWIKMcjs = require('./chunk-IFZDWIKM.cjs');
|
|
56
55
|
|
|
57
56
|
|
|
58
57
|
|
|
59
58
|
|
|
60
59
|
|
|
61
60
|
|
|
61
|
+
var _chunkLQZQDBCDcjs = require('./chunk-LQZQDBCD.cjs');
|
|
62
62
|
|
|
63
|
-
var _chunk3R3QVKY5cjs = require('./chunk-3R3QVKY5.cjs');
|
|
64
63
|
|
|
65
64
|
|
|
66
65
|
|
|
67
66
|
|
|
68
67
|
|
|
69
68
|
|
|
69
|
+
var _chunkYDGMWH43cjs = require('./chunk-YDGMWH43.cjs');
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
|
|
@@ -82,12 +82,18 @@ var _chunk3R3QVKY5cjs = require('./chunk-3R3QVKY5.cjs');
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
var _chunkS3QELJUEcjs = require('./chunk-S3QELJUE.cjs');
|
|
86
92
|
|
|
87
93
|
// src/analyze/arrange/internal.ts
|
|
88
94
|
var MAX_LANE_LEAP = 24;
|
|
89
95
|
function covers(note, beat) {
|
|
90
|
-
return beat >= note.startBeat -
|
|
96
|
+
return beat >= note.startBeat - _chunkS3QELJUEcjs.BEAT_EPS && beat < note.endBeat - _chunkS3QELJUEcjs.BEAT_EPS;
|
|
91
97
|
}
|
|
92
98
|
function isPercussion(role) {
|
|
93
99
|
return role === "drums";
|
|
@@ -101,31 +107,31 @@ var TRACK_ROLE_TABLE = {
|
|
|
101
107
|
};
|
|
102
108
|
var TRACK_ROLES = Object.keys(TRACK_ROLE_TABLE);
|
|
103
109
|
function trackRoleOf(role, name) {
|
|
104
|
-
return role === void 0 ? "other" :
|
|
110
|
+
return role === void 0 ? "other" : _chunkS3QELJUEcjs.assertOneOf.call(void 0, role, TRACK_ROLES, name);
|
|
105
111
|
}
|
|
106
112
|
var DEFAULT_PROFILE = "pop";
|
|
107
|
-
var SAFETY_PROFILES = Object.keys(
|
|
113
|
+
var SAFETY_PROFILES = Object.keys(_chunkYDGMWH43cjs.PROFILE_WEIGHTS);
|
|
108
114
|
function arrangementProfile(profile) {
|
|
109
|
-
return
|
|
115
|
+
return _chunkS3QELJUEcjs.assertOneOf.call(void 0, _nullishCoalesce(profile, () => ( DEFAULT_PROFILE)), SAFETY_PROFILES, "arrangement profile");
|
|
110
116
|
}
|
|
111
117
|
function assertTrackNotes(tracks, options) {
|
|
112
|
-
|
|
118
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, tracks, "arrangement tracks");
|
|
113
119
|
let noteCount = 0;
|
|
114
120
|
for (let index = 0; index < tracks.length; index += 1) {
|
|
115
121
|
const notes = _optionalChain([tracks, 'access', _2 => _2[index], 'optionalAccess', _3 => _3.notes]);
|
|
116
122
|
if (!Array.isArray(notes)) {
|
|
117
|
-
throw new (0,
|
|
118
|
-
`tracks[${index}].notes must be an array; received ${
|
|
123
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
124
|
+
`tracks[${index}].notes must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, notes)}`
|
|
119
125
|
);
|
|
120
126
|
}
|
|
121
|
-
|
|
127
|
+
_chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, `tracks[${index}].notes`, options);
|
|
122
128
|
noteCount += notes.length;
|
|
123
129
|
}
|
|
124
130
|
return noteCount;
|
|
125
131
|
}
|
|
126
132
|
function assertGivenTimeline(timeline, name) {
|
|
127
133
|
if (timeline !== void 0) {
|
|
128
|
-
|
|
134
|
+
_chunkLQZQDBCDcjs.assertChordTimeline.call(void 0, timeline, name);
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
function assertGivenKeys(keys, name) {
|
|
@@ -133,26 +139,27 @@ function assertGivenKeys(keys, name) {
|
|
|
133
139
|
return;
|
|
134
140
|
}
|
|
135
141
|
if (!Array.isArray(keys)) {
|
|
136
|
-
throw new (0,
|
|
137
|
-
`${name} must be an array of key regions; received ${
|
|
142
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
143
|
+
`${name} must be an array of key regions; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, keys)}`
|
|
138
144
|
);
|
|
139
145
|
}
|
|
140
146
|
for (let index = 0; index < keys.length; index += 1) {
|
|
141
147
|
const region = keys[index];
|
|
142
148
|
if (typeof region !== "object" || region === null) {
|
|
143
|
-
throw new (0,
|
|
144
|
-
`${name}[${index}] must be a key region; received ${
|
|
149
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
150
|
+
`${name}[${index}] must be a key region; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, region)}`
|
|
145
151
|
);
|
|
146
152
|
}
|
|
147
|
-
|
|
148
|
-
|
|
153
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, region.startBeat, `${name}[${index}].startBeat`);
|
|
154
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, region.endBeat, `${name}[${index}].endBeat`);
|
|
149
155
|
if (region.key === void 0 || region.key === null || typeof region.key !== "string" && typeof region.key !== "object") {
|
|
150
|
-
throw new (0,
|
|
151
|
-
`${name}[${index}].key must name a key; received ${
|
|
156
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
157
|
+
`${name}[${index}].key must name a key; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, region.key)}`
|
|
152
158
|
);
|
|
153
159
|
}
|
|
154
|
-
|
|
160
|
+
_chunkYDGMWH43cjs.resolveKey.call(void 0, region.key);
|
|
155
161
|
}
|
|
162
|
+
_chunkLQZQDBCDcjs.assertSpansInOrder.call(void 0, keys, name);
|
|
156
163
|
}
|
|
157
164
|
function harmonyTrackSet(harmonyTracks, tracks, name = "harmonyTracks") {
|
|
158
165
|
if (harmonyTracks === void 0) {
|
|
@@ -162,16 +169,16 @@ function harmonyTrackSet(harmonyTracks, tracks, name = "harmonyTracks") {
|
|
|
162
169
|
for (let index = 0; index < harmonyTracks.length; index += 1) {
|
|
163
170
|
const value = harmonyTracks[index];
|
|
164
171
|
if (value === void 0 || !Number.isFinite(value)) {
|
|
165
|
-
throw new (0,
|
|
172
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`${name}[${index}] must be a track index; received ${value}`);
|
|
166
173
|
}
|
|
167
174
|
const track = Math.trunc(value);
|
|
168
175
|
if (track < 0 || track >= tracks.length) {
|
|
169
|
-
throw new (0,
|
|
176
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
170
177
|
`${name}[${index}] ${track} is outside the arrangement's ${tracks.length} tracks`
|
|
171
178
|
);
|
|
172
179
|
}
|
|
173
180
|
if (isPercussion(_optionalChain([tracks, 'access', _4 => _4[track], 'optionalAccess', _5 => _5.role]))) {
|
|
174
|
-
throw new (0,
|
|
181
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
175
182
|
`${name}[${index}] ${track} names a percussion track, whose pitches state no harmony`
|
|
176
183
|
);
|
|
177
184
|
}
|
|
@@ -212,7 +219,7 @@ function splitIntoSubVoices(ordered) {
|
|
|
212
219
|
continue;
|
|
213
220
|
}
|
|
214
221
|
const end = last.startBeat + last.durationBeat;
|
|
215
|
-
if (!
|
|
222
|
+
if (!_chunkLQZQDBCDcjs.hasEnded.call(void 0, end, note.startBeat)) {
|
|
216
223
|
continue;
|
|
217
224
|
}
|
|
218
225
|
const distance = Math.abs(last.pitch - note.pitch);
|
|
@@ -233,13 +240,13 @@ function splitIntoSubVoices(ordered) {
|
|
|
233
240
|
for (let start = 0; start < ordered.length; ) {
|
|
234
241
|
const onset = _nullishCoalesce(_optionalChain([ordered, 'access', _13 => _13[start], 'optionalAccess', _14 => _14.startBeat]), () => ( 0));
|
|
235
242
|
let end = start + 1;
|
|
236
|
-
while (end < ordered.length &&
|
|
243
|
+
while (end < ordered.length && _chunkLQZQDBCDcjs.sameInstant.call(void 0, _nullishCoalesce(_optionalChain([ordered, 'access', _15 => _15[end], 'optionalAccess', _16 => _16.startBeat]), () => ( 0)), onset)) {
|
|
237
244
|
end += 1;
|
|
238
245
|
}
|
|
239
246
|
const block = ordered.slice(start, end);
|
|
240
247
|
if (block.length > 1) {
|
|
241
248
|
const freeLanes = lanes.map((lane, index) => ({ index, last: lane[lane.length - 1] })).filter(
|
|
242
|
-
(entry) => entry.last !== void 0 &&
|
|
249
|
+
(entry) => entry.last !== void 0 && _chunkLQZQDBCDcjs.hasEnded.call(void 0, entry.last.startBeat + entry.last.durationBeat, onset)
|
|
243
250
|
).sort((a, b) => a.last.pitch - b.last.pitch);
|
|
244
251
|
const assignment = pairWithFreeLanes(block, freeLanes);
|
|
245
252
|
const taken = new Set(
|
|
@@ -327,7 +334,7 @@ function lastStartingAtOrBefore(sounding, beat) {
|
|
|
327
334
|
let high = sounding.length;
|
|
328
335
|
while (low < high) {
|
|
329
336
|
const middle = Math.floor((low + high) / 2);
|
|
330
|
-
if ((_nullishCoalesce(_optionalChain([sounding, 'access', _22 => _22[middle], 'optionalAccess', _23 => _23.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat +
|
|
337
|
+
if ((_nullishCoalesce(_optionalChain([sounding, 'access', _22 => _22[middle], 'optionalAccess', _23 => _23.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
331
338
|
low = middle + 1;
|
|
332
339
|
} else {
|
|
333
340
|
high = middle;
|
|
@@ -338,12 +345,17 @@ function lastStartingAtOrBefore(sounding, beat) {
|
|
|
338
345
|
function prepareTracks(tracks) {
|
|
339
346
|
let nextId = 0;
|
|
340
347
|
return tracks.map((track, index) => {
|
|
341
|
-
const ordered = track.notes.map((note, originalIndex) => ({ note, originalIndex })).filter(({ note }) => note.durationBeat > 0).sort((a, b) => a.note.startBeat - b.note.startBeat || a.note.pitch - b.note.pitch).map(({ note, originalIndex }) => ({
|
|
348
|
+
const ordered = track.notes.map((note, originalIndex) => ({ note, originalIndex })).filter(({ note }) => note.durationBeat > 0).sort((a, b) => a.note.startBeat - b.note.startBeat || a.note.pitch - b.note.pitch).map(({ note, originalIndex }) => ({
|
|
349
|
+
...note,
|
|
350
|
+
pitch: note.pitch === 0 ? 0 : note.pitch,
|
|
351
|
+
id: nextId++,
|
|
352
|
+
originalIndex
|
|
353
|
+
}));
|
|
342
354
|
const voices = splitIntoSubVoices(ordered).map((voice) => {
|
|
343
355
|
const sounding = voice.map((note, i) => {
|
|
344
356
|
const prev = i > 0 ? voice[i - 1] : void 0;
|
|
345
357
|
const prevEnd = prev === void 0 ? void 0 : prev.startBeat + prev.durationBeat;
|
|
346
|
-
const contiguous = prevEnd !== void 0 &&
|
|
358
|
+
const contiguous = prevEnd !== void 0 && _chunkLQZQDBCDcjs.adjacent.call(void 0, prevEnd, note.startBeat);
|
|
347
359
|
return {
|
|
348
360
|
id: note.id,
|
|
349
361
|
originalIndex: note.originalIndex,
|
|
@@ -376,24 +388,25 @@ function withGivenKeys(result, given) {
|
|
|
376
388
|
if (given === void 0) {
|
|
377
389
|
return result;
|
|
378
390
|
}
|
|
379
|
-
return { ...result, keys: given, prevailingKey: _nullishCoalesce(
|
|
391
|
+
return { ...result, keys: given, prevailingKey: _nullishCoalesce(_chunkLQZQDBCDcjs.prevailingKeyOf.call(void 0, given), () => ( result.prevailingKey)) };
|
|
380
392
|
}
|
|
381
393
|
function callerTimeline(timeline, key, given, pooled, meters, budget) {
|
|
382
|
-
const chartEnd = timeline.segments.reduce(
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
0
|
|
394
|
+
const chartEnd = timeline.segments.reduce(
|
|
395
|
+
(end, segment) => Math.max(end, segment.endBeat),
|
|
396
|
+
Number.NEGATIVE_INFINITY
|
|
386
397
|
);
|
|
387
|
-
const
|
|
388
|
-
const
|
|
389
|
-
const
|
|
390
|
-
|
|
398
|
+
const soundingEnd = _chunkLQZQDBCDcjs.latestSoundingEnd.call(void 0, pooled, Number.NEGATIVE_INFINITY);
|
|
399
|
+
const spanEnd = Math.max(chartEnd, soundingEnd);
|
|
400
|
+
const totalBeats = Number.isFinite(spanEnd) ? spanEnd : 0;
|
|
401
|
+
const { startBeat: musicStart } = _chunkLQZQDBCDcjs.gridForNotes.call(void 0, pooled, _chunkS3QELJUEcjs.beatsPerBarAt.call(void 0, 0, meters));
|
|
402
|
+
const keys = _nullishCoalesce(given, () => ( _chunkLQZQDBCDcjs.attachPivots.call(void 0,
|
|
403
|
+
key !== void 0 ? _chunkLQZQDBCDcjs.statedKeyRegions.call(void 0, _chunkYDGMWH43cjs.resolveKey.call(void 0, key), musicStart, totalBeats) : _chunkLQZQDBCDcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }),
|
|
391
404
|
timeline.segments
|
|
392
405
|
)));
|
|
393
406
|
return {
|
|
394
407
|
timeline,
|
|
395
408
|
keys,
|
|
396
|
-
prevailingKey: _nullishCoalesce(
|
|
409
|
+
prevailingKey: _nullishCoalesce(_chunkLQZQDBCDcjs.prevailingKeyOf.call(void 0, keys), () => ( _chunkYDGMWH43cjs.resolveKey.call(void 0, _chunkYDGMWH43cjs.majorKey.call(void 0, 0)))),
|
|
397
410
|
segmentConfidence: timeline.segments.map(() => 0)
|
|
398
411
|
};
|
|
399
412
|
}
|
|
@@ -410,7 +423,7 @@ function soundingVoicesAt(prepared, beat) {
|
|
|
410
423
|
continue;
|
|
411
424
|
}
|
|
412
425
|
const snap = { pitch: note.pitch };
|
|
413
|
-
const previous =
|
|
426
|
+
const previous = _chunkLQZQDBCDcjs.sameInstant.call(void 0, note.startBeat, beat) ? note.prevPitch : note.pitch;
|
|
414
427
|
if (previous !== void 0) {
|
|
415
428
|
snap.prevPitch = previous;
|
|
416
429
|
}
|
|
@@ -439,11 +452,11 @@ function snapshotsOf(voices) {
|
|
|
439
452
|
return voices.map(({ snapshot }) => snapshot);
|
|
440
453
|
}
|
|
441
454
|
function analyzePolyphony(notes, chordAtBeat, key) {
|
|
442
|
-
const passage =
|
|
443
|
-
|
|
455
|
+
const passage = _chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, "notes", { allowNonPositiveDuration: true });
|
|
456
|
+
_chunkS3QELJUEcjs.assertFunction.call(void 0, chordAtBeat, "chordAtBeat");
|
|
444
457
|
const prepared = prepareTracks([{ notes: [...passage] }]);
|
|
445
458
|
const track = prepared[0];
|
|
446
|
-
|
|
459
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0,
|
|
447
460
|
passage.length * (_nullishCoalesce(_optionalChain([track, 'optionalAccess', _29 => _29.voices, 'access', _30 => _30.length]), () => ( 0))),
|
|
448
461
|
"polyphony note-voice comparisons"
|
|
449
462
|
);
|
|
@@ -454,7 +467,7 @@ function analyzePolyphony(notes, chordAtBeat, key) {
|
|
|
454
467
|
if (subVoice === void 0) {
|
|
455
468
|
continue;
|
|
456
469
|
}
|
|
457
|
-
const analyzed =
|
|
470
|
+
const analyzed = _chunkLQZQDBCDcjs.analyzeVoice.call(void 0,
|
|
458
471
|
subVoice.voice,
|
|
459
472
|
chordAtBeat,
|
|
460
473
|
key,
|
|
@@ -472,7 +485,7 @@ function analyzePolyphony(notes, chordAtBeat, key) {
|
|
|
472
485
|
if (analyzed !== void 0) {
|
|
473
486
|
return analyzed;
|
|
474
487
|
}
|
|
475
|
-
const [only] =
|
|
488
|
+
const [only] = _chunkLQZQDBCDcjs.analyzeVoice.call(void 0, [{ ...note, id: index }], chordAtBeat, key);
|
|
476
489
|
return _nullishCoalesce(only, () => ( {
|
|
477
490
|
noteId: index,
|
|
478
491
|
pitch: note.pitch,
|
|
@@ -487,7 +500,7 @@ function firstSegmentAfter(timeline, beat) {
|
|
|
487
500
|
let high = timeline.segments.length;
|
|
488
501
|
while (low < high) {
|
|
489
502
|
const middle = Math.floor((low + high) / 2);
|
|
490
|
-
if ((_nullishCoalesce(_optionalChain([timeline, 'access', _35 => _35.segments, 'access', _36 => _36[middle], 'optionalAccess', _37 => _37.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat +
|
|
503
|
+
if ((_nullishCoalesce(_optionalChain([timeline, 'access', _35 => _35.segments, 'access', _36 => _36[middle], 'optionalAccess', _37 => _37.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
491
504
|
low = middle + 1;
|
|
492
505
|
} else {
|
|
493
506
|
high = middle;
|
|
@@ -500,7 +513,7 @@ function evaluationBeats(note, timeline) {
|
|
|
500
513
|
const beats = [note.startBeat];
|
|
501
514
|
for (let i = firstSegmentAfter(timeline, note.startBeat); i < timeline.segments.length; i += 1) {
|
|
502
515
|
const start = _optionalChain([timeline, 'access', _38 => _38.segments, 'access', _39 => _39[i], 'optionalAccess', _40 => _40.startBeat]);
|
|
503
|
-
if (start === void 0 || start >= noteEnd -
|
|
516
|
+
if (start === void 0 || start >= noteEnd - _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
504
517
|
break;
|
|
505
518
|
}
|
|
506
519
|
beats.push(start);
|
|
@@ -511,19 +524,19 @@ function analyzeArrangement(tracks, opts = {}) {
|
|
|
511
524
|
return analyzeArrangementWith(tracks, opts).analysis;
|
|
512
525
|
}
|
|
513
526
|
function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
514
|
-
const meters =
|
|
527
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, opts, "arrangement meters");
|
|
515
528
|
const budget = opts.budget;
|
|
516
529
|
const noteOptions = { allowNonPositiveDuration: true, budget };
|
|
517
530
|
if (opts.pickupBeats !== void 0) {
|
|
518
|
-
|
|
531
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
|
|
519
532
|
noteOptions.minStartBeat = -opts.pickupBeats;
|
|
520
533
|
}
|
|
521
|
-
|
|
522
|
-
|
|
534
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, tracks, "arrangement tracks");
|
|
535
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
|
|
523
536
|
const noteCount = assertTrackNotes(tracks, noteOptions);
|
|
524
|
-
|
|
537
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
|
|
525
538
|
const profile = arrangementProfile(opts.profile);
|
|
526
|
-
const minSeverity = opts.minSeverity === void 0 ? 1 /* Warning */ :
|
|
539
|
+
const minSeverity = opts.minSeverity === void 0 ? 1 /* Warning */ : _chunkS3QELJUEcjs.assertInteger.call(void 0,
|
|
527
540
|
opts.minSeverity,
|
|
528
541
|
"arrangement minSeverity",
|
|
529
542
|
0 /* Safe */,
|
|
@@ -534,12 +547,12 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
534
547
|
const harmonyTracks = harmonyTrackSet(opts.harmonyTracks, tracks);
|
|
535
548
|
const prepared = prepareTracks(tracks);
|
|
536
549
|
const voiceCount = prepared.reduce((sum, track) => sum + track.voices.length, 0);
|
|
537
|
-
|
|
550
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, noteCount * voiceCount, "arrangement note-voice comparisons", budget);
|
|
538
551
|
const pooled = poolNotes(tracks, harmonyTracks);
|
|
539
552
|
let evidence;
|
|
540
553
|
let inferred;
|
|
541
554
|
if (opts.timeline === void 0) {
|
|
542
|
-
const run =
|
|
555
|
+
const run = _chunkLQZQDBCDcjs.analyzeTimeline.call(void 0,
|
|
543
556
|
pooled,
|
|
544
557
|
{
|
|
545
558
|
key: opts.key,
|
|
@@ -557,9 +570,9 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
557
570
|
inferred = callerTimeline(opts.timeline, opts.key, opts.keys, pooled, meters, budget);
|
|
558
571
|
}
|
|
559
572
|
const { timeline, keys, prevailingKey, segmentConfidence } = inferred;
|
|
560
|
-
const keyAt =
|
|
561
|
-
const scaleAt = (beat) =>
|
|
562
|
-
const cadences =
|
|
573
|
+
const keyAt = _chunkLQZQDBCDcjs.keyLookup.call(void 0, keys, prevailingKey);
|
|
574
|
+
const scaleAt = (beat) => _chunkYDGMWH43cjs.scaleOf.call(void 0, keyAt(beat));
|
|
575
|
+
const cadences = _chunkLQZQDBCDcjs.detectCadences.call(void 0, timeline, scaleAt);
|
|
563
576
|
const soundingCache = /* @__PURE__ */ new Map();
|
|
564
577
|
const trackAnalyses = [];
|
|
565
578
|
const conflicts = [];
|
|
@@ -578,7 +591,7 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
578
591
|
if (!subVoice) {
|
|
579
592
|
continue;
|
|
580
593
|
}
|
|
581
|
-
const analyzed =
|
|
594
|
+
const analyzed = _chunkLQZQDBCDcjs.analyzeVoice.call(void 0,
|
|
582
595
|
subVoice.voice,
|
|
583
596
|
timeline.at,
|
|
584
597
|
scaleAt,
|
|
@@ -595,7 +608,7 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
595
608
|
continue;
|
|
596
609
|
}
|
|
597
610
|
for (const beat of evaluationBeats(note, timeline)) {
|
|
598
|
-
const atOnset =
|
|
611
|
+
const atOnset = _chunkLQZQDBCDcjs.sameInstant.call(void 0, beat, note.startBeat);
|
|
599
612
|
const others = otherVoicesSounding(prepared, t, v, beat, soundingCache);
|
|
600
613
|
const safetyQuery = {
|
|
601
614
|
profile,
|
|
@@ -604,11 +617,11 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
604
617
|
chord: timeline.at(beat),
|
|
605
618
|
key: scaleAt(beat),
|
|
606
619
|
otherVoices: snapshotsOf(others),
|
|
607
|
-
strongBeat:
|
|
620
|
+
strongBeat: _chunkS3QELJUEcjs.isStrongBeat.call(void 0, beat, meters)
|
|
608
621
|
};
|
|
609
|
-
let result =
|
|
622
|
+
let result = _chunkYDGMWH43cjs.evaluateSafety.call(void 0, safetyQuery, { suggestions: false });
|
|
610
623
|
if (result.safety !== 0 /* Safe */ && result.safety >= minSeverity) {
|
|
611
|
-
result =
|
|
624
|
+
result = _chunkYDGMWH43cjs.evaluateSafety.call(void 0, safetyQuery, { partners: true });
|
|
612
625
|
const conflict = {
|
|
613
626
|
beat,
|
|
614
627
|
trackName: track.name,
|
|
@@ -721,7 +734,7 @@ function sessionOf(tracks, opts, analysis, evidence) {
|
|
|
721
734
|
tracks,
|
|
722
735
|
analysis,
|
|
723
736
|
update(edits) {
|
|
724
|
-
|
|
737
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, edits.length, "arrangement edits", opts.budget);
|
|
725
738
|
const next = [...tracks];
|
|
726
739
|
let edited = null;
|
|
727
740
|
let reordered = false;
|
|
@@ -732,16 +745,16 @@ function sessionOf(tracks, opts, analysis, evidence) {
|
|
|
732
745
|
}
|
|
733
746
|
const target = next[edit.trackIndex];
|
|
734
747
|
if (target === void 0) {
|
|
735
|
-
throw new (0,
|
|
748
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
736
749
|
`edits[${index}].trackIndex ${edit.trackIndex} is outside the session's ${tracks.length} tracks`
|
|
737
750
|
);
|
|
738
751
|
}
|
|
739
752
|
if (!Array.isArray(edit.notes)) {
|
|
740
|
-
throw new (0,
|
|
741
|
-
`edits[${index}].notes must be an array; received ${
|
|
753
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
754
|
+
`edits[${index}].notes must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, edit.notes)}`
|
|
742
755
|
);
|
|
743
756
|
}
|
|
744
|
-
|
|
757
|
+
_chunkS3QELJUEcjs.assertNoteEvents.call(void 0, edit.notes, `edits[${index}].notes`, {
|
|
745
758
|
allowNonPositiveDuration: true,
|
|
746
759
|
budget: opts.budget
|
|
747
760
|
});
|
|
@@ -752,7 +765,7 @@ function sessionOf(tracks, opts, analysis, evidence) {
|
|
|
752
765
|
if (edited === null && !reordered) {
|
|
753
766
|
return sessionOf(next, opts, analysis, evidence);
|
|
754
767
|
}
|
|
755
|
-
const dirty = evidence === void 0 ? void 0 : edited === null ? { from: 0, to: 0 } :
|
|
768
|
+
const dirty = evidence === void 0 ? void 0 : edited === null ? { from: 0, to: 0 } : _chunkLQZQDBCDcjs.dirtySlotsFor.call(void 0, evidence, edited.startBeat, edited.endBeat);
|
|
756
769
|
const run = analyzeArrangementWith(next, opts, evidence, dirty);
|
|
757
770
|
return sessionOf(next, opts, run.analysis, run.evidence);
|
|
758
771
|
}
|
|
@@ -773,26 +786,27 @@ var FUNCTION_WEIGHT = 0.5;
|
|
|
773
786
|
var DISSONANCE_WEIGHT = 0.35;
|
|
774
787
|
var SPAN_WEIGHT = 0.15;
|
|
775
788
|
var SPAN_SATURATION = 24;
|
|
789
|
+
var MAX_DISTINCT_PITCHES = 128;
|
|
776
790
|
function clamp012(value) {
|
|
777
791
|
return Math.min(1, Math.max(0, value));
|
|
778
792
|
}
|
|
779
793
|
function tensionCurve(tracks, opts = {}) {
|
|
780
|
-
const meters =
|
|
794
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, opts, "arrangement meters");
|
|
781
795
|
const budget = opts.budget;
|
|
782
796
|
const noteOptions = { allowNonPositiveDuration: true, budget };
|
|
783
797
|
if (opts.pickupBeats !== void 0) {
|
|
784
|
-
|
|
798
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
|
|
785
799
|
noteOptions.minStartBeat = -opts.pickupBeats;
|
|
786
800
|
}
|
|
787
|
-
|
|
788
|
-
|
|
801
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, tracks, "arrangement tracks");
|
|
802
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
|
|
789
803
|
const noteCount = assertTrackNotes(tracks, noteOptions);
|
|
790
|
-
|
|
804
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
|
|
791
805
|
const profile = arrangementProfile(opts.profile);
|
|
792
806
|
const step = _nullishCoalesce(opts.step, () => ( 1));
|
|
793
|
-
|
|
807
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, step, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "tension sampling step");
|
|
794
808
|
if (opts.minSeverity !== void 0) {
|
|
795
|
-
|
|
809
|
+
_chunkS3QELJUEcjs.assertInteger.call(void 0,
|
|
796
810
|
opts.minSeverity,
|
|
797
811
|
"arrangement minSeverity",
|
|
798
812
|
0 /* Safe */,
|
|
@@ -804,20 +818,15 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
804
818
|
const harmonyTracks = harmonyTrackSet(opts.harmonyTracks, tracks);
|
|
805
819
|
const pooled = poolNotes(tracks, harmonyTracks);
|
|
806
820
|
const all = poolNotes(tracks);
|
|
807
|
-
const totalBeats =
|
|
808
|
-
const { origin: sampleStart, startBeat: musicStart } =
|
|
809
|
-
const suppliedKeys = opts.timeline === void 0 ? void 0 : _nullishCoalesce(opts.keys, () => ( (opts.key !== void 0 ?
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
key: _chunk3R3QVKY5cjs.resolveKey.call(void 0, opts.key),
|
|
817
|
-
confidence: 1
|
|
818
|
-
}
|
|
819
|
-
] : _chunkIFZDWIKMcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }))));
|
|
820
|
-
const { timeline, keys, prevailingKey } = opts.timeline === void 0 || suppliedKeys === void 0 ? _chunkIFZDWIKMcjs.chordTimelineFromNotes.call(void 0, pooled, {
|
|
821
|
+
const totalBeats = _chunkLQZQDBCDcjs.latestSoundingEnd.call(void 0, all);
|
|
822
|
+
const { origin: sampleStart, startBeat: musicStart } = _chunkLQZQDBCDcjs.gridForNotes.call(void 0, all, step);
|
|
823
|
+
const suppliedKeys = opts.timeline === void 0 ? void 0 : _nullishCoalesce(opts.keys, () => ( (opts.key !== void 0 ? (
|
|
824
|
+
// The one region a named key holds starts where the music does, as
|
|
825
|
+
// the searched regions and the timeline's own key window do: a key
|
|
826
|
+
// cannot be in force over beats nothing sounds in.
|
|
827
|
+
_chunkLQZQDBCDcjs.statedKeyRegions.call(void 0, _chunkYDGMWH43cjs.resolveKey.call(void 0, opts.key), musicStart, totalBeats)
|
|
828
|
+
) : _chunkLQZQDBCDcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }))));
|
|
829
|
+
const { timeline, keys, prevailingKey } = opts.timeline === void 0 || suppliedKeys === void 0 ? _chunkLQZQDBCDcjs.chordTimelineFromNotes.call(void 0, pooled, {
|
|
821
830
|
key: opts.key,
|
|
822
831
|
meters,
|
|
823
832
|
pickupBeats: opts.pickupBeats,
|
|
@@ -826,17 +835,17 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
826
835
|
}) : {
|
|
827
836
|
timeline: opts.timeline,
|
|
828
837
|
keys: suppliedKeys,
|
|
829
|
-
prevailingKey: _nullishCoalesce(
|
|
838
|
+
prevailingKey: _nullishCoalesce(_chunkLQZQDBCDcjs.prevailingKeyOf.call(void 0, suppliedKeys), () => ( _chunkYDGMWH43cjs.resolveKey.call(void 0, _chunkYDGMWH43cjs.majorKey.call(void 0, 0))))
|
|
830
839
|
};
|
|
831
840
|
const regions = _nullishCoalesce(opts.keys, () => ( keys));
|
|
832
|
-
const keyAt =
|
|
841
|
+
const keyAt = _chunkLQZQDBCDcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkLQZQDBCDcjs.prevailingKeyOf.call(void 0, regions), () => ( prevailingKey)));
|
|
833
842
|
const prepared = prepareTracks(tracks);
|
|
834
843
|
const points = [];
|
|
835
|
-
const sampleCount = Math.max(0, Math.ceil((totalBeats - sampleStart) / step -
|
|
836
|
-
|
|
844
|
+
const sampleCount = Math.max(0, Math.ceil((totalBeats - sampleStart) / step - _chunkS3QELJUEcjs.BEAT_EPS));
|
|
845
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, sampleCount, "tension samples", budget);
|
|
837
846
|
const voiceCount = prepared.reduce((sum, track) => sum + track.voices.length, 0);
|
|
838
|
-
|
|
839
|
-
sampleCount * Math.min(
|
|
847
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0,
|
|
848
|
+
sampleCount * Math.min(MAX_DISTINCT_PITCHES, voiceCount) * voiceCount,
|
|
840
849
|
"tension sample-voice comparisons",
|
|
841
850
|
budget
|
|
842
851
|
);
|
|
@@ -844,16 +853,15 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
844
853
|
const beat = i === 0 ? Math.max(sampleStart, musicStart) : sampleStart + i * step;
|
|
845
854
|
points.push({
|
|
846
855
|
beat,
|
|
847
|
-
// The
|
|
848
|
-
|
|
849
|
-
tension: sampleTension(prepared, timeline, _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat)), meters, profile, beat)
|
|
856
|
+
// The key whole: an augmented sixth is told from a dominant by its letters.
|
|
857
|
+
tension: sampleTension(prepared, timeline, keyAt(beat), meters, profile, beat)
|
|
850
858
|
});
|
|
851
859
|
}
|
|
852
860
|
return points;
|
|
853
861
|
}
|
|
854
862
|
function tensionCurveFrom(tracks, analysis, opts = {}) {
|
|
855
|
-
const asked =
|
|
856
|
-
const carried = carriedHarmony(
|
|
863
|
+
const asked = _chunkS3QELJUEcjs.assertRecord.call(void 0, opts, "opts");
|
|
864
|
+
const carried = carriedHarmony(_chunkS3QELJUEcjs.assertRecord.call(void 0, analysis, "analysis"), asked);
|
|
857
865
|
return tensionCurve(tracks, { ...carried, ...asked });
|
|
858
866
|
}
|
|
859
867
|
function carriedHarmony(analysis, opts) {
|
|
@@ -887,9 +895,9 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
887
895
|
return 0;
|
|
888
896
|
}
|
|
889
897
|
const chord = timeline.at(beat);
|
|
890
|
-
const functionScore = chord ? FUNCTION_TENSION[
|
|
891
|
-
const chordPcs = chord ? new Set(
|
|
892
|
-
const strongBeat =
|
|
898
|
+
const functionScore = chord ? FUNCTION_TENSION[_chunkLQZQDBCDcjs.functionOf.call(void 0, chord, key)] : 0;
|
|
899
|
+
const chordPcs = chord ? new Set(_chunkYDGMWH43cjs.chordPitchClasses.call(void 0, chord)) : null;
|
|
900
|
+
const strongBeat = _chunkS3QELJUEcjs.isStrongBeat.call(void 0, beat, meters);
|
|
893
901
|
let nonChord = 0;
|
|
894
902
|
let dissonant = 0;
|
|
895
903
|
const pitches = /* @__PURE__ */ new Map();
|
|
@@ -905,7 +913,7 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
905
913
|
}
|
|
906
914
|
}
|
|
907
915
|
for (const [pitch, count] of pitches) {
|
|
908
|
-
if (chordPcs && !chordPcs.has(
|
|
916
|
+
if (chordPcs && !chordPcs.has(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch))) {
|
|
909
917
|
nonChord += count;
|
|
910
918
|
}
|
|
911
919
|
const at = _nullishCoalesce(firstOf.get(pitch), () => ( 0));
|
|
@@ -916,8 +924,8 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
916
924
|
others[at] = tail;
|
|
917
925
|
others.pop();
|
|
918
926
|
}
|
|
919
|
-
const result =
|
|
920
|
-
{ profile, candidatePitch: pitch, chord, key, otherVoices: others, strongBeat },
|
|
927
|
+
const result = _chunkYDGMWH43cjs.evaluateSafety.call(void 0,
|
|
928
|
+
{ profile, candidatePitch: pitch, chord, key: key.scale, otherVoices: others, strongBeat },
|
|
921
929
|
{ suggestions: false }
|
|
922
930
|
);
|
|
923
931
|
if (held !== void 0 && tail !== void 0) {
|
|
@@ -943,19 +951,34 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
943
951
|
|
|
944
952
|
// src/analyze/form/hypermeter.ts
|
|
945
953
|
var GROUP_CANDIDATES = [2, 3, 4, 6, 8];
|
|
946
|
-
var
|
|
954
|
+
var GROUP_PRIOR_LIST = [
|
|
947
955
|
[2, 0.9],
|
|
948
956
|
[3, 0.75],
|
|
949
957
|
[4, 1],
|
|
950
958
|
[6, 0.7],
|
|
951
959
|
[8, 0.85]
|
|
952
|
-
]
|
|
960
|
+
];
|
|
961
|
+
var GROUP_PRIOR = new Map(GROUP_PRIOR_LIST);
|
|
953
962
|
var CONTRAST_SHARE = 0.65;
|
|
954
963
|
var CADENCE_SHARE = 0.35;
|
|
955
964
|
var GROUP_FINAL_FIT = 1;
|
|
956
965
|
var ELIDED_FIT = 0.5;
|
|
957
966
|
var MIN_GROUPS = 2;
|
|
958
967
|
var MARGIN_FLOOR = 0.7;
|
|
968
|
+
function cadenceSpans(arrivals, segments) {
|
|
969
|
+
return arrivals.map(({ atBeat, strength }) => ({
|
|
970
|
+
atBeat,
|
|
971
|
+
endBeat: _nullishCoalesce(_optionalChain([_chunkLQZQDBCDcjs.segmentStartingAt.call(void 0, segments, atBeat), 'optionalAccess', _41 => _41.endBeat]), () => ( atBeat)),
|
|
972
|
+
strength
|
|
973
|
+
}));
|
|
974
|
+
}
|
|
975
|
+
function cadenceBarsOf(spans, meter) {
|
|
976
|
+
return spans.map((span) => ({
|
|
977
|
+
arrival: _chunkS3QELJUEcjs.barIndexAt.call(void 0, span.atBeat, meter),
|
|
978
|
+
last: _chunkLQZQDBCDcjs.lastBarOf.call(void 0, meter, span.atBeat, span.endBeat),
|
|
979
|
+
strength: span.strength
|
|
980
|
+
}));
|
|
981
|
+
}
|
|
959
982
|
function accentContrast(novelty, slices, groupBars, phase) {
|
|
960
983
|
let headSum = 0;
|
|
961
984
|
let headCount = 0;
|
|
@@ -967,7 +990,7 @@ function accentContrast(novelty, slices, groupBars, phase) {
|
|
|
967
990
|
continue;
|
|
968
991
|
}
|
|
969
992
|
const value = _nullishCoalesce(novelty[i], () => ( 0));
|
|
970
|
-
if (
|
|
993
|
+
if (_chunkLQZQDBCDcjs.floorMod.call(void 0, slice.index - phase, groupBars) === 0) {
|
|
971
994
|
headSum += value;
|
|
972
995
|
headCount += 1;
|
|
973
996
|
} else {
|
|
@@ -980,22 +1003,41 @@ function accentContrast(novelty, slices, groupBars, phase) {
|
|
|
980
1003
|
}
|
|
981
1004
|
return headSum / headCount - otherSum / otherCount;
|
|
982
1005
|
}
|
|
983
|
-
function cadenceFitOf(
|
|
984
|
-
const lastBar = _nullishCoalesce(_optionalChain([slices, 'access',
|
|
1006
|
+
function cadenceFitOf(cadences, slices, groupBars, phase) {
|
|
1007
|
+
const lastBar = _nullishCoalesce(_optionalChain([slices, 'access', _42 => _42[slices.length - 1], 'optionalAccess', _43 => _43.index]), () => ( -1));
|
|
1008
|
+
const closing = /* @__PURE__ */ new Map();
|
|
1009
|
+
const eliding = /* @__PURE__ */ new Map();
|
|
1010
|
+
const credit = (bars, bar, strength) => {
|
|
1011
|
+
bars.set(bar, Math.max(_nullishCoalesce(bars.get(bar), () => ( 0)), strength));
|
|
1012
|
+
};
|
|
1013
|
+
for (const cadence of cadences) {
|
|
1014
|
+
const end = cadence.arrival + _chunkLQZQDBCDcjs.floorMod.call(void 0, groupBars - 1 + phase - cadence.arrival, groupBars);
|
|
1015
|
+
if (end <= cadence.last) {
|
|
1016
|
+
credit(closing, end, cadence.strength);
|
|
1017
|
+
} else if (_chunkLQZQDBCDcjs.floorMod.call(void 0, cadence.arrival - phase, groupBars) === 0 && // Elision needs a next group to arrive into. Past the last bar the span
|
|
1018
|
+
// holds there is none, so a cadence beat beyond the music is not evidence
|
|
1019
|
+
// about how the music that was read is grouped.
|
|
1020
|
+
cadence.arrival <= lastBar) {
|
|
1021
|
+
credit(eliding, cadence.arrival - 1, cadence.strength);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
985
1024
|
let ends = 0;
|
|
986
|
-
let
|
|
1025
|
+
let closed = 0;
|
|
1026
|
+
let weighted = 0;
|
|
987
1027
|
for (const slice of slices) {
|
|
988
|
-
if (slice.index < 0 ||
|
|
1028
|
+
if (slice.index < 0 || _chunkLQZQDBCDcjs.floorMod.call(void 0, slice.index - phase, groupBars) !== groupBars - 1) {
|
|
989
1029
|
continue;
|
|
990
1030
|
}
|
|
991
1031
|
ends += 1;
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1032
|
+
const final = closing.get(slice.index);
|
|
1033
|
+
const elided = eliding.get(slice.index);
|
|
1034
|
+
closed += Math.max(
|
|
1035
|
+
final === void 0 ? 0 : GROUP_FINAL_FIT,
|
|
1036
|
+
elided === void 0 ? 0 : ELIDED_FIT
|
|
1037
|
+
);
|
|
1038
|
+
weighted += Math.max(GROUP_FINAL_FIT * (_nullishCoalesce(final, () => ( 0))), ELIDED_FIT * (_nullishCoalesce(elided, () => ( 0))));
|
|
997
1039
|
}
|
|
998
|
-
return ends === 0 ? 0 :
|
|
1040
|
+
return ends === 0 ? { closed: 0, weighted: 0 } : { closed: _chunkLQZQDBCDcjs.clamp01.call(void 0, closed / ends), weighted: _chunkLQZQDBCDcjs.clamp01.call(void 0, weighted / ends) };
|
|
999
1041
|
}
|
|
1000
1042
|
function undecidedReading(slices) {
|
|
1001
1043
|
const fullBars = slices.filter((slice) => slice.index >= 0);
|
|
@@ -1009,52 +1051,70 @@ function undecidedReading(slices) {
|
|
|
1009
1051
|
};
|
|
1010
1052
|
}
|
|
1011
1053
|
function hypermeter(notes, meter, opts = {}) {
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1054
|
+
return hypermeterOver(
|
|
1055
|
+
notes,
|
|
1056
|
+
meter,
|
|
1057
|
+
opts,
|
|
1058
|
+
(asked) => cadenceSpans(
|
|
1059
|
+
(_nullishCoalesce(asked.cadenceBeats, () => ( []))).map((atBeat) => ({ atBeat, strength: 1 })),
|
|
1060
|
+
[]
|
|
1061
|
+
)
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
function hypermeterOver(notes, meter, opts, spansOf) {
|
|
1065
|
+
const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
|
|
1066
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, { meters: meter }, "meter");
|
|
1067
|
+
_chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, "hypermeter notes", {
|
|
1015
1068
|
allowNonPositiveDuration: true,
|
|
1016
1069
|
budget: asked.budget
|
|
1017
1070
|
});
|
|
1018
1071
|
const sounding = notes.filter((note) => note.durationBeat > 0);
|
|
1019
|
-
const firstOnset =
|
|
1020
|
-
const
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1072
|
+
const firstOnset = _chunkLQZQDBCDcjs.firstSoundingBeat.call(void 0, sounding);
|
|
1073
|
+
const spanEnd = _chunkLQZQDBCDcjs.resolveSpanEnd.call(void 0,
|
|
1074
|
+
asked.totalBeats,
|
|
1075
|
+
firstOnset,
|
|
1076
|
+
_chunkLQZQDBCDcjs.latestSoundingEnd.call(void 0, sounding),
|
|
1077
|
+
"hypermeter totalBeats"
|
|
1078
|
+
);
|
|
1079
|
+
const spanStart = _chunkLQZQDBCDcjs.barGridStart.call(void 0, firstOnset, meters);
|
|
1080
|
+
if (sounding.length === 0 || spanEnd <= spanStart + _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1081
|
+
return undecidedReading([]);
|
|
1082
|
+
}
|
|
1083
|
+
const slices = _chunkLQZQDBCDcjs.sliceBars.call(void 0, sounding, meters, spanStart, spanEnd, asked.budget);
|
|
1025
1084
|
const fullBars = slices.reduce((count, slice) => slice.index >= 0 ? count + 1 : count, 0);
|
|
1026
1085
|
const candidates = GROUP_CANDIDATES.filter((groupBars) => fullBars >= groupBars * MIN_GROUPS);
|
|
1027
1086
|
if (candidates.length === 0) {
|
|
1028
1087
|
return undecidedReading(slices);
|
|
1029
1088
|
}
|
|
1030
|
-
|
|
1089
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0,
|
|
1031
1090
|
candidates.reduce((sum, groupBars) => sum + groupBars * slices.length, 0),
|
|
1032
1091
|
"hypermeter readings",
|
|
1033
1092
|
asked.budget
|
|
1034
1093
|
);
|
|
1035
|
-
const novelty = slices.map((_, index) =>
|
|
1036
|
-
const cadenceBars =
|
|
1037
|
-
const hasCadences = cadenceBars.
|
|
1094
|
+
const novelty = slices.map((_, index) => _chunkLQZQDBCDcjs.harmonicNovelty.call(void 0, slices, index));
|
|
1095
|
+
const cadenceBars = cadenceBarsOf(spansOf(asked), meters);
|
|
1096
|
+
const hasCadences = cadenceBars.length > 0;
|
|
1038
1097
|
const readings = [];
|
|
1039
1098
|
for (const groupBars of candidates) {
|
|
1040
1099
|
const phases = Array.from({ length: groupBars }, (_, phase) => ({
|
|
1041
1100
|
phase,
|
|
1042
1101
|
contrast: accentContrast(novelty, slices, groupBars, phase),
|
|
1043
|
-
|
|
1102
|
+
fit: cadenceFitOf(cadenceBars, slices, groupBars, phase)
|
|
1044
1103
|
}));
|
|
1045
|
-
const bestFit = phases.reduce((best2, reading) => Math.max(best2, reading.
|
|
1046
|
-
for (const { phase, contrast,
|
|
1047
|
-
if (hasCadences &&
|
|
1104
|
+
const bestFit = phases.reduce((best2, reading) => Math.max(best2, reading.fit.weighted), 0);
|
|
1105
|
+
for (const { phase, contrast, fit } of phases) {
|
|
1106
|
+
if (hasCadences && fit.weighted < bestFit - _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1048
1107
|
continue;
|
|
1049
1108
|
}
|
|
1050
|
-
const
|
|
1109
|
+
const cadenceFit = fit.closed;
|
|
1110
|
+
const evidence = _chunkLQZQDBCDcjs.clamp01.call(void 0,
|
|
1051
1111
|
hasCadences ? (
|
|
1052
1112
|
// Floored at zero rather than summed raw: group heads that restate
|
|
1053
1113
|
// the harmony their group opened with — the commonest way a phrase
|
|
1054
1114
|
// begins — change less than the bars between them, and a negative
|
|
1055
1115
|
// contrast subtracted from the cadence term would count that
|
|
1056
1116
|
// restatement as evidence against the very phase it confirms.
|
|
1057
|
-
CONTRAST_SHARE *
|
|
1117
|
+
CONTRAST_SHARE * _chunkLQZQDBCDcjs.clamp01.call(void 0, contrast) + CADENCE_SHARE * cadenceFit
|
|
1058
1118
|
) : contrast
|
|
1059
1119
|
);
|
|
1060
1120
|
readings.push({
|
|
@@ -1075,8 +1135,8 @@ function hypermeter(notes, meter, opts = {}) {
|
|
|
1075
1135
|
return undecidedReading(slices);
|
|
1076
1136
|
}
|
|
1077
1137
|
const runnerUp = readings.find((reading) => reading.groupBars !== best.groupBars);
|
|
1078
|
-
const margin = runnerUp === void 0 || best.score <=
|
|
1079
|
-
const downbeats = slices.filter((slice) => slice.index >= 0 &&
|
|
1138
|
+
const margin = runnerUp === void 0 || best.score <= _chunkS3QELJUEcjs.BEAT_EPS ? 1 : _chunkLQZQDBCDcjs.clamp01.call(void 0, (best.score - runnerUp.score) / best.score);
|
|
1139
|
+
const downbeats = slices.filter((slice) => slice.index >= 0 && _chunkLQZQDBCDcjs.floorMod.call(void 0, slice.index - best.phase, best.groupBars) === 0).map((slice) => slice.startBeat);
|
|
1080
1140
|
const cadencePart = hasCadences ? `${Math.round(best.cadenceFit * 100)}% of group ends closed by a cadence` : "no cadences given";
|
|
1081
1141
|
return {
|
|
1082
1142
|
groupBars: best.groupBars,
|
|
@@ -1086,7 +1146,7 @@ function hypermeter(notes, meter, opts = {}) {
|
|
|
1086
1146
|
// runner-up is nearly always a multiple or a divisor of the winner — four
|
|
1087
1147
|
// bars nest inside eight — and a reading of the same accents at another
|
|
1088
1148
|
// level is weaker counter-evidence than an unrelated rival would be.
|
|
1089
|
-
confidence:
|
|
1149
|
+
confidence: _chunkLQZQDBCDcjs.clamp01.call(void 0, best.evidence * (MARGIN_FLOOR + (1 - MARGIN_FLOOR) * margin)),
|
|
1090
1150
|
rationale: `${best.groupBars}-bar groups from bar ${best.phase}: harmonic change ${Math.round(best.contrast * 100)}% stronger on group heads, ${cadencePart}`
|
|
1091
1151
|
};
|
|
1092
1152
|
}
|
|
@@ -1118,6 +1178,7 @@ var PHRASE_CUT_COST = 1.3;
|
|
|
1118
1178
|
var CLOSING_SHARE = 0.65;
|
|
1119
1179
|
var FINAL_PHRASE_BONUS = 0.15;
|
|
1120
1180
|
var HYPERMETRIC_CLOSE_BONUS = 0.1;
|
|
1181
|
+
var IMPERFECT_CLOSURE_FACTOR = 0.8;
|
|
1121
1182
|
var EVADED_FACTOR = 0.6;
|
|
1122
1183
|
var SIGNAL_ORDER = [
|
|
1123
1184
|
"cadence",
|
|
@@ -1128,7 +1189,7 @@ var SIGNAL_ORDER = [
|
|
|
1128
1189
|
"hypermeter"
|
|
1129
1190
|
];
|
|
1130
1191
|
function addSignal(boundaries, beat, signal, strength, cadence = null) {
|
|
1131
|
-
const key = Math.round(beat /
|
|
1192
|
+
const key = Math.round(beat / _chunkS3QELJUEcjs.BEAT_EPS);
|
|
1132
1193
|
const existing = boundaries.get(key);
|
|
1133
1194
|
const boundary = _nullishCoalesce(existing, () => ( { beat, strengths: /* @__PURE__ */ new Map(), cadence: null }));
|
|
1134
1195
|
boundary.strengths.set(signal, Math.max(_nullishCoalesce(boundary.strengths.get(signal), () => ( 0)), strength));
|
|
@@ -1142,17 +1203,23 @@ function readBoundary(boundary) {
|
|
|
1142
1203
|
(a, b) => b[1] - a[1] || SIGNAL_ORDER.indexOf(a[0]) - SIGNAL_ORDER.indexOf(b[0])
|
|
1143
1204
|
);
|
|
1144
1205
|
return {
|
|
1145
|
-
strength:
|
|
1206
|
+
strength: _chunkLQZQDBCDcjs.combineEvidence.call(void 0, signals.map(([, strength]) => strength)),
|
|
1207
|
+
uncredited: _chunkLQZQDBCDcjs.combineEvidence.call(void 0,
|
|
1208
|
+
signals.filter(([signal]) => signal !== "cadence").map(([, strength]) => strength)
|
|
1209
|
+
),
|
|
1146
1210
|
signals: signals.map(([signal]) => signal)
|
|
1147
1211
|
};
|
|
1148
1212
|
}
|
|
1213
|
+
function closesPhrase(atBeat, startBeat, endBeat) {
|
|
1214
|
+
return atBeat >= startBeat - _chunkS3QELJUEcjs.BEAT_EPS && atBeat < endBeat - _chunkS3QELJUEcjs.BEAT_EPS;
|
|
1215
|
+
}
|
|
1149
1216
|
function lengthFit(length, expected) {
|
|
1150
1217
|
if (!(expected > 0)) {
|
|
1151
1218
|
return 0;
|
|
1152
1219
|
}
|
|
1153
1220
|
return Math.max(-1, 1 - Math.abs(length - expected) / expected);
|
|
1154
1221
|
}
|
|
1155
|
-
function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
|
|
1222
|
+
function choosePhrasePath(beats, strengths, minPhraseBeats, expected, held) {
|
|
1156
1223
|
const value = new Array(beats.length).fill(Number.NEGATIVE_INFINITY);
|
|
1157
1224
|
const cameFrom = new Array(beats.length).fill(-1);
|
|
1158
1225
|
value[0] = 0;
|
|
@@ -1163,10 +1230,12 @@ function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
|
|
|
1163
1230
|
continue;
|
|
1164
1231
|
}
|
|
1165
1232
|
const length = endBeat - (_nullishCoalesce(beats[i], () => ( 0)));
|
|
1166
|
-
if (length < minPhraseBeats -
|
|
1233
|
+
if (length < minPhraseBeats - _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1167
1234
|
continue;
|
|
1168
1235
|
}
|
|
1169
|
-
const
|
|
1236
|
+
const credited = held === void 0 || closesPhrase(_nullishCoalesce(held.arrivals[j], () => ( endBeat)), _nullishCoalesce(beats[i], () => ( 0)), endBeat);
|
|
1237
|
+
const strength = credited ? _nullishCoalesce(strengths[j], () => ( 0)) : _nullishCoalesce(held.uncredited[j], () => ( 0));
|
|
1238
|
+
const gain = (_nullishCoalesce(value[i], () => ( 0))) + strength + lengthFit(length, expected) - PHRASE_CUT_COST;
|
|
1170
1239
|
if (gain > (_nullishCoalesce(value[j], () => ( Number.NEGATIVE_INFINITY)))) {
|
|
1171
1240
|
value[j] = gain;
|
|
1172
1241
|
cameFrom[j] = i;
|
|
@@ -1185,33 +1254,47 @@ function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
|
|
|
1185
1254
|
}
|
|
1186
1255
|
return path;
|
|
1187
1256
|
}
|
|
1188
|
-
function
|
|
1189
|
-
|
|
1257
|
+
function boundaryCadences(timeline, key) {
|
|
1258
|
+
const hits = _chunkLQZQDBCDcjs.detectCadences.call(void 0, timeline, key).filter((hit) => hit.cadence.type !== null);
|
|
1259
|
+
const spans = cadenceSpans(
|
|
1260
|
+
hits.map((hit) => ({
|
|
1261
|
+
atBeat: hit.atBeat,
|
|
1262
|
+
strength: CADENCE_BOUNDARY_STRENGTH[hit.cadence.type]
|
|
1263
|
+
})),
|
|
1264
|
+
timeline.segments
|
|
1265
|
+
);
|
|
1266
|
+
return { hits, spans };
|
|
1267
|
+
}
|
|
1268
|
+
function keyContextFor(key, timeline, meters, totalBeats, budget) {
|
|
1269
|
+
if (key !== void 0) {
|
|
1270
|
+
return key;
|
|
1271
|
+
}
|
|
1272
|
+
const regions = _chunkLQZQDBCDcjs.detectModulations.call(void 0, timeline.segments, { meters, totalBeats, budget });
|
|
1273
|
+
const keyAt = _chunkLQZQDBCDcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkLQZQDBCDcjs.prevailingKeyOf.call(void 0, regions), () => ( _chunkYDGMWH43cjs.resolveKey.call(void 0, _chunkYDGMWH43cjs.majorKey.call(void 0, 0)))));
|
|
1274
|
+
return (beat) => _chunkYDGMWH43cjs.scaleOf.call(void 0, keyAt(beat));
|
|
1190
1275
|
}
|
|
1191
|
-
function
|
|
1192
|
-
|
|
1193
|
-
|
|
1276
|
+
function heldCadenceBoundaries(boundaries, hit, span, meters, spanEnd) {
|
|
1277
|
+
const firstLine = _chunkS3QELJUEcjs.barIndexAt.call(void 0, span.atBeat, meters) + 1;
|
|
1278
|
+
const lastLine = _chunkS3QELJUEcjs.barIndexAt.call(void 0, Math.min(span.endBeat, spanEnd), meters);
|
|
1279
|
+
for (let bar = firstLine; bar <= lastLine; bar += 1) {
|
|
1280
|
+
const line = _chunkS3QELJUEcjs.barPositionToBeat.call(void 0, { bar, beat: 0 }, meters);
|
|
1281
|
+
if (line < span.endBeat - _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1282
|
+
addSignal(boundaries, line, "cadence", span.strength, hit);
|
|
1283
|
+
}
|
|
1194
1284
|
}
|
|
1195
|
-
const regions = _chunkIFZDWIKMcjs.keyTimelineFromNotes.call(void 0, notes, {
|
|
1196
|
-
meters,
|
|
1197
|
-
totalBeats,
|
|
1198
|
-
budget: opts.budget
|
|
1199
|
-
});
|
|
1200
|
-
const keyAt = _chunkIFZDWIKMcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkIFZDWIKMcjs.prevailingKeyOf.call(void 0, regions), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0)))));
|
|
1201
|
-
return (beat) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat));
|
|
1202
1285
|
}
|
|
1203
1286
|
function restBoundaries(boundaries, notes, meters, restBeats) {
|
|
1204
1287
|
const ordered = [...notes].sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
|
|
1205
1288
|
let covered = Number.NEGATIVE_INFINITY;
|
|
1206
1289
|
for (const note of ordered) {
|
|
1207
1290
|
const gap = note.startBeat - covered;
|
|
1208
|
-
if (Number.isFinite(covered) && gap >= restBeats -
|
|
1209
|
-
const bar =
|
|
1291
|
+
if (Number.isFinite(covered) && gap >= restBeats - _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1292
|
+
const bar = _chunkS3QELJUEcjs.beatsPerBarAt.call(void 0, note.startBeat, meters);
|
|
1210
1293
|
addSignal(
|
|
1211
1294
|
boundaries,
|
|
1212
1295
|
note.startBeat,
|
|
1213
1296
|
"rest",
|
|
1214
|
-
REST_STRENGTH *
|
|
1297
|
+
REST_STRENGTH * _chunkLQZQDBCDcjs.clamp01.call(void 0, bar > 0 ? gap / bar : 1)
|
|
1215
1298
|
);
|
|
1216
1299
|
}
|
|
1217
1300
|
covered = Math.max(covered, note.startBeat + note.durationBeat);
|
|
@@ -1221,13 +1304,13 @@ function repetitionBoundaries(boundaries, notes, meters, spanStart, spanEnd, win
|
|
|
1221
1304
|
if (!(windowBeats > 0)) {
|
|
1222
1305
|
return;
|
|
1223
1306
|
}
|
|
1224
|
-
const slices =
|
|
1225
|
-
|
|
1226
|
-
const onsetsIn = (from, to) => notes.filter((note) => note.startBeat >= from -
|
|
1307
|
+
const slices = _chunkLQZQDBCDcjs.sliceBars.call(void 0, notes, meters, spanStart, spanEnd, budget);
|
|
1308
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, slices.length * notes.length, "form repetition comparisons", budget);
|
|
1309
|
+
const onsetsIn = (from, to) => notes.filter((note) => note.startBeat >= from - _chunkS3QELJUEcjs.BEAT_EPS && note.startBeat < to - _chunkS3QELJUEcjs.BEAT_EPS);
|
|
1227
1310
|
let comparisons = 0;
|
|
1228
1311
|
for (const slice of slices) {
|
|
1229
1312
|
const beat = slice.startBeat;
|
|
1230
|
-
if (beat - windowBeats < spanStart -
|
|
1313
|
+
if (beat - windowBeats < spanStart - _chunkS3QELJUEcjs.BEAT_EPS || beat + windowBeats > spanEnd + _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1231
1314
|
continue;
|
|
1232
1315
|
}
|
|
1233
1316
|
const before = onsetsIn(beat - windowBeats, beat);
|
|
@@ -1236,8 +1319,8 @@ function repetitionBoundaries(boundaries, notes, meters, spanStart, spanEnd, win
|
|
|
1236
1319
|
continue;
|
|
1237
1320
|
}
|
|
1238
1321
|
comparisons += before.length * after.length;
|
|
1239
|
-
|
|
1240
|
-
const similarity =
|
|
1322
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, comparisons, "form repetition melody comparisons", budget);
|
|
1323
|
+
const similarity = _chunkLQZQDBCDcjs.melodicSimilarity.call(void 0, before, after);
|
|
1241
1324
|
if (similarity >= REPETITION_THRESHOLD) {
|
|
1242
1325
|
addSignal(boundaries, beat, "repetition", REPETITION_STRENGTH * similarity);
|
|
1243
1326
|
}
|
|
@@ -1253,7 +1336,7 @@ function structuralWeightOf(cadence, confidence, aligned, isLast) {
|
|
|
1253
1336
|
if (result.strength === "perfect") {
|
|
1254
1337
|
base = 1;
|
|
1255
1338
|
} else if (result.strength === "imperfect") {
|
|
1256
|
-
base *=
|
|
1339
|
+
base *= IMPERFECT_CLOSURE_FACTOR;
|
|
1257
1340
|
}
|
|
1258
1341
|
}
|
|
1259
1342
|
if (result.evaded) {
|
|
@@ -1266,7 +1349,7 @@ function structuralWeightOf(cadence, confidence, aligned, isLast) {
|
|
|
1266
1349
|
if (aligned) {
|
|
1267
1350
|
weight += HYPERMETRIC_CLOSE_BONUS;
|
|
1268
1351
|
}
|
|
1269
|
-
return
|
|
1352
|
+
return _chunkLQZQDBCDcjs.clamp01.call(void 0, weight);
|
|
1270
1353
|
}
|
|
1271
1354
|
function describeCadence(cadence) {
|
|
1272
1355
|
if (cadence === null || cadence.cadence.type === null) {
|
|
@@ -1277,72 +1360,61 @@ function describeCadence(cadence) {
|
|
|
1277
1360
|
return `a ${graded} cadence at beat ${cadence.atBeat}`;
|
|
1278
1361
|
}
|
|
1279
1362
|
function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
1280
|
-
|
|
1281
|
-
const meters =
|
|
1282
|
-
|
|
1363
|
+
_chunkLQZQDBCDcjs.assertChordTimeline.call(void 0, timeline);
|
|
1364
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, opts, "phrase meters");
|
|
1365
|
+
_chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, "phrase notes", {
|
|
1283
1366
|
allowNonPositiveDuration: true,
|
|
1284
1367
|
budget: opts.budget
|
|
1285
1368
|
});
|
|
1286
1369
|
if (opts.hypermeter !== void 0) {
|
|
1287
|
-
|
|
1288
|
-
|
|
1370
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, opts.hypermeter.confidence, 0, 1, "phrase hypermeter confidence");
|
|
1371
|
+
_chunkS3QELJUEcjs.assertPositiveInt.call(void 0, opts.hypermeter.groupBars, "phrase hypermeter groupBars");
|
|
1289
1372
|
}
|
|
1290
1373
|
const sounding = notes.filter((note) => note.durationBeat > 0);
|
|
1291
1374
|
const segments = timeline.segments;
|
|
1292
1375
|
const firstSegment = segments[0];
|
|
1293
1376
|
const lastSegment = segments[segments.length - 1];
|
|
1294
|
-
const
|
|
1295
|
-
(
|
|
1296
|
-
_nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess', _44 => _44.startBeat]), () => (
|
|
1377
|
+
const earliest = Math.min(
|
|
1378
|
+
_chunkLQZQDBCDcjs.firstSoundingBeat.call(void 0, sounding, Number.POSITIVE_INFINITY),
|
|
1379
|
+
_nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess', _44 => _44.startBeat]), () => ( Number.POSITIVE_INFINITY))
|
|
1297
1380
|
);
|
|
1298
|
-
const
|
|
1299
|
-
const
|
|
1300
|
-
|
|
1301
|
-
_nullishCoalesce(_optionalChain([lastSegment, 'optionalAccess', _45 => _45.endBeat]), () => (
|
|
1381
|
+
const firstOnset = Number.isFinite(earliest) ? earliest : 0;
|
|
1382
|
+
const spanStart = _chunkLQZQDBCDcjs.barGridStart.call(void 0, firstOnset, meters);
|
|
1383
|
+
const latestEnd = Math.max(
|
|
1384
|
+
_nullishCoalesce(_optionalChain([lastSegment, 'optionalAccess', _45 => _45.endBeat]), () => ( Number.NEGATIVE_INFINITY)),
|
|
1385
|
+
_chunkLQZQDBCDcjs.latestSoundingEnd.call(void 0, sounding, Number.NEGATIVE_INFINITY)
|
|
1302
1386
|
);
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
if (spanEnd <= spanStart +
|
|
1387
|
+
const notesEnd = Number.isFinite(latestEnd) ? latestEnd : 0;
|
|
1388
|
+
const spanEnd = _chunkLQZQDBCDcjs.resolveSpanEnd.call(void 0, opts.totalBeats, spanStart, notesEnd, "phrase totalBeats");
|
|
1389
|
+
if (spanEnd <= spanStart + _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1306
1390
|
return [];
|
|
1307
1391
|
}
|
|
1308
|
-
const barBeats =
|
|
1392
|
+
const barBeats = _chunkS3QELJUEcjs.beatsPerBarAt.call(void 0, Math.max(0, spanStart), meters);
|
|
1309
1393
|
const restBeats = _nullishCoalesce(opts.restBeats, () => ( barBeats / 2));
|
|
1310
|
-
|
|
1394
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, restBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase restBeats");
|
|
1311
1395
|
const longNoteBeats = _nullishCoalesce(opts.longNoteBeats, () => ( barBeats));
|
|
1312
|
-
|
|
1396
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, longNoteBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase longNoteBeats");
|
|
1313
1397
|
const minPhraseBeats = _nullishCoalesce(opts.minPhraseBeats, () => ( barBeats));
|
|
1314
|
-
|
|
1315
|
-
const key = keyContextFor(opts,
|
|
1316
|
-
const cadences =
|
|
1317
|
-
const grouping = _nullishCoalesce(opts.hypermeter, () => (
|
|
1318
|
-
|
|
1319
|
-
cadenceBeats: cadences.map((hit) => hit.atBeat),
|
|
1320
|
-
budget: opts.budget
|
|
1321
|
-
})));
|
|
1322
|
-
const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, Math.max(0, spanStart), meters);
|
|
1398
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, minPhraseBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase minPhraseBeats");
|
|
1399
|
+
const key = keyContextFor(opts.key, timeline, meters, spanEnd, opts.budget);
|
|
1400
|
+
const { hits: cadences, spans } = boundaryCadences(timeline, key);
|
|
1401
|
+
const grouping = _nullishCoalesce(opts.hypermeter, () => ( hypermeterOver(sounding, meters, { totalBeats: spanEnd, budget: opts.budget }, () => spans)));
|
|
1402
|
+
const firstBar = _chunkS3QELJUEcjs.barIndexAt.call(void 0, Math.max(0, spanStart), meters);
|
|
1323
1403
|
const hyperBeats = Math.max(
|
|
1324
1404
|
barBeats,
|
|
1325
|
-
|
|
1405
|
+
_chunkS3QELJUEcjs.barPositionToBeat.call(void 0, { bar: firstBar + grouping.groupBars, beat: 0 }, meters) - _chunkS3QELJUEcjs.barPositionToBeat.call(void 0, { bar: firstBar, beat: 0 }, meters)
|
|
1326
1406
|
);
|
|
1327
1407
|
const expected = _nullishCoalesce(opts.expectedPhraseBeats, () => ( hyperBeats));
|
|
1328
|
-
|
|
1408
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, expected, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase expectedPhraseBeats");
|
|
1329
1409
|
const boundaries = /* @__PURE__ */ new Map();
|
|
1330
|
-
|
|
1331
|
-
const
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
const strength = CADENCE_BOUNDARY_STRENGTH[type];
|
|
1336
|
-
const chordEnd = arrivalEnd(timeline, hit.atBeat);
|
|
1337
|
-
addSignal(boundaries, chordEnd, "cadence", strength, hit);
|
|
1338
|
-
const barEnd = _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: _chunkS5BKZZGMcjs.barIndexAt.call(void 0, hit.atBeat, meters) + 1, beat: 0 }, meters);
|
|
1339
|
-
if (chordEnd > barEnd + _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1340
|
-
addSignal(boundaries, barEnd, "cadence", strength, hit);
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1410
|
+
cadences.forEach((hit, index) => {
|
|
1411
|
+
const span = spans[index];
|
|
1412
|
+
addSignal(boundaries, span.endBeat, "cadence", span.strength, hit);
|
|
1413
|
+
heldCadenceBoundaries(boundaries, hit, span, meters, spanEnd);
|
|
1414
|
+
});
|
|
1343
1415
|
restBoundaries(boundaries, sounding, meters, restBeats);
|
|
1344
1416
|
for (const note of sounding) {
|
|
1345
|
-
if (note.durationBeat >= longNoteBeats -
|
|
1417
|
+
if (note.durationBeat >= longNoteBeats - _chunkS3QELJUEcjs.BEAT_EPS) {
|
|
1346
1418
|
addSignal(boundaries, note.startBeat + note.durationBeat, "longNote", LONG_NOTE_STRENGTH);
|
|
1347
1419
|
}
|
|
1348
1420
|
}
|
|
@@ -1352,9 +1424,9 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1352
1424
|
}
|
|
1353
1425
|
addSignal(boundaries, spanEnd, "pieceEnd", PIECE_END_STRENGTH);
|
|
1354
1426
|
const candidates = [...boundaries.values()].filter(
|
|
1355
|
-
(boundary) => boundary.beat > spanStart +
|
|
1427
|
+
(boundary) => boundary.beat > spanStart + _chunkS3QELJUEcjs.BEAT_EPS && boundary.beat < spanEnd - _chunkS3QELJUEcjs.BEAT_EPS
|
|
1356
1428
|
).filter((boundary) => readBoundary(boundary).strength > 0).sort((a, b) => a.beat - b.beat);
|
|
1357
|
-
const endBoundary = _nullishCoalesce(boundaries.get(Math.round(spanEnd /
|
|
1429
|
+
const endBoundary = _nullishCoalesce(boundaries.get(Math.round(spanEnd / _chunkS3QELJUEcjs.BEAT_EPS)), () => ( {
|
|
1358
1430
|
beat: spanEnd,
|
|
1359
1431
|
strengths: /* @__PURE__ */ new Map(),
|
|
1360
1432
|
cadence: null
|
|
@@ -1364,40 +1436,45 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1364
1436
|
...candidates,
|
|
1365
1437
|
endBoundary
|
|
1366
1438
|
];
|
|
1367
|
-
|
|
1439
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, stops.length * stops.length, "form phrase boundary pairs", opts.budget);
|
|
1368
1440
|
const readings = stops.map(readBoundary);
|
|
1369
1441
|
const path = choosePhrasePath(
|
|
1370
1442
|
stops.map((stop) => stop.beat),
|
|
1371
1443
|
readings.map((reading) => reading.strength),
|
|
1372
1444
|
minPhraseBeats,
|
|
1373
|
-
expected
|
|
1445
|
+
expected,
|
|
1446
|
+
{
|
|
1447
|
+
arrivals: stops.map((stop) => _nullishCoalesce(_optionalChain([stop, 'access', _46 => _46.cadence, 'optionalAccess', _47 => _47.atBeat]), () => ( stop.beat))),
|
|
1448
|
+
uncredited: readings.map((reading) => reading.uncredited)
|
|
1449
|
+
}
|
|
1374
1450
|
);
|
|
1375
1451
|
const downbeatKeys = new Set(
|
|
1376
|
-
grouping.downbeats.map((downbeat) => Math.round(downbeat /
|
|
1452
|
+
grouping.downbeats.map((downbeat) => Math.round(downbeat / _chunkS3QELJUEcjs.BEAT_EPS))
|
|
1377
1453
|
);
|
|
1378
1454
|
const phrases = [];
|
|
1379
1455
|
let from = 0;
|
|
1380
1456
|
for (let n = 0; n < path.length; n += 1) {
|
|
1381
1457
|
const to = _nullishCoalesce(path[n], () => ( stops.length - 1));
|
|
1382
|
-
const startBeat = _nullishCoalesce(_optionalChain([stops, 'access',
|
|
1458
|
+
const startBeat = _nullishCoalesce(_optionalChain([stops, 'access', _48 => _48[from], 'optionalAccess', _49 => _49.beat]), () => ( spanStart));
|
|
1383
1459
|
const stop = stops[to];
|
|
1384
|
-
const endBeat = _nullishCoalesce(_optionalChain([stop, 'optionalAccess',
|
|
1385
|
-
const reading = _nullishCoalesce(readings[to], () => ( { strength: 0, signals: [] }));
|
|
1460
|
+
const endBeat = _nullishCoalesce(_optionalChain([stop, 'optionalAccess', _50 => _50.beat]), () => ( spanEnd));
|
|
1461
|
+
const reading = _nullishCoalesce(readings[to], () => ( { strength: 0, uncredited: 0, signals: [] }));
|
|
1386
1462
|
const length = endBeat - startBeat;
|
|
1387
|
-
const confidence = _chunkIFZDWIKMcjs.clamp01.call(void 0,
|
|
1388
|
-
CLOSING_SHARE * reading.strength + (1 - CLOSING_SHARE) * Math.max(0, lengthFit(length, expected))
|
|
1389
|
-
);
|
|
1390
1463
|
const isLast = n === path.length - 1;
|
|
1391
|
-
const closing = _nullishCoalesce(_optionalChain([stop, 'optionalAccess',
|
|
1392
|
-
const cadence = closing !== null && closing.atBeat
|
|
1464
|
+
const closing = _nullishCoalesce(_optionalChain([stop, 'optionalAccess', _51 => _51.cadence]), () => ( null));
|
|
1465
|
+
const cadence = closing !== null && closesPhrase(closing.atBeat, startBeat, endBeat) ? closing : null;
|
|
1466
|
+
const closingStrength = cadence === null ? reading.uncredited : reading.strength;
|
|
1467
|
+
const confidence = _chunkLQZQDBCDcjs.clamp01.call(void 0,
|
|
1468
|
+
CLOSING_SHARE * closingStrength + (1 - CLOSING_SHARE) * Math.max(0, lengthFit(length, expected))
|
|
1469
|
+
);
|
|
1393
1470
|
const structuralWeight = structuralWeightOf(
|
|
1394
1471
|
cadence,
|
|
1395
1472
|
confidence,
|
|
1396
|
-
downbeatKeys.has(Math.round(endBeat /
|
|
1473
|
+
downbeatKeys.has(Math.round(endBeat / _chunkS3QELJUEcjs.BEAT_EPS)),
|
|
1397
1474
|
isLast
|
|
1398
1475
|
);
|
|
1399
1476
|
const signals = cadence === null ? reading.signals.filter((signal) => signal !== "cadence") : reading.signals;
|
|
1400
|
-
const bars = Math.round(
|
|
1477
|
+
const bars = Math.round(_chunkLQZQDBCDcjs.barSpanOf.call(void 0, startBeat, endBeat, meters) * 100) / 100;
|
|
1401
1478
|
phrases.push({
|
|
1402
1479
|
startBeat,
|
|
1403
1480
|
endBeat,
|
|
@@ -1412,10 +1489,10 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1412
1489
|
return phrases;
|
|
1413
1490
|
}
|
|
1414
1491
|
function structuralCadences(phrases) {
|
|
1415
|
-
|
|
1492
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, phrases, "phrases");
|
|
1416
1493
|
const ranked = [];
|
|
1417
1494
|
for (let index = 0; index < phrases.length; index += 1) {
|
|
1418
|
-
const phrase =
|
|
1495
|
+
const phrase = _chunkS3QELJUEcjs.assertRecord.call(void 0, phrases[index], `phrases[${index}]`);
|
|
1419
1496
|
if (phrase.cadence === null || phrase.cadence === void 0 || phrase.cadence.cadence.type === null) {
|
|
1420
1497
|
continue;
|
|
1421
1498
|
}
|
|
@@ -1449,50 +1526,55 @@ function isSilent(unit) {
|
|
|
1449
1526
|
return unit.notes.length === 0;
|
|
1450
1527
|
}
|
|
1451
1528
|
function unitSimilarity(a, b) {
|
|
1452
|
-
const harmony =
|
|
1529
|
+
const harmony = _chunkLQZQDBCDcjs.weightSimilarity.call(void 0, a.weights, b.weights);
|
|
1453
1530
|
if (a.notes.length < 2 || b.notes.length < 2) {
|
|
1454
1531
|
return a.notes.length === b.notes.length ? harmony : 0;
|
|
1455
1532
|
}
|
|
1456
|
-
const melody =
|
|
1457
|
-
return
|
|
1533
|
+
const melody = _chunkLQZQDBCDcjs.melodicSimilarity.call(void 0, a.notes, b.notes);
|
|
1534
|
+
return _chunkLQZQDBCDcjs.clamp01.call(void 0, MELODY_SHARE * melody + HARMONY_SHARE * harmony);
|
|
1458
1535
|
}
|
|
1459
1536
|
function sectionsFromNotes(notes, opts = {}) {
|
|
1460
|
-
const meters =
|
|
1461
|
-
|
|
1537
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, opts, "section meters");
|
|
1538
|
+
_chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, "section notes", {
|
|
1462
1539
|
allowNonPositiveDuration: true,
|
|
1463
1540
|
budget: opts.budget
|
|
1464
1541
|
});
|
|
1465
1542
|
const sounding = notes.filter((note) => note.durationBeat > 0);
|
|
1543
|
+
const firstSounding = _chunkLQZQDBCDcjs.firstSoundingBeat.call(void 0, sounding);
|
|
1544
|
+
const firstOnset = _chunkLQZQDBCDcjs.barGridStart.call(void 0, firstSounding, meters);
|
|
1545
|
+
const spanEnd = _chunkLQZQDBCDcjs.resolveSpanEnd.call(void 0,
|
|
1546
|
+
opts.totalBeats,
|
|
1547
|
+
firstOnset,
|
|
1548
|
+
_chunkLQZQDBCDcjs.latestSoundingEnd.call(void 0, sounding),
|
|
1549
|
+
"section totalBeats"
|
|
1550
|
+
);
|
|
1466
1551
|
if (sounding.length === 0) {
|
|
1467
1552
|
return [];
|
|
1468
1553
|
}
|
|
1469
|
-
const firstOnset = _chunkIFZDWIKMcjs.barGridStart.call(void 0, _chunkIFZDWIKMcjs.firstSoundingBeat.call(void 0, sounding), meters);
|
|
1470
|
-
const lastEnd = sounding.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
|
|
1471
|
-
const spanEnd = Math.max(firstOnset, _nullishCoalesce(opts.totalBeats, () => ( lastEnd)));
|
|
1472
|
-
_chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "section totalBeats");
|
|
1473
1554
|
const threshold = _nullishCoalesce(opts.threshold, () => ( DEFAULT_THRESHOLD));
|
|
1474
|
-
|
|
1555
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, threshold, 0, 1, "section threshold");
|
|
1475
1556
|
const unitBars = _nullishCoalesce(opts.unitBars, () => ( hypermeter(sounding, meters, { totalBeats: spanEnd, budget: opts.budget }).groupBars));
|
|
1476
|
-
|
|
1477
|
-
const firstBar =
|
|
1478
|
-
const lastBar =
|
|
1557
|
+
_chunkS3QELJUEcjs.assertPositiveInt.call(void 0, unitBars, "section unitBars");
|
|
1558
|
+
const firstBar = _chunkS3QELJUEcjs.barIndexAt.call(void 0, firstOnset, meters);
|
|
1559
|
+
const lastBar = _chunkLQZQDBCDcjs.lastBarOf.call(void 0, meters, firstOnset, spanEnd);
|
|
1479
1560
|
const startBar = Math.max(0, firstBar);
|
|
1480
1561
|
const unitCount = Math.max(1, Math.ceil((lastBar - startBar + 1) / unitBars));
|
|
1481
|
-
|
|
1482
|
-
|
|
1562
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, unitCount * unitCount, "form section comparisons", opts.budget);
|
|
1563
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, unitCount * sounding.length, "form section unit notes", opts.budget);
|
|
1483
1564
|
const units = [];
|
|
1484
1565
|
for (let index = 0; index < unitCount; index += 1) {
|
|
1485
1566
|
const barStart = startBar + index * unitBars;
|
|
1486
|
-
const startBeat = index === 0 ? firstOnset :
|
|
1487
|
-
const endBeat = index === unitCount - 1 ? spanEnd :
|
|
1567
|
+
const startBeat = index === 0 ? firstOnset : _chunkS3QELJUEcjs.barPositionToBeat.call(void 0, { bar: barStart, beat: 0 }, meters);
|
|
1568
|
+
const endBeat = index === unitCount - 1 ? spanEnd : _chunkS3QELJUEcjs.barPositionToBeat.call(void 0, { bar: barStart + unitBars, beat: 0 }, meters);
|
|
1569
|
+
const fromBeat = index === 0 ? Math.min(firstSounding, startBeat) : startBeat;
|
|
1488
1570
|
const unitNotes = sounding.filter(
|
|
1489
|
-
(note) => note.startBeat >=
|
|
1571
|
+
(note) => note.startBeat >= fromBeat - _chunkS3QELJUEcjs.BEAT_EPS && note.startBeat < endBeat - _chunkS3QELJUEcjs.BEAT_EPS
|
|
1490
1572
|
).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
|
|
1491
1573
|
units.push({
|
|
1492
1574
|
startBeat,
|
|
1493
1575
|
endBeat,
|
|
1494
1576
|
notes: unitNotes,
|
|
1495
|
-
weights:
|
|
1577
|
+
weights: _chunkLQZQDBCDcjs.windowWeights.call(void 0, unitNotes, startBeat, endBeat, meters).weights
|
|
1496
1578
|
});
|
|
1497
1579
|
}
|
|
1498
1580
|
let comparisons = 0;
|
|
@@ -1501,7 +1583,7 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
1501
1583
|
comparisons += unit.notes.length * earlierNotes;
|
|
1502
1584
|
earlierNotes += unit.notes.length;
|
|
1503
1585
|
}
|
|
1504
|
-
|
|
1586
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, comparisons, "form section melody comparisons", opts.budget);
|
|
1505
1587
|
const labels = [];
|
|
1506
1588
|
const scores = [];
|
|
1507
1589
|
let distinct = 0;
|
|
@@ -1556,8 +1638,8 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
1556
1638
|
while (end < units.length && labels[end] === null) {
|
|
1557
1639
|
end += 1;
|
|
1558
1640
|
}
|
|
1559
|
-
const startBeat = _nullishCoalesce(_optionalChain([units, 'access',
|
|
1560
|
-
const endBeat = _nullishCoalesce(_optionalChain([units, 'access',
|
|
1641
|
+
const startBeat = _nullishCoalesce(_optionalChain([units, 'access', _52 => _52[index], 'optionalAccess', _53 => _53.startBeat]), () => ( 0));
|
|
1642
|
+
const endBeat = _nullishCoalesce(_optionalChain([units, 'access', _54 => _54[end - 1], 'optionalAccess', _55 => _55.endBeat]), () => ( spanEnd));
|
|
1561
1643
|
const sectionFirstBar = startBar + index * unitBars;
|
|
1562
1644
|
const sectionLastBar = Math.max(
|
|
1563
1645
|
sectionFirstBar,
|
|
@@ -1568,7 +1650,7 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
1568
1650
|
if (first === void 0) {
|
|
1569
1651
|
firstByLabel.set(label, sectionIndex);
|
|
1570
1652
|
}
|
|
1571
|
-
const similarity = first === void 0 ? 1 :
|
|
1653
|
+
const similarity = first === void 0 ? 1 : _chunkLQZQDBCDcjs.clamp01.call(void 0, scoreSum / Math.max(1, sounded));
|
|
1572
1654
|
sections.push({
|
|
1573
1655
|
label,
|
|
1574
1656
|
startBeat,
|
|
@@ -1576,7 +1658,7 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
1576
1658
|
bars: sectionLastBar - sectionFirstBar + 1,
|
|
1577
1659
|
firstOccurrence: _nullishCoalesce(first, () => ( sectionIndex)),
|
|
1578
1660
|
similarity,
|
|
1579
|
-
rationale: first === void 0 ? `Section ${label}: material first heard at beat ${startBeat}` : `Section ${label}: ${Math.round(similarity * 100)}% alike the ${label} at beat ${_nullishCoalesce(_optionalChain([sections, 'access',
|
|
1661
|
+
rationale: first === void 0 ? `Section ${label}: material first heard at beat ${startBeat}` : `Section ${label}: ${Math.round(similarity * 100)}% alike the ${label} at beat ${_nullishCoalesce(_optionalChain([sections, 'access', _56 => _56[first], 'optionalAccess', _57 => _57.startBeat]), () => ( 0))}`
|
|
1580
1662
|
});
|
|
1581
1663
|
index = end;
|
|
1582
1664
|
}
|
|
@@ -1603,51 +1685,51 @@ function rationaleOf(comparison) {
|
|
|
1603
1685
|
return `Most alike: ${describe(highest.slice(0, RATIONALE_FIELDS))}; least alike: ${describe(lowest.slice(0, RATIONALE_FIELDS))}`;
|
|
1604
1686
|
}
|
|
1605
1687
|
function compareReferences(a, b, opts) {
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
const { budget } =
|
|
1688
|
+
_chunkLQZQDBCDcjs.assertReferenceProfile.call(void 0, a, "reference profile a");
|
|
1689
|
+
_chunkLQZQDBCDcjs.assertReferenceProfile.call(void 0, b, "reference profile b");
|
|
1690
|
+
const { budget } = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "compare options");
|
|
1609
1691
|
const structural = (profile) => profile.harmony.chords.filter((chord) => chord.level === "structural");
|
|
1610
|
-
const cadences = (profile) => profile.form.phrases.map((phrase) => _nullishCoalesce(_optionalChain([phrase, 'access',
|
|
1692
|
+
const cadences = (profile) => profile.form.phrases.map((phrase) => _nullishCoalesce(_optionalChain([phrase, 'access', _58 => _58.cadence, 'optionalAccess', _59 => _59.type]), () => ( null)));
|
|
1611
1693
|
const phraseMelodies = (profile) => profile.form.phrases.map((phrase) => phrase.melody);
|
|
1612
1694
|
const comparison = {
|
|
1613
1695
|
form: {
|
|
1614
|
-
sectionSequenceSimilarity:
|
|
1696
|
+
sectionSequenceSimilarity: _chunkLQZQDBCDcjs.sectionSequenceSimilarity.call(void 0,
|
|
1615
1697
|
a.form.sections.map((section) => section.label),
|
|
1616
1698
|
b.form.sections.map((section) => section.label)
|
|
1617
1699
|
),
|
|
1618
|
-
phraseLengthSimilarity:
|
|
1700
|
+
phraseLengthSimilarity: _chunkLQZQDBCDcjs.phraseLengthSimilarity.call(void 0,
|
|
1619
1701
|
a.form.phrases.map((phrase) => phrase.bars),
|
|
1620
1702
|
b.form.phrases.map((phrase) => phrase.bars)
|
|
1621
1703
|
)
|
|
1622
1704
|
},
|
|
1623
1705
|
harmony: {
|
|
1624
|
-
progressionSimilarity:
|
|
1625
|
-
functionSimilarity:
|
|
1626
|
-
cadenceSimilarity:
|
|
1627
|
-
keyPlanSimilarity:
|
|
1706
|
+
progressionSimilarity: _chunkLQZQDBCDcjs.progressionSimilarity.call(void 0, structural(a), structural(b), budget),
|
|
1707
|
+
functionSimilarity: _chunkLQZQDBCDcjs.functionSimilarity.call(void 0, a.harmony.chords, b.harmony.chords),
|
|
1708
|
+
cadenceSimilarity: _chunkLQZQDBCDcjs.cadenceSimilarity.call(void 0, cadences(a), cadences(b)),
|
|
1709
|
+
keyPlanSimilarity: _chunkLQZQDBCDcjs.keyPlanSimilarity.call(void 0,
|
|
1628
1710
|
a.harmony.keys.map((region) => region.key),
|
|
1629
1711
|
b.harmony.keys.map((region) => region.key)
|
|
1630
1712
|
),
|
|
1631
|
-
harmonicRhythmOnsetSimilarity:
|
|
1632
|
-
harmonicRhythmDensitySimilarity:
|
|
1713
|
+
harmonicRhythmOnsetSimilarity: _chunkLQZQDBCDcjs.onsetSimilarity.call(void 0, a.harmony.rhythm, b.harmony.rhythm),
|
|
1714
|
+
harmonicRhythmDensitySimilarity: _chunkLQZQDBCDcjs.densitySimilarity.call(void 0, a.harmony.rhythm, b.harmony.rhythm)
|
|
1633
1715
|
},
|
|
1634
1716
|
melody: {
|
|
1635
|
-
surfaceSimilarity:
|
|
1636
|
-
motifStructureSimilarity:
|
|
1717
|
+
surfaceSimilarity: _chunkLQZQDBCDcjs.surfaceSimilarity.call(void 0, a.melody.motifs, b.melody.motifs),
|
|
1718
|
+
motifStructureSimilarity: _chunkLQZQDBCDcjs.motifStructureSimilarity.call(void 0,
|
|
1637
1719
|
{ graph: a.melody.graph, spanBeats: a.span.endBeat - a.span.startBeat },
|
|
1638
1720
|
{ graph: b.melody.graph, spanBeats: b.span.endBeat - b.span.startBeat }
|
|
1639
1721
|
),
|
|
1640
|
-
contourSimilarity:
|
|
1641
|
-
registerSimilarity:
|
|
1642
|
-
{ phrases: phraseMelodies(a), mean: _nullishCoalesce(_optionalChain([a, 'access',
|
|
1643
|
-
{ phrases: phraseMelodies(b), mean: _nullishCoalesce(_optionalChain([b, 'access',
|
|
1722
|
+
contourSimilarity: _chunkLQZQDBCDcjs.contourSimilarity.call(void 0, phraseMelodies(a), phraseMelodies(b)),
|
|
1723
|
+
registerSimilarity: _chunkLQZQDBCDcjs.registerSimilarity.call(void 0,
|
|
1724
|
+
{ phrases: phraseMelodies(a), mean: _nullishCoalesce(_optionalChain([a, 'access', _60 => _60.melody, 'access', _61 => _61.register, 'optionalAccess', _62 => _62.mean]), () => ( null)) },
|
|
1725
|
+
{ phrases: phraseMelodies(b), mean: _nullishCoalesce(_optionalChain([b, 'access', _63 => _63.melody, 'access', _64 => _64.register, 'optionalAccess', _65 => _65.mean]), () => ( null)) }
|
|
1644
1726
|
)
|
|
1645
1727
|
},
|
|
1646
1728
|
rhythm: {
|
|
1647
|
-
onsetSimilarity:
|
|
1648
|
-
densitySimilarity:
|
|
1649
|
-
durationSimilarity:
|
|
1650
|
-
syncopationSimilarity:
|
|
1729
|
+
onsetSimilarity: _chunkLQZQDBCDcjs.onsetSimilarity.call(void 0, a.melody.rhythm, b.melody.rhythm),
|
|
1730
|
+
densitySimilarity: _chunkLQZQDBCDcjs.densitySimilarity.call(void 0, a.melody.rhythm, b.melody.rhythm),
|
|
1731
|
+
durationSimilarity: _chunkLQZQDBCDcjs.durationSimilarity.call(void 0, a.melody.rhythm, b.melody.rhythm),
|
|
1732
|
+
syncopationSimilarity: _chunkLQZQDBCDcjs.syncopationSimilarity.call(void 0, a.melody.rhythm, b.melody.rhythm)
|
|
1651
1733
|
}
|
|
1652
1734
|
};
|
|
1653
1735
|
return { ...comparison, rationale: rationaleOf(comparison) };
|
|
@@ -1658,19 +1740,20 @@ function spanOf(sounding, timeline, meters, totalBeats) {
|
|
|
1658
1740
|
const segments = timeline.segments;
|
|
1659
1741
|
const firstSegment = segments[0];
|
|
1660
1742
|
const lastSegment = segments[segments.length - 1];
|
|
1661
|
-
const firstOnset =
|
|
1662
|
-
const startBeat =
|
|
1663
|
-
Math.min(firstOnset, _nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess',
|
|
1743
|
+
const firstOnset = _chunkLQZQDBCDcjs.firstSoundingBeat.call(void 0, sounding, _nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess', _66 => _66.startBeat]), () => ( 0)));
|
|
1744
|
+
const startBeat = _chunkLQZQDBCDcjs.barGridStart.call(void 0,
|
|
1745
|
+
Math.min(firstOnset, _nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess', _67 => _67.startBeat]), () => ( firstOnset))),
|
|
1664
1746
|
meters
|
|
1665
1747
|
);
|
|
1666
|
-
const
|
|
1667
|
-
(
|
|
1668
|
-
|
|
1748
|
+
const latestEnd = Math.max(
|
|
1749
|
+
_nullishCoalesce(_optionalChain([lastSegment, 'optionalAccess', _68 => _68.endBeat]), () => ( Number.NEGATIVE_INFINITY)),
|
|
1750
|
+
_chunkLQZQDBCDcjs.latestSoundingEnd.call(void 0, sounding, Number.NEGATIVE_INFINITY)
|
|
1669
1751
|
);
|
|
1752
|
+
const notesEnd = Number.isFinite(latestEnd) ? latestEnd : 0;
|
|
1670
1753
|
return { startBeat, endBeat: Math.max(startBeat, _nullishCoalesce(totalBeats, () => ( notesEnd))) };
|
|
1671
1754
|
}
|
|
1672
1755
|
function sameKey(a, b) {
|
|
1673
|
-
return
|
|
1756
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, a.scale.rootPc) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, b.scale.rootPc) && a.scale.modeMask12 === b.scale.modeMask12;
|
|
1674
1757
|
}
|
|
1675
1758
|
function keyIndexAt(regions, beat, prevailing) {
|
|
1676
1759
|
const holding = regions.findIndex((region) => region.startBeat <= beat && beat < region.endBeat);
|
|
@@ -1684,61 +1767,56 @@ function keyIndexAt(regions, beat, prevailing) {
|
|
|
1684
1767
|
}
|
|
1685
1768
|
function sectionAt(sections, beat) {
|
|
1686
1769
|
const index = sections.findIndex(
|
|
1687
|
-
(section) => beat >= section.startBeat -
|
|
1770
|
+
(section) => beat >= section.startBeat - _chunkS3QELJUEcjs.BEAT_EPS && beat < section.endBeat - _chunkS3QELJUEcjs.BEAT_EPS
|
|
1688
1771
|
);
|
|
1689
1772
|
return index < 0 ? null : index;
|
|
1690
1773
|
}
|
|
1691
1774
|
function readingsFor(notes, opts = {}) {
|
|
1692
|
-
const asked =
|
|
1693
|
-
const meters =
|
|
1775
|
+
const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "reference options");
|
|
1776
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, asked, "reference meters");
|
|
1694
1777
|
const budget = asked.budget;
|
|
1695
1778
|
if (asked.timeline === void 0) {
|
|
1696
|
-
return
|
|
1779
|
+
return _chunkLQZQDBCDcjs.chordTimelineFromNotes.call(void 0, notes, {
|
|
1697
1780
|
meters,
|
|
1698
1781
|
key: asked.key,
|
|
1699
1782
|
totalBeats: asked.totalBeats,
|
|
1700
1783
|
budget
|
|
1701
1784
|
});
|
|
1702
1785
|
}
|
|
1703
|
-
const timeline =
|
|
1786
|
+
const timeline = _chunkLQZQDBCDcjs.assertChordTimeline.call(void 0, asked.timeline, "reference timeline");
|
|
1704
1787
|
let keys;
|
|
1705
1788
|
if (asked.key === void 0) {
|
|
1706
|
-
keys =
|
|
1789
|
+
keys = _chunkLQZQDBCDcjs.keyTimelineFromNotes.call(void 0, notes, { meters, totalBeats: asked.totalBeats, budget });
|
|
1707
1790
|
} else {
|
|
1708
|
-
const sounding =
|
|
1791
|
+
const sounding = _chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, "reference notes", {
|
|
1709
1792
|
allowNonPositiveDuration: true,
|
|
1710
1793
|
budget
|
|
1711
1794
|
}).filter((note) => note.durationBeat > 0);
|
|
1712
1795
|
const span = spanOf(sounding, timeline, meters, asked.totalBeats);
|
|
1713
|
-
keys =
|
|
1714
|
-
{
|
|
1715
|
-
startBeat: span.startBeat,
|
|
1716
|
-
endBeat: span.endBeat,
|
|
1717
|
-
key: _chunk3R3QVKY5cjs.resolveKey.call(void 0, asked.key),
|
|
1718
|
-
confidence: 1
|
|
1719
|
-
}
|
|
1720
|
-
];
|
|
1796
|
+
keys = _chunkLQZQDBCDcjs.statedKeyRegions.call(void 0, _chunkYDGMWH43cjs.resolveKey.call(void 0, asked.key), span.startBeat, span.endBeat);
|
|
1721
1797
|
}
|
|
1722
|
-
return { timeline, keys, prevailingKey: _nullishCoalesce(
|
|
1798
|
+
return { timeline, keys, prevailingKey: _nullishCoalesce(_chunkLQZQDBCDcjs.prevailingKeyOf.call(void 0, keys), () => ( _chunkYDGMWH43cjs.resolveKey.call(void 0, _chunkYDGMWH43cjs.majorKey.call(void 0, 0)))) };
|
|
1723
1799
|
}
|
|
1724
1800
|
function referenceFromReadings(notes, readings, opts = {}) {
|
|
1725
|
-
const asked =
|
|
1726
|
-
const meters =
|
|
1801
|
+
const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "reference options");
|
|
1802
|
+
const meters = _chunkS3QELJUEcjs.resolveMeters.call(void 0, asked, "reference meters");
|
|
1727
1803
|
const budget = asked.budget;
|
|
1728
|
-
const sounding =
|
|
1804
|
+
const sounding = _chunkS3QELJUEcjs.assertNoteEvents.call(void 0, notes, "reference notes", {
|
|
1729
1805
|
allowNonPositiveDuration: true,
|
|
1730
1806
|
budget
|
|
1731
1807
|
}).filter((note) => note.durationBeat > 0);
|
|
1732
1808
|
if (asked.totalBeats !== void 0) {
|
|
1733
|
-
|
|
1809
|
+
_chunkS3QELJUEcjs.assertRange.call(void 0, asked.totalBeats, 0, Number.MAX_SAFE_INTEGER, "reference totalBeats");
|
|
1734
1810
|
}
|
|
1735
|
-
const line =
|
|
1811
|
+
const line = _chunkLQZQDBCDcjs.orderedNotes.call(void 0, _nullishCoalesce(asked.melody, () => ( notes)), "reference melody", budget).map(
|
|
1812
|
+
(note) => Object.is(note.pitch, -0) ? { ...note, pitch: 0 } : note
|
|
1813
|
+
);
|
|
1736
1814
|
const { timeline, prevailingKey } = readings;
|
|
1737
1815
|
const span = spanOf(sounding, timeline, meters, asked.totalBeats);
|
|
1738
1816
|
const spanEnd = span.endBeat;
|
|
1739
|
-
const keyAt =
|
|
1740
|
-
const scaleAt = (beat) =>
|
|
1741
|
-
const cadenceBeats =
|
|
1817
|
+
const keyAt = _chunkLQZQDBCDcjs.keyLookup.call(void 0, readings.keys, prevailingKey);
|
|
1818
|
+
const scaleAt = (beat) => _chunkYDGMWH43cjs.scaleOf.call(void 0, keyAt(beat));
|
|
1819
|
+
const cadenceBeats = _chunkLQZQDBCDcjs.detectCadences.call(void 0, timeline, scaleAt).map((hit) => hit.atBeat);
|
|
1742
1820
|
const grouping = hypermeter(sounding, meters, { cadenceBeats, totalBeats: spanEnd, budget });
|
|
1743
1821
|
const phrases = phrasesFromTimeline(timeline, notes, {
|
|
1744
1822
|
meters,
|
|
@@ -1768,24 +1846,24 @@ function referenceFromReadings(notes, readings, opts = {}) {
|
|
|
1768
1846
|
{
|
|
1769
1847
|
startBeat: span.startBeat,
|
|
1770
1848
|
endBeat: spanEnd,
|
|
1771
|
-
key:
|
|
1849
|
+
key: _chunkYDGMWH43cjs.resolveKey.call(void 0, prevailingKey),
|
|
1772
1850
|
confidence: 0
|
|
1773
1851
|
}
|
|
1774
1852
|
] : readings.keys.map((region) => ({
|
|
1775
1853
|
startBeat: region.startBeat,
|
|
1776
1854
|
endBeat: region.endBeat,
|
|
1777
|
-
key:
|
|
1855
|
+
key: _chunkYDGMWH43cjs.resolveKey.call(void 0, region.key),
|
|
1778
1856
|
confidence: region.confidence
|
|
1779
1857
|
}));
|
|
1780
|
-
const chords =
|
|
1858
|
+
const chords = _chunkLQZQDBCDcjs.reduceProgression.call(void 0, timeline, scaleAt).map((reduced) => {
|
|
1781
1859
|
const index = keyIndexAt(keys, (reduced.startBeat + reduced.endBeat) / 2, prevailingKey);
|
|
1782
1860
|
const key = keys[index].key;
|
|
1783
1861
|
return {
|
|
1784
1862
|
startBeat: reduced.startBeat,
|
|
1785
1863
|
endBeat: reduced.endBeat,
|
|
1786
1864
|
key: index,
|
|
1787
|
-
roman:
|
|
1788
|
-
function:
|
|
1865
|
+
roman: _chunkLQZQDBCDcjs.chordToRoman.call(void 0, reduced.chord, key),
|
|
1866
|
+
function: _chunkLQZQDBCDcjs.functionOf.call(void 0, reduced.chord, key),
|
|
1789
1867
|
level: reduced.level
|
|
1790
1868
|
};
|
|
1791
1869
|
});
|
|
@@ -1794,19 +1872,19 @@ function referenceFromReadings(notes, readings, opts = {}) {
|
|
|
1794
1872
|
startBeat: segment.startBeat,
|
|
1795
1873
|
durationBeat: segment.endBeat - segment.startBeat
|
|
1796
1874
|
}));
|
|
1797
|
-
const harmonyRhythm =
|
|
1798
|
-
const motifs =
|
|
1799
|
-
const graph =
|
|
1875
|
+
const harmonyRhythm = _chunkLQZQDBCDcjs.analyzeRhythm.call(void 0, chordOnsets, { meters, totalBeats: spanEnd, budget });
|
|
1876
|
+
const motifs = _chunkLQZQDBCDcjs.extractMotifs.call(void 0, line, { budget });
|
|
1877
|
+
const graph = _chunkLQZQDBCDcjs.motifGraph.call(void 0, line, motifs, { key: prevailingKey, budget });
|
|
1800
1878
|
let register = null;
|
|
1801
1879
|
if (line.length > 0) {
|
|
1802
1880
|
const pitches = line.map((note) => note.pitch);
|
|
1803
1881
|
register = {
|
|
1804
1882
|
low: Math.min(...pitches),
|
|
1805
1883
|
high: Math.max(...pitches),
|
|
1806
|
-
mean:
|
|
1884
|
+
mean: _chunkLQZQDBCDcjs.weightedMean.call(void 0, line)
|
|
1807
1885
|
};
|
|
1808
1886
|
}
|
|
1809
|
-
const lineMean = _nullishCoalesce(_optionalChain([register, 'optionalAccess',
|
|
1887
|
+
const lineMean = _nullishCoalesce(_optionalChain([register, 'optionalAccess', _69 => _69.mean]), () => ( 0));
|
|
1810
1888
|
const referenceMotifs = motifs.map((motif) => {
|
|
1811
1889
|
const first = motif.occurrences[0];
|
|
1812
1890
|
return {
|
|
@@ -1820,21 +1898,21 @@ function referenceFromReadings(notes, readings, opts = {}) {
|
|
|
1820
1898
|
const referencePhrases = phrases.map((phrase, index) => ({
|
|
1821
1899
|
startBeat: phrase.startBeat,
|
|
1822
1900
|
endBeat: phrase.endBeat,
|
|
1823
|
-
bars:
|
|
1901
|
+
bars: _chunkLQZQDBCDcjs.barSpanOf.call(void 0, phrase.startBeat, phrase.endBeat, meters),
|
|
1824
1902
|
section: sectionAt(sections, phrase.startBeat),
|
|
1825
1903
|
confidence: phrase.confidence,
|
|
1826
1904
|
cadence: _nullishCoalesce(cadences.get(index), () => ( null)),
|
|
1827
|
-
melody:
|
|
1905
|
+
melody: _chunkLQZQDBCDcjs.phraseMelody.call(void 0, line, phrase.startBeat, phrase.endBeat, lineMean, meters, budget),
|
|
1828
1906
|
motifNodes: graph.nodes.flatMap(
|
|
1829
|
-
(node, nodeIndex) => node.startBeat >= phrase.startBeat -
|
|
1907
|
+
(node, nodeIndex) => node.startBeat >= phrase.startBeat - _chunkS3QELJUEcjs.BEAT_EPS && node.startBeat < phrase.endBeat - _chunkS3QELJUEcjs.BEAT_EPS ? [nodeIndex] : []
|
|
1830
1908
|
)
|
|
1831
1909
|
}));
|
|
1832
1910
|
return {
|
|
1833
|
-
profileVersion:
|
|
1911
|
+
profileVersion: _chunkLQZQDBCDcjs.REFERENCE_PROFILE_VERSION,
|
|
1834
1912
|
span: {
|
|
1835
1913
|
startBeat: span.startBeat,
|
|
1836
1914
|
endBeat: spanEnd,
|
|
1837
|
-
bars:
|
|
1915
|
+
bars: _chunkLQZQDBCDcjs.barSpanOf.call(void 0, span.startBeat, spanEnd, meters)
|
|
1838
1916
|
},
|
|
1839
1917
|
meters,
|
|
1840
1918
|
form: {
|
|
@@ -1845,10 +1923,10 @@ function referenceFromReadings(notes, readings, opts = {}) {
|
|
|
1845
1923
|
harmony: { keys, chords, rhythm: harmonyRhythm },
|
|
1846
1924
|
melody: {
|
|
1847
1925
|
register,
|
|
1848
|
-
shape: line.length < 2 ? null :
|
|
1926
|
+
shape: line.length < 2 ? null : _chunkLQZQDBCDcjs.melodicContour.call(void 0, line).shape,
|
|
1849
1927
|
motifs: referenceMotifs,
|
|
1850
1928
|
graph,
|
|
1851
|
-
rhythm:
|
|
1929
|
+
rhythm: _chunkLQZQDBCDcjs.rhythmOver.call(void 0, line, { meters, totalBeats: spanEnd, budget }, span.startBeat)
|
|
1852
1930
|
}
|
|
1853
1931
|
};
|
|
1854
1932
|
}
|
|
@@ -1870,5 +1948,11 @@ function analyzeReference(notes, opts) {
|
|
|
1870
1948
|
|
|
1871
1949
|
|
|
1872
1950
|
|
|
1873
|
-
|
|
1874
|
-
|
|
1951
|
+
|
|
1952
|
+
|
|
1953
|
+
|
|
1954
|
+
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
exports.trackRoleOf = trackRoleOf; exports.arrangementProfile = arrangementProfile; exports.assertTrackNotes = assertTrackNotes; exports.harmonyTrackSet = harmonyTrackSet; exports.analyzePolyphony = analyzePolyphony; exports.analyzeArrangement = analyzeArrangement; exports.createArrangementSession = createArrangementSession; exports.tensionCurve = tensionCurve; exports.tensionCurveFrom = tensionCurveFrom; exports.hypermeter = hypermeter; exports.hypermeterOver = hypermeterOver; exports.boundaryCadences = boundaryCadences; exports.keyContextFor = keyContextFor; exports.phrasesFromTimeline = phrasesFromTimeline; exports.structuralCadences = structuralCadences; exports.sectionsFromNotes = sectionsFromNotes; exports.compareReferences = compareReferences; exports.referenceFromReadings = referenceFromReadings; exports.analyzeReference = analyzeReference;
|
|
1958
|
+
//# sourceMappingURL=chunk-3MDOEFIQ.cjs.map
|