@libraz/libcantus 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -65
- package/README_ja.md +28 -66
- package/dist/analyze/index.cjs +11 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +79 -144
- package/dist/analyze/index.d.ts +79 -144
- package/dist/analyze/index.js +20 -16
- package/dist/chunk-35NBV2FT.cjs +145 -0
- package/dist/chunk-35NBV2FT.cjs.map +1 -0
- package/dist/{chunk-UADYAYAT.cjs → chunk-3R3QVKY5.cjs} +1353 -580
- package/dist/chunk-3R3QVKY5.cjs.map +1 -0
- package/dist/{chunk-WWURE4XT.cjs → chunk-76ZBTRG2.cjs} +624 -729
- package/dist/chunk-76ZBTRG2.cjs.map +1 -0
- package/dist/{chunk-FVSI36UV.js → chunk-7KG3RTYS.js} +197 -110
- package/dist/chunk-7KG3RTYS.js.map +1 -0
- package/dist/{chunk-VTI6FOLB.js → chunk-AGOVW7U6.js} +709 -133
- package/dist/chunk-AGOVW7U6.js.map +1 -0
- package/dist/{chunk-E3F4AHAH.cjs → chunk-CGBADIO5.cjs} +221 -134
- package/dist/chunk-CGBADIO5.cjs.map +1 -0
- package/dist/{chunk-6XH6QZYQ.cjs → chunk-DSMJRXCZ.cjs} +1455 -849
- package/dist/chunk-DSMJRXCZ.cjs.map +1 -0
- package/dist/{chunk-PKFNUHDY.js → chunk-FBH75DAY.js} +1218 -612
- package/dist/chunk-FBH75DAY.js.map +1 -0
- package/dist/chunk-H2KJHBW4.js +3329 -0
- package/dist/chunk-H2KJHBW4.js.map +1 -0
- package/dist/chunk-HPVSH7SF.cjs +2294 -0
- package/dist/chunk-HPVSH7SF.cjs.map +1 -0
- package/dist/{chunk-MXO72PLY.cjs → chunk-HWHGOVO6.cjs} +21 -19
- package/dist/chunk-HWHGOVO6.cjs.map +1 -0
- package/dist/chunk-HYJJ2V2I.js +2294 -0
- package/dist/chunk-HYJJ2V2I.js.map +1 -0
- package/dist/{chunk-AFM2ULJH.cjs → chunk-J7FHVZII.cjs} +1567 -1067
- package/dist/chunk-J7FHVZII.cjs.map +1 -0
- package/dist/chunk-K6OZXIR6.js +1 -0
- package/dist/{chunk-H3VORETI.js → chunk-M5RYMAFI.js} +487 -592
- package/dist/chunk-M5RYMAFI.js.map +1 -0
- package/dist/chunk-NB25P3EH.js +363 -0
- package/dist/chunk-NB25P3EH.js.map +1 -0
- package/dist/{chunk-TTCLJX6D.js → chunk-NFJ4P6ZZ.js} +10 -8
- package/dist/chunk-NFJ4P6ZZ.js.map +1 -0
- package/dist/chunk-NM7UAMC3.cjs +457 -0
- package/dist/chunk-NM7UAMC3.cjs.map +1 -0
- package/dist/chunk-PM4XJE2Y.cjs +363 -0
- package/dist/chunk-PM4XJE2Y.cjs.map +1 -0
- package/dist/chunk-PUKJP2Z5.js +145 -0
- package/dist/chunk-PUKJP2Z5.js.map +1 -0
- package/dist/{chunk-VOHZB45S.js → chunk-Q6LFSAKV.js} +1321 -821
- package/dist/chunk-Q6LFSAKV.js.map +1 -0
- package/dist/{chunk-INHVXP6Z.js → chunk-RFIBF2RR.js} +1203 -430
- package/dist/chunk-RFIBF2RR.js.map +1 -0
- package/dist/{chunk-Q2WGKJNN.cjs → chunk-S5BKZZGM.cjs} +699 -123
- package/dist/chunk-S5BKZZGM.cjs.map +1 -0
- package/dist/chunk-SGLEQVJH.cjs +3329 -0
- package/dist/chunk-SGLEQVJH.cjs.map +1 -0
- package/dist/chunk-UGLFDG7L.cjs +1 -0
- package/dist/chunk-UGLFDG7L.cjs.map +1 -0
- package/dist/{chunk-YH3BIKHH.js → chunk-UMWZ4ZET.js} +146 -49
- package/dist/chunk-UMWZ4ZET.js.map +1 -0
- package/dist/{index-szBv3496.d.ts → coerce-DP0vYu-x.d.ts} +286 -199
- package/dist/{index-C_8o--VE.d.cts → coerce-DRERzdve.d.cts} +286 -199
- package/dist/core/index.cjs +9 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +122 -108
- package/dist/core/index.d.ts +122 -108
- package/dist/core/index.js +32 -28
- package/dist/generate/index.cjs +8 -8
- package/dist/generate/index.d.cts +168 -84
- package/dist/generate/index.d.ts +168 -84
- package/dist/generate/index.js +7 -7
- package/dist/{index-CGpRv5sl.d.cts → index-9eoQs2C1.d.ts} +34 -19
- package/dist/{index-CCNJRG-P.d.cts → index-B9QLziDe.d.cts} +293 -56
- package/dist/{index-Dzr13q3d.d.cts → index-BBWNZS0f.d.cts} +135 -58
- package/dist/{index-9wcMhG73.d.ts → index-BHIUyjhZ.d.ts} +293 -56
- package/dist/{index-BGFW-8P2.d.cts → index-BJgP97N1.d.ts} +196 -114
- package/dist/{index-CunYKLiu.d.ts → index-BL5N2Oyz.d.cts} +1 -1
- package/dist/{index-Cj49F892.d.ts → index-BMweUlm5.d.cts} +63 -23
- package/dist/{index-CgHqxdps.d.ts → index-BNSM-DSk.d.cts} +196 -114
- package/dist/{index-D57QRbVn.d.ts → index-BRMbPkHE.d.ts} +480 -254
- package/dist/{index-Chbst3Jx.d.ts → index-CJBBiAmU.d.ts} +135 -58
- package/dist/{index-BkGmlyI3.d.cts → index-CL4b4gUQ.d.ts} +63 -23
- package/dist/{index-B9MNZboQ.d.ts → index-Cy15oTvh.d.cts} +52 -22
- package/dist/{index-B9MNZboQ.d.cts → index-Cy15oTvh.d.ts} +52 -22
- package/dist/{index-BO6xE9YU.d.cts → index-DGCNKAUr.d.cts} +480 -254
- package/dist/{index-B4o55NDr.d.cts → index-Dw2DP7vm.d.ts} +1 -1
- package/dist/{index-G1uwGGWQ.d.ts → index-cHvbYgJI.d.cts} +34 -19
- package/dist/index.cjs +42 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -14
- package/dist/index.d.ts +14 -14
- package/dist/index.js +82 -54
- package/dist/{masks-DYbE485J.d.cts → masks-Cc7-MzzY.d.ts} +49 -2
- package/dist/{masks-DYbE485J.d.ts → masks-pADfTOiD.d.cts} +49 -2
- package/dist/model/index.cjs +19 -12
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +504 -182
- package/dist/model/index.d.ts +504 -182
- package/dist/model/index.js +18 -11
- package/dist/{positional-Cptlj-xs.d.ts → positional-DJgs6ltD.d.ts} +85 -8
- package/dist/{positional-DvH_sd8u.d.cts → positional-DMZer-FM.d.cts} +85 -8
- package/dist/theory/index.cjs +35 -6
- package/dist/theory/index.cjs.map +1 -1
- package/dist/theory/index.d.cts +257 -62
- package/dist/theory/index.d.ts +257 -62
- package/dist/theory/index.js +41 -12
- package/package.json +7 -5
- package/dist/chunk-2LCPM3EG.js +0 -3224
- package/dist/chunk-2LCPM3EG.js.map +0 -1
- package/dist/chunk-6XH6QZYQ.cjs.map +0 -1
- package/dist/chunk-6XPTBE7Y.cjs +0 -49
- package/dist/chunk-6XPTBE7Y.cjs.map +0 -1
- package/dist/chunk-AFM2ULJH.cjs.map +0 -1
- package/dist/chunk-B6XNKWZV.cjs +0 -3224
- package/dist/chunk-B6XNKWZV.cjs.map +0 -1
- package/dist/chunk-E3F4AHAH.cjs.map +0 -1
- package/dist/chunk-ELCTZUJJ.js +0 -379
- package/dist/chunk-ELCTZUJJ.js.map +0 -1
- package/dist/chunk-FVSI36UV.js.map +0 -1
- package/dist/chunk-H3VORETI.js.map +0 -1
- package/dist/chunk-H42UHPYW.js +0 -1577
- package/dist/chunk-H42UHPYW.js.map +0 -1
- package/dist/chunk-HFPS7JFD.js +0 -1
- package/dist/chunk-INHVXP6Z.js.map +0 -1
- package/dist/chunk-K4ZJUGF4.cjs +0 -379
- package/dist/chunk-K4ZJUGF4.cjs.map +0 -1
- package/dist/chunk-KNJEKLKV.js +0 -49
- package/dist/chunk-KNJEKLKV.js.map +0 -1
- package/dist/chunk-MXO72PLY.cjs.map +0 -1
- package/dist/chunk-NLEU4QSE.cjs +0 -360
- package/dist/chunk-NLEU4QSE.cjs.map +0 -1
- package/dist/chunk-OE6WK2Y2.cjs +0 -1577
- package/dist/chunk-OE6WK2Y2.cjs.map +0 -1
- package/dist/chunk-PKFNUHDY.js.map +0 -1
- package/dist/chunk-Q2WGKJNN.cjs.map +0 -1
- package/dist/chunk-RHIJ3S4I.cjs +0 -1
- package/dist/chunk-RHIJ3S4I.cjs.map +0 -1
- package/dist/chunk-TTCLJX6D.js.map +0 -1
- package/dist/chunk-UADYAYAT.cjs.map +0 -1
- package/dist/chunk-VOHZB45S.js.map +0 -1
- package/dist/chunk-VTI6FOLB.js.map +0 -1
- package/dist/chunk-WWURE4XT.cjs.map +0 -1
- package/dist/chunk-YH3BIKHH.js.map +0 -1
- /package/dist/{chunk-HFPS7JFD.js.map → chunk-K6OZXIR6.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as ChordLike, K as KeyLike,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { c as ChordLike, K as KeyLike, i as ChordToneRole, r as SpelledKeyLike, b as Chord, n as ResolvedKey, j as KeyRelation, e as ChordSegment, V as VoiceSnapshot, g as ChordSpan } from './coerce-DP0vYu-x.js';
|
|
2
|
+
import { b as MeterLike } from './index-CL4b4gUQ.js';
|
|
3
|
+
import { h as NoteEvent, e as KeyScale } from './index-Cy15oTvh.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The vocabulary the analyze layer explains itself in.
|
|
@@ -222,33 +222,41 @@ type DetectCadenceOptions = {
|
|
|
222
222
|
* Classify the cadence formed by moving from one chord to the next.
|
|
223
223
|
*
|
|
224
224
|
* - authentic: V (dominant a fifth above the tonic) to I
|
|
225
|
-
* - plagal: IV
|
|
225
|
+
* - plagal: IV, the chord on the key's own fourth degree, to I
|
|
226
226
|
* - modal: bVII to I, the cadence of rock and modal writing
|
|
227
227
|
* - deceptive: V to the key's own submediant, plus the borrowed bVI of a major
|
|
228
228
|
* key
|
|
229
229
|
* - phrygian: iv6 to V of a minor key, the half cadence whose bass falls a
|
|
230
230
|
* semitone from b6 to 5
|
|
231
|
-
* - half: any other chord than the dominant itself to V
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
* the
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* key
|
|
241
|
-
*
|
|
231
|
+
* - half: any other chord than the dominant itself to V, the cadential six-four
|
|
232
|
+
* standing on the dominant's own bass included
|
|
233
|
+
*
|
|
234
|
+
* These are read as scale degrees rather than as semitone distances, so a mode
|
|
235
|
+
* cadences from and onto the degrees it actually has: the deceptive arrival of
|
|
236
|
+
* dorian is a major sixth above the tonic and that of phrygian a minor sixth,
|
|
237
|
+
* and the subdominant a plagal cadence falls from is the tritone above the
|
|
238
|
+
* tonic in lydian. The two borrowed types are the exception, and are stated as
|
|
239
|
+
* the fixed offsets they name: `modal` is the flattened seventh whatever the
|
|
240
|
+
* key writes on that degree, and the Phrygian bass falls from the lowered
|
|
241
|
+
* submediant. A half cadence normally rests on the major third that carries
|
|
242
|
+
* the leading tone, but where the key's own dominant has no leading tone — the
|
|
243
|
+
* modal `v` of dorian, mixolydian and the pop writing built on them — the
|
|
244
|
+
* arrival's own third suffices as long as the key contains it. That relaxation
|
|
245
|
+
* belongs to the modes alone: a borrowed minor `v` in a major key is no half
|
|
246
|
+
* cadence, and neither is the `v` of a minor key, which cadences through the
|
|
247
|
+
* raised seventh it writes as an accidental rather than in its scale.
|
|
242
248
|
*
|
|
243
249
|
* A static V-to-V repeat with no root motion is not a cadence and yields a null
|
|
244
|
-
* type
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
250
|
+
* type. The tonic six-four resolving onto the dominant it stands on is a half
|
|
251
|
+
* cadence, and the most ordinary one there is: `I - I64 - V` closes the
|
|
252
|
+
* antecedent of a period, and the six-four is a double appoggiatura over the
|
|
253
|
+
* dominant's own bass rather than a chord that keeps the motion going. Where
|
|
254
|
+
* that dominant goes on to resolve, the pair and the resolution are one event —
|
|
255
|
+
* passing the six-four as `approach` when the dominant is the `from` chord is
|
|
256
|
+
* what lets it be reported as one, with the type and the beat still the
|
|
257
|
+
* dominant's resolution while the `rationale` says the cadence began at the
|
|
258
|
+
* six-four. A six-four the bass leaves instead (`IV-I64-IV`, or a neighbouring
|
|
259
|
+
* one over the tonic) is an ordinary inverted tonic and is read as one.
|
|
252
260
|
*
|
|
253
261
|
* An authentic cadence is graded perfect or imperfect. Perfect takes the
|
|
254
262
|
* dominant to the tonic with both chords in root position and the tonic in the
|
|
@@ -336,7 +344,7 @@ declare function detectCadence(from: ChordLike, to: ChordLike, key: KeyLike, opt
|
|
|
336
344
|
* ```
|
|
337
345
|
* @category Functional Harmony
|
|
338
346
|
*/
|
|
339
|
-
declare function romanToChord(text: string, key:
|
|
347
|
+
declare function romanToChord(text: string, key: SpelledKeyLike): Chord;
|
|
340
348
|
/**
|
|
341
349
|
* Options for {@link chordToRoman}.
|
|
342
350
|
*
|
|
@@ -350,10 +358,17 @@ type ChordToRomanOptions = {
|
|
|
350
358
|
* Off by default: naming the root is always a correct spelling, whereas
|
|
351
359
|
* whether a chromatic dominant is genuinely applied is a reading only the
|
|
352
360
|
* caller can make. Turning it on names the chords {@link secondaryDominant}
|
|
353
|
-
* builds as the applied numerals they are, except where the
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
361
|
+
* builds as the applied numerals they are, except in three cases, where the
|
|
362
|
+
* numeral names the root against the home key as it does with this off:
|
|
363
|
+
*
|
|
364
|
+
* - The target degree carries no perfect fifth: nothing tonicizes a
|
|
365
|
+
* diminished triad, so a chord over the seventh degree of a major key stays
|
|
366
|
+
* `#IV7` rather than becoming a numeral no harmony text writes.
|
|
367
|
+
* - The target is the tonic, which its own dominant points at: `V7` is the
|
|
368
|
+
* key's dominant and `V/I` is a numeral no harmony text writes either.
|
|
369
|
+
* - The chord is diatonic to the key, which keeps the function of its degree
|
|
370
|
+
* rather than tonicizing another. `G7` is `VII7` in A minor and `I7` in C
|
|
371
|
+
* mixolydian, not `V7/III` and `V7/IV`.
|
|
357
372
|
*/
|
|
358
373
|
applied?: boolean;
|
|
359
374
|
/**
|
|
@@ -392,6 +407,11 @@ type ChordToRomanOptions = {
|
|
|
392
407
|
* A chord sounding one of the augmented sixths over an explicit bass on the
|
|
393
408
|
* lowered submediant renders as `It6`, `Fr6` or `Ger6`, since no numeral names
|
|
394
409
|
* those chords; see {@link augmentedSixthKind} for exactly when that applies.
|
|
410
|
+
* That reading is made against the key as written, because what separates an
|
|
411
|
+
* augmented sixth from the seventh chord it sounds like is its letters: the
|
|
412
|
+
* German sixth of Ab minor is named from the Fb Ab Cb D it is written with, not
|
|
413
|
+
* from the letters those pitch classes take once the key has been respelled as
|
|
414
|
+
* a G# minor.
|
|
395
415
|
*
|
|
396
416
|
* @param chord The chord to name, as a chord symbol, chord data, or a `Chord`.
|
|
397
417
|
* @param key The prevailing key, as a key name, a key/scale, or a `Key`.
|
|
@@ -502,11 +522,14 @@ declare function isMinorKey(key: KeyLike): boolean;
|
|
|
502
522
|
* an ambiguity the root offset cannot:
|
|
503
523
|
*
|
|
504
524
|
* - A chord that *sounds* like a dominant — a major third with a minor seventh,
|
|
505
|
-
* or a diminished-family chord — and is
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
* tonicizes ii) and its tritone substitute
|
|
509
|
-
* than inheriting the function of the degree
|
|
525
|
+
* or a diminished-family chord — and is neither diatonic to the key nor
|
|
526
|
+
* borrowed from its parallel mode has dominant function when its root
|
|
527
|
+
* resolves onto a degree that can be made a local tonic. This is what makes an
|
|
528
|
+
* applied dominant (`A7` in C, which tonicizes ii) and its tritone substitute
|
|
529
|
+
* (`Db7`) read as dominant rather than inheriting the function of the degree
|
|
530
|
+
* they happen to sit on. A bare major triad carries no tritone, so it only
|
|
531
|
+
* tonicizes by falling a fifth onto a degree other than the tonic: the Picardy
|
|
532
|
+
* third of a minor key and its borrowed major IV sound their own degrees.
|
|
510
533
|
* - The Neapolitan is subdominant.
|
|
511
534
|
* - An augmented sixth is subdominant. All three are altered predominants that
|
|
512
535
|
* resolve outward onto the dominant, so they take subdominant function even
|
|
@@ -646,8 +669,8 @@ declare function secondaryDominant(targetDegree: number, key: KeyLike): Chord;
|
|
|
646
669
|
* @example
|
|
647
670
|
* ```ts
|
|
648
671
|
* import { makeChord, secondaryDominantOf } from '@libraz/libcantus';
|
|
649
|
-
* secondaryDominantOf(makeChord(8, 'maj'));
|
|
650
|
-
* //
|
|
672
|
+
* secondaryDominantOf(makeChord(8, 'maj')).rootPc; // 3 — Eb7 tonicizes the
|
|
673
|
+
* // borrowed bVI of C major
|
|
651
674
|
* ```
|
|
652
675
|
* @category Functional Harmony
|
|
653
676
|
*/
|
|
@@ -727,8 +750,20 @@ type KeyRegion = {
|
|
|
727
750
|
startBeat: number;
|
|
728
751
|
/** End of the region, exclusive. */
|
|
729
752
|
endBeat: number;
|
|
730
|
-
/**
|
|
731
|
-
|
|
753
|
+
/**
|
|
754
|
+
* The key in force across the region, owned by it: every entry point hands
|
|
755
|
+
* back a key of the region's own, so writing to one changes neither the other
|
|
756
|
+
* regions of the same run nor what a later call reports.
|
|
757
|
+
*
|
|
758
|
+
* Whole, whichever way the region was built. A caller who named the key hands
|
|
759
|
+
* its spelling and scale form down, and a key the analysis found is spelled
|
|
760
|
+
* and formed the way {@link resolveKey} reads a bare scale — the reading every
|
|
761
|
+
* other layer would have made of it. There is no third state to guess at: a
|
|
762
|
+
* key/scale alone says nothing about how it is written, so a region carrying
|
|
763
|
+
* one would report whichever spelling those pitch classes read best from, and
|
|
764
|
+
* an Ab minor handed in would come back out a G# minor.
|
|
765
|
+
*/
|
|
766
|
+
key: ResolvedKey;
|
|
732
767
|
/**
|
|
733
768
|
* How well the region's music fits the key, in [0, 1]: the correlation
|
|
734
769
|
* between the span's pitch-class distribution and the key's profile, with
|
|
@@ -770,7 +805,7 @@ type KeyTimelineOptions = {
|
|
|
770
805
|
*
|
|
771
806
|
* @defaultValue `4/4`
|
|
772
807
|
*/
|
|
773
|
-
ts?:
|
|
808
|
+
ts?: MeterLike;
|
|
774
809
|
/**
|
|
775
810
|
* The meter as it changes over the span. Bar lines, downbeats and the metric
|
|
776
811
|
* accents the search discounts a modulation by all follow the signature in
|
|
@@ -779,7 +814,7 @@ type KeyTimelineOptions = {
|
|
|
779
814
|
*
|
|
780
815
|
* @defaultValue 4/4 throughout
|
|
781
816
|
*/
|
|
782
|
-
meters?:
|
|
817
|
+
meters?: MeterLike;
|
|
783
818
|
/**
|
|
784
819
|
* Expected length of one key area in beats; defaults to four bars of the
|
|
785
820
|
* opening meter.
|
|
@@ -881,6 +916,12 @@ declare function keyTimelineFromNotes(notes: readonly NoteEvent[], opts?: KeyTim
|
|
|
881
916
|
* confidence, as it does in the note path, but takes no part in choosing which
|
|
882
917
|
* keys are reported: that is settled by how the chords read.
|
|
883
918
|
*
|
|
919
|
+
* A region's evidence is the run of segments it was grouped from, which is the
|
|
920
|
+
* same reading the search itself makes of them. Where the segments given
|
|
921
|
+
* overlap each other — a chart is a sequence, so a chord timeline's are not —
|
|
922
|
+
* a chord held past the segment after it argues for its own segment's key
|
|
923
|
+
* rather than for both.
|
|
924
|
+
*
|
|
884
925
|
* @param chords The chord segments to analyze, in time order; pass a chord
|
|
885
926
|
* timeline's `segments`.
|
|
886
927
|
* @param opts Analysis options; see {@link KeyTimelineOptions}.
|
|
@@ -916,7 +957,7 @@ declare function detectModulations(chords: readonly ChordSegment[], opts?: KeyTi
|
|
|
916
957
|
* ```
|
|
917
958
|
* @category Arrangement & Analysis
|
|
918
959
|
*/
|
|
919
|
-
declare function prevailingKeyOf(regions: readonly KeyRegion[]):
|
|
960
|
+
declare function prevailingKeyOf(regions: readonly KeyRegion[]): ResolvedKey | null;
|
|
920
961
|
|
|
921
962
|
/**
|
|
922
963
|
* A suspension figure, named by the interval above the bass and the interval it
|
|
@@ -1033,7 +1074,7 @@ type IdentifiedVoiceNote = VoiceNote & {
|
|
|
1033
1074
|
* ```
|
|
1034
1075
|
* @category Arrangement & Analysis
|
|
1035
1076
|
*/
|
|
1036
|
-
type KeyContext =
|
|
1077
|
+
type KeyContext = KeyLike | ((beat: number) => KeyScale);
|
|
1037
1078
|
/**
|
|
1038
1079
|
* Give plain note events the ids {@link analyzeVoice} reports back.
|
|
1039
1080
|
*
|
|
@@ -1055,8 +1096,10 @@ declare function toVoiceNotes(events: readonly NoteEvent[]): IdentifiedVoiceNote
|
|
|
1055
1096
|
* resolving by step the other way), and escape tones, then fall back to
|
|
1056
1097
|
* tension, avoid, or an unresolved-dissonance label. The figures are named as
|
|
1057
1098
|
* {@link classifyMelodyTones} names them, so a caller reading a melody through
|
|
1058
|
-
* both layers gets one vocabulary
|
|
1059
|
-
*
|
|
1099
|
+
* both layers gets one vocabulary. The two answer different questions and
|
|
1100
|
+
* neither refines the other: that classifier weighs the metre, which this one is
|
|
1101
|
+
* not given, so it can call ornamental a note this one reads as a chord tone,
|
|
1102
|
+
* and the reverse. Leading-tone resolutions are noted
|
|
1060
1103
|
* additionally, judged against the key in force at the beat the resolution
|
|
1061
1104
|
* lands on, so a modulation is heard from its new tonic.
|
|
1062
1105
|
*
|
|
@@ -1103,6 +1146,32 @@ type ChordTimeline = {
|
|
|
1103
1146
|
at: (beat: number) => Chord | null;
|
|
1104
1147
|
segments: ChordSegment[];
|
|
1105
1148
|
};
|
|
1149
|
+
/**
|
|
1150
|
+
* Reject a value that is not a chord timeline.
|
|
1151
|
+
*
|
|
1152
|
+
* A timeline is the one argument a host is most likely to hold from somewhere
|
|
1153
|
+
* else — an in-memory project value, a previous run restored to a timeline, or
|
|
1154
|
+
* another library's output — and
|
|
1155
|
+
* it is read field by field deep inside an analysis. Checking it once at the
|
|
1156
|
+
* entrance names the argument that is wrong instead of reporting the library's
|
|
1157
|
+
* own `TypeError` from wherever the first `segments` lookup happened to be.
|
|
1158
|
+
*
|
|
1159
|
+
* The segments are checked too: every reader of a timeline compares beats, and
|
|
1160
|
+
* a segment whose bounds are missing compares as neither before nor after, so
|
|
1161
|
+
* it disappears from the analysis rather than being reported.
|
|
1162
|
+
*
|
|
1163
|
+
* @param timeline The timeline as the caller passed it.
|
|
1164
|
+
* @param name What the argument is called in an error message.
|
|
1165
|
+
* @returns The same timeline.
|
|
1166
|
+
* @throws If the value is not a timeline of chord segments.
|
|
1167
|
+
* @example
|
|
1168
|
+
* ```ts
|
|
1169
|
+
* import { assertChordTimeline, chordTimelineFromChords } from '@libraz/libcantus';
|
|
1170
|
+
* assertChordTimeline(chordTimelineFromChords([], 4)); // the timeline, unchanged
|
|
1171
|
+
* ```
|
|
1172
|
+
* @category Arrangement & Analysis
|
|
1173
|
+
*/
|
|
1174
|
+
declare function assertChordTimeline(timeline: ChordTimeline, name?: string): ChordTimeline;
|
|
1106
1175
|
/**
|
|
1107
1176
|
* Build a chord timeline from placed chords.
|
|
1108
1177
|
*
|
|
@@ -1139,15 +1208,19 @@ type ChordTimelineOptions = {
|
|
|
1139
1208
|
* Key context held across the whole span. Omit it to have the key searched
|
|
1140
1209
|
* for over time with {@link keyTimelineFromNotes}, which is what lets a piece
|
|
1141
1210
|
* that modulates be analysed against the key actually in force.
|
|
1211
|
+
*
|
|
1212
|
+
* Taken in whatever form the caller holds a key, and kept whole: the region
|
|
1213
|
+
* built from it carries the spelling and the scale form it was named with, so
|
|
1214
|
+
* an Ab minor stated here is an Ab minor in the result.
|
|
1142
1215
|
*/
|
|
1143
|
-
key?:
|
|
1216
|
+
key?: KeyLike;
|
|
1144
1217
|
/**
|
|
1145
1218
|
* A single time signature held across the whole span, as sugar for a
|
|
1146
1219
|
* one-element `meters`; defaults to 4/4. Giving both is an input error.
|
|
1147
1220
|
*
|
|
1148
1221
|
* @defaultValue `4/4`
|
|
1149
1222
|
*/
|
|
1150
|
-
ts?:
|
|
1223
|
+
ts?: MeterLike;
|
|
1151
1224
|
/**
|
|
1152
1225
|
* The meter as it changes over the span. Bar lines, downbeats and metric
|
|
1153
1226
|
* weight all follow the signature in force at the beat in question, so a
|
|
@@ -1155,7 +1228,7 @@ type ChordTimelineOptions = {
|
|
|
1155
1228
|
*
|
|
1156
1229
|
* @defaultValue 4/4 throughout
|
|
1157
1230
|
*/
|
|
1158
|
-
meters?:
|
|
1231
|
+
meters?: MeterLike;
|
|
1159
1232
|
/**
|
|
1160
1233
|
* Length of the pickup in beats, when the piece starts with one.
|
|
1161
1234
|
*
|
|
@@ -1184,18 +1257,21 @@ type ChordTimelineOptions = {
|
|
|
1184
1257
|
*/
|
|
1185
1258
|
harmonicRhythm?: number;
|
|
1186
1259
|
/**
|
|
1187
|
-
*
|
|
1188
|
-
*
|
|
1189
|
-
*
|
|
1190
|
-
*
|
|
1260
|
+
* Resolution the `'dynamic'` search looks for changes at, in beats; defaults
|
|
1261
|
+
* to one main pulse of the meter — a quarter in 4/4, a dotted quarter in 6/8.
|
|
1262
|
+
* Lower it to catch changes on off-beats, at the cost of proportionally more
|
|
1263
|
+
* work. Values above `harmonicRhythm` are clamped to it, and the option is
|
|
1264
|
+
* ignored under `'grid'` segmentation.
|
|
1191
1265
|
*
|
|
1192
1266
|
* The search reads it as a resolution rather than as an exact slot length: it
|
|
1193
|
-
* rounds down to a whole division of
|
|
1194
|
-
*
|
|
1195
|
-
*
|
|
1196
|
-
*
|
|
1267
|
+
* rounds down to a whole division of the meter's pulse, so `0.6` in 4/4 is
|
|
1268
|
+
* read in half-beats. That keeps every pulse of the meter, and the bar lines
|
|
1269
|
+
* with them, on the grid whatever resolution is asked for, and with them every
|
|
1270
|
+
* change a coarser setting found. A resolution coarser than one pulse is
|
|
1271
|
+
* therefore read as one pulse rather than stepping over the beats a change is
|
|
1272
|
+
* heard on.
|
|
1197
1273
|
*
|
|
1198
|
-
* @defaultValue
|
|
1274
|
+
* @defaultValue one main pulse of the meter
|
|
1199
1275
|
*/
|
|
1200
1276
|
minChordBeats?: number;
|
|
1201
1277
|
/**
|
|
@@ -1237,7 +1313,7 @@ type ChordTimelineResult = {
|
|
|
1237
1313
|
* The key held longest across {@link ChordTimelineResult.keys} — the one to
|
|
1238
1314
|
* print on a key signature or hand to a generator that takes a single key.
|
|
1239
1315
|
*/
|
|
1240
|
-
prevailingKey:
|
|
1316
|
+
prevailingKey: ResolvedKey;
|
|
1241
1317
|
/** One confidence value in [0, 1] per segment, in segment order. */
|
|
1242
1318
|
segmentConfidence: number[];
|
|
1243
1319
|
};
|
|
@@ -1245,7 +1321,8 @@ type ChordTimelineResult = {
|
|
|
1245
1321
|
* Infer a chord timeline from raw multi-track notes.
|
|
1246
1322
|
*
|
|
1247
1323
|
* Chord boundaries are searched for rather than assumed: the span is examined
|
|
1248
|
-
* in
|
|
1324
|
+
* in slots of one main pulse, subdivided as finely as `minChordBeats` asks for,
|
|
1325
|
+
* and the change points that best explain the notes
|
|
1249
1326
|
* are chosen, trading each slot's harmonic fit against a cost per chord change
|
|
1250
1327
|
* that a strong beat discounts. A bar holding two chords therefore yields two
|
|
1251
1328
|
* segments and a bar holding one yields one, without the caller having to know
|
|
@@ -1340,4 +1417,4 @@ type CadenceHit = {
|
|
|
1340
1417
|
*/
|
|
1341
1418
|
declare function detectCadences(timeline: ChordTimeline, key: KeyContext): CadenceHit[];
|
|
1342
1419
|
|
|
1343
|
-
export { type AnalyzeChordOptions as A, type BorrowedSource as B, type CadenceHit as C, type DetectCadenceOptions as D, type ExplainRomanOptions as E,
|
|
1420
|
+
export { type AnalyzeChordOptions as A, type BorrowedSource as B, type CadenceHit as C, type DetectCadenceOptions as D, type ExplainRomanOptions as E, isDiatonic as F, isMinorKey as G, type HarmonicFunction as H, type IdentifiedVoiceNote as I, keyTimelineFromNotes as J, type KeyContext as K, pivotChords as L, prevailingKeyOf as M, romanToChord as N, secondaryDominant as O, type PivotChord as P, secondaryDominantOf as Q, type RejectedCandidate as R, type SuspensionFigure as S, type TheoryLabel as T, toVoiceNotes as U, type VoiceNote as V, type AnalyzedNote as a, type CadenceResult as b, type ChordAnalysis as c, type ChordSegmentation as d, type ChordTimeline as e, type ChordTimelineOptions as f, type ChordTimelineResult as g, type ChordToRomanOptions as h, type KeyProfileName as i, type KeyProfilePair as j, type KeyRegion as k, type KeyTimelineOptions as l, type RomanExplanation as m, analyzeChord as n, analyzeVoice as o, assertChordTimeline as p, borrowedSource as q, chordTimelineFromChords as r, chordTimelineFromNotes as s, chordToRoman as t, detectCadence as u, detectCadences as v, detectModulations as w, explainRoman as x, functionOf as y, isBorrowedChord as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as ParseResult } from './index-
|
|
1
|
+
import { P as ParseResult } from './index-Cy15oTvh.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Meter arithmetic shared by the meter module and the validation guards.
|
|
@@ -83,6 +83,14 @@ type MeterChange = {
|
|
|
83
83
|
* The first entry also governs everything before it, which is what reads a
|
|
84
84
|
* pickup written at negative beats in the signature the piece opens in.
|
|
85
85
|
*
|
|
86
|
+
* Beat 0 is the first downbeat here as everywhere else: the opening signature
|
|
87
|
+
* lays its bar lines from beat 0 whatever beat the first entry is written at, so
|
|
88
|
+
* a map opening at the pickup it covers numbers its bars exactly as the bare
|
|
89
|
+
* signature does. Every later entry starts a bar at the beat it takes effect.
|
|
90
|
+
*
|
|
91
|
+
* Pass the whole piece with its map rather than one call per meter span: a
|
|
92
|
+
* split call cannot see a voice move or a key region that crosses the change.
|
|
93
|
+
*
|
|
86
94
|
* @category Rhythm & Meter
|
|
87
95
|
*/
|
|
88
96
|
type MeterMap = MeterChange[];
|
|
@@ -123,7 +131,10 @@ type MeterLike = string | TimeSignature | MeterMap | {
|
|
|
123
131
|
* value whose `toJSON` returns one of those.
|
|
124
132
|
* @param name What the meter is called in an error message, so a caller that
|
|
125
133
|
* holds several of them hears which one was malformed.
|
|
126
|
-
* @returns The validated signature, or the validated map
|
|
134
|
+
* @returns The validated signature, or the validated map, freshly allocated
|
|
135
|
+
* down to every grouping array — so a caller may keep and edit what it gets
|
|
136
|
+
* back without editing the meter it passed in, and without any two calls
|
|
137
|
+
* handing out the same object.
|
|
127
138
|
* @throws If the value names no meter, or the meter it names is malformed.
|
|
128
139
|
*/
|
|
129
140
|
declare function toMeterData(value: MeterLike, name?: string): MeterData;
|
|
@@ -186,17 +197,23 @@ declare function tryParseTimeSignature(text: string): ParseResult<TimeSignature>
|
|
|
186
197
|
*
|
|
187
198
|
* The additive form is what {@link parseTimeSignature} reads back, and it adds
|
|
188
199
|
* its terms to get the numerator — so only a grouping written in denominator
|
|
189
|
-
* units can be rendered that way. A grouping counted in main pulses
|
|
190
|
-
* `[1, 1, 1]`, 12/8 as `[2, 2]`)
|
|
191
|
-
*
|
|
192
|
-
*
|
|
200
|
+
* units can be rendered that way. A grouping counted in main pulses whose groups
|
|
201
|
+
* are all the same length (9/8 as `[1, 1, 1]`, 12/8 as `[2, 2]`) states the
|
|
202
|
+
* division the bare signature already has, so it falls back to the plain form at
|
|
203
|
+
* no cost. One whose groups differ (12/8 as `[1, 1, 2]`) states an accent no
|
|
204
|
+
* signature text can carry, and asking for the additive form of it is refused
|
|
205
|
+
* rather than answered with a bar that weighs its pulses differently.
|
|
193
206
|
*
|
|
194
207
|
* The plain form drops the grouping, so a round trip through it reads 7/8 as
|
|
195
208
|
* flat rather than as 2+2+3; ask for the additive form to keep it.
|
|
196
209
|
*
|
|
197
|
-
* @param ts The time signature
|
|
210
|
+
* @param ts The time signature, in any form that names one; a meter map is
|
|
211
|
+
* rendered as the signature it opens in.
|
|
198
212
|
* @param opts Set `grouping: true` to render an additive grouping.
|
|
199
213
|
* @returns The formatted signature.
|
|
214
|
+
* @throws If `grouping: true` is asked of a grouping that no signature text can
|
|
215
|
+
* spell: one counted in main pulses, on a compound numerator, whose groups are
|
|
216
|
+
* not all the same length.
|
|
200
217
|
* @example
|
|
201
218
|
* ```ts
|
|
202
219
|
* import { formatTimeSignature } from '@libraz/libcantus';
|
|
@@ -206,7 +223,7 @@ declare function tryParseTimeSignature(text: string): ParseResult<TimeSignature>
|
|
|
206
223
|
* ```
|
|
207
224
|
* @category Rhythm & Meter
|
|
208
225
|
*/
|
|
209
|
-
declare function formatTimeSignature(ts:
|
|
226
|
+
declare function formatTimeSignature(ts: MeterLike, opts?: {
|
|
210
227
|
grouping?: boolean;
|
|
211
228
|
}): string;
|
|
212
229
|
/**
|
|
@@ -217,19 +234,27 @@ declare function formatTimeSignature(ts: TimeSignature, opts?: {
|
|
|
217
234
|
* is a signature whose {@link TimeSignature.grouping} selects the additive
|
|
218
235
|
* reading (9/8 as 2+2+2+3).
|
|
219
236
|
*
|
|
220
|
-
* @param ts The time signature
|
|
237
|
+
* @param ts The time signature, in any form that names one; a meter map is read
|
|
238
|
+
* as the signature it opens in.
|
|
221
239
|
* @returns True for compound meters.
|
|
222
240
|
* @category Rhythm & Meter
|
|
223
241
|
*/
|
|
224
|
-
declare function isCompound(ts:
|
|
242
|
+
declare function isCompound(ts: MeterLike): boolean;
|
|
225
243
|
/**
|
|
226
244
|
* Length of a bar in quarter-note beats.
|
|
227
245
|
*
|
|
228
|
-
* @param ts The time signature
|
|
246
|
+
* @param ts The time signature, in any form that names one; a meter map has no
|
|
247
|
+
* single bar length, so it is read as the signature it opens in. Ask
|
|
248
|
+
* {@link beatsPerBarAt} for the bar a given beat falls in.
|
|
229
249
|
* @returns The bar length in quarter notes.
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* import { beatsPerBar } from '@libraz/libcantus';
|
|
253
|
+
* beatsPerBar('6/8'); // 3
|
|
254
|
+
* ```
|
|
230
255
|
* @category Rhythm & Meter
|
|
231
256
|
*/
|
|
232
|
-
declare function beatsPerBar(ts:
|
|
257
|
+
declare function beatsPerBar(ts: MeterLike): number;
|
|
233
258
|
/**
|
|
234
259
|
* The time signature in force at a beat.
|
|
235
260
|
*
|
|
@@ -284,6 +309,12 @@ declare function barIndexAt(beatInQuarters: number, meter: MeterLike): number;
|
|
|
284
309
|
* The meter-map counterpart of {@link beatsPerBar}, which answers for one
|
|
285
310
|
* signature and so cannot be asked about a piece that changes meter.
|
|
286
311
|
*
|
|
312
|
+
* The bar the beat is in, not the bar its signature nominally has: a change of
|
|
313
|
+
* meter starts a new bar, so a bar interrupted by one is shorter than its own
|
|
314
|
+
* signature says. Reading the signature's own length there would put the end of
|
|
315
|
+
* the bar past where the next one begins, and every span measured in bars from
|
|
316
|
+
* that point on would be counted against a bar length the music never had.
|
|
317
|
+
*
|
|
287
318
|
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
288
319
|
* @param meter A single signature, or the piece's meter map.
|
|
289
320
|
* @returns The bar length in quarter notes.
|
|
@@ -300,7 +331,9 @@ declare function beatsPerBarAt(beatInQuarters: number, meter: MeterLike): number
|
|
|
300
331
|
*
|
|
301
332
|
* @param opts The options carrying `ts`, `meters`, or neither.
|
|
302
333
|
* @param name What the options belong to, for the error message.
|
|
303
|
-
* @returns The meter map to analyse against
|
|
334
|
+
* @returns The meter map to analyse against, freshly allocated down to every
|
|
335
|
+
* signature and grouping array, so writing to it changes nothing another
|
|
336
|
+
* caller reads; 4/4 throughout when neither `ts` nor `meters` is given.
|
|
304
337
|
* @throws If both `ts` and `meters` are given, or the map is malformed.
|
|
305
338
|
* @example
|
|
306
339
|
* ```ts
|
|
@@ -311,8 +344,8 @@ declare function beatsPerBarAt(beatInQuarters: number, meter: MeterLike): number
|
|
|
311
344
|
* @category Rhythm & Meter
|
|
312
345
|
*/
|
|
313
346
|
declare function resolveMeters(opts: {
|
|
314
|
-
ts?:
|
|
315
|
-
meters?:
|
|
347
|
+
ts?: MeterLike;
|
|
348
|
+
meters?: MeterLike;
|
|
316
349
|
}, name?: string): MeterMap;
|
|
317
350
|
/**
|
|
318
351
|
* Number of main pulses (felt beats) per bar: the numerator for simple meters,
|
|
@@ -324,11 +357,12 @@ declare function resolveMeters(opts: {
|
|
|
324
357
|
* {@link TimeSignature.grouping}; {@link metricWeight} then accents each
|
|
325
358
|
* group's head pulse.
|
|
326
359
|
*
|
|
327
|
-
* @param ts The time signature
|
|
360
|
+
* @param ts The time signature, in any form that names one; a meter map is read
|
|
361
|
+
* as the signature it opens in.
|
|
328
362
|
* @returns The pulse count per bar.
|
|
329
363
|
* @category Rhythm & Meter
|
|
330
364
|
*/
|
|
331
|
-
declare function pulsesPerBar(ts:
|
|
365
|
+
declare function pulsesPerBar(ts: MeterLike): number;
|
|
332
366
|
/**
|
|
333
367
|
* Convert an absolute quarter-note position to a bar index and in-bar offset.
|
|
334
368
|
*
|
|
@@ -351,16 +385,17 @@ declare function beatToBarPosition(beatInQuarters: number, meter: MeterLike): Ba
|
|
|
351
385
|
* denominator unit in an additive metre. Position displays, click tracks, and
|
|
352
386
|
* score export are all written against this length.
|
|
353
387
|
*
|
|
354
|
-
* @param ts The time signature
|
|
388
|
+
* @param ts The time signature, in any form that names one; a meter map is read
|
|
389
|
+
* as the signature it opens in.
|
|
355
390
|
* @returns The pulse length in quarter-note beats.
|
|
356
391
|
* @example
|
|
357
392
|
* ```ts
|
|
358
|
-
* import {
|
|
359
|
-
* pulseBeats(
|
|
393
|
+
* import { pulseBeats } from '@libraz/libcantus';
|
|
394
|
+
* pulseBeats('6/8'); // 1.5
|
|
360
395
|
* ```
|
|
361
396
|
* @category Rhythm & Meter
|
|
362
397
|
*/
|
|
363
|
-
declare function pulseBeats(ts:
|
|
398
|
+
declare function pulseBeats(ts: MeterLike): number;
|
|
364
399
|
/**
|
|
365
400
|
* The felt-beat number of a bar position, 1-based.
|
|
366
401
|
*
|
|
@@ -391,11 +426,16 @@ declare function barPositionToPulse(pos: BarPosition, meter: MeterLike): number;
|
|
|
391
426
|
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
392
427
|
* @param meter A single signature, or the piece's meter map.
|
|
393
428
|
* @param decimals Digits of the fractional beat to keep.
|
|
394
|
-
* @returns The formatted position
|
|
429
|
+
* @returns The formatted position in one of two forms: `bar.beat` on a felt
|
|
430
|
+
* beat, e.g. `'3.2'` for bar 3, felt beat 2; and `bar.beat+fraction` between
|
|
431
|
+
* felt beats, e.g. `'3.2+0.5'` halfway from the second felt beat to the third.
|
|
432
|
+
* A reader of these strings has to take both, since most onsets of an ordinary
|
|
433
|
+
* piece fall between pulses.
|
|
395
434
|
* @example
|
|
396
435
|
* ```ts
|
|
397
436
|
* import { formatBarPosition, parseTimeSignature } from '@libraz/libcantus';
|
|
398
437
|
* formatBarPosition(7.5, parseTimeSignature('6/8')); // '3.2'
|
|
438
|
+
* formatBarPosition(8.25, parseTimeSignature('6/8')); // '3.2+0.5'
|
|
399
439
|
* ```
|
|
400
440
|
* @category Rhythm & Meter
|
|
401
441
|
*/
|
|
@@ -425,7 +465,7 @@ declare function barPositionToBeat(pos: BarPosition, meter: MeterLike): number;
|
|
|
425
465
|
* an ungrouped bar rather than accenting every group head.
|
|
426
466
|
*
|
|
427
467
|
* Given a meter map, the weight follows the signature in force at that beat, so
|
|
428
|
-
* beat
|
|
468
|
+
* beat 2 of a piece is a mid-bar accent in 4/4 and a plain main pulse in 3/4.
|
|
429
469
|
* The downbeat is beat 0 however much pickup precedes it, so a note in the
|
|
430
470
|
* pickup weighs as the upbeat it is rather than as a downbeat.
|
|
431
471
|
*
|