@libraz/libcantus 1.0.0 → 1.1.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-TTCLJX6D.js → chunk-57WB2EDF.js} +10 -8
- package/dist/chunk-57WB2EDF.js.map +1 -0
- package/dist/chunk-5JJ6EHEZ.cjs +457 -0
- package/dist/chunk-5JJ6EHEZ.cjs.map +1 -0
- package/dist/{chunk-AFM2ULJH.cjs → chunk-5KW7DNCJ.cjs} +1567 -1067
- package/dist/chunk-5KW7DNCJ.cjs.map +1 -0
- package/dist/chunk-7GOKQJTQ.js +145 -0
- package/dist/chunk-7GOKQJTQ.js.map +1 -0
- package/dist/{chunk-H3VORETI.js → chunk-AWEMD747.js} +487 -592
- package/dist/chunk-AWEMD747.js.map +1 -0
- package/dist/{chunk-4A2RMUCC.js → chunk-DKICR7AN.js} +1216 -611
- package/dist/chunk-DKICR7AN.js.map +1 -0
- package/dist/{chunk-INHVXP6Z.js → chunk-FPBZFNCD.js} +1159 -415
- package/dist/chunk-FPBZFNCD.js.map +1 -0
- package/dist/{chunk-M4CWTJWJ.cjs → chunk-GDKE6RQW.cjs} +1453 -848
- package/dist/chunk-GDKE6RQW.cjs.map +1 -0
- package/dist/chunk-H66ARFU5.js +363 -0
- package/dist/chunk-H66ARFU5.js.map +1 -0
- package/dist/{chunk-YH3BIKHH.js → chunk-HOHFYGKW.js} +146 -49
- package/dist/chunk-HOHFYGKW.js.map +1 -0
- package/dist/chunk-HSY2VQXZ.js +2272 -0
- package/dist/chunk-HSY2VQXZ.js.map +1 -0
- package/dist/{chunk-E3F4AHAH.cjs → chunk-J772DL3B.cjs} +221 -134
- package/dist/chunk-J772DL3B.cjs.map +1 -0
- package/dist/chunk-K6OZXIR6.js +1 -0
- package/dist/{chunk-VTI6FOLB.js → chunk-PQL7E5F6.js} +709 -133
- package/dist/chunk-PQL7E5F6.js.map +1 -0
- package/dist/chunk-Q6R3QAZD.cjs +3329 -0
- package/dist/chunk-Q6R3QAZD.cjs.map +1 -0
- package/dist/{chunk-MXO72PLY.cjs → chunk-QCXYKSZS.cjs} +21 -19
- package/dist/chunk-QCXYKSZS.cjs.map +1 -0
- package/dist/{chunk-VOHZB45S.js → chunk-R5VUXQMP.js} +1321 -821
- package/dist/chunk-R5VUXQMP.js.map +1 -0
- package/dist/chunk-R7B5N2JK.cjs +363 -0
- package/dist/chunk-R7B5N2JK.cjs.map +1 -0
- package/dist/{chunk-WWURE4XT.cjs → chunk-RVS4G4MR.cjs} +624 -729
- package/dist/chunk-RVS4G4MR.cjs.map +1 -0
- package/dist/chunk-TT6PKMPR.cjs +145 -0
- package/dist/chunk-TT6PKMPR.cjs.map +1 -0
- package/dist/chunk-UGLFDG7L.cjs +1 -0
- package/dist/chunk-UGLFDG7L.cjs.map +1 -0
- package/dist/chunk-VLE5R7PF.js +3329 -0
- package/dist/chunk-VLE5R7PF.js.map +1 -0
- package/dist/{chunk-FVSI36UV.js → chunk-X6RJAHII.js} +197 -110
- package/dist/chunk-X6RJAHII.js.map +1 -0
- package/dist/{chunk-Q2WGKJNN.cjs → chunk-XKSO2V5I.cjs} +699 -123
- package/dist/chunk-XKSO2V5I.cjs.map +1 -0
- package/dist/chunk-XVMJO3QF.cjs +2272 -0
- package/dist/chunk-XVMJO3QF.cjs.map +1 -0
- package/dist/{chunk-UADYAYAT.cjs → chunk-YPB3A3EY.cjs} +1309 -565
- package/dist/chunk-YPB3A3EY.cjs.map +1 -0
- package/dist/{index-C_8o--VE.d.cts → coerce-CJlgULrQ.d.cts} +210 -199
- package/dist/{index-szBv3496.d.ts → coerce-wwdELNYS.d.ts} +210 -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-Dzr13q3d.d.cts → index-B3WCj_Hm.d.cts} +135 -58
- package/dist/{index-BO6xE9YU.d.cts → index-BUtIf2go.d.ts} +460 -254
- package/dist/{index-CCNJRG-P.d.cts → index-BaoKVVhE.d.cts} +293 -56
- package/dist/{index-Chbst3Jx.d.ts → index-BpWOhkkE.d.ts} +135 -58
- package/dist/{index-BGFW-8P2.d.cts → index-BzLNkmA7.d.cts} +196 -114
- package/dist/{index-CunYKLiu.d.ts → index-CBCP84rv.d.cts} +1 -1
- package/dist/{index-BkGmlyI3.d.cts → index-Ci3xyows.d.ts} +60 -23
- package/dist/{index-9wcMhG73.d.ts → index-CnHQgqNh.d.ts} +293 -56
- package/dist/{index-B4o55NDr.d.cts → index-CnIdP4EZ.d.ts} +1 -1
- 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-D57QRbVn.d.ts → index-DTsKaPaC.d.cts} +460 -254
- package/dist/{index-Cj49F892.d.ts → index-D_hzxD8w.d.cts} +60 -23
- package/dist/{index-CgHqxdps.d.ts → index-DpC-mDlV.d.ts} +196 -114
- 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.ts → masks-C8TWLFIi.d.cts} +49 -2
- package/dist/{masks-DYbE485J.d.cts → masks-O73Rhj5d.d.ts} +49 -2
- package/dist/model/index.cjs +19 -12
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +502 -181
- package/dist/model/index.d.ts +502 -181
- 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 +6 -5
- package/dist/chunk-3JXCW6DX.cjs +0 -3220
- package/dist/chunk-3JXCW6DX.cjs.map +0 -1
- package/dist/chunk-4A2RMUCC.js.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-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-GOZG57ER.js +0 -3220
- package/dist/chunk-GOZG57ER.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-M4CWTJWJ.cjs.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-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, q as SpelledKeyLike, b as Chord, n as ResolvedKey, j as KeyRelation, e as ChordSegment, V as VoiceSnapshot, g as ChordSpan } from './coerce-wwdELNYS.js';
|
|
2
|
+
import { b as MeterLike } from './index-Ci3xyows.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 };
|