@libraz/libcantus 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +63 -0
- package/README.md +3 -1
- package/README_ja.md +13 -11
- package/dist/analyze/index.cjs +7 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +14 -12
- package/dist/analyze/index.d.ts +14 -12
- package/dist/analyze/index.js +6 -6
- package/dist/{chunk-NB25P3EH.js → chunk-2G5MCGYU.js} +33 -11
- package/dist/chunk-2G5MCGYU.js.map +1 -0
- package/dist/{chunk-NM7UAMC3.cjs → chunk-3FDBMIPR.cjs} +64 -64
- package/dist/chunk-3FDBMIPR.cjs.map +1 -0
- package/dist/{chunk-YFA7X2F6.cjs → chunk-3MDOEFIQ.cjs} +411 -327
- package/dist/chunk-3MDOEFIQ.cjs.map +1 -0
- package/dist/{chunk-IPEF6NWB.js → chunk-5MWRBYAT.js} +278 -154
- package/dist/chunk-5MWRBYAT.js.map +1 -0
- package/dist/{chunk-B2PW6EHN.cjs → chunk-6TTBEON3.cjs} +1253 -889
- package/dist/chunk-6TTBEON3.cjs.map +1 -0
- package/dist/{chunk-UMWZ4ZET.js → chunk-7NQ6AL3H.js} +4 -4
- package/dist/chunk-7NQ6AL3H.js.map +1 -0
- package/dist/{chunk-PWC4CRWT.cjs → chunk-E3QO3UET.cjs} +31 -23
- package/dist/chunk-E3QO3UET.cjs.map +1 -0
- package/dist/{chunk-GNVN4PPJ.js → chunk-FJFULJZE.js} +531 -213
- package/dist/chunk-FJFULJZE.js.map +1 -0
- package/dist/{chunk-CPMB7P75.js → chunk-FK3DGAIZ.js} +608 -244
- package/dist/chunk-FK3DGAIZ.js.map +1 -0
- package/dist/chunk-GEDTJHAC.cjs.map +1 -1
- package/dist/{chunk-RFIBF2RR.js → chunk-H7FVMBUC.js} +138 -65
- package/dist/chunk-H7FVMBUC.js.map +1 -0
- package/dist/{chunk-4R2LWV7E.cjs → chunk-HYSVSFNI.cjs} +664 -540
- package/dist/chunk-HYSVSFNI.cjs.map +1 -0
- package/dist/{chunk-35NBV2FT.cjs → chunk-KMYGRFZ6.cjs} +47 -24
- package/dist/chunk-KMYGRFZ6.cjs.map +1 -0
- package/dist/{chunk-IFZDWIKM.cjs → chunk-LQZQDBCD.cjs} +1048 -730
- package/dist/chunk-LQZQDBCD.cjs.map +1 -0
- package/dist/{chunk-PM4XJE2Y.cjs → chunk-P3CPXAJ5.cjs} +76 -54
- package/dist/chunk-P3CPXAJ5.cjs.map +1 -0
- package/dist/{chunk-S5BKZZGM.cjs → chunk-S3QELJUE.cjs} +72 -56
- package/dist/chunk-S3QELJUE.cjs.map +1 -0
- package/dist/{chunk-PUKJP2Z5.js → chunk-TXFWSU5D.js} +31 -8
- package/dist/chunk-TXFWSU5D.js.map +1 -0
- package/dist/{chunk-76ZBTRG2.cjs → chunk-U4EQTDGN.cjs} +258 -218
- package/dist/chunk-U4EQTDGN.cjs.map +1 -0
- package/dist/chunk-UGLFDG7L.cjs.map +1 -1
- package/dist/{chunk-MLBPXA4Z.js → chunk-UTE5A36R.js} +198 -114
- package/dist/chunk-UTE5A36R.js.map +1 -0
- package/dist/{chunk-ZBUROTJQ.js → chunk-UZKQISRF.js} +17 -9
- package/dist/chunk-UZKQISRF.js.map +1 -0
- package/dist/{chunk-7KG3RTYS.js → chunk-VL5NXVCN.js} +281 -155
- package/dist/chunk-VL5NXVCN.js.map +1 -0
- package/dist/{chunk-CGBADIO5.cjs → chunk-WOMCXN2W.cjs} +328 -202
- package/dist/chunk-WOMCXN2W.cjs.map +1 -0
- package/dist/{chunk-3R3QVKY5.cjs → chunk-YDGMWH43.cjs} +397 -324
- package/dist/chunk-YDGMWH43.cjs.map +1 -0
- package/dist/{chunk-AGOVW7U6.js → chunk-YYVXRV3V.js} +72 -56
- package/dist/chunk-YYVXRV3V.js.map +1 -0
- package/dist/{chunk-M5RYMAFI.js → chunk-ZLNSH4UL.js} +71 -31
- package/dist/chunk-ZLNSH4UL.js.map +1 -0
- package/dist/{coerce-DRERzdve.d.cts → coerce-CUhHc3Tu.d.ts} +16 -8
- package/dist/{coerce-DP0vYu-x.d.ts → coerce-Ytt2Eiq9.d.cts} +16 -8
- package/dist/core/index.cjs +5 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +9 -8
- package/dist/core/index.d.ts +9 -8
- package/dist/core/index.js +4 -4
- package/dist/generate/index.cjs +8 -8
- package/dist/generate/index.cjs.map +1 -1
- package/dist/generate/index.d.cts +28 -18
- package/dist/generate/index.d.ts +28 -18
- package/dist/generate/index.js +7 -7
- package/dist/{index-BMweUlm5.d.cts → index-5VJgKz_Q.d.cts} +6 -2
- package/dist/{index-BHIUyjhZ.d.ts → index-BLuDesVG.d.ts} +20 -13
- package/dist/{index-B9QLziDe.d.cts → index-BV6APVa6.d.cts} +20 -13
- package/dist/{index-CL4b4gUQ.d.ts → index-Bf0Sv8a9.d.ts} +6 -2
- package/dist/{index-Dw2DP7vm.d.ts → index-BkT21EMv.d.cts} +3 -2
- package/dist/{index-BL5N2Oyz.d.cts → index-C7KCaTRz.d.ts} +3 -2
- package/dist/{index-Cy15oTvh.d.ts → index-C9MYbuKS.d.cts} +7 -3
- package/dist/{index-Cy15oTvh.d.cts → index-C9MYbuKS.d.ts} +7 -3
- package/dist/{index-CY-3NVfy.d.cts → index-DVInzCDS.d.cts} +53 -29
- package/dist/{index-9eoQs2C1.d.ts → index-Dg-SAfhz.d.ts} +6 -4
- package/dist/{index-zaZdmnU4.d.ts → index-jgeug9EA.d.ts} +53 -29
- package/dist/{index-cHvbYgJI.d.cts → index-pQihL4z7.d.cts} +6 -4
- package/dist/index.cjs +13 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +12 -12
- package/dist/{masks-Cc7-MzzY.d.ts → masks-BnzXnBj0.d.cts} +3 -2
- package/dist/{masks-pADfTOiD.d.cts → masks-tycmkrgs.d.ts} +3 -2
- package/dist/model/index.cjs +12 -12
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +63 -48
- package/dist/model/index.d.ts +63 -48
- package/dist/model/index.js +11 -11
- package/dist/{positional-DJgs6ltD.d.ts → positional-CscpxtlE.d.cts} +3 -2
- package/dist/{positional-DMZer-FM.d.cts → positional-DLnfUgqG.d.ts} +3 -2
- package/dist/{profile-DLdlIpS9.d.ts → profile-B4WqcM4H.d.ts} +25 -17
- package/dist/{profile-CQMEqdH9.d.cts → profile-BJd1XkPB.d.cts} +25 -17
- package/dist/theory/index.cjs +5 -5
- package/dist/theory/index.cjs.map +1 -1
- package/dist/theory/index.d.cts +18 -14
- package/dist/theory/index.d.ts +18 -14
- package/dist/theory/index.js +4 -4
- package/dist/{types-D-XgxGvp.d.cts → types-7mGFwvMm.d.ts} +45 -22
- package/dist/{types-Dh7C064C.d.ts → types-_ofpb2be.d.cts} +45 -22
- package/package.json +13 -13
- package/dist/chunk-35NBV2FT.cjs.map +0 -1
- package/dist/chunk-3R3QVKY5.cjs.map +0 -1
- package/dist/chunk-4R2LWV7E.cjs.map +0 -1
- package/dist/chunk-76ZBTRG2.cjs.map +0 -1
- package/dist/chunk-7KG3RTYS.js.map +0 -1
- package/dist/chunk-AGOVW7U6.js.map +0 -1
- package/dist/chunk-B2PW6EHN.cjs.map +0 -1
- package/dist/chunk-CGBADIO5.cjs.map +0 -1
- package/dist/chunk-CPMB7P75.js.map +0 -1
- package/dist/chunk-GNVN4PPJ.js.map +0 -1
- package/dist/chunk-IFZDWIKM.cjs.map +0 -1
- package/dist/chunk-IPEF6NWB.js.map +0 -1
- package/dist/chunk-M5RYMAFI.js.map +0 -1
- package/dist/chunk-MLBPXA4Z.js.map +0 -1
- package/dist/chunk-NB25P3EH.js.map +0 -1
- package/dist/chunk-NM7UAMC3.cjs.map +0 -1
- package/dist/chunk-PM4XJE2Y.cjs.map +0 -1
- package/dist/chunk-PUKJP2Z5.js.map +0 -1
- package/dist/chunk-PWC4CRWT.cjs.map +0 -1
- package/dist/chunk-RFIBF2RR.js.map +0 -1
- package/dist/chunk-S5BKZZGM.cjs.map +0 -1
- package/dist/chunk-UMWZ4ZET.js.map +0 -1
- package/dist/chunk-YFA7X2F6.cjs.map +0 -1
- package/dist/chunk-ZBUROTJQ.js.map +0 -1
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
var
|
|
36
|
+
var _chunkS3QELJUEcjs = require('./chunk-S3QELJUE.cjs');
|
|
37
37
|
|
|
38
38
|
// src/theory/scale/masks.ts
|
|
39
39
|
function maskFromOffsets(offsets) {
|
|
40
|
-
|
|
40
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, offsets, "offsets");
|
|
41
41
|
let mask = 1;
|
|
42
42
|
for (const [index, offset] of offsets.entries()) {
|
|
43
|
-
|
|
43
|
+
_chunkS3QELJUEcjs.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 _chunkS3QELJUEcjs.assertInteger.call(void 0, modeMask12, name, 1, CHROMATIC_MASK);
|
|
66
66
|
}
|
|
67
67
|
function maskOf(scale, name = "key") {
|
|
68
|
-
return assertModeMask(
|
|
68
|
+
return assertModeMask(_chunkS3QELJUEcjs.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, _chunkS3QELJUEcjs.InvalidInputError)(`scale name must be a string; received ${_chunkS3QELJUEcjs.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, _chunkS3QELJUEcjs.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
|
+
_chunkS3QELJUEcjs.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, _chunkS3QELJUEcjs.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: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc), modeMask12: MAJOR_MASK };
|
|
237
237
|
}
|
|
238
238
|
function minorScale(rootPc) {
|
|
239
|
-
return { rootPc:
|
|
239
|
+
return { rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc), modeMask12: NATURAL_MINOR_MASK };
|
|
240
240
|
}
|
|
241
241
|
function namedScale(name, rootPc) {
|
|
242
|
-
return { rootPc:
|
|
242
|
+
return { rootPc: _chunkS3QELJUEcjs.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 = _chunkS3QELJUEcjs.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, _chunkS3QELJUEcjs.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 = _chunkS3QELJUEcjs.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 = _chunkS3QELJUEcjs.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 = _chunkS3QELJUEcjs.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 _chunkS3QELJUEcjs.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, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
315
315
|
`key.modeMask12 must include its root; received ${scale.modeMask12}`
|
|
316
316
|
);
|
|
317
317
|
}
|
|
318
|
-
|
|
319
|
-
return { rootPc:
|
|
318
|
+
_chunkS3QELJUEcjs.assertInteger.call(void 0, scale.rootPc, "key.rootPc");
|
|
319
|
+
return { rootPc: _chunkS3QELJUEcjs.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,14 @@ function toKeyScale(value) {
|
|
|
328
328
|
return normalizedKeyScale(data);
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
-
throw new (0,
|
|
331
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
332
|
+
`key must be a key name or a key/scale; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`
|
|
333
|
+
);
|
|
332
334
|
}
|
|
333
335
|
|
|
334
336
|
// src/theory/scale/degrees.ts
|
|
335
337
|
function scaleOffset(pitch, key) {
|
|
336
|
-
return (
|
|
338
|
+
return (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch) - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc) + 12) % 12;
|
|
337
339
|
}
|
|
338
340
|
function inScale(pitch, scale) {
|
|
339
341
|
return (scale.modeMask12 >> scaleOffset(pitch, scale) & 1) === 1;
|
|
@@ -343,8 +345,8 @@ function isScaleTone(pitch, key) {
|
|
|
343
345
|
}
|
|
344
346
|
function nearestScaleTone(pitch, key) {
|
|
345
347
|
const scale = toKeyScale(key);
|
|
346
|
-
|
|
347
|
-
const base =
|
|
348
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
|
|
349
|
+
const base = _chunkS3QELJUEcjs.clampToMidi.call(void 0, Math.round(pitch), "pitch");
|
|
348
350
|
for (let distance = 0; distance < 12; distance += 1) {
|
|
349
351
|
const lower = base - distance;
|
|
350
352
|
if (lower >= 0 && inScale(lower, scale)) {
|
|
@@ -370,13 +372,13 @@ function scaleLadderPosition(pitch, key) {
|
|
|
370
372
|
return ladderPosition(pitch, toKeyScale(key));
|
|
371
373
|
}
|
|
372
374
|
function ladderPosition(pitch, key) {
|
|
373
|
-
|
|
375
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
|
|
374
376
|
const offsets = scaleOffsets(key);
|
|
375
377
|
const size = offsets.length;
|
|
376
378
|
if (size === 0) {
|
|
377
379
|
return { rung: 0, offset: 0 };
|
|
378
380
|
}
|
|
379
|
-
const relative = pitch -
|
|
381
|
+
const relative = pitch - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
380
382
|
const octave = Math.floor(relative / 12);
|
|
381
383
|
const within = relative - octave * 12;
|
|
382
384
|
let degree = 0;
|
|
@@ -391,19 +393,19 @@ function scaleLadderPitch(rung, key) {
|
|
|
391
393
|
return ladderPitch(rung, toKeyScale(key));
|
|
392
394
|
}
|
|
393
395
|
function ladderPitch(rung, key) {
|
|
394
|
-
|
|
396
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, rung, "rung");
|
|
395
397
|
const offsets = scaleOffsets(key);
|
|
396
398
|
const size = offsets.length;
|
|
397
399
|
if (size === 0) {
|
|
398
|
-
return
|
|
400
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
399
401
|
}
|
|
400
402
|
const octave = Math.floor(rung / size);
|
|
401
403
|
const degree = rung - octave * size;
|
|
402
|
-
return
|
|
404
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc) + octave * 12 + (_nullishCoalesce(offsets[degree], () => ( 0)));
|
|
403
405
|
}
|
|
404
406
|
function shiftByScaleDegrees(pitch, degrees, key) {
|
|
405
407
|
const scale = toKeyScale(key);
|
|
406
|
-
const steps = Math.trunc(
|
|
408
|
+
const steps = Math.trunc(_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, degrees, "degrees"));
|
|
407
409
|
if (steps === 0) {
|
|
408
410
|
return pitch;
|
|
409
411
|
}
|
|
@@ -429,7 +431,7 @@ function diatonicPitchClasses(key) {
|
|
|
429
431
|
}
|
|
430
432
|
function scaleTonesInDegreeOrder(key) {
|
|
431
433
|
const scale = toKeyScale(key);
|
|
432
|
-
const root =
|
|
434
|
+
const root = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, scale.rootPc);
|
|
433
435
|
const pcs = [];
|
|
434
436
|
for (let n = 0; n < 12; n += 1) {
|
|
435
437
|
if ((scale.modeMask12 >> n & 1) === 1) {
|
|
@@ -449,7 +451,7 @@ function rotateMask(mask, semitones) {
|
|
|
449
451
|
const steps = (semitones % 12 + 12) % 12;
|
|
450
452
|
return (mask >> steps | mask << 12 - steps) & 4095;
|
|
451
453
|
}
|
|
452
|
-
var
|
|
454
|
+
var DIATONIC_MODE_OFFSET_ENTRIES = [
|
|
453
455
|
[rotateMask(MAJOR_MASK, 5), 1],
|
|
454
456
|
// lydian
|
|
455
457
|
[MAJOR_MASK, 0],
|
|
@@ -464,7 +466,8 @@ var DIATONIC_MODE_OFFSETS = /* @__PURE__ */ new Map([
|
|
|
464
466
|
// phrygian
|
|
465
467
|
[rotateMask(MAJOR_MASK, 11), -5]
|
|
466
468
|
// locrian
|
|
467
|
-
]
|
|
469
|
+
];
|
|
470
|
+
var DIATONIC_MODE_OFFSETS = new Map(DIATONIC_MODE_OFFSET_ENTRIES);
|
|
468
471
|
function modeOffset(key) {
|
|
469
472
|
const diatonic = DIATONIC_MODE_OFFSETS.get(key.modeMask12);
|
|
470
473
|
if (diatonic !== void 0) {
|
|
@@ -477,20 +480,20 @@ function isSignatureKey(key) {
|
|
|
477
480
|
return DIATONIC_MODE_OFFSETS.has(mask) || mask === HARMONIC_MINOR_MASK || mask === MELODIC_MINOR_MASK;
|
|
478
481
|
}
|
|
479
482
|
function keySignatureFifths(tonic, key) {
|
|
480
|
-
const note =
|
|
483
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
481
484
|
const scale = toKeyScale(key);
|
|
482
|
-
const letter =
|
|
483
|
-
|
|
484
|
-
|
|
485
|
+
const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, note.letter);
|
|
486
|
+
_chunkS3QELJUEcjs.assertInteger.call(void 0, note.alter, "tonic.alter");
|
|
487
|
+
_chunkS3QELJUEcjs.assertInteger.call(void 0, scale.modeMask12, "key.modeMask12", 1, 4095);
|
|
485
488
|
return (_nullishCoalesce(LETTER_FIFTHS[letter], () => ( 0))) + FIFTHS_PER_ALTERATION * note.alter + modeOffset(scale);
|
|
486
489
|
}
|
|
487
490
|
function keyFromFifths(fifths, mode = "major") {
|
|
488
|
-
|
|
489
|
-
const which =
|
|
491
|
+
_chunkS3QELJUEcjs.assertInteger.call(void 0, fifths, "fifths", -MAX_FIFTHS, MAX_FIFTHS);
|
|
492
|
+
const which = _chunkS3QELJUEcjs.assertOneOf.call(void 0, mode, ["major", "minor"], "mode");
|
|
490
493
|
const index = fifths + 1 + (which === "minor" ? -MINOR_MODE_OFFSET : 0);
|
|
491
494
|
const letter = _nullishCoalesce(FIFTHS_LETTERS[(index % 7 + 7) % 7], () => ( 0));
|
|
492
495
|
const alter = Math.floor(index / 7);
|
|
493
|
-
const rootPc =
|
|
496
|
+
const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, letter) + alter);
|
|
494
497
|
const scale = which === "minor" ? minorScale(rootPc) : majorScale(rootPc);
|
|
495
498
|
return {
|
|
496
499
|
tonic: { letter, alter },
|
|
@@ -512,10 +515,10 @@ function oppositeMode(mode) {
|
|
|
512
515
|
return mode === "major" ? "minor" : "major";
|
|
513
516
|
}
|
|
514
517
|
function soundsLike(a, b) {
|
|
515
|
-
return
|
|
518
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, a.rootPc) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, b.rootPc) && isMinorMask(a.modeMask12) === isMinorMask(b.modeMask12);
|
|
516
519
|
}
|
|
517
520
|
function spelledLike(a, b) {
|
|
518
|
-
return
|
|
521
|
+
return _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, a.letter) === _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, b.letter) && a.alter === b.alter;
|
|
519
522
|
}
|
|
520
523
|
function tonicCost(tonic, key) {
|
|
521
524
|
let doubles = 0;
|
|
@@ -523,7 +526,7 @@ function tonicCost(tonic, key) {
|
|
|
523
526
|
for (const note of spellScale(tonic, key)) {
|
|
524
527
|
const alter = Math.abs(note.alter);
|
|
525
528
|
accidentals += alter;
|
|
526
|
-
if (alter >=
|
|
529
|
+
if (alter >= _chunkS3QELJUEcjs.MAX_NAME_ACCIDENTALS) {
|
|
527
530
|
doubles += 1;
|
|
528
531
|
}
|
|
529
532
|
}
|
|
@@ -539,14 +542,14 @@ function spellsBetter(a, b, signatureKey) {
|
|
|
539
542
|
return false;
|
|
540
543
|
}
|
|
541
544
|
function spelledKeyOf(key) {
|
|
542
|
-
const scale =
|
|
543
|
-
const rootPc =
|
|
545
|
+
const scale = _chunkS3QELJUEcjs.assertRecord.call(void 0, key, "key");
|
|
546
|
+
const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, scale.rootPc);
|
|
544
547
|
const signatureKey = isSignatureKey(scale);
|
|
545
548
|
let tonic = keyFromFifths(0).tonic;
|
|
546
549
|
let best;
|
|
547
550
|
for (let fifths = FLATTEST_TONIC_FIFTHS; fifths <= SHARPEST_TONIC_FIFTHS; fifths += 1) {
|
|
548
551
|
const candidate = keyFromFifths(fifths).tonic;
|
|
549
|
-
if (
|
|
552
|
+
if (_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, candidate) !== rootPc) {
|
|
550
553
|
continue;
|
|
551
554
|
}
|
|
552
555
|
const cost = tonicCost(candidate, scale);
|
|
@@ -559,21 +562,21 @@ function spelledKeyOf(key) {
|
|
|
559
562
|
}
|
|
560
563
|
function relativeKeyOf(tonic, key) {
|
|
561
564
|
const mode = modeOf(toKeyScale(key));
|
|
562
|
-
return keyFromFifths(tonicFifths(
|
|
565
|
+
return keyFromFifths(tonicFifths(_chunkS3QELJUEcjs.toNoteData.call(void 0, tonic), mode), oppositeMode(mode));
|
|
563
566
|
}
|
|
564
567
|
function parallelKeyOf(tonic, key) {
|
|
565
|
-
const note =
|
|
568
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
566
569
|
const mode = oppositeMode(modeOf(toKeyScale(key)));
|
|
567
|
-
const rootPc =
|
|
570
|
+
const rootPc = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, note);
|
|
568
571
|
const scale = mode === "minor" ? minorScale(rootPc) : majorScale(rootPc);
|
|
569
572
|
return {
|
|
570
|
-
tonic: { letter:
|
|
573
|
+
tonic: { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, note.letter), alter: note.alter },
|
|
571
574
|
scale,
|
|
572
575
|
variant: variantOfMask(scale.modeMask12)
|
|
573
576
|
};
|
|
574
577
|
}
|
|
575
578
|
function tonicPosition(tonic) {
|
|
576
|
-
return keySignatureFifths(tonic, majorScale(
|
|
579
|
+
return keySignatureFifths(tonic, majorScale(_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic)));
|
|
577
580
|
}
|
|
578
581
|
function tonicFifths(tonic, mode) {
|
|
579
582
|
return tonicPosition(tonic) - (mode === "minor" ? MINOR_TONIC_FIFTHS : 0);
|
|
@@ -583,18 +586,18 @@ function isWrittenTonic(tonic, key) {
|
|
|
583
586
|
if (isSignatureKey(key)) {
|
|
584
587
|
return Math.abs(position) <= MAX_FIFTHS && Math.abs(keySignatureFifths(tonic, key)) <= MAX_CONVENTIONAL_FIFTHS;
|
|
585
588
|
}
|
|
586
|
-
return position >= FLATTEST_TONIC_FIFTHS && position <= SHARPEST_TONIC_FIFTHS && tonicCost(tonic, { rootPc:
|
|
589
|
+
return position >= FLATTEST_TONIC_FIFTHS && position <= SHARPEST_TONIC_FIFTHS && tonicCost(tonic, { rootPc: _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic), modeMask12: key.modeMask12 }).doubles === 0;
|
|
587
590
|
}
|
|
588
591
|
function dominantKeyOf(tonic, key) {
|
|
589
592
|
const mode = modeOf(toKeyScale(key));
|
|
590
|
-
return keyFromFifths(tonicFifths(
|
|
593
|
+
return keyFromFifths(tonicFifths(_chunkS3QELJUEcjs.toNoteData.call(void 0, tonic), mode) + 1, mode);
|
|
591
594
|
}
|
|
592
595
|
function subdominantKeyOf(tonic, key) {
|
|
593
596
|
const mode = modeOf(toKeyScale(key));
|
|
594
|
-
return keyFromFifths(tonicFifths(
|
|
597
|
+
return keyFromFifths(tonicFifths(_chunkS3QELJUEcjs.toNoteData.call(void 0, tonic), mode) - 1, mode);
|
|
595
598
|
}
|
|
596
599
|
function enharmonicKeyOf(tonic, key) {
|
|
597
|
-
const note =
|
|
600
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
598
601
|
const scale = toKeyScale(key);
|
|
599
602
|
maskOf(scale);
|
|
600
603
|
for (const position of [
|
|
@@ -612,7 +615,7 @@ function enharmonicKeyOf(tonic, key) {
|
|
|
612
615
|
tonic: spelled2,
|
|
613
616
|
// The mask is the caller's; only the root is re-read, so a tonic that did
|
|
614
617
|
// not spell the mask's own root still comes back consistent.
|
|
615
|
-
scale: { rootPc:
|
|
618
|
+
scale: { rootPc: _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, spelled2), modeMask12: scale.modeMask12 },
|
|
616
619
|
variant: variantOfMask(scale.modeMask12)
|
|
617
620
|
};
|
|
618
621
|
}
|
|
@@ -635,13 +638,13 @@ var CLOSELY_RELATED = [
|
|
|
635
638
|
{ relation: "relativeOfSubdominant", of: relativeOfSubdominantKeyOf }
|
|
636
639
|
];
|
|
637
640
|
function relatedKeysOf(tonic, key) {
|
|
638
|
-
const note =
|
|
641
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
639
642
|
const scale = toKeyScale(key);
|
|
640
643
|
return CLOSELY_RELATED.map(({ relation, of }) => ({ ...of(note, scale), relation }));
|
|
641
644
|
}
|
|
642
645
|
function keyRelationBetween(a, b) {
|
|
643
|
-
const from =
|
|
644
|
-
const to =
|
|
646
|
+
const from = _chunkS3QELJUEcjs.assertRecord.call(void 0, a, "a");
|
|
647
|
+
const to = _chunkS3QELJUEcjs.assertRecord.call(void 0, b, "b");
|
|
645
648
|
maskOf(from.scale, "a.scale");
|
|
646
649
|
maskOf(to.scale, "b.scale");
|
|
647
650
|
if (soundsLike(from.scale, to.scale)) {
|
|
@@ -660,9 +663,9 @@ function carriesIdentity(value) {
|
|
|
660
663
|
return typeof value === "object" && value !== null;
|
|
661
664
|
}
|
|
662
665
|
function carriedTonic(tonic, scale) {
|
|
663
|
-
if (
|
|
664
|
-
throw new (0,
|
|
665
|
-
`tonic ${
|
|
666
|
+
if (_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic) !== scale.rootPc) {
|
|
667
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
668
|
+
`tonic ${_chunkS3QELJUEcjs.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
669
|
);
|
|
667
670
|
}
|
|
668
671
|
return { letter: tonic.letter, alter: tonic.alter };
|
|
@@ -682,7 +685,7 @@ function resolveKey(value) {
|
|
|
682
685
|
return { scale, tonic, variant };
|
|
683
686
|
}
|
|
684
687
|
function scaleOf(key) {
|
|
685
|
-
const scale =
|
|
688
|
+
const scale = _chunkS3QELJUEcjs.assertRecord.call(void 0, key, "key").scale;
|
|
686
689
|
maskOf(scale, "key.scale");
|
|
687
690
|
return scale;
|
|
688
691
|
}
|
|
@@ -765,7 +768,7 @@ function scaleSystemOf(scale) {
|
|
|
765
768
|
if (typeof scale === "string") {
|
|
766
769
|
const canonical = resolveScaleName(scale);
|
|
767
770
|
if (canonical === void 0) {
|
|
768
|
-
throw new (0,
|
|
771
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown scale: ${scale}`);
|
|
769
772
|
}
|
|
770
773
|
return SCALE_SYSTEMS[canonical];
|
|
771
774
|
}
|
|
@@ -1067,7 +1070,7 @@ var QUALITY_BY_KEY = new Map(
|
|
|
1067
1070
|
function chordSpecForQuality(quality, rootPc, bassPc) {
|
|
1068
1071
|
const named = SPEC_BY_QUALITY.get(quality);
|
|
1069
1072
|
if (named === void 0) {
|
|
1070
|
-
throw new (0,
|
|
1073
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
|
|
1071
1074
|
}
|
|
1072
1075
|
const spec = normalizeChordSpec(named);
|
|
1073
1076
|
spec.rootPc = rootPc;
|
|
@@ -1097,7 +1100,7 @@ function chordSpecQuality(spec) {
|
|
|
1097
1100
|
}
|
|
1098
1101
|
return _nullishCoalesce(nearest, () => ( BASE_QUALITY[checked.base]));
|
|
1099
1102
|
}
|
|
1100
|
-
var
|
|
1103
|
+
var EXTENSION_ENTRIES = [
|
|
1101
1104
|
[13, { degree: 9, alter: -1 }],
|
|
1102
1105
|
[14, { degree: 9, alter: 0 }],
|
|
1103
1106
|
[15, { degree: 9, alter: 1 }],
|
|
@@ -1107,7 +1110,8 @@ var EXTENSION_BY_SEMITONE = /* @__PURE__ */ new Map([
|
|
|
1107
1110
|
[20, { degree: 13, alter: -1 }],
|
|
1108
1111
|
[21, { degree: 13, alter: 0 }],
|
|
1109
1112
|
[22, { degree: 13, alter: 1 }]
|
|
1110
|
-
]
|
|
1113
|
+
];
|
|
1114
|
+
var EXTENSION_BY_SEMITONE = new Map(EXTENSION_ENTRIES);
|
|
1111
1115
|
function sameOffsets(a, b) {
|
|
1112
1116
|
return a.length === b.length && a.every((offset, index) => offset === b[index]);
|
|
1113
1117
|
}
|
|
@@ -1172,17 +1176,20 @@ function chordSpecFromIntervals(intervals) {
|
|
|
1172
1176
|
const normalized = normalizeChordSpec(spec);
|
|
1173
1177
|
return sameOffsets(specIntervals(normalized), offsets) ? normalized : void 0;
|
|
1174
1178
|
}
|
|
1179
|
+
var ALTERABLE_DEGREES = [5, 9, 11, 13];
|
|
1180
|
+
var ALTERATION_STEPS = [-1, 0, 1];
|
|
1181
|
+
var ADDABLE_DEGREES = [6, 9, 11, 13];
|
|
1175
1182
|
function assertPart(value, allowed, name) {
|
|
1176
1183
|
if (!allowed.includes(value)) {
|
|
1177
|
-
throw new (0,
|
|
1178
|
-
`${name} must be one of ${allowed.join(", ")}; received ${
|
|
1184
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1185
|
+
`${name} must be one of ${allowed.join(", ")}; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`
|
|
1179
1186
|
);
|
|
1180
1187
|
}
|
|
1181
1188
|
return value;
|
|
1182
1189
|
}
|
|
1183
1190
|
function assertDegreeIn(value, allowed, name) {
|
|
1184
1191
|
if (!allowed.includes(value)) {
|
|
1185
|
-
throw new (0,
|
|
1192
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1186
1193
|
`${name} must be one of ${allowed.join(", ")}; received ${String(value)}`
|
|
1187
1194
|
);
|
|
1188
1195
|
}
|
|
@@ -1190,7 +1197,7 @@ function assertDegreeIn(value, allowed, name) {
|
|
|
1190
1197
|
}
|
|
1191
1198
|
function assertDegreeList(value, allowed, name) {
|
|
1192
1199
|
if (!Array.isArray(value)) {
|
|
1193
|
-
throw new (0,
|
|
1200
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`${name} must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`);
|
|
1194
1201
|
}
|
|
1195
1202
|
for (const degree of value) {
|
|
1196
1203
|
assertDegreeIn(degree, allowed, name);
|
|
@@ -1198,11 +1205,11 @@ function assertDegreeList(value, allowed, name) {
|
|
|
1198
1205
|
}
|
|
1199
1206
|
function assertChordSpec(spec) {
|
|
1200
1207
|
if (spec === null || typeof spec !== "object") {
|
|
1201
|
-
throw new (0,
|
|
1208
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`chord spec must be an object; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, spec)}`);
|
|
1202
1209
|
}
|
|
1203
|
-
|
|
1210
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, spec.rootPc, "chord spec rootPc");
|
|
1204
1211
|
if (spec.bassPc !== void 0) {
|
|
1205
|
-
|
|
1212
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, spec.bassPc, "chord spec bassPc");
|
|
1206
1213
|
}
|
|
1207
1214
|
assertPart(spec.base, Object.keys(BASE_TONES), "chord spec base");
|
|
1208
1215
|
if (spec.seventh !== void 0) {
|
|
@@ -1213,13 +1220,13 @@ function assertChordSpec(spec) {
|
|
|
1213
1220
|
);
|
|
1214
1221
|
}
|
|
1215
1222
|
if (!Array.isArray(spec.alterations)) {
|
|
1216
|
-
throw new (0,
|
|
1223
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("chord spec alterations must be an array");
|
|
1217
1224
|
}
|
|
1218
1225
|
for (const alteration of spec.alterations) {
|
|
1219
|
-
assertDegreeIn(_optionalChain([alteration, 'optionalAccess', _5 => _5.degree]),
|
|
1220
|
-
assertDegreeIn(alteration.alter,
|
|
1226
|
+
assertDegreeIn(_optionalChain([alteration, 'optionalAccess', _5 => _5.degree]), ALTERABLE_DEGREES, "chord spec alteration degree");
|
|
1227
|
+
assertDegreeIn(alteration.alter, ALTERATION_STEPS, "chord spec alteration");
|
|
1221
1228
|
}
|
|
1222
|
-
assertDegreeList(spec.additions,
|
|
1229
|
+
assertDegreeList(spec.additions, ADDABLE_DEGREES, "chord spec additions");
|
|
1223
1230
|
assertDegreeList(spec.omissions, OMITTABLE_DEGREES, "chord spec omissions");
|
|
1224
1231
|
return normalizeChordSpec(spec);
|
|
1225
1232
|
}
|
|
@@ -1230,60 +1237,84 @@ function chordQualities() {
|
|
|
1230
1237
|
return [...QUALITY_ORDER];
|
|
1231
1238
|
}
|
|
1232
1239
|
function assertChordQuality(quality) {
|
|
1233
|
-
if (!Object.hasOwn(QUALITY_INTERVALS, quality)) {
|
|
1234
|
-
throw new (0,
|
|
1240
|
+
if (typeof quality !== "string" || !Object.hasOwn(QUALITY_INTERVALS, quality)) {
|
|
1241
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
|
|
1235
1242
|
}
|
|
1236
1243
|
return quality;
|
|
1237
1244
|
}
|
|
1238
1245
|
function assertChord(chord, name = "chord") {
|
|
1239
|
-
const read =
|
|
1240
|
-
|
|
1246
|
+
const read = _chunkS3QELJUEcjs.assertRecord.call(void 0, chord, name);
|
|
1247
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, read.rootPc, `${name}.rootPc`);
|
|
1241
1248
|
assertChordQuality(read.quality);
|
|
1242
1249
|
return read;
|
|
1243
1250
|
}
|
|
1244
1251
|
function chordFromDegree(degree, ext, key) {
|
|
1245
|
-
|
|
1252
|
+
_chunkS3QELJUEcjs.assertDegree.call(void 0, degree, "chord degree");
|
|
1246
1253
|
assertChordQuality(ext);
|
|
1247
|
-
const
|
|
1248
|
-
const tones = scaleTonesInDegreeOrder(scale);
|
|
1254
|
+
const resolved = resolveKey(key);
|
|
1255
|
+
const tones = scaleTonesInDegreeOrder(resolved.scale);
|
|
1249
1256
|
const length = tones.length;
|
|
1250
1257
|
const index = length > 0 ? (degree - 1) % length : 0;
|
|
1251
|
-
const rootPc = _nullishCoalesce(tones[index], () => (
|
|
1252
|
-
return
|
|
1258
|
+
const rootPc = _nullishCoalesce(tones[index], () => ( _chunkS3QELJUEcjs.pitchClassOf.call(void 0, resolved.scale.rootPc)));
|
|
1259
|
+
return makeSpelledChord(rootPc, ext, { rootSpelling: keySpelling(rootPc, resolved) });
|
|
1253
1260
|
}
|
|
1254
1261
|
function makeChord(rootPc, quality, bassPc) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1262
|
+
return makeSpelledChord(rootPc, quality, { bassPc });
|
|
1263
|
+
}
|
|
1264
|
+
function makeSpelledChord(rootPc, quality, parts2 = {}) {
|
|
1265
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, rootPc, "chord rootPc");
|
|
1266
|
+
if (parts2.bassPc !== void 0) {
|
|
1267
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, parts2.bassPc, "chord bassPc");
|
|
1258
1268
|
}
|
|
1259
1269
|
assertChordQuality(quality);
|
|
1260
1270
|
const chord = {
|
|
1261
|
-
rootPc:
|
|
1271
|
+
rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc),
|
|
1262
1272
|
quality,
|
|
1263
1273
|
intervals: [..._nullishCoalesce(QUALITY_INTERVALS[quality], () => ( []))]
|
|
1264
1274
|
};
|
|
1265
|
-
if (bassPc !== void 0) {
|
|
1266
|
-
chord.bassPc =
|
|
1275
|
+
if (parts2.bassPc !== void 0) {
|
|
1276
|
+
chord.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, parts2.bassPc);
|
|
1277
|
+
}
|
|
1278
|
+
if (parts2.rootSpelling !== void 0) {
|
|
1279
|
+
chord.rootSpelling = { letter: parts2.rootSpelling.letter, alter: parts2.rootSpelling.alter };
|
|
1280
|
+
}
|
|
1281
|
+
if (parts2.bassSpelling !== void 0) {
|
|
1282
|
+
chord.bassSpelling = { letter: parts2.bassSpelling.letter, alter: parts2.bassSpelling.alter };
|
|
1283
|
+
} else if (chord.rootSpelling !== void 0 && chord.bassPc !== void 0) {
|
|
1284
|
+
const index = chord.intervals.findIndex(
|
|
1285
|
+
(interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === chord.bassPc
|
|
1286
|
+
);
|
|
1287
|
+
const tone = index >= 0 ? spellChordFromRoot(chord, chord.rootSpelling)[index] : void 0;
|
|
1288
|
+
if (tone !== void 0) {
|
|
1289
|
+
chord.bassSpelling = { letter: tone.letter, alter: tone.alter };
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
if (parts2.toneSpellings !== void 0) {
|
|
1293
|
+
chord.toneSpellings = parts2.toneSpellings.map(({ letter, alter }) => ({ letter, alter }));
|
|
1267
1294
|
}
|
|
1268
1295
|
return chord;
|
|
1269
1296
|
}
|
|
1297
|
+
function keySpelling(pc, key) {
|
|
1298
|
+
const { letter, alter } = spellPitchClass(pc, key.tonic, key.scale);
|
|
1299
|
+
return { letter, alter };
|
|
1300
|
+
}
|
|
1270
1301
|
function chordFromSpec(spec) {
|
|
1271
1302
|
const checked = assertChordSpec(spec);
|
|
1272
1303
|
const chord = {
|
|
1273
|
-
rootPc:
|
|
1304
|
+
rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, checked.rootPc),
|
|
1274
1305
|
quality: chordSpecQuality(checked),
|
|
1275
1306
|
intervals: chordSpecIntervals(checked)
|
|
1276
1307
|
};
|
|
1277
1308
|
if (checked.bassPc !== void 0) {
|
|
1278
|
-
chord.bassPc =
|
|
1309
|
+
chord.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, checked.bassPc);
|
|
1279
1310
|
}
|
|
1280
1311
|
return chord;
|
|
1281
1312
|
}
|
|
1282
1313
|
function chordSpecOf(chord) {
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
const rootPc =
|
|
1286
|
-
const bassPc = chord.bassPc === void 0 ? void 0 :
|
|
1314
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, chord, "chord");
|
|
1315
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, chord.rootPc, "chord rootPc");
|
|
1316
|
+
const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc);
|
|
1317
|
+
const bassPc = chord.bassPc === void 0 ? void 0 : _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc);
|
|
1287
1318
|
const intervals = _nullishCoalesce(chord.intervals, () => ( []));
|
|
1288
1319
|
const read = intervals.length === 0 ? void 0 : chordSpecFromIntervals(intervals);
|
|
1289
1320
|
if (read === void 0) {
|
|
@@ -1298,21 +1329,23 @@ function chordSpecOf(chord) {
|
|
|
1298
1329
|
function copySpanIntervals(intervals) {
|
|
1299
1330
|
const name = "chord span intervals";
|
|
1300
1331
|
if (!Array.isArray(intervals)) {
|
|
1301
|
-
throw new (0,
|
|
1332
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1333
|
+
`${name} must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, intervals)}`
|
|
1334
|
+
);
|
|
1302
1335
|
}
|
|
1303
1336
|
if (intervals.length === 0) {
|
|
1304
|
-
throw new (0,
|
|
1337
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`${name} must name at least one interval`);
|
|
1305
1338
|
}
|
|
1306
1339
|
const copy = [];
|
|
1307
1340
|
for (let index = 0; index < intervals.length; index += 1) {
|
|
1308
1341
|
const interval = intervals[index];
|
|
1309
1342
|
if (interval === void 0) {
|
|
1310
|
-
throw new (0,
|
|
1343
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1311
1344
|
`${name}[${index}] must be a semitone offset; received undefined`
|
|
1312
1345
|
);
|
|
1313
1346
|
}
|
|
1314
1347
|
copy.push(
|
|
1315
|
-
|
|
1348
|
+
_chunkS3QELJUEcjs.assertInteger.call(void 0, interval, `${name}[${index}]`, -MAX_CHORD_INTERVAL, MAX_CHORD_INTERVAL)
|
|
1316
1349
|
);
|
|
1317
1350
|
}
|
|
1318
1351
|
return copy;
|
|
@@ -1321,15 +1354,15 @@ function hasCustomIntervals(chord) {
|
|
|
1321
1354
|
return !matchesQualityIntervals(chord.quality, chord.intervals);
|
|
1322
1355
|
}
|
|
1323
1356
|
function chordFromSpan(span) {
|
|
1324
|
-
|
|
1325
|
-
const chord =
|
|
1357
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, span, "chord span");
|
|
1358
|
+
const chord = makeSpelledChord(span.rootPc, span.quality, { bassPc: span.bassPc });
|
|
1326
1359
|
if (span.intervals !== void 0) {
|
|
1327
1360
|
chord.intervals = copySpanIntervals(span.intervals);
|
|
1328
1361
|
}
|
|
1329
1362
|
return chord;
|
|
1330
1363
|
}
|
|
1331
1364
|
function spanFromChord(chord, startBeat) {
|
|
1332
|
-
|
|
1365
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, startBeat, "chord span startBeat");
|
|
1333
1366
|
assertChord(chord);
|
|
1334
1367
|
const span = { rootPc: chord.rootPc, quality: chord.quality, startBeat };
|
|
1335
1368
|
if (chord.bassPc !== void 0) {
|
|
@@ -1342,15 +1375,15 @@ function spanFromChord(chord, startBeat) {
|
|
|
1342
1375
|
}
|
|
1343
1376
|
function transposeChord(chord, semitones) {
|
|
1344
1377
|
assertChord(chord);
|
|
1345
|
-
|
|
1378
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, semitones, "semitones");
|
|
1346
1379
|
const steps = Math.round(semitones);
|
|
1347
1380
|
const moved = {
|
|
1348
|
-
rootPc:
|
|
1381
|
+
rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + steps),
|
|
1349
1382
|
quality: chord.quality,
|
|
1350
1383
|
intervals: [...chord.intervals]
|
|
1351
1384
|
};
|
|
1352
1385
|
if (chord.bassPc !== void 0) {
|
|
1353
|
-
moved.bassPc =
|
|
1386
|
+
moved.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc + steps);
|
|
1354
1387
|
}
|
|
1355
1388
|
return moved;
|
|
1356
1389
|
}
|
|
@@ -1366,20 +1399,20 @@ function chordToneSpellings(chord) {
|
|
|
1366
1399
|
if (hint === void 0 || interval === void 0) {
|
|
1367
1400
|
return void 0;
|
|
1368
1401
|
}
|
|
1369
|
-
if (
|
|
1402
|
+
if (_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, hint) !== _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval)) {
|
|
1370
1403
|
return void 0;
|
|
1371
1404
|
}
|
|
1372
|
-
usable.push({ letter:
|
|
1405
|
+
usable.push({ letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter });
|
|
1373
1406
|
}
|
|
1374
1407
|
return usable;
|
|
1375
1408
|
}
|
|
1376
1409
|
function chordToneLetterOffsets(chord) {
|
|
1377
1410
|
const hints = chordToneSpellings(chord);
|
|
1378
|
-
const rootHint = _optionalChain([hints, 'optionalAccess', _6 => _6[chord.intervals.findIndex((interval) =>
|
|
1411
|
+
const rootHint = _optionalChain([hints, 'optionalAccess', _6 => _6[chord.intervals.findIndex((interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, interval) === 0)]]);
|
|
1379
1412
|
if (hints === void 0 || rootHint === void 0) {
|
|
1380
1413
|
return void 0;
|
|
1381
1414
|
}
|
|
1382
|
-
return hints.map((hint) =>
|
|
1415
|
+
return hints.map((hint) => _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, hint.letter - rootHint.letter));
|
|
1383
1416
|
}
|
|
1384
1417
|
var ROLE_BY_LETTER_OFFSET = {
|
|
1385
1418
|
0: "root",
|
|
@@ -1394,20 +1427,20 @@ function spelledToneRole(pitch, chord) {
|
|
|
1394
1427
|
return void 0;
|
|
1395
1428
|
}
|
|
1396
1429
|
const index = chord.intervals.findIndex(
|
|
1397
|
-
(interval) =>
|
|
1430
|
+
(interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch)
|
|
1398
1431
|
);
|
|
1399
1432
|
const offset = offsets[index];
|
|
1400
1433
|
return offset === void 0 ? void 0 : _nullishCoalesce(ROLE_BY_LETTER_OFFSET[offset], () => ( null));
|
|
1401
1434
|
}
|
|
1402
1435
|
function chordPcMask(chord, opts = {}) {
|
|
1403
|
-
|
|
1404
|
-
|
|
1436
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, chord, "chord");
|
|
1437
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, chord.intervals, "chord intervals");
|
|
1405
1438
|
let mask = 0;
|
|
1406
1439
|
for (const interval of chord.intervals) {
|
|
1407
|
-
mask |= 1 <<
|
|
1440
|
+
mask |= 1 << _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
1408
1441
|
}
|
|
1409
1442
|
if (opts.includeBass !== false && chord.bassPc !== void 0) {
|
|
1410
|
-
mask |= 1 <<
|
|
1443
|
+
mask |= 1 << _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc);
|
|
1411
1444
|
}
|
|
1412
1445
|
return mask;
|
|
1413
1446
|
}
|
|
@@ -1422,7 +1455,7 @@ function chordIntervalMask(chord) {
|
|
|
1422
1455
|
return mask;
|
|
1423
1456
|
}
|
|
1424
1457
|
function chordPitchClasses(chord, opts = {}) {
|
|
1425
|
-
const mask = chordPcMask(assertChord(chord),
|
|
1458
|
+
const mask = chordPcMask(assertChord(chord), _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts"));
|
|
1426
1459
|
const pcs = [];
|
|
1427
1460
|
for (let pc = 0; pc < 12; pc += 1) {
|
|
1428
1461
|
if (hasPitchClass(mask, pc)) {
|
|
@@ -1432,18 +1465,18 @@ function chordPitchClasses(chord, opts = {}) {
|
|
|
1432
1465
|
return pcs;
|
|
1433
1466
|
}
|
|
1434
1467
|
function intervalAboveRoot(pitch, chord) {
|
|
1435
|
-
return ((
|
|
1468
|
+
return ((_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch) - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, assertChord(chord).rootPc)) % 12 + 12) % 12;
|
|
1436
1469
|
}
|
|
1437
1470
|
function isChordMember(pitch, chord) {
|
|
1438
|
-
return chord === null ? false : hasPitchClass(chordPcMask(chord),
|
|
1471
|
+
return chord === null ? false : hasPitchClass(chordPcMask(chord), _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch));
|
|
1439
1472
|
}
|
|
1440
1473
|
function chordToneRole(pitch, chord) {
|
|
1441
|
-
|
|
1474
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, chord, "chord");
|
|
1442
1475
|
const spelled2 = spelledToneRole(pitch, chord);
|
|
1443
1476
|
if (spelled2 !== void 0) {
|
|
1444
1477
|
return spelled2;
|
|
1445
1478
|
}
|
|
1446
|
-
const interval = (
|
|
1479
|
+
const interval = (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch) - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc) + 12) % 12;
|
|
1447
1480
|
const tones = chordIntervalMask(chord);
|
|
1448
1481
|
const sounds = (ic) => hasPitchClass(tones, ic);
|
|
1449
1482
|
if (interval === 0) {
|
|
@@ -1486,7 +1519,7 @@ var DEGREE_BY_ROLE = {
|
|
|
1486
1519
|
};
|
|
1487
1520
|
var TENSION_DEGREE = [1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7];
|
|
1488
1521
|
function degreeOfInterval(interval, chord) {
|
|
1489
|
-
const role = chordToneRole(
|
|
1522
|
+
const role = chordToneRole(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval), chord);
|
|
1490
1523
|
if (role !== null) {
|
|
1491
1524
|
return DEGREE_BY_ROLE[role];
|
|
1492
1525
|
}
|
|
@@ -1510,7 +1543,7 @@ function thirdSlotOf(chord) {
|
|
|
1510
1543
|
return { kind: "none" };
|
|
1511
1544
|
}
|
|
1512
1545
|
function displacedThirds(chord) {
|
|
1513
|
-
return thirdSlotOf(chord).kind === "suspension" ? [
|
|
1546
|
+
return thirdSlotOf(chord).kind === "suspension" ? [_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + 3), _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + 4)] : [];
|
|
1514
1547
|
}
|
|
1515
1548
|
function classifyTriad(thirdIc, fifthIc) {
|
|
1516
1549
|
if (thirdIc === 4 && fifthIc === 8) {
|
|
@@ -1558,17 +1591,18 @@ function matchesQualityIntervals(quality, intervals) {
|
|
|
1558
1591
|
const template = QUALITY_INTERVALS[quality];
|
|
1559
1592
|
return template.length === intervals.length && template.every((interval, index) => interval === intervals[index]);
|
|
1560
1593
|
}
|
|
1561
|
-
function stackThirds(degree,
|
|
1562
|
-
|
|
1594
|
+
function stackThirds(degree, resolved, size) {
|
|
1595
|
+
_chunkS3QELJUEcjs.assertDegree.call(void 0, degree, "chord degree");
|
|
1596
|
+
const key = resolved.scale;
|
|
1563
1597
|
const tones = scaleTonesInDegreeOrder(key);
|
|
1564
1598
|
const length = tones.length;
|
|
1565
1599
|
if (length !== 7) {
|
|
1566
|
-
throw new (0,
|
|
1600
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1567
1601
|
`diatonic chord stacking requires a heptatonic scale (received ${length} tones)`
|
|
1568
1602
|
);
|
|
1569
1603
|
}
|
|
1570
1604
|
const idx = (step) => (degree - 1 + step) % length;
|
|
1571
|
-
const rootPc = _nullishCoalesce(tones[idx(0)], () => (
|
|
1605
|
+
const rootPc = _nullishCoalesce(tones[idx(0)], () => ( _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc)));
|
|
1572
1606
|
const offsets = [0, 2, 4, 6].slice(0, size).map((step) => {
|
|
1573
1607
|
const pc = _nullishCoalesce(tones[idx(step)], () => ( rootPc));
|
|
1574
1608
|
return ((pc - rootPc) % 12 + 12) % 12;
|
|
@@ -1577,17 +1611,17 @@ function stackThirds(degree, key, size) {
|
|
|
1577
1611
|
const fifthIc = _nullishCoalesce(offsets[2], () => ( 7));
|
|
1578
1612
|
const quality = size === 3 ? classifyTriad(thirdIc, fifthIc) : classifySeventh(thirdIc, fifthIc, _nullishCoalesce(offsets[3], () => ( 11)));
|
|
1579
1613
|
if (!matchesQualityIntervals(quality, offsets)) {
|
|
1580
|
-
throw new (0,
|
|
1614
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1581
1615
|
`scale thirds at degree ${degree} produce unsupported intervals [${offsets.join(", ")}]`
|
|
1582
1616
|
);
|
|
1583
1617
|
}
|
|
1584
|
-
return
|
|
1618
|
+
return makeSpelledChord(rootPc, quality, { rootSpelling: keySpelling(rootPc, resolved) });
|
|
1585
1619
|
}
|
|
1586
1620
|
function diatonicTriad(degree, key) {
|
|
1587
|
-
return stackThirds(degree,
|
|
1621
|
+
return stackThirds(degree, resolveKey(key), 3);
|
|
1588
1622
|
}
|
|
1589
1623
|
function diatonicSeventh(degree, key) {
|
|
1590
|
-
return stackThirds(degree,
|
|
1624
|
+
return stackThirds(degree, resolveKey(key), 4);
|
|
1591
1625
|
}
|
|
1592
1626
|
|
|
1593
1627
|
// src/theory/spelling/index.ts
|
|
@@ -1645,20 +1679,20 @@ var CHROMATIC_SPELLING_SHARP = {
|
|
|
1645
1679
|
// M7
|
|
1646
1680
|
};
|
|
1647
1681
|
function notePitchClass(note) {
|
|
1648
|
-
return
|
|
1682
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, note.letter) + note.alter);
|
|
1649
1683
|
}
|
|
1650
1684
|
function assertTonicOf(tonic, key, source) {
|
|
1651
1685
|
const tonicPc = notePitchClass(tonic);
|
|
1652
|
-
const rootPc =
|
|
1686
|
+
const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
1653
1687
|
if (tonicPc !== rootPc) {
|
|
1654
|
-
const name =
|
|
1655
|
-
throw new (0,
|
|
1688
|
+
const name = _chunkS3QELJUEcjs.formatNote.call(void 0, { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter });
|
|
1689
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
1656
1690
|
`${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
1691
|
);
|
|
1658
1692
|
}
|
|
1659
1693
|
}
|
|
1660
1694
|
function alterFor(letter, pc) {
|
|
1661
|
-
let d =
|
|
1695
|
+
let d = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, letter));
|
|
1662
1696
|
if (d > 6) {
|
|
1663
1697
|
d -= 12;
|
|
1664
1698
|
}
|
|
@@ -1668,7 +1702,7 @@ function letterFor(tonic, degreeOffset, pc) {
|
|
|
1668
1702
|
if (degreeOffset === void 0) {
|
|
1669
1703
|
return void 0;
|
|
1670
1704
|
}
|
|
1671
|
-
const letter =
|
|
1705
|
+
const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
|
|
1672
1706
|
return { letter, alter: alterFor(letter, pc) };
|
|
1673
1707
|
}
|
|
1674
1708
|
function pickSpelling(flat, sharp, preferFlat) {
|
|
@@ -1686,14 +1720,15 @@ function capChromaticAccidentals(preferred, alternative) {
|
|
|
1686
1720
|
var DIATONIC_LETTER_COUNT = 7;
|
|
1687
1721
|
var MAX_JOINT_TONE_COUNT = DIATONIC_LETTER_COUNT + 1;
|
|
1688
1722
|
var MAJOR_SEMITONES = [0, 2, 4, 5, 7, 9, 11];
|
|
1689
|
-
var
|
|
1723
|
+
var IMPERFECT_DEGREE_LIST = [1, 2, 5, 6];
|
|
1724
|
+
var IMPERFECT_DEGREES = new Set(IMPERFECT_DEGREE_LIST);
|
|
1690
1725
|
var DIATONIC_MODE_OFFSETS2 = MAJOR_SEMITONES.map(
|
|
1691
|
-
(tonic, mode) => MAJOR_SEMITONES.map((_, degree) =>
|
|
1726
|
+
(tonic, mode) => MAJOR_SEMITONES.map((_, degree) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, (_nullishCoalesce(MAJOR_SEMITONES[(mode + degree) % 7], () => ( 0))) - tonic))
|
|
1692
1727
|
);
|
|
1693
1728
|
function degreeStrain(tonic, note) {
|
|
1694
|
-
const letterOffset =
|
|
1695
|
-
const offset =
|
|
1696
|
-
let deviation =
|
|
1729
|
+
const letterOffset = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, note.letter - tonic.letter);
|
|
1730
|
+
const offset = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, notePitchClass(note) - notePitchClass(tonic));
|
|
1731
|
+
let deviation = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, offset - (_nullishCoalesce(MAJOR_SEMITONES[letterOffset], () => ( 0))));
|
|
1697
1732
|
if (deviation > 6) {
|
|
1698
1733
|
deviation -= 12;
|
|
1699
1734
|
}
|
|
@@ -1705,8 +1740,8 @@ function isHeptatonic(key) {
|
|
|
1705
1740
|
}
|
|
1706
1741
|
function hasMinorThird(key) {
|
|
1707
1742
|
const tones = scaleTonesInDegreeOrder(key);
|
|
1708
|
-
const root =
|
|
1709
|
-
return tones.includes(
|
|
1743
|
+
const root = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
|
|
1744
|
+
return tones.includes(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, root + 3)) && !tones.includes(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, root + 4));
|
|
1710
1745
|
}
|
|
1711
1746
|
function leansFlat(tonic, key) {
|
|
1712
1747
|
return tonic.alter < 0 || hasMinorThird(key);
|
|
@@ -1731,7 +1766,7 @@ function spellByParentMode(tonic, pcs, preferFlat) {
|
|
|
1731
1766
|
let alter = 0;
|
|
1732
1767
|
let signed = 0;
|
|
1733
1768
|
for (const pc of pcs) {
|
|
1734
|
-
const degree = offsets.indexOf(
|
|
1769
|
+
const degree = offsets.indexOf(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc));
|
|
1735
1770
|
const note = letterFor(tonic, degree < 0 ? void 0 : degree, pc);
|
|
1736
1771
|
if (note === void 0) {
|
|
1737
1772
|
break;
|
|
@@ -1754,7 +1789,7 @@ function spellByParentMode(tonic, pcs, preferFlat) {
|
|
|
1754
1789
|
return best;
|
|
1755
1790
|
}
|
|
1756
1791
|
function assignDistinctLetters(candidates, tonic, duplicates) {
|
|
1757
|
-
const reserved = 1 <<
|
|
1792
|
+
const reserved = 1 << _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter);
|
|
1758
1793
|
let best;
|
|
1759
1794
|
let bestStrain = 0;
|
|
1760
1795
|
let bestAlter = 0;
|
|
@@ -1797,7 +1832,7 @@ function assignDistinctLetters(candidates, tonic, duplicates) {
|
|
|
1797
1832
|
return best;
|
|
1798
1833
|
}
|
|
1799
1834
|
function spellGappedScale(tonic, key) {
|
|
1800
|
-
const cacheKey = `${
|
|
1835
|
+
const cacheKey = `${_chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter)}:${tonic.alter}:${key.rootPc}:${key.modeMask12}`;
|
|
1801
1836
|
const cached = JOINT_SPELLINGS.get(cacheKey);
|
|
1802
1837
|
if (cached !== void 0) {
|
|
1803
1838
|
return cached.spellings;
|
|
@@ -1816,11 +1851,11 @@ function readGappedScale(tonic, key) {
|
|
|
1816
1851
|
if (tones.length > MAX_JOINT_TONE_COUNT) {
|
|
1817
1852
|
return void 0;
|
|
1818
1853
|
}
|
|
1819
|
-
const tonicPc =
|
|
1820
|
-
const tonicNote = { letter:
|
|
1854
|
+
const tonicPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
|
|
1855
|
+
const tonicNote = { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
|
|
1821
1856
|
const preferFlat = leansFlat(tonic, key);
|
|
1822
|
-
const rest = tones.filter((pc) =>
|
|
1823
|
-
const candidates = rest.map((pc) => gappedCandidates(tonic,
|
|
1857
|
+
const rest = tones.filter((pc) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc) !== 0);
|
|
1858
|
+
const candidates = rest.map((pc) => gappedCandidates(tonic, _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc), pc, preferFlat));
|
|
1824
1859
|
const chosen = _nullishCoalesce(_nullishCoalesce(spellByParentMode(tonicNote, rest, preferFlat), () => ( // A scale that can hold a letter per tone does; only one that cannot writes
|
|
1825
1860
|
// a letter twice, and then where the doubling falls is what is chosen.
|
|
1826
1861
|
assignDistinctLetters(candidates, tonicNote, 0))), () => ( assignDistinctLetters(candidates, tonicNote, 1)));
|
|
@@ -1831,22 +1866,22 @@ function readGappedScale(tonic, key) {
|
|
|
1831
1866
|
for (const [index, pc] of rest.entries()) {
|
|
1832
1867
|
const note = chosen[index];
|
|
1833
1868
|
if (note !== void 0) {
|
|
1834
|
-
spellings.set(
|
|
1869
|
+
spellings.set(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc), note);
|
|
1835
1870
|
}
|
|
1836
1871
|
}
|
|
1837
1872
|
return spellings;
|
|
1838
1873
|
}
|
|
1839
1874
|
function spellByKey(pc, tonic, key) {
|
|
1840
|
-
const tonicPc =
|
|
1841
|
-
const offset =
|
|
1875
|
+
const tonicPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
|
|
1876
|
+
const offset = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc);
|
|
1842
1877
|
if (offset === 0) {
|
|
1843
|
-
return { letter:
|
|
1878
|
+
return { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
|
|
1844
1879
|
}
|
|
1845
1880
|
const heptatonic = isHeptatonic(key);
|
|
1846
1881
|
if (heptatonic) {
|
|
1847
|
-
const degree = scaleTonesInDegreeOrder(key).indexOf(
|
|
1882
|
+
const degree = scaleTonesInDegreeOrder(key).indexOf(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc));
|
|
1848
1883
|
if (degree >= 0) {
|
|
1849
|
-
const letter =
|
|
1884
|
+
const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter + degree);
|
|
1850
1885
|
return { letter, alter: alterFor(letter, pc) };
|
|
1851
1886
|
}
|
|
1852
1887
|
const degreeOffset = CHROMATIC_SPELLING[offset];
|
|
@@ -1859,7 +1894,7 @@ function spellByKey(pc, tonic, key) {
|
|
|
1859
1894
|
}
|
|
1860
1895
|
} else {
|
|
1861
1896
|
if (isScaleTone(pc, key)) {
|
|
1862
|
-
const assigned = _optionalChain([spellGappedScale, 'call', _9 => _9(tonic, key), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(
|
|
1897
|
+
const assigned = _optionalChain([spellGappedScale, 'call', _9 => _9(tonic, key), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc))]);
|
|
1863
1898
|
if (assigned !== void 0) {
|
|
1864
1899
|
return { letter: assigned.letter, alter: assigned.alter };
|
|
1865
1900
|
}
|
|
@@ -1869,9 +1904,10 @@ function spellByKey(pc, tonic, key) {
|
|
|
1869
1904
|
return preferred;
|
|
1870
1905
|
}
|
|
1871
1906
|
}
|
|
1872
|
-
const belowLetter =
|
|
1907
|
+
const belowLetter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, _nullishCoalesce(LETTER_BELOW_PITCH_CLASS[_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc)], () => ( 0)));
|
|
1873
1908
|
return { letter: belowLetter, alter: alterFor(belowLetter, pc) };
|
|
1874
1909
|
}
|
|
1910
|
+
var LETTER_BELOW_PITCH_CLASS = [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6];
|
|
1875
1911
|
var CHORD_TONE_LETTER_STEPS = {
|
|
1876
1912
|
0: 0,
|
|
1877
1913
|
// root
|
|
@@ -1898,7 +1934,7 @@ function chordToneLetterStep(pc, rootPc, chord) {
|
|
|
1898
1934
|
if (chord !== void 0) {
|
|
1899
1935
|
const offsets = chordToneLetterOffsets(chord);
|
|
1900
1936
|
const index = chord.intervals.findIndex(
|
|
1901
|
-
(interval) =>
|
|
1937
|
+
(interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc)
|
|
1902
1938
|
);
|
|
1903
1939
|
const offset = _optionalChain([offsets, 'optionalAccess', _12 => _12[index]]);
|
|
1904
1940
|
if (offset !== void 0) {
|
|
@@ -1909,7 +1945,7 @@ function chordToneLetterStep(pc, rootPc, chord) {
|
|
|
1909
1945
|
return LETTER_STEP_BY_ROLE[role];
|
|
1910
1946
|
}
|
|
1911
1947
|
}
|
|
1912
|
-
return CHORD_TONE_LETTER_STEPS[
|
|
1948
|
+
return CHORD_TONE_LETTER_STEPS[_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - rootPc)];
|
|
1913
1949
|
}
|
|
1914
1950
|
function spellChordTone(pc, context, tonic, key) {
|
|
1915
1951
|
const { chord } = context;
|
|
@@ -1917,19 +1953,19 @@ function spellChordTone(pc, context, tonic, key) {
|
|
|
1917
1953
|
if (chordRoot === void 0) {
|
|
1918
1954
|
return void 0;
|
|
1919
1955
|
}
|
|
1920
|
-
const root = chord === void 0 ? spellByKey(
|
|
1956
|
+
const root = chord === void 0 ? spellByKey(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chordRoot), tonic, key) : chordRootSpelling(chord, tonic, key);
|
|
1921
1957
|
return letterFor(root, chordToneLetterStep(pc, chordRoot, chord), pc);
|
|
1922
1958
|
}
|
|
1923
1959
|
function neighbourSpelling(neighbour, gap, letterStep, pc, tonic, key) {
|
|
1924
|
-
if (neighbour === void 0 ||
|
|
1960
|
+
if (neighbour === void 0 || _chunkS3QELJUEcjs.pitchClassOf.call(void 0, neighbour - pc) !== _chunkS3QELJUEcjs.pitchClassOf.call(void 0, gap)) {
|
|
1925
1961
|
return void 0;
|
|
1926
1962
|
}
|
|
1927
|
-
return letterFor(spellByKey(
|
|
1963
|
+
return letterFor(spellByKey(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, neighbour), tonic, key), letterStep, pc);
|
|
1928
1964
|
}
|
|
1929
|
-
function refineByContext(pc, tonic, key, context,
|
|
1930
|
-
const tonicPc =
|
|
1931
|
-
if (
|
|
1932
|
-
return
|
|
1965
|
+
function refineByContext(pc, tonic, key, context, keySpelling2) {
|
|
1966
|
+
const tonicPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
|
|
1967
|
+
if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc) === tonicPc || isScaleTone(pc, key)) {
|
|
1968
|
+
return keySpelling2;
|
|
1933
1969
|
}
|
|
1934
1970
|
const { previous, next } = context;
|
|
1935
1971
|
const candidates = [
|
|
@@ -1952,34 +1988,35 @@ function refineByContext(pc, tonic, key, context, keySpelling) {
|
|
|
1952
1988
|
return candidate;
|
|
1953
1989
|
}
|
|
1954
1990
|
}
|
|
1955
|
-
return
|
|
1991
|
+
return keySpelling2;
|
|
1956
1992
|
}
|
|
1957
1993
|
function spellPitchClass(pc, tonic, key, context) {
|
|
1958
|
-
const note =
|
|
1994
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
1959
1995
|
const scale = toKeyScale(key);
|
|
1960
1996
|
assertTonicOf(note, scale, "spellPitchClass");
|
|
1961
|
-
|
|
1997
|
+
_chunkS3QELJUEcjs.assertOptions.call(void 0, context, "context");
|
|
1962
1998
|
return spelledPitchClass(pc, note, scale, context);
|
|
1963
1999
|
}
|
|
1964
2000
|
function spelledPitchClass(pc, tonic, key, context) {
|
|
1965
|
-
const
|
|
1966
|
-
return context === void 0 ?
|
|
2001
|
+
const keySpelling2 = spellByKey(pc, tonic, key);
|
|
2002
|
+
return context === void 0 ? keySpelling2 : refineByContext(pc, tonic, key, context, keySpelling2);
|
|
1967
2003
|
}
|
|
1968
2004
|
function spellScale(tonic, key) {
|
|
1969
|
-
const note =
|
|
2005
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
1970
2006
|
const scale = toKeyScale(key);
|
|
1971
2007
|
assertTonicOf(note, scale, "spellScale");
|
|
1972
2008
|
return scaleTonesInDegreeOrder(scale).map((pc) => spelledPitchClass(pc, note, scale));
|
|
1973
2009
|
}
|
|
1974
2010
|
function spellPitchClasses(pcs, tonic, key) {
|
|
1975
|
-
const classes =
|
|
1976
|
-
const note =
|
|
2011
|
+
const classes = _chunkS3QELJUEcjs.assertArray.call(void 0, pcs, "pcs");
|
|
2012
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
1977
2013
|
const scale = toKeyScale(key);
|
|
1978
2014
|
assertTonicOf(note, scale, "spellPitchClasses");
|
|
1979
2015
|
return classes.map(
|
|
1980
|
-
(pc, index) => spelledPitchClass(
|
|
2016
|
+
(pc, index) => spelledPitchClass(_chunkS3QELJUEcjs.assertPitchClass.call(void 0, pc, `pcs[${index}]`), note, scale)
|
|
1981
2017
|
);
|
|
1982
2018
|
}
|
|
2019
|
+
var SIMPLE_LETTER_OFFSETS = [0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6];
|
|
1983
2020
|
function chordLetterOffset(interval, chord) {
|
|
1984
2021
|
switch (interval) {
|
|
1985
2022
|
case 0:
|
|
@@ -1994,7 +2031,7 @@ function chordLetterOffset(interval, chord) {
|
|
|
1994
2031
|
case 4:
|
|
1995
2032
|
return 2;
|
|
1996
2033
|
case 15:
|
|
1997
|
-
return
|
|
2034
|
+
return 1;
|
|
1998
2035
|
case 5:
|
|
1999
2036
|
case 16:
|
|
2000
2037
|
case 17:
|
|
@@ -2017,74 +2054,74 @@ function chordLetterOffset(interval, chord) {
|
|
|
2017
2054
|
return 6;
|
|
2018
2055
|
default: {
|
|
2019
2056
|
const octaves = Math.floor(Math.max(0, interval) / 12);
|
|
2020
|
-
const simple =
|
|
2021
|
-
const simpleOffset = _nullishCoalesce([
|
|
2057
|
+
const simple = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, interval);
|
|
2058
|
+
const simpleOffset = _nullishCoalesce(SIMPLE_LETTER_OFFSETS[simple], () => ( 0));
|
|
2022
2059
|
return octaves * 7 + simpleOffset;
|
|
2023
2060
|
}
|
|
2024
2061
|
}
|
|
2025
2062
|
}
|
|
2026
2063
|
function spellChordFromRoot(chord, root) {
|
|
2027
|
-
return chordTonesFromRoot(assertChord(chord),
|
|
2064
|
+
return chordTonesFromRoot(assertChord(chord), _chunkS3QELJUEcjs.toNoteData.call(void 0, root));
|
|
2028
2065
|
}
|
|
2029
2066
|
function chordTonesFromRoot(chord, root) {
|
|
2030
|
-
if (
|
|
2031
|
-
throw new (0,
|
|
2067
|
+
if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, root.letter) + root.alter) !== _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc)) {
|
|
2068
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("chord root spelling must match chord.rootPc");
|
|
2032
2069
|
}
|
|
2033
2070
|
const hinted = chordToneLetterOffsets(chord);
|
|
2034
2071
|
return chord.intervals.map((interval, index) => {
|
|
2035
|
-
const letter =
|
|
2036
|
-
const pc =
|
|
2072
|
+
const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, root.letter + (_nullishCoalesce(_optionalChain([hinted, 'optionalAccess', _14 => _14[index]]), () => ( chordLetterOffset(interval, chord)))));
|
|
2073
|
+
const pc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
2037
2074
|
return { letter, alter: alterFor(letter, pc) };
|
|
2038
2075
|
});
|
|
2039
2076
|
}
|
|
2040
2077
|
function spellChord(chord, tonic, key) {
|
|
2041
2078
|
assertChord(chord);
|
|
2042
|
-
const note =
|
|
2079
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
2043
2080
|
const scale = toKeyScale(key);
|
|
2044
2081
|
assertTonicOf(note, scale, "spellChord");
|
|
2045
2082
|
return chordTonesFromRoot(chord, chordRootSpelling(chord, note, scale));
|
|
2046
2083
|
}
|
|
2047
2084
|
function chordRootSpelling(chord, tonic, key) {
|
|
2048
2085
|
const hint = chord.rootSpelling;
|
|
2049
|
-
if (hint !== void 0 &&
|
|
2050
|
-
return { letter:
|
|
2086
|
+
if (hint !== void 0 && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, hint.letter) + hint.alter) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc)) {
|
|
2087
|
+
return { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter };
|
|
2051
2088
|
}
|
|
2052
2089
|
return spelledPitchClass(chord.rootPc, tonic, key);
|
|
2053
2090
|
}
|
|
2054
2091
|
function spellPitch(pitch, tonic, key, context) {
|
|
2055
|
-
const note =
|
|
2092
|
+
const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
|
|
2056
2093
|
const scale = toKeyScale(key);
|
|
2057
2094
|
assertTonicOf(note, scale, "spellPitch");
|
|
2058
|
-
|
|
2059
|
-
const rounded = Math.round(
|
|
2060
|
-
const spelled2 = spelledPitchClass(
|
|
2061
|
-
const octave = (rounded -
|
|
2095
|
+
_chunkS3QELJUEcjs.assertOptions.call(void 0, context, "context");
|
|
2096
|
+
const rounded = Math.round(_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, pitch, "pitch"));
|
|
2097
|
+
const spelled2 = spelledPitchClass(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, rounded), note, scale, context);
|
|
2098
|
+
const octave = (rounded - _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, spelled2.letter) - spelled2.alter) / 12 - 1;
|
|
2062
2099
|
return { letter: spelled2.letter, alter: spelled2.alter, octave };
|
|
2063
2100
|
}
|
|
2064
2101
|
function noteNames(notes) {
|
|
2065
|
-
|
|
2066
|
-
return notes.map((note) =>
|
|
2102
|
+
_chunkS3QELJUEcjs.assertArray.call(void 0, notes, "notes");
|
|
2103
|
+
return notes.map((note) => _chunkS3QELJUEcjs.formatNote.call(void 0, _chunkS3QELJUEcjs.toNoteData.call(void 0, note)));
|
|
2067
2104
|
}
|
|
2068
2105
|
|
|
2069
2106
|
// src/theory/counterpoint/internal.ts
|
|
2070
2107
|
function assertQualityLabel(quality) {
|
|
2071
2108
|
if (typeof quality !== "string" || !/^(P|M|m|A+|d+)$/.test(quality)) {
|
|
2072
|
-
throw new (0,
|
|
2073
|
-
`interval.quality must be an interval quality; received ${
|
|
2109
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
2110
|
+
`interval.quality must be an interval quality; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, quality)}`
|
|
2074
2111
|
);
|
|
2075
2112
|
}
|
|
2076
2113
|
return quality;
|
|
2077
2114
|
}
|
|
2078
2115
|
function pitchOf(value) {
|
|
2079
|
-
return typeof value === "number" ? value :
|
|
2116
|
+
return typeof value === "number" ? value : _chunkS3QELJUEcjs.noteToMidi.call(void 0, value);
|
|
2080
2117
|
}
|
|
2081
2118
|
function simpleIntervalNumber(numberValue) {
|
|
2082
2119
|
return (Math.abs(numberValue) - 1) % 7 + 1;
|
|
2083
2120
|
}
|
|
2084
2121
|
function classifySpelledInterval(interval, twoVoice = true) {
|
|
2085
|
-
|
|
2086
|
-
const read =
|
|
2087
|
-
const simple = simpleIntervalNumber(
|
|
2122
|
+
_chunkS3QELJUEcjs.assertFlag.call(void 0, twoVoice, "twoVoice");
|
|
2123
|
+
const read = _chunkS3QELJUEcjs.assertRecord.call(void 0, interval, "interval");
|
|
2124
|
+
const simple = simpleIntervalNumber(_chunkS3QELJUEcjs.assertDegree.call(void 0, read.number, "interval.number"));
|
|
2088
2125
|
const quality = assertQualityLabel(read.quality);
|
|
2089
2126
|
if (quality === "P") {
|
|
2090
2127
|
if (simple === 1 || simple === 5) {
|
|
@@ -2131,16 +2168,16 @@ function motionBetween(from, to) {
|
|
|
2131
2168
|
if (leadMove > 0 !== counterMove > 0) {
|
|
2132
2169
|
return "contrary";
|
|
2133
2170
|
}
|
|
2134
|
-
const before = simpleIntervalNumber(
|
|
2135
|
-
const after = simpleIntervalNumber(
|
|
2171
|
+
const before = simpleIntervalNumber(_chunkS3QELJUEcjs.spelledInterval.call(void 0, from.counter, from.lead).number);
|
|
2172
|
+
const after = simpleIntervalNumber(_chunkS3QELJUEcjs.spelledInterval.call(void 0, to.counter, to.lead).number);
|
|
2136
2173
|
return before === after ? "parallel" : "similar";
|
|
2137
2174
|
}
|
|
2138
2175
|
function voiceIndependence(lead, counter, opts) {
|
|
2139
|
-
|
|
2140
|
-
const upper =
|
|
2141
|
-
const lower =
|
|
2176
|
+
_chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
|
|
2177
|
+
const upper = _chunkS3QELJUEcjs.assertArray.call(void 0, lead, "lead");
|
|
2178
|
+
const lower = _chunkS3QELJUEcjs.assertArray.call(void 0, counter, "counter");
|
|
2142
2179
|
if (upper.length !== lower.length) {
|
|
2143
|
-
throw new (0,
|
|
2180
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
2144
2181
|
`voiceIndependence needs the two lines aligned slot for slot; received ${upper.length} and ${lower.length}`
|
|
2145
2182
|
);
|
|
2146
2183
|
}
|
|
@@ -2149,7 +2186,7 @@ function voiceIndependence(lead, counter, opts) {
|
|
|
2149
2186
|
["counterAttacks", _optionalChain([opts, 'optionalAccess', _16 => _16.counterAttacks])]
|
|
2150
2187
|
]) {
|
|
2151
2188
|
if (flags !== void 0 && flags.length !== upper.length) {
|
|
2152
|
-
throw new (0,
|
|
2189
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
2153
2190
|
`voiceIndependence needs ${name} aligned slot for slot with the lines; received ${flags.length} and ${upper.length}`
|
|
2154
2191
|
);
|
|
2155
2192
|
}
|
|
@@ -2206,7 +2243,7 @@ function voiceIndependence(lead, counter, opts) {
|
|
|
2206
2243
|
totalGap += Math.abs(gap);
|
|
2207
2244
|
minGap = Math.min(minGap, Math.abs(gap));
|
|
2208
2245
|
orderSum += Math.sign(gap);
|
|
2209
|
-
const interval =
|
|
2246
|
+
const interval = _chunkS3QELJUEcjs.spelledInterval.call(void 0, slot.counter, slot.lead);
|
|
2210
2247
|
const perfect = classifySpelledInterval(interval) === 0 /* PerfectConsonance */ || (_nullishCoalesce(_optionalChain([opts, 'optionalAccess', _19 => _19.countFourths]), () => ( false))) && interval.quality === "P" && simpleIntervalNumber(interval.number) === 4;
|
|
2211
2248
|
perfectRun = perfect ? perfectRun + 1 : 0;
|
|
2212
2249
|
longestPerfectRun = Math.max(longestPerfectRun, perfectRun);
|
|
@@ -2247,13 +2284,13 @@ function createsVoiceCrossing(upper, lower) {
|
|
|
2247
2284
|
}
|
|
2248
2285
|
function createsVerticalDissonance(a, b, twoVoice) {
|
|
2249
2286
|
if (typeof a !== "number" && typeof b !== "number") {
|
|
2250
|
-
return classifySpelledInterval(
|
|
2287
|
+
return classifySpelledInterval(_chunkS3QELJUEcjs.spelledInterval.call(void 0, a, b), twoVoice) === 2 /* Dissonance */;
|
|
2251
2288
|
}
|
|
2252
|
-
return !
|
|
2289
|
+
return !_chunkS3QELJUEcjs.isConsonantInterval.call(void 0, pitchOf(a) - pitchOf(b), twoVoice);
|
|
2253
2290
|
}
|
|
2254
2291
|
function isForbiddenMelodicLeap(prev, cur) {
|
|
2255
2292
|
if (typeof prev !== "number" && typeof cur !== "number") {
|
|
2256
|
-
const interval =
|
|
2293
|
+
const interval = _chunkS3QELJUEcjs.spelledInterval.call(void 0, prev, cur);
|
|
2257
2294
|
if (Math.abs(interval.semitones) > 12 || interval.number > 8) {
|
|
2258
2295
|
return true;
|
|
2259
2296
|
}
|
|
@@ -2272,11 +2309,11 @@ function isAugmentedMelodicInterval(prev, cur) {
|
|
|
2272
2309
|
if (typeof prev === "number" || typeof cur === "number") {
|
|
2273
2310
|
return false;
|
|
2274
2311
|
}
|
|
2275
|
-
const interval =
|
|
2312
|
+
const interval = _chunkS3QELJUEcjs.spelledInterval.call(void 0, prev, cur);
|
|
2276
2313
|
return interval.number >= 2 && interval.quality.startsWith("A");
|
|
2277
2314
|
}
|
|
2278
2315
|
function simpleClass(semitones) {
|
|
2279
|
-
return
|
|
2316
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, Math.abs(semitones));
|
|
2280
2317
|
}
|
|
2281
2318
|
function isPerfectClass(cls) {
|
|
2282
2319
|
return cls === 0 || cls === 7;
|
|
@@ -2320,7 +2357,7 @@ function createsParallelUnison(aPrev, aCur, bPrev, bCur) {
|
|
|
2320
2357
|
return a1 === b1 && a0 === b0;
|
|
2321
2358
|
}
|
|
2322
2359
|
function createsHiddenParallelPerfect(aPrev, aCur, bPrev, bCur, strictness = "fourPart") {
|
|
2323
|
-
|
|
2360
|
+
_chunkS3QELJUEcjs.assertOneOf.call(void 0, strictness, HIDDEN_PARALLEL_READINGS, "strictness");
|
|
2324
2361
|
const a0 = pitchOf(aPrev);
|
|
2325
2362
|
const a1 = pitchOf(aCur);
|
|
2326
2363
|
const b0 = pitchOf(bPrev);
|
|
@@ -2370,15 +2407,15 @@ function createsVoiceOverlap(upperPrev, upperCur, lowerPrev, lowerCur) {
|
|
|
2370
2407
|
return u1 < l0 || l1 > u0;
|
|
2371
2408
|
}
|
|
2372
2409
|
function exceedsSpacing(upper, lower, maxSemitones = 12) {
|
|
2373
|
-
|
|
2410
|
+
_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, maxSemitones, "maxSemitones");
|
|
2374
2411
|
return Math.abs(pitchOf(upper) - pitchOf(lower)) > maxSemitones;
|
|
2375
2412
|
}
|
|
2376
2413
|
function isLeadingToneResolution(prev, cur, key) {
|
|
2377
2414
|
const prevPitch = pitchOf(prev);
|
|
2378
2415
|
const curPitch = pitchOf(cur);
|
|
2379
|
-
const tonic =
|
|
2416
|
+
const tonic = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, toKeyScale(key).rootPc);
|
|
2380
2417
|
const leading = (tonic + 11) % 12;
|
|
2381
|
-
if (
|
|
2418
|
+
if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, prevPitch) !== leading || _chunkS3QELJUEcjs.pitchClassOf.call(void 0, curPitch) !== tonic) {
|
|
2382
2419
|
return false;
|
|
2383
2420
|
}
|
|
2384
2421
|
return curPitch > prevPitch && curPitch - prevPitch <= 2;
|
|
@@ -2417,17 +2454,17 @@ var PROFILE_WEIGHTS = Object.freeze({
|
|
|
2417
2454
|
});
|
|
2418
2455
|
var SAFETY_PROFILES = Object.keys(PROFILE_WEIGHTS);
|
|
2419
2456
|
function profileWeights(profile, overrides) {
|
|
2420
|
-
const base = PROFILE_WEIGHTS[
|
|
2457
|
+
const base = PROFILE_WEIGHTS[_chunkS3QELJUEcjs.assertOneOf.call(void 0, profile, SAFETY_PROFILES, "safety profile")];
|
|
2421
2458
|
if (overrides === void 0) {
|
|
2422
2459
|
return { ...base };
|
|
2423
2460
|
}
|
|
2424
|
-
|
|
2461
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, overrides, "overrides");
|
|
2425
2462
|
const weights = { ...base };
|
|
2426
2463
|
for (const [field, value] of Object.entries(overrides)) {
|
|
2427
2464
|
if (value === void 0) {
|
|
2428
2465
|
continue;
|
|
2429
2466
|
}
|
|
2430
|
-
weights[field] =
|
|
2467
|
+
weights[field] = _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, value, `weight ${field}`);
|
|
2431
2468
|
}
|
|
2432
2469
|
return weights;
|
|
2433
2470
|
}
|
|
@@ -2494,7 +2531,7 @@ function avoidsMajorSeventh(chord) {
|
|
|
2494
2531
|
return chord.intervals.includes(4) && chord.intervals.includes(10);
|
|
2495
2532
|
}
|
|
2496
2533
|
function isStructuralChordDissonance(a, b, chord) {
|
|
2497
|
-
const rawClass =
|
|
2534
|
+
const rawClass = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, Math.abs(a - b));
|
|
2498
2535
|
const aOffset = intervalAboveRoot(a, chord);
|
|
2499
2536
|
const bOffset = intervalAboveRoot(b, chord);
|
|
2500
2537
|
const rootSeventh = aOffset === 0 && (bOffset === 10 || bOffset === 11) || bOffset === 0 && (aOffset === 10 || aOffset === 11);
|
|
@@ -2513,31 +2550,35 @@ function stepResolution(pitch, chord) {
|
|
|
2513
2550
|
}
|
|
2514
2551
|
function evaluateSafety(q, opts = {}) {
|
|
2515
2552
|
assertSafetyContext(q);
|
|
2516
|
-
|
|
2517
|
-
const options =
|
|
2553
|
+
_chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.candidatePitch, "candidatePitch");
|
|
2554
|
+
const options = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
|
|
2518
2555
|
return evaluateInternal(q, _nullishCoalesce(options.suggestions, () => ( true)), _nullishCoalesce(options.partners, () => ( false)));
|
|
2519
2556
|
}
|
|
2520
2557
|
function assertSafetyContext(q) {
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
if (q.prevPitch !== void 0)
|
|
2524
|
-
if (q.vocalLow !== void 0)
|
|
2525
|
-
if (q.vocalHigh !== void 0)
|
|
2558
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, q, "safety query");
|
|
2559
|
+
_chunkS3QELJUEcjs.assertOneOf.call(void 0, q.profile, SAFETY_PROFILES, "safety profile");
|
|
2560
|
+
if (q.prevPitch !== void 0) _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.prevPitch, "prevPitch");
|
|
2561
|
+
if (q.vocalLow !== void 0) _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.vocalLow, "vocalLow");
|
|
2562
|
+
if (q.vocalHigh !== void 0) _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.vocalHigh, "vocalHigh");
|
|
2526
2563
|
if (q.vocalLow !== void 0 && q.vocalHigh !== void 0 && q.vocalLow > q.vocalHigh) {
|
|
2527
|
-
throw new (0,
|
|
2564
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("vocalLow must not exceed vocalHigh");
|
|
2528
2565
|
}
|
|
2529
2566
|
if (!Array.isArray(q.otherVoices)) {
|
|
2530
|
-
throw new (0,
|
|
2567
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
2568
|
+
`otherVoices must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, q.otherVoices)}`
|
|
2569
|
+
);
|
|
2531
2570
|
}
|
|
2532
|
-
|
|
2571
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, q.otherVoices.length, "other voices");
|
|
2533
2572
|
for (let index = 0; index < q.otherVoices.length; index += 1) {
|
|
2534
|
-
const voice = q.otherVoices[index];
|
|
2535
|
-
|
|
2536
|
-
_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, voice.pitch, `otherVoices[${index}].pitch`);
|
|
2573
|
+
const voice = _chunkS3QELJUEcjs.assertRecord.call(void 0, q.otherVoices[index], `otherVoices[${index}]`);
|
|
2574
|
+
_chunkS3QELJUEcjs.assertMidiPitch.call(void 0, voice.pitch, `otherVoices[${index}].pitch`);
|
|
2537
2575
|
if (voice.prevPitch !== void 0) {
|
|
2538
|
-
|
|
2576
|
+
_chunkS3QELJUEcjs.assertMidiPitch.call(void 0, voice.prevPitch, `otherVoices[${index}].prevPitch`);
|
|
2539
2577
|
}
|
|
2540
2578
|
}
|
|
2579
|
+
if (q.chord !== null) {
|
|
2580
|
+
_chunkS3QELJUEcjs.assertRecord.call(void 0, q.chord, "chord");
|
|
2581
|
+
}
|
|
2541
2582
|
}
|
|
2542
2583
|
function evaluateInternal(q, collectSuggestions, collectPartners) {
|
|
2543
2584
|
let reasons = 0;
|
|
@@ -2633,7 +2674,7 @@ function evaluateInternal(q, collectSuggestions, collectPartners) {
|
|
|
2633
2674
|
if (chord && isStructuralChordDissonance(pitch, ov.pitch, chord)) {
|
|
2634
2675
|
continue;
|
|
2635
2676
|
}
|
|
2636
|
-
if (chord && q.profile === "pop" &&
|
|
2677
|
+
if (chord && q.profile === "pop" && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, Math.abs(pitch - ov.pitch)) === 5 && isChordMember(pitch, chord) && isChordMember(ov.pitch, chord)) {
|
|
2637
2678
|
continue;
|
|
2638
2679
|
}
|
|
2639
2680
|
flagPair(index, 1024 /* VerticalDissonance */);
|
|
@@ -2755,14 +2796,14 @@ function enumerateSafePitches(q, pitchLow, pitchHigh) {
|
|
|
2755
2796
|
assertSafetyContext(q);
|
|
2756
2797
|
const chordTones = [];
|
|
2757
2798
|
const others = [];
|
|
2758
|
-
|
|
2759
|
-
|
|
2799
|
+
_chunkS3QELJUEcjs.assertMidiPitch.call(void 0, pitchLow, "pitchLow");
|
|
2800
|
+
_chunkS3QELJUEcjs.assertMidiPitch.call(void 0, pitchHigh, "pitchHigh");
|
|
2760
2801
|
if (pitchLow > pitchHigh) {
|
|
2761
|
-
throw new (0,
|
|
2802
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
2762
2803
|
`pitchLow must not exceed pitchHigh; received ${pitchLow} > ${pitchHigh}`
|
|
2763
2804
|
);
|
|
2764
2805
|
}
|
|
2765
|
-
|
|
2806
|
+
_chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, pitchHigh - pitchLow + 1, "safe pitch candidates");
|
|
2766
2807
|
const low = Math.max(pitchLow, _nullishCoalesce(q.vocalLow, () => ( pitchLow)));
|
|
2767
2808
|
const high = Math.min(pitchHigh, _nullishCoalesce(q.vocalHigh, () => ( pitchHigh)));
|
|
2768
2809
|
for (let pitch = high; pitch >= low; pitch -= 1) {
|
|
@@ -2925,6 +2966,19 @@ var ADDED_DEGREES = {
|
|
|
2925
2966
|
};
|
|
2926
2967
|
var ALTERABLE = { "5": 5, "9": 9, "11": 11, "13": 13 };
|
|
2927
2968
|
var OMITTABLE = { "1": 1, "3": 3, "5": 5 };
|
|
2969
|
+
var SUSPENSION_TOKENS = [
|
|
2970
|
+
["sus2", "sus2"],
|
|
2971
|
+
["sus4", "sus4"],
|
|
2972
|
+
["sus", "sus4"]
|
|
2973
|
+
];
|
|
2974
|
+
var OMISSION_TOKENS = [
|
|
2975
|
+
["omit", 4],
|
|
2976
|
+
["no", 2]
|
|
2977
|
+
];
|
|
2978
|
+
var ACCIDENTAL_TOKENS = [
|
|
2979
|
+
["b", -1],
|
|
2980
|
+
["#", 1]
|
|
2981
|
+
];
|
|
2928
2982
|
function alterationKey(degree, alter) {
|
|
2929
2983
|
return `${degree}:${alter}`;
|
|
2930
2984
|
}
|
|
@@ -2984,11 +3038,7 @@ function stackTo(draft, top) {
|
|
|
2984
3038
|
}
|
|
2985
3039
|
}
|
|
2986
3040
|
function applyFigure(draft, text, at) {
|
|
2987
|
-
const base = matchToken(text, at,
|
|
2988
|
-
["sus2", "sus2"],
|
|
2989
|
-
["sus4", "sus4"],
|
|
2990
|
-
["sus", "sus4"]
|
|
2991
|
-
]);
|
|
3041
|
+
const base = matchToken(text, at, SUSPENSION_TOKENS);
|
|
2992
3042
|
if (base !== void 0) {
|
|
2993
3043
|
draft.base = base.value;
|
|
2994
3044
|
return base.next;
|
|
@@ -3007,10 +3057,7 @@ function applyFigure(draft, text, at) {
|
|
|
3007
3057
|
draft.additions.add(degree2.value);
|
|
3008
3058
|
return degree2.next;
|
|
3009
3059
|
}
|
|
3010
|
-
const omitted = matchToken(text, at,
|
|
3011
|
-
["omit", 4],
|
|
3012
|
-
["no", 2]
|
|
3013
|
-
]);
|
|
3060
|
+
const omitted = matchToken(text, at, OMISSION_TOKENS);
|
|
3014
3061
|
if (omitted !== void 0) {
|
|
3015
3062
|
const degree2 = matchNumberToken(text, omitted.next, OMITTABLE);
|
|
3016
3063
|
if (degree2 === void 0) {
|
|
@@ -3019,10 +3066,7 @@ function applyFigure(draft, text, at) {
|
|
|
3019
3066
|
draft.omissions.add(degree2.value);
|
|
3020
3067
|
return degree2.next;
|
|
3021
3068
|
}
|
|
3022
|
-
const accidental = matchToken(text, at,
|
|
3023
|
-
["b", -1],
|
|
3024
|
-
["#", 1]
|
|
3025
|
-
]);
|
|
3069
|
+
const accidental = matchToken(text, at, ACCIDENTAL_TOKENS);
|
|
3026
3070
|
const from = _nullishCoalesce(_optionalChain([accidental, 'optionalAccess', _20 => _20.next]), () => ( at));
|
|
3027
3071
|
const degree = matchNumberToken(text, from, ALTERABLE);
|
|
3028
3072
|
if (degree === void 0) {
|
|
@@ -3171,10 +3215,10 @@ function suffixSpec(suffix) {
|
|
|
3171
3215
|
return quality === void 0 ? structuralSpec(suffix) : chordSpecForQuality(quality, 0);
|
|
3172
3216
|
}
|
|
3173
3217
|
function assertNamingSystem(system) {
|
|
3174
|
-
|
|
3218
|
+
_chunkS3QELJUEcjs.formatNote.call(void 0, SYSTEM_PROBE, { system });
|
|
3175
3219
|
}
|
|
3176
3220
|
function bareNote(text, system) {
|
|
3177
|
-
const read =
|
|
3221
|
+
const read = _chunkS3QELJUEcjs.tryParseNote.call(void 0, text, { system });
|
|
3178
3222
|
if (!read.ok) {
|
|
3179
3223
|
return void 0;
|
|
3180
3224
|
}
|
|
@@ -3184,11 +3228,11 @@ function rootSplits(text, system) {
|
|
|
3184
3228
|
if (system === "english") {
|
|
3185
3229
|
const match = text.match(ROOT_RE);
|
|
3186
3230
|
const token = _optionalChain([match, 'optionalAccess', _22 => _22[0]]);
|
|
3187
|
-
return token === void 0 ? [] : [{ root:
|
|
3231
|
+
return token === void 0 ? [] : [{ root: _chunkS3QELJUEcjs.parseNote.call(void 0, token, { system }), rest: text.slice(token.length) }];
|
|
3188
3232
|
}
|
|
3189
3233
|
assertNamingSystem(system);
|
|
3190
3234
|
const splits = [];
|
|
3191
|
-
const longest = Math.min(text.length,
|
|
3235
|
+
const longest = Math.min(text.length, _chunkS3QELJUEcjs.maxNoteNameLength.call(void 0, system));
|
|
3192
3236
|
for (let end = longest; end > 0; end -= 1) {
|
|
3193
3237
|
const root = bareNote(text.slice(0, end), system);
|
|
3194
3238
|
if (root !== void 0) {
|
|
@@ -3199,14 +3243,14 @@ function rootSplits(text, system) {
|
|
|
3199
3243
|
}
|
|
3200
3244
|
function bassNote(text, system) {
|
|
3201
3245
|
if (system === "english") {
|
|
3202
|
-
return BASS_RE.test(text) ?
|
|
3246
|
+
return BASS_RE.test(text) ? _chunkS3QELJUEcjs.parseNote.call(void 0, text, { system }) : void 0;
|
|
3203
3247
|
}
|
|
3204
3248
|
return bareNote(text, system);
|
|
3205
3249
|
}
|
|
3206
|
-
function
|
|
3207
|
-
const rooted = { ...spec, rootPc:
|
|
3250
|
+
function chordFromSymbolParts(root, spec, bass) {
|
|
3251
|
+
const rooted = { ...spec, rootPc: _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, root) };
|
|
3208
3252
|
if (bass !== void 0) {
|
|
3209
|
-
rooted.bassPc =
|
|
3253
|
+
rooted.bassPc = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, bass);
|
|
3210
3254
|
}
|
|
3211
3255
|
const chord = chordFromSpec(rooted);
|
|
3212
3256
|
chord.rootSpelling = { letter: root.letter, alter: root.alter };
|
|
@@ -3221,11 +3265,11 @@ function chordAfterRoot(root, rest, system) {
|
|
|
3221
3265
|
const slashSpec = suffixSpec(rest.slice(0, slashIndex));
|
|
3222
3266
|
const bass = slashSpec === void 0 ? void 0 : bassNote(rest.slice(slashIndex + 1), system);
|
|
3223
3267
|
if (slashSpec !== void 0 && bass !== void 0) {
|
|
3224
|
-
return
|
|
3268
|
+
return chordFromSymbolParts(root, slashSpec, bass);
|
|
3225
3269
|
}
|
|
3226
3270
|
}
|
|
3227
3271
|
const spec = suffixSpec(rest);
|
|
3228
|
-
return spec === void 0 ? void 0 :
|
|
3272
|
+
return spec === void 0 ? void 0 : chordFromSymbolParts(root, spec);
|
|
3229
3273
|
}
|
|
3230
3274
|
|
|
3231
3275
|
// src/theory/symbol/suffix.ts
|
|
@@ -3302,7 +3346,11 @@ var BASE_SUFFIX = {
|
|
|
3302
3346
|
sus4: "sus4",
|
|
3303
3347
|
power: "5"
|
|
3304
3348
|
};
|
|
3305
|
-
var SEVENTH_SUFFIX = {
|
|
3349
|
+
var SEVENTH_SUFFIX = {
|
|
3350
|
+
maj7: "maj7",
|
|
3351
|
+
min7: "7",
|
|
3352
|
+
dim7: "dim7"
|
|
3353
|
+
};
|
|
3306
3354
|
var MAJOR_SEVENTH_AFTER_BASE = "Maj7";
|
|
3307
3355
|
function builtCoreSuffix(spec) {
|
|
3308
3356
|
const base = BASE_SUFFIX[spec.base];
|
|
@@ -3351,21 +3399,21 @@ function bareSpelling(note) {
|
|
|
3351
3399
|
return { letter: note.letter, alter: note.alter };
|
|
3352
3400
|
}
|
|
3353
3401
|
function plainSpelling(pc, asFlat) {
|
|
3354
|
-
return bareSpelling(
|
|
3402
|
+
return bareSpelling(_chunkS3QELJUEcjs.midiToNote.call(void 0, 60 + pc, asFlat ? "flat" : "sharp"));
|
|
3355
3403
|
}
|
|
3356
3404
|
function symbolName(note, system) {
|
|
3357
|
-
const name =
|
|
3405
|
+
const name = _chunkS3QELJUEcjs.formatNote.call(void 0, note, { system });
|
|
3358
3406
|
return system === "german" ? `${name.slice(0, 1).toUpperCase()}${name.slice(1)}` : name;
|
|
3359
3407
|
}
|
|
3360
3408
|
function isWrittenSpelling(spelling) {
|
|
3361
|
-
const written =
|
|
3362
|
-
60 +
|
|
3409
|
+
const written = _chunkS3QELJUEcjs.midiToNote.call(void 0,
|
|
3410
|
+
60 + _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, spelling),
|
|
3363
3411
|
spelling.alter < 0 ? "flat" : "sharp"
|
|
3364
3412
|
);
|
|
3365
3413
|
return written.letter === spelling.letter && written.alter === spelling.alter;
|
|
3366
3414
|
}
|
|
3367
3415
|
function pitchClassName(pc, hint, system, flats, inheritFlats) {
|
|
3368
|
-
if (flats === void 0 && hint !== void 0 &&
|
|
3416
|
+
if (flats === void 0 && hint !== void 0 && _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, hint) === pc) {
|
|
3369
3417
|
return symbolName(hint, system);
|
|
3370
3418
|
}
|
|
3371
3419
|
return symbolName(plainSpelling(pc, _nullishCoalesce(_nullishCoalesce(flats, () => ( inheritFlats)), () => ( false))), system);
|
|
@@ -3374,19 +3422,19 @@ function onAccidentalSide(spelling, flats) {
|
|
|
3374
3422
|
return flats === void 0 || spelling.alter === 0 || spelling.alter < 0 === flats;
|
|
3375
3423
|
}
|
|
3376
3424
|
function bySameStep(spelling, from, to) {
|
|
3377
|
-
return bareSpelling(
|
|
3425
|
+
return bareSpelling(_chunkS3QELJUEcjs.transposeByInterval.call(void 0, spelling, _chunkS3QELJUEcjs.spelledInterval.call(void 0, from, to)));
|
|
3378
3426
|
}
|
|
3379
3427
|
function spellingAbove(root, letters, pc) {
|
|
3380
3428
|
const letter = ((root.letter + letters) % 7 + 7) % 7;
|
|
3381
|
-
const natural =
|
|
3429
|
+
const natural = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, { letter, alter: 0 });
|
|
3382
3430
|
return { letter, alter: ((pc - natural) % 12 + 18) % 12 - 6 };
|
|
3383
3431
|
}
|
|
3384
3432
|
function carriedBass(spelling, from, to, asFlat, isOwnSpelling) {
|
|
3385
3433
|
const carried = bySameStep(spelling, from, to);
|
|
3386
|
-
return isOwnSpelling(carried) || isWrittenSpelling(carried) ? carried : plainSpelling(
|
|
3434
|
+
return isOwnSpelling(carried) || isWrittenSpelling(carried) ? carried : plainSpelling(_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, carried), asFlat);
|
|
3387
3435
|
}
|
|
3388
3436
|
function hintFor(hint, pc) {
|
|
3389
|
-
return hint !== void 0 &&
|
|
3437
|
+
return hint !== void 0 && _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, hint) === pc ? hint : void 0;
|
|
3390
3438
|
}
|
|
3391
3439
|
function rootSpellingFor(pc, hint, flats) {
|
|
3392
3440
|
return hint !== void 0 && onAccidentalSide(hint, flats) ? hint : plainSpelling(pc, _nullishCoalesce(flats, () => ( false)));
|
|
@@ -3394,19 +3442,19 @@ function rootSpellingFor(pc, hint, flats) {
|
|
|
3394
3442
|
|
|
3395
3443
|
// src/theory/symbol/index.ts
|
|
3396
3444
|
function parseChordSymbol(text, opts) {
|
|
3397
|
-
return
|
|
3445
|
+
return _chunkS3QELJUEcjs.unwrapParse.call(void 0, tryParseChordSymbol(text, opts));
|
|
3398
3446
|
}
|
|
3399
3447
|
function tryParseChordSymbol(text, opts) {
|
|
3400
|
-
const asked =
|
|
3448
|
+
const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
|
|
3401
3449
|
try {
|
|
3402
3450
|
if (typeof text !== "string") {
|
|
3403
|
-
throw new (0,
|
|
3451
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`chord symbol must be a string; received ${typeof text}`);
|
|
3404
3452
|
}
|
|
3405
3453
|
const system = _nullishCoalesce(asked.system, () => ( DEFAULT_SYSTEM));
|
|
3406
3454
|
const trimmed = text.trim().replaceAll("\u266F", "#").replaceAll("\u266D", "b").replaceAll("\u{1D12A}", "x").replaceAll("\u{1D12B}", "bb").replaceAll("\u2206", "\u0394");
|
|
3407
3455
|
const splits = rootSplits(trimmed, system);
|
|
3408
3456
|
if (splits.length === 0) {
|
|
3409
|
-
throw new (0,
|
|
3457
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Invalid chord symbol: ${_chunkS3QELJUEcjs.describeRejected.call(void 0, text)}`);
|
|
3410
3458
|
}
|
|
3411
3459
|
for (const { root, rest } of splits) {
|
|
3412
3460
|
const chord = chordAfterRoot(root, rest, system);
|
|
@@ -3414,34 +3462,34 @@ function tryParseChordSymbol(text, opts) {
|
|
|
3414
3462
|
return { ok: true, value: chord };
|
|
3415
3463
|
}
|
|
3416
3464
|
}
|
|
3417
|
-
throw new (0,
|
|
3465
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unrecognized chord quality: ${_chunkS3QELJUEcjs.describeRejected.call(void 0, text)}`);
|
|
3418
3466
|
} catch (error) {
|
|
3419
|
-
return
|
|
3467
|
+
return _chunkS3QELJUEcjs.parseFailure.call(void 0, error);
|
|
3420
3468
|
}
|
|
3421
3469
|
}
|
|
3422
3470
|
function formatChordSymbol(chord, opts) {
|
|
3423
3471
|
const data = toChordData(chord);
|
|
3424
|
-
if (!Object.hasOwn(CANONICAL_SUFFIX, data.quality)) {
|
|
3425
|
-
throw new (0,
|
|
3472
|
+
if (typeof data.quality !== "string" || !Object.hasOwn(CANONICAL_SUFFIX, data.quality)) {
|
|
3473
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown chord quality: ${String(data.quality)}`);
|
|
3426
3474
|
}
|
|
3427
|
-
const asked =
|
|
3475
|
+
const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
|
|
3428
3476
|
const system = _nullishCoalesce(asked.system, () => ( DEFAULT_SYSTEM));
|
|
3429
|
-
const flats = asked.flats;
|
|
3430
|
-
const rootPc =
|
|
3477
|
+
const flats = symbolFlats(asked.flats);
|
|
3478
|
+
const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, data.rootPc);
|
|
3431
3479
|
const rootHint = hintFor(data.rootSpelling, rootPc);
|
|
3432
3480
|
const rootSpelling = rootSpellingFor(rootPc, rootHint, flats);
|
|
3433
3481
|
const suffix = specSuffix(chordSpecOf(data));
|
|
3434
3482
|
let symbol = `${symbolName(rootSpelling, system)}${suffix}`;
|
|
3435
|
-
if (data.bassPc !== void 0 &&
|
|
3436
|
-
const bassPc =
|
|
3483
|
+
if (data.bassPc !== void 0 && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, data.bassPc) !== rootPc) {
|
|
3484
|
+
const bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, data.bassPc);
|
|
3437
3485
|
const bassHint = hintFor(data.bassSpelling, bassPc);
|
|
3438
3486
|
const tonePcs = new Set(chordPitchClasses(data, { includeBass: false }));
|
|
3439
3487
|
const ownSpelling = tonePcs.has(bassPc) ? spellingAbove(
|
|
3440
3488
|
rootSpelling,
|
|
3441
|
-
(_nullishCoalesce(degreeOfInterval(
|
|
3489
|
+
(_nullishCoalesce(degreeOfInterval(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, bassPc - rootPc), data), () => ( 1))) - 1,
|
|
3442
3490
|
bassPc
|
|
3443
3491
|
) : void 0;
|
|
3444
|
-
const bassName = rootHint !== void 0 && bassHint !== void 0 ? symbolName(
|
|
3492
|
+
const bassName = flats !== void 0 && rootHint !== void 0 && bassHint !== void 0 ? symbolName(
|
|
3445
3493
|
carriedBass(
|
|
3446
3494
|
bassHint,
|
|
3447
3495
|
rootHint,
|
|
@@ -3455,16 +3503,19 @@ function formatChordSymbol(chord, opts) {
|
|
|
3455
3503
|
}
|
|
3456
3504
|
return symbol;
|
|
3457
3505
|
}
|
|
3506
|
+
function symbolFlats(flats) {
|
|
3507
|
+
return flats === void 0 ? void 0 : _chunkS3QELJUEcjs.assertFlag.call(void 0, flats, "flats");
|
|
3508
|
+
}
|
|
3458
3509
|
function transposeChordSpellings(spellings, semitones, flats) {
|
|
3459
|
-
const byLetter = (spelling) => spelling === void 0 ? void 0 : bareSpelling(
|
|
3510
|
+
const byLetter = (spelling) => spelling === void 0 ? void 0 : bareSpelling(_chunkS3QELJUEcjs.transposeNote.call(void 0, spelling, semitones));
|
|
3460
3511
|
const movedRoot = byLetter(spellings.rootSpelling);
|
|
3461
3512
|
const movedBass = byLetter(spellings.bassSpelling);
|
|
3462
3513
|
const side = [movedRoot, spellings.rootSpelling, movedBass, spellings.bassSpelling].find(
|
|
3463
3514
|
(spelling) => spelling !== void 0 && spelling.alter !== 0
|
|
3464
3515
|
);
|
|
3465
3516
|
const preferFlats = _nullishCoalesce(flats, () => ( (side !== void 0 && side.alter < 0)));
|
|
3466
|
-
const octaveOnly =
|
|
3467
|
-
const plainName = (spelling, asFlat) => plainSpelling(
|
|
3517
|
+
const octaveOnly = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, semitones) === 0;
|
|
3518
|
+
const plainName = (spelling, asFlat) => plainSpelling(_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, spelling), asFlat);
|
|
3468
3519
|
const writable = (spelling) => octaveOnly || isWrittenSpelling(spelling) ? spelling : plainName(spelling, preferFlats);
|
|
3469
3520
|
const root = spellings.rootSpelling;
|
|
3470
3521
|
const bass = spellings.bassSpelling;
|
|
@@ -3486,9 +3537,9 @@ function transposeChordSpellings(spellings, semitones, flats) {
|
|
|
3486
3537
|
];
|
|
3487
3538
|
moved.rootSpelling = _nullishCoalesce(candidates.find(carriesBass), () => ( plainName(movedRoot, preferFlats)));
|
|
3488
3539
|
}
|
|
3489
|
-
const step = root !== void 0 && moved.rootSpelling !== void 0 ?
|
|
3540
|
+
const step = root !== void 0 && moved.rootSpelling !== void 0 ? _chunkS3QELJUEcjs.spelledInterval.call(void 0, root, moved.rootSpelling) : void 0;
|
|
3490
3541
|
const byStep = (spelling) => bareSpelling(
|
|
3491
|
-
step === void 0 ?
|
|
3542
|
+
step === void 0 ? _chunkS3QELJUEcjs.transposeNote.call(void 0, spelling, semitones) : _chunkS3QELJUEcjs.transposeByInterval.call(void 0, spelling, step)
|
|
3492
3543
|
);
|
|
3493
3544
|
if (bass !== void 0) {
|
|
3494
3545
|
moved.bassSpelling = writable(byStep(bass));
|
|
@@ -3499,13 +3550,13 @@ function transposeChordSpellings(spellings, semitones, flats) {
|
|
|
3499
3550
|
return moved;
|
|
3500
3551
|
}
|
|
3501
3552
|
function transposeChordSymbol(text, semitones, opts) {
|
|
3502
|
-
|
|
3553
|
+
_chunkS3QELJUEcjs.assertFiniteSemitones.call(void 0, semitones);
|
|
3503
3554
|
const chord = parseChordSymbol(text, opts);
|
|
3504
|
-
const transposed = { ...chord, rootPc:
|
|
3555
|
+
const transposed = { ...chord, rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + semitones) };
|
|
3505
3556
|
if (chord.bassPc !== void 0) {
|
|
3506
|
-
transposed.bassPc =
|
|
3557
|
+
transposed.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc + semitones);
|
|
3507
3558
|
}
|
|
3508
|
-
const spellings = transposeChordSpellings(chord, semitones, _optionalChain([opts, 'optionalAccess', _26 => _26.flats]));
|
|
3559
|
+
const spellings = transposeChordSpellings(chord, semitones, symbolFlats(_optionalChain([opts, 'optionalAccess', _26 => _26.flats])));
|
|
3509
3560
|
if (spellings.rootSpelling !== void 0) {
|
|
3510
3561
|
transposed.rootSpelling = spellings.rootSpelling;
|
|
3511
3562
|
}
|
|
@@ -3521,20 +3572,20 @@ function transposeChordSymbol(text, semitones, opts) {
|
|
|
3521
3572
|
// src/theory/symbol/coerce.ts
|
|
3522
3573
|
function normalizedChord(data) {
|
|
3523
3574
|
if (!Array.isArray(data.intervals)) {
|
|
3524
|
-
throw new (0,
|
|
3575
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("chord.intervals must be an array of semitone offsets");
|
|
3525
3576
|
}
|
|
3526
3577
|
const copy = {
|
|
3527
|
-
rootPc:
|
|
3578
|
+
rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, data.rootPc, "chord.rootPc")),
|
|
3528
3579
|
quality: data.quality,
|
|
3529
3580
|
// Each offset is checked rather than copied blind: a chord holding a NaN
|
|
3530
3581
|
// interval voices, spells and formats as a chord that looks real, and the
|
|
3531
3582
|
// failure surfaces wherever the number is finally used.
|
|
3532
3583
|
intervals: data.intervals.map(
|
|
3533
|
-
(interval, index) =>
|
|
3584
|
+
(interval, index) => _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, interval, `chord.intervals[${index}]`)
|
|
3534
3585
|
)
|
|
3535
3586
|
};
|
|
3536
3587
|
if (data.bassPc !== void 0) {
|
|
3537
|
-
copy.bassPc =
|
|
3588
|
+
copy.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, data.bassPc, "chord.bassPc"));
|
|
3538
3589
|
}
|
|
3539
3590
|
if (data.rootSpelling !== void 0) {
|
|
3540
3591
|
copy.rootSpelling = data.rootSpelling;
|
|
@@ -3552,21 +3603,24 @@ function toChordData(value) {
|
|
|
3552
3603
|
return parseChordSymbol(value);
|
|
3553
3604
|
}
|
|
3554
3605
|
if (typeof value === "object" && value !== null) {
|
|
3555
|
-
const data = "toJSON" in value && typeof value.toJSON === "function" ? value.toJSON() : value;
|
|
3606
|
+
const data = "toJSON" in value && typeof value.toJSON === "function" ? "data" in value && typeof value.data === "object" && value.data !== null ? value.data : value.toJSON() : value;
|
|
3556
3607
|
return normalizedChord(data);
|
|
3557
3608
|
}
|
|
3558
|
-
throw new (0,
|
|
3559
|
-
`chord must be a chord symbol or chord data; received ${
|
|
3609
|
+
throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
|
|
3610
|
+
`chord must be a chord symbol or chord data; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`
|
|
3560
3611
|
);
|
|
3561
3612
|
}
|
|
3562
3613
|
|
|
3563
3614
|
// src/theory/tendency/index.ts
|
|
3564
3615
|
function hasInterval(chord, semitones) {
|
|
3565
|
-
return chord.intervals.some((interval) =>
|
|
3616
|
+
return chord.intervals.some((interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, interval) === semitones);
|
|
3566
3617
|
}
|
|
3567
3618
|
function isDiatonicChord(chord, key) {
|
|
3568
3619
|
return chordPitchClasses(chord).every((pc) => isScaleTone(pc, key));
|
|
3569
3620
|
}
|
|
3621
|
+
function isNativeDominantSeventh(rootPc, key) {
|
|
3622
|
+
return isDiatonicChord(makeChord(rootPc, "dom7"), key);
|
|
3623
|
+
}
|
|
3570
3624
|
function hasMajorThird(chord) {
|
|
3571
3625
|
return hasInterval(chord, 4);
|
|
3572
3626
|
}
|
|
@@ -3580,7 +3634,7 @@ function hasDominantSonority(chord) {
|
|
|
3580
3634
|
return soundsMajorTriad(chord) || soundsDominantSeventh(chord);
|
|
3581
3635
|
}
|
|
3582
3636
|
function isDominantChordOf(chord, key) {
|
|
3583
|
-
if (
|
|
3637
|
+
if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) !== 7) {
|
|
3584
3638
|
return false;
|
|
3585
3639
|
}
|
|
3586
3640
|
if (hasMajorThird(chord)) {
|
|
@@ -3590,17 +3644,17 @@ function isDominantChordOf(chord, key) {
|
|
|
3590
3644
|
return suspended && hasInterval(chord, 10);
|
|
3591
3645
|
}
|
|
3592
3646
|
function isNeapolitanChordOf(chord, key) {
|
|
3593
|
-
return
|
|
3647
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 1 && soundsMajorTriad(chord) && !isDiatonicChord(chord, key);
|
|
3594
3648
|
}
|
|
3595
3649
|
var DOMINANT_DEGREE = 5;
|
|
3596
3650
|
function heptatonicFrameOf(key) {
|
|
3597
|
-
return scaleTonesInDegreeOrder(key).length === 7 ? key : majorKey(
|
|
3651
|
+
return scaleTonesInDegreeOrder(key).length === 7 ? key : majorKey(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc));
|
|
3598
3652
|
}
|
|
3599
3653
|
function degreeTriad(tones, index) {
|
|
3600
3654
|
const root = _nullishCoalesce(tones[index], () => ( 0));
|
|
3601
3655
|
return {
|
|
3602
|
-
third:
|
|
3603
|
-
fifth:
|
|
3656
|
+
third: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 2) % tones.length], () => ( 0))) - root),
|
|
3657
|
+
fifth: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 4) % tones.length], () => ( 0))) - root)
|
|
3604
3658
|
};
|
|
3605
3659
|
}
|
|
3606
3660
|
function tonicizableDegrees(key) {
|
|
@@ -3622,25 +3676,38 @@ function tonicizableDegrees(key) {
|
|
|
3622
3676
|
return out;
|
|
3623
3677
|
}
|
|
3624
3678
|
function appliedDominantTarget(rootPc, key) {
|
|
3625
|
-
const target =
|
|
3679
|
+
const target = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc);
|
|
3626
3680
|
return _nullishCoalesce(tonicizableDegrees(key).find(
|
|
3627
3681
|
(degree) => degree.degreeNumber !== 1 && degree.rootPc === target
|
|
3628
3682
|
), () => ( null));
|
|
3629
3683
|
}
|
|
3684
|
+
function cadencesThroughRaisedSeventh(key) {
|
|
3685
|
+
return isMinorMask(key.modeMask12) && scaleSystemOf(key) === "common-practice";
|
|
3686
|
+
}
|
|
3630
3687
|
function leadingTonePcOf(key) {
|
|
3631
|
-
return
|
|
3688
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc - 1);
|
|
3689
|
+
}
|
|
3690
|
+
var LEADING_TONE_QUALITY_NAMES = ["dim", "dim7", "m7b5"];
|
|
3691
|
+
var LEADING_TONE_QUALITIES = new Set(
|
|
3692
|
+
LEADING_TONE_QUALITY_NAMES
|
|
3693
|
+
);
|
|
3694
|
+
function appliedChordTarget(chord, key) {
|
|
3695
|
+
const dominant = hasDominantSonority(chord);
|
|
3696
|
+
if (!dominant && !LEADING_TONE_QUALITIES.has(chord.quality)) {
|
|
3697
|
+
return null;
|
|
3698
|
+
}
|
|
3699
|
+
return appliedDominantTarget(chord.rootPc + (dominant ? 5 : 1), key);
|
|
3632
3700
|
}
|
|
3633
|
-
var LEADING_TONE_QUALITIES = /* @__PURE__ */ new Set(["dim", "dim7", "m7b5"]);
|
|
3634
3701
|
function soundsDiminishedTriad(chord) {
|
|
3635
3702
|
return hasInterval(chord, 3) && hasInterval(chord, 6) && !hasInterval(chord, 7);
|
|
3636
3703
|
}
|
|
3637
3704
|
function isLeadingToneChordOf(chord, key) {
|
|
3638
|
-
return
|
|
3705
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc) === leadingTonePcOf(key) && soundsDiminishedTriad(chord);
|
|
3639
3706
|
}
|
|
3640
3707
|
function isFunctioningLeadingTone(chord, key) {
|
|
3641
3708
|
const role = chordToneRole(leadingTonePcOf(key), chord);
|
|
3642
3709
|
if (role === "third") {
|
|
3643
|
-
return
|
|
3710
|
+
return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc + 7);
|
|
3644
3711
|
}
|
|
3645
3712
|
if (role === "root") {
|
|
3646
3713
|
return soundsDiminishedTriad(chord);
|
|
@@ -3649,7 +3716,7 @@ function isFunctioningLeadingTone(chord, key) {
|
|
|
3649
3716
|
}
|
|
3650
3717
|
function seventhPcOf(chord) {
|
|
3651
3718
|
for (const interval of chord.intervals) {
|
|
3652
|
-
const pc =
|
|
3719
|
+
const pc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
3653
3720
|
if (chordToneRole(pc, chord) === "seventh") {
|
|
3654
3721
|
return pc;
|
|
3655
3722
|
}
|
|
@@ -3658,7 +3725,7 @@ function seventhPcOf(chord) {
|
|
|
3658
3725
|
}
|
|
3659
3726
|
function fifthPcOf(chord) {
|
|
3660
3727
|
for (const interval of chord.intervals) {
|
|
3661
|
-
const pc =
|
|
3728
|
+
const pc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
|
|
3662
3729
|
if (chordToneRole(pc, chord) === "fifth") {
|
|
3663
3730
|
return pc;
|
|
3664
3731
|
}
|
|
@@ -3674,7 +3741,7 @@ function isFrustratedLeadingTone(fromPitch, toPitch, nextChord) {
|
|
|
3674
3741
|
return false;
|
|
3675
3742
|
}
|
|
3676
3743
|
const fifthPc = fifthPcOf(nextChord);
|
|
3677
|
-
return fifthPc !== void 0 &&
|
|
3744
|
+
return fifthPc !== void 0 && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, toPitch) === fifthPc;
|
|
3678
3745
|
}
|
|
3679
3746
|
|
|
3680
3747
|
|
|
@@ -3822,5 +3889,11 @@ function isFrustratedLeadingTone(fromPitch, toPitch, nextChord) {
|
|
|
3822
3889
|
|
|
3823
3890
|
|
|
3824
3891
|
|
|
3825
|
-
|
|
3826
|
-
|
|
3892
|
+
|
|
3893
|
+
|
|
3894
|
+
|
|
3895
|
+
|
|
3896
|
+
|
|
3897
|
+
|
|
3898
|
+
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.QUALITY_INTERVALS = QUALITY_INTERVALS; exports.chordSpecForQuality = chordSpecForQuality; exports.chordSpecQuality = chordSpecQuality; exports.chordQualities = chordQualities; exports.assertChordQuality = assertChordQuality; exports.assertChord = assertChord; exports.chordFromDegree = chordFromDegree; exports.makeChord = makeChord; exports.makeSpelledChord = makeSpelledChord; exports.keySpelling = keySpelling; 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.spellingAbove = spellingAbove; exports.parseChordSymbol = parseChordSymbol; exports.tryParseChordSymbol = tryParseChordSymbol; exports.formatChordSymbol = formatChordSymbol; exports.transposeChordSpellings = transposeChordSpellings; exports.transposeChordSymbol = transposeChordSymbol; exports.isDiatonicChord = isDiatonicChord; exports.isNativeDominantSeventh = isNativeDominantSeventh; exports.hasMajorThird = hasMajorThird; exports.soundsDominantSeventh = soundsDominantSeventh; exports.isDominantChordOf = isDominantChordOf; exports.isNeapolitanChordOf = isNeapolitanChordOf; exports.heptatonicFrameOf = heptatonicFrameOf; exports.tonicizableDegrees = tonicizableDegrees; exports.cadencesThroughRaisedSeventh = cadencesThroughRaisedSeventh; exports.leadingTonePcOf = leadingTonePcOf; exports.LEADING_TONE_QUALITIES = LEADING_TONE_QUALITIES; exports.appliedChordTarget = appliedChordTarget; exports.isLeadingToneChordOf = isLeadingToneChordOf; exports.isFunctioningLeadingTone = isFunctioningLeadingTone; exports.seventhPcOf = seventhPcOf; exports.fifthPcOf = fifthPcOf; exports.isDescendingStep = isDescendingStep; exports.isFrustratedLeadingTone = isFrustratedLeadingTone;
|
|
3899
|
+
//# sourceMappingURL=chunk-YDGMWH43.cjs.map
|