@libraz/libcantus 0.9.5 → 1.0.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 +61 -270
- package/README_ja.md +61 -214
- package/dist/analyze/index.cjs +54 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +200 -353
- package/dist/analyze/index.d.ts +200 -353
- package/dist/analyze/index.js +56 -9
- package/dist/chunk-3JXCW6DX.cjs +3220 -0
- package/dist/chunk-3JXCW6DX.cjs.map +1 -0
- package/dist/chunk-4A2RMUCC.js +7647 -0
- package/dist/chunk-4A2RMUCC.js.map +1 -0
- package/dist/chunk-6XPTBE7Y.cjs +49 -0
- package/dist/chunk-6XPTBE7Y.cjs.map +1 -0
- package/dist/chunk-AFM2ULJH.cjs +5121 -0
- package/dist/chunk-AFM2ULJH.cjs.map +1 -0
- package/dist/chunk-E3F4AHAH.cjs +690 -0
- package/dist/chunk-E3F4AHAH.cjs.map +1 -0
- package/dist/{chunk-2PTFGVD7.js → chunk-ELCTZUJJ.js} +250 -132
- package/dist/chunk-ELCTZUJJ.js.map +1 -0
- package/dist/chunk-FVSI36UV.js +690 -0
- package/dist/chunk-FVSI36UV.js.map +1 -0
- package/dist/chunk-GEDTJHAC.cjs +1 -0
- package/dist/chunk-GEDTJHAC.cjs.map +1 -0
- package/dist/chunk-GOZG57ER.js +3220 -0
- package/dist/chunk-GOZG57ER.js.map +1 -0
- package/dist/chunk-H3VORETI.js +2243 -0
- package/dist/chunk-H3VORETI.js.map +1 -0
- package/dist/chunk-H42UHPYW.js +1577 -0
- package/dist/chunk-H42UHPYW.js.map +1 -0
- package/dist/chunk-HFPS7JFD.js +1 -0
- package/dist/chunk-INHVXP6Z.js +3053 -0
- package/dist/chunk-INHVXP6Z.js.map +1 -0
- package/dist/chunk-K4ZJUGF4.cjs +379 -0
- package/dist/chunk-K4ZJUGF4.cjs.map +1 -0
- package/dist/chunk-KNJEKLKV.js +49 -0
- package/dist/chunk-KNJEKLKV.js.map +1 -0
- package/dist/chunk-M4CWTJWJ.cjs +7647 -0
- package/dist/chunk-M4CWTJWJ.cjs.map +1 -0
- package/dist/chunk-MXO72PLY.cjs +211 -0
- package/dist/chunk-MXO72PLY.cjs.map +1 -0
- package/dist/chunk-NLEU4QSE.cjs +360 -0
- package/dist/chunk-NLEU4QSE.cjs.map +1 -0
- package/dist/chunk-OE6WK2Y2.cjs +1577 -0
- package/dist/chunk-OE6WK2Y2.cjs.map +1 -0
- package/dist/chunk-Q2WGKJNN.cjs +1064 -0
- package/dist/chunk-Q2WGKJNN.cjs.map +1 -0
- package/dist/chunk-QYQQ5J6E.js +1 -0
- package/dist/chunk-QYQQ5J6E.js.map +1 -0
- package/dist/chunk-RHIJ3S4I.cjs +1 -0
- package/dist/chunk-RHIJ3S4I.cjs.map +1 -0
- package/dist/chunk-TTCLJX6D.js +211 -0
- package/dist/chunk-TTCLJX6D.js.map +1 -0
- package/dist/chunk-UADYAYAT.cjs +3053 -0
- package/dist/chunk-UADYAYAT.cjs.map +1 -0
- package/dist/chunk-VOHZB45S.js +5121 -0
- package/dist/chunk-VOHZB45S.js.map +1 -0
- package/dist/chunk-VTI6FOLB.js +1064 -0
- package/dist/chunk-VTI6FOLB.js.map +1 -0
- package/dist/chunk-WWURE4XT.cjs +2243 -0
- package/dist/chunk-WWURE4XT.cjs.map +1 -0
- package/dist/chunk-YH3BIKHH.js +360 -0
- package/dist/chunk-YH3BIKHH.js.map +1 -0
- package/dist/core/index.cjs +93 -6
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +87 -346
- package/dist/core/index.d.ts +87 -346
- package/dist/core/index.js +94 -7
- package/dist/generate/index.cjs +89 -10
- package/dist/generate/index.cjs.map +1 -1
- package/dist/generate/index.d.cts +436 -1094
- package/dist/generate/index.d.ts +436 -1094
- package/dist/generate/index.js +94 -15
- package/dist/index-9wcMhG73.d.ts +1095 -0
- package/dist/{index-Cfx8xgH0.d.ts → index-B4o55NDr.d.cts} +13 -9
- package/dist/index-B9MNZboQ.d.cts +770 -0
- package/dist/index-B9MNZboQ.d.ts +770 -0
- package/dist/index-BGFW-8P2.d.cts +2307 -0
- package/dist/index-BO6xE9YU.d.cts +1804 -0
- package/dist/index-BkGmlyI3.d.cts +470 -0
- package/dist/index-CCNJRG-P.d.cts +1095 -0
- package/dist/index-CGpRv5sl.d.cts +643 -0
- package/dist/index-C_8o--VE.d.cts +1242 -0
- package/dist/index-CgHqxdps.d.ts +2307 -0
- package/dist/index-Chbst3Jx.d.ts +1343 -0
- package/dist/index-Cj49F892.d.ts +470 -0
- package/dist/{index-x2vcsduE.d.cts → index-CunYKLiu.d.ts} +13 -9
- package/dist/index-D57QRbVn.d.ts +1804 -0
- package/dist/index-DInQqT8Q.d.cts +66 -0
- package/dist/index-DInQqT8Q.d.ts +66 -0
- package/dist/index-Dzr13q3d.d.cts +1343 -0
- package/dist/index-G1uwGGWQ.d.ts +643 -0
- package/dist/index-szBv3496.d.ts +1242 -0
- package/dist/index.cjs +348 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -15
- package/dist/index.d.ts +17 -15
- package/dist/index.js +397 -64
- package/dist/masks-DYbE485J.d.cts +445 -0
- package/dist/masks-DYbE485J.d.ts +445 -0
- package/dist/model/index.cjs +39 -7
- package/dist/model/index.cjs.map +1 -1
- package/dist/model/index.d.cts +4659 -249
- package/dist/model/index.d.ts +4659 -249
- package/dist/model/index.js +40 -8
- package/dist/positional-Cptlj-xs.d.ts +287 -0
- package/dist/positional-DvH_sd8u.d.cts +287 -0
- package/dist/theory/index.cjs +101 -7
- package/dist/theory/index.cjs.map +1 -1
- package/dist/theory/index.d.cts +511 -171
- package/dist/theory/index.d.ts +511 -171
- package/dist/theory/index.js +118 -24
- package/package.json +6 -4
- package/dist/chunk-2A2QMA74.cjs +0 -261
- package/dist/chunk-2A2QMA74.cjs.map +0 -1
- package/dist/chunk-2PTFGVD7.js.map +0 -1
- package/dist/chunk-357ZDPVU.cjs +0 -162
- package/dist/chunk-357ZDPVU.cjs.map +0 -1
- package/dist/chunk-3KX76RLG.js +0 -1548
- package/dist/chunk-3KX76RLG.js.map +0 -1
- package/dist/chunk-4VZ5MZAM.cjs +0 -889
- package/dist/chunk-4VZ5MZAM.cjs.map +0 -1
- package/dist/chunk-7EONYVI5.js +0 -1204
- package/dist/chunk-7EONYVI5.js.map +0 -1
- package/dist/chunk-7JEP3MFY.js +0 -162
- package/dist/chunk-7JEP3MFY.js.map +0 -1
- package/dist/chunk-AID75RN3.js +0 -3176
- package/dist/chunk-AID75RN3.js.map +0 -1
- package/dist/chunk-BSLTLGM3.cjs +0 -497
- package/dist/chunk-BSLTLGM3.cjs.map +0 -1
- package/dist/chunk-CU6VG2YM.cjs +0 -109
- package/dist/chunk-CU6VG2YM.cjs.map +0 -1
- package/dist/chunk-DZMHIGI4.js +0 -337
- package/dist/chunk-DZMHIGI4.js.map +0 -1
- package/dist/chunk-EDOTEABK.js +0 -109
- package/dist/chunk-EDOTEABK.js.map +0 -1
- package/dist/chunk-HN2OEUN2.js +0 -33
- package/dist/chunk-HN2OEUN2.js.map +0 -1
- package/dist/chunk-KBTTEX7Q.js +0 -497
- package/dist/chunk-KBTTEX7Q.js.map +0 -1
- package/dist/chunk-KQN2ZYND.cjs +0 -724
- package/dist/chunk-KQN2ZYND.cjs.map +0 -1
- package/dist/chunk-MPTVJIVG.cjs +0 -3176
- package/dist/chunk-MPTVJIVG.cjs.map +0 -1
- package/dist/chunk-MTMZTMWM.cjs +0 -53
- package/dist/chunk-MTMZTMWM.cjs.map +0 -1
- package/dist/chunk-N6IHQUOX.js +0 -1
- package/dist/chunk-NNB67XA2.js +0 -724
- package/dist/chunk-NNB67XA2.js.map +0 -1
- package/dist/chunk-OL3IHHSJ.cjs +0 -1204
- package/dist/chunk-OL3IHHSJ.cjs.map +0 -1
- package/dist/chunk-PI3UXRWK.cjs +0 -528
- package/dist/chunk-PI3UXRWK.cjs.map +0 -1
- package/dist/chunk-R2VVFAIN.js +0 -528
- package/dist/chunk-R2VVFAIN.js.map +0 -1
- package/dist/chunk-T64C7ZD7.cjs +0 -1
- package/dist/chunk-T64C7ZD7.cjs.map +0 -1
- package/dist/chunk-WFDXOLUB.cjs +0 -337
- package/dist/chunk-WFDXOLUB.cjs.map +0 -1
- package/dist/chunk-WTAN4ACG.cjs +0 -1548
- package/dist/chunk-WTAN4ACG.cjs.map +0 -1
- package/dist/chunk-YFJXS3AU.cjs +0 -33
- package/dist/chunk-YFJXS3AU.cjs.map +0 -1
- package/dist/chunk-YUE6TJ4M.js +0 -889
- package/dist/chunk-YUE6TJ4M.js.map +0 -1
- package/dist/chunk-ZGLJM4A4.js +0 -53
- package/dist/chunk-ZGLJM4A4.js.map +0 -1
- package/dist/function-CxixTB02.d.cts +0 -299
- package/dist/function-DTCt675z.d.ts +0 -299
- package/dist/index-B2Ulxxpo.d.cts +0 -144
- package/dist/index-BkYJ0xMq.d.cts +0 -152
- package/dist/index-BuaB-ypt.d.ts +0 -144
- package/dist/index-CAN7v-kw.d.ts +0 -199
- package/dist/index-COw1Ky9g.d.ts +0 -242
- package/dist/index-DRtIhlJj.d.ts +0 -152
- package/dist/index-DXd9JikN.d.cts +0 -246
- package/dist/index-DXd9JikN.d.ts +0 -246
- package/dist/index-alrRninU.d.cts +0 -199
- package/dist/index-oTQbYYIs.d.cts +0 -242
- package/dist/index-tR9jTn26.d.cts +0 -275
- package/dist/index-tR9jTn26.d.ts +0 -275
- package/dist/styled-Bl0ZK28h.d.ts +0 -543
- package/dist/styled-Crv6SA4S.d.cts +0 -543
- package/dist/types-BN6_Q9Kl.d.cts +0 -39
- package/dist/types-BN6_Q9Kl.d.ts +0 -39
- /package/dist/{chunk-N6IHQUOX.js.map → chunk-HFPS7JFD.js.map} +0 -0
|
@@ -1,299 +0,0 @@
|
|
|
1
|
-
import { K as KeyScale } from './types-BN6_Q9Kl.js';
|
|
2
|
-
import { C as Chord } from './index-COw1Ky9g.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Borrowed chords (modal interchange) and the Neapolitan.
|
|
6
|
-
*
|
|
7
|
-
* Roots are pitch classes measured against the key tonic, so borrowed and
|
|
8
|
-
* chromatic chords are handled by their semitone offset rather than requiring a
|
|
9
|
-
* spelled key signature.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* The origin of a recognized non-diatonic chord, or null when none applies.
|
|
14
|
-
*
|
|
15
|
-
* @category Functional Harmony
|
|
16
|
-
*/
|
|
17
|
-
type BorrowedSource = 'parallelMinor' | 'parallelMajor' | 'neapolitan' | null;
|
|
18
|
-
/**
|
|
19
|
-
* Whether a chord is borrowed from the parallel mode (modal interchange).
|
|
20
|
-
*
|
|
21
|
-
* True when the chord is not diatonic to `key` but is diatonic to its
|
|
22
|
-
* {@link parallelKey} — e.g. iv, bVI, or bVII in a major key, or the Picardy
|
|
23
|
-
* tonic and major IV in a minor key. Two non-diatonic families are excluded:
|
|
24
|
-
* chords diatonic to neither mode (they are chromatic, not borrowed), and, in
|
|
25
|
-
* a minor key, chords explained by the altered minor forms (the major
|
|
26
|
-
* dominant and raised-leading-tone chords), which are in-key alterations
|
|
27
|
-
* rather than interchange even though they happen to fit the parallel major.
|
|
28
|
-
*
|
|
29
|
-
* @param chord The chord to test.
|
|
30
|
-
* @param key The prevailing key.
|
|
31
|
-
* @returns True if the chord is borrowed from the parallel mode.
|
|
32
|
-
* @category Functional Harmony
|
|
33
|
-
*/
|
|
34
|
-
declare function isBorrowedChord(chord: Chord, key: KeyScale): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Identify where a non-diatonic chord comes from.
|
|
37
|
-
*
|
|
38
|
-
* The Neapolitan (major triad on b2) is recognized first, since it sits
|
|
39
|
-
* outside both parallel modes; parallel-mode borrowing follows the
|
|
40
|
-
* {@link isBorrowedChord} rules. Diatonic chords and altered-minor chords,
|
|
41
|
-
* and unrecognized chromatic chords all yield null.
|
|
42
|
-
*
|
|
43
|
-
* @param chord The chord to classify.
|
|
44
|
-
* @param key The prevailing key.
|
|
45
|
-
* @returns The borrowing source, or null.
|
|
46
|
-
* @category Functional Harmony
|
|
47
|
-
*/
|
|
48
|
-
declare function borrowedSource(chord: Chord, key: KeyScale): BorrowedSource;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Cadence detection between two successive chords.
|
|
52
|
-
*
|
|
53
|
-
* Roots are pitch classes measured against the key tonic, so borrowed and
|
|
54
|
-
* chromatic chords are handled by their semitone offset rather than requiring a
|
|
55
|
-
* spelled key signature.
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* A recognized cadence type, or null when a chord pair forms none.
|
|
60
|
-
*
|
|
61
|
-
* @category Functional Harmony
|
|
62
|
-
*/
|
|
63
|
-
type Cadence = 'authentic' | 'plagal' | 'half' | 'deceptive' | null;
|
|
64
|
-
/**
|
|
65
|
-
* Classify the cadence formed by moving from one chord to the next.
|
|
66
|
-
*
|
|
67
|
-
* - authentic: V (dominant a fifth above the tonic) to I
|
|
68
|
-
* - plagal: IV (a fourth above the tonic) to I
|
|
69
|
-
* - deceptive: V to the submediant (diatonic vi or borrowed bVI in major, VI in
|
|
70
|
-
* minor)
|
|
71
|
-
* - half: any chord other than the dominant itself to V
|
|
72
|
-
*
|
|
73
|
-
* A static V-to-V repeat with no root motion is not a cadence and yields null.
|
|
74
|
-
*
|
|
75
|
-
* @param from The penultimate chord.
|
|
76
|
-
* @param to The final chord.
|
|
77
|
-
* @param key The prevailing key.
|
|
78
|
-
* @returns The cadence type, or null.
|
|
79
|
-
* @example
|
|
80
|
-
* ```ts
|
|
81
|
-
* import { detectCadence, makeChord, majorKey } from '@libraz/libcantus';
|
|
82
|
-
* detectCadence(makeChord(7, 'maj'), makeChord(0, 'maj'), majorKey(0)); // => 'authentic'
|
|
83
|
-
* ```
|
|
84
|
-
* @category Functional Harmony
|
|
85
|
-
*/
|
|
86
|
-
declare function detectCadence(from: Chord, to: Chord, key: KeyScale): Cadence;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Roman-numeral parsing and formatting.
|
|
90
|
-
*
|
|
91
|
-
* The {@link ROMAN_STYLE} table is the single source of truth for both
|
|
92
|
-
* directions, so {@link chordToRoman} and {@link romanToChord} stay mutual
|
|
93
|
-
* inverses by construction.
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Build the chord denoted by a Roman numeral in a key.
|
|
98
|
-
*
|
|
99
|
-
* Supports accidentals (`bVII`, `#iv`), case-based triad quality, the `o`/`ø`/`+`
|
|
100
|
-
* suffixes, sevenths (`V7`, `viio7`, `Imaj7`), figured-bass inversions
|
|
101
|
-
* (`V6`, `V64`, `V65`, `V43`, `V42`), and applied/secondary chords via a slash
|
|
102
|
-
* (`V7/V`, `viio/ii`). The target after the slash is read as a scale degree
|
|
103
|
-
* whose root becomes a local major tonic for the applied chord. Inverted chords
|
|
104
|
-
* carry a `bassPc`.
|
|
105
|
-
*
|
|
106
|
-
* The `ø` glyph always denotes the half-diminished seventh (`iiø` == `iiø7` ==
|
|
107
|
-
* `m7b5`), since no half-diminished triad exists. Extension and added-tone
|
|
108
|
-
* suffixes are the canonical case-sensitive forms emitted by
|
|
109
|
-
* {@link chordToRoman} and honor the numeral case: `V9` -> `dom9`, `ii9` ->
|
|
110
|
-
* `min9`, `Imaj9` -> `maj9`, `V11` -> `11`, `V13` -> `13`, `Iadd6`/`iadd6` ->
|
|
111
|
-
* `6`/`min6`, `I69` -> `6/9`, `Isus2`/`Isus4`, `Iadd9`/`Iadd11`, `Ib5` ->
|
|
112
|
-
* `majb5`, `I5` -> `5`, and the altered dominants `V7b9`/`V7#9`/`V7#11`/`V7b13`.
|
|
113
|
-
* A figure string that is neither a recognized inversion nor a supported
|
|
114
|
-
* quality suffix throws rather than silently degrading to a triad.
|
|
115
|
-
*
|
|
116
|
-
* @param text The Roman numeral.
|
|
117
|
-
* @param key The prevailing key.
|
|
118
|
-
* @returns The chord.
|
|
119
|
-
* @example
|
|
120
|
-
* ```ts
|
|
121
|
-
* import { romanToChord, majorKey } from '@libraz/libcantus';
|
|
122
|
-
* romanToChord('V7', majorKey(0)); // G7 in C major: { rootPc: 7, quality: 'dom7', ... }
|
|
123
|
-
* ```
|
|
124
|
-
* @category Functional Harmony
|
|
125
|
-
*/
|
|
126
|
-
declare function romanToChord(text: string, key: KeyScale): Chord;
|
|
127
|
-
/**
|
|
128
|
-
* Options for {@link chordToRoman}.
|
|
129
|
-
*
|
|
130
|
-
* @category Functional Harmony
|
|
131
|
-
*/
|
|
132
|
-
type ChordToRomanOptions = {
|
|
133
|
-
/**
|
|
134
|
-
* Render a tonicizing chord as an applied numeral (`V7/V`, `viio7/ii`)
|
|
135
|
-
* instead of naming its root against the home key (`II7`, `#ivo7`).
|
|
136
|
-
*
|
|
137
|
-
* Off by default: naming the root is always a correct spelling, whereas
|
|
138
|
-
* whether a chromatic dominant is genuinely applied is a reading only the
|
|
139
|
-
* caller can make. Turning it on makes {@link chordToRoman} the exact inverse
|
|
140
|
-
* of {@link romanToChord} for the chords {@link secondaryDominant} builds.
|
|
141
|
-
*/
|
|
142
|
-
applied?: boolean;
|
|
143
|
-
};
|
|
144
|
-
/**
|
|
145
|
-
* Render a chord as a Roman numeral relative to a key.
|
|
146
|
-
*
|
|
147
|
-
* Diatonic roots take their scale-degree numeral directly, so numerals are
|
|
148
|
-
* correct in both major and minor keys (and any custom scale). The quality
|
|
149
|
-
* selects the case and suffix; chromatic roots receive a flat/sharp spelling by
|
|
150
|
-
* convention. A key that is not heptatonic has no numeral of its own for every
|
|
151
|
-
* degree, so its roots are named against its parallel major.
|
|
152
|
-
*
|
|
153
|
-
* When the chord carries a `bassPc` on a chord tone, a figured-bass inversion
|
|
154
|
-
* (`6`, `64`, `65`, `43`, `42`) is emitted for plain triads and true seventh
|
|
155
|
-
* chords; added-tone and extended qualities have no lossless figure and render
|
|
156
|
-
* in root position instead (the bass is dropped, pitch classes are preserved).
|
|
157
|
-
*
|
|
158
|
-
* A `bassPc` that is *not* a chord tone — a pedal or passing bass such as
|
|
159
|
-
* `C/D` — is likewise dropped, and the numeral names the upper chord alone.
|
|
160
|
-
* Roman-numeral notation spends its slash on applied chords (`V7/V`), so there
|
|
161
|
-
* is no unambiguous way to write such a bass; a caller that must keep it should
|
|
162
|
-
* read `chord.bassPc` alongside the numeral.
|
|
163
|
-
*
|
|
164
|
-
* @param chord The chord to name.
|
|
165
|
-
* @param key The prevailing key.
|
|
166
|
-
* @param opts `applied` renders tonicizing chords as `V7/V`-style numerals.
|
|
167
|
-
* @returns The Roman numeral string.
|
|
168
|
-
* @example
|
|
169
|
-
* ```ts
|
|
170
|
-
* import { chordToRoman, makeChord, majorKey } from '@libraz/libcantus';
|
|
171
|
-
* chordToRoman(makeChord(7, 'dom7'), majorKey(0)); // => 'V7' (G7 in C major)
|
|
172
|
-
* chordToRoman(makeChord(2, 'dom7'), majorKey(0), { applied: true }); // => 'V7/V'
|
|
173
|
-
* ```
|
|
174
|
-
* @category Functional Harmony
|
|
175
|
-
*/
|
|
176
|
-
declare function chordToRoman(chord: Chord, key: KeyScale, opts?: ChordToRomanOptions): string;
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Harmonic function (tonic / subdominant / dominant), diatonicity, parallel-key
|
|
180
|
-
* mirroring, and full chord analysis.
|
|
181
|
-
*
|
|
182
|
-
* Roots are pitch classes measured against the key tonic, so borrowed and
|
|
183
|
-
* chromatic chords are handled by their semitone offset rather than requiring a
|
|
184
|
-
* spelled key signature.
|
|
185
|
-
*/
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* The three broad harmonic functions of tonal music.
|
|
189
|
-
*
|
|
190
|
-
* @category Functional Harmony
|
|
191
|
-
*/
|
|
192
|
-
type HarmonicFunction = 'tonic' | 'subdominant' | 'dominant';
|
|
193
|
-
/**
|
|
194
|
-
* Whether a key's scale has a minor third and no major third (a minor key).
|
|
195
|
-
*
|
|
196
|
-
* @category Functional Harmony
|
|
197
|
-
*/
|
|
198
|
-
declare function isMinorKey(key: KeyScale): boolean;
|
|
199
|
-
/**
|
|
200
|
-
* The harmonic function of a chord in a key.
|
|
201
|
-
*
|
|
202
|
-
* The root's offset above the tonic gives the baseline mapping, which follows
|
|
203
|
-
* common-practice major-key function and is a useful approximation in minor and
|
|
204
|
-
* for borrowed chords. Chord quality then refines it where the sonority settles
|
|
205
|
-
* an ambiguity the root offset cannot:
|
|
206
|
-
*
|
|
207
|
-
* - A chord that *sounds* like a dominant — a major third with a minor seventh,
|
|
208
|
-
* or a diminished-family chord — and is not diatonic to the key has dominant
|
|
209
|
-
* function when its root resolves down a fifth or by a semitone onto a
|
|
210
|
-
* diatonic degree. This is what makes an applied dominant (`A7` in C, which
|
|
211
|
-
* tonicizes ii) and its tritone substitute (`Db7`) read as dominant rather
|
|
212
|
-
* than inheriting the function of the degree they happen to sit on.
|
|
213
|
-
* - The Neapolitan is subdominant.
|
|
214
|
-
* - A major triad on bVI or bVII of a major key is subdominant — the borrowed
|
|
215
|
-
* pop cadence chord, distinct from the bVII7 above, which has a seventh and
|
|
216
|
-
* is a dominant sonority.
|
|
217
|
-
*
|
|
218
|
-
* @param chord The chord.
|
|
219
|
-
* @param key The prevailing key.
|
|
220
|
-
* @returns The harmonic function.
|
|
221
|
-
* @example
|
|
222
|
-
* ```ts
|
|
223
|
-
* import { functionOf, makeChord, majorKey } from '@libraz/libcantus';
|
|
224
|
-
* functionOf(makeChord(9, 'dom7'), majorKey(0)); // 'dominant' — A7 tonicizes ii
|
|
225
|
-
* functionOf(makeChord(10, 'maj'), majorKey(0)); // 'subdominant' — borrowed bVII
|
|
226
|
-
* ```
|
|
227
|
-
* @category Functional Harmony
|
|
228
|
-
*/
|
|
229
|
-
declare function functionOf(chord: Chord, key: KeyScale): HarmonicFunction;
|
|
230
|
-
/**
|
|
231
|
-
* The result of {@link analyzeChord}: function, borrowing, and Roman numeral.
|
|
232
|
-
*
|
|
233
|
-
* @category Functional Harmony
|
|
234
|
-
*/
|
|
235
|
-
type ChordAnalysis = {
|
|
236
|
-
function: HarmonicFunction;
|
|
237
|
-
borrowed: boolean;
|
|
238
|
-
source: BorrowedSource;
|
|
239
|
-
roman: string;
|
|
240
|
-
};
|
|
241
|
-
/**
|
|
242
|
-
* Whether every pitch class of a chord belongs to the key's scale.
|
|
243
|
-
*
|
|
244
|
-
* The test is strict against the key's own mode mask: in a natural-minor key
|
|
245
|
-
* the harmonic-minor dominant (major V) is *not* diatonic, since the raised
|
|
246
|
-
* leading tone lies outside the mask. Borrowing predicates treat that case as
|
|
247
|
-
* an in-key alteration separately (see {@link isBorrowedChord}).
|
|
248
|
-
*
|
|
249
|
-
* @param chord The chord to test.
|
|
250
|
-
* @param key The prevailing key.
|
|
251
|
-
* @returns True if all chord pitch classes are scale tones.
|
|
252
|
-
* @category Functional Harmony
|
|
253
|
-
*/
|
|
254
|
-
declare function isDiatonic(chord: Chord, key: KeyScale): boolean;
|
|
255
|
-
/**
|
|
256
|
-
* The parallel key: same tonic, opposite mode.
|
|
257
|
-
*
|
|
258
|
-
* A key with a minor third (natural/harmonic/melodic minor, dorian, phrygian)
|
|
259
|
-
* maps to the parallel major; any other key maps to the parallel natural minor.
|
|
260
|
-
*
|
|
261
|
-
* @param key The key to mirror.
|
|
262
|
-
* @returns The parallel major or natural-minor key on the same tonic.
|
|
263
|
-
* @category Functional Harmony
|
|
264
|
-
*/
|
|
265
|
-
declare function parallelKey(key: KeyScale): KeyScale;
|
|
266
|
-
/**
|
|
267
|
-
* Analyze a chord in a key: harmonic function, borrowing, and Roman numeral.
|
|
268
|
-
*
|
|
269
|
-
* The function is quality-aware (see the predicates behind it), the source
|
|
270
|
-
* follows {@link borrowedSource}, and the numeral comes from
|
|
271
|
-
* {@link chordToRoman}. `borrowed` is true whenever a source is identified —
|
|
272
|
-
* including the Neapolitan, which the stricter parallel-mode predicate
|
|
273
|
-
* {@link isBorrowedChord} does not count.
|
|
274
|
-
*
|
|
275
|
-
* @param chord The chord to analyze.
|
|
276
|
-
* @param key The prevailing key.
|
|
277
|
-
* @param opts Options used when rendering the Roman numeral.
|
|
278
|
-
* @returns The chord analysis.
|
|
279
|
-
* @example
|
|
280
|
-
* ```ts
|
|
281
|
-
* import { analyzeChord, makeChord, majorKey } from '@libraz/libcantus';
|
|
282
|
-
* analyzeChord(makeChord(7, 'dom7'), majorKey(0));
|
|
283
|
-
* // { function: 'dominant', borrowed: false, source: null, roman: 'V7' }
|
|
284
|
-
* ```
|
|
285
|
-
* @category Functional Harmony
|
|
286
|
-
*/
|
|
287
|
-
declare function analyzeChord(chord: Chord, key: KeyScale, opts?: ChordToRomanOptions): ChordAnalysis;
|
|
288
|
-
/**
|
|
289
|
-
* The secondary dominant (V7) that tonicizes a scale degree.
|
|
290
|
-
*
|
|
291
|
-
* @param targetDegree 0-based scale degree to tonicize.
|
|
292
|
-
* @param key The prevailing key.
|
|
293
|
-
* @returns A dominant-seventh chord a fifth above the target's root.
|
|
294
|
-
* @throws If `targetDegree` is not an integer naming a degree in `key`.
|
|
295
|
-
* @category Functional Harmony
|
|
296
|
-
*/
|
|
297
|
-
declare function secondaryDominant(targetDegree: number, key: KeyScale): Chord;
|
|
298
|
-
|
|
299
|
-
export { type BorrowedSource as B, type Cadence as C, type HarmonicFunction as H, type ChordAnalysis as a, type ChordToRomanOptions as b, analyzeChord as c, borrowedSource as d, chordToRoman as e, detectCadence as f, functionOf as g, isDiatonic as h, isBorrowedChord as i, isMinorKey as j, parallelKey as p, romanToChord as r, secondaryDominant as s };
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { K as KeyScale } from './types-BN6_Q9Kl.cjs';
|
|
2
|
-
import { C as Chord } from './index-oTQbYYIs.cjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Severity policy: `strict` counterpoint vs. lenient `pop` voice-leading.
|
|
6
|
-
*
|
|
7
|
-
* @category Arrangement & Analysis
|
|
8
|
-
*/
|
|
9
|
-
type SafetyProfile = 'strict' | 'pop';
|
|
10
|
-
/**
|
|
11
|
-
* Overall placeability verdict for a candidate pitch.
|
|
12
|
-
*
|
|
13
|
-
* @category Arrangement & Analysis
|
|
14
|
-
*/
|
|
15
|
-
declare enum NoteSafety {
|
|
16
|
-
Safe = 0,
|
|
17
|
-
Warning = 1,
|
|
18
|
-
Dissonant = 2
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Bit flags describing why a pitch received its verdict.
|
|
22
|
-
*
|
|
23
|
-
* @category Arrangement & Analysis
|
|
24
|
-
*/
|
|
25
|
-
declare enum ReasonFlag {
|
|
26
|
-
ChordTone = 1,
|
|
27
|
-
Tension = 2,
|
|
28
|
-
AvoidNote = 4,
|
|
29
|
-
ScaleTone = 8,
|
|
30
|
-
NonScale = 16,
|
|
31
|
-
OutOfRange = 32,
|
|
32
|
-
Tritone = 64,
|
|
33
|
-
LargeLeap = 128,
|
|
34
|
-
MinorSecond = 256,
|
|
35
|
-
MajorSeventh = 512,
|
|
36
|
-
VerticalDissonance = 1024,
|
|
37
|
-
ParallelPerfect = 2048,
|
|
38
|
-
HiddenParallel = 4096,
|
|
39
|
-
VoiceCrossing = 8192,
|
|
40
|
-
Suspension = 16384,
|
|
41
|
-
NeedsResolution = 32768,
|
|
42
|
-
MelodicTritone = 65536
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* A neighbouring voice's current and previous pitch.
|
|
46
|
-
*
|
|
47
|
-
* @category Arrangement & Analysis
|
|
48
|
-
*/
|
|
49
|
-
type VoiceSnapshot = {
|
|
50
|
-
pitch: number;
|
|
51
|
-
prevPitch?: number;
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
* Everything needed to evaluate one candidate pitch.
|
|
55
|
-
*
|
|
56
|
-
* @category Arrangement & Analysis
|
|
57
|
-
*/
|
|
58
|
-
type SafetyQuery = {
|
|
59
|
-
profile: SafetyProfile;
|
|
60
|
-
candidatePitch: number;
|
|
61
|
-
prevPitch?: number;
|
|
62
|
-
chord: Chord | null;
|
|
63
|
-
key: KeyScale;
|
|
64
|
-
otherVoices: VoiceSnapshot[];
|
|
65
|
-
strongBeat: boolean;
|
|
66
|
-
vocalLow?: number;
|
|
67
|
-
vocalHigh?: number;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* The verdict, reason flags, and optional resolution guidance.
|
|
71
|
-
*
|
|
72
|
-
* @category Arrangement & Analysis
|
|
73
|
-
*/
|
|
74
|
-
type SafetyResult = {
|
|
75
|
-
safety: NoteSafety;
|
|
76
|
-
reasons: number;
|
|
77
|
-
resolveTo?: number;
|
|
78
|
-
suggestions?: number[];
|
|
79
|
-
rationale?: string;
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Evaluate the safety of placing a candidate pitch in a voice.
|
|
83
|
-
*
|
|
84
|
-
* Reasons are merged from harmonic context (chord tone / tension / avoid / scale)
|
|
85
|
-
* and counterpoint (vertical dissonance, parallels, voice crossing). The `strict`
|
|
86
|
-
* profile treats avoid notes and parallels as dissonant; `pop` treats them as
|
|
87
|
-
* warnings. The final verdict is the worst severity among the reasons.
|
|
88
|
-
*
|
|
89
|
-
* @param q The candidate and its harmonic/voice-leading context.
|
|
90
|
-
* @returns The verdict, reason bitmask, and optional resolution guidance.
|
|
91
|
-
* @example
|
|
92
|
-
* ```ts
|
|
93
|
-
* import { evaluateSafety, makeChord, majorKey, NoteSafety } from '@libraz/libcantus';
|
|
94
|
-
* const result = evaluateSafety({
|
|
95
|
-
* profile: 'pop',
|
|
96
|
-
* candidatePitch: 60, // C over a C major chord
|
|
97
|
-
* chord: makeChord(0, 'maj'),
|
|
98
|
-
* key: majorKey(0),
|
|
99
|
-
* otherVoices: [],
|
|
100
|
-
* strongBeat: true,
|
|
101
|
-
* });
|
|
102
|
-
* result.safety === NoteSafety.Safe; // true — C is a chord tone
|
|
103
|
-
* ```
|
|
104
|
-
* @category Arrangement & Analysis
|
|
105
|
-
*/
|
|
106
|
-
declare function evaluateSafety(q: SafetyQuery, opts?: EvaluateSafetyOptions): SafetyResult;
|
|
107
|
-
/**
|
|
108
|
-
* Options for {@link evaluateSafety}.
|
|
109
|
-
*
|
|
110
|
-
* @category Arrangement & Analysis
|
|
111
|
-
*/
|
|
112
|
-
type EvaluateSafetyOptions = {
|
|
113
|
-
/**
|
|
114
|
-
* Whether to search for safe replacement pitches when the verdict is not
|
|
115
|
-
* safe. Turning it off skips up to two dozen extra evaluations per rejected
|
|
116
|
-
* pitch, which is worth doing when only the verdict is wanted.
|
|
117
|
-
*
|
|
118
|
-
* @defaultValue true
|
|
119
|
-
*/
|
|
120
|
-
suggestions?: boolean;
|
|
121
|
-
};
|
|
122
|
-
/**
|
|
123
|
-
* Enumerate placeable pitches in a range, chord tones first, descending.
|
|
124
|
-
*
|
|
125
|
-
* @param q The safety context minus the candidate pitch.
|
|
126
|
-
* @param pitchLow Lowest MIDI pitch to consider (inclusive).
|
|
127
|
-
* @param pitchHigh Highest MIDI pitch to consider (inclusive).
|
|
128
|
-
* @returns Placeable pitches (non-dissonant), chord tones before others, each group descending.
|
|
129
|
-
* @throws If either bound is non-finite/non-integral, reversed, or exceeds the generation budget.
|
|
130
|
-
* @example
|
|
131
|
-
* ```ts
|
|
132
|
-
* import { enumerateSafePitches, makeChord, majorKey } from '@libraz/libcantus';
|
|
133
|
-
* const pitches = enumerateSafePitches(
|
|
134
|
-
* { profile: 'pop', chord: makeChord(0, 'maj'), key: majorKey(0), otherVoices: [], strongBeat: true },
|
|
135
|
-
* 60,
|
|
136
|
-
* 72,
|
|
137
|
-
* );
|
|
138
|
-
* pitches; // placeable pitches in [60, 72], chord tones first, each group descending
|
|
139
|
-
* ```
|
|
140
|
-
* @category Arrangement & Analysis
|
|
141
|
-
*/
|
|
142
|
-
declare function enumerateSafePitches(q: Omit<SafetyQuery, 'candidatePitch'>, pitchLow: number, pitchHigh: number): number[];
|
|
143
|
-
|
|
144
|
-
export { type EvaluateSafetyOptions as E, NoteSafety as N, ReasonFlag as R, type SafetyProfile as S, type VoiceSnapshot as V, type SafetyQuery as a, type SafetyResult as b, evaluateSafety as c, enumerateSafePitches as e };
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { T as TimeSignature } from './index-DXd9JikN.cjs';
|
|
2
|
-
import { K as KeyScale, N as NoteEvent } from './types-BN6_Q9Kl.cjs';
|
|
3
|
-
import { C as Chord, b as ChordSegment, c as ChordSpan } from './index-oTQbYYIs.cjs';
|
|
4
|
-
import { C as Cadence } from './function-CxixTB02.cjs';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A beat-indexed sequence of chord segments.
|
|
8
|
-
*
|
|
9
|
-
* @category Arrangement & Analysis
|
|
10
|
-
*/
|
|
11
|
-
type ChordTimeline = {
|
|
12
|
-
/** The chord sounding at a beat, or null when no segment covers it. */
|
|
13
|
-
at: (beat: number) => Chord | null;
|
|
14
|
-
segments: ChordSegment[];
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Build a chord timeline from placed chords.
|
|
18
|
-
*
|
|
19
|
-
* Each chord spans from its `startBeat` to the next chord's `startBeat`; the last
|
|
20
|
-
* chord runs to `totalBeats`. Segments with no positive length (from duplicate
|
|
21
|
-
* onsets or a last chord at or past `totalBeats`) are dropped. `at(beat)` returns
|
|
22
|
-
* the covering segment's chord, or null when the beat lies outside every segment.
|
|
23
|
-
*
|
|
24
|
-
* @param chords Placed chords in time order.
|
|
25
|
-
* @param totalBeats End of the timeline in beats.
|
|
26
|
-
* @returns A queryable chord timeline.
|
|
27
|
-
* @category Arrangement & Analysis
|
|
28
|
-
*/
|
|
29
|
-
declare function chordTimelineFromChords(chords: readonly ChordSpan[], totalBeats: number): ChordTimeline;
|
|
30
|
-
/**
|
|
31
|
-
* Options controlling {@link chordTimelineFromNotes}.
|
|
32
|
-
*
|
|
33
|
-
* @category Arrangement & Analysis
|
|
34
|
-
*/
|
|
35
|
-
type ChordTimelineOptions = {
|
|
36
|
-
/** Key context; inferred from the notes with {@link detectKeyFromNotes} when omitted. */
|
|
37
|
-
key?: KeyScale;
|
|
38
|
-
/**
|
|
39
|
-
* Time signature used for metric accents; defaults to 4/4.
|
|
40
|
-
*
|
|
41
|
-
* @defaultValue `4/4`
|
|
42
|
-
*/
|
|
43
|
-
ts?: TimeSignature;
|
|
44
|
-
/**
|
|
45
|
-
* Window length in beats per chord slot; defaults to one bar of `ts`.
|
|
46
|
-
*
|
|
47
|
-
* @defaultValue one bar of `ts`
|
|
48
|
-
*/
|
|
49
|
-
harmonicRhythm?: number;
|
|
50
|
-
/**
|
|
51
|
-
* End of the analyzed span in beats; defaults to the end of the last note.
|
|
52
|
-
*
|
|
53
|
-
* @defaultValue the end of the last note
|
|
54
|
-
*/
|
|
55
|
-
totalBeats?: number;
|
|
56
|
-
/**
|
|
57
|
-
* Upper bound on the work this call may do — note counts, windows, and
|
|
58
|
-
* candidate counts are each checked against it before anything is allocated.
|
|
59
|
-
*
|
|
60
|
-
* Raise it to analyse a piece larger than the default allows; the default is
|
|
61
|
-
* {@link DEFAULT_GENERATION_BUDGET}, chosen so a runaway input fails fast
|
|
62
|
-
* rather than blocking the thread.
|
|
63
|
-
*
|
|
64
|
-
* @defaultValue {@link DEFAULT_GENERATION_BUDGET}
|
|
65
|
-
*/
|
|
66
|
-
budget?: number;
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* The result of {@link chordTimelineFromNotes}.
|
|
70
|
-
*
|
|
71
|
-
* @category Arrangement & Analysis
|
|
72
|
-
*/
|
|
73
|
-
type ChordTimelineResult = {
|
|
74
|
-
/** The inferred timeline, with adjacent identical chords merged. */
|
|
75
|
-
timeline: ChordTimeline;
|
|
76
|
-
/** The key used for the analysis (given or inferred). */
|
|
77
|
-
key: KeyScale;
|
|
78
|
-
/** One confidence value in [0, 1] per segment, in segment order. */
|
|
79
|
-
segmentConfidence: number[];
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Infer a chord timeline from raw multi-track notes.
|
|
83
|
-
*
|
|
84
|
-
* The span `[0, totalBeats)` is sliced into `harmonicRhythm`-beat windows; each
|
|
85
|
-
* window's chord is inferred from a pitch-class weight histogram of the notes
|
|
86
|
-
* overlapping it (weight = overlap duration x velocity x metric-accent bonus
|
|
87
|
-
* for onsets in the window). Adjacent windows carrying the identical chord are
|
|
88
|
-
* merged into one segment; windows with no notes produce no segment, so
|
|
89
|
-
* `at(beat)` returns null there. Each segment carries a confidence in [0, 1]:
|
|
90
|
-
* the fraction of the window weight explained by chord tones, reduced when the
|
|
91
|
-
* match is inexact, and duration-weighted across merged windows.
|
|
92
|
-
*
|
|
93
|
-
* Notes with a zero or negative duration never sound, so they are dropped at
|
|
94
|
-
* ingest: they contribute to neither the key inference, the span, nor any
|
|
95
|
-
* window's histogram.
|
|
96
|
-
*
|
|
97
|
-
* @param notes The notes to analyze (any number of tracks, flattened).
|
|
98
|
-
* @param opts Analysis options; see {@link ChordTimelineOptions}.
|
|
99
|
-
* @returns The inferred timeline, the key used, and per-segment confidences.
|
|
100
|
-
* @throws If `harmonicRhythm` is not positive.
|
|
101
|
-
* @example
|
|
102
|
-
* ```ts
|
|
103
|
-
* import { chordTimelineFromNotes } from '@libraz/libcantus';
|
|
104
|
-
* const notes = [
|
|
105
|
-
* { pitch: 60, startBeat: 0, durationBeat: 2 }, // C
|
|
106
|
-
* { pitch: 64, startBeat: 0, durationBeat: 2 }, // E
|
|
107
|
-
* { pitch: 67, startBeat: 0, durationBeat: 2 }, // G
|
|
108
|
-
* ];
|
|
109
|
-
* const { timeline, key } = chordTimelineFromNotes(notes);
|
|
110
|
-
* timeline.at(0); // the chord inferred over beat 0, or null
|
|
111
|
-
* ```
|
|
112
|
-
* @category Arrangement & Analysis
|
|
113
|
-
*/
|
|
114
|
-
declare function chordTimelineFromNotes(notes: NoteEvent[], opts?: ChordTimelineOptions): ChordTimelineResult;
|
|
115
|
-
/**
|
|
116
|
-
* A cadence found between two consecutive timeline segments.
|
|
117
|
-
*
|
|
118
|
-
* @category Arrangement & Analysis
|
|
119
|
-
*/
|
|
120
|
-
type CadenceHit = {
|
|
121
|
-
/** The beat where the cadence arrives (the second chord's onset). */
|
|
122
|
-
atBeat: number;
|
|
123
|
-
type: Exclude<Cadence, null>;
|
|
124
|
-
from: Chord;
|
|
125
|
-
to: Chord;
|
|
126
|
-
};
|
|
127
|
-
/**
|
|
128
|
-
* Find cadences between consecutive segments of a chord timeline.
|
|
129
|
-
*
|
|
130
|
-
* Each temporally adjacent segment pair is classified with
|
|
131
|
-
* {@link detectCadence}; pairs forming no cadence are skipped. Segments
|
|
132
|
-
* separated by a gap (a rest in the timeline) are not a chord-to-chord
|
|
133
|
-
* progression, so they are never paired.
|
|
134
|
-
*
|
|
135
|
-
* @param timeline The chord timeline to scan.
|
|
136
|
-
* @param key The prevailing key.
|
|
137
|
-
* @returns The cadences found, in time order.
|
|
138
|
-
* @example
|
|
139
|
-
* ```ts
|
|
140
|
-
* import { chordTimelineFromNotes, detectCadences } from '@libraz/libcantus';
|
|
141
|
-
* const notes = [
|
|
142
|
-
* { pitch: 67, startBeat: 0, durationBeat: 4 }, // G, a dominant
|
|
143
|
-
* { pitch: 60, startBeat: 4, durationBeat: 4 }, // C, the tonic
|
|
144
|
-
* ];
|
|
145
|
-
* const { timeline, key } = chordTimelineFromNotes(notes);
|
|
146
|
-
* const cadences = detectCadences(timeline, key);
|
|
147
|
-
* ```
|
|
148
|
-
* @category Arrangement & Analysis
|
|
149
|
-
*/
|
|
150
|
-
declare function detectCadences(timeline: ChordTimeline, key: KeyScale): CadenceHit[];
|
|
151
|
-
|
|
152
|
-
export { type CadenceHit as C, type ChordTimeline as a, type ChordTimelineOptions as b, type ChordTimelineResult as c, chordTimelineFromChords as d, chordTimelineFromNotes as e, detectCadences as f };
|