@libraz/libcantus 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/README_ja.md +4 -0
- package/dist/analyze/index.cjs +31 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +155 -9
- package/dist/analyze/index.d.ts +155 -9
- package/dist/analyze/index.js +37 -13
- 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-GDKE6RQW.cjs → chunk-4R2LWV7E.cjs} +691 -413
- package/dist/chunk-4R2LWV7E.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-5KW7DNCJ.cjs → chunk-B2PW6EHN.cjs} +2423 -453
- package/dist/chunk-B2PW6EHN.cjs.map +1 -0
- 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-R5VUXQMP.js → chunk-CPMB7P75.js} +1978 -8
- package/dist/chunk-CPMB7P75.js.map +1 -0
- package/dist/{chunk-VLE5R7PF.js → chunk-GNVN4PPJ.js} +1874 -8
- package/dist/chunk-GNVN4PPJ.js.map +1 -0
- package/dist/{chunk-Q6R3QAZD.cjs → chunk-IFZDWIKM.cjs} +2199 -333
- package/dist/chunk-IFZDWIKM.cjs.map +1 -0
- package/dist/{chunk-DKICR7AN.js → chunk-IPEF6NWB.js} +296 -18
- package/dist/chunk-IPEF6NWB.js.map +1 -0
- package/dist/{chunk-AWEMD747.js → chunk-M5RYMAFI.js} +3 -3
- package/dist/{chunk-HSY2VQXZ.js → chunk-MLBPXA4Z.js} +330 -728
- package/dist/chunk-MLBPXA4Z.js.map +1 -0
- package/dist/{chunk-H66ARFU5.js → chunk-NB25P3EH.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-QCXYKSZS.cjs → chunk-PWC4CRWT.cjs} +19 -19
- package/dist/{chunk-QCXYKSZS.cjs.map → chunk-PWC4CRWT.cjs.map} +1 -1
- 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-HOHFYGKW.js → chunk-UMWZ4ZET.js} +2 -2
- package/dist/{chunk-XVMJO3QF.cjs → chunk-YFA7X2F6.cjs} +489 -887
- package/dist/chunk-YFA7X2F6.cjs.map +1 -0
- package/dist/{chunk-57WB2EDF.js → chunk-ZBUROTJQ.js} +3 -3
- 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 +20 -8
- package/dist/generate/index.cjs.map +1 -1
- package/dist/generate/index.d.cts +87 -9
- package/dist/generate/index.d.ts +87 -9
- package/dist/generate/index.js +19 -7
- package/dist/{index-BaoKVVhE.d.cts → index-B9QLziDe.d.cts} +2 -2
- package/dist/{index-CnHQgqNh.d.ts → index-BHIUyjhZ.d.ts} +2 -2
- 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-Ci3xyows.d.ts → index-CL4b4gUQ.d.ts} +3 -0
- package/dist/{index-BzLNkmA7.d.cts → index-CY-3NVfy.d.cts} +486 -5
- package/dist/{index-CnIdP4EZ.d.ts → index-Dw2DP7vm.d.ts} +1 -1
- package/dist/{index-DpC-mDlV.d.ts → index-zaZdmnU4.d.ts} +486 -5
- package/dist/index.cjs +49 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +55 -19
- 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 +213 -16
- package/dist/model/index.d.ts +213 -16
- package/dist/model/index.js +11 -11
- package/dist/{index-DTsKaPaC.d.cts → profile-CQMEqdH9.d.cts} +88 -601
- package/dist/{index-BUtIf2go.d.ts → profile-DLdlIpS9.d.ts} +88 -601
- 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/dist/{index-BpWOhkkE.d.ts → types-D-XgxGvp.d.cts} +1170 -14
- package/dist/{index-B3WCj_Hm.d.cts → types-Dh7C064C.d.ts} +1170 -14
- package/package.json +6 -5
- package/dist/chunk-5KW7DNCJ.cjs.map +0 -1
- package/dist/chunk-DKICR7AN.js.map +0 -1
- package/dist/chunk-GDKE6RQW.cjs.map +0 -1
- package/dist/chunk-HSY2VQXZ.js.map +0 -1
- package/dist/chunk-Q6R3QAZD.cjs.map +0 -1
- package/dist/chunk-R5VUXQMP.js.map +0 -1
- package/dist/chunk-VLE5R7PF.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-AWEMD747.js.map → chunk-M5RYMAFI.js.map} +0 -0
- /package/dist/{chunk-H66ARFU5.js.map → chunk-NB25P3EH.js.map} +0 -0
- /package/dist/{chunk-7GOKQJTQ.js.map → chunk-PUKJP2Z5.js.map} +0 -0
- /package/dist/{chunk-HOHFYGKW.js.map → chunk-UMWZ4ZET.js.map} +0 -0
- /package/dist/{chunk-57WB2EDF.js.map → chunk-ZBUROTJQ.js.map} +0 -0
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
var
|
|
36
|
+
var _chunkS5BKZZGMcjs = require('./chunk-S5BKZZGM.cjs');
|
|
37
37
|
|
|
38
38
|
// src/theory/scale/masks.ts
|
|
39
39
|
function maskFromOffsets(offsets) {
|
|
40
|
-
|
|
40
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, offsets, "offsets");
|
|
41
41
|
let mask = 1;
|
|
42
42
|
for (const [index, offset] of offsets.entries()) {
|
|
43
|
-
|
|
43
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0, offset, `offsets[${index}]`);
|
|
44
44
|
mask |= 1 << (offset % 12 + 12) % 12;
|
|
45
45
|
}
|
|
46
46
|
return mask;
|
|
@@ -62,10 +62,10 @@ var OCTATONIC_HALF_WHOLE_MASK = maskFromOffsets([0, 1, 3, 4, 6, 7, 9, 10]);
|
|
|
62
62
|
var OCTATONIC_WHOLE_HALF_MASK = maskFromOffsets([0, 2, 3, 5, 6, 8, 9, 11]);
|
|
63
63
|
var CHROMATIC_MASK = 4095;
|
|
64
64
|
function assertModeMask(modeMask12, name = "modeMask12") {
|
|
65
|
-
return
|
|
65
|
+
return _chunkS5BKZZGMcjs.assertInteger.call(void 0, modeMask12, name, 1, CHROMATIC_MASK);
|
|
66
66
|
}
|
|
67
67
|
function maskOf(scale, name = "key") {
|
|
68
|
-
return assertModeMask(
|
|
68
|
+
return assertModeMask(_chunkS5BKZZGMcjs.assertRecord.call(void 0, scale, name).modeMask12, `${name}.modeMask12`);
|
|
69
69
|
}
|
|
70
70
|
var LYDIAN_DOMINANT_MASK = maskFromOffsets([0, 2, 4, 6, 7, 9, 10]);
|
|
71
71
|
var MIXOLYDIAN_B13_MASK = maskFromOffsets([0, 2, 4, 5, 7, 8, 10]);
|
|
@@ -173,7 +173,7 @@ var SCALE_ALIASES = Object.freeze({
|
|
|
173
173
|
});
|
|
174
174
|
function resolveScaleName(name) {
|
|
175
175
|
if (typeof name !== "string") {
|
|
176
|
-
throw new (0,
|
|
176
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`scale name must be a string; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, name)}`);
|
|
177
177
|
}
|
|
178
178
|
if (Object.hasOwn(NAMED_SCALES, name)) {
|
|
179
179
|
return name;
|
|
@@ -193,7 +193,7 @@ function namedScaleMask(name) {
|
|
|
193
193
|
function requireScaleMask(name, label = "scale") {
|
|
194
194
|
const mask = namedScaleMask(name);
|
|
195
195
|
if (mask === void 0) {
|
|
196
|
-
throw new (0,
|
|
196
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown ${label}: ${String(name)}`);
|
|
197
197
|
}
|
|
198
198
|
return mask;
|
|
199
199
|
}
|
|
@@ -220,12 +220,12 @@ var KEY_VARIANTS = [
|
|
|
220
220
|
"modal"
|
|
221
221
|
];
|
|
222
222
|
function assertKeyVariant(variant, modeMask12) {
|
|
223
|
-
|
|
223
|
+
_chunkS5BKZZGMcjs.assertOneOf.call(void 0, variant, KEY_VARIANTS, "variant");
|
|
224
224
|
assertModeMask(modeMask12);
|
|
225
225
|
const named = VARIANT_MASKS[variant];
|
|
226
226
|
const matches = named === void 0 ? !Object.values(VARIANT_MASKS).includes(modeMask12) : named === modeMask12;
|
|
227
227
|
if (!matches) {
|
|
228
|
-
throw new (0,
|
|
228
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
229
229
|
`variant ${variant} does not match the scale mask ${modeMask12}; pass the scale that variant names, or omit the variant`
|
|
230
230
|
);
|
|
231
231
|
}
|
|
@@ -233,13 +233,13 @@ function assertKeyVariant(variant, modeMask12) {
|
|
|
233
233
|
|
|
234
234
|
// src/theory/scale/scales.ts
|
|
235
235
|
function majorScale(rootPc) {
|
|
236
|
-
return { rootPc:
|
|
236
|
+
return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc), modeMask12: MAJOR_MASK };
|
|
237
237
|
}
|
|
238
238
|
function minorScale(rootPc) {
|
|
239
|
-
return { rootPc:
|
|
239
|
+
return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc), modeMask12: NATURAL_MINOR_MASK };
|
|
240
240
|
}
|
|
241
241
|
function namedScale(name, rootPc) {
|
|
242
|
-
return { rootPc:
|
|
242
|
+
return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc), modeMask12: requireScaleMask(name) };
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
// src/theory/scale/name.ts
|
|
@@ -280,43 +280,43 @@ function tryNamedScaleKey(text) {
|
|
|
280
280
|
if (name === void 0) {
|
|
281
281
|
return null;
|
|
282
282
|
}
|
|
283
|
-
const tonic =
|
|
283
|
+
const tonic = _chunkS5BKZZGMcjs.tryParseNote.call(void 0, trimmed.slice(0, separator));
|
|
284
284
|
if (!tonic.ok) {
|
|
285
285
|
return null;
|
|
286
286
|
}
|
|
287
|
-
const scale = namedScale(name,
|
|
287
|
+
const scale = namedScale(name, _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic.value));
|
|
288
288
|
return { scale, tonic: bareTonic(tonic.value), variant: variantOfMask(scale.modeMask12) };
|
|
289
289
|
}
|
|
290
290
|
function tryResolveKeyName(text, opts) {
|
|
291
|
-
const asked =
|
|
291
|
+
const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
292
292
|
if (typeof text === "string" && (asked.system === void 0 || asked.system === "english")) {
|
|
293
293
|
const named = tryNamedScaleKey(text);
|
|
294
294
|
if (named !== null) {
|
|
295
295
|
return { ok: true, value: named };
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
-
const parsed =
|
|
298
|
+
const parsed = _chunkS5BKZZGMcjs.tryParseKeyName.call(void 0, text, asked);
|
|
299
299
|
if (!parsed.ok) {
|
|
300
300
|
return parsed;
|
|
301
301
|
}
|
|
302
302
|
const tonic = bareTonic(parsed.value.tonic);
|
|
303
|
-
const rootPc =
|
|
303
|
+
const rootPc = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic);
|
|
304
304
|
return parsed.value.mode === "major" ? { ok: true, value: { scale: majorScale(rootPc), tonic, variant: "major" } } : { ok: true, value: { scale: minorScale(rootPc), tonic, variant: "natural" } };
|
|
305
305
|
}
|
|
306
306
|
function resolveKeyName(text, opts) {
|
|
307
|
-
return
|
|
307
|
+
return _chunkS5BKZZGMcjs.unwrapParse.call(void 0, tryResolveKeyName(text, opts));
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
// src/theory/scale/coerce.ts
|
|
311
311
|
function normalizedKeyScale(scale) {
|
|
312
312
|
assertModeMask(scale.modeMask12, "key.modeMask12");
|
|
313
313
|
if ((scale.modeMask12 & 1) === 0) {
|
|
314
|
-
throw new (0,
|
|
314
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
315
315
|
`key.modeMask12 must include its root; received ${scale.modeMask12}`
|
|
316
316
|
);
|
|
317
317
|
}
|
|
318
|
-
|
|
319
|
-
return { rootPc:
|
|
318
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0, scale.rootPc, "key.rootPc");
|
|
319
|
+
return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc), modeMask12: scale.modeMask12 };
|
|
320
320
|
}
|
|
321
321
|
function toKeyScale(value) {
|
|
322
322
|
if (typeof value === "string") {
|
|
@@ -328,12 +328,12 @@ function toKeyScale(value) {
|
|
|
328
328
|
return normalizedKeyScale(data);
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
-
throw new (0,
|
|
331
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`key must be a key name or a key/scale; received ${typeof value}`);
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
// src/theory/scale/degrees.ts
|
|
335
335
|
function scaleOffset(pitch, key) {
|
|
336
|
-
return (
|
|
336
|
+
return (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc) + 12) % 12;
|
|
337
337
|
}
|
|
338
338
|
function inScale(pitch, scale) {
|
|
339
339
|
return (scale.modeMask12 >> scaleOffset(pitch, scale) & 1) === 1;
|
|
@@ -343,8 +343,8 @@ function isScaleTone(pitch, key) {
|
|
|
343
343
|
}
|
|
344
344
|
function nearestScaleTone(pitch, key) {
|
|
345
345
|
const scale = toKeyScale(key);
|
|
346
|
-
|
|
347
|
-
const base =
|
|
346
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
|
|
347
|
+
const base = _chunkS5BKZZGMcjs.clampToMidi.call(void 0, Math.round(pitch), "pitch");
|
|
348
348
|
for (let distance = 0; distance < 12; distance += 1) {
|
|
349
349
|
const lower = base - distance;
|
|
350
350
|
if (lower >= 0 && inScale(lower, scale)) {
|
|
@@ -370,13 +370,13 @@ function scaleLadderPosition(pitch, key) {
|
|
|
370
370
|
return ladderPosition(pitch, toKeyScale(key));
|
|
371
371
|
}
|
|
372
372
|
function ladderPosition(pitch, key) {
|
|
373
|
-
|
|
373
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
|
|
374
374
|
const offsets = scaleOffsets(key);
|
|
375
375
|
const size = offsets.length;
|
|
376
376
|
if (size === 0) {
|
|
377
377
|
return { rung: 0, offset: 0 };
|
|
378
378
|
}
|
|
379
|
-
const relative = pitch -
|
|
379
|
+
const relative = pitch - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
380
380
|
const octave = Math.floor(relative / 12);
|
|
381
381
|
const within = relative - octave * 12;
|
|
382
382
|
let degree = 0;
|
|
@@ -391,19 +391,19 @@ function scaleLadderPitch(rung, key) {
|
|
|
391
391
|
return ladderPitch(rung, toKeyScale(key));
|
|
392
392
|
}
|
|
393
393
|
function ladderPitch(rung, key) {
|
|
394
|
-
|
|
394
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, rung, "rung");
|
|
395
395
|
const offsets = scaleOffsets(key);
|
|
396
396
|
const size = offsets.length;
|
|
397
397
|
if (size === 0) {
|
|
398
|
-
return
|
|
398
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
399
399
|
}
|
|
400
400
|
const octave = Math.floor(rung / size);
|
|
401
401
|
const degree = rung - octave * size;
|
|
402
|
-
return
|
|
402
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc) + octave * 12 + (_nullishCoalesce(offsets[degree], () => ( 0)));
|
|
403
403
|
}
|
|
404
404
|
function shiftByScaleDegrees(pitch, degrees, key) {
|
|
405
405
|
const scale = toKeyScale(key);
|
|
406
|
-
const steps = Math.trunc(
|
|
406
|
+
const steps = Math.trunc(_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, degrees, "degrees"));
|
|
407
407
|
if (steps === 0) {
|
|
408
408
|
return pitch;
|
|
409
409
|
}
|
|
@@ -429,7 +429,7 @@ function diatonicPitchClasses(key) {
|
|
|
429
429
|
}
|
|
430
430
|
function scaleTonesInDegreeOrder(key) {
|
|
431
431
|
const scale = toKeyScale(key);
|
|
432
|
-
const root =
|
|
432
|
+
const root = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc);
|
|
433
433
|
const pcs = [];
|
|
434
434
|
for (let n = 0; n < 12; n += 1) {
|
|
435
435
|
if ((scale.modeMask12 >> n & 1) === 1) {
|
|
@@ -477,20 +477,20 @@ function isSignatureKey(key) {
|
|
|
477
477
|
return DIATONIC_MODE_OFFSETS.has(mask) || mask === HARMONIC_MINOR_MASK || mask === MELODIC_MINOR_MASK;
|
|
478
478
|
}
|
|
479
479
|
function keySignatureFifths(tonic, key) {
|
|
480
|
-
const note =
|
|
480
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
481
481
|
const scale = toKeyScale(key);
|
|
482
|
-
const letter =
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, note.letter);
|
|
483
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0, note.alter, "tonic.alter");
|
|
484
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0, scale.modeMask12, "key.modeMask12", 1, 4095);
|
|
485
485
|
return (_nullishCoalesce(LETTER_FIFTHS[letter], () => ( 0))) + FIFTHS_PER_ALTERATION * note.alter + modeOffset(scale);
|
|
486
486
|
}
|
|
487
487
|
function keyFromFifths(fifths, mode = "major") {
|
|
488
|
-
|
|
489
|
-
const which =
|
|
488
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0, fifths, "fifths", -MAX_FIFTHS, MAX_FIFTHS);
|
|
489
|
+
const which = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, mode, ["major", "minor"], "mode");
|
|
490
490
|
const index = fifths + 1 + (which === "minor" ? -MINOR_MODE_OFFSET : 0);
|
|
491
491
|
const letter = _nullishCoalesce(FIFTHS_LETTERS[(index % 7 + 7) % 7], () => ( 0));
|
|
492
492
|
const alter = Math.floor(index / 7);
|
|
493
|
-
const rootPc =
|
|
493
|
+
const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, letter) + alter);
|
|
494
494
|
const scale = which === "minor" ? minorScale(rootPc) : majorScale(rootPc);
|
|
495
495
|
return {
|
|
496
496
|
tonic: { letter, alter },
|
|
@@ -512,10 +512,10 @@ function oppositeMode(mode) {
|
|
|
512
512
|
return mode === "major" ? "minor" : "major";
|
|
513
513
|
}
|
|
514
514
|
function soundsLike(a, b) {
|
|
515
|
-
return
|
|
515
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, a.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, b.rootPc) && isMinorMask(a.modeMask12) === isMinorMask(b.modeMask12);
|
|
516
516
|
}
|
|
517
517
|
function spelledLike(a, b) {
|
|
518
|
-
return
|
|
518
|
+
return _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, a.letter) === _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, b.letter) && a.alter === b.alter;
|
|
519
519
|
}
|
|
520
520
|
function tonicCost(tonic, key) {
|
|
521
521
|
let doubles = 0;
|
|
@@ -523,7 +523,7 @@ function tonicCost(tonic, key) {
|
|
|
523
523
|
for (const note of spellScale(tonic, key)) {
|
|
524
524
|
const alter = Math.abs(note.alter);
|
|
525
525
|
accidentals += alter;
|
|
526
|
-
if (alter >=
|
|
526
|
+
if (alter >= _chunkS5BKZZGMcjs.MAX_NAME_ACCIDENTALS) {
|
|
527
527
|
doubles += 1;
|
|
528
528
|
}
|
|
529
529
|
}
|
|
@@ -539,14 +539,14 @@ function spellsBetter(a, b, signatureKey) {
|
|
|
539
539
|
return false;
|
|
540
540
|
}
|
|
541
541
|
function spelledKeyOf(key) {
|
|
542
|
-
const scale =
|
|
543
|
-
const rootPc =
|
|
542
|
+
const scale = _chunkS5BKZZGMcjs.assertRecord.call(void 0, key, "key");
|
|
543
|
+
const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc);
|
|
544
544
|
const signatureKey = isSignatureKey(scale);
|
|
545
545
|
let tonic = keyFromFifths(0).tonic;
|
|
546
546
|
let best;
|
|
547
547
|
for (let fifths = FLATTEST_TONIC_FIFTHS; fifths <= SHARPEST_TONIC_FIFTHS; fifths += 1) {
|
|
548
548
|
const candidate = keyFromFifths(fifths).tonic;
|
|
549
|
-
if (
|
|
549
|
+
if (_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, candidate) !== rootPc) {
|
|
550
550
|
continue;
|
|
551
551
|
}
|
|
552
552
|
const cost = tonicCost(candidate, scale);
|
|
@@ -559,21 +559,21 @@ function spelledKeyOf(key) {
|
|
|
559
559
|
}
|
|
560
560
|
function relativeKeyOf(tonic, key) {
|
|
561
561
|
const mode = modeOf(toKeyScale(key));
|
|
562
|
-
return keyFromFifths(tonicFifths(
|
|
562
|
+
return keyFromFifths(tonicFifths(_chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic), mode), oppositeMode(mode));
|
|
563
563
|
}
|
|
564
564
|
function parallelKeyOf(tonic, key) {
|
|
565
|
-
const note =
|
|
565
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
566
566
|
const mode = oppositeMode(modeOf(toKeyScale(key)));
|
|
567
|
-
const rootPc =
|
|
567
|
+
const rootPc = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, note);
|
|
568
568
|
const scale = mode === "minor" ? minorScale(rootPc) : majorScale(rootPc);
|
|
569
569
|
return {
|
|
570
|
-
tonic: { letter:
|
|
570
|
+
tonic: { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, note.letter), alter: note.alter },
|
|
571
571
|
scale,
|
|
572
572
|
variant: variantOfMask(scale.modeMask12)
|
|
573
573
|
};
|
|
574
574
|
}
|
|
575
575
|
function tonicPosition(tonic) {
|
|
576
|
-
return keySignatureFifths(tonic, majorScale(
|
|
576
|
+
return keySignatureFifths(tonic, majorScale(_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic)));
|
|
577
577
|
}
|
|
578
578
|
function tonicFifths(tonic, mode) {
|
|
579
579
|
return tonicPosition(tonic) - (mode === "minor" ? MINOR_TONIC_FIFTHS : 0);
|
|
@@ -583,18 +583,18 @@ function isWrittenTonic(tonic, key) {
|
|
|
583
583
|
if (isSignatureKey(key)) {
|
|
584
584
|
return Math.abs(position) <= MAX_FIFTHS && Math.abs(keySignatureFifths(tonic, key)) <= MAX_CONVENTIONAL_FIFTHS;
|
|
585
585
|
}
|
|
586
|
-
return position >= FLATTEST_TONIC_FIFTHS && position <= SHARPEST_TONIC_FIFTHS && tonicCost(tonic, { rootPc:
|
|
586
|
+
return position >= FLATTEST_TONIC_FIFTHS && position <= SHARPEST_TONIC_FIFTHS && tonicCost(tonic, { rootPc: _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic), modeMask12: key.modeMask12 }).doubles === 0;
|
|
587
587
|
}
|
|
588
588
|
function dominantKeyOf(tonic, key) {
|
|
589
589
|
const mode = modeOf(toKeyScale(key));
|
|
590
|
-
return keyFromFifths(tonicFifths(
|
|
590
|
+
return keyFromFifths(tonicFifths(_chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic), mode) + 1, mode);
|
|
591
591
|
}
|
|
592
592
|
function subdominantKeyOf(tonic, key) {
|
|
593
593
|
const mode = modeOf(toKeyScale(key));
|
|
594
|
-
return keyFromFifths(tonicFifths(
|
|
594
|
+
return keyFromFifths(tonicFifths(_chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic), mode) - 1, mode);
|
|
595
595
|
}
|
|
596
596
|
function enharmonicKeyOf(tonic, key) {
|
|
597
|
-
const note =
|
|
597
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
598
598
|
const scale = toKeyScale(key);
|
|
599
599
|
maskOf(scale);
|
|
600
600
|
for (const position of [
|
|
@@ -612,7 +612,7 @@ function enharmonicKeyOf(tonic, key) {
|
|
|
612
612
|
tonic: spelled2,
|
|
613
613
|
// The mask is the caller's; only the root is re-read, so a tonic that did
|
|
614
614
|
// not spell the mask's own root still comes back consistent.
|
|
615
|
-
scale: { rootPc:
|
|
615
|
+
scale: { rootPc: _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, spelled2), modeMask12: scale.modeMask12 },
|
|
616
616
|
variant: variantOfMask(scale.modeMask12)
|
|
617
617
|
};
|
|
618
618
|
}
|
|
@@ -635,13 +635,13 @@ var CLOSELY_RELATED = [
|
|
|
635
635
|
{ relation: "relativeOfSubdominant", of: relativeOfSubdominantKeyOf }
|
|
636
636
|
];
|
|
637
637
|
function relatedKeysOf(tonic, key) {
|
|
638
|
-
const note =
|
|
638
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
639
639
|
const scale = toKeyScale(key);
|
|
640
640
|
return CLOSELY_RELATED.map(({ relation, of }) => ({ ...of(note, scale), relation }));
|
|
641
641
|
}
|
|
642
642
|
function keyRelationBetween(a, b) {
|
|
643
|
-
const from =
|
|
644
|
-
const to =
|
|
643
|
+
const from = _chunkS5BKZZGMcjs.assertRecord.call(void 0, a, "a");
|
|
644
|
+
const to = _chunkS5BKZZGMcjs.assertRecord.call(void 0, b, "b");
|
|
645
645
|
maskOf(from.scale, "a.scale");
|
|
646
646
|
maskOf(to.scale, "b.scale");
|
|
647
647
|
if (soundsLike(from.scale, to.scale)) {
|
|
@@ -660,9 +660,9 @@ function carriesIdentity(value) {
|
|
|
660
660
|
return typeof value === "object" && value !== null;
|
|
661
661
|
}
|
|
662
662
|
function carriedTonic(tonic, scale) {
|
|
663
|
-
if (
|
|
664
|
-
throw new (0,
|
|
665
|
-
`tonic ${
|
|
663
|
+
if (_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic) !== scale.rootPc) {
|
|
664
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
665
|
+
`tonic ${_chunkS5BKZZGMcjs.formatNote.call(void 0, tonic)} does not match the scale root pitch class ${scale.rootPc}; pass a tonic that spells the scale root, or omit it to have one chosen`
|
|
666
666
|
);
|
|
667
667
|
}
|
|
668
668
|
return { letter: tonic.letter, alter: tonic.alter };
|
|
@@ -682,7 +682,7 @@ function resolveKey(value) {
|
|
|
682
682
|
return { scale, tonic, variant };
|
|
683
683
|
}
|
|
684
684
|
function scaleOf(key) {
|
|
685
|
-
const scale =
|
|
685
|
+
const scale = _chunkS5BKZZGMcjs.assertRecord.call(void 0, key, "key").scale;
|
|
686
686
|
maskOf(scale, "key.scale");
|
|
687
687
|
return scale;
|
|
688
688
|
}
|
|
@@ -765,7 +765,7 @@ function scaleSystemOf(scale) {
|
|
|
765
765
|
if (typeof scale === "string") {
|
|
766
766
|
const canonical = resolveScaleName(scale);
|
|
767
767
|
if (canonical === void 0) {
|
|
768
|
-
throw new (0,
|
|
768
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown scale: ${scale}`);
|
|
769
769
|
}
|
|
770
770
|
return SCALE_SYSTEMS[canonical];
|
|
771
771
|
}
|
|
@@ -1067,7 +1067,7 @@ var QUALITY_BY_KEY = new Map(
|
|
|
1067
1067
|
function chordSpecForQuality(quality, rootPc, bassPc) {
|
|
1068
1068
|
const named = SPEC_BY_QUALITY.get(quality);
|
|
1069
1069
|
if (named === void 0) {
|
|
1070
|
-
throw new (0,
|
|
1070
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
|
|
1071
1071
|
}
|
|
1072
1072
|
const spec = normalizeChordSpec(named);
|
|
1073
1073
|
spec.rootPc = rootPc;
|
|
@@ -1174,15 +1174,15 @@ function chordSpecFromIntervals(intervals) {
|
|
|
1174
1174
|
}
|
|
1175
1175
|
function assertPart(value, allowed, name) {
|
|
1176
1176
|
if (!allowed.includes(value)) {
|
|
1177
|
-
throw new (0,
|
|
1178
|
-
`${name} must be one of ${allowed.join(", ")}; received ${
|
|
1177
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1178
|
+
`${name} must be one of ${allowed.join(", ")}; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, value)}`
|
|
1179
1179
|
);
|
|
1180
1180
|
}
|
|
1181
1181
|
return value;
|
|
1182
1182
|
}
|
|
1183
1183
|
function assertDegreeIn(value, allowed, name) {
|
|
1184
1184
|
if (!allowed.includes(value)) {
|
|
1185
|
-
throw new (0,
|
|
1185
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1186
1186
|
`${name} must be one of ${allowed.join(", ")}; received ${String(value)}`
|
|
1187
1187
|
);
|
|
1188
1188
|
}
|
|
@@ -1190,7 +1190,7 @@ function assertDegreeIn(value, allowed, name) {
|
|
|
1190
1190
|
}
|
|
1191
1191
|
function assertDegreeList(value, allowed, name) {
|
|
1192
1192
|
if (!Array.isArray(value)) {
|
|
1193
|
-
throw new (0,
|
|
1193
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be an array; received ${typeof value}`);
|
|
1194
1194
|
}
|
|
1195
1195
|
for (const degree of value) {
|
|
1196
1196
|
assertDegreeIn(degree, allowed, name);
|
|
@@ -1198,11 +1198,11 @@ function assertDegreeList(value, allowed, name) {
|
|
|
1198
1198
|
}
|
|
1199
1199
|
function assertChordSpec(spec) {
|
|
1200
1200
|
if (spec === null || typeof spec !== "object") {
|
|
1201
|
-
throw new (0,
|
|
1201
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`chord spec must be an object; received ${typeof spec}`);
|
|
1202
1202
|
}
|
|
1203
|
-
|
|
1203
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, spec.rootPc, "chord spec rootPc");
|
|
1204
1204
|
if (spec.bassPc !== void 0) {
|
|
1205
|
-
|
|
1205
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, spec.bassPc, "chord spec bassPc");
|
|
1206
1206
|
}
|
|
1207
1207
|
assertPart(spec.base, Object.keys(BASE_TONES), "chord spec base");
|
|
1208
1208
|
if (spec.seventh !== void 0) {
|
|
@@ -1213,7 +1213,7 @@ function assertChordSpec(spec) {
|
|
|
1213
1213
|
);
|
|
1214
1214
|
}
|
|
1215
1215
|
if (!Array.isArray(spec.alterations)) {
|
|
1216
|
-
throw new (0,
|
|
1216
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("chord spec alterations must be an array");
|
|
1217
1217
|
}
|
|
1218
1218
|
for (const alteration of spec.alterations) {
|
|
1219
1219
|
assertDegreeIn(_optionalChain([alteration, 'optionalAccess', _5 => _5.degree]), [5, 9, 11, 13], "chord spec alteration degree");
|
|
@@ -1231,59 +1231,59 @@ function chordQualities() {
|
|
|
1231
1231
|
}
|
|
1232
1232
|
function assertChordQuality(quality) {
|
|
1233
1233
|
if (!Object.hasOwn(QUALITY_INTERVALS, quality)) {
|
|
1234
|
-
throw new (0,
|
|
1234
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
|
|
1235
1235
|
}
|
|
1236
1236
|
return quality;
|
|
1237
1237
|
}
|
|
1238
1238
|
function assertChord(chord, name = "chord") {
|
|
1239
|
-
const read =
|
|
1240
|
-
|
|
1239
|
+
const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, name);
|
|
1240
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.rootPc, `${name}.rootPc`);
|
|
1241
1241
|
assertChordQuality(read.quality);
|
|
1242
1242
|
return read;
|
|
1243
1243
|
}
|
|
1244
1244
|
function chordFromDegree(degree, ext, key) {
|
|
1245
|
-
|
|
1245
|
+
_chunkS5BKZZGMcjs.assertDegree.call(void 0, degree, "chord degree");
|
|
1246
1246
|
assertChordQuality(ext);
|
|
1247
1247
|
const scale = toKeyScale(key);
|
|
1248
1248
|
const tones = scaleTonesInDegreeOrder(scale);
|
|
1249
1249
|
const length = tones.length;
|
|
1250
1250
|
const index = length > 0 ? (degree - 1) % length : 0;
|
|
1251
|
-
const rootPc = _nullishCoalesce(tones[index], () => (
|
|
1251
|
+
const rootPc = _nullishCoalesce(tones[index], () => ( _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc)));
|
|
1252
1252
|
return { rootPc, quality: ext, intervals: [...QUALITY_INTERVALS[ext]] };
|
|
1253
1253
|
}
|
|
1254
1254
|
function makeChord(rootPc, quality, bassPc) {
|
|
1255
|
-
|
|
1255
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, rootPc, "chord rootPc");
|
|
1256
1256
|
if (bassPc !== void 0) {
|
|
1257
|
-
|
|
1257
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, bassPc, "chord bassPc");
|
|
1258
1258
|
}
|
|
1259
1259
|
assertChordQuality(quality);
|
|
1260
1260
|
const chord = {
|
|
1261
|
-
rootPc:
|
|
1261
|
+
rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc),
|
|
1262
1262
|
quality,
|
|
1263
1263
|
intervals: [..._nullishCoalesce(QUALITY_INTERVALS[quality], () => ( []))]
|
|
1264
1264
|
};
|
|
1265
1265
|
if (bassPc !== void 0) {
|
|
1266
|
-
chord.bassPc =
|
|
1266
|
+
chord.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, bassPc);
|
|
1267
1267
|
}
|
|
1268
1268
|
return chord;
|
|
1269
1269
|
}
|
|
1270
1270
|
function chordFromSpec(spec) {
|
|
1271
1271
|
const checked = assertChordSpec(spec);
|
|
1272
1272
|
const chord = {
|
|
1273
|
-
rootPc:
|
|
1273
|
+
rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, checked.rootPc),
|
|
1274
1274
|
quality: chordSpecQuality(checked),
|
|
1275
1275
|
intervals: chordSpecIntervals(checked)
|
|
1276
1276
|
};
|
|
1277
1277
|
if (checked.bassPc !== void 0) {
|
|
1278
|
-
chord.bassPc =
|
|
1278
|
+
chord.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, checked.bassPc);
|
|
1279
1279
|
}
|
|
1280
1280
|
return chord;
|
|
1281
1281
|
}
|
|
1282
1282
|
function chordSpecOf(chord) {
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
const rootPc =
|
|
1286
|
-
const bassPc = chord.bassPc === void 0 ? void 0 :
|
|
1283
|
+
_chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, "chord");
|
|
1284
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, chord.rootPc, "chord rootPc");
|
|
1285
|
+
const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc);
|
|
1286
|
+
const bassPc = chord.bassPc === void 0 ? void 0 : _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc);
|
|
1287
1287
|
const intervals = _nullishCoalesce(chord.intervals, () => ( []));
|
|
1288
1288
|
const read = intervals.length === 0 ? void 0 : chordSpecFromIntervals(intervals);
|
|
1289
1289
|
if (read === void 0) {
|
|
@@ -1298,21 +1298,21 @@ function chordSpecOf(chord) {
|
|
|
1298
1298
|
function copySpanIntervals(intervals) {
|
|
1299
1299
|
const name = "chord span intervals";
|
|
1300
1300
|
if (!Array.isArray(intervals)) {
|
|
1301
|
-
throw new (0,
|
|
1301
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be an array; received ${typeof intervals}`);
|
|
1302
1302
|
}
|
|
1303
1303
|
if (intervals.length === 0) {
|
|
1304
|
-
throw new (0,
|
|
1304
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must name at least one interval`);
|
|
1305
1305
|
}
|
|
1306
1306
|
const copy = [];
|
|
1307
1307
|
for (let index = 0; index < intervals.length; index += 1) {
|
|
1308
1308
|
const interval = intervals[index];
|
|
1309
1309
|
if (interval === void 0) {
|
|
1310
|
-
throw new (0,
|
|
1310
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1311
1311
|
`${name}[${index}] must be a semitone offset; received undefined`
|
|
1312
1312
|
);
|
|
1313
1313
|
}
|
|
1314
1314
|
copy.push(
|
|
1315
|
-
|
|
1315
|
+
_chunkS5BKZZGMcjs.assertInteger.call(void 0, interval, `${name}[${index}]`, -MAX_CHORD_INTERVAL, MAX_CHORD_INTERVAL)
|
|
1316
1316
|
);
|
|
1317
1317
|
}
|
|
1318
1318
|
return copy;
|
|
@@ -1321,7 +1321,7 @@ function hasCustomIntervals(chord) {
|
|
|
1321
1321
|
return !matchesQualityIntervals(chord.quality, chord.intervals);
|
|
1322
1322
|
}
|
|
1323
1323
|
function chordFromSpan(span) {
|
|
1324
|
-
|
|
1324
|
+
_chunkS5BKZZGMcjs.assertRecord.call(void 0, span, "chord span");
|
|
1325
1325
|
const chord = makeChord(span.rootPc, span.quality, span.bassPc);
|
|
1326
1326
|
if (span.intervals !== void 0) {
|
|
1327
1327
|
chord.intervals = copySpanIntervals(span.intervals);
|
|
@@ -1329,7 +1329,7 @@ function chordFromSpan(span) {
|
|
|
1329
1329
|
return chord;
|
|
1330
1330
|
}
|
|
1331
1331
|
function spanFromChord(chord, startBeat) {
|
|
1332
|
-
|
|
1332
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, startBeat, "chord span startBeat");
|
|
1333
1333
|
assertChord(chord);
|
|
1334
1334
|
const span = { rootPc: chord.rootPc, quality: chord.quality, startBeat };
|
|
1335
1335
|
if (chord.bassPc !== void 0) {
|
|
@@ -1342,15 +1342,15 @@ function spanFromChord(chord, startBeat) {
|
|
|
1342
1342
|
}
|
|
1343
1343
|
function transposeChord(chord, semitones) {
|
|
1344
1344
|
assertChord(chord);
|
|
1345
|
-
|
|
1345
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, semitones, "semitones");
|
|
1346
1346
|
const steps = Math.round(semitones);
|
|
1347
1347
|
const moved = {
|
|
1348
|
-
rootPc:
|
|
1348
|
+
rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + steps),
|
|
1349
1349
|
quality: chord.quality,
|
|
1350
1350
|
intervals: [...chord.intervals]
|
|
1351
1351
|
};
|
|
1352
1352
|
if (chord.bassPc !== void 0) {
|
|
1353
|
-
moved.bassPc =
|
|
1353
|
+
moved.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc + steps);
|
|
1354
1354
|
}
|
|
1355
1355
|
return moved;
|
|
1356
1356
|
}
|
|
@@ -1366,20 +1366,20 @@ function chordToneSpellings(chord) {
|
|
|
1366
1366
|
if (hint === void 0 || interval === void 0) {
|
|
1367
1367
|
return void 0;
|
|
1368
1368
|
}
|
|
1369
|
-
if (
|
|
1369
|
+
if (_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, hint) !== _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval)) {
|
|
1370
1370
|
return void 0;
|
|
1371
1371
|
}
|
|
1372
|
-
usable.push({ letter:
|
|
1372
|
+
usable.push({ letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter });
|
|
1373
1373
|
}
|
|
1374
1374
|
return usable;
|
|
1375
1375
|
}
|
|
1376
1376
|
function chordToneLetterOffsets(chord) {
|
|
1377
1377
|
const hints = chordToneSpellings(chord);
|
|
1378
|
-
const rootHint = _optionalChain([hints, 'optionalAccess', _6 => _6[chord.intervals.findIndex((interval) =>
|
|
1378
|
+
const rootHint = _optionalChain([hints, 'optionalAccess', _6 => _6[chord.intervals.findIndex((interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval) === 0)]]);
|
|
1379
1379
|
if (hints === void 0 || rootHint === void 0) {
|
|
1380
1380
|
return void 0;
|
|
1381
1381
|
}
|
|
1382
|
-
return hints.map((hint) =>
|
|
1382
|
+
return hints.map((hint) => _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, hint.letter - rootHint.letter));
|
|
1383
1383
|
}
|
|
1384
1384
|
var ROLE_BY_LETTER_OFFSET = {
|
|
1385
1385
|
0: "root",
|
|
@@ -1394,20 +1394,20 @@ function spelledToneRole(pitch, chord) {
|
|
|
1394
1394
|
return void 0;
|
|
1395
1395
|
}
|
|
1396
1396
|
const index = chord.intervals.findIndex(
|
|
1397
|
-
(interval) =>
|
|
1397
|
+
(interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch)
|
|
1398
1398
|
);
|
|
1399
1399
|
const offset = offsets[index];
|
|
1400
1400
|
return offset === void 0 ? void 0 : _nullishCoalesce(ROLE_BY_LETTER_OFFSET[offset], () => ( null));
|
|
1401
1401
|
}
|
|
1402
1402
|
function chordPcMask(chord, opts = {}) {
|
|
1403
|
-
|
|
1404
|
-
|
|
1403
|
+
_chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, "chord");
|
|
1404
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, chord.intervals, "chord intervals");
|
|
1405
1405
|
let mask = 0;
|
|
1406
1406
|
for (const interval of chord.intervals) {
|
|
1407
|
-
mask |= 1 <<
|
|
1407
|
+
mask |= 1 << _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
1408
1408
|
}
|
|
1409
1409
|
if (opts.includeBass !== false && chord.bassPc !== void 0) {
|
|
1410
|
-
mask |= 1 <<
|
|
1410
|
+
mask |= 1 << _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc);
|
|
1411
1411
|
}
|
|
1412
1412
|
return mask;
|
|
1413
1413
|
}
|
|
@@ -1422,7 +1422,7 @@ function chordIntervalMask(chord) {
|
|
|
1422
1422
|
return mask;
|
|
1423
1423
|
}
|
|
1424
1424
|
function chordPitchClasses(chord, opts = {}) {
|
|
1425
|
-
const mask = chordPcMask(assertChord(chord),
|
|
1425
|
+
const mask = chordPcMask(assertChord(chord), _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts"));
|
|
1426
1426
|
const pcs = [];
|
|
1427
1427
|
for (let pc = 0; pc < 12; pc += 1) {
|
|
1428
1428
|
if (hasPitchClass(mask, pc)) {
|
|
@@ -1432,18 +1432,18 @@ function chordPitchClasses(chord, opts = {}) {
|
|
|
1432
1432
|
return pcs;
|
|
1433
1433
|
}
|
|
1434
1434
|
function intervalAboveRoot(pitch, chord) {
|
|
1435
|
-
return ((
|
|
1435
|
+
return ((_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, assertChord(chord).rootPc)) % 12 + 12) % 12;
|
|
1436
1436
|
}
|
|
1437
1437
|
function isChordMember(pitch, chord) {
|
|
1438
|
-
return chord === null ? false : hasPitchClass(chordPcMask(chord),
|
|
1438
|
+
return chord === null ? false : hasPitchClass(chordPcMask(chord), _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch));
|
|
1439
1439
|
}
|
|
1440
1440
|
function chordToneRole(pitch, chord) {
|
|
1441
|
-
|
|
1441
|
+
_chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, "chord");
|
|
1442
1442
|
const spelled2 = spelledToneRole(pitch, chord);
|
|
1443
1443
|
if (spelled2 !== void 0) {
|
|
1444
1444
|
return spelled2;
|
|
1445
1445
|
}
|
|
1446
|
-
const interval = (
|
|
1446
|
+
const interval = (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) + 12) % 12;
|
|
1447
1447
|
const tones = chordIntervalMask(chord);
|
|
1448
1448
|
const sounds = (ic) => hasPitchClass(tones, ic);
|
|
1449
1449
|
if (interval === 0) {
|
|
@@ -1486,7 +1486,7 @@ var DEGREE_BY_ROLE = {
|
|
|
1486
1486
|
};
|
|
1487
1487
|
var TENSION_DEGREE = [1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7];
|
|
1488
1488
|
function degreeOfInterval(interval, chord) {
|
|
1489
|
-
const role = chordToneRole(
|
|
1489
|
+
const role = chordToneRole(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval), chord);
|
|
1490
1490
|
if (role !== null) {
|
|
1491
1491
|
return DEGREE_BY_ROLE[role];
|
|
1492
1492
|
}
|
|
@@ -1510,7 +1510,7 @@ function thirdSlotOf(chord) {
|
|
|
1510
1510
|
return { kind: "none" };
|
|
1511
1511
|
}
|
|
1512
1512
|
function displacedThirds(chord) {
|
|
1513
|
-
return thirdSlotOf(chord).kind === "suspension" ? [
|
|
1513
|
+
return thirdSlotOf(chord).kind === "suspension" ? [_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + 3), _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + 4)] : [];
|
|
1514
1514
|
}
|
|
1515
1515
|
function classifyTriad(thirdIc, fifthIc) {
|
|
1516
1516
|
if (thirdIc === 4 && fifthIc === 8) {
|
|
@@ -1559,16 +1559,16 @@ function matchesQualityIntervals(quality, intervals) {
|
|
|
1559
1559
|
return template.length === intervals.length && template.every((interval, index) => interval === intervals[index]);
|
|
1560
1560
|
}
|
|
1561
1561
|
function stackThirds(degree, key, size) {
|
|
1562
|
-
|
|
1562
|
+
_chunkS5BKZZGMcjs.assertDegree.call(void 0, degree, "chord degree");
|
|
1563
1563
|
const tones = scaleTonesInDegreeOrder(key);
|
|
1564
1564
|
const length = tones.length;
|
|
1565
1565
|
if (length !== 7) {
|
|
1566
|
-
throw new (0,
|
|
1566
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1567
1567
|
`diatonic chord stacking requires a heptatonic scale (received ${length} tones)`
|
|
1568
1568
|
);
|
|
1569
1569
|
}
|
|
1570
1570
|
const idx = (step) => (degree - 1 + step) % length;
|
|
1571
|
-
const rootPc = _nullishCoalesce(tones[idx(0)], () => (
|
|
1571
|
+
const rootPc = _nullishCoalesce(tones[idx(0)], () => ( _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc)));
|
|
1572
1572
|
const offsets = [0, 2, 4, 6].slice(0, size).map((step) => {
|
|
1573
1573
|
const pc = _nullishCoalesce(tones[idx(step)], () => ( rootPc));
|
|
1574
1574
|
return ((pc - rootPc) % 12 + 12) % 12;
|
|
@@ -1577,7 +1577,7 @@ function stackThirds(degree, key, size) {
|
|
|
1577
1577
|
const fifthIc = _nullishCoalesce(offsets[2], () => ( 7));
|
|
1578
1578
|
const quality = size === 3 ? classifyTriad(thirdIc, fifthIc) : classifySeventh(thirdIc, fifthIc, _nullishCoalesce(offsets[3], () => ( 11)));
|
|
1579
1579
|
if (!matchesQualityIntervals(quality, offsets)) {
|
|
1580
|
-
throw new (0,
|
|
1580
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1581
1581
|
`scale thirds at degree ${degree} produce unsupported intervals [${offsets.join(", ")}]`
|
|
1582
1582
|
);
|
|
1583
1583
|
}
|
|
@@ -1645,20 +1645,20 @@ var CHROMATIC_SPELLING_SHARP = {
|
|
|
1645
1645
|
// M7
|
|
1646
1646
|
};
|
|
1647
1647
|
function notePitchClass(note) {
|
|
1648
|
-
return
|
|
1648
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, note.letter) + note.alter);
|
|
1649
1649
|
}
|
|
1650
1650
|
function assertTonicOf(tonic, key, source) {
|
|
1651
1651
|
const tonicPc = notePitchClass(tonic);
|
|
1652
|
-
const rootPc =
|
|
1652
|
+
const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
1653
1653
|
if (tonicPc !== rootPc) {
|
|
1654
|
-
const name =
|
|
1655
|
-
throw new (0,
|
|
1654
|
+
const name = _chunkS5BKZZGMcjs.formatNote.call(void 0, { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter });
|
|
1655
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
1656
1656
|
`${source}: tonic ${name} sounds pitch class ${tonicPc}, not the key root ${rootPc}; pass a tonic that spells the key root, or take one from spelledKeyOf`
|
|
1657
1657
|
);
|
|
1658
1658
|
}
|
|
1659
1659
|
}
|
|
1660
1660
|
function alterFor(letter, pc) {
|
|
1661
|
-
let d =
|
|
1661
|
+
let d = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, letter));
|
|
1662
1662
|
if (d > 6) {
|
|
1663
1663
|
d -= 12;
|
|
1664
1664
|
}
|
|
@@ -1668,7 +1668,7 @@ function letterFor(tonic, degreeOffset, pc) {
|
|
|
1668
1668
|
if (degreeOffset === void 0) {
|
|
1669
1669
|
return void 0;
|
|
1670
1670
|
}
|
|
1671
|
-
const letter =
|
|
1671
|
+
const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
|
|
1672
1672
|
return { letter, alter: alterFor(letter, pc) };
|
|
1673
1673
|
}
|
|
1674
1674
|
function pickSpelling(flat, sharp, preferFlat) {
|
|
@@ -1688,12 +1688,12 @@ var MAX_JOINT_TONE_COUNT = DIATONIC_LETTER_COUNT + 1;
|
|
|
1688
1688
|
var MAJOR_SEMITONES = [0, 2, 4, 5, 7, 9, 11];
|
|
1689
1689
|
var IMPERFECT_DEGREES = /* @__PURE__ */ new Set([1, 2, 5, 6]);
|
|
1690
1690
|
var DIATONIC_MODE_OFFSETS2 = MAJOR_SEMITONES.map(
|
|
1691
|
-
(tonic, mode) => MAJOR_SEMITONES.map((_, degree) =>
|
|
1691
|
+
(tonic, mode) => MAJOR_SEMITONES.map((_, degree) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, (_nullishCoalesce(MAJOR_SEMITONES[(mode + degree) % 7], () => ( 0))) - tonic))
|
|
1692
1692
|
);
|
|
1693
1693
|
function degreeStrain(tonic, note) {
|
|
1694
|
-
const letterOffset =
|
|
1695
|
-
const offset =
|
|
1696
|
-
let deviation =
|
|
1694
|
+
const letterOffset = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, note.letter - tonic.letter);
|
|
1695
|
+
const offset = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, notePitchClass(note) - notePitchClass(tonic));
|
|
1696
|
+
let deviation = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, offset - (_nullishCoalesce(MAJOR_SEMITONES[letterOffset], () => ( 0))));
|
|
1697
1697
|
if (deviation > 6) {
|
|
1698
1698
|
deviation -= 12;
|
|
1699
1699
|
}
|
|
@@ -1705,8 +1705,8 @@ function isHeptatonic(key) {
|
|
|
1705
1705
|
}
|
|
1706
1706
|
function hasMinorThird(key) {
|
|
1707
1707
|
const tones = scaleTonesInDegreeOrder(key);
|
|
1708
|
-
const root =
|
|
1709
|
-
return tones.includes(
|
|
1708
|
+
const root = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
1709
|
+
return tones.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, root + 3)) && !tones.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, root + 4));
|
|
1710
1710
|
}
|
|
1711
1711
|
function leansFlat(tonic, key) {
|
|
1712
1712
|
return tonic.alter < 0 || hasMinorThird(key);
|
|
@@ -1731,7 +1731,7 @@ function spellByParentMode(tonic, pcs, preferFlat) {
|
|
|
1731
1731
|
let alter = 0;
|
|
1732
1732
|
let signed = 0;
|
|
1733
1733
|
for (const pc of pcs) {
|
|
1734
|
-
const degree = offsets.indexOf(
|
|
1734
|
+
const degree = offsets.indexOf(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc));
|
|
1735
1735
|
const note = letterFor(tonic, degree < 0 ? void 0 : degree, pc);
|
|
1736
1736
|
if (note === void 0) {
|
|
1737
1737
|
break;
|
|
@@ -1754,7 +1754,7 @@ function spellByParentMode(tonic, pcs, preferFlat) {
|
|
|
1754
1754
|
return best;
|
|
1755
1755
|
}
|
|
1756
1756
|
function assignDistinctLetters(candidates, tonic, duplicates) {
|
|
1757
|
-
const reserved = 1 <<
|
|
1757
|
+
const reserved = 1 << _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter);
|
|
1758
1758
|
let best;
|
|
1759
1759
|
let bestStrain = 0;
|
|
1760
1760
|
let bestAlter = 0;
|
|
@@ -1797,7 +1797,7 @@ function assignDistinctLetters(candidates, tonic, duplicates) {
|
|
|
1797
1797
|
return best;
|
|
1798
1798
|
}
|
|
1799
1799
|
function spellGappedScale(tonic, key) {
|
|
1800
|
-
const cacheKey = `${
|
|
1800
|
+
const cacheKey = `${_chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter)}:${tonic.alter}:${key.rootPc}:${key.modeMask12}`;
|
|
1801
1801
|
const cached = JOINT_SPELLINGS.get(cacheKey);
|
|
1802
1802
|
if (cached !== void 0) {
|
|
1803
1803
|
return cached.spellings;
|
|
@@ -1816,11 +1816,11 @@ function readGappedScale(tonic, key) {
|
|
|
1816
1816
|
if (tones.length > MAX_JOINT_TONE_COUNT) {
|
|
1817
1817
|
return void 0;
|
|
1818
1818
|
}
|
|
1819
|
-
const tonicPc =
|
|
1820
|
-
const tonicNote = { letter:
|
|
1819
|
+
const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
|
|
1820
|
+
const tonicNote = { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
|
|
1821
1821
|
const preferFlat = leansFlat(tonic, key);
|
|
1822
|
-
const rest = tones.filter((pc) =>
|
|
1823
|
-
const candidates = rest.map((pc) => gappedCandidates(tonic,
|
|
1822
|
+
const rest = tones.filter((pc) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc) !== 0);
|
|
1823
|
+
const candidates = rest.map((pc) => gappedCandidates(tonic, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc), pc, preferFlat));
|
|
1824
1824
|
const chosen = _nullishCoalesce(_nullishCoalesce(spellByParentMode(tonicNote, rest, preferFlat), () => ( // A scale that can hold a letter per tone does; only one that cannot writes
|
|
1825
1825
|
// a letter twice, and then where the doubling falls is what is chosen.
|
|
1826
1826
|
assignDistinctLetters(candidates, tonicNote, 0))), () => ( assignDistinctLetters(candidates, tonicNote, 1)));
|
|
@@ -1831,22 +1831,22 @@ function readGappedScale(tonic, key) {
|
|
|
1831
1831
|
for (const [index, pc] of rest.entries()) {
|
|
1832
1832
|
const note = chosen[index];
|
|
1833
1833
|
if (note !== void 0) {
|
|
1834
|
-
spellings.set(
|
|
1834
|
+
spellings.set(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc), note);
|
|
1835
1835
|
}
|
|
1836
1836
|
}
|
|
1837
1837
|
return spellings;
|
|
1838
1838
|
}
|
|
1839
1839
|
function spellByKey(pc, tonic, key) {
|
|
1840
|
-
const tonicPc =
|
|
1841
|
-
const offset =
|
|
1840
|
+
const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
|
|
1841
|
+
const offset = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc);
|
|
1842
1842
|
if (offset === 0) {
|
|
1843
|
-
return { letter:
|
|
1843
|
+
return { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
|
|
1844
1844
|
}
|
|
1845
1845
|
const heptatonic = isHeptatonic(key);
|
|
1846
1846
|
if (heptatonic) {
|
|
1847
|
-
const degree = scaleTonesInDegreeOrder(key).indexOf(
|
|
1847
|
+
const degree = scaleTonesInDegreeOrder(key).indexOf(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc));
|
|
1848
1848
|
if (degree >= 0) {
|
|
1849
|
-
const letter =
|
|
1849
|
+
const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter + degree);
|
|
1850
1850
|
return { letter, alter: alterFor(letter, pc) };
|
|
1851
1851
|
}
|
|
1852
1852
|
const degreeOffset = CHROMATIC_SPELLING[offset];
|
|
@@ -1859,7 +1859,7 @@ function spellByKey(pc, tonic, key) {
|
|
|
1859
1859
|
}
|
|
1860
1860
|
} else {
|
|
1861
1861
|
if (isScaleTone(pc, key)) {
|
|
1862
|
-
const assigned = _optionalChain([spellGappedScale, 'call', _9 => _9(tonic, key), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(
|
|
1862
|
+
const assigned = _optionalChain([spellGappedScale, 'call', _9 => _9(tonic, key), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc))]);
|
|
1863
1863
|
if (assigned !== void 0) {
|
|
1864
1864
|
return { letter: assigned.letter, alter: assigned.alter };
|
|
1865
1865
|
}
|
|
@@ -1869,7 +1869,7 @@ function spellByKey(pc, tonic, key) {
|
|
|
1869
1869
|
return preferred;
|
|
1870
1870
|
}
|
|
1871
1871
|
}
|
|
1872
|
-
const belowLetter =
|
|
1872
|
+
const belowLetter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, _nullishCoalesce([0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc)], () => ( 0)));
|
|
1873
1873
|
return { letter: belowLetter, alter: alterFor(belowLetter, pc) };
|
|
1874
1874
|
}
|
|
1875
1875
|
var CHORD_TONE_LETTER_STEPS = {
|
|
@@ -1898,7 +1898,7 @@ function chordToneLetterStep(pc, rootPc, chord) {
|
|
|
1898
1898
|
if (chord !== void 0) {
|
|
1899
1899
|
const offsets = chordToneLetterOffsets(chord);
|
|
1900
1900
|
const index = chord.intervals.findIndex(
|
|
1901
|
-
(interval) =>
|
|
1901
|
+
(interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc)
|
|
1902
1902
|
);
|
|
1903
1903
|
const offset = _optionalChain([offsets, 'optionalAccess', _12 => _12[index]]);
|
|
1904
1904
|
if (offset !== void 0) {
|
|
@@ -1909,7 +1909,7 @@ function chordToneLetterStep(pc, rootPc, chord) {
|
|
|
1909
1909
|
return LETTER_STEP_BY_ROLE[role];
|
|
1910
1910
|
}
|
|
1911
1911
|
}
|
|
1912
|
-
return CHORD_TONE_LETTER_STEPS[
|
|
1912
|
+
return CHORD_TONE_LETTER_STEPS[_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - rootPc)];
|
|
1913
1913
|
}
|
|
1914
1914
|
function spellChordTone(pc, context, tonic, key) {
|
|
1915
1915
|
const { chord } = context;
|
|
@@ -1917,18 +1917,18 @@ function spellChordTone(pc, context, tonic, key) {
|
|
|
1917
1917
|
if (chordRoot === void 0) {
|
|
1918
1918
|
return void 0;
|
|
1919
1919
|
}
|
|
1920
|
-
const root = chord === void 0 ? spellByKey(
|
|
1920
|
+
const root = chord === void 0 ? spellByKey(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chordRoot), tonic, key) : chordRootSpelling(chord, tonic, key);
|
|
1921
1921
|
return letterFor(root, chordToneLetterStep(pc, chordRoot, chord), pc);
|
|
1922
1922
|
}
|
|
1923
1923
|
function neighbourSpelling(neighbour, gap, letterStep, pc, tonic, key) {
|
|
1924
|
-
if (neighbour === void 0 ||
|
|
1924
|
+
if (neighbour === void 0 || _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, neighbour - pc) !== _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, gap)) {
|
|
1925
1925
|
return void 0;
|
|
1926
1926
|
}
|
|
1927
|
-
return letterFor(spellByKey(
|
|
1927
|
+
return letterFor(spellByKey(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, neighbour), tonic, key), letterStep, pc);
|
|
1928
1928
|
}
|
|
1929
1929
|
function refineByContext(pc, tonic, key, context, keySpelling) {
|
|
1930
|
-
const tonicPc =
|
|
1931
|
-
if (
|
|
1930
|
+
const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
|
|
1931
|
+
if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc) === tonicPc || isScaleTone(pc, key)) {
|
|
1932
1932
|
return keySpelling;
|
|
1933
1933
|
}
|
|
1934
1934
|
const { previous, next } = context;
|
|
@@ -1955,10 +1955,10 @@ function refineByContext(pc, tonic, key, context, keySpelling) {
|
|
|
1955
1955
|
return keySpelling;
|
|
1956
1956
|
}
|
|
1957
1957
|
function spellPitchClass(pc, tonic, key, context) {
|
|
1958
|
-
const note =
|
|
1958
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
1959
1959
|
const scale = toKeyScale(key);
|
|
1960
1960
|
assertTonicOf(note, scale, "spellPitchClass");
|
|
1961
|
-
|
|
1961
|
+
_chunkS5BKZZGMcjs.assertOptions.call(void 0, context, "context");
|
|
1962
1962
|
return spelledPitchClass(pc, note, scale, context);
|
|
1963
1963
|
}
|
|
1964
1964
|
function spelledPitchClass(pc, tonic, key, context) {
|
|
@@ -1966,18 +1966,18 @@ function spelledPitchClass(pc, tonic, key, context) {
|
|
|
1966
1966
|
return context === void 0 ? keySpelling : refineByContext(pc, tonic, key, context, keySpelling);
|
|
1967
1967
|
}
|
|
1968
1968
|
function spellScale(tonic, key) {
|
|
1969
|
-
const note =
|
|
1969
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
1970
1970
|
const scale = toKeyScale(key);
|
|
1971
1971
|
assertTonicOf(note, scale, "spellScale");
|
|
1972
1972
|
return scaleTonesInDegreeOrder(scale).map((pc) => spelledPitchClass(pc, note, scale));
|
|
1973
1973
|
}
|
|
1974
1974
|
function spellPitchClasses(pcs, tonic, key) {
|
|
1975
|
-
const classes =
|
|
1976
|
-
const note =
|
|
1975
|
+
const classes = _chunkS5BKZZGMcjs.assertArray.call(void 0, pcs, "pcs");
|
|
1976
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
1977
1977
|
const scale = toKeyScale(key);
|
|
1978
1978
|
assertTonicOf(note, scale, "spellPitchClasses");
|
|
1979
1979
|
return classes.map(
|
|
1980
|
-
(pc, index) => spelledPitchClass(
|
|
1980
|
+
(pc, index) => spelledPitchClass(_chunkS5BKZZGMcjs.assertPitchClass.call(void 0, pc, `pcs[${index}]`), note, scale)
|
|
1981
1981
|
);
|
|
1982
1982
|
}
|
|
1983
1983
|
function chordLetterOffset(interval, chord) {
|
|
@@ -2017,74 +2017,74 @@ function chordLetterOffset(interval, chord) {
|
|
|
2017
2017
|
return 6;
|
|
2018
2018
|
default: {
|
|
2019
2019
|
const octaves = Math.floor(Math.max(0, interval) / 12);
|
|
2020
|
-
const simple =
|
|
2020
|
+
const simple = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval);
|
|
2021
2021
|
const simpleOffset = _nullishCoalesce([0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6][simple], () => ( 0));
|
|
2022
2022
|
return octaves * 7 + simpleOffset;
|
|
2023
2023
|
}
|
|
2024
2024
|
}
|
|
2025
2025
|
}
|
|
2026
2026
|
function spellChordFromRoot(chord, root) {
|
|
2027
|
-
return chordTonesFromRoot(assertChord(chord),
|
|
2027
|
+
return chordTonesFromRoot(assertChord(chord), _chunkS5BKZZGMcjs.toNoteData.call(void 0, root));
|
|
2028
2028
|
}
|
|
2029
2029
|
function chordTonesFromRoot(chord, root) {
|
|
2030
|
-
if (
|
|
2031
|
-
throw new (0,
|
|
2030
|
+
if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, root.letter) + root.alter) !== _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc)) {
|
|
2031
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("chord root spelling must match chord.rootPc");
|
|
2032
2032
|
}
|
|
2033
2033
|
const hinted = chordToneLetterOffsets(chord);
|
|
2034
2034
|
return chord.intervals.map((interval, index) => {
|
|
2035
|
-
const letter =
|
|
2036
|
-
const pc =
|
|
2035
|
+
const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, root.letter + (_nullishCoalesce(_optionalChain([hinted, 'optionalAccess', _14 => _14[index]]), () => ( chordLetterOffset(interval, chord)))));
|
|
2036
|
+
const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
2037
2037
|
return { letter, alter: alterFor(letter, pc) };
|
|
2038
2038
|
});
|
|
2039
2039
|
}
|
|
2040
2040
|
function spellChord(chord, tonic, key) {
|
|
2041
2041
|
assertChord(chord);
|
|
2042
|
-
const note =
|
|
2042
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
2043
2043
|
const scale = toKeyScale(key);
|
|
2044
2044
|
assertTonicOf(note, scale, "spellChord");
|
|
2045
2045
|
return chordTonesFromRoot(chord, chordRootSpelling(chord, note, scale));
|
|
2046
2046
|
}
|
|
2047
2047
|
function chordRootSpelling(chord, tonic, key) {
|
|
2048
2048
|
const hint = chord.rootSpelling;
|
|
2049
|
-
if (hint !== void 0 &&
|
|
2050
|
-
return { letter:
|
|
2049
|
+
if (hint !== void 0 && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, hint.letter) + hint.alter) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc)) {
|
|
2050
|
+
return { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter };
|
|
2051
2051
|
}
|
|
2052
2052
|
return spelledPitchClass(chord.rootPc, tonic, key);
|
|
2053
2053
|
}
|
|
2054
2054
|
function spellPitch(pitch, tonic, key, context) {
|
|
2055
|
-
const note =
|
|
2055
|
+
const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
|
|
2056
2056
|
const scale = toKeyScale(key);
|
|
2057
2057
|
assertTonicOf(note, scale, "spellPitch");
|
|
2058
|
-
|
|
2059
|
-
const rounded = Math.round(
|
|
2060
|
-
const spelled2 = spelledPitchClass(
|
|
2061
|
-
const octave = (rounded -
|
|
2058
|
+
_chunkS5BKZZGMcjs.assertOptions.call(void 0, context, "context");
|
|
2059
|
+
const rounded = Math.round(_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, pitch, "pitch"));
|
|
2060
|
+
const spelled2 = spelledPitchClass(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rounded), note, scale, context);
|
|
2061
|
+
const octave = (rounded - _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, spelled2.letter) - spelled2.alter) / 12 - 1;
|
|
2062
2062
|
return { letter: spelled2.letter, alter: spelled2.alter, octave };
|
|
2063
2063
|
}
|
|
2064
2064
|
function noteNames(notes) {
|
|
2065
|
-
|
|
2066
|
-
return notes.map((note) =>
|
|
2065
|
+
_chunkS5BKZZGMcjs.assertArray.call(void 0, notes, "notes");
|
|
2066
|
+
return notes.map((note) => _chunkS5BKZZGMcjs.formatNote.call(void 0, _chunkS5BKZZGMcjs.toNoteData.call(void 0, note)));
|
|
2067
2067
|
}
|
|
2068
2068
|
|
|
2069
2069
|
// src/theory/counterpoint/internal.ts
|
|
2070
2070
|
function assertQualityLabel(quality) {
|
|
2071
2071
|
if (typeof quality !== "string" || !/^(P|M|m|A+|d+)$/.test(quality)) {
|
|
2072
|
-
throw new (0,
|
|
2073
|
-
`interval.quality must be an interval quality; received ${
|
|
2072
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
2073
|
+
`interval.quality must be an interval quality; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, quality)}`
|
|
2074
2074
|
);
|
|
2075
2075
|
}
|
|
2076
2076
|
return quality;
|
|
2077
2077
|
}
|
|
2078
2078
|
function pitchOf(value) {
|
|
2079
|
-
return typeof value === "number" ? value :
|
|
2079
|
+
return typeof value === "number" ? value : _chunkS5BKZZGMcjs.noteToMidi.call(void 0, value);
|
|
2080
2080
|
}
|
|
2081
2081
|
function simpleIntervalNumber(numberValue) {
|
|
2082
2082
|
return (Math.abs(numberValue) - 1) % 7 + 1;
|
|
2083
2083
|
}
|
|
2084
2084
|
function classifySpelledInterval(interval, twoVoice = true) {
|
|
2085
|
-
|
|
2086
|
-
const read =
|
|
2087
|
-
const simple = simpleIntervalNumber(
|
|
2085
|
+
_chunkS5BKZZGMcjs.assertFlag.call(void 0, twoVoice, "twoVoice");
|
|
2086
|
+
const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, interval, "interval");
|
|
2087
|
+
const simple = simpleIntervalNumber(_chunkS5BKZZGMcjs.assertDegree.call(void 0, read.number, "interval.number"));
|
|
2088
2088
|
const quality = assertQualityLabel(read.quality);
|
|
2089
2089
|
if (quality === "P") {
|
|
2090
2090
|
if (simple === 1 || simple === 5) {
|
|
@@ -2131,16 +2131,16 @@ function motionBetween(from, to) {
|
|
|
2131
2131
|
if (leadMove > 0 !== counterMove > 0) {
|
|
2132
2132
|
return "contrary";
|
|
2133
2133
|
}
|
|
2134
|
-
const before = simpleIntervalNumber(
|
|
2135
|
-
const after = simpleIntervalNumber(
|
|
2134
|
+
const before = simpleIntervalNumber(_chunkS5BKZZGMcjs.spelledInterval.call(void 0, from.counter, from.lead).number);
|
|
2135
|
+
const after = simpleIntervalNumber(_chunkS5BKZZGMcjs.spelledInterval.call(void 0, to.counter, to.lead).number);
|
|
2136
2136
|
return before === after ? "parallel" : "similar";
|
|
2137
2137
|
}
|
|
2138
2138
|
function voiceIndependence(lead, counter, opts) {
|
|
2139
|
-
|
|
2140
|
-
const upper =
|
|
2141
|
-
const lower =
|
|
2139
|
+
_chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
2140
|
+
const upper = _chunkS5BKZZGMcjs.assertArray.call(void 0, lead, "lead");
|
|
2141
|
+
const lower = _chunkS5BKZZGMcjs.assertArray.call(void 0, counter, "counter");
|
|
2142
2142
|
if (upper.length !== lower.length) {
|
|
2143
|
-
throw new (0,
|
|
2143
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
2144
2144
|
`voiceIndependence needs the two lines aligned slot for slot; received ${upper.length} and ${lower.length}`
|
|
2145
2145
|
);
|
|
2146
2146
|
}
|
|
@@ -2149,7 +2149,7 @@ function voiceIndependence(lead, counter, opts) {
|
|
|
2149
2149
|
["counterAttacks", _optionalChain([opts, 'optionalAccess', _16 => _16.counterAttacks])]
|
|
2150
2150
|
]) {
|
|
2151
2151
|
if (flags !== void 0 && flags.length !== upper.length) {
|
|
2152
|
-
throw new (0,
|
|
2152
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
2153
2153
|
`voiceIndependence needs ${name} aligned slot for slot with the lines; received ${flags.length} and ${upper.length}`
|
|
2154
2154
|
);
|
|
2155
2155
|
}
|
|
@@ -2206,7 +2206,7 @@ function voiceIndependence(lead, counter, opts) {
|
|
|
2206
2206
|
totalGap += Math.abs(gap);
|
|
2207
2207
|
minGap = Math.min(minGap, Math.abs(gap));
|
|
2208
2208
|
orderSum += Math.sign(gap);
|
|
2209
|
-
const interval =
|
|
2209
|
+
const interval = _chunkS5BKZZGMcjs.spelledInterval.call(void 0, slot.counter, slot.lead);
|
|
2210
2210
|
const perfect = classifySpelledInterval(interval) === 0 /* PerfectConsonance */ || (_nullishCoalesce(_optionalChain([opts, 'optionalAccess', _19 => _19.countFourths]), () => ( false))) && interval.quality === "P" && simpleIntervalNumber(interval.number) === 4;
|
|
2211
2211
|
perfectRun = perfect ? perfectRun + 1 : 0;
|
|
2212
2212
|
longestPerfectRun = Math.max(longestPerfectRun, perfectRun);
|
|
@@ -2247,13 +2247,13 @@ function createsVoiceCrossing(upper, lower) {
|
|
|
2247
2247
|
}
|
|
2248
2248
|
function createsVerticalDissonance(a, b, twoVoice) {
|
|
2249
2249
|
if (typeof a !== "number" && typeof b !== "number") {
|
|
2250
|
-
return classifySpelledInterval(
|
|
2250
|
+
return classifySpelledInterval(_chunkS5BKZZGMcjs.spelledInterval.call(void 0, a, b), twoVoice) === 2 /* Dissonance */;
|
|
2251
2251
|
}
|
|
2252
|
-
return !
|
|
2252
|
+
return !_chunkS5BKZZGMcjs.isConsonantInterval.call(void 0, pitchOf(a) - pitchOf(b), twoVoice);
|
|
2253
2253
|
}
|
|
2254
2254
|
function isForbiddenMelodicLeap(prev, cur) {
|
|
2255
2255
|
if (typeof prev !== "number" && typeof cur !== "number") {
|
|
2256
|
-
const interval =
|
|
2256
|
+
const interval = _chunkS5BKZZGMcjs.spelledInterval.call(void 0, prev, cur);
|
|
2257
2257
|
if (Math.abs(interval.semitones) > 12 || interval.number > 8) {
|
|
2258
2258
|
return true;
|
|
2259
2259
|
}
|
|
@@ -2272,11 +2272,11 @@ function isAugmentedMelodicInterval(prev, cur) {
|
|
|
2272
2272
|
if (typeof prev === "number" || typeof cur === "number") {
|
|
2273
2273
|
return false;
|
|
2274
2274
|
}
|
|
2275
|
-
const interval =
|
|
2275
|
+
const interval = _chunkS5BKZZGMcjs.spelledInterval.call(void 0, prev, cur);
|
|
2276
2276
|
return interval.number >= 2 && interval.quality.startsWith("A");
|
|
2277
2277
|
}
|
|
2278
2278
|
function simpleClass(semitones) {
|
|
2279
|
-
return
|
|
2279
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, Math.abs(semitones));
|
|
2280
2280
|
}
|
|
2281
2281
|
function isPerfectClass(cls) {
|
|
2282
2282
|
return cls === 0 || cls === 7;
|
|
@@ -2320,7 +2320,7 @@ function createsParallelUnison(aPrev, aCur, bPrev, bCur) {
|
|
|
2320
2320
|
return a1 === b1 && a0 === b0;
|
|
2321
2321
|
}
|
|
2322
2322
|
function createsHiddenParallelPerfect(aPrev, aCur, bPrev, bCur, strictness = "fourPart") {
|
|
2323
|
-
|
|
2323
|
+
_chunkS5BKZZGMcjs.assertOneOf.call(void 0, strictness, HIDDEN_PARALLEL_READINGS, "strictness");
|
|
2324
2324
|
const a0 = pitchOf(aPrev);
|
|
2325
2325
|
const a1 = pitchOf(aCur);
|
|
2326
2326
|
const b0 = pitchOf(bPrev);
|
|
@@ -2370,15 +2370,15 @@ function createsVoiceOverlap(upperPrev, upperCur, lowerPrev, lowerCur) {
|
|
|
2370
2370
|
return u1 < l0 || l1 > u0;
|
|
2371
2371
|
}
|
|
2372
2372
|
function exceedsSpacing(upper, lower, maxSemitones = 12) {
|
|
2373
|
-
|
|
2373
|
+
_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, maxSemitones, "maxSemitones");
|
|
2374
2374
|
return Math.abs(pitchOf(upper) - pitchOf(lower)) > maxSemitones;
|
|
2375
2375
|
}
|
|
2376
2376
|
function isLeadingToneResolution(prev, cur, key) {
|
|
2377
2377
|
const prevPitch = pitchOf(prev);
|
|
2378
2378
|
const curPitch = pitchOf(cur);
|
|
2379
|
-
const tonic =
|
|
2379
|
+
const tonic = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, toKeyScale(key).rootPc);
|
|
2380
2380
|
const leading = (tonic + 11) % 12;
|
|
2381
|
-
if (
|
|
2381
|
+
if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, prevPitch) !== leading || _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, curPitch) !== tonic) {
|
|
2382
2382
|
return false;
|
|
2383
2383
|
}
|
|
2384
2384
|
return curPitch > prevPitch && curPitch - prevPitch <= 2;
|
|
@@ -2417,17 +2417,17 @@ var PROFILE_WEIGHTS = Object.freeze({
|
|
|
2417
2417
|
});
|
|
2418
2418
|
var SAFETY_PROFILES = Object.keys(PROFILE_WEIGHTS);
|
|
2419
2419
|
function profileWeights(profile, overrides) {
|
|
2420
|
-
const base = PROFILE_WEIGHTS[
|
|
2420
|
+
const base = PROFILE_WEIGHTS[_chunkS5BKZZGMcjs.assertOneOf.call(void 0, profile, SAFETY_PROFILES, "safety profile")];
|
|
2421
2421
|
if (overrides === void 0) {
|
|
2422
2422
|
return { ...base };
|
|
2423
2423
|
}
|
|
2424
|
-
|
|
2424
|
+
_chunkS5BKZZGMcjs.assertRecord.call(void 0, overrides, "overrides");
|
|
2425
2425
|
const weights = { ...base };
|
|
2426
2426
|
for (const [field, value] of Object.entries(overrides)) {
|
|
2427
2427
|
if (value === void 0) {
|
|
2428
2428
|
continue;
|
|
2429
2429
|
}
|
|
2430
|
-
weights[field] =
|
|
2430
|
+
weights[field] = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, value, `weight ${field}`);
|
|
2431
2431
|
}
|
|
2432
2432
|
return weights;
|
|
2433
2433
|
}
|
|
@@ -2494,7 +2494,7 @@ function avoidsMajorSeventh(chord) {
|
|
|
2494
2494
|
return chord.intervals.includes(4) && chord.intervals.includes(10);
|
|
2495
2495
|
}
|
|
2496
2496
|
function isStructuralChordDissonance(a, b, chord) {
|
|
2497
|
-
const rawClass =
|
|
2497
|
+
const rawClass = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, Math.abs(a - b));
|
|
2498
2498
|
const aOffset = intervalAboveRoot(a, chord);
|
|
2499
2499
|
const bOffset = intervalAboveRoot(b, chord);
|
|
2500
2500
|
const rootSeventh = aOffset === 0 && (bOffset === 10 || bOffset === 11) || bOffset === 0 && (aOffset === 10 || aOffset === 11);
|
|
@@ -2513,32 +2513,33 @@ function stepResolution(pitch, chord) {
|
|
|
2513
2513
|
}
|
|
2514
2514
|
function evaluateSafety(q, opts = {}) {
|
|
2515
2515
|
assertSafetyContext(q);
|
|
2516
|
-
|
|
2517
|
-
|
|
2516
|
+
_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.candidatePitch, "candidatePitch");
|
|
2517
|
+
const options = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
2518
|
+
return evaluateInternal(q, _nullishCoalesce(options.suggestions, () => ( true)), _nullishCoalesce(options.partners, () => ( false)));
|
|
2518
2519
|
}
|
|
2519
2520
|
function assertSafetyContext(q) {
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
if (q.prevPitch !== void 0)
|
|
2523
|
-
if (q.vocalLow !== void 0)
|
|
2524
|
-
if (q.vocalHigh !== void 0)
|
|
2521
|
+
_chunkS5BKZZGMcjs.assertRecord.call(void 0, q, "safety query");
|
|
2522
|
+
_chunkS5BKZZGMcjs.assertOneOf.call(void 0, q.profile, SAFETY_PROFILES, "safety profile");
|
|
2523
|
+
if (q.prevPitch !== void 0) _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.prevPitch, "prevPitch");
|
|
2524
|
+
if (q.vocalLow !== void 0) _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.vocalLow, "vocalLow");
|
|
2525
|
+
if (q.vocalHigh !== void 0) _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.vocalHigh, "vocalHigh");
|
|
2525
2526
|
if (q.vocalLow !== void 0 && q.vocalHigh !== void 0 && q.vocalLow > q.vocalHigh) {
|
|
2526
|
-
throw new (0,
|
|
2527
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("vocalLow must not exceed vocalHigh");
|
|
2527
2528
|
}
|
|
2528
2529
|
if (!Array.isArray(q.otherVoices)) {
|
|
2529
|
-
throw new (0,
|
|
2530
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`otherVoices must be an array; received ${typeof q.otherVoices}`);
|
|
2530
2531
|
}
|
|
2531
|
-
|
|
2532
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, q.otherVoices.length, "other voices");
|
|
2532
2533
|
for (let index = 0; index < q.otherVoices.length; index += 1) {
|
|
2533
2534
|
const voice = q.otherVoices[index];
|
|
2534
2535
|
if (!voice) continue;
|
|
2535
|
-
|
|
2536
|
+
_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, voice.pitch, `otherVoices[${index}].pitch`);
|
|
2536
2537
|
if (voice.prevPitch !== void 0) {
|
|
2537
|
-
|
|
2538
|
+
_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, voice.prevPitch, `otherVoices[${index}].prevPitch`);
|
|
2538
2539
|
}
|
|
2539
2540
|
}
|
|
2540
2541
|
}
|
|
2541
|
-
function evaluateInternal(q, collectSuggestions) {
|
|
2542
|
+
function evaluateInternal(q, collectSuggestions, collectPartners) {
|
|
2542
2543
|
let reasons = 0;
|
|
2543
2544
|
let level = 0 /* Safe */;
|
|
2544
2545
|
let resolveTo;
|
|
@@ -2609,41 +2610,58 @@ function evaluateInternal(q, collectSuggestions) {
|
|
|
2609
2610
|
reasons |= 512 /* MajorSeventh */;
|
|
2610
2611
|
}
|
|
2611
2612
|
}
|
|
2613
|
+
let bass = pitch;
|
|
2614
|
+
let top = pitch;
|
|
2615
|
+
for (const ov of q.otherVoices) {
|
|
2616
|
+
bass = Math.min(bass, ov.pitch);
|
|
2617
|
+
top = Math.max(top, ov.pitch);
|
|
2618
|
+
}
|
|
2619
|
+
const pairReasons = collectPartners ? new Array(q.otherVoices.length).fill(0) : void 0;
|
|
2620
|
+
const flagPair = (index, flag) => {
|
|
2621
|
+
reasons |= flag;
|
|
2622
|
+
if (pairReasons !== void 0) {
|
|
2623
|
+
pairReasons[index] = (_nullishCoalesce(pairReasons[index], () => ( 0))) | flag;
|
|
2624
|
+
}
|
|
2625
|
+
};
|
|
2612
2626
|
if (q.strongBeat) {
|
|
2613
|
-
const twoVoice = q.otherVoices.length === 1;
|
|
2614
2627
|
const prev = q.prevPitch;
|
|
2615
|
-
for (const ov of q.otherVoices) {
|
|
2616
|
-
|
|
2628
|
+
for (const [index, ov] of q.otherVoices.entries()) {
|
|
2629
|
+
const againstBass = pitch === bass || ov.pitch === bass;
|
|
2630
|
+
if (!createsVerticalDissonance(pitch, ov.pitch, againstBass)) {
|
|
2617
2631
|
continue;
|
|
2618
2632
|
}
|
|
2619
2633
|
if (chord && isStructuralChordDissonance(pitch, ov.pitch, chord)) {
|
|
2620
2634
|
continue;
|
|
2621
2635
|
}
|
|
2622
|
-
|
|
2636
|
+
if (chord && q.profile === "pop" && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, Math.abs(pitch - ov.pitch)) === 5 && isChordMember(pitch, chord) && isChordMember(ov.pitch, chord)) {
|
|
2637
|
+
continue;
|
|
2638
|
+
}
|
|
2639
|
+
flagPair(index, 1024 /* VerticalDissonance */);
|
|
2623
2640
|
raise(2 /* Dissonant */);
|
|
2624
|
-
if (prev !== void 0 && pitch === prev && ov.prevPitch !== void 0 && !createsVerticalDissonance(prev, ov.prevPitch,
|
|
2625
|
-
|
|
2641
|
+
if (prev !== void 0 && pitch === prev && ov.prevPitch !== void 0 && !createsVerticalDissonance(prev, ov.prevPitch, againstBass)) {
|
|
2642
|
+
flagPair(index, 16384 /* Suspension */);
|
|
2626
2643
|
}
|
|
2627
2644
|
}
|
|
2628
2645
|
}
|
|
2629
2646
|
if (q.prevPitch !== void 0) {
|
|
2630
2647
|
const prev = q.prevPitch;
|
|
2631
|
-
for (const ov of q.otherVoices) {
|
|
2648
|
+
for (const [index, ov] of q.otherVoices.entries()) {
|
|
2632
2649
|
if (ov.prevPitch === void 0) {
|
|
2633
2650
|
continue;
|
|
2634
2651
|
}
|
|
2635
2652
|
if (createsParallelPerfect(prev, pitch, ov.prevPitch, ov.pitch)) {
|
|
2636
|
-
|
|
2653
|
+
flagPair(index, 2048 /* ParallelPerfect */);
|
|
2637
2654
|
raise(parallelSeverity);
|
|
2638
2655
|
}
|
|
2639
|
-
|
|
2640
|
-
|
|
2656
|
+
const outerPair = pitch === top && ov.pitch === bass || pitch === bass && ov.pitch === top;
|
|
2657
|
+
if (outerPair && createsHiddenParallelPerfect(prev, pitch, ov.prevPitch, ov.pitch)) {
|
|
2658
|
+
flagPair(index, 4096 /* HiddenParallel */);
|
|
2641
2659
|
raise(parallelSeverity);
|
|
2642
2660
|
}
|
|
2643
2661
|
const crossedNow = pitch - ov.pitch;
|
|
2644
2662
|
const crossedPrev = prev - ov.prevPitch;
|
|
2645
2663
|
if (crossedNow !== 0 && crossedPrev !== 0 && crossedNow > 0 !== crossedPrev > 0) {
|
|
2646
|
-
|
|
2664
|
+
flagPair(index, 8192 /* VoiceCrossing */);
|
|
2647
2665
|
raise(parallelSeverity);
|
|
2648
2666
|
}
|
|
2649
2667
|
}
|
|
@@ -2659,6 +2677,17 @@ function evaluateInternal(q, collectSuggestions) {
|
|
|
2659
2677
|
result.suggestions = suggestions;
|
|
2660
2678
|
}
|
|
2661
2679
|
}
|
|
2680
|
+
if (pairReasons !== void 0) {
|
|
2681
|
+
const partners = [];
|
|
2682
|
+
pairReasons.forEach((pair, index) => {
|
|
2683
|
+
if (pair !== 0) {
|
|
2684
|
+
partners.push({ index, reasons: pair });
|
|
2685
|
+
}
|
|
2686
|
+
});
|
|
2687
|
+
if (partners.length > 0) {
|
|
2688
|
+
result.partners = partners;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2662
2691
|
return result;
|
|
2663
2692
|
}
|
|
2664
2693
|
function findSafeNearby(q, candidate) {
|
|
@@ -2668,7 +2697,7 @@ function findSafeNearby(q, candidate) {
|
|
|
2668
2697
|
if (p < 0 || p > 127) {
|
|
2669
2698
|
continue;
|
|
2670
2699
|
}
|
|
2671
|
-
if (evaluateInternal({ ...q, candidatePitch: p }, false).safety === 0 /* Safe */) {
|
|
2700
|
+
if (evaluateInternal({ ...q, candidatePitch: p }, false, false).safety === 0 /* Safe */) {
|
|
2672
2701
|
out.push(p);
|
|
2673
2702
|
if (out.length >= MAX_SUGGESTIONS) {
|
|
2674
2703
|
return out;
|
|
@@ -2692,7 +2721,7 @@ var REASON_TEXT = [
|
|
|
2692
2721
|
[2048 /* ParallelPerfect */, "Parallel perfect interval with another voice"],
|
|
2693
2722
|
[4096 /* HiddenParallel */, "Hidden perfect interval by similar motion"],
|
|
2694
2723
|
[8192 /* VoiceCrossing */, "Crosses another voice"],
|
|
2695
|
-
[128 /* LargeLeap */, "
|
|
2724
|
+
[128 /* LargeLeap */, "Forbidden melodic leap \u2014 a seventh or wider than an octave"],
|
|
2696
2725
|
[32768 /* NeedsResolution */, "Dissonance awaiting a stepwise resolution"],
|
|
2697
2726
|
[2 /* Tension */, "Chord tension"],
|
|
2698
2727
|
[8 /* ScaleTone */, "Scale tone, not in the chord"],
|
|
@@ -2726,18 +2755,18 @@ function enumerateSafePitches(q, pitchLow, pitchHigh) {
|
|
|
2726
2755
|
assertSafetyContext(q);
|
|
2727
2756
|
const chordTones = [];
|
|
2728
2757
|
const others = [];
|
|
2729
|
-
|
|
2730
|
-
|
|
2758
|
+
_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, pitchLow, "pitchLow");
|
|
2759
|
+
_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, pitchHigh, "pitchHigh");
|
|
2731
2760
|
if (pitchLow > pitchHigh) {
|
|
2732
|
-
throw new (0,
|
|
2761
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
2733
2762
|
`pitchLow must not exceed pitchHigh; received ${pitchLow} > ${pitchHigh}`
|
|
2734
2763
|
);
|
|
2735
2764
|
}
|
|
2736
|
-
|
|
2765
|
+
_chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, pitchHigh - pitchLow + 1, "safe pitch candidates");
|
|
2737
2766
|
const low = Math.max(pitchLow, _nullishCoalesce(q.vocalLow, () => ( pitchLow)));
|
|
2738
2767
|
const high = Math.min(pitchHigh, _nullishCoalesce(q.vocalHigh, () => ( pitchHigh)));
|
|
2739
2768
|
for (let pitch = high; pitch >= low; pitch -= 1) {
|
|
2740
|
-
const result = evaluateInternal({ ...q, candidatePitch: pitch }, false);
|
|
2769
|
+
const result = evaluateInternal({ ...q, candidatePitch: pitch }, false, false);
|
|
2741
2770
|
if (result.safety === 2 /* Dissonant */) {
|
|
2742
2771
|
continue;
|
|
2743
2772
|
}
|
|
@@ -3142,10 +3171,10 @@ function suffixSpec(suffix) {
|
|
|
3142
3171
|
return quality === void 0 ? structuralSpec(suffix) : chordSpecForQuality(quality, 0);
|
|
3143
3172
|
}
|
|
3144
3173
|
function assertNamingSystem(system) {
|
|
3145
|
-
|
|
3174
|
+
_chunkS5BKZZGMcjs.formatNote.call(void 0, SYSTEM_PROBE, { system });
|
|
3146
3175
|
}
|
|
3147
3176
|
function bareNote(text, system) {
|
|
3148
|
-
const read =
|
|
3177
|
+
const read = _chunkS5BKZZGMcjs.tryParseNote.call(void 0, text, { system });
|
|
3149
3178
|
if (!read.ok) {
|
|
3150
3179
|
return void 0;
|
|
3151
3180
|
}
|
|
@@ -3155,11 +3184,11 @@ function rootSplits(text, system) {
|
|
|
3155
3184
|
if (system === "english") {
|
|
3156
3185
|
const match = text.match(ROOT_RE);
|
|
3157
3186
|
const token = _optionalChain([match, 'optionalAccess', _22 => _22[0]]);
|
|
3158
|
-
return token === void 0 ? [] : [{ root:
|
|
3187
|
+
return token === void 0 ? [] : [{ root: _chunkS5BKZZGMcjs.parseNote.call(void 0, token, { system }), rest: text.slice(token.length) }];
|
|
3159
3188
|
}
|
|
3160
3189
|
assertNamingSystem(system);
|
|
3161
3190
|
const splits = [];
|
|
3162
|
-
const longest = Math.min(text.length,
|
|
3191
|
+
const longest = Math.min(text.length, _chunkS5BKZZGMcjs.maxNoteNameLength.call(void 0, system));
|
|
3163
3192
|
for (let end = longest; end > 0; end -= 1) {
|
|
3164
3193
|
const root = bareNote(text.slice(0, end), system);
|
|
3165
3194
|
if (root !== void 0) {
|
|
@@ -3170,14 +3199,14 @@ function rootSplits(text, system) {
|
|
|
3170
3199
|
}
|
|
3171
3200
|
function bassNote(text, system) {
|
|
3172
3201
|
if (system === "english") {
|
|
3173
|
-
return BASS_RE.test(text) ?
|
|
3202
|
+
return BASS_RE.test(text) ? _chunkS5BKZZGMcjs.parseNote.call(void 0, text, { system }) : void 0;
|
|
3174
3203
|
}
|
|
3175
3204
|
return bareNote(text, system);
|
|
3176
3205
|
}
|
|
3177
3206
|
function makeSpelledChord(root, spec, bass) {
|
|
3178
|
-
const rooted = { ...spec, rootPc:
|
|
3207
|
+
const rooted = { ...spec, rootPc: _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, root) };
|
|
3179
3208
|
if (bass !== void 0) {
|
|
3180
|
-
rooted.bassPc =
|
|
3209
|
+
rooted.bassPc = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, bass);
|
|
3181
3210
|
}
|
|
3182
3211
|
const chord = chordFromSpec(rooted);
|
|
3183
3212
|
chord.rootSpelling = { letter: root.letter, alter: root.alter };
|
|
@@ -3322,21 +3351,21 @@ function bareSpelling(note) {
|
|
|
3322
3351
|
return { letter: note.letter, alter: note.alter };
|
|
3323
3352
|
}
|
|
3324
3353
|
function plainSpelling(pc, asFlat) {
|
|
3325
|
-
return bareSpelling(
|
|
3354
|
+
return bareSpelling(_chunkS5BKZZGMcjs.midiToNote.call(void 0, 60 + pc, asFlat ? "flat" : "sharp"));
|
|
3326
3355
|
}
|
|
3327
3356
|
function symbolName(note, system) {
|
|
3328
|
-
const name =
|
|
3357
|
+
const name = _chunkS5BKZZGMcjs.formatNote.call(void 0, note, { system });
|
|
3329
3358
|
return system === "german" ? `${name.slice(0, 1).toUpperCase()}${name.slice(1)}` : name;
|
|
3330
3359
|
}
|
|
3331
3360
|
function isWrittenSpelling(spelling) {
|
|
3332
|
-
const written =
|
|
3333
|
-
60 +
|
|
3361
|
+
const written = _chunkS5BKZZGMcjs.midiToNote.call(void 0,
|
|
3362
|
+
60 + _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, spelling),
|
|
3334
3363
|
spelling.alter < 0 ? "flat" : "sharp"
|
|
3335
3364
|
);
|
|
3336
3365
|
return written.letter === spelling.letter && written.alter === spelling.alter;
|
|
3337
3366
|
}
|
|
3338
3367
|
function pitchClassName(pc, hint, system, flats, inheritFlats) {
|
|
3339
|
-
if (flats === void 0 && hint !== void 0 &&
|
|
3368
|
+
if (flats === void 0 && hint !== void 0 && _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, hint) === pc) {
|
|
3340
3369
|
return symbolName(hint, system);
|
|
3341
3370
|
}
|
|
3342
3371
|
return symbolName(plainSpelling(pc, _nullishCoalesce(_nullishCoalesce(flats, () => ( inheritFlats)), () => ( false))), system);
|
|
@@ -3345,19 +3374,19 @@ function onAccidentalSide(spelling, flats) {
|
|
|
3345
3374
|
return flats === void 0 || spelling.alter === 0 || spelling.alter < 0 === flats;
|
|
3346
3375
|
}
|
|
3347
3376
|
function bySameStep(spelling, from, to) {
|
|
3348
|
-
return bareSpelling(
|
|
3377
|
+
return bareSpelling(_chunkS5BKZZGMcjs.transposeByInterval.call(void 0, spelling, _chunkS5BKZZGMcjs.spelledInterval.call(void 0, from, to)));
|
|
3349
3378
|
}
|
|
3350
3379
|
function spellingAbove(root, letters, pc) {
|
|
3351
3380
|
const letter = ((root.letter + letters) % 7 + 7) % 7;
|
|
3352
|
-
const natural =
|
|
3381
|
+
const natural = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, { letter, alter: 0 });
|
|
3353
3382
|
return { letter, alter: ((pc - natural) % 12 + 18) % 12 - 6 };
|
|
3354
3383
|
}
|
|
3355
3384
|
function carriedBass(spelling, from, to, asFlat, isOwnSpelling) {
|
|
3356
3385
|
const carried = bySameStep(spelling, from, to);
|
|
3357
|
-
return isOwnSpelling(carried) || isWrittenSpelling(carried) ? carried : plainSpelling(
|
|
3386
|
+
return isOwnSpelling(carried) || isWrittenSpelling(carried) ? carried : plainSpelling(_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, carried), asFlat);
|
|
3358
3387
|
}
|
|
3359
3388
|
function hintFor(hint, pc) {
|
|
3360
|
-
return hint !== void 0 &&
|
|
3389
|
+
return hint !== void 0 && _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, hint) === pc ? hint : void 0;
|
|
3361
3390
|
}
|
|
3362
3391
|
function rootSpellingFor(pc, hint, flats) {
|
|
3363
3392
|
return hint !== void 0 && onAccidentalSide(hint, flats) ? hint : plainSpelling(pc, _nullishCoalesce(flats, () => ( false)));
|
|
@@ -3365,19 +3394,19 @@ function rootSpellingFor(pc, hint, flats) {
|
|
|
3365
3394
|
|
|
3366
3395
|
// src/theory/symbol/index.ts
|
|
3367
3396
|
function parseChordSymbol(text, opts) {
|
|
3368
|
-
return
|
|
3397
|
+
return _chunkS5BKZZGMcjs.unwrapParse.call(void 0, tryParseChordSymbol(text, opts));
|
|
3369
3398
|
}
|
|
3370
3399
|
function tryParseChordSymbol(text, opts) {
|
|
3371
|
-
const asked =
|
|
3400
|
+
const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
3372
3401
|
try {
|
|
3373
3402
|
if (typeof text !== "string") {
|
|
3374
|
-
throw new (0,
|
|
3403
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`chord symbol must be a string; received ${typeof text}`);
|
|
3375
3404
|
}
|
|
3376
3405
|
const system = _nullishCoalesce(asked.system, () => ( DEFAULT_SYSTEM));
|
|
3377
3406
|
const trimmed = text.trim().replaceAll("\u266F", "#").replaceAll("\u266D", "b").replaceAll("\u{1D12A}", "x").replaceAll("\u{1D12B}", "bb").replaceAll("\u2206", "\u0394");
|
|
3378
3407
|
const splits = rootSplits(trimmed, system);
|
|
3379
3408
|
if (splits.length === 0) {
|
|
3380
|
-
throw new (0,
|
|
3409
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Invalid chord symbol: ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, text)}`);
|
|
3381
3410
|
}
|
|
3382
3411
|
for (const { root, rest } of splits) {
|
|
3383
3412
|
const chord = chordAfterRoot(root, rest, system);
|
|
@@ -3385,31 +3414,31 @@ function tryParseChordSymbol(text, opts) {
|
|
|
3385
3414
|
return { ok: true, value: chord };
|
|
3386
3415
|
}
|
|
3387
3416
|
}
|
|
3388
|
-
throw new (0,
|
|
3417
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unrecognized chord quality: ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, text)}`);
|
|
3389
3418
|
} catch (error) {
|
|
3390
|
-
return
|
|
3419
|
+
return _chunkS5BKZZGMcjs.parseFailure.call(void 0, error);
|
|
3391
3420
|
}
|
|
3392
3421
|
}
|
|
3393
3422
|
function formatChordSymbol(chord, opts) {
|
|
3394
3423
|
const data = toChordData(chord);
|
|
3395
3424
|
if (!Object.hasOwn(CANONICAL_SUFFIX, data.quality)) {
|
|
3396
|
-
throw new (0,
|
|
3425
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown chord quality: ${String(data.quality)}`);
|
|
3397
3426
|
}
|
|
3398
|
-
const asked =
|
|
3427
|
+
const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
|
|
3399
3428
|
const system = _nullishCoalesce(asked.system, () => ( DEFAULT_SYSTEM));
|
|
3400
3429
|
const flats = asked.flats;
|
|
3401
|
-
const rootPc =
|
|
3430
|
+
const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, data.rootPc);
|
|
3402
3431
|
const rootHint = hintFor(data.rootSpelling, rootPc);
|
|
3403
3432
|
const rootSpelling = rootSpellingFor(rootPc, rootHint, flats);
|
|
3404
3433
|
const suffix = specSuffix(chordSpecOf(data));
|
|
3405
3434
|
let symbol = `${symbolName(rootSpelling, system)}${suffix}`;
|
|
3406
|
-
if (data.bassPc !== void 0 &&
|
|
3407
|
-
const bassPc =
|
|
3435
|
+
if (data.bassPc !== void 0 && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, data.bassPc) !== rootPc) {
|
|
3436
|
+
const bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, data.bassPc);
|
|
3408
3437
|
const bassHint = hintFor(data.bassSpelling, bassPc);
|
|
3409
3438
|
const tonePcs = new Set(chordPitchClasses(data, { includeBass: false }));
|
|
3410
3439
|
const ownSpelling = tonePcs.has(bassPc) ? spellingAbove(
|
|
3411
3440
|
rootSpelling,
|
|
3412
|
-
(_nullishCoalesce(degreeOfInterval(
|
|
3441
|
+
(_nullishCoalesce(degreeOfInterval(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, bassPc - rootPc), data), () => ( 1))) - 1,
|
|
3413
3442
|
bassPc
|
|
3414
3443
|
) : void 0;
|
|
3415
3444
|
const bassName = rootHint !== void 0 && bassHint !== void 0 ? symbolName(
|
|
@@ -3427,15 +3456,15 @@ function formatChordSymbol(chord, opts) {
|
|
|
3427
3456
|
return symbol;
|
|
3428
3457
|
}
|
|
3429
3458
|
function transposeChordSpellings(spellings, semitones, flats) {
|
|
3430
|
-
const byLetter = (spelling) => spelling === void 0 ? void 0 : bareSpelling(
|
|
3459
|
+
const byLetter = (spelling) => spelling === void 0 ? void 0 : bareSpelling(_chunkS5BKZZGMcjs.transposeNote.call(void 0, spelling, semitones));
|
|
3431
3460
|
const movedRoot = byLetter(spellings.rootSpelling);
|
|
3432
3461
|
const movedBass = byLetter(spellings.bassSpelling);
|
|
3433
3462
|
const side = [movedRoot, spellings.rootSpelling, movedBass, spellings.bassSpelling].find(
|
|
3434
3463
|
(spelling) => spelling !== void 0 && spelling.alter !== 0
|
|
3435
3464
|
);
|
|
3436
3465
|
const preferFlats = _nullishCoalesce(flats, () => ( (side !== void 0 && side.alter < 0)));
|
|
3437
|
-
const octaveOnly =
|
|
3438
|
-
const plainName = (spelling, asFlat) => plainSpelling(
|
|
3466
|
+
const octaveOnly = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, semitones) === 0;
|
|
3467
|
+
const plainName = (spelling, asFlat) => plainSpelling(_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, spelling), asFlat);
|
|
3439
3468
|
const writable = (spelling) => octaveOnly || isWrittenSpelling(spelling) ? spelling : plainName(spelling, preferFlats);
|
|
3440
3469
|
const root = spellings.rootSpelling;
|
|
3441
3470
|
const bass = spellings.bassSpelling;
|
|
@@ -3457,9 +3486,9 @@ function transposeChordSpellings(spellings, semitones, flats) {
|
|
|
3457
3486
|
];
|
|
3458
3487
|
moved.rootSpelling = _nullishCoalesce(candidates.find(carriesBass), () => ( plainName(movedRoot, preferFlats)));
|
|
3459
3488
|
}
|
|
3460
|
-
const step = root !== void 0 && moved.rootSpelling !== void 0 ?
|
|
3489
|
+
const step = root !== void 0 && moved.rootSpelling !== void 0 ? _chunkS5BKZZGMcjs.spelledInterval.call(void 0, root, moved.rootSpelling) : void 0;
|
|
3461
3490
|
const byStep = (spelling) => bareSpelling(
|
|
3462
|
-
step === void 0 ?
|
|
3491
|
+
step === void 0 ? _chunkS5BKZZGMcjs.transposeNote.call(void 0, spelling, semitones) : _chunkS5BKZZGMcjs.transposeByInterval.call(void 0, spelling, step)
|
|
3463
3492
|
);
|
|
3464
3493
|
if (bass !== void 0) {
|
|
3465
3494
|
moved.bassSpelling = writable(byStep(bass));
|
|
@@ -3470,11 +3499,11 @@ function transposeChordSpellings(spellings, semitones, flats) {
|
|
|
3470
3499
|
return moved;
|
|
3471
3500
|
}
|
|
3472
3501
|
function transposeChordSymbol(text, semitones, opts) {
|
|
3473
|
-
|
|
3502
|
+
_chunkS5BKZZGMcjs.assertFiniteSemitones.call(void 0, semitones);
|
|
3474
3503
|
const chord = parseChordSymbol(text, opts);
|
|
3475
|
-
const transposed = { ...chord, rootPc:
|
|
3504
|
+
const transposed = { ...chord, rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + semitones) };
|
|
3476
3505
|
if (chord.bassPc !== void 0) {
|
|
3477
|
-
transposed.bassPc =
|
|
3506
|
+
transposed.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc + semitones);
|
|
3478
3507
|
}
|
|
3479
3508
|
const spellings = transposeChordSpellings(chord, semitones, _optionalChain([opts, 'optionalAccess', _26 => _26.flats]));
|
|
3480
3509
|
if (spellings.rootSpelling !== void 0) {
|
|
@@ -3492,20 +3521,20 @@ function transposeChordSymbol(text, semitones, opts) {
|
|
|
3492
3521
|
// src/theory/symbol/coerce.ts
|
|
3493
3522
|
function normalizedChord(data) {
|
|
3494
3523
|
if (!Array.isArray(data.intervals)) {
|
|
3495
|
-
throw new (0,
|
|
3524
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("chord.intervals must be an array of semitone offsets");
|
|
3496
3525
|
}
|
|
3497
3526
|
const copy = {
|
|
3498
|
-
rootPc:
|
|
3527
|
+
rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, data.rootPc, "chord.rootPc")),
|
|
3499
3528
|
quality: data.quality,
|
|
3500
3529
|
// Each offset is checked rather than copied blind: a chord holding a NaN
|
|
3501
3530
|
// interval voices, spells and formats as a chord that looks real, and the
|
|
3502
3531
|
// failure surfaces wherever the number is finally used.
|
|
3503
3532
|
intervals: data.intervals.map(
|
|
3504
|
-
(interval, index) =>
|
|
3533
|
+
(interval, index) => _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, interval, `chord.intervals[${index}]`)
|
|
3505
3534
|
)
|
|
3506
3535
|
};
|
|
3507
3536
|
if (data.bassPc !== void 0) {
|
|
3508
|
-
copy.bassPc =
|
|
3537
|
+
copy.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, data.bassPc, "chord.bassPc"));
|
|
3509
3538
|
}
|
|
3510
3539
|
if (data.rootSpelling !== void 0) {
|
|
3511
3540
|
copy.rootSpelling = data.rootSpelling;
|
|
@@ -3526,14 +3555,14 @@ function toChordData(value) {
|
|
|
3526
3555
|
const data = "toJSON" in value && typeof value.toJSON === "function" ? value.toJSON() : value;
|
|
3527
3556
|
return normalizedChord(data);
|
|
3528
3557
|
}
|
|
3529
|
-
throw new (0,
|
|
3558
|
+
throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
|
|
3530
3559
|
`chord must be a chord symbol or chord data; received ${typeof value}`
|
|
3531
3560
|
);
|
|
3532
3561
|
}
|
|
3533
3562
|
|
|
3534
3563
|
// src/theory/tendency/index.ts
|
|
3535
3564
|
function hasInterval(chord, semitones) {
|
|
3536
|
-
return chord.intervals.some((interval) =>
|
|
3565
|
+
return chord.intervals.some((interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval) === semitones);
|
|
3537
3566
|
}
|
|
3538
3567
|
function isDiatonicChord(chord, key) {
|
|
3539
3568
|
return chordPitchClasses(chord).every((pc) => isScaleTone(pc, key));
|
|
@@ -3551,7 +3580,7 @@ function hasDominantSonority(chord) {
|
|
|
3551
3580
|
return soundsMajorTriad(chord) || soundsDominantSeventh(chord);
|
|
3552
3581
|
}
|
|
3553
3582
|
function isDominantChordOf(chord, key) {
|
|
3554
|
-
if (
|
|
3583
|
+
if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) !== 7) {
|
|
3555
3584
|
return false;
|
|
3556
3585
|
}
|
|
3557
3586
|
if (hasMajorThird(chord)) {
|
|
@@ -3561,17 +3590,17 @@ function isDominantChordOf(chord, key) {
|
|
|
3561
3590
|
return suspended && hasInterval(chord, 10);
|
|
3562
3591
|
}
|
|
3563
3592
|
function isNeapolitanChordOf(chord, key) {
|
|
3564
|
-
return
|
|
3593
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 1 && soundsMajorTriad(chord) && !isDiatonicChord(chord, key);
|
|
3565
3594
|
}
|
|
3566
3595
|
var DOMINANT_DEGREE = 5;
|
|
3567
3596
|
function heptatonicFrameOf(key) {
|
|
3568
|
-
return scaleTonesInDegreeOrder(key).length === 7 ? key : majorKey(
|
|
3597
|
+
return scaleTonesInDegreeOrder(key).length === 7 ? key : majorKey(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc));
|
|
3569
3598
|
}
|
|
3570
3599
|
function degreeTriad(tones, index) {
|
|
3571
3600
|
const root = _nullishCoalesce(tones[index], () => ( 0));
|
|
3572
3601
|
return {
|
|
3573
|
-
third:
|
|
3574
|
-
fifth:
|
|
3602
|
+
third: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 2) % tones.length], () => ( 0))) - root),
|
|
3603
|
+
fifth: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 4) % tones.length], () => ( 0))) - root)
|
|
3575
3604
|
};
|
|
3576
3605
|
}
|
|
3577
3606
|
function tonicizableDegrees(key) {
|
|
@@ -3593,25 +3622,25 @@ function tonicizableDegrees(key) {
|
|
|
3593
3622
|
return out;
|
|
3594
3623
|
}
|
|
3595
3624
|
function appliedDominantTarget(rootPc, key) {
|
|
3596
|
-
const target =
|
|
3625
|
+
const target = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc);
|
|
3597
3626
|
return _nullishCoalesce(tonicizableDegrees(key).find(
|
|
3598
3627
|
(degree) => degree.degreeNumber !== 1 && degree.rootPc === target
|
|
3599
3628
|
), () => ( null));
|
|
3600
3629
|
}
|
|
3601
3630
|
function leadingTonePcOf(key) {
|
|
3602
|
-
return
|
|
3631
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc - 1);
|
|
3603
3632
|
}
|
|
3604
3633
|
var LEADING_TONE_QUALITIES = /* @__PURE__ */ new Set(["dim", "dim7", "m7b5"]);
|
|
3605
3634
|
function soundsDiminishedTriad(chord) {
|
|
3606
3635
|
return hasInterval(chord, 3) && hasInterval(chord, 6) && !hasInterval(chord, 7);
|
|
3607
3636
|
}
|
|
3608
3637
|
function isLeadingToneChordOf(chord, key) {
|
|
3609
|
-
return
|
|
3638
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) === leadingTonePcOf(key) && soundsDiminishedTriad(chord);
|
|
3610
3639
|
}
|
|
3611
3640
|
function isFunctioningLeadingTone(chord, key) {
|
|
3612
3641
|
const role = chordToneRole(leadingTonePcOf(key), chord);
|
|
3613
3642
|
if (role === "third") {
|
|
3614
|
-
return
|
|
3643
|
+
return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc + 7);
|
|
3615
3644
|
}
|
|
3616
3645
|
if (role === "root") {
|
|
3617
3646
|
return soundsDiminishedTriad(chord);
|
|
@@ -3620,7 +3649,7 @@ function isFunctioningLeadingTone(chord, key) {
|
|
|
3620
3649
|
}
|
|
3621
3650
|
function seventhPcOf(chord) {
|
|
3622
3651
|
for (const interval of chord.intervals) {
|
|
3623
|
-
const pc =
|
|
3652
|
+
const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
3624
3653
|
if (chordToneRole(pc, chord) === "seventh") {
|
|
3625
3654
|
return pc;
|
|
3626
3655
|
}
|
|
@@ -3629,7 +3658,7 @@ function seventhPcOf(chord) {
|
|
|
3629
3658
|
}
|
|
3630
3659
|
function fifthPcOf(chord) {
|
|
3631
3660
|
for (const interval of chord.intervals) {
|
|
3632
|
-
const pc =
|
|
3661
|
+
const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
3633
3662
|
if (chordToneRole(pc, chord) === "fifth") {
|
|
3634
3663
|
return pc;
|
|
3635
3664
|
}
|
|
@@ -3645,7 +3674,7 @@ function isFrustratedLeadingTone(fromPitch, toPitch, nextChord) {
|
|
|
3645
3674
|
return false;
|
|
3646
3675
|
}
|
|
3647
3676
|
const fifthPc = fifthPcOf(nextChord);
|
|
3648
|
-
return fifthPc !== void 0 &&
|
|
3677
|
+
return fifthPc !== void 0 && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, toPitch) === fifthPc;
|
|
3649
3678
|
}
|
|
3650
3679
|
|
|
3651
3680
|
|
|
@@ -3794,4 +3823,4 @@ function isFrustratedLeadingTone(fromPitch, toPitch, nextChord) {
|
|
|
3794
3823
|
|
|
3795
3824
|
|
|
3796
3825
|
exports.maskFromOffsets = maskFromOffsets; exports.MAJOR_MASK = MAJOR_MASK; exports.NATURAL_MINOR_MASK = NATURAL_MINOR_MASK; exports.HARMONIC_MINOR_MASK = HARMONIC_MINOR_MASK; exports.MELODIC_MINOR_MASK = MELODIC_MINOR_MASK; exports.DORIAN_MASK = DORIAN_MASK; exports.PHRYGIAN_MASK = PHRYGIAN_MASK; exports.LYDIAN_MASK = LYDIAN_MASK; exports.MIXOLYDIAN_MASK = MIXOLYDIAN_MASK; exports.LOCRIAN_MASK = LOCRIAN_MASK; exports.MAJOR_PENTATONIC_MASK = MAJOR_PENTATONIC_MASK; exports.MINOR_PENTATONIC_MASK = MINOR_PENTATONIC_MASK; exports.BLUES_MASK = BLUES_MASK; exports.WHOLE_TONE_MASK = WHOLE_TONE_MASK; exports.OCTATONIC_HALF_WHOLE_MASK = OCTATONIC_HALF_WHOLE_MASK; exports.OCTATONIC_WHOLE_HALF_MASK = OCTATONIC_WHOLE_HALF_MASK; exports.CHROMATIC_MASK = CHROMATIC_MASK; exports.assertModeMask = assertModeMask; exports.LYDIAN_DOMINANT_MASK = LYDIAN_DOMINANT_MASK; exports.MIXOLYDIAN_B13_MASK = MIXOLYDIAN_B13_MASK; exports.LOCRIAN_NATURAL2_MASK = LOCRIAN_NATURAL2_MASK; exports.ALTERED_MASK = ALTERED_MASK; exports.PHRYGIAN_DOMINANT_MASK = PHRYGIAN_DOMINANT_MASK; exports.MIYAKO_BUSHI_MASK = MIYAKO_BUSHI_MASK; exports.RITSU_MASK = RITSU_MASK; exports.RYUKYU_MASK = RYUKYU_MASK; exports.DOUBLE_HARMONIC_MASK = DOUBLE_HARMONIC_MASK; exports.TODI_MASK = TODI_MASK; exports.MARWA_MASK = MARWA_MASK; exports.PURVI_MASK = PURVI_MASK; exports.NAMED_SCALES = NAMED_SCALES; exports.WORLD_SCALES = WORLD_SCALES; exports.SCALE_ALIASES = SCALE_ALIASES; exports.resolveScaleName = resolveScaleName; exports.namedScaleMask = namedScaleMask; exports.requireScaleMask = requireScaleMask; exports.isMinorMask = isMinorMask; exports.variantOfMask = variantOfMask; exports.assertKeyVariant = assertKeyVariant; exports.scaleNameOfMask = scaleNameOfMask; exports.tryResolveKeyName = tryResolveKeyName; exports.toKeyScale = toKeyScale; exports.isScaleTone = isScaleTone; exports.nearestScaleTone = nearestScaleTone; exports.scaleLadderPosition = scaleLadderPosition; exports.scaleLadderPitch = scaleLadderPitch; exports.shiftByScaleDegrees = shiftByScaleDegrees; exports.pitchToScaleDegree = pitchToScaleDegree; exports.diatonicPitchClasses = diatonicPitchClasses; exports.scaleTonesInDegreeOrder = scaleTonesInDegreeOrder; exports.assertTonicOf = assertTonicOf; exports.spellPitchClass = spellPitchClass; exports.spellScale = spellScale; exports.spellPitchClasses = spellPitchClasses; exports.spellChordFromRoot = spellChordFromRoot; exports.spellChord = spellChord; exports.spellPitch = spellPitch; exports.noteNames = noteNames; exports.isSignatureKey = isSignatureKey; exports.keySignatureFifths = keySignatureFifths; exports.keyFromFifths = keyFromFifths; exports.spelledKeyOf = spelledKeyOf; exports.relativeKeyOf = relativeKeyOf; exports.parallelKeyOf = parallelKeyOf; exports.isWrittenTonic = isWrittenTonic; exports.dominantKeyOf = dominantKeyOf; exports.subdominantKeyOf = subdominantKeyOf; exports.enharmonicKeyOf = enharmonicKeyOf; exports.relatedKeysOf = relatedKeysOf; exports.keyRelationBetween = keyRelationBetween; exports.resolveKey = resolveKey; exports.scaleOf = scaleOf; exports.majorKey = majorKey; exports.minorKey = minorKey; exports.scaleByName = scaleByName; exports.SCALE_SYSTEMS = SCALE_SYSTEMS; exports.scaleSystemOf = scaleSystemOf; exports.supportsFunctionalHarmony = supportsFunctionalHarmony; exports.chordSpecIntervals = chordSpecIntervals; exports.chordSpecQuality = chordSpecQuality; exports.chordQualities = chordQualities; exports.assertChordQuality = assertChordQuality; exports.assertChord = assertChord; exports.chordFromDegree = chordFromDegree; exports.makeChord = makeChord; exports.chordFromSpec = chordFromSpec; exports.chordSpecOf = chordSpecOf; exports.chordFromSpan = chordFromSpan; exports.spanFromChord = spanFromChord; exports.transposeChord = transposeChord; exports.chordToneSpellings = chordToneSpellings; exports.chordPitchClasses = chordPitchClasses; exports.intervalAboveRoot = intervalAboveRoot; exports.isChordMember = isChordMember; exports.chordToneRole = chordToneRole; exports.degreeOfInterval = degreeOfInterval; exports.thirdSlotOf = thirdSlotOf; exports.displacedThirds = displacedThirds; exports.diatonicTriad = diatonicTriad; exports.diatonicSeventh = diatonicSeventh; exports.simpleIntervalNumber = simpleIntervalNumber; exports.classifySpelledInterval = classifySpelledInterval; exports.voiceIndependence = voiceIndependence; exports.createsVoiceCrossing = createsVoiceCrossing; exports.createsVerticalDissonance = createsVerticalDissonance; exports.isForbiddenMelodicLeap = isForbiddenMelodicLeap; exports.isAugmentedMelodicInterval = isAugmentedMelodicInterval; exports.createsParallelPerfect = createsParallelPerfect; exports.createsParallelOctave = createsParallelOctave; exports.createsParallelUnison = createsParallelUnison; exports.createsHiddenParallelPerfect = createsHiddenParallelPerfect; exports.createsBattuta = createsBattuta; exports.createsVoiceOverlap = createsVoiceOverlap; exports.exceedsSpacing = exceedsSpacing; exports.isLeadingToneResolution = isLeadingToneResolution; exports.PROFILE_WEIGHTS = PROFILE_WEIGHTS; exports.profileWeights = profileWeights; exports.NoteSafety = NoteSafety; exports.ReasonFlag = ReasonFlag; exports.evaluateSafety = evaluateSafety; exports.enumerateSafePitches = enumerateSafePitches; exports.toChordData = toChordData; exports.parseChordSymbol = parseChordSymbol; exports.tryParseChordSymbol = tryParseChordSymbol; exports.formatChordSymbol = formatChordSymbol; exports.transposeChordSpellings = transposeChordSpellings; exports.transposeChordSymbol = transposeChordSymbol; exports.isDiatonicChord = isDiatonicChord; exports.hasMajorThird = hasMajorThird; exports.soundsDominantSeventh = soundsDominantSeventh; exports.hasDominantSonority = hasDominantSonority; exports.isDominantChordOf = isDominantChordOf; exports.isNeapolitanChordOf = isNeapolitanChordOf; exports.heptatonicFrameOf = heptatonicFrameOf; exports.tonicizableDegrees = tonicizableDegrees; exports.appliedDominantTarget = appliedDominantTarget; exports.leadingTonePcOf = leadingTonePcOf; exports.LEADING_TONE_QUALITIES = LEADING_TONE_QUALITIES; exports.isLeadingToneChordOf = isLeadingToneChordOf; exports.isFunctioningLeadingTone = isFunctioningLeadingTone; exports.seventhPcOf = seventhPcOf; exports.fifthPcOf = fifthPcOf; exports.isDescendingStep = isDescendingStep; exports.isFrustratedLeadingTone = isFrustratedLeadingTone;
|
|
3797
|
-
//# sourceMappingURL=chunk-
|
|
3826
|
+
//# sourceMappingURL=chunk-3R3QVKY5.cjs.map
|