@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,15 +1,156 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { e as KeyScale, g as Note, i as NoteLike } from './index-Cy15oTvh.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The vocabulary a key is described in.
|
|
5
|
+
*
|
|
6
|
+
* Kept in a module of its own, below the masks that define the scale forms, the
|
|
7
|
+
* name reader that produces a key from text, and the coercion that accepts one
|
|
8
|
+
* from a caller. All three name these types and none of them can be the others'
|
|
9
|
+
* home without importing one back.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Which scale form a key stands in.
|
|
13
|
+
*
|
|
14
|
+
* `'modal'` is the honest answer for a key standing in none of the four, and it
|
|
15
|
+
* is an answer rather than an absence.
|
|
16
|
+
*
|
|
17
|
+
* @category Scales
|
|
18
|
+
*/
|
|
19
|
+
type KeyVariant = 'major' | 'natural' | 'harmonic' | 'melodic' | 'modal';
|
|
20
|
+
/**
|
|
21
|
+
* The complete identity of a key: what it sounds, how it is written, and which
|
|
22
|
+
* scale form it stands in.
|
|
23
|
+
*
|
|
24
|
+
* What {@link resolveKey} hands back, and the shape a key is passed on in. Every
|
|
25
|
+
* field is present: a key that reaches here has been read, so there is nothing
|
|
26
|
+
* left undecided about it, and a reader never has to ask whether a missing
|
|
27
|
+
* field means `'modal'` or means nobody looked.
|
|
6
28
|
*
|
|
7
29
|
* @category Scales
|
|
8
30
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
31
|
+
/**
|
|
32
|
+
* A key/scale with the spelling it is conventionally written in beside it.
|
|
33
|
+
*
|
|
34
|
+
* What the key builders hand back. It is a {@link KeyScale} — every reader that
|
|
35
|
+
* wants only the pitch classes takes it unchanged — and it carries the tonic
|
|
36
|
+
* those pitch classes are conventionally written on, so it also satisfies the
|
|
37
|
+
* entry points whose answer depends on how the key is written.
|
|
38
|
+
*
|
|
39
|
+
* Carrying the spelling here is what lets those entry points refuse a bare
|
|
40
|
+
* `KeyScale` without refusing the library's own builders. A bare scale reaching
|
|
41
|
+
* one of them has had a spelling and lost it, which is the defect; a built key
|
|
42
|
+
* never lost one.
|
|
43
|
+
*
|
|
44
|
+
* @category Scales
|
|
45
|
+
*/
|
|
46
|
+
type SpelledKeyScale = KeyScale & {
|
|
47
|
+
/** The tonic the key is conventionally written on. */
|
|
48
|
+
tonic: Note;
|
|
49
|
+
/** The scale form the mask stands in. */
|
|
50
|
+
variant: KeyVariant;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* A key read into the three things every reader of one needs: the pitch
|
|
54
|
+
* classes it is built from, the spelled tonic its letter names are anchored on,
|
|
55
|
+
* and the scale form it stands in.
|
|
56
|
+
*
|
|
57
|
+
* What a key-shaped argument becomes once it has been read, whatever form the
|
|
58
|
+
* caller held it in — a name, a scale, a `Key`. Carrying the tonic beside the
|
|
59
|
+
* scale is what keeps an A flat minor an A flat minor rather than the G sharp
|
|
60
|
+
* minor its pitch classes alone would be spelled back as.
|
|
61
|
+
*
|
|
62
|
+
* @category Scales
|
|
63
|
+
*/
|
|
64
|
+
type ResolvedKey = {
|
|
65
|
+
/** The pitch classes the key is built from. */
|
|
66
|
+
readonly scale: KeyScale;
|
|
67
|
+
/** The spelled tonic every letter name derived from this key is anchored on. */
|
|
68
|
+
readonly tonic: Note;
|
|
69
|
+
/** The scale form the key stands in. */
|
|
70
|
+
readonly variant: KeyVariant;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Anything that names a key: a key name, a plain {@link KeyScale}, the plain
|
|
75
|
+
* data a key serializes to, or a value that serializes to one such as the `Key`
|
|
76
|
+
* class.
|
|
77
|
+
*
|
|
78
|
+
* The plain-data form is here because a project file holds a key that way, and
|
|
79
|
+
* reading one back has to be the same call as passing the class it came from.
|
|
80
|
+
*
|
|
81
|
+
* Deliberately wider than what a resolver hands back: a caller may hand in a
|
|
82
|
+
* bare scale, or data written before the spelling travelled with it, and the
|
|
83
|
+
* resolver fills in what is missing rather than refusing it. Narrowing this to
|
|
84
|
+
* the resolved shape would make the acceptance of every entry point shrink the
|
|
85
|
+
* day the resolved shape gained a field.
|
|
86
|
+
*
|
|
87
|
+
* A scale is accepted with the spelling and the form written beside it as well
|
|
88
|
+
* as without them, because a key region carries its key that way — asked
|
|
89
|
+
* positional questions wherever a plain scale would be. The resolver reads them
|
|
90
|
+
* when they are there, and this says so: a shape a resolver reads and a type
|
|
91
|
+
* denies is one refactoring away from being dropped silently.
|
|
92
|
+
*
|
|
93
|
+
* @category Scales
|
|
94
|
+
*/
|
|
95
|
+
type KeyLike = string | (KeyScale & {
|
|
96
|
+
/** The spelled tonic the key is written with, when it travels beside it. */
|
|
97
|
+
tonic?: Note;
|
|
98
|
+
/** The scale form the key stands in, when it travels beside it. */
|
|
99
|
+
variant?: KeyVariant;
|
|
100
|
+
}) | {
|
|
101
|
+
/** The scale this key data denotes. */
|
|
102
|
+
scale: KeyScale;
|
|
103
|
+
/** The spelled tonic the key is written with, when the caller named one. */
|
|
104
|
+
tonic?: Note;
|
|
105
|
+
/** The scale form the key was read under, when it was read under one. */
|
|
106
|
+
variant?: KeyVariant;
|
|
107
|
+
} | {
|
|
108
|
+
/** The key data this value stands for, carrying everything it knows. */
|
|
109
|
+
toJSON(): {
|
|
110
|
+
scale: KeyScale;
|
|
111
|
+
tonic?: Note;
|
|
112
|
+
variant?: KeyVariant;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* A key that says how it is written, for the entry points whose answer depends
|
|
117
|
+
* on it.
|
|
118
|
+
*
|
|
119
|
+
* The shapes {@link KeyLike} accepts, minus the one that cannot carry a
|
|
120
|
+
* spelling: a bare {@link KeyScale}. An A flat minor and a G sharp minor are one
|
|
121
|
+
* set of pitch classes and two keys, so an entry point whose answer differs
|
|
122
|
+
* between them cannot be handed the shape that does not distinguish them and
|
|
123
|
+
* still be right. Declaring this makes that a compile error rather than a
|
|
124
|
+
* defect found later — and `Key`, `ResolvedKey`, a key name and stored key data
|
|
125
|
+
* all satisfy it, so the narrowing costs a caller nothing it was doing
|
|
126
|
+
* correctly.
|
|
127
|
+
*
|
|
128
|
+
* Which entry points declare this is measured rather than chosen: an entry point
|
|
129
|
+
* belongs here exactly when varying its key argument alone — between the two
|
|
130
|
+
* spellings of one sound — changes its answer. A scale a caller genuinely wants
|
|
131
|
+
* to hand in is spelled first, at the place it happens, which is the same rule
|
|
132
|
+
* the reduction in the other direction already follows.
|
|
133
|
+
*
|
|
134
|
+
* @category Scales
|
|
135
|
+
*/
|
|
136
|
+
type SpelledKeyLike = string | (KeyScale & {
|
|
137
|
+
/** The spelled tonic the key is written with. Required: it is the point. */
|
|
138
|
+
tonic: Note;
|
|
139
|
+
/** The scale form the key stands in, when it travels beside it. */
|
|
140
|
+
variant?: KeyVariant;
|
|
141
|
+
}) | {
|
|
142
|
+
/** The scale this key data denotes. */
|
|
143
|
+
scale: KeyScale;
|
|
144
|
+
/** The spelled tonic the key is written with, when the caller named one. */
|
|
145
|
+
tonic?: Note;
|
|
146
|
+
/** The scale form the key was read under, when it was read under one. */
|
|
147
|
+
variant?: KeyVariant;
|
|
148
|
+
} | {
|
|
149
|
+
/** The key data this value stands for, carrying everything it knows. */
|
|
11
150
|
toJSON(): {
|
|
12
151
|
scale: KeyScale;
|
|
152
|
+
tonic?: Note;
|
|
153
|
+
variant?: KeyVariant;
|
|
13
154
|
};
|
|
14
155
|
};
|
|
15
156
|
/**
|
|
@@ -21,12 +162,12 @@ type KeyLike = string | KeyScale | {
|
|
|
21
162
|
* instance is accepted through its `toJSON` method rather than by its type, so
|
|
22
163
|
* the layers below the model can read a class without importing it.
|
|
23
164
|
*
|
|
24
|
-
* A name is read by {@link
|
|
25
|
-
* that takes a key accepts exactly the names a
|
|
26
|
-
* every notation system
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
165
|
+
* A name is read by the one reader {@link resolveKey} and `Key.parse` also use,
|
|
166
|
+
* so every entry point that takes a key accepts exactly the same names: a mode
|
|
167
|
+
* word in every notation system that reader knows, and a built-in scale's own
|
|
168
|
+
* word — `'D dorian'`, `'D harmonic minor'` — in English.
|
|
169
|
+
* The spelling the name carries is dropped here along with the scale form,
|
|
170
|
+
* which is what {@link resolveKey} is for.
|
|
30
171
|
*
|
|
31
172
|
* @param value A key name, a plain key/scale, or a value whose `toJSON`
|
|
32
173
|
* returns data carrying one.
|
|
@@ -74,16 +215,13 @@ declare function toKeyScale(value: KeyLike): KeyScale;
|
|
|
74
215
|
*
|
|
75
216
|
* @example
|
|
76
217
|
* ```ts
|
|
77
|
-
* import type {
|
|
78
|
-
* import { majorKey,
|
|
79
|
-
* const dbMajor:
|
|
218
|
+
* import type { ResolvedKey } from '@libraz/libcantus';
|
|
219
|
+
* import { formatNote, majorKey, spelledKeyOf } from '@libraz/libcantus';
|
|
220
|
+
* const dbMajor: ResolvedKey = spelledKeyOf(majorKey(1));
|
|
221
|
+
* formatNote(dbMajor.tonic); // 'Db'
|
|
80
222
|
* ```
|
|
81
223
|
* @category Scales
|
|
82
224
|
*/
|
|
83
|
-
type SpelledKey = {
|
|
84
|
-
tonic: Note;
|
|
85
|
-
key: KeyScale;
|
|
86
|
-
};
|
|
87
225
|
/**
|
|
88
226
|
* How one key stands to another, as reported by {@link keyRelationBetween} and
|
|
89
227
|
* tagged onto every entry of {@link relatedKeysOf}.
|
|
@@ -144,21 +282,29 @@ type KeyRelation = 'same' | 'enharmonic' | 'relative' | 'parallel' | 'dominant'
|
|
|
144
282
|
* ```
|
|
145
283
|
* @category Scales
|
|
146
284
|
*/
|
|
147
|
-
declare function spelledKeyOf(key: KeyScale):
|
|
285
|
+
declare function spelledKeyOf(key: KeyScale): ResolvedKey;
|
|
148
286
|
/**
|
|
149
|
-
* The relative key: the same key signature read
|
|
287
|
+
* The relative key: for a plain major or minor key, the same key signature read
|
|
288
|
+
* in the other mode.
|
|
150
289
|
*
|
|
151
290
|
* C major and A minor share a signature, and so are each other's relative; the
|
|
152
291
|
* relation is its own inverse for a plain major or minor key. Because the new
|
|
153
292
|
* tonic is read off the circle of fifths rather than transposed by semitones,
|
|
154
293
|
* the relative of Db major is Bb minor and not its enharmonic A# minor.
|
|
155
294
|
*
|
|
295
|
+
* A key that is not a plain major or minor is read through the mode its third
|
|
296
|
+
* names and stepped from where its tonic stands on the circle, the origin every
|
|
297
|
+
* relation here shares: the relative of D dorian is F major, the relative of the
|
|
298
|
+
* D minor its third names. The shared-signature reading does not carry over to
|
|
299
|
+
* those — D dorian is written with no accidentals and F major with one — and the
|
|
300
|
+
* modes have no relative of their own for it to be measured against.
|
|
301
|
+
*
|
|
156
302
|
* @param tonic The spelled tonic of the key, as a note name, note data, or a
|
|
157
303
|
* `Note`.
|
|
158
304
|
* @param key The key/scale, as a key name, a key/scale, or a `Key`; its mask
|
|
159
305
|
* decides which mode the relative is in.
|
|
160
306
|
* @returns The relative key and the tonic spelling it is written with.
|
|
161
|
-
* @throws If the tonic or the mask is malformed, or if the
|
|
307
|
+
* @throws If the tonic or the mask is malformed, or if the resulting signature
|
|
162
308
|
* falls outside [-12, 12] fifths.
|
|
163
309
|
* @example
|
|
164
310
|
* ```ts
|
|
@@ -168,7 +314,7 @@ declare function spelledKeyOf(key: KeyScale): SpelledKey;
|
|
|
168
314
|
* ```
|
|
169
315
|
* @category Scales
|
|
170
316
|
*/
|
|
171
|
-
declare function relativeKeyOf(tonic: NoteLike, key: KeyLike):
|
|
317
|
+
declare function relativeKeyOf(tonic: NoteLike, key: KeyLike): ResolvedKey;
|
|
172
318
|
/**
|
|
173
319
|
* The parallel key: the other mode on the same tonic.
|
|
174
320
|
*
|
|
@@ -190,7 +336,7 @@ declare function relativeKeyOf(tonic: NoteLike, key: KeyLike): SpelledKey;
|
|
|
190
336
|
* ```
|
|
191
337
|
* @category Scales
|
|
192
338
|
*/
|
|
193
|
-
declare function parallelKeyOf(tonic: NoteLike, key: KeyLike):
|
|
339
|
+
declare function parallelKeyOf(tonic: NoteLike, key: KeyLike): ResolvedKey;
|
|
194
340
|
/**
|
|
195
341
|
* The dominant key: the key a fifth above, in the mode this key's third names.
|
|
196
342
|
*
|
|
@@ -212,7 +358,7 @@ declare function parallelKeyOf(tonic: NoteLike, key: KeyLike): SpelledKey;
|
|
|
212
358
|
* ```
|
|
213
359
|
* @category Scales
|
|
214
360
|
*/
|
|
215
|
-
declare function dominantKeyOf(tonic: NoteLike, key: KeyLike):
|
|
361
|
+
declare function dominantKeyOf(tonic: NoteLike, key: KeyLike): ResolvedKey;
|
|
216
362
|
/**
|
|
217
363
|
* The subdominant key: the key a fifth below, in the mode this key's third
|
|
218
364
|
* names, and the exact inverse of {@link dominantKeyOf} on the tonic spelling.
|
|
@@ -231,7 +377,7 @@ declare function dominantKeyOf(tonic: NoteLike, key: KeyLike): SpelledKey;
|
|
|
231
377
|
* ```
|
|
232
378
|
* @category Scales
|
|
233
379
|
*/
|
|
234
|
-
declare function subdominantKeyOf(tonic: NoteLike, key: KeyLike):
|
|
380
|
+
declare function subdominantKeyOf(tonic: NoteLike, key: KeyLike): ResolvedKey;
|
|
235
381
|
/**
|
|
236
382
|
* The same sounding key written the other way round the circle of fifths, or
|
|
237
383
|
* null when it has no second spelling.
|
|
@@ -268,18 +414,25 @@ declare function subdominantKeyOf(tonic: NoteLike, key: KeyLike): SpelledKey;
|
|
|
268
414
|
* ```
|
|
269
415
|
* @category Scales
|
|
270
416
|
*/
|
|
271
|
-
declare function enharmonicKeyOf(tonic: NoteLike, key: KeyLike):
|
|
417
|
+
declare function enharmonicKeyOf(tonic: NoteLike, key: KeyLike): ResolvedKey | null;
|
|
272
418
|
/**
|
|
273
419
|
* The six closely related keys of a key, each tagged with its relation.
|
|
274
420
|
*
|
|
275
421
|
* These are the keys the German and Japanese teaching tradition counts as a
|
|
276
422
|
* key's near relations: the relative and parallel keys, the dominant and the
|
|
277
423
|
* subdominant, and the relatives of those two. For C major they are A minor,
|
|
278
|
-
* C minor, G major, F major, E minor and D minor, in that order.
|
|
279
|
-
* are written within one accidental of the key's
|
|
280
|
-
* shares it exactly and the other four stand one
|
|
281
|
-
* not — C minor is three flats away from C major —
|
|
282
|
-
* the tonic it shares rather than for the signature
|
|
424
|
+
* C minor, G major, F major, E minor and D minor, in that order. For a plain
|
|
425
|
+
* major or minor key five of them are written within one accidental of the key's
|
|
426
|
+
* own signature — the relative shares it exactly and the other four stand one
|
|
427
|
+
* away; the parallel key does not — C minor is three flats away from C major —
|
|
428
|
+
* and belongs to the set for the tonic it shares rather than for the signature
|
|
429
|
+
* it carries.
|
|
430
|
+
*
|
|
431
|
+
* A key that is not a plain major or minor is read through the mode its third
|
|
432
|
+
* names, so its relations are walked from where its tonic stands on the circle
|
|
433
|
+
* rather than from its own signature, and the accidental counts above do not
|
|
434
|
+
* describe them: the relative of D dorian is F major, one flat against dorian's
|
|
435
|
+
* none.
|
|
283
436
|
*
|
|
284
437
|
* @param tonic The spelled tonic of the key, as a note name, note data, or a
|
|
285
438
|
* `Note`.
|
|
@@ -296,7 +449,7 @@ declare function enharmonicKeyOf(tonic: NoteLike, key: KeyLike): SpelledKey | nu
|
|
|
296
449
|
* ```
|
|
297
450
|
* @category Scales
|
|
298
451
|
*/
|
|
299
|
-
declare function relatedKeysOf(tonic: NoteLike, key: KeyLike): (
|
|
452
|
+
declare function relatedKeysOf(tonic: NoteLike, key: KeyLike): (ResolvedKey & {
|
|
300
453
|
relation: KeyRelation;
|
|
301
454
|
})[];
|
|
302
455
|
/**
|
|
@@ -321,14 +474,14 @@ declare function relatedKeysOf(tonic: NoteLike, key: KeyLike): (SpelledKey & {
|
|
|
321
474
|
* falls outside [-12, 12] fifths.
|
|
322
475
|
* @example
|
|
323
476
|
* ```ts
|
|
324
|
-
* import { keyRelationBetween, majorKey, minorKey,
|
|
325
|
-
* const cMajor =
|
|
326
|
-
* keyRelationBetween(cMajor,
|
|
327
|
-
* keyRelationBetween(cMajor,
|
|
477
|
+
* import { keyRelationBetween, majorKey, minorKey, spelledKeyOf } from '@libraz/libcantus';
|
|
478
|
+
* const cMajor = spelledKeyOf(majorKey(0));
|
|
479
|
+
* keyRelationBetween(cMajor, spelledKeyOf(minorKey(9))); // 'relative'
|
|
480
|
+
* keyRelationBetween(cMajor, spelledKeyOf(minorKey(3))); // null
|
|
328
481
|
* ```
|
|
329
482
|
* @category Scales
|
|
330
483
|
*/
|
|
331
|
-
declare function keyRelationBetween(a:
|
|
484
|
+
declare function keyRelationBetween(a: ResolvedKey, b: ResolvedKey): KeyRelation | null;
|
|
332
485
|
|
|
333
486
|
/**
|
|
334
487
|
* The structured reading of a chord: what it is built from, not what it is
|
|
@@ -783,10 +936,14 @@ declare function isChordMember(pitch: number, chord: Chord | null): boolean;
|
|
|
783
936
|
/**
|
|
784
937
|
* Determine a pitch's harmonic role within a chord.
|
|
785
938
|
*
|
|
786
|
-
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
939
|
+
* A chord carrying its own tone spellings is read by them, since the degree it
|
|
940
|
+
* writes a tone as is the degree that tone plays: the ten semitones above the
|
|
941
|
+
* root of a German sixth are written five letters up, so they are its sixth and
|
|
942
|
+
* not a seventh owing a step downward. Everywhere else the role is derived from
|
|
943
|
+
* the pitch's interval above the chord root, reduced modulo 12. A major sixth
|
|
944
|
+
* (9) reads as a `sixth` for sixth chords but as a `seventh` for a
|
|
945
|
+
* diminished-seventh chord; ninths and other tensions have no basic role and
|
|
946
|
+
* return null.
|
|
790
947
|
*
|
|
791
948
|
* @param pitch MIDI pitch or bare pitch class.
|
|
792
949
|
* @param chord The chord providing the root reference.
|
|
@@ -899,10 +1056,13 @@ declare const PROFILE_WEIGHTS: Readonly<Record<SafetyProfile, Readonly<ProfileWe
|
|
|
899
1056
|
*
|
|
900
1057
|
* @param profile The profile whose table to start from.
|
|
901
1058
|
* @param overrides Fields to replace; anything absent keeps the profile's value.
|
|
1059
|
+
* A field written as an explicit `undefined` is absent, not a replacement.
|
|
902
1060
|
* @returns The complete weight table to score with.
|
|
903
|
-
* @throws If `profile` is not one of the profile names
|
|
904
|
-
* ({@link InvalidInputError}). A misspelled profile scored under
|
|
905
|
-
* table would rank candidates by a style the caller did not ask for
|
|
1061
|
+
* @throws If `profile` is not one of the profile names, or an override is not a
|
|
1062
|
+
* finite number ({@link InvalidInputError}). A misspelled profile scored under
|
|
1063
|
+
* a default table would rank candidates by a style the caller did not ask for,
|
|
1064
|
+
* and a single non-finite weight poisons every candidate's score, which turns
|
|
1065
|
+
* the ranking into the order the candidates happened to be enumerated in.
|
|
906
1066
|
* @example
|
|
907
1067
|
* ```ts
|
|
908
1068
|
* import { profileWeights } from '@libraz/libcantus';
|
|
@@ -924,25 +1084,73 @@ declare enum NoteSafety {
|
|
|
924
1084
|
/**
|
|
925
1085
|
* Bit flags describing why a pitch received its verdict.
|
|
926
1086
|
*
|
|
1087
|
+
* Several flags can describe one pitch, so test the combination rather than a
|
|
1088
|
+
* flag alone: an avoid eleventh carries `Tension` as well as `AvoidNote`, and a
|
|
1089
|
+
* usable tension is `Tension` without `AvoidNote`. `ChordTone`, `MinorSecond`
|
|
1090
|
+
* and `MajorSeventh` are informational and never lower the verdict on their
|
|
1091
|
+
* own; every other flag sets at least a warning, and the profile decides how
|
|
1092
|
+
* far past that it goes.
|
|
1093
|
+
*
|
|
927
1094
|
* @category Arrangement & Analysis
|
|
928
1095
|
*/
|
|
929
1096
|
declare enum ReasonFlag {
|
|
1097
|
+
/** The candidate is a member of the chord. Informational. */
|
|
930
1098
|
ChordTone = 1,
|
|
1099
|
+
/**
|
|
1100
|
+
* The candidate is a ninth, eleventh or thirteenth above the root, not a chord
|
|
1101
|
+
* tone. Also set alongside `AvoidNote` when the avoid note is the eleventh.
|
|
1102
|
+
*/
|
|
931
1103
|
Tension = 2,
|
|
1104
|
+
/**
|
|
1105
|
+
* The eleventh over a chord with a major third and no fourth, or the major
|
|
1106
|
+
* seventh over a dominant. Always set with `NeedsResolution`, and with
|
|
1107
|
+
* `Tension` for the eleventh.
|
|
1108
|
+
*/
|
|
932
1109
|
AvoidNote = 4,
|
|
1110
|
+
/** The candidate is in the key but neither a chord tone nor a tension. */
|
|
933
1111
|
ScaleTone = 8,
|
|
1112
|
+
/** The candidate is outside the key and not a chord tone. */
|
|
934
1113
|
NonScale = 16,
|
|
1114
|
+
/** The candidate lies outside `vocalLow`..`vocalHigh`. */
|
|
935
1115
|
OutOfRange = 32,
|
|
1116
|
+
/** The candidate, not itself a chord tone, is a tritone from one. */
|
|
936
1117
|
Tritone = 64,
|
|
1118
|
+
/**
|
|
1119
|
+
* The move from `prevPitch` is a forbidden melodic leap as
|
|
1120
|
+
* {@link isForbiddenMelodicLeap} defines it: a tritone, either seventh, or
|
|
1121
|
+
* anything wider than an octave. An octave itself is not. The profile sets
|
|
1122
|
+
* the severity, not the set of leaps. Set with `MelodicTritone` on a tritone
|
|
1123
|
+
* and with `MajorSeventh` on a major seventh.
|
|
1124
|
+
*/
|
|
937
1125
|
LargeLeap = 128,
|
|
1126
|
+
/** The move from `prevPitch` reduces to a semitone, the minor ninth included. Informational. */
|
|
938
1127
|
MinorSecond = 256,
|
|
1128
|
+
/** The move from `prevPitch` reduces to a major seventh; always with `LargeLeap`. Informational. */
|
|
939
1129
|
MajorSeventh = 512,
|
|
1130
|
+
/**
|
|
1131
|
+
* On a strong beat, the candidate is dissonant against at least one of
|
|
1132
|
+
* `otherVoices`, apart from the tritone or seventh two chord tones spell. A
|
|
1133
|
+
* perfect fourth counts only when one of the two is the lowest sounding voice,
|
|
1134
|
+
* and under `pop` not when both are chord tones — an inverted chord.
|
|
1135
|
+
*/
|
|
940
1136
|
VerticalDissonance = 1024,
|
|
1137
|
+
/** The candidate moves in parallel perfect intervals with at least one of `otherVoices`. */
|
|
941
1138
|
ParallelPerfect = 2048,
|
|
1139
|
+
/**
|
|
1140
|
+
* The candidate and another voice, the two outer voices of the texture, reach
|
|
1141
|
+
* a perfect interval by similar motion with the upper one leaping.
|
|
1142
|
+
*/
|
|
942
1143
|
HiddenParallel = 4096,
|
|
1144
|
+
/** The candidate crosses at least one of `otherVoices` since the previous step. */
|
|
943
1145
|
VoiceCrossing = 8192,
|
|
1146
|
+
/**
|
|
1147
|
+
* A held pitch, consonant with a voice on the previous step, now dissonant
|
|
1148
|
+
* against it. Always with `VerticalDissonance`.
|
|
1149
|
+
*/
|
|
944
1150
|
Suspension = 16384,
|
|
1151
|
+
/** The candidate should move by step to `resolveTo`. Set with `AvoidNote`. */
|
|
945
1152
|
NeedsResolution = 32768,
|
|
1153
|
+
/** The move from `prevPitch` reduces to a tritone; always with `LargeLeap`. */
|
|
946
1154
|
MelodicTritone = 65536
|
|
947
1155
|
}
|
|
948
1156
|
/**
|
|
@@ -970,6 +1178,20 @@ type SafetyQuery = {
|
|
|
970
1178
|
vocalLow?: number;
|
|
971
1179
|
vocalHigh?: number;
|
|
972
1180
|
};
|
|
1181
|
+
/**
|
|
1182
|
+
* The reasons one of `otherVoices` contributes to a verdict.
|
|
1183
|
+
*
|
|
1184
|
+
* @category Arrangement & Analysis
|
|
1185
|
+
*/
|
|
1186
|
+
type SafetyPartner = {
|
|
1187
|
+
/** The voice's index in {@link SafetyQuery.otherVoices}. */
|
|
1188
|
+
index: number;
|
|
1189
|
+
/**
|
|
1190
|
+
* The pairwise flags this voice raises: `VerticalDissonance`, `Suspension`,
|
|
1191
|
+
* `ParallelPerfect`, `HiddenParallel` and `VoiceCrossing`.
|
|
1192
|
+
*/
|
|
1193
|
+
reasons: number;
|
|
1194
|
+
};
|
|
973
1195
|
/**
|
|
974
1196
|
* The verdict, reason flags, and optional resolution guidance.
|
|
975
1197
|
*
|
|
@@ -980,6 +1202,12 @@ type SafetyResult = {
|
|
|
980
1202
|
reasons: number;
|
|
981
1203
|
resolveTo?: number;
|
|
982
1204
|
suggestions?: number[];
|
|
1205
|
+
/**
|
|
1206
|
+
* The voices behind the pairwise flags in `reasons`, in `otherVoices` order,
|
|
1207
|
+
* when {@link EvaluateSafetyOptions.partners} asked for them and any voice
|
|
1208
|
+
* raised one. Their `reasons` together are exactly the pairwise flags set.
|
|
1209
|
+
*/
|
|
1210
|
+
partners?: SafetyPartner[];
|
|
983
1211
|
rationale?: string;
|
|
984
1212
|
};
|
|
985
1213
|
/**
|
|
@@ -1024,6 +1252,14 @@ type EvaluateSafetyOptions = {
|
|
|
1024
1252
|
* @defaultValue true
|
|
1025
1253
|
*/
|
|
1026
1254
|
suggestions?: boolean;
|
|
1255
|
+
/**
|
|
1256
|
+
* Whether to report which of `otherVoices` raised each pairwise flag, as
|
|
1257
|
+
* {@link SafetyResult.partners}. The bitmask alone says a parallel fifth is
|
|
1258
|
+
* there; this says against which voice.
|
|
1259
|
+
*
|
|
1260
|
+
* @defaultValue false
|
|
1261
|
+
*/
|
|
1262
|
+
partners?: boolean;
|
|
1027
1263
|
};
|
|
1028
1264
|
/**
|
|
1029
1265
|
* Enumerate placeable pitches in a range, chord tones first, descending.
|
|
@@ -1049,92 +1285,12 @@ type EvaluateSafetyOptions = {
|
|
|
1049
1285
|
declare function enumerateSafePitches(q: Omit<SafetyQuery, 'candidatePitch'>, pitchLow: number, pitchHigh: number): number[];
|
|
1050
1286
|
|
|
1051
1287
|
/**
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
* The root and the slash bass are note names, so they are read and written in
|
|
1059
|
-
* whichever notation system the caller names — a German chart's `H7`, `As7` and
|
|
1060
|
-
* `Ges/B` included. Unlike a note name, a chord symbol is never attributed to a
|
|
1061
|
-
* system on its own: German `B` is a B flat and English `B` a B natural, and a
|
|
1062
|
-
* symbol carries no `dur`/`moll` word to break the tie, so the most common
|
|
1063
|
-
* symbol in the vocabulary would otherwise change chord with the source it came
|
|
1064
|
-
* from. With no system given a symbol is English.
|
|
1065
|
-
*/
|
|
1066
|
-
|
|
1067
|
-
/**
|
|
1068
|
-
* Parse a lead-sheet chord symbol into a {@link Chord}.
|
|
1069
|
-
*
|
|
1070
|
-
* Accepts `<root><quality>[/<bass>]`, e.g. `Cmaj7`, `F#m7b5`, `Bb7`, `C/G`,
|
|
1071
|
-
* `C6/9`, `C6/9/E`. Root and bass letters are case-insensitive, matching
|
|
1072
|
-
* {@link parseNote}. A `/` is ambiguous between a slash bass and the `6/9`
|
|
1073
|
-
* quality; the text splits at the last `/` whose right-hand side is a valid
|
|
1074
|
-
* bare note preceded by a recognized quality, so `6/9` (with or without a
|
|
1075
|
-
* further slash bass) parses as a quality.
|
|
1076
|
-
*
|
|
1077
|
-
* The root and bass are read in `system`, so a German chart's `H7`, `As7` and
|
|
1078
|
-
* `Ges/B` are read by asking for `'german'`. The system is never inferred: with
|
|
1079
|
-
* none given the symbol is English, where `B` is the B natural and `H` no note
|
|
1080
|
-
* at all. Case carries nothing in a chord symbol — unlike a German key name,
|
|
1081
|
-
* where the case of the tonic is the mode — so the quality suffix alone says
|
|
1082
|
-
* major or minor. Where a German root's flat suffix could equally open the
|
|
1083
|
-
* quality, the longest root that leaves a known quality behind wins: `Asus4` is
|
|
1084
|
-
* an A suspended chord and `Assus4` the A flat one.
|
|
1085
|
-
*
|
|
1086
|
-
* The quality suffix is read structurally when no name covers it, so a chart's
|
|
1087
|
-
* bracketed tensions parse as readily as the names do: `Cmaj7(#11)`,
|
|
1088
|
-
* `C7(b9,#11)`, `C7(13)`, `Csus4(add9)`, `C-Δ9`, `C6/9(#11)`. A `/` between two
|
|
1089
|
-
* figures separates them as it does inside brackets, which is what the sixth
|
|
1090
|
-
* and ninth of a `6/9` are. Such a chord carries the tones it names and reports
|
|
1091
|
-
* the nearest quality name (see {@link chordSpecQuality}); read
|
|
1092
|
-
* {@link chordSpecOf} for its structure.
|
|
1093
|
-
*
|
|
1094
|
-
* The parsed chord carries the root/bass spellings as enharmonic hints
|
|
1095
|
-
* (`rootSpelling`/`bassSpelling`) so {@link formatChordSymbol} can reproduce
|
|
1096
|
-
* flat spellings such as `Bbmaj7` instead of respelling them with sharps.
|
|
1097
|
-
*
|
|
1098
|
-
* @param text The chord symbol text.
|
|
1099
|
-
* @param opts `system` reads the root and bass in that notation system instead
|
|
1100
|
-
* of English.
|
|
1101
|
-
* @returns The parsed chord.
|
|
1102
|
-
* @throws If the root or quality is not recognized in that system. Use
|
|
1103
|
-
* {@link tryParseChordSymbol} where failure is ordinary, such as a chord
|
|
1104
|
-
* field read on every keystroke.
|
|
1105
|
-
* @example
|
|
1106
|
-
* ```ts
|
|
1107
|
-
* import { parseChordSymbol, formatChordSymbol } from '@libraz/libcantus';
|
|
1108
|
-
* const c = parseChordSymbol('Bbmaj7');
|
|
1109
|
-
* formatChordSymbol(c); // 'Bbmaj7' — flat spelling is preserved on round-trip
|
|
1110
|
-
* parseChordSymbol('H7', { system: 'german' }).rootPc; // 11 — the B natural
|
|
1111
|
-
* parseChordSymbol('B', { system: 'german' }).rootPc; // 10 — the German B flat
|
|
1112
|
-
* ```
|
|
1113
|
-
* @category Chords
|
|
1114
|
-
*/
|
|
1115
|
-
declare function parseChordSymbol(text: string, opts?: NoteNameOptions): Chord;
|
|
1116
|
-
/**
|
|
1117
|
-
* Parse a lead-sheet chord symbol, reporting failure instead of throwing it.
|
|
1118
|
-
*
|
|
1119
|
-
* The same reading as {@link parseChordSymbol} — that function is this one with
|
|
1120
|
-
* its error thrown — for the callers where a symbol that does not parse yet is
|
|
1121
|
-
* the normal state of the input rather than a fault: a chord field says what is
|
|
1122
|
-
* wrong with what has been typed so far, and does not need a `try` around every
|
|
1123
|
-
* keystroke to do it.
|
|
1124
|
-
*
|
|
1125
|
-
* @param text The chord symbol text.
|
|
1126
|
-
* @param opts `system` reads the root and bass in that notation system instead
|
|
1127
|
-
* of English.
|
|
1128
|
-
* @returns The chord, or the error explaining why the text is not one.
|
|
1129
|
-
* @example
|
|
1130
|
-
* ```ts
|
|
1131
|
-
* import { tryParseChordSymbol } from '@libraz/libcantus';
|
|
1132
|
-
* const result = tryParseChordSymbol('Cmaj7(#11)');
|
|
1133
|
-
* result.ok ? result.value.intervals : result.error.message;
|
|
1134
|
-
* ```
|
|
1135
|
-
* @category Chords
|
|
1288
|
+
* Reading a caller's chord into the one shape the library works in.
|
|
1289
|
+
*
|
|
1290
|
+
* The widening counterpart of the other `to*Data` coercers, kept beside the
|
|
1291
|
+
* grammar it falls back on rather than inside it: what a chord symbol means is
|
|
1292
|
+
* the parser's question, and what shapes stand for a chord is this one's.
|
|
1136
1293
|
*/
|
|
1137
|
-
declare function tryParseChordSymbol(text: string, opts?: NoteNameOptions): ParseResult<Chord>;
|
|
1138
1294
|
/**
|
|
1139
1295
|
* Anything that names a chord: a chord symbol, plain chord data, or a value
|
|
1140
1296
|
* that serializes to chord data such as the `Chord` class.
|
|
@@ -1169,74 +1325,5 @@ type ChordLike = string | Chord | {
|
|
|
1169
1325
|
* @category Chords
|
|
1170
1326
|
*/
|
|
1171
1327
|
declare function toChordData(value: ChordLike): Chord;
|
|
1172
|
-
/**
|
|
1173
|
-
* How a chord symbol is written: in which notation system, and on which side of
|
|
1174
|
-
* the enharmonic fence.
|
|
1175
|
-
*
|
|
1176
|
-
* @category Chords
|
|
1177
|
-
*/
|
|
1178
|
-
type ChordSymbolOptions = NoteNameOptions & {
|
|
1179
|
-
/**
|
|
1180
|
-
* Prefer flat spellings over sharps for an altered root or bass; passing
|
|
1181
|
-
* either `true` or `false` overrides any spelling hint the chord carries.
|
|
1182
|
-
*/
|
|
1183
|
-
flats?: boolean;
|
|
1184
|
-
};
|
|
1185
|
-
/**
|
|
1186
|
-
* Format a {@link Chord} as a lead-sheet chord symbol.
|
|
1187
|
-
*
|
|
1188
|
-
* The inverse of {@link parseChordSymbol} in every notation system: each
|
|
1189
|
-
* quality maps to one canonical suffix spelling, the root and bass are written
|
|
1190
|
-
* in `system`, and a slash bass is appended only when it differs from the root.
|
|
1191
|
-
* Every symbol written here reads back through {@link parseChordSymbol} as the
|
|
1192
|
-
* same root, sounding bass and tones — whatever combination of tensions the
|
|
1193
|
-
* chord carries, and whether or not a quality name covers it.
|
|
1194
|
-
* When the chord carries `rootSpelling`/`bassSpelling` hints (as chords from
|
|
1195
|
-
* {@link parseChordSymbol} do) and no explicit `flats` preference is given, the
|
|
1196
|
-
* hints are reused so flat symbols round-trip unchanged.
|
|
1197
|
-
*
|
|
1198
|
-
* The suffix is written from the chord's own tones (see {@link chordSpecOf}),
|
|
1199
|
-
* not from its quality name, so a chord carrying alterations no name covers is
|
|
1200
|
-
* written out in full — `C7(b9,#11)` — rather than under the nearest name. A
|
|
1201
|
-
* tone the chord leaves out is not written: the symbol names the harmony, so a
|
|
1202
|
-
* fifth-less dominant is still `C7`.
|
|
1203
|
-
*
|
|
1204
|
-
* @param chord The chord to format, as a chord symbol, chord data, or a
|
|
1205
|
-
* `Chord`.
|
|
1206
|
-
* @param opts `system` writes the root and bass in that notation system instead
|
|
1207
|
-
* of English; `flats` overrides the spelling hints, as
|
|
1208
|
-
* {@link ChordSymbolOptions} describes.
|
|
1209
|
-
* @returns The chord symbol text.
|
|
1210
|
-
* @example
|
|
1211
|
-
* ```ts
|
|
1212
|
-
* import { makeChord, formatChordSymbol, parseChordSymbol } from '@libraz/libcantus';
|
|
1213
|
-
* formatChordSymbol(makeChord(0, 'min7')); // 'Cm7'
|
|
1214
|
-
* formatChordSymbol(parseChordSymbol('Bb7'), { system: 'german' }); // 'B7'
|
|
1215
|
-
* formatChordSymbol(parseChordSymbol('B7'), { system: 'german' }); // 'H7'
|
|
1216
|
-
* ```
|
|
1217
|
-
* @category Chords
|
|
1218
|
-
*/
|
|
1219
|
-
declare function formatChordSymbol(chord: ChordLike, opts?: ChordSymbolOptions): string;
|
|
1220
|
-
/**
|
|
1221
|
-
* Transpose a chord symbol by a number of semitones.
|
|
1222
|
-
*
|
|
1223
|
-
* The symbol is read in the same system it is written back in, so a German
|
|
1224
|
-
* chart stays German across the transposition.
|
|
1225
|
-
*
|
|
1226
|
-
* @param text The chord symbol text.
|
|
1227
|
-
* @param semitones Signed semitone offset to apply to the root and bass.
|
|
1228
|
-
* @param opts Options for reading and writing the symbol; see
|
|
1229
|
-
* {@link ChordSymbolOptions}.
|
|
1230
|
-
* @returns The transposed chord symbol text.
|
|
1231
|
-
* @throws If `text` does not parse as a chord symbol.
|
|
1232
|
-
* @example
|
|
1233
|
-
* ```ts
|
|
1234
|
-
* import { transposeChordSymbol } from '@libraz/libcantus';
|
|
1235
|
-
* transposeChordSymbol('C/G', 2); // 'D/A'
|
|
1236
|
-
* transposeChordSymbol('H7', 1, { system: 'german' }); // 'C7'
|
|
1237
|
-
* ```
|
|
1238
|
-
* @category Chords
|
|
1239
|
-
*/
|
|
1240
|
-
declare function transposeChordSymbol(text: string, semitones: number, opts?: ChordSymbolOptions): string;
|
|
1241
1328
|
|
|
1242
|
-
export {
|
|
1329
|
+
export { subdominantKeyOf as $, type Alteration as A, chordSpecQuality as B, type ChordBase as C, chordToneRole as D, type EvaluateSafetyOptions as E, diatonicSeventh as F, diatonicTriad as G, dominantKeyOf as H, enharmonicKeyOf as I, enumerateSafePitches as J, type KeyLike as K, evaluateSafety as L, intervalAboveRoot as M, NoteSafety as N, isChordMember as O, PROFILE_WEIGHTS as P, keyRelationBetween as Q, ReasonFlag as R, type SafetyPartner as S, makeChord as T, parallelKeyOf as U, type VoiceSnapshot as V, profileWeights as W, relatedKeysOf as X, relativeKeyOf as Y, spanFromChord as Z, spelledKeyOf as _, type AlteredDegree as a, toChordData as a0, toKeyScale as a1, transposeChord as a2, type Chord as b, type ChordLike as c, type ChordQuality as d, type ChordSegment as e, type ChordSeventh as f, type ChordSpan as g, type ChordSpec as h, type ChordToneRole as i, type KeyRelation as j, type KeyVariant as k, type PitchSpelling as l, type ProfileWeights as m, type ResolvedKey as n, type SafetyProfile as o, type SafetyQuery as p, type SafetyResult as q, type SpelledKeyLike as r, type SpelledKeyScale as s, chordFromDegree as t, chordFromSpan as u, chordFromSpec as v, chordPitchClasses as w, chordQualities as x, chordSpecIntervals as y, chordSpecOf as z };
|