@libraz/libcantus 0.9.4 → 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 -261
- package/README_ja.md +115 -0
- package/dist/analyze/index.cjs +54 -7
- package/dist/analyze/index.cjs.map +1 -1
- package/dist/analyze/index.d.cts +213 -456
- package/dist/analyze/index.d.ts +213 -456
- 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-ELCTZUJJ.js +379 -0
- 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 +103 -6
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +96 -345
- package/dist/core/index.d.ts +96 -345
- package/dist/core/index.js +104 -7
- package/dist/generate/index.cjs +89 -10
- package/dist/generate/index.cjs.map +1 -1
- package/dist/generate/index.d.cts +437 -1095
- package/dist/generate/index.d.ts +437 -1095
- package/dist/generate/index.js +94 -15
- package/dist/index-9wcMhG73.d.ts +1095 -0
- package/dist/{index-D6b6na69.d.cts → 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-tSQh-xwY.d.ts → 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 +358 -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 +407 -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 +4685 -243
- package/dist/model/index.d.ts +4685 -243
- 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 +513 -173
- package/dist/theory/index.d.ts +513 -173
- package/dist/theory/index.js +118 -24
- package/package.json +16 -11
- package/dist/chunk-36N73KZ3.cjs +0 -246
- package/dist/chunk-36N73KZ3.cjs.map +0 -1
- package/dist/chunk-4HLLZPXT.cjs +0 -3077
- package/dist/chunk-4HLLZPXT.cjs.map +0 -1
- package/dist/chunk-7MGZ7D62.cjs +0 -498
- package/dist/chunk-7MGZ7D62.cjs.map +0 -1
- package/dist/chunk-7NKDPF74.js +0 -3077
- package/dist/chunk-7NKDPF74.js.map +0 -1
- package/dist/chunk-CAN76NCU.cjs +0 -679
- package/dist/chunk-CAN76NCU.cjs.map +0 -1
- package/dist/chunk-D2FAJBYL.js +0 -479
- package/dist/chunk-D2FAJBYL.js.map +0 -1
- package/dist/chunk-EHVEBWM5.js +0 -1449
- package/dist/chunk-EHVEBWM5.js.map +0 -1
- package/dist/chunk-FCANXBAT.cjs +0 -30
- package/dist/chunk-FCANXBAT.cjs.map +0 -1
- package/dist/chunk-FNDWXRRI.cjs +0 -479
- package/dist/chunk-FNDWXRRI.cjs.map +0 -1
- package/dist/chunk-GQSGS2N4.js +0 -173
- package/dist/chunk-GQSGS2N4.js.map +0 -1
- package/dist/chunk-HKGYCQ34.js +0 -53
- package/dist/chunk-HKGYCQ34.js.map +0 -1
- package/dist/chunk-I24MV65U.js +0 -106
- package/dist/chunk-I24MV65U.js.map +0 -1
- package/dist/chunk-KMHOICIY.js +0 -679
- package/dist/chunk-KMHOICIY.js.map +0 -1
- package/dist/chunk-LW53AHQU.cjs +0 -1117
- package/dist/chunk-LW53AHQU.cjs.map +0 -1
- package/dist/chunk-N6IHQUOX.js +0 -1
- package/dist/chunk-NKIBQ6PT.js +0 -30
- package/dist/chunk-NKIBQ6PT.js.map +0 -1
- package/dist/chunk-NP4NA2FB.cjs +0 -106
- package/dist/chunk-NP4NA2FB.cjs.map +0 -1
- package/dist/chunk-NVE34YGZ.cjs +0 -1449
- package/dist/chunk-NVE34YGZ.cjs.map +0 -1
- package/dist/chunk-NYYWMV2C.js +0 -327
- package/dist/chunk-NYYWMV2C.js.map +0 -1
- package/dist/chunk-Q2XUP227.js +0 -845
- package/dist/chunk-Q2XUP227.js.map +0 -1
- package/dist/chunk-Q6OP4U43.cjs +0 -327
- package/dist/chunk-Q6OP4U43.cjs.map +0 -1
- package/dist/chunk-RC6GBMCD.cjs +0 -845
- package/dist/chunk-RC6GBMCD.cjs.map +0 -1
- package/dist/chunk-RK35RIN7.js +0 -1117
- package/dist/chunk-RK35RIN7.js.map +0 -1
- package/dist/chunk-RUMU3UA6.cjs +0 -53
- package/dist/chunk-RUMU3UA6.cjs.map +0 -1
- package/dist/chunk-T64C7ZD7.cjs +0 -1
- package/dist/chunk-T64C7ZD7.cjs.map +0 -1
- package/dist/chunk-XEBG3G53.js +0 -498
- package/dist/chunk-XEBG3G53.js.map +0 -1
- package/dist/chunk-YLEMGEFH.js +0 -246
- package/dist/chunk-YLEMGEFH.js.map +0 -1
- package/dist/chunk-ZEJR4TKL.cjs +0 -173
- package/dist/chunk-ZEJR4TKL.cjs.map +0 -1
- package/dist/function-BtiZb9i9.d.ts +0 -208
- package/dist/function-DNugAOrt.d.cts +0 -208
- package/dist/index-6VR8-kit.d.ts +0 -143
- package/dist/index-70p168VM.d.ts +0 -192
- package/dist/index-Be74mcon.d.cts +0 -152
- package/dist/index-BtXT6UQ0.d.cts +0 -192
- package/dist/index-C5UBbQ4G.d.ts +0 -152
- package/dist/index-C83mZI1P.d.ts +0 -242
- package/dist/index-DXd9JikN.d.cts +0 -246
- package/dist/index-DXd9JikN.d.ts +0 -246
- package/dist/index-OG65ocOr.d.cts +0 -272
- package/dist/index-OG65ocOr.d.ts +0 -272
- package/dist/index-tJhkmQgE.d.cts +0 -143
- package/dist/index-y_ak9_Hi.d.cts +0 -242
- package/dist/styled-DIRkk9Uz.d.ts +0 -506
- package/dist/styled-DJbkJQfj.d.cts +0 -506
- 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
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import { P as ParseResult } from './index-B9MNZboQ.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Meter arithmetic shared by the meter module and the validation guards.
|
|
5
|
+
*
|
|
6
|
+
* These helpers never validate: they are the single definition of how a time
|
|
7
|
+
* signature is read, so the guard that rejects a malformed signature and the
|
|
8
|
+
* functions that use a validated one cannot drift apart. Everything here is
|
|
9
|
+
* integer arithmetic on the numerator, so a bar's pulse count is exact rather
|
|
10
|
+
* than the result of dividing two floats.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A meter in the plain data the library reads it as: one signature, or the map
|
|
15
|
+
* of a piece that changes meter.
|
|
16
|
+
*
|
|
17
|
+
* What {@link MeterLike} resolves to, and the type every function below the
|
|
18
|
+
* entry points works in — the text form is read once, at the boundary.
|
|
19
|
+
*
|
|
20
|
+
* @category Rhythm & Meter
|
|
21
|
+
*/
|
|
22
|
+
type MeterData = TimeSignature | MeterMap;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Meter and time signatures: bar/beat arithmetic, simple vs. compound meters,
|
|
26
|
+
* metric-accent hierarchy, and tuplet subdivision.
|
|
27
|
+
*
|
|
28
|
+
* Positions and durations are measured in quarter-note beats, matching the rest
|
|
29
|
+
* of the library's beat convention (four quarter-note beats per bar in 4/4).
|
|
30
|
+
* Beat 0 is the first downbeat, so a pickup sounds at negative beats, and a
|
|
31
|
+
* piece that changes meter is described by a {@link MeterMap} rather than by
|
|
32
|
+
* one signature.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A time signature as a numerator over a note-value denominator.
|
|
37
|
+
*
|
|
38
|
+
* @category Rhythm & Meter
|
|
39
|
+
*/
|
|
40
|
+
type TimeSignature = {
|
|
41
|
+
numerator: number;
|
|
42
|
+
denominator: number;
|
|
43
|
+
/**
|
|
44
|
+
* Optional grouping of the bar into felt beats, as positive integers. The
|
|
45
|
+
* entries are group lengths, written either in the meter's main pulses —
|
|
46
|
+
* `[2, 2, 3]` for a 2+2+3 reading of 7/8, `[3, 2]` for 5/8 — or, for a
|
|
47
|
+
* compound numerator, in denominator units. They must sum to
|
|
48
|
+
* {@link pulsesPerBar} in the first spelling and to the numerator in the
|
|
49
|
+
* second; a pulse is one unit outside compound meters, where the two
|
|
50
|
+
* spellings coincide.
|
|
51
|
+
*
|
|
52
|
+
* A compound numerator accepts both readings, and the shape of the grouping
|
|
53
|
+
* says which is meant. Groups of nothing but threes spell the compound
|
|
54
|
+
* division itself, so 9/8 as `[3, 3, 3]` (equivalently `[1, 1, 1]`) is the
|
|
55
|
+
* ordinary three dotted-quarter pulses; any other grouping summing to the
|
|
56
|
+
* numerator reads additively, so 9/8 as `[2, 2, 2, 3]` is nine quaver pulses
|
|
57
|
+
* grouped aksak-fashion. {@link pulsesPerBar}, {@link pulseBeats} and
|
|
58
|
+
* {@link isCompound} follow whichever reading the grouping selects.
|
|
59
|
+
*
|
|
60
|
+
* The head pulse of each group other than the downbeat is a secondary strong
|
|
61
|
+
* pulse to {@link metricWeight}/{@link isStrongBeat}. A grouping whose groups
|
|
62
|
+
* are all the same length states no accent the meter does not already have,
|
|
63
|
+
* so it weighs exactly as an ungrouped bar does.
|
|
64
|
+
*/
|
|
65
|
+
grouping?: number[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* One time signature and the beat at which it takes effect.
|
|
69
|
+
*
|
|
70
|
+
* @category Rhythm & Meter
|
|
71
|
+
*/
|
|
72
|
+
type MeterChange = {
|
|
73
|
+
/** Absolute quarter-note beat the signature takes effect at. */
|
|
74
|
+
startBeat: number;
|
|
75
|
+
/** The signature in force from that beat until the next change. */
|
|
76
|
+
ts: TimeSignature;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* A piece's meter over time: the signatures in force, in beat order.
|
|
80
|
+
*
|
|
81
|
+
* A meter change starts a new bar, so a span that does not divide evenly into
|
|
82
|
+
* its own bars ends with a short bar rather than spilling across the change.
|
|
83
|
+
* The first entry also governs everything before it, which is what reads a
|
|
84
|
+
* pickup written at negative beats in the signature the piece opens in.
|
|
85
|
+
*
|
|
86
|
+
* @category Rhythm & Meter
|
|
87
|
+
*/
|
|
88
|
+
type MeterMap = MeterChange[];
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Anything that names a meter: a signature text such as `'6/8'`, a plain
|
|
92
|
+
* {@link TimeSignature}, a full {@link MeterMap}, or a value that serializes to
|
|
93
|
+
* one of those such as the `Meter` class.
|
|
94
|
+
*
|
|
95
|
+
* Every meter-aware function takes this, so a piece in one meter reads as
|
|
96
|
+
* `'4/4'` and a piece that changes meter reads as the map, without the caller
|
|
97
|
+
* choosing a different function for each. Only a signature has a text form — a
|
|
98
|
+
* meter map is a run of changes and is given as the data it is.
|
|
99
|
+
*
|
|
100
|
+
* @category Rhythm & Meter
|
|
101
|
+
*/
|
|
102
|
+
type MeterLike = string | TimeSignature | MeterMap | {
|
|
103
|
+
/** The meter data this value stands for. */
|
|
104
|
+
toJSON(): TimeSignature | MeterMap;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Resolve any meter-shaped value to the plain meter data the library reads.
|
|
108
|
+
*
|
|
109
|
+
* The counterpart of {@link toNoteData} for meters: an entry point takes
|
|
110
|
+
* whatever form the caller has — the signature a meter field holds, the data
|
|
111
|
+
* the meter module returns, the map of a piece that changes meter, or a `Meter`
|
|
112
|
+
* instance — and gets one of two shapes back. An instance is accepted through
|
|
113
|
+
* its `toJSON` method rather than by its type, so the core layer can read a
|
|
114
|
+
* class it cannot import.
|
|
115
|
+
*
|
|
116
|
+
* Text is read by {@link parseTimeSignature} and nothing else, so every entry
|
|
117
|
+
* point that takes a meter accepts exactly the signatures that parser accepts,
|
|
118
|
+
* the additive `'2+2+3/8'` included and nothing besides. A meter map has no text
|
|
119
|
+
* form — it is a run of changes, each with the beat it starts at — so text
|
|
120
|
+
* always names a single signature.
|
|
121
|
+
*
|
|
122
|
+
* @param value A signature text, a plain time signature, a meter map, or a
|
|
123
|
+
* value whose `toJSON` returns one of those.
|
|
124
|
+
* @param name What the meter is called in an error message, so a caller that
|
|
125
|
+
* holds several of them hears which one was malformed.
|
|
126
|
+
* @returns The validated signature, or the validated map.
|
|
127
|
+
* @throws If the value names no meter, or the meter it names is malformed.
|
|
128
|
+
*/
|
|
129
|
+
declare function toMeterData(value: MeterLike, name?: string): MeterData;
|
|
130
|
+
/**
|
|
131
|
+
* A position expressed as a bar index and a quarter-note offset within the bar.
|
|
132
|
+
*
|
|
133
|
+
* @category Rhythm & Meter
|
|
134
|
+
*/
|
|
135
|
+
type BarPosition = {
|
|
136
|
+
/**
|
|
137
|
+
* 0-based bar index, counting the first full bar as 0.
|
|
138
|
+
* {@link formatBarPosition} renders it 1-based. A pickup sounds before that
|
|
139
|
+
* bar, so its notes report bar -1.
|
|
140
|
+
*/
|
|
141
|
+
bar: number;
|
|
142
|
+
/**
|
|
143
|
+
* Quarter-note offset from the start of the bar — not the felt beat. In 6/8
|
|
144
|
+
* the second felt beat is at `beat: 1.5`; {@link barPositionToPulse} converts
|
|
145
|
+
* to felt-beat numbering.
|
|
146
|
+
*/
|
|
147
|
+
beat: number;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Parse a time signature such as `"4/4"` or `"6/8"`, or the additive `"2+2+3/8"`.
|
|
151
|
+
*
|
|
152
|
+
* @param text The signature text.
|
|
153
|
+
* @returns The parsed time signature.
|
|
154
|
+
* @throws If the text is not `n/d` with positive integers, or names a signature
|
|
155
|
+
* the library rejects. Use {@link tryParseTimeSignature} where failure is
|
|
156
|
+
* ordinary, such as a meter field read on every keystroke.
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* import { parseTimeSignature } from '@libraz/libcantus';
|
|
160
|
+
* parseTimeSignature('6/8'); // { numerator: 6, denominator: 8 }
|
|
161
|
+
* ```
|
|
162
|
+
* @category Rhythm & Meter
|
|
163
|
+
*/
|
|
164
|
+
declare function parseTimeSignature(text: string): TimeSignature;
|
|
165
|
+
/**
|
|
166
|
+
* Parse a time signature, reporting failure instead of throwing it.
|
|
167
|
+
*
|
|
168
|
+
* The same reading as {@link parseTimeSignature} — that function is this one
|
|
169
|
+
* with its error thrown — for the callers where text that does not parse yet is
|
|
170
|
+
* the normal state of the input rather than a fault.
|
|
171
|
+
*
|
|
172
|
+
* @param text The signature text.
|
|
173
|
+
* @returns The signature, or the error explaining why the text is not one.
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* import { tryParseTimeSignature } from '@libraz/libcantus';
|
|
177
|
+
* const result = tryParseTimeSignature('7/8');
|
|
178
|
+
* result.ok ? result.value.numerator : result.error.message;
|
|
179
|
+
* ```
|
|
180
|
+
* @category Rhythm & Meter
|
|
181
|
+
*/
|
|
182
|
+
declare function tryParseTimeSignature(text: string): ParseResult<TimeSignature>;
|
|
183
|
+
/**
|
|
184
|
+
* Render a time signature as `"n/d"`, or as `"a+b+c/d"` when it carries an
|
|
185
|
+
* additive grouping and `grouping` is requested.
|
|
186
|
+
*
|
|
187
|
+
* The additive form is what {@link parseTimeSignature} reads back, and it adds
|
|
188
|
+
* its terms to get the numerator — so only a grouping written in denominator
|
|
189
|
+
* units can be rendered that way. A grouping counted in main pulses (9/8 as
|
|
190
|
+
* `[1, 1, 1]`, 12/8 as `[2, 2]`) would come back as a different bar, so it
|
|
191
|
+
* falls back to the plain form, which those groupings cost nothing: they select
|
|
192
|
+
* the same reading the bare signature does.
|
|
193
|
+
*
|
|
194
|
+
* The plain form drops the grouping, so a round trip through it reads 7/8 as
|
|
195
|
+
* flat rather than as 2+2+3; ask for the additive form to keep it.
|
|
196
|
+
*
|
|
197
|
+
* @param ts The time signature.
|
|
198
|
+
* @param opts Set `grouping: true` to render an additive grouping.
|
|
199
|
+
* @returns The formatted signature.
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* import { formatTimeSignature } from '@libraz/libcantus';
|
|
203
|
+
* const aksak = { numerator: 7, denominator: 8, grouping: [2, 2, 3] };
|
|
204
|
+
* formatTimeSignature(aksak); // '7/8'
|
|
205
|
+
* formatTimeSignature(aksak, { grouping: true }); // '2+2+3/8'
|
|
206
|
+
* ```
|
|
207
|
+
* @category Rhythm & Meter
|
|
208
|
+
*/
|
|
209
|
+
declare function formatTimeSignature(ts: TimeSignature, opts?: {
|
|
210
|
+
grouping?: boolean;
|
|
211
|
+
}): string;
|
|
212
|
+
/**
|
|
213
|
+
* Whether a meter is compound: its main pulses each divide into three, as in
|
|
214
|
+
* 6/8, 9/8, 12/8, or 6/4. Compound meters are those whose numerator is a
|
|
215
|
+
* multiple of three greater than three, independent of the denominator. Meters
|
|
216
|
+
* like 3/8 and 3/4 (simple triples, numerator 3) are not compound, and neither
|
|
217
|
+
* is a signature whose {@link TimeSignature.grouping} selects the additive
|
|
218
|
+
* reading (9/8 as 2+2+2+3).
|
|
219
|
+
*
|
|
220
|
+
* @param ts The time signature.
|
|
221
|
+
* @returns True for compound meters.
|
|
222
|
+
* @category Rhythm & Meter
|
|
223
|
+
*/
|
|
224
|
+
declare function isCompound(ts: TimeSignature): boolean;
|
|
225
|
+
/**
|
|
226
|
+
* Length of a bar in quarter-note beats.
|
|
227
|
+
*
|
|
228
|
+
* @param ts The time signature.
|
|
229
|
+
* @returns The bar length in quarter notes.
|
|
230
|
+
* @category Rhythm & Meter
|
|
231
|
+
*/
|
|
232
|
+
declare function beatsPerBar(ts: TimeSignature): number;
|
|
233
|
+
/**
|
|
234
|
+
* The time signature in force at a beat.
|
|
235
|
+
*
|
|
236
|
+
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
237
|
+
* @param meter A single signature, or the piece's meter map.
|
|
238
|
+
* @returns The signature governing that beat.
|
|
239
|
+
* @example
|
|
240
|
+
* ```ts
|
|
241
|
+
* import { meterAt, parseTimeSignature } from '@libraz/libcantus';
|
|
242
|
+
* const meters = [
|
|
243
|
+
* { startBeat: 0, ts: parseTimeSignature('4/4') },
|
|
244
|
+
* { startBeat: 8, ts: parseTimeSignature('3/4') },
|
|
245
|
+
* ];
|
|
246
|
+
* meterAt(9, meters); // { numerator: 3, denominator: 4 }
|
|
247
|
+
* ```
|
|
248
|
+
* @category Rhythm & Meter
|
|
249
|
+
*/
|
|
250
|
+
declare function meterAt(beatInQuarters: number, meter: MeterLike): TimeSignature;
|
|
251
|
+
/**
|
|
252
|
+
* Absolute beat at which the bar containing `beatInQuarters` begins.
|
|
253
|
+
*
|
|
254
|
+
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
255
|
+
* @param meter A single signature, or the piece's meter map.
|
|
256
|
+
* @returns The bar's first beat, negative inside a pickup.
|
|
257
|
+
* @category Rhythm & Meter
|
|
258
|
+
*/
|
|
259
|
+
declare function barStartBeat(beatInQuarters: number, meter: MeterLike): number;
|
|
260
|
+
/**
|
|
261
|
+
* Bar index of a beat: 0 for the first full bar, negative inside a pickup.
|
|
262
|
+
*
|
|
263
|
+
* Bars accumulate across meter changes, so the bar after a 4/4-to-3/4 change is
|
|
264
|
+
* the next bar and not the first bar of a new count.
|
|
265
|
+
*
|
|
266
|
+
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
267
|
+
* @param meter A single signature, or the piece's meter map.
|
|
268
|
+
* @returns The 0-based bar index.
|
|
269
|
+
* @example
|
|
270
|
+
* ```ts
|
|
271
|
+
* import { barIndexAt, parseTimeSignature } from '@libraz/libcantus';
|
|
272
|
+
* const meters = [
|
|
273
|
+
* { startBeat: 0, ts: parseTimeSignature('4/4') },
|
|
274
|
+
* { startBeat: 8, ts: parseTimeSignature('3/4') },
|
|
275
|
+
* ];
|
|
276
|
+
* barIndexAt(11, meters); // 3
|
|
277
|
+
* ```
|
|
278
|
+
* @category Rhythm & Meter
|
|
279
|
+
*/
|
|
280
|
+
declare function barIndexAt(beatInQuarters: number, meter: MeterLike): number;
|
|
281
|
+
/**
|
|
282
|
+
* Length in quarter-note beats of the bar containing a beat.
|
|
283
|
+
*
|
|
284
|
+
* The meter-map counterpart of {@link beatsPerBar}, which answers for one
|
|
285
|
+
* signature and so cannot be asked about a piece that changes meter.
|
|
286
|
+
*
|
|
287
|
+
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
288
|
+
* @param meter A single signature, or the piece's meter map.
|
|
289
|
+
* @returns The bar length in quarter notes.
|
|
290
|
+
* @category Rhythm & Meter
|
|
291
|
+
*/
|
|
292
|
+
declare function beatsPerBarAt(beatInQuarters: number, meter: MeterLike): number;
|
|
293
|
+
/**
|
|
294
|
+
* Read the meter out of a pair of options that accept either form.
|
|
295
|
+
*
|
|
296
|
+
* Entry points take `meters` for a piece that changes meter and keep `ts` as
|
|
297
|
+
* sugar for a piece that does not, so this is the one place that resolves the
|
|
298
|
+
* pair — including the rule that naming both is an input error rather than one
|
|
299
|
+
* of them silently winning.
|
|
300
|
+
*
|
|
301
|
+
* @param opts The options carrying `ts`, `meters`, or neither.
|
|
302
|
+
* @param name What the options belong to, for the error message.
|
|
303
|
+
* @returns The meter map to analyse against; 4/4 throughout when neither is given.
|
|
304
|
+
* @throws If both `ts` and `meters` are given, or the map is malformed.
|
|
305
|
+
* @example
|
|
306
|
+
* ```ts
|
|
307
|
+
* import { parseTimeSignature, resolveMeters } from '@libraz/libcantus';
|
|
308
|
+
* resolveMeters({ ts: parseTimeSignature('3/4') });
|
|
309
|
+
* // [{ startBeat: 0, ts: { numerator: 3, denominator: 4 } }]
|
|
310
|
+
* ```
|
|
311
|
+
* @category Rhythm & Meter
|
|
312
|
+
*/
|
|
313
|
+
declare function resolveMeters(opts: {
|
|
314
|
+
ts?: TimeSignature;
|
|
315
|
+
meters?: MeterMap;
|
|
316
|
+
}, name?: string): MeterMap;
|
|
317
|
+
/**
|
|
318
|
+
* Number of main pulses (felt beats) per bar: the numerator for simple meters,
|
|
319
|
+
* a third of it for compound meters.
|
|
320
|
+
*
|
|
321
|
+
* For additive/irregular meters such as 7/8 or 5/8 this counts the raw pulses
|
|
322
|
+
* (7 and 5 respectively), which are otherwise felt as flat, evenly divided and
|
|
323
|
+
* equally accented pulses. To recover a 2+2+3 or 3+2 felt-beat grouping, set
|
|
324
|
+
* {@link TimeSignature.grouping}; {@link metricWeight} then accents each
|
|
325
|
+
* group's head pulse.
|
|
326
|
+
*
|
|
327
|
+
* @param ts The time signature.
|
|
328
|
+
* @returns The pulse count per bar.
|
|
329
|
+
* @category Rhythm & Meter
|
|
330
|
+
*/
|
|
331
|
+
declare function pulsesPerBar(ts: TimeSignature): number;
|
|
332
|
+
/**
|
|
333
|
+
* Convert an absolute quarter-note position to a bar index and in-bar offset.
|
|
334
|
+
*
|
|
335
|
+
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
336
|
+
* @param meter A single signature, or the piece's meter map.
|
|
337
|
+
* @returns The bar and in-bar quarter-note offset.
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* import { parseTimeSignature, beatToBarPosition } from '@libraz/libcantus';
|
|
341
|
+
* const ts = parseTimeSignature('4/4');
|
|
342
|
+
* beatToBarPosition(5, ts); // { bar: 1, beat: 1 }
|
|
343
|
+
* ```
|
|
344
|
+
* @category Rhythm & Meter
|
|
345
|
+
*/
|
|
346
|
+
declare function beatToBarPosition(beatInQuarters: number, meter: MeterLike): BarPosition;
|
|
347
|
+
/**
|
|
348
|
+
* Length of one felt beat (main pulse) in quarter-note beats.
|
|
349
|
+
*
|
|
350
|
+
* A quarter note in simple meters, a dotted quarter in compound ones, and one
|
|
351
|
+
* denominator unit in an additive metre. Position displays, click tracks, and
|
|
352
|
+
* score export are all written against this length.
|
|
353
|
+
*
|
|
354
|
+
* @param ts The time signature.
|
|
355
|
+
* @returns The pulse length in quarter-note beats.
|
|
356
|
+
* @example
|
|
357
|
+
* ```ts
|
|
358
|
+
* import { parseTimeSignature, pulseBeats } from '@libraz/libcantus';
|
|
359
|
+
* pulseBeats(parseTimeSignature('6/8')); // 1.5
|
|
360
|
+
* ```
|
|
361
|
+
* @category Rhythm & Meter
|
|
362
|
+
*/
|
|
363
|
+
declare function pulseBeats(ts: TimeSignature): number;
|
|
364
|
+
/**
|
|
365
|
+
* The felt-beat number of a bar position, 1-based.
|
|
366
|
+
*
|
|
367
|
+
* {@link BarPosition.beat} is a quarter-note offset, so in 6/8 the second felt
|
|
368
|
+
* beat reads as 1.5. This is the number a musician says and a position display
|
|
369
|
+
* shows.
|
|
370
|
+
*
|
|
371
|
+
* @param pos The bar position.
|
|
372
|
+
* @param meter A single signature, or the piece's meter map.
|
|
373
|
+
* @returns The 1-based felt-beat number, fractional between pulses.
|
|
374
|
+
* @example
|
|
375
|
+
* ```ts
|
|
376
|
+
* import { barPositionToPulse, parseTimeSignature } from '@libraz/libcantus';
|
|
377
|
+
* barPositionToPulse({ bar: 0, beat: 1.5 }, parseTimeSignature('6/8')); // 2
|
|
378
|
+
* ```
|
|
379
|
+
* @category Rhythm & Meter
|
|
380
|
+
*/
|
|
381
|
+
declare function barPositionToPulse(pos: BarPosition, meter: MeterLike): number;
|
|
382
|
+
/**
|
|
383
|
+
* Render an absolute position as the `bar.beat` a DAW or a score shows:
|
|
384
|
+
* 1-based bar, 1-based felt beat.
|
|
385
|
+
*
|
|
386
|
+
* The felt beats counted are the ones the bar actually has. A meter change
|
|
387
|
+
* starts a new bar, so the bar it interrupts is short, and a position that
|
|
388
|
+
* rounds past the end of a short bar reads as the downbeat of the next one
|
|
389
|
+
* rather than as a beat the bar never reached.
|
|
390
|
+
*
|
|
391
|
+
* @param beatInQuarters Absolute position in quarter-note beats.
|
|
392
|
+
* @param meter A single signature, or the piece's meter map.
|
|
393
|
+
* @param decimals Digits of the fractional beat to keep.
|
|
394
|
+
* @returns The formatted position, e.g. `'3.2'` for bar 3, felt beat 2.
|
|
395
|
+
* @example
|
|
396
|
+
* ```ts
|
|
397
|
+
* import { formatBarPosition, parseTimeSignature } from '@libraz/libcantus';
|
|
398
|
+
* formatBarPosition(7.5, parseTimeSignature('6/8')); // '3.2'
|
|
399
|
+
* ```
|
|
400
|
+
* @category Rhythm & Meter
|
|
401
|
+
*/
|
|
402
|
+
declare function formatBarPosition(beatInQuarters: number, meter: MeterLike, decimals?: number): string;
|
|
403
|
+
/**
|
|
404
|
+
* Convert a bar index and in-bar offset back to an absolute quarter-note
|
|
405
|
+
* position.
|
|
406
|
+
*
|
|
407
|
+
* @param pos The bar position.
|
|
408
|
+
* @param meter A single signature, or the piece's meter map.
|
|
409
|
+
* @returns The absolute position in quarter-note beats.
|
|
410
|
+
* @category Rhythm & Meter
|
|
411
|
+
*/
|
|
412
|
+
declare function barPositionToBeat(pos: BarPosition, meter: MeterLike): number;
|
|
413
|
+
/**
|
|
414
|
+
* Metric weight of a position within its bar, on a 0–3 scale:
|
|
415
|
+
* 3 the downbeat, 2 a secondary strong pulse, 1 any other main pulse, and 0 an
|
|
416
|
+
* off-pulse subdivision.
|
|
417
|
+
*
|
|
418
|
+
* The secondary strong pulse is the bar's midpoint in even simple/compound
|
|
419
|
+
* meters. For an additive/irregular meter with {@link TimeSignature.grouping}
|
|
420
|
+
* set (e.g. `[2, 2, 3]` for 7/8), each group's head pulse other than the
|
|
421
|
+
* downbeat is the secondary strong pulse instead; without a grouping every
|
|
422
|
+
* non-downbeat main pulse of such a meter weighs 1 (flat, evenly divided
|
|
423
|
+
* pulses). A grouping of equal-length groups (9/8 as `[1, 1, 1]`, 4/4 as
|
|
424
|
+
* `[1, 1, 1, 1]`) states the division the meter already has, so it weighs as
|
|
425
|
+
* an ungrouped bar rather than accenting every group head.
|
|
426
|
+
*
|
|
427
|
+
* Given a meter map, the weight follows the signature in force at that beat, so
|
|
428
|
+
* beat 5 of a piece is a mid-bar accent in 4/4 and a plain main pulse in 3/4.
|
|
429
|
+
* The downbeat is beat 0 however much pickup precedes it, so a note in the
|
|
430
|
+
* pickup weighs as the upbeat it is rather than as a downbeat.
|
|
431
|
+
*
|
|
432
|
+
* @param beatInQuarters Absolute quarter-note position, or an in-bar offset
|
|
433
|
+
* when the meter is a single signature.
|
|
434
|
+
* @param meter A single signature, or the piece's meter map.
|
|
435
|
+
* @returns The metric weight (0–3).
|
|
436
|
+
* @throws If the meter is malformed, including a grouping that is not a
|
|
437
|
+
* positive-integer list summing to the pulse count or the numerator.
|
|
438
|
+
* @example
|
|
439
|
+
* ```ts
|
|
440
|
+
* import { parseTimeSignature, metricWeight } from '@libraz/libcantus';
|
|
441
|
+
* const ts = parseTimeSignature('4/4');
|
|
442
|
+
* metricWeight(0, ts); // 3 (the downbeat)
|
|
443
|
+
* ```
|
|
444
|
+
* @category Rhythm & Meter
|
|
445
|
+
*/
|
|
446
|
+
declare function metricWeight(beatInQuarters: number, meter: MeterLike): number;
|
|
447
|
+
/**
|
|
448
|
+
* Whether a position is metrically accented (weight 2 or more — a downbeat or a
|
|
449
|
+
* secondary strong pulse).
|
|
450
|
+
*
|
|
451
|
+
* @param beatInQuarters Absolute quarter-note position, or an in-bar offset
|
|
452
|
+
* when the meter is a single signature.
|
|
453
|
+
* @param meter A single signature, or the piece's meter map.
|
|
454
|
+
* @returns True on strong beats.
|
|
455
|
+
* @category Rhythm & Meter
|
|
456
|
+
*/
|
|
457
|
+
declare function isStrongBeat(beatInQuarters: number, meter: MeterLike): boolean;
|
|
458
|
+
/**
|
|
459
|
+
* Subdivide a span into `count` equal tuplet durations (e.g. an eighth-note
|
|
460
|
+
* triplet is `tuplet(1, 3)`).
|
|
461
|
+
*
|
|
462
|
+
* @param totalBeats Total span in quarter-note beats.
|
|
463
|
+
* @param count Number of equal parts.
|
|
464
|
+
* @returns `count` equal durations summing to `totalBeats`.
|
|
465
|
+
* @throws If `count` is not a positive integer.
|
|
466
|
+
* @category Rhythm & Meter
|
|
467
|
+
*/
|
|
468
|
+
declare function tuplet(totalBeats: number, count: number): number[];
|
|
469
|
+
|
|
470
|
+
export { type BarPosition as B, type MeterChange as M, type TimeSignature as T, type MeterData as a, type MeterLike as b, type MeterMap as c, barIndexAt as d, barPositionToBeat as e, barPositionToPulse as f, barStartBeat as g, beatToBarPosition as h, beatsPerBar as i, beatsPerBarAt as j, formatBarPosition as k, formatTimeSignature as l, isCompound as m, isStrongBeat as n, meterAt as o, metricWeight as p, parseTimeSignature as q, pulseBeats as r, pulsesPerBar as s, resolveMeters as t, toMeterData as u, tryParseTimeSignature as v, tuplet as w };
|