@libraz/libcantus 1.1.0 → 1.2.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/dist/analyze/index.cjs +7 -7
- package/dist/analyze/index.d.cts +8 -8
- package/dist/analyze/index.d.ts +8 -8
- package/dist/analyze/index.js +6 -6
- package/dist/{chunk-TT6PKMPR.cjs → chunk-35NBV2FT.cjs} +16 -16
- package/dist/{chunk-TT6PKMPR.cjs.map → chunk-35NBV2FT.cjs.map} +1 -1
- package/dist/{chunk-YPB3A3EY.cjs → chunk-3R3QVKY5.cjs} +314 -285
- package/dist/chunk-3R3QVKY5.cjs.map +1 -0
- package/dist/{chunk-RVS4G4MR.cjs → chunk-76ZBTRG2.cjs} +198 -198
- package/dist/{chunk-RVS4G4MR.cjs.map → chunk-76ZBTRG2.cjs.map} +1 -1
- package/dist/{chunk-X6RJAHII.js → chunk-7KG3RTYS.js} +2 -2
- package/dist/{chunk-PQL7E5F6.js → chunk-AGOVW7U6.js} +1 -1
- package/dist/{chunk-PQL7E5F6.js.map → chunk-AGOVW7U6.js.map} +1 -1
- package/dist/{chunk-J772DL3B.cjs → chunk-CGBADIO5.cjs} +53 -53
- package/dist/{chunk-J772DL3B.cjs.map → chunk-CGBADIO5.cjs.map} +1 -1
- package/dist/{chunk-GDKE6RQW.cjs → chunk-DSMJRXCZ.cjs} +402 -401
- package/dist/chunk-DSMJRXCZ.cjs.map +1 -0
- package/dist/{chunk-DKICR7AN.js → chunk-FBH75DAY.js} +13 -12
- package/dist/{chunk-DKICR7AN.js.map → chunk-FBH75DAY.js.map} +1 -1
- package/dist/{chunk-VLE5R7PF.js → chunk-H2KJHBW4.js} +4 -4
- package/dist/{chunk-XVMJO3QF.cjs → chunk-HPVSH7SF.cjs} +237 -215
- package/dist/chunk-HPVSH7SF.cjs.map +1 -0
- package/dist/{chunk-QCXYKSZS.cjs → chunk-HWHGOVO6.cjs} +19 -19
- package/dist/{chunk-QCXYKSZS.cjs.map → chunk-HWHGOVO6.cjs.map} +1 -1
- package/dist/{chunk-HSY2VQXZ.js → chunk-HYJJ2V2I.js} +32 -10
- package/dist/chunk-HYJJ2V2I.js.map +1 -0
- package/dist/{chunk-5KW7DNCJ.cjs → chunk-J7FHVZII.cjs} +445 -445
- package/dist/{chunk-5KW7DNCJ.cjs.map → chunk-J7FHVZII.cjs.map} +1 -1
- package/dist/{chunk-AWEMD747.js → chunk-M5RYMAFI.js} +3 -3
- package/dist/{chunk-H66ARFU5.js → chunk-NB25P3EH.js} +3 -3
- package/dist/{chunk-57WB2EDF.js → chunk-NFJ4P6ZZ.js} +3 -3
- package/dist/{chunk-5JJ6EHEZ.cjs → chunk-NM7UAMC3.cjs} +62 -62
- package/dist/{chunk-5JJ6EHEZ.cjs.map → chunk-NM7UAMC3.cjs.map} +1 -1
- package/dist/{chunk-R7B5N2JK.cjs → chunk-PM4XJE2Y.cjs} +47 -47
- package/dist/{chunk-R7B5N2JK.cjs.map → chunk-PM4XJE2Y.cjs.map} +1 -1
- package/dist/{chunk-7GOKQJTQ.js → chunk-PUKJP2Z5.js} +2 -2
- package/dist/{chunk-R5VUXQMP.js → chunk-Q6LFSAKV.js} +7 -7
- package/dist/{chunk-FPBZFNCD.js → chunk-RFIBF2RR.js} +47 -18
- package/dist/{chunk-FPBZFNCD.js.map → chunk-RFIBF2RR.js.map} +1 -1
- package/dist/{chunk-XKSO2V5I.cjs → chunk-S5BKZZGM.cjs} +1 -1
- package/dist/{chunk-XKSO2V5I.cjs.map → chunk-S5BKZZGM.cjs.map} +1 -1
- package/dist/{chunk-Q6R3QAZD.cjs → chunk-SGLEQVJH.cjs} +332 -332
- package/dist/{chunk-Q6R3QAZD.cjs.map → chunk-SGLEQVJH.cjs.map} +1 -1
- package/dist/{chunk-HOHFYGKW.js → chunk-UMWZ4ZET.js} +2 -2
- package/dist/{coerce-wwdELNYS.d.ts → coerce-DP0vYu-x.d.ts} +77 -1
- package/dist/{coerce-CJlgULrQ.d.cts → coerce-DRERzdve.d.cts} +77 -1
- package/dist/core/index.cjs +5 -5
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +4 -4
- package/dist/generate/index.cjs +8 -8
- package/dist/generate/index.d.cts +8 -8
- package/dist/generate/index.d.ts +8 -8
- package/dist/generate/index.js +7 -7
- package/dist/{index-BaoKVVhE.d.cts → index-B9QLziDe.d.cts} +2 -2
- package/dist/{index-B3WCj_Hm.d.cts → index-BBWNZS0f.d.cts} +2 -2
- package/dist/{index-CnHQgqNh.d.ts → index-BHIUyjhZ.d.ts} +2 -2
- package/dist/{index-DpC-mDlV.d.ts → index-BJgP97N1.d.ts} +4 -4
- package/dist/{index-CBCP84rv.d.cts → index-BL5N2Oyz.d.cts} +1 -1
- package/dist/{index-D_hzxD8w.d.cts → index-BMweUlm5.d.cts} +3 -0
- package/dist/{index-BzLNkmA7.d.cts → index-BNSM-DSk.d.cts} +4 -4
- package/dist/{index-BUtIf2go.d.ts → index-BRMbPkHE.d.ts} +25 -5
- package/dist/{index-BpWOhkkE.d.ts → index-CJBBiAmU.d.ts} +2 -2
- package/dist/{index-Ci3xyows.d.ts → index-CL4b4gUQ.d.ts} +3 -0
- package/dist/{index-DTsKaPaC.d.cts → index-DGCNKAUr.d.cts} +25 -5
- package/dist/{index-CnIdP4EZ.d.ts → index-Dw2DP7vm.d.ts} +1 -1
- package/dist/index.cjs +13 -13
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +12 -12
- package/dist/{masks-O73Rhj5d.d.ts → masks-Cc7-MzzY.d.ts} +1 -1
- package/dist/{masks-C8TWLFIi.d.cts → masks-pADfTOiD.d.cts} +1 -1
- package/dist/model/index.cjs +12 -12
- package/dist/model/index.d.cts +16 -15
- package/dist/model/index.d.ts +16 -15
- package/dist/model/index.js +11 -11
- package/dist/theory/index.cjs +5 -5
- package/dist/theory/index.d.cts +7 -7
- package/dist/theory/index.d.ts +7 -7
- package/dist/theory/index.js +4 -4
- package/package.json +6 -5
- package/dist/chunk-GDKE6RQW.cjs.map +0 -1
- package/dist/chunk-HSY2VQXZ.js.map +0 -1
- package/dist/chunk-XVMJO3QF.cjs.map +0 -1
- package/dist/chunk-YPB3A3EY.cjs.map +0 -1
- /package/dist/{chunk-X6RJAHII.js.map → chunk-7KG3RTYS.js.map} +0 -0
- /package/dist/{chunk-VLE5R7PF.js.map → chunk-H2KJHBW4.js.map} +0 -0
- /package/dist/{chunk-AWEMD747.js.map → chunk-M5RYMAFI.js.map} +0 -0
- /package/dist/{chunk-H66ARFU5.js.map → chunk-NB25P3EH.js.map} +0 -0
- /package/dist/{chunk-57WB2EDF.js.map → chunk-NFJ4P6ZZ.js.map} +0 -0
- /package/dist/{chunk-7GOKQJTQ.js.map → chunk-PUKJP2Z5.js.map} +0 -0
- /package/dist/{chunk-R5VUXQMP.js.map → chunk-Q6LFSAKV.js.map} +0 -0
- /package/dist/{chunk-HOHFYGKW.js.map → chunk-UMWZ4ZET.js.map} +0 -0
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
var
|
|
33
|
+
var _chunkSGLEQVJHcjs = require('./chunk-SGLEQVJH.cjs');
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
@@ -41,7 +41,7 @@ var _chunkQ6R3QAZDcjs = require('./chunk-Q6R3QAZD.cjs');
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
var
|
|
44
|
+
var _chunk3R3QVKY5cjs = require('./chunk-3R3QVKY5.cjs');
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
|
|
@@ -65,12 +65,12 @@ var _chunkYPB3A3EYcjs = require('./chunk-YPB3A3EY.cjs');
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
var
|
|
68
|
+
var _chunkS5BKZZGMcjs = require('./chunk-S5BKZZGM.cjs');
|
|
69
69
|
|
|
70
70
|
// src/analyze/arrange/internal.ts
|
|
71
71
|
var MAX_LANE_LEAP = 24;
|
|
72
72
|
function covers(note, beat) {
|
|
73
|
-
return beat >= note.startBeat -
|
|
73
|
+
return beat >= note.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && beat < note.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS;
|
|
74
74
|
}
|
|
75
75
|
function isPercussion(role) {
|
|
76
76
|
return role === "drums";
|
|
@@ -84,31 +84,31 @@ var TRACK_ROLE_TABLE = {
|
|
|
84
84
|
};
|
|
85
85
|
var TRACK_ROLES = Object.keys(TRACK_ROLE_TABLE);
|
|
86
86
|
function trackRoleOf(role, name) {
|
|
87
|
-
return role === void 0 ? "other" :
|
|
87
|
+
return role === void 0 ? "other" : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, role, TRACK_ROLES, name);
|
|
88
88
|
}
|
|
89
89
|
var DEFAULT_PROFILE = "pop";
|
|
90
|
-
var SAFETY_PROFILES = Object.keys(
|
|
90
|
+
var SAFETY_PROFILES = Object.keys(_chunk3R3QVKY5cjs.PROFILE_WEIGHTS);
|
|
91
91
|
function arrangementProfile(profile) {
|
|
92
|
-
return
|
|
92
|
+
return _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(profile, () => ( DEFAULT_PROFILE)), SAFETY_PROFILES, "arrangement profile");
|
|
93
93
|
}
|
|
94
94
|
function assertTrackNotes(tracks, options) {
|
|
95
|
-
|
|
95
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, tracks, "arrangement tracks");
|
|
96
96
|
let noteCount = 0;
|
|
97
97
|
for (let index = 0; index < tracks.length; index += 1) {
|
|
98
98
|
const notes = _optionalChain([tracks, 'access', _2 => _2[index], 'optionalAccess', _3 => _3.notes]);
|
|
99
99
|
if (!Array.isArray(notes)) {
|
|
100
|
-
throw new (0,
|
|
100
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
101
101
|
`tracks[${index}].notes must be an array; received ${typeof notes}`
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
_chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, `tracks[${index}].notes`, options);
|
|
105
105
|
noteCount += notes.length;
|
|
106
106
|
}
|
|
107
107
|
return noteCount;
|
|
108
108
|
}
|
|
109
109
|
function assertGivenTimeline(timeline, name) {
|
|
110
110
|
if (timeline !== void 0) {
|
|
111
|
-
|
|
111
|
+
_chunkSGLEQVJHcjs.assertChordTimeline.call(void 0, timeline, name);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
function assertGivenKeys(keys, name) {
|
|
@@ -116,25 +116,25 @@ function assertGivenKeys(keys, name) {
|
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
118
|
if (!Array.isArray(keys)) {
|
|
119
|
-
throw new (0,
|
|
120
|
-
`${name} must be an array of key regions; received ${
|
|
119
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
120
|
+
`${name} must be an array of key regions; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, keys)}`
|
|
121
121
|
);
|
|
122
122
|
}
|
|
123
123
|
for (let index = 0; index < keys.length; index += 1) {
|
|
124
124
|
const region = keys[index];
|
|
125
125
|
if (typeof region !== "object" || region === null) {
|
|
126
|
-
throw new (0,
|
|
127
|
-
`${name}[${index}] must be a key region; received ${
|
|
126
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
127
|
+
`${name}[${index}] must be a key region; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, region)}`
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, region.startBeat, `${name}[${index}].startBeat`);
|
|
131
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, region.endBeat, `${name}[${index}].endBeat`);
|
|
132
132
|
if (region.key === void 0 || region.key === null || typeof region.key !== "string" && typeof region.key !== "object") {
|
|
133
|
-
throw new (0,
|
|
134
|
-
`${name}[${index}].key must name a key; received ${
|
|
133
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
134
|
+
`${name}[${index}].key must name a key; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, region.key)}`
|
|
135
135
|
);
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
_chunk3R3QVKY5cjs.resolveKey.call(void 0, region.key);
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
function harmonyTrackSet(harmonyTracks, tracks, name = "harmonyTracks") {
|
|
@@ -145,16 +145,16 @@ function harmonyTrackSet(harmonyTracks, tracks, name = "harmonyTracks") {
|
|
|
145
145
|
for (let index = 0; index < harmonyTracks.length; index += 1) {
|
|
146
146
|
const value = harmonyTracks[index];
|
|
147
147
|
if (value === void 0 || !Number.isFinite(value)) {
|
|
148
|
-
throw new (0,
|
|
148
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}[${index}] must be a track index; received ${value}`);
|
|
149
149
|
}
|
|
150
150
|
const track = Math.trunc(value);
|
|
151
151
|
if (track < 0 || track >= tracks.length) {
|
|
152
|
-
throw new (0,
|
|
152
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
153
153
|
`${name}[${index}] ${track} is outside the arrangement's ${tracks.length} tracks`
|
|
154
154
|
);
|
|
155
155
|
}
|
|
156
156
|
if (isPercussion(_optionalChain([tracks, 'access', _4 => _4[track], 'optionalAccess', _5 => _5.role]))) {
|
|
157
|
-
throw new (0,
|
|
157
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
158
158
|
`${name}[${index}] ${track} names a percussion track, whose pitches state no harmony`
|
|
159
159
|
);
|
|
160
160
|
}
|
|
@@ -195,7 +195,7 @@ function splitIntoSubVoices(ordered) {
|
|
|
195
195
|
continue;
|
|
196
196
|
}
|
|
197
197
|
const end = last.startBeat + last.durationBeat;
|
|
198
|
-
if (!
|
|
198
|
+
if (!_chunkSGLEQVJHcjs.hasEnded.call(void 0, end, note.startBeat)) {
|
|
199
199
|
continue;
|
|
200
200
|
}
|
|
201
201
|
const distance = Math.abs(last.pitch - note.pitch);
|
|
@@ -216,13 +216,13 @@ function splitIntoSubVoices(ordered) {
|
|
|
216
216
|
for (let start = 0; start < ordered.length; ) {
|
|
217
217
|
const onset = _nullishCoalesce(_optionalChain([ordered, 'access', _13 => _13[start], 'optionalAccess', _14 => _14.startBeat]), () => ( 0));
|
|
218
218
|
let end = start + 1;
|
|
219
|
-
while (end < ordered.length &&
|
|
219
|
+
while (end < ordered.length && _chunkSGLEQVJHcjs.sameInstant.call(void 0, _nullishCoalesce(_optionalChain([ordered, 'access', _15 => _15[end], 'optionalAccess', _16 => _16.startBeat]), () => ( 0)), onset)) {
|
|
220
220
|
end += 1;
|
|
221
221
|
}
|
|
222
222
|
const block = ordered.slice(start, end);
|
|
223
223
|
if (block.length > 1) {
|
|
224
224
|
const freeLanes = lanes.map((lane, index) => ({ index, last: lane[lane.length - 1] })).filter(
|
|
225
|
-
(entry) => entry.last !== void 0 &&
|
|
225
|
+
(entry) => entry.last !== void 0 && _chunkSGLEQVJHcjs.hasEnded.call(void 0, entry.last.startBeat + entry.last.durationBeat, onset)
|
|
226
226
|
).sort((a, b) => a.last.pitch - b.last.pitch);
|
|
227
227
|
const assignment = pairWithFreeLanes(block, freeLanes);
|
|
228
228
|
const taken = new Set(
|
|
@@ -310,7 +310,7 @@ function lastStartingAtOrBefore(sounding, beat) {
|
|
|
310
310
|
let high = sounding.length;
|
|
311
311
|
while (low < high) {
|
|
312
312
|
const middle = Math.floor((low + high) / 2);
|
|
313
|
-
if ((_nullishCoalesce(_optionalChain([sounding, 'access', _22 => _22[middle], 'optionalAccess', _23 => _23.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat +
|
|
313
|
+
if ((_nullishCoalesce(_optionalChain([sounding, 'access', _22 => _22[middle], 'optionalAccess', _23 => _23.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
314
314
|
low = middle + 1;
|
|
315
315
|
} else {
|
|
316
316
|
high = middle;
|
|
@@ -326,8 +326,10 @@ function prepareTracks(tracks) {
|
|
|
326
326
|
const sounding = voice.map((note, i) => {
|
|
327
327
|
const prev = i > 0 ? voice[i - 1] : void 0;
|
|
328
328
|
const prevEnd = prev === void 0 ? void 0 : prev.startBeat + prev.durationBeat;
|
|
329
|
-
const contiguous = prevEnd !== void 0 &&
|
|
329
|
+
const contiguous = prevEnd !== void 0 && _chunkSGLEQVJHcjs.adjacent.call(void 0, prevEnd, note.startBeat);
|
|
330
330
|
return {
|
|
331
|
+
id: note.id,
|
|
332
|
+
originalIndex: note.originalIndex,
|
|
331
333
|
pitch: note.pitch,
|
|
332
334
|
prevPitch: contiguous ? _optionalChain([prev, 'optionalAccess', _24 => _24.pitch]) : void 0,
|
|
333
335
|
startBeat: note.startBeat,
|
|
@@ -357,7 +359,7 @@ function withGivenKeys(result, given) {
|
|
|
357
359
|
if (given === void 0) {
|
|
358
360
|
return result;
|
|
359
361
|
}
|
|
360
|
-
return { ...result, keys: given, prevailingKey: _nullishCoalesce(
|
|
362
|
+
return { ...result, keys: given, prevailingKey: _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, given), () => ( result.prevailingKey)) };
|
|
361
363
|
}
|
|
362
364
|
function callerTimeline(timeline, key, given, pooled, meters, budget) {
|
|
363
365
|
const chartEnd = timeline.segments.reduce((end, segment) => Math.max(end, segment.endBeat), 0);
|
|
@@ -366,15 +368,15 @@ function callerTimeline(timeline, key, given, pooled, meters, budget) {
|
|
|
366
368
|
0
|
|
367
369
|
);
|
|
368
370
|
const totalBeats = Math.max(chartEnd, soundingEnd);
|
|
369
|
-
const { startBeat: musicStart } =
|
|
370
|
-
const keys = _nullishCoalesce(given, () => (
|
|
371
|
-
key !== void 0 ? [{ startBeat: musicStart, endBeat: totalBeats, key:
|
|
371
|
+
const { startBeat: musicStart } = _chunkSGLEQVJHcjs.gridForNotes.call(void 0, pooled, _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, 0, meters));
|
|
372
|
+
const keys = _nullishCoalesce(given, () => ( _chunkSGLEQVJHcjs.attachPivots.call(void 0,
|
|
373
|
+
key !== void 0 ? [{ startBeat: musicStart, endBeat: totalBeats, key: _chunk3R3QVKY5cjs.resolveKey.call(void 0, key), confidence: 1 }] : _chunkSGLEQVJHcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }),
|
|
372
374
|
timeline.segments
|
|
373
375
|
)));
|
|
374
376
|
return {
|
|
375
377
|
timeline,
|
|
376
378
|
keys,
|
|
377
|
-
prevailingKey: _nullishCoalesce(
|
|
379
|
+
prevailingKey: _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, keys), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0)))),
|
|
378
380
|
segmentConfidence: timeline.segments.map(() => 0)
|
|
379
381
|
};
|
|
380
382
|
}
|
|
@@ -391,11 +393,11 @@ function soundingVoicesAt(prepared, beat) {
|
|
|
391
393
|
continue;
|
|
392
394
|
}
|
|
393
395
|
const snap = { pitch: note.pitch };
|
|
394
|
-
const previous =
|
|
396
|
+
const previous = _chunkSGLEQVJHcjs.sameInstant.call(void 0, note.startBeat, beat) ? note.prevPitch : note.pitch;
|
|
395
397
|
if (previous !== void 0) {
|
|
396
398
|
snap.prevPitch = previous;
|
|
397
399
|
}
|
|
398
|
-
out.push({ track: t, voice: v, snapshot: snap });
|
|
400
|
+
out.push({ track: t, voice: v, trackIndex: track.trackIndex, note, snapshot: snap });
|
|
399
401
|
}
|
|
400
402
|
}
|
|
401
403
|
return out;
|
|
@@ -403,14 +405,28 @@ function soundingVoicesAt(prepared, beat) {
|
|
|
403
405
|
function otherVoicesSounding(prepared, excludeTrack, excludeVoice, beat, cache) {
|
|
404
406
|
const sounding = _nullishCoalesce(cache.get(beat), () => ( soundingVoicesAt(prepared, beat)));
|
|
405
407
|
cache.set(beat, sounding);
|
|
406
|
-
return sounding.filter(({ track, voice }) => track !== excludeTrack || voice !== excludeVoice)
|
|
408
|
+
return sounding.filter(({ track, voice }) => track !== excludeTrack || voice !== excludeVoice);
|
|
409
|
+
}
|
|
410
|
+
function conflictPartner(sounding, reasons) {
|
|
411
|
+
const partner = {
|
|
412
|
+
trackIndex: sounding.trackIndex,
|
|
413
|
+
noteId: sounding.note.id,
|
|
414
|
+
reasons
|
|
415
|
+
};
|
|
416
|
+
if (sounding.note.originalIndex !== void 0) {
|
|
417
|
+
partner.originalIndex = sounding.note.originalIndex;
|
|
418
|
+
}
|
|
419
|
+
return partner;
|
|
420
|
+
}
|
|
421
|
+
function snapshotsOf(voices) {
|
|
422
|
+
return voices.map(({ snapshot }) => snapshot);
|
|
407
423
|
}
|
|
408
424
|
function analyzePolyphony(notes, chordAtBeat, key) {
|
|
409
|
-
const passage =
|
|
410
|
-
|
|
425
|
+
const passage = _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "notes", { allowNonPositiveDuration: true });
|
|
426
|
+
_chunkS5BKZZGMcjs.assertFunction.call(void 0, chordAtBeat, "chordAtBeat");
|
|
411
427
|
const prepared = prepareTracks([{ notes: [...passage] }]);
|
|
412
428
|
const track = prepared[0];
|
|
413
|
-
|
|
429
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
|
|
414
430
|
passage.length * (_nullishCoalesce(_optionalChain([track, 'optionalAccess', _29 => _29.voices, 'access', _30 => _30.length]), () => ( 0))),
|
|
415
431
|
"polyphony note-voice comparisons"
|
|
416
432
|
);
|
|
@@ -421,11 +437,11 @@ function analyzePolyphony(notes, chordAtBeat, key) {
|
|
|
421
437
|
if (subVoice === void 0) {
|
|
422
438
|
continue;
|
|
423
439
|
}
|
|
424
|
-
const analyzed =
|
|
440
|
+
const analyzed = _chunkSGLEQVJHcjs.analyzeVoice.call(void 0,
|
|
425
441
|
subVoice.voice,
|
|
426
442
|
chordAtBeat,
|
|
427
443
|
key,
|
|
428
|
-
(beat) => otherVoicesSounding(prepared, 0, v, beat, soundingCache)
|
|
444
|
+
(beat) => snapshotsOf(otherVoicesSounding(prepared, 0, v, beat, soundingCache))
|
|
429
445
|
);
|
|
430
446
|
for (const note of analyzed) {
|
|
431
447
|
if (note.originalIndex !== void 0) {
|
|
@@ -439,7 +455,7 @@ function analyzePolyphony(notes, chordAtBeat, key) {
|
|
|
439
455
|
if (analyzed !== void 0) {
|
|
440
456
|
return analyzed;
|
|
441
457
|
}
|
|
442
|
-
const [only] =
|
|
458
|
+
const [only] = _chunkSGLEQVJHcjs.analyzeVoice.call(void 0, [{ ...note, id: index }], chordAtBeat, key);
|
|
443
459
|
return _nullishCoalesce(only, () => ( {
|
|
444
460
|
noteId: index,
|
|
445
461
|
pitch: note.pitch,
|
|
@@ -454,7 +470,7 @@ function firstSegmentAfter(timeline, beat) {
|
|
|
454
470
|
let high = timeline.segments.length;
|
|
455
471
|
while (low < high) {
|
|
456
472
|
const middle = Math.floor((low + high) / 2);
|
|
457
|
-
if ((_nullishCoalesce(_optionalChain([timeline, 'access', _35 => _35.segments, 'access', _36 => _36[middle], 'optionalAccess', _37 => _37.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat +
|
|
473
|
+
if ((_nullishCoalesce(_optionalChain([timeline, 'access', _35 => _35.segments, 'access', _36 => _36[middle], 'optionalAccess', _37 => _37.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
458
474
|
low = middle + 1;
|
|
459
475
|
} else {
|
|
460
476
|
high = middle;
|
|
@@ -467,7 +483,7 @@ function evaluationBeats(note, timeline) {
|
|
|
467
483
|
const beats = [note.startBeat];
|
|
468
484
|
for (let i = firstSegmentAfter(timeline, note.startBeat); i < timeline.segments.length; i += 1) {
|
|
469
485
|
const start = _optionalChain([timeline, 'access', _38 => _38.segments, 'access', _39 => _39[i], 'optionalAccess', _40 => _40.startBeat]);
|
|
470
|
-
if (start === void 0 || start >= noteEnd -
|
|
486
|
+
if (start === void 0 || start >= noteEnd - _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
471
487
|
break;
|
|
472
488
|
}
|
|
473
489
|
beats.push(start);
|
|
@@ -478,19 +494,19 @@ function analyzeArrangement(tracks, opts = {}) {
|
|
|
478
494
|
return analyzeArrangementWith(tracks, opts).analysis;
|
|
479
495
|
}
|
|
480
496
|
function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
481
|
-
const meters =
|
|
497
|
+
const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "arrangement meters");
|
|
482
498
|
const budget = opts.budget;
|
|
483
499
|
const noteOptions = { allowNonPositiveDuration: true, budget };
|
|
484
500
|
if (opts.pickupBeats !== void 0) {
|
|
485
|
-
|
|
501
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
|
|
486
502
|
noteOptions.minStartBeat = -opts.pickupBeats;
|
|
487
503
|
}
|
|
488
|
-
|
|
489
|
-
|
|
504
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, tracks, "arrangement tracks");
|
|
505
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
|
|
490
506
|
const noteCount = assertTrackNotes(tracks, noteOptions);
|
|
491
|
-
|
|
507
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
|
|
492
508
|
const profile = arrangementProfile(opts.profile);
|
|
493
|
-
const minSeverity = opts.minSeverity === void 0 ? 1 /* Warning */ :
|
|
509
|
+
const minSeverity = opts.minSeverity === void 0 ? 1 /* Warning */ : _chunkS5BKZZGMcjs.assertInteger.call(void 0,
|
|
494
510
|
opts.minSeverity,
|
|
495
511
|
"arrangement minSeverity",
|
|
496
512
|
0 /* Safe */,
|
|
@@ -501,12 +517,12 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
501
517
|
const harmonyTracks = harmonyTrackSet(opts.harmonyTracks, tracks);
|
|
502
518
|
const prepared = prepareTracks(tracks);
|
|
503
519
|
const voiceCount = prepared.reduce((sum, track) => sum + track.voices.length, 0);
|
|
504
|
-
|
|
520
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount * voiceCount, "arrangement note-voice comparisons", budget);
|
|
505
521
|
const pooled = poolNotes(tracks, harmonyTracks);
|
|
506
522
|
let evidence;
|
|
507
523
|
let inferred;
|
|
508
524
|
if (opts.timeline === void 0) {
|
|
509
|
-
const run =
|
|
525
|
+
const run = _chunkSGLEQVJHcjs.analyzeTimeline.call(void 0,
|
|
510
526
|
pooled,
|
|
511
527
|
{
|
|
512
528
|
key: opts.key,
|
|
@@ -524,9 +540,9 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
524
540
|
inferred = callerTimeline(opts.timeline, opts.key, opts.keys, pooled, meters, budget);
|
|
525
541
|
}
|
|
526
542
|
const { timeline, keys, prevailingKey, segmentConfidence } = inferred;
|
|
527
|
-
const keyAt =
|
|
528
|
-
const scaleAt = (beat) =>
|
|
529
|
-
const cadences =
|
|
543
|
+
const keyAt = _chunkSGLEQVJHcjs.keyLookup.call(void 0, keys, prevailingKey);
|
|
544
|
+
const scaleAt = (beat) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat));
|
|
545
|
+
const cadences = _chunkSGLEQVJHcjs.detectCadences.call(void 0, timeline, scaleAt);
|
|
530
546
|
const soundingCache = /* @__PURE__ */ new Map();
|
|
531
547
|
const trackAnalyses = [];
|
|
532
548
|
const conflicts = [];
|
|
@@ -545,11 +561,11 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
545
561
|
if (!subVoice) {
|
|
546
562
|
continue;
|
|
547
563
|
}
|
|
548
|
-
const analyzed =
|
|
564
|
+
const analyzed = _chunkSGLEQVJHcjs.analyzeVoice.call(void 0,
|
|
549
565
|
subVoice.voice,
|
|
550
566
|
timeline.at,
|
|
551
567
|
scaleAt,
|
|
552
|
-
(beat) => otherVoicesSounding(prepared, t, v, beat, soundingCache)
|
|
568
|
+
(beat) => snapshotsOf(otherVoicesSounding(prepared, t, v, beat, soundingCache))
|
|
553
569
|
);
|
|
554
570
|
for (const note of analyzed) {
|
|
555
571
|
notes.push({ ...note, trackIndex: track.trackIndex });
|
|
@@ -562,19 +578,20 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
562
578
|
continue;
|
|
563
579
|
}
|
|
564
580
|
for (const beat of evaluationBeats(note, timeline)) {
|
|
565
|
-
const atOnset =
|
|
581
|
+
const atOnset = _chunkSGLEQVJHcjs.sameInstant.call(void 0, beat, note.startBeat);
|
|
582
|
+
const others = otherVoicesSounding(prepared, t, v, beat, soundingCache);
|
|
566
583
|
const safetyQuery = {
|
|
567
584
|
profile,
|
|
568
585
|
candidatePitch: note.pitch,
|
|
569
586
|
prevPitch: atOnset ? preparedNote.prevPitch : note.pitch,
|
|
570
587
|
chord: timeline.at(beat),
|
|
571
588
|
key: scaleAt(beat),
|
|
572
|
-
otherVoices:
|
|
573
|
-
strongBeat:
|
|
589
|
+
otherVoices: snapshotsOf(others),
|
|
590
|
+
strongBeat: _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, beat, meters)
|
|
574
591
|
};
|
|
575
|
-
let result =
|
|
592
|
+
let result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0, safetyQuery, { suggestions: false });
|
|
576
593
|
if (result.safety !== 0 /* Safe */ && result.safety >= minSeverity) {
|
|
577
|
-
result =
|
|
594
|
+
result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0, safetyQuery, { partners: true });
|
|
578
595
|
const conflict = {
|
|
579
596
|
beat,
|
|
580
597
|
trackName: track.name,
|
|
@@ -597,6 +614,11 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
|
|
|
597
614
|
if (result.suggestions !== void 0) {
|
|
598
615
|
conflict.suggestions = [...result.suggestions];
|
|
599
616
|
}
|
|
617
|
+
if (result.partners !== void 0) {
|
|
618
|
+
conflict.partners = result.partners.map(
|
|
619
|
+
({ index, reasons }) => conflictPartner(others[index], reasons)
|
|
620
|
+
);
|
|
621
|
+
}
|
|
600
622
|
conflicts.push(conflict);
|
|
601
623
|
}
|
|
602
624
|
}
|
|
@@ -682,7 +704,7 @@ function sessionOf(tracks, opts, analysis, evidence) {
|
|
|
682
704
|
tracks,
|
|
683
705
|
analysis,
|
|
684
706
|
update(edits) {
|
|
685
|
-
|
|
707
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, edits.length, "arrangement edits", opts.budget);
|
|
686
708
|
const next = [...tracks];
|
|
687
709
|
let edited = null;
|
|
688
710
|
let reordered = false;
|
|
@@ -693,16 +715,16 @@ function sessionOf(tracks, opts, analysis, evidence) {
|
|
|
693
715
|
}
|
|
694
716
|
const target = next[edit.trackIndex];
|
|
695
717
|
if (target === void 0) {
|
|
696
|
-
throw new (0,
|
|
718
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
697
719
|
`edits[${index}].trackIndex ${edit.trackIndex} is outside the session's ${tracks.length} tracks`
|
|
698
720
|
);
|
|
699
721
|
}
|
|
700
722
|
if (!Array.isArray(edit.notes)) {
|
|
701
|
-
throw new (0,
|
|
723
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
702
724
|
`edits[${index}].notes must be an array; received ${typeof edit.notes}`
|
|
703
725
|
);
|
|
704
726
|
}
|
|
705
|
-
|
|
727
|
+
_chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, edit.notes, `edits[${index}].notes`, {
|
|
706
728
|
allowNonPositiveDuration: true,
|
|
707
729
|
budget: opts.budget
|
|
708
730
|
});
|
|
@@ -713,7 +735,7 @@ function sessionOf(tracks, opts, analysis, evidence) {
|
|
|
713
735
|
if (edited === null && !reordered) {
|
|
714
736
|
return sessionOf(next, opts, analysis, evidence);
|
|
715
737
|
}
|
|
716
|
-
const dirty = evidence === void 0 ? void 0 : edited === null ? { from: 0, to: 0 } :
|
|
738
|
+
const dirty = evidence === void 0 ? void 0 : edited === null ? { from: 0, to: 0 } : _chunkSGLEQVJHcjs.dirtySlotsFor.call(void 0, evidence, edited.startBeat, edited.endBeat);
|
|
717
739
|
const run = analyzeArrangementWith(next, opts, evidence, dirty);
|
|
718
740
|
return sessionOf(next, opts, run.analysis, run.evidence);
|
|
719
741
|
}
|
|
@@ -738,22 +760,22 @@ function clamp012(value) {
|
|
|
738
760
|
return Math.min(1, Math.max(0, value));
|
|
739
761
|
}
|
|
740
762
|
function tensionCurve(tracks, opts = {}) {
|
|
741
|
-
const meters =
|
|
763
|
+
const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "arrangement meters");
|
|
742
764
|
const budget = opts.budget;
|
|
743
765
|
const noteOptions = { allowNonPositiveDuration: true, budget };
|
|
744
766
|
if (opts.pickupBeats !== void 0) {
|
|
745
|
-
|
|
767
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
|
|
746
768
|
noteOptions.minStartBeat = -opts.pickupBeats;
|
|
747
769
|
}
|
|
748
|
-
|
|
749
|
-
|
|
770
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, tracks, "arrangement tracks");
|
|
771
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
|
|
750
772
|
const noteCount = assertTrackNotes(tracks, noteOptions);
|
|
751
|
-
|
|
773
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
|
|
752
774
|
const profile = arrangementProfile(opts.profile);
|
|
753
775
|
const step = _nullishCoalesce(opts.step, () => ( 1));
|
|
754
|
-
|
|
776
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, step, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "tension sampling step");
|
|
755
777
|
if (opts.minSeverity !== void 0) {
|
|
756
|
-
|
|
778
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0,
|
|
757
779
|
opts.minSeverity,
|
|
758
780
|
"arrangement minSeverity",
|
|
759
781
|
0 /* Safe */,
|
|
@@ -766,7 +788,7 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
766
788
|
const pooled = poolNotes(tracks, harmonyTracks);
|
|
767
789
|
const all = poolNotes(tracks);
|
|
768
790
|
const totalBeats = all.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
|
|
769
|
-
const { origin: sampleStart, startBeat: musicStart } =
|
|
791
|
+
const { origin: sampleStart, startBeat: musicStart } = _chunkSGLEQVJHcjs.gridForNotes.call(void 0, all, step);
|
|
770
792
|
const suppliedKeys = opts.timeline === void 0 ? void 0 : _nullishCoalesce(opts.keys, () => ( (opts.key !== void 0 ? [
|
|
771
793
|
{
|
|
772
794
|
// The one region a named key holds starts where the music does,
|
|
@@ -774,11 +796,11 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
774
796
|
// a key cannot be in force over beats nothing sounds in.
|
|
775
797
|
startBeat: musicStart,
|
|
776
798
|
endBeat: totalBeats,
|
|
777
|
-
key:
|
|
799
|
+
key: _chunk3R3QVKY5cjs.resolveKey.call(void 0, opts.key),
|
|
778
800
|
confidence: 1
|
|
779
801
|
}
|
|
780
|
-
] :
|
|
781
|
-
const { timeline, keys, prevailingKey } = opts.timeline === void 0 || suppliedKeys === void 0 ?
|
|
802
|
+
] : _chunkSGLEQVJHcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }))));
|
|
803
|
+
const { timeline, keys, prevailingKey } = opts.timeline === void 0 || suppliedKeys === void 0 ? _chunkSGLEQVJHcjs.chordTimelineFromNotes.call(void 0, pooled, {
|
|
782
804
|
key: opts.key,
|
|
783
805
|
meters,
|
|
784
806
|
pickupBeats: opts.pickupBeats,
|
|
@@ -787,16 +809,16 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
787
809
|
}) : {
|
|
788
810
|
timeline: opts.timeline,
|
|
789
811
|
keys: suppliedKeys,
|
|
790
|
-
prevailingKey: _nullishCoalesce(
|
|
812
|
+
prevailingKey: _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, suppliedKeys), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0))))
|
|
791
813
|
};
|
|
792
814
|
const regions = _nullishCoalesce(opts.keys, () => ( keys));
|
|
793
|
-
const keyAt =
|
|
815
|
+
const keyAt = _chunkSGLEQVJHcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, regions), () => ( prevailingKey)));
|
|
794
816
|
const prepared = prepareTracks(tracks);
|
|
795
817
|
const points = [];
|
|
796
|
-
const sampleCount = Math.max(0, Math.ceil((totalBeats - sampleStart) / step -
|
|
797
|
-
|
|
818
|
+
const sampleCount = Math.max(0, Math.ceil((totalBeats - sampleStart) / step - _chunkS5BKZZGMcjs.BEAT_EPS));
|
|
819
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, sampleCount, "tension samples", budget);
|
|
798
820
|
const voiceCount = prepared.reduce((sum, track) => sum + track.voices.length, 0);
|
|
799
|
-
|
|
821
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
|
|
800
822
|
sampleCount * Math.min(128, voiceCount) * voiceCount,
|
|
801
823
|
"tension sample-voice comparisons",
|
|
802
824
|
budget
|
|
@@ -807,14 +829,14 @@ function tensionCurve(tracks, opts = {}) {
|
|
|
807
829
|
beat,
|
|
808
830
|
// The pitch classes alone: tension is scored from what sounds against
|
|
809
831
|
// the tonic, and no reading below here asks how the key is written.
|
|
810
|
-
tension: sampleTension(prepared, timeline,
|
|
832
|
+
tension: sampleTension(prepared, timeline, _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat)), meters, profile, beat)
|
|
811
833
|
});
|
|
812
834
|
}
|
|
813
835
|
return points;
|
|
814
836
|
}
|
|
815
837
|
function tensionCurveFrom(tracks, analysis, opts = {}) {
|
|
816
|
-
const asked =
|
|
817
|
-
const carried = carriedHarmony(
|
|
838
|
+
const asked = _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "opts");
|
|
839
|
+
const carried = carriedHarmony(_chunkS5BKZZGMcjs.assertRecord.call(void 0, analysis, "analysis"), asked);
|
|
818
840
|
return tensionCurve(tracks, { ...carried, ...asked });
|
|
819
841
|
}
|
|
820
842
|
function carriedHarmony(analysis, opts) {
|
|
@@ -848,9 +870,9 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
848
870
|
return 0;
|
|
849
871
|
}
|
|
850
872
|
const chord = timeline.at(beat);
|
|
851
|
-
const functionScore = chord ? FUNCTION_TENSION[
|
|
852
|
-
const chordPcs = chord ? new Set(
|
|
853
|
-
const strongBeat =
|
|
873
|
+
const functionScore = chord ? FUNCTION_TENSION[_chunkSGLEQVJHcjs.functionOf.call(void 0, chord, key)] : 0;
|
|
874
|
+
const chordPcs = chord ? new Set(_chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord)) : null;
|
|
875
|
+
const strongBeat = _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, beat, meters);
|
|
854
876
|
let nonChord = 0;
|
|
855
877
|
let dissonant = 0;
|
|
856
878
|
const pitches = /* @__PURE__ */ new Map();
|
|
@@ -866,7 +888,7 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
866
888
|
}
|
|
867
889
|
}
|
|
868
890
|
for (const [pitch, count] of pitches) {
|
|
869
|
-
if (chordPcs && !chordPcs.has(
|
|
891
|
+
if (chordPcs && !chordPcs.has(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch))) {
|
|
870
892
|
nonChord += count;
|
|
871
893
|
}
|
|
872
894
|
const at = _nullishCoalesce(firstOf.get(pitch), () => ( 0));
|
|
@@ -877,7 +899,7 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
|
|
|
877
899
|
others[at] = tail;
|
|
878
900
|
others.pop();
|
|
879
901
|
}
|
|
880
|
-
const result =
|
|
902
|
+
const result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0,
|
|
881
903
|
{ profile, candidatePitch: pitch, chord, key, otherVoices: others, strongBeat },
|
|
882
904
|
{ suggestions: false }
|
|
883
905
|
);
|
|
@@ -928,7 +950,7 @@ function accentContrast(novelty, slices, groupBars, phase) {
|
|
|
928
950
|
continue;
|
|
929
951
|
}
|
|
930
952
|
const value = _nullishCoalesce(novelty[i], () => ( 0));
|
|
931
|
-
if (
|
|
953
|
+
if (_chunkSGLEQVJHcjs.floorMod.call(void 0, slice.index - phase, groupBars) === 0) {
|
|
932
954
|
headSum += value;
|
|
933
955
|
headCount += 1;
|
|
934
956
|
} else {
|
|
@@ -946,7 +968,7 @@ function cadenceFitOf(cadenceBars, slices, groupBars, phase) {
|
|
|
946
968
|
let ends = 0;
|
|
947
969
|
let fit = 0;
|
|
948
970
|
for (const slice of slices) {
|
|
949
|
-
if (slice.index < 0 ||
|
|
971
|
+
if (slice.index < 0 || _chunkSGLEQVJHcjs.floorMod.call(void 0, slice.index - phase, groupBars) !== groupBars - 1) {
|
|
950
972
|
continue;
|
|
951
973
|
}
|
|
952
974
|
ends += 1;
|
|
@@ -956,7 +978,7 @@ function cadenceFitOf(cadenceBars, slices, groupBars, phase) {
|
|
|
956
978
|
fit += ELIDED_FIT;
|
|
957
979
|
}
|
|
958
980
|
}
|
|
959
|
-
return ends === 0 ? 0 :
|
|
981
|
+
return ends === 0 ? 0 : _chunkSGLEQVJHcjs.clamp01.call(void 0, fit / ends);
|
|
960
982
|
}
|
|
961
983
|
function undecidedReading(slices) {
|
|
962
984
|
const fullBars = slices.filter((slice) => slice.index >= 0);
|
|
@@ -970,31 +992,31 @@ function undecidedReading(slices) {
|
|
|
970
992
|
};
|
|
971
993
|
}
|
|
972
994
|
function hypermeter(notes, meter, opts = {}) {
|
|
973
|
-
const asked =
|
|
974
|
-
const meters =
|
|
975
|
-
|
|
995
|
+
const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
996
|
+
const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, { meters: meter }, "meter");
|
|
997
|
+
_chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "hypermeter notes", {
|
|
976
998
|
allowNonPositiveDuration: true,
|
|
977
999
|
budget: asked.budget
|
|
978
1000
|
});
|
|
979
1001
|
const sounding = notes.filter((note) => note.durationBeat > 0);
|
|
980
|
-
const firstOnset =
|
|
1002
|
+
const firstOnset = _chunkSGLEQVJHcjs.firstSoundingBeat.call(void 0, sounding);
|
|
981
1003
|
const lastEnd = sounding.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
|
|
982
1004
|
const spanEnd = _nullishCoalesce(asked.totalBeats, () => ( lastEnd));
|
|
983
|
-
|
|
984
|
-
const spanStart =
|
|
985
|
-
const slices =
|
|
1005
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "hypermeter totalBeats");
|
|
1006
|
+
const spanStart = _chunkSGLEQVJHcjs.barGridStart.call(void 0, firstOnset, meters);
|
|
1007
|
+
const slices = _chunkSGLEQVJHcjs.sliceBars.call(void 0, sounding, meters, spanStart, spanEnd, asked.budget);
|
|
986
1008
|
const fullBars = slices.reduce((count, slice) => slice.index >= 0 ? count + 1 : count, 0);
|
|
987
1009
|
const candidates = GROUP_CANDIDATES.filter((groupBars) => fullBars >= groupBars * MIN_GROUPS);
|
|
988
1010
|
if (candidates.length === 0) {
|
|
989
1011
|
return undecidedReading(slices);
|
|
990
1012
|
}
|
|
991
|
-
|
|
1013
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
|
|
992
1014
|
candidates.reduce((sum, groupBars) => sum + groupBars * slices.length, 0),
|
|
993
1015
|
"hypermeter readings",
|
|
994
1016
|
asked.budget
|
|
995
1017
|
);
|
|
996
|
-
const novelty = slices.map((_, index) =>
|
|
997
|
-
const cadenceBars = new Set((_nullishCoalesce(asked.cadenceBeats, () => ( []))).map((beat) =>
|
|
1018
|
+
const novelty = slices.map((_, index) => _chunkSGLEQVJHcjs.harmonicNovelty.call(void 0, slices, index));
|
|
1019
|
+
const cadenceBars = new Set((_nullishCoalesce(asked.cadenceBeats, () => ( []))).map((beat) => _chunkS5BKZZGMcjs.barIndexAt.call(void 0, beat, meters)));
|
|
998
1020
|
const hasCadences = cadenceBars.size > 0;
|
|
999
1021
|
const readings = [];
|
|
1000
1022
|
for (const groupBars of candidates) {
|
|
@@ -1005,17 +1027,17 @@ function hypermeter(notes, meter, opts = {}) {
|
|
|
1005
1027
|
}));
|
|
1006
1028
|
const bestFit = phases.reduce((best2, reading) => Math.max(best2, reading.cadenceFit), 0);
|
|
1007
1029
|
for (const { phase, contrast, cadenceFit } of phases) {
|
|
1008
|
-
if (hasCadences && cadenceFit < bestFit -
|
|
1030
|
+
if (hasCadences && cadenceFit < bestFit - _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1009
1031
|
continue;
|
|
1010
1032
|
}
|
|
1011
|
-
const evidence =
|
|
1033
|
+
const evidence = _chunkSGLEQVJHcjs.clamp01.call(void 0,
|
|
1012
1034
|
hasCadences ? (
|
|
1013
1035
|
// Floored at zero rather than summed raw: group heads that restate
|
|
1014
1036
|
// the harmony their group opened with — the commonest way a phrase
|
|
1015
1037
|
// begins — change less than the bars between them, and a negative
|
|
1016
1038
|
// contrast subtracted from the cadence term would count that
|
|
1017
1039
|
// restatement as evidence against the very phase it confirms.
|
|
1018
|
-
CONTRAST_SHARE *
|
|
1040
|
+
CONTRAST_SHARE * _chunkSGLEQVJHcjs.clamp01.call(void 0, contrast) + CADENCE_SHARE * cadenceFit
|
|
1019
1041
|
) : contrast
|
|
1020
1042
|
);
|
|
1021
1043
|
readings.push({
|
|
@@ -1036,8 +1058,8 @@ function hypermeter(notes, meter, opts = {}) {
|
|
|
1036
1058
|
return undecidedReading(slices);
|
|
1037
1059
|
}
|
|
1038
1060
|
const runnerUp = readings.find((reading) => reading.groupBars !== best.groupBars);
|
|
1039
|
-
const margin = runnerUp === void 0 || best.score <=
|
|
1040
|
-
const downbeats = slices.filter((slice) => slice.index >= 0 &&
|
|
1061
|
+
const margin = runnerUp === void 0 || best.score <= _chunkS5BKZZGMcjs.BEAT_EPS ? 1 : _chunkSGLEQVJHcjs.clamp01.call(void 0, (best.score - runnerUp.score) / best.score);
|
|
1062
|
+
const downbeats = slices.filter((slice) => slice.index >= 0 && _chunkSGLEQVJHcjs.floorMod.call(void 0, slice.index - best.phase, best.groupBars) === 0).map((slice) => slice.startBeat);
|
|
1041
1063
|
const cadencePart = hasCadences ? `${Math.round(best.cadenceFit * 100)}% of group ends closed by a cadence` : "no cadences given";
|
|
1042
1064
|
return {
|
|
1043
1065
|
groupBars: best.groupBars,
|
|
@@ -1047,7 +1069,7 @@ function hypermeter(notes, meter, opts = {}) {
|
|
|
1047
1069
|
// runner-up is nearly always a multiple or a divisor of the winner — four
|
|
1048
1070
|
// bars nest inside eight — and a reading of the same accents at another
|
|
1049
1071
|
// level is weaker counter-evidence than an unrelated rival would be.
|
|
1050
|
-
confidence:
|
|
1072
|
+
confidence: _chunkSGLEQVJHcjs.clamp01.call(void 0, best.evidence * (MARGIN_FLOOR + (1 - MARGIN_FLOOR) * margin)),
|
|
1051
1073
|
rationale: `${best.groupBars}-bar groups from bar ${best.phase}: harmonic change ${Math.round(best.contrast * 100)}% stronger on group heads, ${cadencePart}`
|
|
1052
1074
|
};
|
|
1053
1075
|
}
|
|
@@ -1058,15 +1080,15 @@ function phraseNotes(phrase) {
|
|
|
1058
1080
|
if (Array.isArray(phrase)) {
|
|
1059
1081
|
return phrase;
|
|
1060
1082
|
}
|
|
1061
|
-
return
|
|
1083
|
+
return _chunkS5BKZZGMcjs.assertRecord.call(void 0, phrase, "melodic phrase").notes;
|
|
1062
1084
|
}
|
|
1063
1085
|
function orderedNotes(notes, name, budget) {
|
|
1064
|
-
|
|
1086
|
+
_chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, name, { allowNonPositiveDuration: true, budget });
|
|
1065
1087
|
const sounding = notes.filter((note) => note.durationBeat > 0).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
|
|
1066
1088
|
const line = [];
|
|
1067
1089
|
for (const note of sounding) {
|
|
1068
1090
|
const previous = line[line.length - 1];
|
|
1069
|
-
if (previous !== void 0 && Math.abs(note.startBeat - previous.startBeat) <=
|
|
1091
|
+
if (previous !== void 0 && Math.abs(note.startBeat - previous.startBeat) <= _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1070
1092
|
line[line.length - 1] = note;
|
|
1071
1093
|
continue;
|
|
1072
1094
|
}
|
|
@@ -1101,7 +1123,7 @@ function retrogradeGaps(notes) {
|
|
|
1101
1123
|
}
|
|
1102
1124
|
function rhythmProfile(gaps) {
|
|
1103
1125
|
const unit = _nullishCoalesce(gaps[0], () => ( 0));
|
|
1104
|
-
if (!(unit >
|
|
1126
|
+
if (!(unit > _chunkS5BKZZGMcjs.BEAT_EPS)) {
|
|
1105
1127
|
return gaps.length === 0 ? [] : null;
|
|
1106
1128
|
}
|
|
1107
1129
|
return gaps.map((gap) => Math.round(gap / unit * RHYTHM_GRID) / RHYTHM_GRID);
|
|
@@ -1111,7 +1133,7 @@ function sameNumbers(a, b) {
|
|
|
1111
1133
|
return false;
|
|
1112
1134
|
}
|
|
1113
1135
|
for (let i = 0; i < a.length; i += 1) {
|
|
1114
|
-
if (Math.abs((_nullishCoalesce(a[i], () => ( 0))) - (_nullishCoalesce(b[i], () => ( 0)))) >
|
|
1136
|
+
if (Math.abs((_nullishCoalesce(a[i], () => ( 0))) - (_nullishCoalesce(b[i], () => ( 0)))) > _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1115
1137
|
return false;
|
|
1116
1138
|
}
|
|
1117
1139
|
}
|
|
@@ -1262,12 +1284,12 @@ function motifFromGroup(group, notes) {
|
|
|
1262
1284
|
startBeat: _nullishCoalesce(_optionalChain([statement, 'access', _79 => _79[0], 'optionalAccess', _80 => _80.startBeat]), () => ( 0)),
|
|
1263
1285
|
endBeat: endBeatOf(statement),
|
|
1264
1286
|
transpose: (_nullishCoalesce(_optionalChain([statement, 'access', _81 => _81[0], 'optionalAccess', _82 => _82.pitch]), () => ( 0))) - primePitch,
|
|
1265
|
-
timeRatio: primeSpan >
|
|
1287
|
+
timeRatio: primeSpan > _chunkS5BKZZGMcjs.BEAT_EPS ? span / primeSpan : 1
|
|
1266
1288
|
};
|
|
1267
1289
|
});
|
|
1268
1290
|
const shape = melodicContour(prime).shape;
|
|
1269
1291
|
const transposed = occurrences.some((occurrence) => occurrence.transpose !== 0);
|
|
1270
|
-
const stretched = occurrences.some((occurrence) => Math.abs(occurrence.timeRatio - 1) >
|
|
1292
|
+
const stretched = occurrences.some((occurrence) => Math.abs(occurrence.timeRatio - 1) > _chunkS5BKZZGMcjs.BEAT_EPS);
|
|
1271
1293
|
const detail = [
|
|
1272
1294
|
transposed ? "at more than one pitch level" : "at the same pitch level",
|
|
1273
1295
|
stretched ? "and in more than one set of note values" : ""
|
|
@@ -1281,15 +1303,15 @@ function motifFromGroup(group, notes) {
|
|
|
1281
1303
|
};
|
|
1282
1304
|
}
|
|
1283
1305
|
function extractMotifs(notes, opts = {}) {
|
|
1284
|
-
const asked =
|
|
1285
|
-
const minNotes =
|
|
1286
|
-
const maxNotes =
|
|
1306
|
+
const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
1307
|
+
const minNotes = _chunkS5BKZZGMcjs.assertInteger.call(void 0, _nullishCoalesce(asked.minNotes, () => ( MIN_CELL_NOTES)), "motif minNotes", 2, 64);
|
|
1308
|
+
const maxNotes = _chunkS5BKZZGMcjs.assertInteger.call(void 0, _nullishCoalesce(asked.maxNotes, () => ( MAX_CELL_NOTES)), "motif maxNotes", 2, 64);
|
|
1287
1309
|
if (maxNotes < minNotes) {
|
|
1288
|
-
throw new (0,
|
|
1310
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1289
1311
|
`motif maxNotes must be at least minNotes ${minNotes}; received ${maxNotes}`
|
|
1290
1312
|
);
|
|
1291
1313
|
}
|
|
1292
|
-
const minOccurrences =
|
|
1314
|
+
const minOccurrences = _chunkS5BKZZGMcjs.assertInteger.call(void 0,
|
|
1293
1315
|
_nullishCoalesce(asked.minOccurrences, () => ( MIN_OCCURRENCES)),
|
|
1294
1316
|
"motif minOccurrences",
|
|
1295
1317
|
2
|
|
@@ -1298,7 +1320,7 @@ function extractMotifs(notes, opts = {}) {
|
|
|
1298
1320
|
if (sounding.length < minNotes) {
|
|
1299
1321
|
return [];
|
|
1300
1322
|
}
|
|
1301
|
-
|
|
1323
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
|
|
1302
1324
|
sounding.length * (maxNotes - minNotes + 1),
|
|
1303
1325
|
"motif windows",
|
|
1304
1326
|
asked.budget
|
|
@@ -1345,7 +1367,7 @@ function extractMotifs(notes, opts = {}) {
|
|
|
1345
1367
|
}
|
|
1346
1368
|
}
|
|
1347
1369
|
}
|
|
1348
|
-
|
|
1370
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, comparisons, "motif subsumption comparisons", asked.budget);
|
|
1349
1371
|
if (!covered) {
|
|
1350
1372
|
kept.push(candidate);
|
|
1351
1373
|
let byStart = keptByLength.get(candidate.length);
|
|
@@ -1373,18 +1395,18 @@ function spellingOf(key) {
|
|
|
1373
1395
|
if (key === void 0) {
|
|
1374
1396
|
return "sharp";
|
|
1375
1397
|
}
|
|
1376
|
-
return
|
|
1398
|
+
return _chunk3R3QVKY5cjs.keySignatureFifths.call(void 0, key.tonic, key.scale) < 0 ? "flat" : "sharp";
|
|
1377
1399
|
}
|
|
1378
1400
|
function intervalBetween(from, to, key) {
|
|
1379
1401
|
const spelling = spellingOf(key);
|
|
1380
|
-
return
|
|
1402
|
+
return _chunkS5BKZZGMcjs.spelledInterval.call(void 0, _chunkS5BKZZGMcjs.midiToNote.call(void 0, from, spelling), _chunkS5BKZZGMcjs.midiToNote.call(void 0, to, spelling));
|
|
1381
1403
|
}
|
|
1382
1404
|
function intervalName(interval) {
|
|
1383
1405
|
return `${interval.descending && interval.semitones !== 0 ? "-" : ""}${interval.quality}${interval.number}`;
|
|
1384
1406
|
}
|
|
1385
1407
|
function ladderIndices(notes, key) {
|
|
1386
|
-
const root =
|
|
1387
|
-
const offsets =
|
|
1408
|
+
const root = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
1409
|
+
const offsets = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, key).map((pc) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - root));
|
|
1388
1410
|
if (offsets.length === 0) {
|
|
1389
1411
|
return null;
|
|
1390
1412
|
}
|
|
@@ -1435,15 +1457,15 @@ function totalGap(gaps) {
|
|
|
1435
1457
|
}
|
|
1436
1458
|
function stretchRatio(modelGaps, answerGaps) {
|
|
1437
1459
|
const span = totalGap(modelGaps);
|
|
1438
|
-
return span >
|
|
1460
|
+
return span > _chunkS5BKZZGMcjs.BEAT_EPS ? totalGap(answerGaps) / span : 1;
|
|
1439
1461
|
}
|
|
1440
1462
|
function stretchPhrase(ratio) {
|
|
1441
1463
|
return `note values ${roundTo(ratio, 3)}x the model's`;
|
|
1442
1464
|
}
|
|
1443
1465
|
function relateMotifs(a, b, keyLike) {
|
|
1444
|
-
const key = keyLike === void 0 ? void 0 :
|
|
1445
|
-
const model =
|
|
1446
|
-
const answer =
|
|
1466
|
+
const key = keyLike === void 0 ? void 0 : _chunk3R3QVKY5cjs.resolveKey.call(void 0, keyLike);
|
|
1467
|
+
const model = _chunkS5BKZZGMcjs.assertArray.call(void 0, _chunkS5BKZZGMcjs.assertRecord.call(void 0, a, "a").notes, "a.notes");
|
|
1468
|
+
const answer = _chunkS5BKZZGMcjs.assertArray.call(void 0, _chunkS5BKZZGMcjs.assertRecord.call(void 0, b, "b").notes, "b.notes");
|
|
1447
1469
|
if (model.length === 0 || model.length !== answer.length) {
|
|
1448
1470
|
return null;
|
|
1449
1471
|
}
|
|
@@ -1461,9 +1483,9 @@ function relateMotifs(a, b, keyLike) {
|
|
|
1461
1483
|
const semitones = (_nullishCoalesce(_optionalChain([answer, 'access', _83 => _83[0], 'optionalAccess', _84 => _84.pitch]), () => ( 0))) - (_nullishCoalesce(_optionalChain([model, 'access', _85 => _85[0], 'optionalAccess', _86 => _86.pitch]), () => ( 0)));
|
|
1462
1484
|
const interval = intervalBetween(_nullishCoalesce(_optionalChain([model, 'access', _87 => _87[0], 'optionalAccess', _88 => _88.pitch]), () => ( 0)), _nullishCoalesce(_optionalChain([answer, 'access', _89 => _89[0], 'optionalAccess', _90 => _90.pitch]), () => ( 0)), key);
|
|
1463
1485
|
const gap = (_nullishCoalesce(_optionalChain([answer, 'access', _91 => _91[0], 'optionalAccess', _92 => _92.startBeat]), () => ( 0))) - endBeatOf(model);
|
|
1464
|
-
const sequence = gap >= -
|
|
1486
|
+
const sequence = gap >= -_chunkSGLEQVJHcjs.HUMANIZE_ADJACENCY && gap <= _chunkSGLEQVJHcjs.HUMANIZE_ADJACENCY;
|
|
1465
1487
|
const timeRatio = stretchRatio(modelGaps, answerGaps);
|
|
1466
|
-
const stretched = Math.abs(timeRatio - 1) >
|
|
1488
|
+
const stretched = Math.abs(timeRatio - 1) > _chunkS5BKZZGMcjs.BEAT_EPS;
|
|
1467
1489
|
const shapes = pitchShapes(intervalsOf(model), intervalsOf(answer));
|
|
1468
1490
|
const base = { sequence, semitones, interval, timeRatio };
|
|
1469
1491
|
const backwardBase = { ...base, timeRatio: stretchRatio(retroGaps, answerGaps) };
|
|
@@ -1561,8 +1583,8 @@ function intervalCost(x, y) {
|
|
|
1561
1583
|
return Math.min(1, Math.abs(x - y) / INTERVAL_TOLERANCE);
|
|
1562
1584
|
}
|
|
1563
1585
|
function gapCost(x, y) {
|
|
1564
|
-
if (!(x >
|
|
1565
|
-
return Math.abs(x - y) >
|
|
1586
|
+
if (!(x > _chunkS5BKZZGMcjs.BEAT_EPS) || !(y > _chunkS5BKZZGMcjs.BEAT_EPS)) {
|
|
1587
|
+
return Math.abs(x - y) > _chunkS5BKZZGMcjs.BEAT_EPS ? 1 : 0;
|
|
1566
1588
|
}
|
|
1567
1589
|
return Math.min(1, Math.abs(Math.log2(x / y)));
|
|
1568
1590
|
}
|
|
@@ -1632,7 +1654,7 @@ var SIGNAL_ORDER = [
|
|
|
1632
1654
|
"hypermeter"
|
|
1633
1655
|
];
|
|
1634
1656
|
function addSignal(boundaries, beat, signal, strength, cadence = null) {
|
|
1635
|
-
const key = Math.round(beat /
|
|
1657
|
+
const key = Math.round(beat / _chunkS5BKZZGMcjs.BEAT_EPS);
|
|
1636
1658
|
const existing = boundaries.get(key);
|
|
1637
1659
|
const boundary = _nullishCoalesce(existing, () => ( { beat, strengths: /* @__PURE__ */ new Map(), cadence: null }));
|
|
1638
1660
|
boundary.strengths.set(signal, Math.max(_nullishCoalesce(boundary.strengths.get(signal), () => ( 0)), strength));
|
|
@@ -1646,7 +1668,7 @@ function readBoundary(boundary) {
|
|
|
1646
1668
|
(a, b) => b[1] - a[1] || SIGNAL_ORDER.indexOf(a[0]) - SIGNAL_ORDER.indexOf(b[0])
|
|
1647
1669
|
);
|
|
1648
1670
|
return {
|
|
1649
|
-
strength:
|
|
1671
|
+
strength: _chunkSGLEQVJHcjs.combineEvidence.call(void 0, signals.map(([, strength]) => strength)),
|
|
1650
1672
|
signals: signals.map(([signal]) => signal)
|
|
1651
1673
|
};
|
|
1652
1674
|
}
|
|
@@ -1667,7 +1689,7 @@ function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
|
|
|
1667
1689
|
continue;
|
|
1668
1690
|
}
|
|
1669
1691
|
const length = endBeat - (_nullishCoalesce(beats[i], () => ( 0)));
|
|
1670
|
-
if (length < minPhraseBeats -
|
|
1692
|
+
if (length < minPhraseBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1671
1693
|
continue;
|
|
1672
1694
|
}
|
|
1673
1695
|
const gain = (_nullishCoalesce(value[i], () => ( 0))) + (_nullishCoalesce(strengths[j], () => ( 0))) + lengthFit(length, expected) - PHRASE_CUT_COST;
|
|
@@ -1690,14 +1712,14 @@ function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
|
|
|
1690
1712
|
return path;
|
|
1691
1713
|
}
|
|
1692
1714
|
function arrivalEnd(timeline, atBeat) {
|
|
1693
|
-
return _nullishCoalesce(_optionalChain([
|
|
1715
|
+
return _nullishCoalesce(_optionalChain([_chunkSGLEQVJHcjs.segmentStartingAt.call(void 0, timeline.segments, atBeat), 'optionalAccess', _93 => _93.endBeat]), () => ( atBeat));
|
|
1694
1716
|
}
|
|
1695
1717
|
function barSpanOf(startBeat, endBeat, meters) {
|
|
1696
|
-
const firstBar =
|
|
1697
|
-
const lastBar =
|
|
1718
|
+
const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, startBeat, meters);
|
|
1719
|
+
const lastBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, endBeat, meters);
|
|
1698
1720
|
const partOf = (beat, bar) => {
|
|
1699
|
-
const barStart =
|
|
1700
|
-
const barLength =
|
|
1721
|
+
const barStart = _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar, beat: 0 }, meters);
|
|
1722
|
+
const barLength = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, barStart, meters);
|
|
1701
1723
|
return barLength > 0 ? (beat - barStart) / barLength : 0;
|
|
1702
1724
|
};
|
|
1703
1725
|
const bars = lastBar - firstBar + partOf(endBeat, lastBar) - partOf(startBeat, firstBar);
|
|
@@ -1707,26 +1729,26 @@ function keyContextFor(opts, notes, meters, totalBeats) {
|
|
|
1707
1729
|
if (opts.key !== void 0) {
|
|
1708
1730
|
return opts.key;
|
|
1709
1731
|
}
|
|
1710
|
-
const regions =
|
|
1732
|
+
const regions = _chunkSGLEQVJHcjs.keyTimelineFromNotes.call(void 0, notes, {
|
|
1711
1733
|
meters,
|
|
1712
1734
|
totalBeats,
|
|
1713
1735
|
budget: opts.budget
|
|
1714
1736
|
});
|
|
1715
|
-
const keyAt =
|
|
1716
|
-
return (beat) =>
|
|
1737
|
+
const keyAt = _chunkSGLEQVJHcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, regions), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0)))));
|
|
1738
|
+
return (beat) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat));
|
|
1717
1739
|
}
|
|
1718
1740
|
function restBoundaries(boundaries, notes, meters, restBeats) {
|
|
1719
1741
|
const ordered = [...notes].sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
|
|
1720
1742
|
let covered = Number.NEGATIVE_INFINITY;
|
|
1721
1743
|
for (const note of ordered) {
|
|
1722
1744
|
const gap = note.startBeat - covered;
|
|
1723
|
-
if (Number.isFinite(covered) && gap >= restBeats -
|
|
1724
|
-
const bar =
|
|
1745
|
+
if (Number.isFinite(covered) && gap >= restBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1746
|
+
const bar = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, note.startBeat, meters);
|
|
1725
1747
|
addSignal(
|
|
1726
1748
|
boundaries,
|
|
1727
1749
|
note.startBeat,
|
|
1728
1750
|
"rest",
|
|
1729
|
-
REST_STRENGTH *
|
|
1751
|
+
REST_STRENGTH * _chunkSGLEQVJHcjs.clamp01.call(void 0, bar > 0 ? gap / bar : 1)
|
|
1730
1752
|
);
|
|
1731
1753
|
}
|
|
1732
1754
|
covered = Math.max(covered, note.startBeat + note.durationBeat);
|
|
@@ -1736,13 +1758,13 @@ function repetitionBoundaries(boundaries, notes, meters, spanStart, spanEnd, win
|
|
|
1736
1758
|
if (!(windowBeats > 0)) {
|
|
1737
1759
|
return;
|
|
1738
1760
|
}
|
|
1739
|
-
const slices =
|
|
1740
|
-
|
|
1741
|
-
const onsetsIn = (from, to) => notes.filter((note) => note.startBeat >= from -
|
|
1761
|
+
const slices = _chunkSGLEQVJHcjs.sliceBars.call(void 0, notes, meters, spanStart, spanEnd, budget);
|
|
1762
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, slices.length * notes.length, "form repetition comparisons", budget);
|
|
1763
|
+
const onsetsIn = (from, to) => notes.filter((note) => note.startBeat >= from - _chunkS5BKZZGMcjs.BEAT_EPS && note.startBeat < to - _chunkS5BKZZGMcjs.BEAT_EPS);
|
|
1742
1764
|
let comparisons = 0;
|
|
1743
1765
|
for (const slice of slices) {
|
|
1744
1766
|
const beat = slice.startBeat;
|
|
1745
|
-
if (beat - windowBeats < spanStart -
|
|
1767
|
+
if (beat - windowBeats < spanStart - _chunkS5BKZZGMcjs.BEAT_EPS || beat + windowBeats > spanEnd + _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1746
1768
|
continue;
|
|
1747
1769
|
}
|
|
1748
1770
|
const before = onsetsIn(beat - windowBeats, beat);
|
|
@@ -1751,7 +1773,7 @@ function repetitionBoundaries(boundaries, notes, meters, spanStart, spanEnd, win
|
|
|
1751
1773
|
continue;
|
|
1752
1774
|
}
|
|
1753
1775
|
comparisons += before.length * after.length;
|
|
1754
|
-
|
|
1776
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, comparisons, "form repetition melody comparisons", budget);
|
|
1755
1777
|
const similarity = melodicSimilarity(before, after);
|
|
1756
1778
|
if (similarity >= REPETITION_THRESHOLD) {
|
|
1757
1779
|
addSignal(boundaries, beat, "repetition", REPETITION_STRENGTH * similarity);
|
|
@@ -1781,7 +1803,7 @@ function structuralWeightOf(cadence, confidence, aligned, isLast) {
|
|
|
1781
1803
|
if (aligned) {
|
|
1782
1804
|
weight += HYPERMETRIC_CLOSE_BONUS;
|
|
1783
1805
|
}
|
|
1784
|
-
return
|
|
1806
|
+
return _chunkSGLEQVJHcjs.clamp01.call(void 0, weight);
|
|
1785
1807
|
}
|
|
1786
1808
|
function describeCadence(cadence) {
|
|
1787
1809
|
if (cadence === null || cadence.cadence.type === null) {
|
|
@@ -1792,15 +1814,15 @@ function describeCadence(cadence) {
|
|
|
1792
1814
|
return `a ${graded} cadence at beat ${cadence.atBeat}`;
|
|
1793
1815
|
}
|
|
1794
1816
|
function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
1795
|
-
|
|
1796
|
-
const meters =
|
|
1797
|
-
|
|
1817
|
+
_chunkSGLEQVJHcjs.assertChordTimeline.call(void 0, timeline);
|
|
1818
|
+
const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "phrase meters");
|
|
1819
|
+
_chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "phrase notes", {
|
|
1798
1820
|
allowNonPositiveDuration: true,
|
|
1799
1821
|
budget: opts.budget
|
|
1800
1822
|
});
|
|
1801
1823
|
if (opts.hypermeter !== void 0) {
|
|
1802
|
-
|
|
1803
|
-
|
|
1824
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, opts.hypermeter.confidence, 0, 1, "phrase hypermeter confidence");
|
|
1825
|
+
_chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, opts.hypermeter.groupBars, "phrase hypermeter groupBars");
|
|
1804
1826
|
}
|
|
1805
1827
|
const sounding = notes.filter((note) => note.durationBeat > 0);
|
|
1806
1828
|
const segments = timeline.segments;
|
|
@@ -1810,37 +1832,37 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1810
1832
|
(first, n) => Math.min(first, n.startBeat),
|
|
1811
1833
|
_nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess', _94 => _94.startBeat]), () => ( 0))
|
|
1812
1834
|
);
|
|
1813
|
-
const spanStart =
|
|
1835
|
+
const spanStart = _chunkSGLEQVJHcjs.barGridStart.call(void 0, firstOnset, meters);
|
|
1814
1836
|
const notesEnd = sounding.reduce(
|
|
1815
1837
|
(end, n) => Math.max(end, n.startBeat + n.durationBeat),
|
|
1816
1838
|
_nullishCoalesce(_optionalChain([lastSegment, 'optionalAccess', _95 => _95.endBeat]), () => ( 0))
|
|
1817
1839
|
);
|
|
1818
1840
|
const spanEnd = Math.max(spanStart, _nullishCoalesce(opts.totalBeats, () => ( notesEnd)));
|
|
1819
|
-
|
|
1820
|
-
if (spanEnd <= spanStart +
|
|
1841
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "phrase totalBeats");
|
|
1842
|
+
if (spanEnd <= spanStart + _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1821
1843
|
return [];
|
|
1822
1844
|
}
|
|
1823
|
-
const barBeats =
|
|
1845
|
+
const barBeats = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, Math.max(0, spanStart), meters);
|
|
1824
1846
|
const restBeats = _nullishCoalesce(opts.restBeats, () => ( barBeats / 2));
|
|
1825
|
-
|
|
1847
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, restBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase restBeats");
|
|
1826
1848
|
const longNoteBeats = _nullishCoalesce(opts.longNoteBeats, () => ( barBeats));
|
|
1827
|
-
|
|
1849
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, longNoteBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase longNoteBeats");
|
|
1828
1850
|
const minPhraseBeats = _nullishCoalesce(opts.minPhraseBeats, () => ( barBeats));
|
|
1829
|
-
|
|
1851
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, minPhraseBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase minPhraseBeats");
|
|
1830
1852
|
const key = keyContextFor(opts, sounding, meters, spanEnd);
|
|
1831
|
-
const cadences =
|
|
1853
|
+
const cadences = _chunkSGLEQVJHcjs.detectCadences.call(void 0, timeline, key);
|
|
1832
1854
|
const grouping = _nullishCoalesce(opts.hypermeter, () => ( hypermeter(sounding, meters, {
|
|
1833
1855
|
totalBeats: spanEnd,
|
|
1834
1856
|
cadenceBeats: cadences.map((hit) => hit.atBeat),
|
|
1835
1857
|
budget: opts.budget
|
|
1836
1858
|
})));
|
|
1837
|
-
const firstBar =
|
|
1859
|
+
const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, Math.max(0, spanStart), meters);
|
|
1838
1860
|
const hyperBeats = Math.max(
|
|
1839
1861
|
barBeats,
|
|
1840
|
-
|
|
1862
|
+
_chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: firstBar + grouping.groupBars, beat: 0 }, meters) - _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: firstBar, beat: 0 }, meters)
|
|
1841
1863
|
);
|
|
1842
1864
|
const expected = _nullishCoalesce(opts.expectedPhraseBeats, () => ( hyperBeats));
|
|
1843
|
-
|
|
1865
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, expected, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase expectedPhraseBeats");
|
|
1844
1866
|
const boundaries = /* @__PURE__ */ new Map();
|
|
1845
1867
|
for (const hit of cadences) {
|
|
1846
1868
|
const type = hit.cadence.type;
|
|
@@ -1850,14 +1872,14 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1850
1872
|
const strength = CADENCE_BOUNDARY_STRENGTH[type];
|
|
1851
1873
|
const chordEnd = arrivalEnd(timeline, hit.atBeat);
|
|
1852
1874
|
addSignal(boundaries, chordEnd, "cadence", strength, hit);
|
|
1853
|
-
const barEnd =
|
|
1854
|
-
if (chordEnd > barEnd +
|
|
1875
|
+
const barEnd = _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: _chunkS5BKZZGMcjs.barIndexAt.call(void 0, hit.atBeat, meters) + 1, beat: 0 }, meters);
|
|
1876
|
+
if (chordEnd > barEnd + _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1855
1877
|
addSignal(boundaries, barEnd, "cadence", strength, hit);
|
|
1856
1878
|
}
|
|
1857
1879
|
}
|
|
1858
1880
|
restBoundaries(boundaries, sounding, meters, restBeats);
|
|
1859
1881
|
for (const note of sounding) {
|
|
1860
|
-
if (note.durationBeat >= longNoteBeats -
|
|
1882
|
+
if (note.durationBeat >= longNoteBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
|
|
1861
1883
|
addSignal(boundaries, note.startBeat + note.durationBeat, "longNote", LONG_NOTE_STRENGTH);
|
|
1862
1884
|
}
|
|
1863
1885
|
}
|
|
@@ -1867,9 +1889,9 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1867
1889
|
}
|
|
1868
1890
|
addSignal(boundaries, spanEnd, "pieceEnd", PIECE_END_STRENGTH);
|
|
1869
1891
|
const candidates = [...boundaries.values()].filter(
|
|
1870
|
-
(boundary) => boundary.beat > spanStart +
|
|
1892
|
+
(boundary) => boundary.beat > spanStart + _chunkS5BKZZGMcjs.BEAT_EPS && boundary.beat < spanEnd - _chunkS5BKZZGMcjs.BEAT_EPS
|
|
1871
1893
|
).filter((boundary) => readBoundary(boundary).strength > 0).sort((a, b) => a.beat - b.beat);
|
|
1872
|
-
const endBoundary = _nullishCoalesce(boundaries.get(Math.round(spanEnd /
|
|
1894
|
+
const endBoundary = _nullishCoalesce(boundaries.get(Math.round(spanEnd / _chunkS5BKZZGMcjs.BEAT_EPS)), () => ( {
|
|
1873
1895
|
beat: spanEnd,
|
|
1874
1896
|
strengths: /* @__PURE__ */ new Map(),
|
|
1875
1897
|
cadence: null
|
|
@@ -1879,7 +1901,7 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1879
1901
|
...candidates,
|
|
1880
1902
|
endBoundary
|
|
1881
1903
|
];
|
|
1882
|
-
|
|
1904
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, stops.length * stops.length, "form phrase boundary pairs", opts.budget);
|
|
1883
1905
|
const readings = stops.map(readBoundary);
|
|
1884
1906
|
const path = choosePhrasePath(
|
|
1885
1907
|
stops.map((stop) => stop.beat),
|
|
@@ -1888,7 +1910,7 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1888
1910
|
expected
|
|
1889
1911
|
);
|
|
1890
1912
|
const downbeatKeys = new Set(
|
|
1891
|
-
grouping.downbeats.map((downbeat) => Math.round(downbeat /
|
|
1913
|
+
grouping.downbeats.map((downbeat) => Math.round(downbeat / _chunkS5BKZZGMcjs.BEAT_EPS))
|
|
1892
1914
|
);
|
|
1893
1915
|
const phrases = [];
|
|
1894
1916
|
let from = 0;
|
|
@@ -1899,16 +1921,16 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1899
1921
|
const endBeat = _nullishCoalesce(_optionalChain([stop, 'optionalAccess', _98 => _98.beat]), () => ( spanEnd));
|
|
1900
1922
|
const reading = _nullishCoalesce(readings[to], () => ( { strength: 0, signals: [] }));
|
|
1901
1923
|
const length = endBeat - startBeat;
|
|
1902
|
-
const confidence =
|
|
1924
|
+
const confidence = _chunkSGLEQVJHcjs.clamp01.call(void 0,
|
|
1903
1925
|
CLOSING_SHARE * reading.strength + (1 - CLOSING_SHARE) * Math.max(0, lengthFit(length, expected))
|
|
1904
1926
|
);
|
|
1905
1927
|
const isLast = n === path.length - 1;
|
|
1906
1928
|
const closing = _nullishCoalesce(_optionalChain([stop, 'optionalAccess', _99 => _99.cadence]), () => ( null));
|
|
1907
|
-
const cadence = closing !== null && closing.atBeat >= startBeat -
|
|
1929
|
+
const cadence = closing !== null && closing.atBeat >= startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && closing.atBeat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS ? closing : null;
|
|
1908
1930
|
const structuralWeight = structuralWeightOf(
|
|
1909
1931
|
cadence,
|
|
1910
1932
|
confidence,
|
|
1911
|
-
downbeatKeys.has(Math.round(endBeat /
|
|
1933
|
+
downbeatKeys.has(Math.round(endBeat / _chunkS5BKZZGMcjs.BEAT_EPS)),
|
|
1912
1934
|
isLast
|
|
1913
1935
|
);
|
|
1914
1936
|
const signals = cadence === null ? reading.signals.filter((signal) => signal !== "cadence") : reading.signals;
|
|
@@ -1927,10 +1949,10 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
|
|
|
1927
1949
|
return phrases;
|
|
1928
1950
|
}
|
|
1929
1951
|
function structuralCadences(phrases) {
|
|
1930
|
-
|
|
1952
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, phrases, "phrases");
|
|
1931
1953
|
const ranked = [];
|
|
1932
1954
|
for (let index = 0; index < phrases.length; index += 1) {
|
|
1933
|
-
const phrase =
|
|
1955
|
+
const phrase = _chunkS5BKZZGMcjs.assertRecord.call(void 0, phrases[index], `phrases[${index}]`);
|
|
1934
1956
|
if (phrase.cadence === null || phrase.cadence === void 0 || phrase.cadence.cadence.type === null) {
|
|
1935
1957
|
continue;
|
|
1936
1958
|
}
|
|
@@ -1964,16 +1986,16 @@ function isSilent(unit) {
|
|
|
1964
1986
|
return unit.notes.length === 0;
|
|
1965
1987
|
}
|
|
1966
1988
|
function unitSimilarity(a, b) {
|
|
1967
|
-
const harmony =
|
|
1989
|
+
const harmony = _chunkSGLEQVJHcjs.weightSimilarity.call(void 0, a.weights, b.weights);
|
|
1968
1990
|
if (a.notes.length < 2 || b.notes.length < 2) {
|
|
1969
1991
|
return a.notes.length === b.notes.length ? harmony : 0;
|
|
1970
1992
|
}
|
|
1971
1993
|
const melody = melodicSimilarity(a.notes, b.notes);
|
|
1972
|
-
return
|
|
1994
|
+
return _chunkSGLEQVJHcjs.clamp01.call(void 0, MELODY_SHARE * melody + HARMONY_SHARE * harmony);
|
|
1973
1995
|
}
|
|
1974
1996
|
function sectionsFromNotes(notes, opts = {}) {
|
|
1975
|
-
const meters =
|
|
1976
|
-
|
|
1997
|
+
const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "section meters");
|
|
1998
|
+
_chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "section notes", {
|
|
1977
1999
|
allowNonPositiveDuration: true,
|
|
1978
2000
|
budget: opts.budget
|
|
1979
2001
|
});
|
|
@@ -1981,33 +2003,33 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
1981
2003
|
if (sounding.length === 0) {
|
|
1982
2004
|
return [];
|
|
1983
2005
|
}
|
|
1984
|
-
const firstOnset =
|
|
2006
|
+
const firstOnset = _chunkSGLEQVJHcjs.barGridStart.call(void 0, _chunkSGLEQVJHcjs.firstSoundingBeat.call(void 0, sounding), meters);
|
|
1985
2007
|
const lastEnd = sounding.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
|
|
1986
2008
|
const spanEnd = Math.max(firstOnset, _nullishCoalesce(opts.totalBeats, () => ( lastEnd)));
|
|
1987
|
-
|
|
2009
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "section totalBeats");
|
|
1988
2010
|
const threshold = _nullishCoalesce(opts.threshold, () => ( DEFAULT_THRESHOLD));
|
|
1989
|
-
|
|
2011
|
+
_chunkS5BKZZGMcjs.assertRange.call(void 0, threshold, 0, 1, "section threshold");
|
|
1990
2012
|
const unitBars = _nullishCoalesce(opts.unitBars, () => ( hypermeter(sounding, meters, { totalBeats: spanEnd, budget: opts.budget }).groupBars));
|
|
1991
|
-
|
|
1992
|
-
const firstBar =
|
|
1993
|
-
const lastBar =
|
|
2013
|
+
_chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, unitBars, "section unitBars");
|
|
2014
|
+
const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, firstOnset, meters);
|
|
2015
|
+
const lastBar = _chunkSGLEQVJHcjs.lastBarOf.call(void 0, meters, firstOnset, spanEnd);
|
|
1994
2016
|
const startBar = Math.max(0, firstBar);
|
|
1995
2017
|
const unitCount = Math.max(1, Math.ceil((lastBar - startBar + 1) / unitBars));
|
|
1996
|
-
|
|
1997
|
-
|
|
2018
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, unitCount * unitCount, "form section comparisons", opts.budget);
|
|
2019
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, unitCount * sounding.length, "form section unit notes", opts.budget);
|
|
1998
2020
|
const units = [];
|
|
1999
2021
|
for (let index = 0; index < unitCount; index += 1) {
|
|
2000
2022
|
const barStart = startBar + index * unitBars;
|
|
2001
|
-
const startBeat = index === 0 ? firstOnset :
|
|
2002
|
-
const endBeat = index === unitCount - 1 ? spanEnd :
|
|
2023
|
+
const startBeat = index === 0 ? firstOnset : _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: barStart, beat: 0 }, meters);
|
|
2024
|
+
const endBeat = index === unitCount - 1 ? spanEnd : _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: barStart + unitBars, beat: 0 }, meters);
|
|
2003
2025
|
const unitNotes = sounding.filter(
|
|
2004
|
-
(note) => note.startBeat >= startBeat -
|
|
2026
|
+
(note) => note.startBeat >= startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && note.startBeat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
|
|
2005
2027
|
).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
|
|
2006
2028
|
units.push({
|
|
2007
2029
|
startBeat,
|
|
2008
2030
|
endBeat,
|
|
2009
2031
|
notes: unitNotes,
|
|
2010
|
-
weights:
|
|
2032
|
+
weights: _chunkSGLEQVJHcjs.windowWeights.call(void 0, unitNotes, startBeat, endBeat, meters).weights
|
|
2011
2033
|
});
|
|
2012
2034
|
}
|
|
2013
2035
|
let comparisons = 0;
|
|
@@ -2016,7 +2038,7 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
2016
2038
|
comparisons += unit.notes.length * earlierNotes;
|
|
2017
2039
|
earlierNotes += unit.notes.length;
|
|
2018
2040
|
}
|
|
2019
|
-
|
|
2041
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, comparisons, "form section melody comparisons", opts.budget);
|
|
2020
2042
|
const labels = [];
|
|
2021
2043
|
const scores = [];
|
|
2022
2044
|
let distinct = 0;
|
|
@@ -2083,7 +2105,7 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
2083
2105
|
if (first === void 0) {
|
|
2084
2106
|
firstByLabel.set(label, sectionIndex);
|
|
2085
2107
|
}
|
|
2086
|
-
const similarity = first === void 0 ? 1 :
|
|
2108
|
+
const similarity = first === void 0 ? 1 : _chunkSGLEQVJHcjs.clamp01.call(void 0, scoreSum / Math.max(1, sounded));
|
|
2087
2109
|
sections.push({
|
|
2088
2110
|
label,
|
|
2089
2111
|
startBeat,
|
|
@@ -2101,14 +2123,14 @@ function sectionsFromNotes(notes, opts = {}) {
|
|
|
2101
2123
|
// src/analyze/reduction/index.ts
|
|
2102
2124
|
var TONIC_ARRIVING = /* @__PURE__ */ new Set(["authentic", "plagal", "modal", "deceptive"]);
|
|
2103
2125
|
function signedStep(fromPc, toPc) {
|
|
2104
|
-
return (
|
|
2126
|
+
return (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, toPc) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, fromPc) + 18) % 12 - 6;
|
|
2105
2127
|
}
|
|
2106
2128
|
function isStep(distance) {
|
|
2107
2129
|
const size = Math.abs(distance);
|
|
2108
2130
|
return size === 1 || size === 2;
|
|
2109
2131
|
}
|
|
2110
2132
|
function touches(before, after) {
|
|
2111
|
-
return Math.abs(after.startBeat - before.endBeat) <=
|
|
2133
|
+
return Math.abs(after.startBeat - before.endBeat) <= _chunkS5BKZZGMcjs.BEAT_EPS;
|
|
2112
2134
|
}
|
|
2113
2135
|
function salienceFloors(durations) {
|
|
2114
2136
|
const order = durations.map((_, index) => index).sort((a, b) => {
|
|
@@ -2135,27 +2157,27 @@ function salienceFloors(durations) {
|
|
|
2135
2157
|
return floors;
|
|
2136
2158
|
}
|
|
2137
2159
|
function isTonicChord(chord, key) {
|
|
2138
|
-
return
|
|
2160
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 0 && !_chunkSGLEQVJHcjs.isAppliedDominant.call(void 0, chord, key);
|
|
2139
2161
|
}
|
|
2140
2162
|
function functionalReason(segment, before, after, keyAt) {
|
|
2141
2163
|
const key = keyAt(segment.startBeat);
|
|
2142
|
-
if (after !== void 0 &&
|
|
2164
|
+
if (after !== void 0 && _chunkSGLEQVJHcjs.isCadentialSixFour.call(void 0, segment.chord, after.chord, key)) {
|
|
2143
2165
|
return { kind: "cadentialSixFour" };
|
|
2144
2166
|
}
|
|
2145
2167
|
if (isTonicChord(segment.chord, key)) {
|
|
2146
2168
|
return { kind: "tonic" };
|
|
2147
2169
|
}
|
|
2148
|
-
if (
|
|
2170
|
+
if (_chunk3R3QVKY5cjs.isDominantChordOf.call(void 0, segment.chord, key)) {
|
|
2149
2171
|
return { kind: "dominant" };
|
|
2150
2172
|
}
|
|
2151
2173
|
if (before !== void 0) {
|
|
2152
|
-
const arrival =
|
|
2174
|
+
const arrival = _chunkSGLEQVJHcjs.detectCadence.call(void 0, before.chord, segment.chord, key).type;
|
|
2153
2175
|
if (arrival !== null) {
|
|
2154
2176
|
return { kind: "cadenceArrival", cadence: arrival };
|
|
2155
2177
|
}
|
|
2156
2178
|
}
|
|
2157
2179
|
if (after !== void 0) {
|
|
2158
|
-
const agent =
|
|
2180
|
+
const agent = _chunkSGLEQVJHcjs.detectCadence.call(void 0, segment.chord, after.chord, keyAt(after.startBeat)).type;
|
|
2159
2181
|
if (agent !== null && TONIC_ARRIVING.has(agent)) {
|
|
2160
2182
|
return { kind: "cadenceAgent", cadence: agent };
|
|
2161
2183
|
}
|
|
@@ -2174,7 +2196,7 @@ function figureReason(segment, before, after) {
|
|
|
2174
2196
|
if (incoming > 0 === outgoing > 0) {
|
|
2175
2197
|
return { kind: "passing" };
|
|
2176
2198
|
}
|
|
2177
|
-
return
|
|
2199
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, before.chord.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, after.chord.rootPc) ? { kind: "neighbor" } : null;
|
|
2178
2200
|
}
|
|
2179
2201
|
function describe(reason) {
|
|
2180
2202
|
switch (reason.kind) {
|
|
@@ -2214,10 +2236,10 @@ function levelOf(reason) {
|
|
|
2214
2236
|
return reason.kind === "neighbor" ? "neighbor" : "structural";
|
|
2215
2237
|
}
|
|
2216
2238
|
function reduceProgression(timeline, key, opts = {}) {
|
|
2217
|
-
|
|
2218
|
-
const asked =
|
|
2219
|
-
const keyAt =
|
|
2220
|
-
const basis =
|
|
2239
|
+
_chunkSGLEQVJHcjs.assertChordTimeline.call(void 0, timeline);
|
|
2240
|
+
const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
2241
|
+
const keyAt = _chunkSGLEQVJHcjs.keyScaleAt.call(void 0, key);
|
|
2242
|
+
const basis = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(asked.basis, () => ( "function")), REDUCTION_BASES, "reduction basis");
|
|
2221
2243
|
const reading = BASIS_READINGS[basis];
|
|
2222
2244
|
const segments = timeline.segments;
|
|
2223
2245
|
const floors = basis === "duration" ? salienceFloors(segments.map((segment) => segment.endBeat - segment.startBeat)) : [];
|
|
@@ -2269,4 +2291,4 @@ function reduceProgression(timeline, key, opts = {}) {
|
|
|
2269
2291
|
|
|
2270
2292
|
|
|
2271
2293
|
exports.trackRoleOf = trackRoleOf; exports.analyzePolyphony = analyzePolyphony; exports.analyzeArrangement = analyzeArrangement; exports.createArrangementSession = createArrangementSession; exports.tensionCurve = tensionCurve; exports.tensionCurveFrom = tensionCurveFrom; exports.hypermeter = hypermeter; exports.melodicContour = melodicContour; exports.extractMotifs = extractMotifs; exports.motifFromNotes = motifFromNotes; exports.relateMotifs = relateMotifs; exports.compareMelodies = compareMelodies; exports.melodicSimilarity = melodicSimilarity; exports.phrasesFromTimeline = phrasesFromTimeline; exports.structuralCadences = structuralCadences; exports.sectionsFromNotes = sectionsFromNotes; exports.reduceProgression = reduceProgression;
|
|
2272
|
-
//# sourceMappingURL=chunk-
|
|
2294
|
+
//# sourceMappingURL=chunk-HPVSH7SF.cjs.map
|