tonus 0.1.8 → 0.5.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/BIBLIOGRAPHY.md +132 -108
- package/CHANGELOG.md +598 -1
- package/LICENSE +133 -29
- package/README.md +106 -83
- package/dist/data/am.js +2666 -11196
- package/dist/data/ams.d.ts +5 -0
- package/dist/data/ams.js +122 -0
- package/dist/data/attestation.d.ts +19 -0
- package/dist/data/attestation.js +15716 -0
- package/dist/data/attestation.json +15711 -0
- package/dist/data/cadentiae.d.ts +43 -0
- package/dist/data/cadentiae.js +174 -0
- package/dist/data/cal.js +48 -0
- package/dist/data/census.d.ts +12 -0
- package/dist/data/census.js +36 -0
- package/dist/data/commune-office.d.ts +4 -0
- package/dist/data/commune-office.js +2371 -0
- package/dist/data/commune-office.json +2365 -0
- package/dist/data/commune.js +181 -11
- package/dist/data/corpus-overlap.d.ts +17 -0
- package/dist/data/corpus-overlap.js +299 -5
- package/dist/data/cot.d.ts +5 -0
- package/dist/data/cot.js +172 -0
- package/dist/data/cse.d.ts +5 -0
- package/dist/data/cse.js +122 -0
- package/dist/data/gabc-glyphs.d.ts +45 -0
- package/dist/data/gabc-glyphs.js +122 -0
- package/dist/data/gr.js +754 -6394
- package/dist/data/kyriale.js +116 -116
- package/dist/data/la.js +799 -13419
- package/dist/data/lh.js +113 -3473
- package/dist/data/lu.js +931 -17631
- package/dist/data/nocturnale-romanum.js +1659 -10411
- package/dist/data/office-ferial.d.ts +4 -0
- package/dist/data/office-ferial.js +396 -0
- package/dist/data/office-ferial.json +391 -0
- package/dist/data/office-monastic.d.ts +17 -1
- package/dist/data/office-monastic.js +1403 -466
- package/dist/data/office-psalms-monastic.d.ts +13 -1
- package/dist/data/office-psalms-monastic.js +9 -0
- package/dist/data/propers.js +1 -1
- package/dist/data/psalms.js +22919 -5
- package/dist/data/psm.d.ts +5 -0
- package/dist/data/psm.js +122 -0
- package/dist/data/seasonal-respbreve.d.ts +5 -0
- package/dist/data/seasonal-respbreve.js +41 -0
- package/dist/data/seasonal-respbreve.json +35 -0
- package/dist/data/smufl-glyphs.d.ts +17 -0
- package/dist/data/smufl-glyphs.js +1546 -0
- package/dist/data/smufl-glyphs.json +1530 -0
- package/dist/engines/cal/calendar.d.ts +3 -2
- package/dist/engines/cal/calendar.js +105 -29
- package/dist/engines/cal/data/eras.d.ts +35 -0
- package/dist/engines/cal/data/eras.js +128 -0
- package/dist/engines/cal/date.js +44 -0
- package/dist/engines/cal/types.d.ts +15 -3
- package/dist/engines/cal/types.js +5 -5
- package/dist/engines/census/census.d.ts +7 -0
- package/dist/engines/census/census.js +179 -0
- package/dist/engines/census/types.d.ts +55 -0
- package/dist/engines/census/types.js +8 -0
- package/dist/engines/chant/attest.d.ts +39 -0
- package/dist/engines/chant/attest.js +90 -0
- package/dist/engines/chant/chant.d.ts +16 -4
- package/dist/engines/chant/chant.js +220 -30
- package/dist/engines/chant/data/compline.js +2 -1
- package/dist/engines/chant/data/masses.d.ts +56 -4
- package/dist/engines/chant/data/masses.js +305 -80
- package/dist/engines/chant/data/prime.js +1 -1
- package/dist/engines/chant/hour.js +279 -58
- package/dist/engines/chant/ordinary.d.ts +2 -0
- package/dist/engines/chant/ordinary.js +336 -56
- package/dist/engines/chant/propers.js +55 -5
- package/dist/engines/chant/psalm.d.ts +4 -4
- package/dist/engines/chant/psalm.js +25 -11
- package/dist/engines/chant/syllabify.d.ts +1 -0
- package/dist/engines/chant/syllabify.js +90 -17
- package/dist/engines/chant/types.d.ts +115 -12
- package/dist/engines/chant/types.js +38 -3
- package/dist/engines/harmonia/api.js +4 -0
- package/dist/engines/harmonia/data/doctrines.js +3 -1
- package/dist/engines/harmonia/tabula.d.ts +3 -0
- package/dist/engines/harmonia/tabula.js +1 -0
- package/dist/engines/harmonia/voice.d.ts +4 -0
- package/dist/engines/harmonia/voice.js +8 -4
- package/dist/engines/imprint.js +14 -1
- package/dist/engines/planet/orbital.js +4 -4
- package/dist/engines/planet/planet.d.ts +10 -0
- package/dist/engines/planet/planet.js +30 -3
- package/dist/engines/planet/position.js +13 -10
- package/dist/engines/planet/types.d.ts +1 -0
- package/dist/engines/score/api.d.ts +2 -13
- package/dist/engines/score/api.js +21 -8
- package/dist/engines/score/articulation.js +2 -2
- package/dist/engines/score/cadence.d.ts +76 -0
- package/dist/engines/score/cadence.js +96 -0
- package/dist/engines/score/emitters/accidentals.d.ts +21 -0
- package/dist/engines/score/emitters/accidentals.js +88 -0
- package/dist/engines/score/emitters/atramentum.d.ts +107 -0
- package/dist/engines/score/emitters/atramentum.js +239 -0
- package/dist/engines/score/emitters/breaking.d.ts +62 -0
- package/dist/engines/score/emitters/breaking.js +80 -0
- package/dist/engines/score/emitters/moderna.d.ts +38 -0
- package/dist/engines/score/emitters/moderna.js +612 -0
- package/dist/engines/score/emitters/svg.d.ts +143 -0
- package/dist/engines/score/emitters/svg.js +1328 -0
- package/dist/engines/score/emitters/tracks.d.ts +104 -0
- package/dist/engines/score/emitters/tracks.js +728 -0
- package/dist/engines/score/infer.d.ts +3 -3
- package/dist/engines/score/infer.js +2 -2
- package/dist/engines/score/inscriptio.d.ts +69 -0
- package/dist/engines/score/inscriptio.js +138 -0
- package/dist/engines/score/ir.d.ts +2 -2
- package/dist/engines/score/ir.js +59 -12
- package/dist/engines/score/lyric.d.ts +23 -0
- package/dist/engines/score/lyric.js +234 -0
- package/dist/engines/score/meta.d.ts +2 -2
- package/dist/engines/score/modulation.d.ts +12 -0
- package/dist/engines/score/modulation.js +49 -0
- package/dist/engines/score/neume.js +35 -4
- package/dist/engines/score/parse.js +150 -9
- package/dist/engines/score/phrasing.js +4 -3
- package/dist/engines/score/prosody.d.ts +38 -0
- package/dist/engines/score/prosody.js +70 -6
- package/dist/engines/score/tabula.d.ts +37 -5
- package/dist/engines/score/tabula.js +18 -0
- package/dist/engines/score/types.d.ts +88 -1
- package/dist/engines/temper/api.d.ts +4 -1
- package/dist/engines/temper/api.js +28 -5
- package/dist/engines/temper/data/guido.js +6 -2
- package/dist/engines/temper/data/modes.d.ts +6 -0
- package/dist/engines/temper/data/modes.js +42 -0
- package/dist/engines/temper/data/tones.d.ts +1 -1
- package/dist/engines/temper/data/tones.js +20 -11
- package/dist/engines/temper/interval.js +4 -3
- package/dist/engines/temper/modality.d.ts +11 -2
- package/dist/engines/temper/modality.js +74 -2
- package/dist/engines/temper/modes.d.ts +1 -1
- package/dist/engines/temper/pitch.d.ts +1 -1
- package/dist/engines/temper/pitch.js +12 -2
- package/dist/engines/temper/scale.d.ts +53 -0
- package/dist/engines/temper/scale.js +107 -8
- package/dist/index.d.ts +26 -8
- package/dist/index.js +37 -4
- package/docs/api/calendar.md +279 -0
- package/docs/api/census.md +288 -0
- package/docs/api/chant.md +657 -0
- package/docs/api/heavens.md +346 -0
- package/docs/api/index.md +263 -0
- package/docs/api/score.md +873 -0
- package/docs/api/tuning.md +619 -0
- package/package.json +11 -5
- package/dist/data/office-matins-roman.d.ts +0 -19
- package/dist/data/office-matins-roman.js +0 -4383
- package/dist/data/office-psalms-roman.d.ts +0 -15
- package/dist/data/office-psalms-roman.js +0 -28
- package/dist/data/office-roman.d.ts +0 -19
- package/dist/data/office-roman.js +0 -13792
- package/dist/engines/chant/matutinum.d.ts +0 -33
- package/dist/engines/chant/matutinum.js +0 -81
- package/dist/engines/score/emitters/midi.d.ts +0 -65
- package/dist/engines/score/emitters/midi.js +0 -162
- package/dist/engines/score/emitters/musicxml.d.ts +0 -18
- package/dist/engines/score/emitters/musicxml.js +0 -166
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
# Chant
|
|
2
|
+
|
|
3
|
+
The chant engines retrieve the sung repertoire. `cantus` searches the
|
|
4
|
+
corpora at large and parses raw GABC; `proprium` supplies the Mass propers
|
|
5
|
+
of a feast; `ordinarium` the Kyriale settings appropriate to it;
|
|
6
|
+
`officium` the chants of the canonical hours; `psalmus` psalm and canticle
|
|
7
|
+
verses intoned to the psalm tones. Every melody is GABC-encoded and
|
|
8
|
+
carries page-level provenance back to its book.
|
|
9
|
+
|
|
10
|
+
- [Chant](#chant)
|
|
11
|
+
- [The corpora](#the-corpora)
|
|
12
|
+
- [The cut](#the-cut)
|
|
13
|
+
- [The books — `corpus`](#the-books--corpus)
|
|
14
|
+
- [The ledger of the cut — `full`](#the-ledger-of-the-cut--full)
|
|
15
|
+
- [Retrieval — `cantus`](#retrieval--cantus)
|
|
16
|
+
- [Reaching the ordinary — `ordinary`](#reaching-the-ordinary--ordinary)
|
|
17
|
+
- [On chant ids](#on-chant-ids)
|
|
18
|
+
- [The repertoire as of a date — the era view](#the-repertoire-as-of-a-date--the-era-view)
|
|
19
|
+
- [The Mass propers — `proprium`](#the-mass-propers--proprium)
|
|
20
|
+
- [The ordinary — `ordinarium`](#the-ordinary--ordinarium)
|
|
21
|
+
- [The Office — `officium`](#the-office--officium)
|
|
22
|
+
- [One cursus, the Benedictine](#one-cursus-the-benedictine)
|
|
23
|
+
- [Psalms — `psalmus`](#psalms--psalmus)
|
|
24
|
+
- [Theory \& Context](#theory--context)
|
|
25
|
+
- [The Solesmes restoration](#the-solesmes-restoration)
|
|
26
|
+
- [GABC: neumes as text](#gabc-neumes-as-text)
|
|
27
|
+
- [The Mass: proper and ordinary](#the-mass-proper-and-ordinary)
|
|
28
|
+
- [The Office: the daily cursus](#the-office-the-daily-cursus)
|
|
29
|
+
- [Psalm tones](#psalm-tones)
|
|
30
|
+
|
|
31
|
+
## The corpora
|
|
32
|
+
|
|
33
|
+
Nine Solesmes books, extracted from
|
|
34
|
+
[GregoBase](https://gregobase.selapa.net/), joined by the Divinum Officium
|
|
35
|
+
propers, office, and psalter, plus the Nocturnale Romanum for the night office:
|
|
36
|
+
|
|
37
|
+
| Source | Book | Edition | Chants |
|
|
38
|
+
| ------ | --------------------------------- | ------------------ | ------ |
|
|
39
|
+
| `gr` | Graduale Romanum | Solesmes, 1961 | 780 |
|
|
40
|
+
| `lu` | The Liber Usualis | Solesmes, 1961 | 707 |
|
|
41
|
+
| `la` | Liber antiphonarius | Solesmes, 1960 | 160 |
|
|
42
|
+
| `lh` | Liber Hymnarius | Solesmes, 1983 | 25 |
|
|
43
|
+
| `am` | Antiphonale Monasticum | Solesmes, 1934 | 576 |
|
|
44
|
+
| `ams` | Antiphonale Monasticum Solesmense | Solesmes, 1935 | 11 |
|
|
45
|
+
| `psm` | Psalterium Monasticum | Solesmes, 1981 | 11 |
|
|
46
|
+
| `cse` | Cantus selecti | Solesmes, 1957 | 11 |
|
|
47
|
+
| `cot` | Chants of the Church | Solesmes, 1956 | 16 |
|
|
48
|
+
| `nr` | Nocturnale Romanum | Sandhofe, 2002 | 470 |
|
|
49
|
+
|
|
50
|
+
**2,187 chants in all**, plus the Mass ordinary (120 settings, reached by
|
|
51
|
+
[`ordinary`](#reaching-the-ordinary--ordinary) rather than by book). The books
|
|
52
|
+
hold 10,156 between them; tonus ships only what the calendar calls for on some
|
|
53
|
+
day of the year, so a chant with no day to be sung on is not here. See
|
|
54
|
+
[The cut](#the-cut) below.
|
|
55
|
+
|
|
56
|
+
The ten books list 2,767 rows for those 2,187 chants: a melody printed in two
|
|
57
|
+
books is stored once and listed under both.
|
|
58
|
+
|
|
59
|
+
`am`, `ams`, and `psm` are the monastic (Benedictine) books; the rest are
|
|
60
|
+
Roman. Every book here bears the rhythmic markings the score engine reads; that
|
|
61
|
+
is the admission rule. `nr` is the night-office repertoire (responsories,
|
|
62
|
+
antiphons) from the
|
|
63
|
+
[Nocturnale Romanum](https://github.com/Nocturnale-Romanum/nocturnale-romanum)
|
|
64
|
+
community restitution, the one non-Solesmes source, admitted because it carries
|
|
65
|
+
those marks too.
|
|
66
|
+
|
|
67
|
+
### The cut
|
|
68
|
+
|
|
69
|
+
The corpus is **assignment-driven**: a chant ships when some day of the
|
|
70
|
+
liturgical year calls for it. The calendar is walked year by year until it stops
|
|
71
|
+
finding new assignments (39 years, in the event), and what it never reaches is
|
|
72
|
+
not shipped — 10,156 book chants become 2,187.
|
|
73
|
+
|
|
74
|
+
Everything here answers "what was sung on this day". A query for a chant the
|
|
75
|
+
calendar never calls for returns nothing.
|
|
76
|
+
|
|
77
|
+
## The books — `corpus`
|
|
78
|
+
|
|
79
|
+
`corpus(code)` returns one book's bibliographic identity and a breakdown of what
|
|
80
|
+
it holds — how many chants, in what genres, in what modes. `corpus({ book })` is
|
|
81
|
+
the same question in the query form every other verb uses; both spellings return
|
|
82
|
+
one answer.
|
|
83
|
+
|
|
84
|
+
`corpus()` with no argument returns **the whole shelf** — the rollup plus every
|
|
85
|
+
book's ledger:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
tonus.corpus();
|
|
89
|
+
// { count: 2187, // chants tonus holds, each counted once
|
|
90
|
+
// listings: 2767, // rows on the shelf — a chant in two books appears twice
|
|
91
|
+
// total: 10156, // what the books hold, before the cut
|
|
92
|
+
// genera: [ { office: "an", genus: "Antiphona", count: 693 }, … ],
|
|
93
|
+
// modes: [ { mode: "1", modus: "Modus I", count: 392 }, … ],
|
|
94
|
+
// books: [ …10 Corpus entries, in registry order ] }
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**`count` is the number of chants** — the one to quote. `listings` is how long
|
|
98
|
+
the shelf is, and `listings - count` is 580 extra rows, over the 683 chants
|
|
99
|
+
printed in more than one book. The breakdowns describe the same population
|
|
100
|
+
`count` does, so `genera` and `modes` sum to it.
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
tonus.corpus("am");
|
|
104
|
+
// { code: "am", book: "Antiphonale Monasticum", fullTitle: null,
|
|
105
|
+
// edition: "Pro Diurnis Horis", year: 1934, editor: "Solesmes",
|
|
106
|
+
// scanSource: "Scans courtesy of Corpus Christi Watershed", count: 576,
|
|
107
|
+
// genera: [ { office: "an", genus: "Antiphona", count: 458 }, … ],
|
|
108
|
+
// modes: [ { mode: "1", modus: "Modus I", count: 101 }, …,
|
|
109
|
+
// { mode: null, modus: null, count: 24 } ] }
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
interface Corpus {
|
|
114
|
+
code: ChantSource;
|
|
115
|
+
book: string; // short title
|
|
116
|
+
fullTitle: string | null; // full Latin title, where the edition records one
|
|
117
|
+
edition: string | null; // edition note, else null
|
|
118
|
+
year: number | null;
|
|
119
|
+
editor: string | null;
|
|
120
|
+
scanSource: string | null; // scan attribution
|
|
121
|
+
count: number; // chants tonus stores (after dedup)
|
|
122
|
+
total: number | null; // chants the book holds (before dedup); null if unmeasured
|
|
123
|
+
unique: number | null; // chants in this book alone; null if unmeasured
|
|
124
|
+
shared: { code: ChantSource; count: number }[] | null; // shared per book, desc; null if unmeasured
|
|
125
|
+
genera: { office: OfficeCode; genus: string; count: number }[]; // descending
|
|
126
|
+
modes: { mode: string | null; modus: string | null; count: number }[];
|
|
127
|
+
full: { total: number; genera: GenusCount[]; modes: ModeCount[] } | null; // the pre-cut tally (below); null if unmeasured
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### The ledger of the cut — `full`
|
|
132
|
+
|
|
133
|
+
Every `Corpus` carries `full`: what the book HELD, before the keep set ran, in
|
|
134
|
+
the same genera/modes shape as the shipped counts.
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
const am = tonus.corpus("am");
|
|
138
|
+
am.count; // 576 — antiphons and the rest tonus kept
|
|
139
|
+
am.full.total; // 1456 — what the Antiphonale Monasticum holds
|
|
140
|
+
am.genera[0]; // { office: "an", genus: "Antiphona", count: 458 }
|
|
141
|
+
am.full.genera[0]; // { office: "an", genus: "Antiphona", count: 1049 }
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Reading the two tallies side by side names what was left out — 1,049 antiphons
|
|
145
|
+
in the book, 458 sung.
|
|
146
|
+
|
|
147
|
+
Only the extractor can measure this. By the time tonus loads, the keep set has
|
|
148
|
+
already run, so the pre-cut tally is read from an artifact rather than derived.
|
|
149
|
+
Every shelved book reports one, including the Nocturnale, whose tally comes
|
|
150
|
+
from its own extract rather than from GregoBase.
|
|
151
|
+
|
|
152
|
+
The metadata is drawn from GregoBase's own catalogue. The `genera` list is the
|
|
153
|
+
office distribution (descending by count); `modes` counts modes I–VIII, with a
|
|
154
|
+
final `mode: null` bucket for chants outside the eight modes (psalm tones and the
|
|
155
|
+
like) so the counts reconcile with `count`.
|
|
156
|
+
|
|
157
|
+
**Overlap.** tonus keeps one copy of each chant (the Liber Usualis is the primary
|
|
158
|
+
source; the Antiphonarius and Hymnarius fill gaps), so a book's stored `count`
|
|
159
|
+
undercounts what it holds. `total` is the full pre-dedup count, `unique` the
|
|
160
|
+
chants a book alone has, and `shared` how many it holds in common with each other
|
|
161
|
+
book (by GregoBase chant id). These reveal, for instance, that the Liber Usualis
|
|
162
|
+
is largely the Graduale and the Antiphonarius bound together (it shares hundreds
|
|
163
|
+
of chants with each), while the Antiphonale Monasticum is almost entirely its own.
|
|
164
|
+
|
|
165
|
+
The Nocturnale (`nr`) is compared differently, because it has no GregoBase
|
|
166
|
+
catalogue: its counts come from its own extract, and it shares **nothing** —
|
|
167
|
+
`unique` is all 1,564 chants it holds. That is a measurement, not a gap. The
|
|
168
|
+
nocturnale–GregoBase crosswalk is a route to metadata, not a claim that the two
|
|
169
|
+
books print the same chant, so it does not count as sharing.
|
|
170
|
+
|
|
171
|
+
The `null` those fields can still carry means **unmeasured**, distinct from a
|
|
172
|
+
measured zero, so a consumer never mistakes "not compared" for "shares
|
|
173
|
+
nothing".
|
|
174
|
+
|
|
175
|
+
## Retrieval — `cantus`
|
|
176
|
+
|
|
177
|
+
`cantus(query?)` searches across the corpora by id, incipit, mode, genre,
|
|
178
|
+
and source. Results sort by rank, then incipit; `limit` and `offset` page
|
|
179
|
+
through them.
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
tonus.cantus({ mode: 1, office: "an", source: "am", limit: 1 });
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
[
|
|
187
|
+
{
|
|
188
|
+
id: "gregobase:10082",
|
|
189
|
+
incipit: "Ait latro",
|
|
190
|
+
gabc: "(c4) A(d)it(f') la(d)tro(dc) ad(f) la(g)tró(f_h)nem:(h'_) *(,)…",
|
|
191
|
+
office: "an",
|
|
192
|
+
genus: "Antiphona",
|
|
193
|
+
mode: "1",
|
|
194
|
+
modus: "Modus I",
|
|
195
|
+
pages: [{ page: "439", sequence: 2, extent: 2 }],
|
|
196
|
+
source: {
|
|
197
|
+
book: "Antiphonale Monasticum",
|
|
198
|
+
fullTitle: null,
|
|
199
|
+
edition: "Pro Diurnis Horis",
|
|
200
|
+
year: 1934,
|
|
201
|
+
editor: "Solesmes",
|
|
202
|
+
scanSource: "Scans courtesy of Corpus Christi Watershed",
|
|
203
|
+
code: "am",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The Graduale is the Mass book and holds four antiphons in the shipped corpus,
|
|
210
|
+
so the same query against `source: "gr"` returns `[]`.
|
|
211
|
+
|
|
212
|
+
`cantus` also accepts raw GABC through the `gabc` field. The corpus is
|
|
213
|
+
bypassed and a single user `Chant` returns. The input may be a notation
|
|
214
|
+
body or a full GABC file (headers, `%%`, body); header values for `name`,
|
|
215
|
+
`mode`, and `office-part` are read automatically, and the `incipit`,
|
|
216
|
+
`mode`, and `office` query fields override them.
|
|
217
|
+
|
|
218
|
+
```js
|
|
219
|
+
// notation body
|
|
220
|
+
tonus.cantus({
|
|
221
|
+
gabc: "(c4) Sán(g)ctus(h) Sán(g)ctus(h)",
|
|
222
|
+
incipit: "Sanctus",
|
|
223
|
+
mode: 1,
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// full GABC file
|
|
227
|
+
tonus.cantus({
|
|
228
|
+
gabc: "name: Sanctus;\nmode: 1;\n%%\n(c4) Sán(g)ctus(h) Sán(g)ctus(h)",
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The `office` field is the genre code; `genus` carries the genre's Latin
|
|
233
|
+
name:
|
|
234
|
+
|
|
235
|
+
| `office` | `genus` | `office` | `genus` | `office` | `genus` |
|
|
236
|
+
| -------- | --------- | -------- | ------------ | -------- | ------------------ |
|
|
237
|
+
| `an` | Antiphona | `hy` | Hymnus | `rb` | Responsorium Breve |
|
|
238
|
+
| `al` | Alleluia | `in` | Introitus | `se` | Sequentia |
|
|
239
|
+
| `ca` | Canticum | `of` | Offertorium | `tr` | Tractus |
|
|
240
|
+
| `co` | Communio | `ps` | Psalmus | `tp` | Tonus Peregrinus |
|
|
241
|
+
| `gr` | Graduale | `re` | Responsorium | `or` | Ordinarium |
|
|
242
|
+
|
|
243
|
+
```ts
|
|
244
|
+
interface Chant {
|
|
245
|
+
id: string; // "gregobase:1210", "nocturnale:E1F2R3" — see below
|
|
246
|
+
incipit: string;
|
|
247
|
+
gabc: string;
|
|
248
|
+
office: OfficeCode; // genre code
|
|
249
|
+
genus: string; // Latin genre name, "Antiphona", "Introitus" …
|
|
250
|
+
mode: string | null; // raw from source: "1"–"8", differentia forms ("2d", "8g"), "p"/"d"/"e" …
|
|
251
|
+
modus: string | null; // Latin mode name, "Modus I"–"Modus VIII"
|
|
252
|
+
pages: { page: string; sequence: number; extent: number }[];
|
|
253
|
+
source: {
|
|
254
|
+
book: string;
|
|
255
|
+
year: number | null;
|
|
256
|
+
editor: string | null;
|
|
257
|
+
code?: ChantSource | "user";
|
|
258
|
+
fullTitle?: string; // the book's full Latin title
|
|
259
|
+
edition?: string;
|
|
260
|
+
scanSource?: string; // scan attribution (GregoBase catalogue)
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
interface CantusQuery {
|
|
265
|
+
id?: string | string[];
|
|
266
|
+
gabc?: string;
|
|
267
|
+
incipit?: string;
|
|
268
|
+
mode?: number | string | (number | string)[];
|
|
269
|
+
office?: OfficeCode | OfficeCode[];
|
|
270
|
+
source?: ChantSource | ChantSource[];
|
|
271
|
+
ordinary?: OrdinaryCode | OrdinaryCode[]; // a part of the Mass ordinary
|
|
272
|
+
before?: number; // only chants ATTESTED by this year (the era view)
|
|
273
|
+
cursus?: "monastic" | "secular"; // transmission; `both` satisfies either
|
|
274
|
+
limit?: number;
|
|
275
|
+
offset?: number;
|
|
276
|
+
sort?: "incipit" | "mode" | "id";
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Reaching the ordinary — `ordinary`
|
|
281
|
+
|
|
282
|
+
The Mass ordinary is addressable but not shelved. `ordinary` is the door:
|
|
283
|
+
|
|
284
|
+
```js
|
|
285
|
+
tonus.cantus({ ordinary: "ky" }); // all 31 Kyries
|
|
286
|
+
tonus.cantus({ ordinary: "gl", mode: 4 }); // mode-4 Glorias
|
|
287
|
+
tonus.cantus({ ordinary: ["as", "va"] }); // the sprinkle antiphons
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The Kyriale is a **partition of the Graduale**, so it is not a `source` and not
|
|
291
|
+
a row in the shelf. It stays nameable by `id` and by the part of the Mass it
|
|
292
|
+
belongs to.
|
|
293
|
+
|
|
294
|
+
A plain search does not sweep it in: `{ mode: 5 }` returns the shelf. Ask for a
|
|
295
|
+
Kyrie and you get Kyries.
|
|
296
|
+
|
|
297
|
+
For the setting a given DAY calls for, [`ordinarium`](#the-ordinary--ordinarium)
|
|
298
|
+
is the verb — it applies the Kyriale's own rubrics. This is flat retrieval.
|
|
299
|
+
|
|
300
|
+
### On chant ids
|
|
301
|
+
|
|
302
|
+
An id's prefix names **the catalogue the identifier came from** — not the book
|
|
303
|
+
the chant is printed in, and not a claim about who the melody belongs to. A
|
|
304
|
+
chant carrying `gregobase:1210` is a Solesmes book chant that GregoBase happens
|
|
305
|
+
to have catalogued; the corpus is assembled from ten books, and GregoBase is
|
|
306
|
+
one source among several.
|
|
307
|
+
|
|
308
|
+
The prefix is therefore **not a namespace you can query against**. GregoBase
|
|
309
|
+
holds 18,148 chants; tonus ships 1,717 of them — 9.5% — because the corpus is
|
|
310
|
+
assignment-driven, so an id copied from the GregoBase site will usually return
|
|
311
|
+
`[]` here. That is not a lookup failure; it means no day of the calendar calls
|
|
312
|
+
for that chant. The two prefixes in the shipped corpus are `gregobase:` (1,717)
|
|
313
|
+
and `nocturnale:` (470), the latter carrying the Nocturnale's own alphanumeric
|
|
314
|
+
keys rather than numbers.
|
|
315
|
+
|
|
316
|
+
Within tonus an id is exactly one chant. A melody printed in several books —
|
|
317
|
+
683 of them are — is stored once, under the record `cantus({ id })` returns, so
|
|
318
|
+
`id` is a stable key to a chant rather than to a printing.
|
|
319
|
+
|
|
320
|
+
## The repertoire as of a date — the era view
|
|
321
|
+
|
|
322
|
+
`before: 1098` keeps only chants a manuscript of the 10th century or earlier
|
|
323
|
+
already holds. This is **evidence, not existence**: the dates come from
|
|
324
|
+
CANTUS's manuscript index, a terminus ante quem, so the filter answers "what
|
|
325
|
+
is attested by then," never "what existed then" — and a chant with no dated
|
|
326
|
+
witness is excluded rather than assumed old. CANTUS dates only to the century,
|
|
327
|
+
so a year admits the centuries that have CLOSED before it (`before: 1098` →
|
|
328
|
+
through the 900s).
|
|
329
|
+
|
|
330
|
+
The view is the analogue of
|
|
331
|
+
[`festum({ before })`](calendar.md#the-day-as-of-a-year--before) over the
|
|
332
|
+
calendar, and the two **compose**: a feast resolved under a view carries it,
|
|
333
|
+
and every day verb serves the same view unasked.
|
|
334
|
+
|
|
335
|
+
```js
|
|
336
|
+
const [easter] = tonus.festum({ date: new Date("2026-04-05"), before: 1100 });
|
|
337
|
+
tonus.proprium({ feast: easter }); // only propers attested by 1100
|
|
338
|
+
tonus.ordinarium({ feast: easter }); // the ordinary the view attests
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
What happens to a slot the view excludes differs by verb, on the rubric's
|
|
342
|
+
own logic: `ordinarium` **re-picks** — the Kyriale offers ranked
|
|
343
|
+
alternatives by design, so the rotation runs over the admissible pool and
|
|
344
|
+
the day still sings. `proprium` and `officium` have no pool
|
|
345
|
+
of alternatives, so an excluded chant **falls silent**. A `before` given to a
|
|
346
|
+
day verb directly overrides the feast's view; an invalid one throws at every
|
|
347
|
+
door.
|
|
348
|
+
|
|
349
|
+
## The Mass propers — `proprium`
|
|
350
|
+
|
|
351
|
+
`proprium(query?)` retrieves the chants whose texts change with the day:
|
|
352
|
+
Introitus, Graduale, Alleluia or Tractus, Offertorium, Communio. A feast
|
|
353
|
+
narrows the result to its own propers.
|
|
354
|
+
|
|
355
|
+
```js
|
|
356
|
+
const [feast] = tonus.festum({ date: new Date("2026-12-25") });
|
|
357
|
+
tonus.proprium({ feast, office: "in" });
|
|
358
|
+
// Puer natus est — Introitus, Modus VII, Liber Usualis p. 408
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Coverage is 689 proper formularies. When a feast has no dedicated proper for a
|
|
362
|
+
slot, the Commune Sanctorum (formularies for classes of saints) supplies it
|
|
363
|
+
through 48 commune sets and 254 feast-to-commune mappings.
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
interface PropriumQuery extends CantusQuery {
|
|
367
|
+
feast?: Feast | Feast[];
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## The ordinary — `ordinarium`
|
|
372
|
+
|
|
373
|
+
`ordinarium(query?)` retrieves the fixed chants of the Mass from the
|
|
374
|
+
Kyriale. A feast drives mass selection through its `masses` list — the
|
|
375
|
+
masses the day's Kyriale RUBRIC appoints, derived as described in
|
|
376
|
+
[calendar.md](calendar.md#the-days-feasts--festum); `mass` pins a kyriale
|
|
377
|
+
number directly. Where the rubric names several masses, the year rotates
|
|
378
|
+
through them (same feast, same year → same answer, every time), and sibling
|
|
379
|
+
printings under one number (Mass I prints two dismissals; Mass XVII prints
|
|
380
|
+
Kyrie A/B/C) rotate with it. Slots resolve independently, which the book
|
|
381
|
+
licenses outright — "chants from one Mass may be used together with those
|
|
382
|
+
from others" — with one exception, the book's own: **"the Ferial Masses
|
|
383
|
+
excepted."** Under a ferial rubric the sung ordinary is not gathered from
|
|
384
|
+
several masses; only the dismissal travels.
|
|
385
|
+
|
|
386
|
+
```js
|
|
387
|
+
const [easter] = tonus.festum({ date: new Date("2026-04-05") });
|
|
388
|
+
tonus.ordinarium({ feast: easter });
|
|
389
|
+
// ky Kyrie I (mass 1) — Lux et origo, Paschal time, every year
|
|
390
|
+
// gl Gloria I (mass 1)
|
|
391
|
+
// cr Credo III (mass 3) — the credo rotates on its own cycle
|
|
392
|
+
// sa Sanctus I (mass 1)
|
|
393
|
+
// ag Agnus Dei I (mass 1)
|
|
394
|
+
// it Ite Ia (mass 1)
|
|
395
|
+
// va Vidi aquam (mass 0) — the Paschaltide sprinkling antiphon rides along
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
The **Gloria follows the day's rank rubric, not its season**: the ferial
|
|
399
|
+
masses print none (XVI, XVIII) and the penitential-Sunday mass none (XVII),
|
|
400
|
+
while a I-class feast inside Advent or Lent — the Immaculate Conception —
|
|
401
|
+
keeps its Gloria. At a Gloria-less Mass the dismissal is the Benedicamus
|
|
402
|
+
Domino, and a mass with no dismissal of its own borrows one exactly as the
|
|
403
|
+
book directs: "Benedicamus Domino **as in Mass II**" — so a green feria
|
|
404
|
+
sings Mass XVI whole with the Mass II Benedicamus. The ad libitum appendix
|
|
405
|
+
is a **solemnity boost**, reachable only under the festal rubrics (it takes
|
|
406
|
+
its turn in the rotation once every _n + 1_ years); it never reaches a
|
|
407
|
+
penitential day or a feria, and the Requiem settings stay out of every
|
|
408
|
+
calendar-driven pick (reachable by `ordinarium({ mass: 102 })` only). The
|
|
409
|
+
Triduum returns no ordinary at all: Good Friday has no Mass, and the
|
|
410
|
+
Vigil's ordinary belongs to Easter. A pinned `mass` overrides the Triduum
|
|
411
|
+
rule and the rotation both.
|
|
412
|
+
|
|
413
|
+
**Maundy Thursday** (In Cena Domini) is the Triduum's exception: it keeps a
|
|
414
|
+
full Mass with the Gloria, its ordinary fixed to Mass I (Lux et origo).
|
|
415
|
+
|
|
416
|
+
The sprinkle rite (aspersion before the principal Sunday Mass) is appended
|
|
417
|
+
and selected by season: **Vidi aquam** (`va`) in Paschaltide, **Asperges
|
|
418
|
+
me** (`as`) otherwise.
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
tonus.ordinarium({ ordinary: "ky" }); // every Kyrie
|
|
422
|
+
tonus.ordinarium({ mass: 9, ordinary: "gl" }); // Gloria of Cum jubilo
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
| `ordinary` | `ordinarium` |
|
|
426
|
+
| ---------- | --------------------------------------------- |
|
|
427
|
+
| `ky` | Kyrie eleison |
|
|
428
|
+
| `gl` | Gloria |
|
|
429
|
+
| `cr` | Credo |
|
|
430
|
+
| `sa` | Sanctus |
|
|
431
|
+
| `ag` | Agnus Dei |
|
|
432
|
+
| `be` | Benedicamus |
|
|
433
|
+
| `it` | Ite missa est |
|
|
434
|
+
| `as` | Asperges (sprinkle rite, outside Paschaltide) |
|
|
435
|
+
| `va` | Vidi aquam (sprinkle rite, Paschaltide) |
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
interface OrdinaryChant extends Chant {
|
|
439
|
+
ordinary: OrdinaryCode; // movement code
|
|
440
|
+
ordinarium: string; // Latin movement name, "Kyrie eleison" …
|
|
441
|
+
mass: number;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
interface OrdinariumQuery extends CantusQuery {
|
|
445
|
+
feast?: Feast | Feast[];
|
|
446
|
+
ordinary?: OrdinaryCode;
|
|
447
|
+
mass?: number;
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## The Office — `officium`
|
|
452
|
+
|
|
453
|
+
`officium(query?)` retrieves the chants of a canonical hour; a feast acts
|
|
454
|
+
as a filter. Without an hour, every available hour returns.
|
|
455
|
+
|
|
456
|
+
```js
|
|
457
|
+
const christmas = tonus.festum({ date: new Date("2026-12-25") });
|
|
458
|
+
tonus.officium({ feast: christmas, hora: "laudes" });
|
|
459
|
+
// 7 chants: the Lauds antiphons, the Benedictus antiphon, and the hymn
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
| Hour | Content |
|
|
463
|
+
| --------------------------- | ---------------------------------------------------------------------------- |
|
|
464
|
+
| `matutinum` | Invitatory, antiphons, hymn, responsories |
|
|
465
|
+
| `laudes` | Antiphons, Benedictus antiphon, hymn |
|
|
466
|
+
| `tertia` / `sexta` / `nona` | The gradual psalms (Terce 119–121, Sext 122–124, None 125–127; Sunday and Monday take portions of Ps 118) + responsory breve |
|
|
467
|
+
| `vesperae` | Antiphons, Magnificat antiphon, hymn |
|
|
468
|
+
| `prima` | The Prime ordo (sung parts) — see below |
|
|
469
|
+
| `completorium` | The full Compline ordo — see below |
|
|
470
|
+
|
|
471
|
+
**Prime and Compline are ordos, not chant sets.** These two hours are
|
|
472
|
+
almost invariable: the same
|
|
473
|
+
sequence each day, varying only by season. They are assembled from a small
|
|
474
|
+
seasonal ordo and returned in liturgical order. With no feast, each resolves
|
|
475
|
+
for the [default epoch](index.md#dates).
|
|
476
|
+
|
|
477
|
+
**Matins is returned flat.** The night office answers like any other hour,
|
|
478
|
+
its responsories drawn from the Nocturnale Romanum (`nr`) — but the
|
|
479
|
+
three-nocturn, twelve-psalm division is not modelled: the chants are right,
|
|
480
|
+
their grouping into nocturns is not expressed.
|
|
481
|
+
|
|
482
|
+
```js
|
|
483
|
+
tonus.officium({ feast: christmas, hora: "completorium" });
|
|
484
|
+
// Deus in adjutorium → Ps 4, 90, 133 → Te lucis → In manus tuas
|
|
485
|
+
// → Nunc dimittis → Alma Redemptoris (simple tone)
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
```ts
|
|
489
|
+
interface OfficiumQuery extends CantusQuery {
|
|
490
|
+
feast?: Feast | Feast[];
|
|
491
|
+
hora?: CanonicalHour;
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
The eight hours ship as [`HORAE`](index.md#the-appendix), Matins first — read
|
|
496
|
+
them from there rather than transcribing them, and an unrecognised `hora`
|
|
497
|
+
throws rather than matching nothing, so a misspelling cannot read as an empty
|
|
498
|
+
hour.
|
|
499
|
+
|
|
500
|
+
```js
|
|
501
|
+
import { HORAE } from "tonus";
|
|
502
|
+
// ["matutinum", "laudes", "prima", "tertia", "sexta", "nona",
|
|
503
|
+
// "vesperae", "completorium"]
|
|
504
|
+
|
|
505
|
+
tonus.officium({ hora: "vespers" }); // throws: unknown hora "vespers"
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### One cursus, the Benedictine
|
|
509
|
+
|
|
510
|
+
tonus assembles a single office — the monastic cursus — with no option to
|
|
511
|
+
choose another. The chants come from the Antiphonale Monasticum (`am`) and its
|
|
512
|
+
companions; the psalmody follows the Benedictine distribution — the little
|
|
513
|
+
hours take the gradual psalms (Terce 119–121, Sext 122–124, None 125–127),
|
|
514
|
+
with Sunday and Monday walking their portions of Ps 118 instead; Prime walks
|
|
515
|
+
Pss 1–19 across the week (Sunday opens Ps 118); and Compline is the fixed
|
|
516
|
+
three, 4, 90 and 133.
|
|
517
|
+
|
|
518
|
+
```js
|
|
519
|
+
tonus.officium({ feast: benedict, hora: "vesperae" });
|
|
520
|
+
// the monastic Vespers antiphons, sourced from the Antiphonale Monasticum
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
## Psalms — `psalmus`
|
|
524
|
+
|
|
525
|
+
`psalmus(query?)` returns psalm and canticle verses as intoned chant:
|
|
526
|
+
GABC pointed to a psalm tone, modes 1–8 or the tonus peregrinus (mode 0).
|
|
527
|
+
`differentia` selects the cadential variant; `intonatio` controls whether
|
|
528
|
+
the opening formula is included, as it is for a psalm's first verse.
|
|
529
|
+
`inDirectum` recites a verse straight through to the termination with no
|
|
530
|
+
mediant, as a psalm sung without an antiphon; `solemn` uses a tone's
|
|
531
|
+
ornamented mediant where it has one. Canticles are addressed by name:
|
|
532
|
+
`benedictus`, `magnificat`, `nunc dimittis`, `benedicite`. (The Te Deum
|
|
533
|
+
is not psalmody — it carries its own melody and is not addressable here.)
|
|
534
|
+
|
|
535
|
+
```js
|
|
536
|
+
tonus.psalmus({ psalm: 109, verse: "1a", mode: 1 });
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
```js
|
|
540
|
+
[
|
|
541
|
+
{
|
|
542
|
+
incipit: "Dixit Dóminus Dómino meo:",
|
|
543
|
+
modus: "Modus I",
|
|
544
|
+
gabc: "(c4) (f)Di(h)xit (j)Dó(h)mi(h)nus (h)Dó(j)mi(h)no (g)me(h)o:(:) …",
|
|
545
|
+
},
|
|
546
|
+
];
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
```js
|
|
550
|
+
tonus.psalmus({ psalm: 109, mode: 2, differentia: "6F" });
|
|
551
|
+
tonus.psalmus({ psalm: "benedictus", mode: 8, intonatio: false });
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
The tones and their differentiae follow the Graduale Romanum appendix; the
|
|
555
|
+
tone's anatomy as tuned pitches is available from
|
|
556
|
+
[`temperamentum.tonus()`](tuning.md#psalm-tones--tonus).
|
|
557
|
+
|
|
558
|
+
```ts
|
|
559
|
+
interface PsalmusQuery {
|
|
560
|
+
psalm?: number | string;
|
|
561
|
+
verse?: string;
|
|
562
|
+
mode?: number;
|
|
563
|
+
differentia?: string; // differentia code, e.g. "6F", "4e"
|
|
564
|
+
intonatio?: boolean; // include opening intonation formula, default true
|
|
565
|
+
inDirectum?: boolean; // recite straight through, no mediant
|
|
566
|
+
solemn?: boolean; // use the ornamented solemn mediant where the tone has one
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
## Theory & Context
|
|
571
|
+
|
|
572
|
+
### The Solesmes restoration
|
|
573
|
+
|
|
574
|
+
The melodies in tonus are the Solesmes editions: the scholarly restoration
|
|
575
|
+
produced from the mid-19th century onward and matured into the books listed
|
|
576
|
+
under [The corpora](#the-corpora). The 1961 Graduale, the last complete edition
|
|
577
|
+
before the post-conciliar reforms, covers the full Tridentine cycle the
|
|
578
|
+
calendar in [calendar.md](calendar.md) expects.
|
|
579
|
+
|
|
580
|
+
Every reading reflects editorial judgment (no single medieval church sang
|
|
581
|
+
precisely these books), and the Solesmes books are a complete, internally
|
|
582
|
+
consistent edition of the Tridentine cycle, available machine-readable through
|
|
583
|
+
GregoBase.
|
|
584
|
+
|
|
585
|
+
### GABC: neumes as text
|
|
586
|
+
|
|
587
|
+
All melodies are encoded in GABC, the plain-text notation of the
|
|
588
|
+
[Gregorio](https://gregorio-project.github.io/) project: lyric syllables
|
|
589
|
+
each followed by a parenthesized note group, with pitch letters (`a`–`m`)
|
|
590
|
+
read against a clef declaration such as `(c4)`.
|
|
591
|
+
|
|
592
|
+
```
|
|
593
|
+
(c4) Pu(g)er(gh) na(hj)tus(j) est(j)
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
Melodic shapes are implicit in the letter groupings and define the neume
|
|
597
|
+
vocabulary in [tuning.md](tuning.md#neumes--neuma). Other marks carry the
|
|
598
|
+
Solesmes performance layer (episemas, the quilisma, liquescents, dots,
|
|
599
|
+
and divisiones) which the score engine reads into performance data and
|
|
600
|
+
phrase punctuation ([score.md](score.md#the-tabula)).
|
|
601
|
+
|
|
602
|
+
Because the encoding is textual, lyrics and neumes stay aligned syllable
|
|
603
|
+
by syllable, which is what lets `tonus.notatio` reconstruct syllables,
|
|
604
|
+
neumes, and prosody without images.
|
|
605
|
+
|
|
606
|
+
### The Mass: proper and ordinary
|
|
607
|
+
|
|
608
|
+
Two layers of chant make up a sung Mass, and tonus separates them exactly
|
|
609
|
+
as the books do:
|
|
610
|
+
|
|
611
|
+
- **The proper** (`tonus.proprium`) supplies the five processional and
|
|
612
|
+
interlectionary chants whose texts change with the day: Introitus,
|
|
613
|
+
Graduale, Alleluia (or Tractus in penitential seasons), Offertorium,
|
|
614
|
+
Communio. When a feast lacks its own proper, the rite supplies one from
|
|
615
|
+
the Commune Sanctorum, the shared formularies for classes of saints;
|
|
616
|
+
this is why `proprium` falls back to commune sets.
|
|
617
|
+
- **The ordinary** (`tonus.ordinarium`) supplies the fixed texts sung at
|
|
618
|
+
every Mass: Kyrie, Gloria, Credo, Sanctus, Agnus Dei, Ite or Benedicamus.
|
|
619
|
+
Their melodies live in the **Kyriale**, eighteen numbered mass-settings
|
|
620
|
+
plus ad libitum chants, each conventionally assigned to a class of day
|
|
621
|
+
(Lux et origo for Paschaltide, Orbis factor for Sundays throughout the year, the
|
|
622
|
+
Missa de Angelis everywhere). Feast-aware mass selection follows those
|
|
623
|
+
assignments.
|
|
624
|
+
|
|
625
|
+
### The Office: the daily cursus
|
|
626
|
+
|
|
627
|
+
The Divine Office (`tonus.officium`) supplies the eight canonical hours
|
|
628
|
+
that structure the liturgical day: Matutinum (the night office), Laudes
|
|
629
|
+
at dawn, the little hours of Prima, Tertia, Sexta, and Nona, Vesperae at
|
|
630
|
+
evening, and Completorium before sleep. The backbone of every hour is
|
|
631
|
+
psalmody: psalms and canticles framed by antiphons, with hymns and
|
|
632
|
+
responsories proper to the hour and the day. The eight-hour cursus is a
|
|
633
|
+
medieval inheritance intact in the Tridentine books.
|
|
634
|
+
|
|
635
|
+
### Psalm tones
|
|
636
|
+
|
|
637
|
+
Psalm verses are not through-composed; they are _intoned_ on recitation
|
|
638
|
+
formulas (`tonus.psalmus`): one tone per mode, plus the wandering
|
|
639
|
+
**tonus peregrinus** with its two tenors (sung to _In exitu Israel_).
|
|
640
|
+
Each tone has a fixed anatomy: an **intonatio** (the opening rise, sung
|
|
641
|
+
for the first verse), recitation on the **tenor**, a **mediatio** cadence
|
|
642
|
+
at the verse's colon, recitation again, and a **terminatio** cadence.
|
|
643
|
+
|
|
644
|
+
Terminations come in variants, the **differentiae** (`"6F"`, `"4e"`, …),
|
|
645
|
+
whose purpose is practical: ending the verse on a pitch that leads
|
|
646
|
+
smoothly back into the antiphon's opening. The tones and differentiae in
|
|
647
|
+
tonus follow the Graduale Romanum appendix (Toni Communes), keyed by the
|
|
648
|
+
same codes Divinum Officium uses. The gamut-level mechanics, tenor and
|
|
649
|
+
finalis per mode, are on the tuning page
|
|
650
|
+
([tuning.md](tuning.md#modes--modus)).
|
|
651
|
+
|
|
652
|
+
## Sources
|
|
653
|
+
|
|
654
|
+
Sources for this page are in the central [bibliography](https://github.com/jeffreypierce/tonus/blob/main/BIBLIOGRAPHY.md):
|
|
655
|
+
`gregobase` (the ten Solesmes books), `nocturnale-romanum`, `divinum-officium`,
|
|
656
|
+
`graduale-toni-communes`, `bloomfield-compline`, `gregorio-gabc`, `apel-chant`,
|
|
657
|
+
`hiley-plainchant`, `saulnier-guide`.
|