@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.
Files changed (142) hide show
  1. package/README.md +27 -65
  2. package/README_ja.md +28 -66
  3. package/dist/analyze/index.cjs +11 -7
  4. package/dist/analyze/index.cjs.map +1 -1
  5. package/dist/analyze/index.d.cts +79 -144
  6. package/dist/analyze/index.d.ts +79 -144
  7. package/dist/analyze/index.js +20 -16
  8. package/dist/chunk-35NBV2FT.cjs +145 -0
  9. package/dist/chunk-35NBV2FT.cjs.map +1 -0
  10. package/dist/{chunk-UADYAYAT.cjs → chunk-3R3QVKY5.cjs} +1353 -580
  11. package/dist/chunk-3R3QVKY5.cjs.map +1 -0
  12. package/dist/{chunk-WWURE4XT.cjs → chunk-76ZBTRG2.cjs} +624 -729
  13. package/dist/chunk-76ZBTRG2.cjs.map +1 -0
  14. package/dist/{chunk-FVSI36UV.js → chunk-7KG3RTYS.js} +197 -110
  15. package/dist/chunk-7KG3RTYS.js.map +1 -0
  16. package/dist/{chunk-VTI6FOLB.js → chunk-AGOVW7U6.js} +709 -133
  17. package/dist/chunk-AGOVW7U6.js.map +1 -0
  18. package/dist/{chunk-E3F4AHAH.cjs → chunk-CGBADIO5.cjs} +221 -134
  19. package/dist/chunk-CGBADIO5.cjs.map +1 -0
  20. package/dist/{chunk-6XH6QZYQ.cjs → chunk-DSMJRXCZ.cjs} +1455 -849
  21. package/dist/chunk-DSMJRXCZ.cjs.map +1 -0
  22. package/dist/{chunk-PKFNUHDY.js → chunk-FBH75DAY.js} +1218 -612
  23. package/dist/chunk-FBH75DAY.js.map +1 -0
  24. package/dist/chunk-H2KJHBW4.js +3329 -0
  25. package/dist/chunk-H2KJHBW4.js.map +1 -0
  26. package/dist/chunk-HPVSH7SF.cjs +2294 -0
  27. package/dist/chunk-HPVSH7SF.cjs.map +1 -0
  28. package/dist/{chunk-MXO72PLY.cjs → chunk-HWHGOVO6.cjs} +21 -19
  29. package/dist/chunk-HWHGOVO6.cjs.map +1 -0
  30. package/dist/chunk-HYJJ2V2I.js +2294 -0
  31. package/dist/chunk-HYJJ2V2I.js.map +1 -0
  32. package/dist/{chunk-AFM2ULJH.cjs → chunk-J7FHVZII.cjs} +1567 -1067
  33. package/dist/chunk-J7FHVZII.cjs.map +1 -0
  34. package/dist/chunk-K6OZXIR6.js +1 -0
  35. package/dist/{chunk-H3VORETI.js → chunk-M5RYMAFI.js} +487 -592
  36. package/dist/chunk-M5RYMAFI.js.map +1 -0
  37. package/dist/chunk-NB25P3EH.js +363 -0
  38. package/dist/chunk-NB25P3EH.js.map +1 -0
  39. package/dist/{chunk-TTCLJX6D.js → chunk-NFJ4P6ZZ.js} +10 -8
  40. package/dist/chunk-NFJ4P6ZZ.js.map +1 -0
  41. package/dist/chunk-NM7UAMC3.cjs +457 -0
  42. package/dist/chunk-NM7UAMC3.cjs.map +1 -0
  43. package/dist/chunk-PM4XJE2Y.cjs +363 -0
  44. package/dist/chunk-PM4XJE2Y.cjs.map +1 -0
  45. package/dist/chunk-PUKJP2Z5.js +145 -0
  46. package/dist/chunk-PUKJP2Z5.js.map +1 -0
  47. package/dist/{chunk-VOHZB45S.js → chunk-Q6LFSAKV.js} +1321 -821
  48. package/dist/chunk-Q6LFSAKV.js.map +1 -0
  49. package/dist/{chunk-INHVXP6Z.js → chunk-RFIBF2RR.js} +1203 -430
  50. package/dist/chunk-RFIBF2RR.js.map +1 -0
  51. package/dist/{chunk-Q2WGKJNN.cjs → chunk-S5BKZZGM.cjs} +699 -123
  52. package/dist/chunk-S5BKZZGM.cjs.map +1 -0
  53. package/dist/chunk-SGLEQVJH.cjs +3329 -0
  54. package/dist/chunk-SGLEQVJH.cjs.map +1 -0
  55. package/dist/chunk-UGLFDG7L.cjs +1 -0
  56. package/dist/chunk-UGLFDG7L.cjs.map +1 -0
  57. package/dist/{chunk-YH3BIKHH.js → chunk-UMWZ4ZET.js} +146 -49
  58. package/dist/chunk-UMWZ4ZET.js.map +1 -0
  59. package/dist/{index-szBv3496.d.ts → coerce-DP0vYu-x.d.ts} +286 -199
  60. package/dist/{index-C_8o--VE.d.cts → coerce-DRERzdve.d.cts} +286 -199
  61. package/dist/core/index.cjs +9 -5
  62. package/dist/core/index.cjs.map +1 -1
  63. package/dist/core/index.d.cts +122 -108
  64. package/dist/core/index.d.ts +122 -108
  65. package/dist/core/index.js +32 -28
  66. package/dist/generate/index.cjs +8 -8
  67. package/dist/generate/index.d.cts +168 -84
  68. package/dist/generate/index.d.ts +168 -84
  69. package/dist/generate/index.js +7 -7
  70. package/dist/{index-CGpRv5sl.d.cts → index-9eoQs2C1.d.ts} +34 -19
  71. package/dist/{index-CCNJRG-P.d.cts → index-B9QLziDe.d.cts} +293 -56
  72. package/dist/{index-Dzr13q3d.d.cts → index-BBWNZS0f.d.cts} +135 -58
  73. package/dist/{index-9wcMhG73.d.ts → index-BHIUyjhZ.d.ts} +293 -56
  74. package/dist/{index-BGFW-8P2.d.cts → index-BJgP97N1.d.ts} +196 -114
  75. package/dist/{index-CunYKLiu.d.ts → index-BL5N2Oyz.d.cts} +1 -1
  76. package/dist/{index-Cj49F892.d.ts → index-BMweUlm5.d.cts} +63 -23
  77. package/dist/{index-CgHqxdps.d.ts → index-BNSM-DSk.d.cts} +196 -114
  78. package/dist/{index-D57QRbVn.d.ts → index-BRMbPkHE.d.ts} +480 -254
  79. package/dist/{index-Chbst3Jx.d.ts → index-CJBBiAmU.d.ts} +135 -58
  80. package/dist/{index-BkGmlyI3.d.cts → index-CL4b4gUQ.d.ts} +63 -23
  81. package/dist/{index-B9MNZboQ.d.ts → index-Cy15oTvh.d.cts} +52 -22
  82. package/dist/{index-B9MNZboQ.d.cts → index-Cy15oTvh.d.ts} +52 -22
  83. package/dist/{index-BO6xE9YU.d.cts → index-DGCNKAUr.d.cts} +480 -254
  84. package/dist/{index-B4o55NDr.d.cts → index-Dw2DP7vm.d.ts} +1 -1
  85. package/dist/{index-G1uwGGWQ.d.ts → index-cHvbYgJI.d.cts} +34 -19
  86. package/dist/index.cjs +42 -14
  87. package/dist/index.cjs.map +1 -1
  88. package/dist/index.d.cts +14 -14
  89. package/dist/index.d.ts +14 -14
  90. package/dist/index.js +82 -54
  91. package/dist/{masks-DYbE485J.d.cts → masks-Cc7-MzzY.d.ts} +49 -2
  92. package/dist/{masks-DYbE485J.d.ts → masks-pADfTOiD.d.cts} +49 -2
  93. package/dist/model/index.cjs +19 -12
  94. package/dist/model/index.cjs.map +1 -1
  95. package/dist/model/index.d.cts +504 -182
  96. package/dist/model/index.d.ts +504 -182
  97. package/dist/model/index.js +18 -11
  98. package/dist/{positional-Cptlj-xs.d.ts → positional-DJgs6ltD.d.ts} +85 -8
  99. package/dist/{positional-DvH_sd8u.d.cts → positional-DMZer-FM.d.cts} +85 -8
  100. package/dist/theory/index.cjs +35 -6
  101. package/dist/theory/index.cjs.map +1 -1
  102. package/dist/theory/index.d.cts +257 -62
  103. package/dist/theory/index.d.ts +257 -62
  104. package/dist/theory/index.js +41 -12
  105. package/package.json +7 -5
  106. package/dist/chunk-2LCPM3EG.js +0 -3224
  107. package/dist/chunk-2LCPM3EG.js.map +0 -1
  108. package/dist/chunk-6XH6QZYQ.cjs.map +0 -1
  109. package/dist/chunk-6XPTBE7Y.cjs +0 -49
  110. package/dist/chunk-6XPTBE7Y.cjs.map +0 -1
  111. package/dist/chunk-AFM2ULJH.cjs.map +0 -1
  112. package/dist/chunk-B6XNKWZV.cjs +0 -3224
  113. package/dist/chunk-B6XNKWZV.cjs.map +0 -1
  114. package/dist/chunk-E3F4AHAH.cjs.map +0 -1
  115. package/dist/chunk-ELCTZUJJ.js +0 -379
  116. package/dist/chunk-ELCTZUJJ.js.map +0 -1
  117. package/dist/chunk-FVSI36UV.js.map +0 -1
  118. package/dist/chunk-H3VORETI.js.map +0 -1
  119. package/dist/chunk-H42UHPYW.js +0 -1577
  120. package/dist/chunk-H42UHPYW.js.map +0 -1
  121. package/dist/chunk-HFPS7JFD.js +0 -1
  122. package/dist/chunk-INHVXP6Z.js.map +0 -1
  123. package/dist/chunk-K4ZJUGF4.cjs +0 -379
  124. package/dist/chunk-K4ZJUGF4.cjs.map +0 -1
  125. package/dist/chunk-KNJEKLKV.js +0 -49
  126. package/dist/chunk-KNJEKLKV.js.map +0 -1
  127. package/dist/chunk-MXO72PLY.cjs.map +0 -1
  128. package/dist/chunk-NLEU4QSE.cjs +0 -360
  129. package/dist/chunk-NLEU4QSE.cjs.map +0 -1
  130. package/dist/chunk-OE6WK2Y2.cjs +0 -1577
  131. package/dist/chunk-OE6WK2Y2.cjs.map +0 -1
  132. package/dist/chunk-PKFNUHDY.js.map +0 -1
  133. package/dist/chunk-Q2WGKJNN.cjs.map +0 -1
  134. package/dist/chunk-RHIJ3S4I.cjs +0 -1
  135. package/dist/chunk-RHIJ3S4I.cjs.map +0 -1
  136. package/dist/chunk-TTCLJX6D.js.map +0 -1
  137. package/dist/chunk-UADYAYAT.cjs.map +0 -1
  138. package/dist/chunk-VOHZB45S.js.map +0 -1
  139. package/dist/chunk-VTI6FOLB.js.map +0 -1
  140. package/dist/chunk-WWURE4XT.cjs.map +0 -1
  141. package/dist/chunk-YH3BIKHH.js.map +0 -1
  142. /package/dist/{chunk-HFPS7JFD.js.map → chunk-K6OZXIR6.js.map} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @libraz/libcantus
2
2
 
3
- Pure-TypeScript music theory for MIDI note events. Build and spell chords, inspect harmony, analyze keys and form, and generate parts from the same data model. The package has no runtime dependencies.
3
+ Pure-TypeScript music theory for MIDI note events. Recover the harmony from notes, and write new parts against that same reading. No runtime dependencies.
4
4
 
5
5
  [![CI](https://img.shields.io/github/actions/workflow/status/libraz/libcantus/ci.yml?branch=main&label=CI)](https://github.com/libraz/libcantus/actions)
6
6
  [![npm](https://img.shields.io/npm/v/@libraz/libcantus)](https://www.npmjs.com/package/@libraz/libcantus)
@@ -10,9 +10,11 @@ Pure-TypeScript music theory for MIDI note events. Build and spell chords, inspe
10
10
  [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D22-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
11
11
  [![docs](https://img.shields.io/badge/docs-API%20reference-b5892e)](https://libraz.github.io/libcantus/)
12
12
 
13
- ## What it does
13
+ ![From note events to parts, and back](docs/images/pipeline.svg)
14
+
15
+ The library sits between software that already holds notes or chord symbols — a DAW project, a MIDI parser, a practice tool — and what those notes mean harmonically. Note events go in, the harmony comes out, and the generators write against the harmony that was just read.
14
16
 
15
- It sits between software that already holds notes or chord symbols — a DAW project, a MIDI parser, a practice tool — and what those notes mean harmonically. Give it note events and it recovers the harmony; give it that harmony back and it writes parts against it:
17
+ ## What it does
16
18
 
17
19
  ```ts
18
20
  import { Composer, Score } from '@libraz/libcantus';
@@ -31,84 +33,44 @@ Composer.of({ key: chords.key, bpm: 120, seed: 1 }).bass(chords, { style: 'walki
31
33
  // 16 notes: [{ pitch: 36, startBeat: 0, durationBeat: 1, velocity: 100 }, ...]
32
34
  ```
33
35
 
34
- Chord boundaries are searched for rather than assumed, and so is the key, so a piece that modulates is not read against the key it started in.
35
-
36
- What each layer covers:
37
-
38
- - **[Pitch and notation](docs/en/pitch-and-notation.md)** — spelled notes and intervals, MIDI conversion, note names read and written in English, German, Japanese, Italian or fixed-do, and line spelling solved as one path instead of note by note. Every text parser has a non-throwing sibling (`tryParseNote`, `tryParseInterval`, `tryParseChordSymbol`, `tryParseKeyName`, `tryParseTimeSignature`, and `tryParse` on `Note`, `Interval`, `Key`, `Chord` and `Meter`), so a text field needs no `try`/`catch` per keystroke.
39
- - **[Harmony](docs/en/harmony.md)** — chords as structured values, scales including modes, pentatonics and the `WORLD_SCALES` set, Roman numerals and function, voicing, figured bass, and the part-writing and species-counterpoint checkers that report a violation with the voice it happened in and the reason.
40
- - **[Analysis](docs/en/analysis.md)** — chord and key detection over note events, timelines and cadences, prolongational reduction, phrases, sections, hypermeter, motifs, and arrangement reports.
41
- - **[Generation](docs/en/generation.md)** — progressions, motifs, rhythms, drums, bass and counter-melody, all drawing on one `GenerationContext`: a project seed, three additive complexity dials (rhythmic, harmonic, ornament), a separate difficulty ceiling, the tempo, and the instrument each part is written for. Same context, same output.
42
- - **[Time and arrangement](docs/en/time-and-arrangement.md)** — meter, tempo, positions in bars and beats, and analysis across several tracks at once.
43
- - **[Class API](docs/en/api-reference.md)** — the same theory as one immutable class per thing the library works with, `Score`, `Timeline` and `Composer` included, each a thin skin over the functions above. Reach for a function or a class as it suits the call site; the answers are the same.
44
-
45
- Answers say why they were reached. `analyzeChord`, `detectCadence` and `explainRoman` carry a `rationale`, `detectKey` attaches one on request, and each can report the readings it turned down as `alternatives`. Where the input cannot settle a question, the field comes back `null` rather than a plausible guess — grading a cadence perfect or imperfect needs a voicing, because only a voicing says what is in the soprano.
46
-
47
- Spelling is kept wherever it decides the answer. A diminished fifth and an augmented fourth are the same distance in pitch classes but not the same interval, so the counterpoint and part-writing checkers take spelled notes rather than numbers.
36
+ Chord boundaries are searched for rather than assumed, and so is the key, so a piece that modulates is not read against the key it started in. Answers carry their evidence: a chord analysis, a cadence and a Roman numeral each come with a `rationale` and the readings they turned down, and where the input cannot settle a question the field comes back `null` rather than a plausible guess.
48
37
 
49
- Seven worked guides start from the data an application already has: [DAW workflow](docs/en/use-cases/daw-workflow.md), [piece analysis](docs/en/use-cases/piece-analysis.md), [modulation report](docs/en/use-cases/modulation-report.md), [harmony exercise checker](docs/en/use-cases/harmony-exercise-checker.md), [generative arrangement](docs/en/use-cases/generative-arrangement.md), [chord chart import](docs/en/use-cases/chord-chart-import.md), and [part preparation](docs/en/use-cases/part-preparation.md).
38
+ ## Use cases
50
39
 
51
- ## What it doesn't do
52
-
53
- - **No I/O, notation or audio.** No MIDI file reader or writer, no score rendering, no audio analysis, no playback. Bring your own parser and hand it note events. If that layer is what you need, [libsonare](https://github.com/libraz/libsonare) covers audio analysis, mastering, synthesis and SMF I/O; the two share no code and neither requires the other.
54
- - **No microtonal analysis.** Frequencies, cents, equal divisions of the octave and just-intonation ratios live in `core`, but everything above the pitch layer runs on twelve pitch classes. Music organised in smaller steps than a semitone is out of reach, which is also why the maqāmāt built on half-flat degrees are left out of `WORLD_SCALES` rather than rounded to a twelve-tone neighbour.
55
- - **No modal systems.** `WORLD_SCALES` records the pitch material a tradition names — a thāt, a maqām's set, a Japanese pentatonic — and not the system built on it: ascent and descent forms, the notes a phrase leans on, and the phrase grammar have no place in a mask.
56
- - **No assumption that the material is tonal.** Roman numerals and functional harmony presuppose the common practice, and `supportsFunctionalHarmony` says whether a named scale admits that reading at all — `'dorian'` does, `'miyakoBushi'` does not.
57
- - **No corpus.** Nothing is bundled to run statistics over.
58
- - **Known gaps in functional harmony.** `functionOf` answers from a chord and a key alone, so a cadential six-four reads there as an inverted tonic; the dominant reading of it belongs to the layers that see time, and `detectCadence` gives it when the chord before the dominant is passed as `approach`.
59
-
60
- ## Requirements
61
-
62
- Node.js >= 22.
40
+ | Use case | What it does | Worked guide |
41
+ |---|---|---|
42
+ | A DAW assistant | Infers the harmony from tracks, then writes a bass line against it. | [DAW workflow](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/daw-workflow.md) |
43
+ | A piece analyzer | Key regions, cadences, harmonic reduction, phrases, sections and motifs from one score. | [Piece analysis](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/piece-analysis.md) |
44
+ | A modulation report | Key changes with their pivot chords, confidences and relations. | [Modulation report](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/modulation-report.md) |
45
+ | A harmony exercise checker | Part-writing and species-counterpoint violations, each with the voice it happened in and the rule it broke. | [Harmony exercise checker](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/harmony-exercise-checker.md) |
46
+ | A generative arrangement | One seeded composer writing a progression, its parts and its drums, then a playability check. | [Generative arrangement](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/generative-arrangement.md) |
47
+ | A chord chart importer | Typed chord symbols turned into a timeline, voicings and a bass line. | [Chord chart import](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/chord-chart-import.md) |
48
+ | Part preparation | A part fitted to an instrument and written at the pitch its player reads. | [Part preparation](https://github.com/libraz/libcantus/blob/main/docs/en/use-cases/part-preparation.md) |
63
49
 
64
50
  ## Install
65
51
 
52
+ Node.js 22 or later.
53
+
66
54
  ```sh
67
55
  yarn add @libraz/libcantus
68
56
  ```
69
57
 
70
- ## Quick start
71
-
72
- The theory lives in tree-shakeable pure functions. On top of them sits an immutable class API — one class per thing the library works with, from a single `Note`, `Interval` or `Chord` up to the `Score`, `Timeline`, `Arrangement` and `Composer` that carry a whole piece — that reads the way theory is spoken:
73
-
74
- ```ts
75
- import { Chord, Key } from '@libraz/libcantus';
76
-
77
- const key = Key.major('C');
78
- const dominant = key.chord(5, 'dom7');
79
-
80
- dominant.symbol(); // 'G7'
81
- dominant.analyze(key).roman; // 'V7'
82
- Chord.parse('C7(b9,#11)').pitchClasses(); // [0, 1, 4, 6, 7, 10]
83
- ```
84
-
85
- The functions are the library; every class is a thin skin over them. A class wraps a plain object it exposes as `.data`, and the functions return data a class can be built from, so neither side is a walled garden and the two give the same answers. What a class adds is holding a value together with its context, so a chain of calls does not restate the same facts: a `Score` carries its notes with their meter, tempo, and key, and a `Composer` carries the key, tempo, and seed one piece is written under.
86
-
87
- ## Import paths
88
-
89
- The package root exports everything. To pull in a single layer, import its subpath instead:
90
-
91
- ```ts
92
- import { parseNote, edo } from '@libraz/libcantus/core'; // pitch, meter, tempo, tuning
93
- import { majorKey, makeChord } from '@libraz/libcantus/theory'; // scales, chords, voicing, rules
94
- import { analyzeArrangement, detectKey } from '@libraz/libcantus/analyze';
95
- import { generateDrums, generateProgression } from '@libraz/libcantus/generate';
96
- import { Chord, Key, Note } from '@libraz/libcantus/model'; // class API
97
- ```
98
-
99
- Both ESM and CommonJS builds ship for every path.
58
+ The package root exports the whole API. `@libraz/libcantus/core`, `/theory`, `/analyze`, `/generate` and `/model` are narrower import boundaries onto the same symbols, and every path ships an ESM and a CommonJS build.
100
59
 
101
60
  ## Documentation
102
61
 
103
- Start here: [Introduction](docs/en/introduction.md), [Getting started](docs/en/getting-started.md), [Use cases](docs/en/use-cases/index.md).
62
+ New to music theory? [The primer](https://github.com/libraz/libcantus/blob/main/docs/en/primer/index.md) teaches the concepts this API is built on — pitch and intervals, scales and keys, chords, harmony, voices, rhythm and meter — for a reader who writes TypeScript rather than scores.
104
63
 
105
- Domain guides: [Pitch and notation](docs/en/pitch-and-notation.md), [Scales and modes](docs/en/scales-and-modes.md), [Harmony](docs/en/harmony.md), [Key relations and modulation](docs/en/key-relations-and-modulation.md), [Voicing](docs/en/voicing.md), [Counterpoint and part-writing](docs/en/counterpoint-and-part-writing.md), [Time and arrangement](docs/en/time-and-arrangement.md), [Analysis](docs/en/analysis.md), [Melody and motifs](docs/en/melody-and-motifs.md), [Rhythm and groove](docs/en/rhythm-and-groove.md), [Generation](docs/en/generation.md), [Reharmonization](docs/en/reharmonization.md), [Instruments and playability](docs/en/instruments-and-playability.md), [Tuning and frequency](docs/en/tuning-and-frequency.md).
64
+ Otherwise start at [Introduction](https://github.com/libraz/libcantus/blob/main/docs/en/introduction.md) and [Getting started](https://github.com/libraz/libcantus/blob/main/docs/en/getting-started.md), which index the domain guides and the reference pages. Every `ts` example in the guides is executed by the test suite, and a trailing comment that names a literal — with or without the reason for it after an em dash — is checked against what the call returns.
106
65
 
107
- Cross-cutting: [Determinism and seeding](docs/en/determinism-and-seeding.md), [Errors and validation](docs/en/errors-and-validation.md), [Performance](docs/en/performance.md), [Interoperability](docs/en/interoperability.md).
66
+ ## What it doesn't do
108
67
 
109
- Reference: [API reference](docs/en/api-reference.md), [Glossary](docs/en/glossary.md), [Questions and limitations](docs/en/faq.md).
68
+ - **No I/O, notation or audio.** No MIDI file reader or writer, no score rendering, no audio analysis, no playback. Bring your own parser and hand it note events. For the layer below, [libsonare](https://github.com/libraz/libsonare) covers audio analysis, mastering, synthesis and SMF I/O; the two share no code and neither requires the other.
69
+ - **No microtonal analysis.** Frequencies, cents, equal divisions of the octave and just-intonation ratios live in `core`, but everything above the pitch layer runs on twelve pitch classes.
70
+ - **No modal systems.** `WORLD_SCALES` records the pitch material a tradition names — a thāt, a maqām's set, a Japanese pentatonic — and not the grammar built on it.
71
+ - **No corpus.** Nothing is bundled to run statistics over.
110
72
 
111
- Every `ts` example in these guides is executed by the test suite, and an expected value written as a trailing comment is checked against what the call returns. The generated TypeDoc reference is written to `docs/api` and is separate from the hand-authored guides.
73
+ [Questions and limitations](https://github.com/libraz/libcantus/blob/main/docs/en/faq.md) covers the rest, including where a functional reading does not apply and what the engine will not guess.
112
74
 
113
75
  ## License
114
76
 
package/README_ja.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @libraz/libcantus
2
2
 
3
- MIDI ノートイベントを扱う、TypeScript 製の音楽理論ライブラリです。コードの組み立てと綴り、和声とキーの解析、曲の形式の読み取り、パート生成を同じデータモデルで行えます。実行時依存はありません。
3
+ MIDI ノートイベントのための、TypeScript 製の音楽理論ライブラリです。ノートから和声を読み取り、その読み取り結果に沿って新しいパートを書けます。実行時依存はありません。
4
4
 
5
5
  [![CI](https://img.shields.io/github/actions/workflow/status/libraz/libcantus/ci.yml?branch=main&label=CI)](https://github.com/libraz/libcantus/actions)
6
6
  [![npm](https://img.shields.io/npm/v/@libraz/libcantus)](https://www.npmjs.com/package/@libraz/libcantus)
@@ -10,9 +10,11 @@ MIDI ノートイベントを扱う、TypeScript 製の音楽理論ライブラ
10
10
  [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D22-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
11
11
  [![docs](https://img.shields.io/badge/docs-API%20reference-b5892e)](https://libraz.github.io/libcantus/)
12
12
 
13
- ## できること
13
+ ![ノートイベントからパートへ、そして再びノートイベントへ](docs/images/pipeline-ja.svg)
14
+
15
+ このライブラリは、すでにノートやコード記号を持っているソフトウェア(DAW のプロジェクト、MIDI パーサー、練習支援ツールなど)と、その音が和声的に何を意味するかとの間を埋めます。ノートイベントを渡すと和声が求まり、ジェネレーターはいま読み取ったその和声に沿ってパートを書きます。
14
16
 
15
- すでにノートやコード記号を持っているソフトウェア(DAW のプロジェクト、MIDI パーサー、練習支援ツールなど)と、その音が和声的に何を意味するかとの間を埋めます。ノートイベントを渡せば和声が求まり、その和声を渡せばそれに沿ったパートが書けます。
17
+ ## できること
16
18
 
17
19
  ```ts
18
20
  import { Composer, Score } from '@libraz/libcantus';
@@ -31,85 +33,45 @@ Composer.of({ key: chords.key, bpm: 120, seed: 1 }).bass(chords, { style: 'walki
31
33
  // 16 音: [{ pitch: 36, startBeat: 0, durationBeat: 1, velocity: 100 }, ...]
32
34
  ```
33
35
 
34
- コードの境界は決め打ちせずに探索し、キーも同様に探します。転調する曲を、冒頭のキーのまま読み続けることはありません。
35
-
36
- 各レイヤーが受け持つ範囲は次のとおりです。
37
-
38
- - **[音高と記譜](docs/ja/pitch-and-notation.md)** — 綴りを保った音名と音程、MIDI 変換、英語・ドイツ語・日本語・イタリア語・固定ドでの読み書き、そして 1 音ずつではなく声部全体を 1 本の経路として解く綴り付け。テキストのパーサーにはいずれも例外を投げない対 (`tryParseNote`、`tryParseInterval`、`tryParseChordSymbol`、`tryParseKeyName`、`tryParseTimeSignature`、および `Note`・`Interval`・`Key`・`Chord`・`Meter` の `tryParse`) があるので、入力欄の 1 打鍵ごとに `try`/`catch` を書く必要はありません。
39
- - **[和声](docs/ja/harmony.md)** — 構造を持つ値としてのコード、教会旋法やペンタトニックに加えて `WORLD_SCALES` を含むスケール、ローマ数字と和声機能、ヴォイシング、数字付き低音、そして違反した声部と理由まで返す声部書法・種目対位法のチェッカー。
40
- - **[解析](docs/ja/analysis.md)** — ノートイベントからのコード・キー検出、タイムラインとカデンツ、和声的な還元、フレーズ、セクション、ハイパーメーター、モチーフ、アレンジ全体のレポート。
41
- - **[生成](docs/ja/generation.md)** — プログレッション、モチーフ、リズム、ドラム、ベース、対旋律。いずれも 1 つの `GenerationContext` を参照します。プロジェクトのシード、加算的な 3 つの複雑さのダイヤル(リズム・和声・装飾)、それとは別枠の難易度の上限、テンポ、各パートの対象楽器がそこに入ります。同じコンテキストからは同じ結果が出ます。
42
- - **[時間とアレンジ](docs/ja/time-and-arrangement.md)** — 拍子、テンポ、小節と拍による位置、複数トラックをまたぐ解析。
43
- - **[クラス API](docs/ja/api-reference.md)** — 同じ理論を、ライブラリが扱う対象ごとの不変クラスとして提供します。`Score`、`Timeline`、`Composer` も含め、いずれも上記の関数の薄い外皮です。呼び出し側の都合で関数とクラスのどちらを使ってもよく、返る答えは同じです。
44
-
45
- 答えには、そう読んだ理由が付きます。`analyzeChord`、`detectCadence`、`explainRoman` は `rationale` を必ず返し、`detectKey` は要求があれば付けます。いずれも、退けた解釈を `alternatives` として報告できます。渡された情報だけでは決まらない場合、それらしい答えを作らずに `null` を返します。カデンツが完全か不完全かはヴォイシングがなければ決まりません。ソプラノに何があるかはヴォイシングだけが答えられるからです。
36
+ コードの境界は決め打ちせずに探索し、キーも同様に探します。転調する曲を、冒頭のキーのまま読み続けることはありません。答えには根拠が伴います。コード分析・終止・ローマ数字はいずれも `rationale` と、退けた候補を併せて返し、入力だけでは決まらない項目は、もっともらしい推測ではなく `null` を返します。
46
37
 
47
- 答えを左右する場面では、綴りの情報を落としません。減 5 度と増 4 度はピッチクラス上の距離が同じでも同じ音程ではないので、声部書法と対位法のチェッカーは数値ではなく綴られた音を受け取ります。
38
+ ## ユースケース
48
39
 
49
- アプリケーションが手元に持っているデータから始まるガイドが 7 本あります。[DAW との連携](docs/ja/use-cases/daw-workflow.md)、[曲の解析](docs/ja/use-cases/piece-analysis.md)、[転調レポート](docs/ja/use-cases/modulation-report.md)、[和声課題のチェック](docs/ja/use-cases/harmony-exercise-checker.md)、[生成によるアレンジ](docs/ja/use-cases/generative-arrangement.md)、[コード譜の取り込み](docs/ja/use-cases/chord-chart-import.md)、[パートの準備](docs/ja/use-cases/part-preparation.md)です。
50
-
51
- ## やらないこと
52
-
53
- - **入出力・記譜・音声を扱いません。** MIDI ファイルの読み書き、楽譜の描画、音声解析、再生はありません。パーサーは各自で用意し、ノートイベントとして渡してください。その層こそが必要なら、[libsonare](https://github.com/libraz/libsonare) が音声解析、マスタリング、合成、SMF 入出力を扱います。両者はコードを共有せず、どちらも相手を必要としません。
54
- - **微分音の解析はしません。** 周波数、セント、オクターブの等分割、純正律の比は `core` にありますが、音高より上の層はすべて 12 のピッチクラスで動きます。半音より細かい単位で組み立てられた音楽は範囲外です。半フラットの音度を持つマカームを 12 音の近い音で代用せず `WORLD_SCALES` から外しているのも、同じ理由です。
55
- - **旋法体系そのものは扱いません。** `WORLD_SCALES` が収録するのは、thāt やマカーム、日本の音階といった伝統が名を与えた音組織であって、その上に立つ体系ではありません。上行形と下行形、フレーズが寄りかかる音、旋律型の文法は、マスクには入りません。
56
- - **調性を前提にしません。** ローマ数字と機能和声は西洋の慣習を前提とします。その読み方が適用できるスケールかどうかは `supportsFunctionalHarmony` が答えます(`'dorian'` は真、`'miyakoBushi'` は偽)。
57
- - **コーパスは持ちません。** 統計を取るためのデータは同梱していません。
58
- - **機能和声には既知の穴があります。** `functionOf` は和音と調だけから答えるため、終止四六の和音はその層では主和音の転回として読まれます。属和音としての読みは時間軸を見る層のものであり、属和音の前の和音を `approach` として渡したときに `detectCadence` がそれを示します。
59
-
60
- ## 要件
61
-
62
- Node.js >= 22。
40
+ | ユースケース | 内容 | 実例のガイド |
41
+ |---|---|---|
42
+ | DAW のアシスタント | トラックから和声を読み取り、それに沿ってベースラインを書く。 | [DAW ワークフロー](docs/ja/use-cases/daw-workflow.md) |
43
+ | 楽曲アナライザー | 1 つのスコアから調区間、終止形、和声的な還元、フレーズ、セクション、モチーフを得る。 | [楽曲の解析](docs/ja/use-cases/piece-analysis.md) |
44
+ | 転調レポート | 転調を、軸和音・確信度・調同士の関係とともに提示する。 | [転調レポート](docs/ja/use-cases/modulation-report.md) |
45
+ | 和声課題のチェッカー | 声部書法と種目対位法の違反を、違反した声部と破った規則つきで報告する。 | [和声課題のチェック](docs/ja/use-cases/harmony-exercise-checker.md) |
46
+ | 自動生成アレンジ | シードを固定した 1 つのコンポーザーがコード進行・各パート・ドラムを書き、演奏可能性を確認する。 | [生成によるアレンジ](docs/ja/use-cases/generative-arrangement.md) |
47
+ | コード譜の取り込み | 打ち込んだコード記号をタイムライン、ヴォイシング、ベースラインに変換する。 | [コード譜の取り込み](docs/ja/use-cases/chord-chart-import.md) |
48
+ | パート譜の準備 | パートを楽器に合わせ、その奏者が読む音高で書き出す。 | [パート譜の準備](docs/ja/use-cases/part-preparation.md) |
63
49
 
64
50
  ## インストール
65
51
 
52
+ Node.js 22 以降が必要です。
53
+
66
54
  ```sh
67
55
  yarn add @libraz/libcantus
68
56
  ```
69
57
 
70
- ## 最初の例
71
-
72
- 理論の本体はツリーシェイク可能な純粋関数にあります。その上に、理論を語るときの言い方に近い不変のクラス API が乗っています。ライブラリが扱う対象ごとに1つのクラスがあり、単体の `Note`、`Interval`、`Chord` から、曲全体を受け持つ `Score`、`Timeline`、`Arrangement`、`Composer` までが揃います。
73
-
74
- ```ts
75
- import { Chord, Key } from '@libraz/libcantus';
76
-
77
- const key = Key.major('C');
78
- const dominant = key.chord(5, 'dom7');
79
-
80
- dominant.symbol(); // 'G7'
81
- dominant.analyze(key).roman; // 'V7'
82
- Chord.parse('C7(b9,#11)').pitchClasses(); // [0, 1, 4, 6, 7, 10]
83
- ```
84
-
85
- 本体は関数で、クラスはいずれもその薄い外皮です。クラスは `.data` でプレーンな値を公開し、関数が返したデータからクラスを作れます。どちらかが閉じた世界になることはなく、返す答えも同じです。クラスが足すのは、値とその文脈をひとまとめに保持することです。呼び出しを連ねるときに同じ事実を書き直さずに済みます。`Score` は音符と拍子・テンポ・調をまとめて持ち、`Composer` は 1 曲を書くときの調・テンポ・シードを持ちます。
86
-
87
- ## インポートパス
88
-
89
- ルートからすべてを export しています。1 つのレイヤーだけを取り込みたい場合は、サブパスを使ってください。
90
-
91
- ```ts
92
- import { parseNote, edo } from '@libraz/libcantus/core'; // 音高、拍子、テンポ、音律
93
- import { majorKey, makeChord } from '@libraz/libcantus/theory'; // スケール、コード、ヴォイシング、規則
94
- import { analyzeArrangement, detectKey } from '@libraz/libcantus/analyze';
95
- import { generateDrums, generateProgression } from '@libraz/libcantus/generate';
96
- import { Chord, Key, Note } from '@libraz/libcantus/model'; // クラス API
97
- ```
98
-
99
- いずれのパスにも ESM と CommonJS の両方のビルドがあります。
58
+ パッケージのルートから API 全体を公開しています。`@libraz/libcantus/core`、`/theory`、`/analyze`、`/generate`、`/model` は同じシンボル群に対する、より狭い読み込み境界です。いずれのパスも ESM と CommonJS の両方のビルドを同梱しています。
100
59
 
101
60
  ## ドキュメント
102
61
 
103
- 最初に読むページ: [概要](docs/ja/introduction.md)、[使い始める](docs/ja/getting-started.md)、[ユースケース](docs/ja/use-cases/index.md)。
62
+ 音楽理論にはじめて触れる場合は、[入門ガイド](docs/ja/primer/index.md)から始めてください。この API が土台にしている考え方 — 音高と音程、音階と調、和音、和声、声部、リズムと拍子 — を、楽譜ではなく TypeScript を書く読者に向けて説明しています。
104
63
 
105
- 各領域のガイド: [音高と記譜](docs/ja/pitch-and-notation.md)、[スケールとモード](docs/ja/scales-and-modes.md)、[和声](docs/ja/harmony.md)、[調関係と転調](docs/ja/key-relations-and-modulation.md)、[ボイシング](docs/ja/voicing.md)、[対位法と和声課題](docs/ja/counterpoint-and-part-writing.md)、[時間とアレンジ](docs/ja/time-and-arrangement.md)、[解析](docs/ja/analysis.md)、[旋律とモチーフ](docs/ja/melody-and-motifs.md)、[リズムとグルーヴ](docs/ja/rhythm-and-groove.md)、[生成](docs/ja/generation.md)、[リハーモナイズ](docs/ja/reharmonization.md)、[楽器と演奏可能性](docs/ja/instruments-and-playability.md)、[音律と周波数](docs/ja/tuning-and-frequency.md)。
64
+ そうでなければ、[はじめに](docs/ja/introduction.md)と[使いはじめる](docs/ja/getting-started.md)から読んでください。各分野のガイドとリファレンスはそこから辿れます。ガイド中の `ts` の例はすべてテストスイートで実行され、行末コメントがリテラルを名指していれば(em ダッシュに続けて理由が書かれていてもかまいません)実際の戻り値と照合されます。
106
65
 
107
- 横断的な話題: [決定性とシード](docs/ja/determinism-and-seeding.md)、[エラーと検証](docs/ja/errors-and-validation.md)、[パフォーマンス](docs/ja/performance.md)、[相互運用](docs/ja/interoperability.md)。
66
+ ## できないこと
108
67
 
109
- リファレンス: [API リファレンス](docs/ja/api-reference.md)、[用語集](docs/ja/glossary.md)、[FAQ と制限](docs/ja/faq.md)。
68
+ - **入出力・記譜・音声は扱いません。** MIDI ファイルの読み書き、楽譜の描画、音声解析、再生はいずれも対象外です。パーサーは呼び出し側で用意し、ノートイベントを渡してください。その下の層が必要な場合、[libsonare](https://github.com/libraz/libsonare) が音声解析・マスタリング・合成・SMF の入出力を扱います。両者はコードを共有せず、どちらも他方を必要としません。
69
+ - **微分音の解析は行いません。** 周波数、セント、オクターブの等分割、純正律の比は `core` にありますが、音高より上の層はすべて 12 のピッチクラスで動きます。
70
+ - **旋法体系そのものは扱いません。** `WORLD_SCALES` が記録するのは、その伝統が名前を与えている音の素材 — ターット、マカームの音組織、日本の五音音階 — であって、その上に築かれた語法ではありません。
71
+ - **コーパスは同梱しません。** 統計を取るためのデータは含みません。
110
72
 
111
- これらのガイドの `ts` の例はすべてテストスイートで実行され、末尾コメントに書いた期待値は実際の返り値と照合されます。生成される TypeDoc のリファレンスは `docs/api` に出力され、手書きガイドとは分かれています。
73
+ 残りは[疑問と制限](docs/ja/faq.md)にまとめています。機能和声の読みが適用できない場合や、エンジンが推測しないことについてもそこで扱います。
112
74
 
113
75
  ## ライセンス
114
76
 
115
- [@libraz/libcantus](https://github.com/libraz/libcantus) は [Apache License 2.0](LICENSE) で提供します。
77
+ [@libraz/libcantus](https://github.com/libraz/libcantus) は [Apache License 2.0](LICENSE) で公開しています。
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkMXO72PLYcjs = require('../chunk-MXO72PLY.cjs');
3
+ var _chunkHWHGOVO6cjs = require('../chunk-HWHGOVO6.cjs');
4
4
 
5
5
 
6
6
 
@@ -18,6 +18,7 @@ var _chunkMXO72PLYcjs = require('../chunk-MXO72PLY.cjs');
18
18
 
19
19
 
20
20
 
21
+ var _chunkHPVSH7SFcjs = require('../chunk-HPVSH7SF.cjs');
21
22
 
22
23
 
23
24
 
@@ -25,7 +26,6 @@ var _chunkMXO72PLYcjs = require('../chunk-MXO72PLY.cjs');
25
26
 
26
27
 
27
28
 
28
- var _chunkB6XNKWZVcjs = require('../chunk-B6XNKWZV.cjs');
29
29
 
30
30
 
31
31
 
@@ -50,14 +50,14 @@ var _chunkB6XNKWZVcjs = require('../chunk-B6XNKWZV.cjs');
50
50
 
51
51
 
52
52
 
53
- var _chunkOE6WK2Y2cjs = require('../chunk-OE6WK2Y2.cjs');
54
- require('../chunk-K4ZJUGF4.cjs');
55
53
 
56
54
 
57
- var _chunkUADYAYATcjs = require('../chunk-UADYAYAT.cjs');
58
- require('../chunk-Q2WGKJNN.cjs');
55
+ var _chunkSGLEQVJHcjs = require('../chunk-SGLEQVJH.cjs');
56
+ require('../chunk-35NBV2FT.cjs');
59
57
 
60
58
 
59
+ var _chunk3R3QVKY5cjs = require('../chunk-3R3QVKY5.cjs');
60
+ require('../chunk-S5BKZZGM.cjs');
61
61
 
62
62
 
63
63
 
@@ -105,5 +105,9 @@ require('../chunk-Q2WGKJNN.cjs');
105
105
 
106
106
 
107
107
 
108
- exports.MODAL_SCALE_NAMES = _chunkOE6WK2Y2cjs.MODAL_SCALE_NAMES; exports.NoteSafety = _chunkUADYAYATcjs.NoteSafety; exports.analyzeArrangement = _chunkB6XNKWZVcjs.analyzeArrangement; exports.analyzeChord = _chunkOE6WK2Y2cjs.analyzeChord; exports.analyzeVoice = _chunkB6XNKWZVcjs.analyzeVoice; exports.augmentedSixthChord = _chunkOE6WK2Y2cjs.augmentedSixthChord; exports.augmentedSixthFromPitchClasses = _chunkOE6WK2Y2cjs.augmentedSixthFromPitchClasses; exports.augmentedSixthKind = _chunkOE6WK2Y2cjs.augmentedSixthKind; exports.borrowedSource = _chunkOE6WK2Y2cjs.borrowedSource; exports.chordTimelineFromChords = _chunkB6XNKWZVcjs.chordTimelineFromChords; exports.chordTimelineFromNotes = _chunkB6XNKWZVcjs.chordTimelineFromNotes; exports.chordToRoman = _chunkOE6WK2Y2cjs.chordToRoman; exports.compareMelodies = _chunkB6XNKWZVcjs.compareMelodies; exports.createArrangementSession = _chunkB6XNKWZVcjs.createArrangementSession; exports.detectCadence = _chunkOE6WK2Y2cjs.detectCadence; exports.detectCadences = _chunkB6XNKWZVcjs.detectCadences; exports.detectChord = _chunkOE6WK2Y2cjs.detectChord; exports.detectChordBest = _chunkOE6WK2Y2cjs.detectChordBest; exports.detectKey = _chunkOE6WK2Y2cjs.detectKey; exports.detectKeyBest = _chunkOE6WK2Y2cjs.detectKeyBest; exports.detectKeyFromNotes = _chunkOE6WK2Y2cjs.detectKeyFromNotes; exports.detectModulations = _chunkB6XNKWZVcjs.detectModulations; exports.explainRoman = _chunkOE6WK2Y2cjs.explainRoman; exports.extractMotifs = _chunkB6XNKWZVcjs.extractMotifs; exports.functionOf = _chunkOE6WK2Y2cjs.functionOf; exports.hypermeter = _chunkB6XNKWZVcjs.hypermeter; exports.isBorrowedChord = _chunkOE6WK2Y2cjs.isBorrowedChord; exports.isDiatonic = _chunkOE6WK2Y2cjs.isDiatonic; exports.isMinorKey = _chunkOE6WK2Y2cjs.isMinorKey; exports.keyTimelineFromNotes = _chunkB6XNKWZVcjs.keyTimelineFromNotes; exports.melodicContour = _chunkB6XNKWZVcjs.melodicContour; exports.melodicSimilarity = _chunkB6XNKWZVcjs.melodicSimilarity; exports.motifFromNotes = _chunkB6XNKWZVcjs.motifFromNotes; exports.phrasesFromTimeline = _chunkB6XNKWZVcjs.phrasesFromTimeline; exports.pivotChords = _chunkOE6WK2Y2cjs.pivotChords; exports.prevailingKeyOf = _chunkB6XNKWZVcjs.prevailingKeyOf; exports.reduceProgression = _chunkB6XNKWZVcjs.reduceProgression; exports.relateMotifs = _chunkB6XNKWZVcjs.relateMotifs; exports.romanToChord = _chunkOE6WK2Y2cjs.romanToChord; exports.secondaryDominant = _chunkOE6WK2Y2cjs.secondaryDominant; exports.secondaryDominantOf = _chunkOE6WK2Y2cjs.secondaryDominantOf; exports.sectionsFromNotes = _chunkB6XNKWZVcjs.sectionsFromNotes; exports.spellAugmentedSixth = _chunkOE6WK2Y2cjs.spellAugmentedSixth; exports.spellLine = _chunkMXO72PLYcjs.spellLine; exports.structuralCadences = _chunkB6XNKWZVcjs.structuralCadences; exports.tensionCurve = _chunkB6XNKWZVcjs.tensionCurve; exports.tensionCurveFrom = _chunkB6XNKWZVcjs.tensionCurveFrom; exports.toVoiceNotes = _chunkB6XNKWZVcjs.toVoiceNotes;
108
+
109
+
110
+
111
+
112
+ exports.MODAL_SCALE_NAMES = _chunkSGLEQVJHcjs.MODAL_SCALE_NAMES; exports.NoteSafety = _chunk3R3QVKY5cjs.NoteSafety; exports.analyzeArrangement = _chunkHPVSH7SFcjs.analyzeArrangement; exports.analyzeChord = _chunkSGLEQVJHcjs.analyzeChord; exports.analyzePolyphony = _chunkHPVSH7SFcjs.analyzePolyphony; exports.analyzeVoice = _chunkSGLEQVJHcjs.analyzeVoice; exports.assertChordTimeline = _chunkSGLEQVJHcjs.assertChordTimeline; exports.augmentedSixthChord = _chunkSGLEQVJHcjs.augmentedSixthChord; exports.augmentedSixthFromPitchClasses = _chunkSGLEQVJHcjs.augmentedSixthFromPitchClasses; exports.augmentedSixthKind = _chunkSGLEQVJHcjs.augmentedSixthKind; exports.borrowedSource = _chunkSGLEQVJHcjs.borrowedSource; exports.chordTimelineFromChords = _chunkSGLEQVJHcjs.chordTimelineFromChords; exports.chordTimelineFromNotes = _chunkSGLEQVJHcjs.chordTimelineFromNotes; exports.chordToRoman = _chunkSGLEQVJHcjs.chordToRoman; exports.compareMelodies = _chunkHPVSH7SFcjs.compareMelodies; exports.createArrangementSession = _chunkHPVSH7SFcjs.createArrangementSession; exports.detectCadence = _chunkSGLEQVJHcjs.detectCadence; exports.detectCadences = _chunkSGLEQVJHcjs.detectCadences; exports.detectChord = _chunkSGLEQVJHcjs.detectChord; exports.detectChordBest = _chunkSGLEQVJHcjs.detectChordBest; exports.detectKey = _chunkSGLEQVJHcjs.detectKey; exports.detectKeyBest = _chunkSGLEQVJHcjs.detectKeyBest; exports.detectKeyFromNotes = _chunkSGLEQVJHcjs.detectKeyFromNotes; exports.detectModulations = _chunkSGLEQVJHcjs.detectModulations; exports.explainRoman = _chunkSGLEQVJHcjs.explainRoman; exports.extractMotifs = _chunkHPVSH7SFcjs.extractMotifs; exports.functionOf = _chunkSGLEQVJHcjs.functionOf; exports.hypermeter = _chunkHPVSH7SFcjs.hypermeter; exports.isBorrowedChord = _chunkSGLEQVJHcjs.isBorrowedChord; exports.isDiatonic = _chunkSGLEQVJHcjs.isDiatonic; exports.isMinorKey = _chunkSGLEQVJHcjs.isMinorKey; exports.keyTimelineFromNotes = _chunkSGLEQVJHcjs.keyTimelineFromNotes; exports.melodicContour = _chunkHPVSH7SFcjs.melodicContour; exports.melodicSimilarity = _chunkHPVSH7SFcjs.melodicSimilarity; exports.motifFromNotes = _chunkHPVSH7SFcjs.motifFromNotes; exports.phrasesFromTimeline = _chunkHPVSH7SFcjs.phrasesFromTimeline; exports.pivotChords = _chunkSGLEQVJHcjs.pivotChords; exports.prevailingKeyOf = _chunkSGLEQVJHcjs.prevailingKeyOf; exports.reduceProgression = _chunkHPVSH7SFcjs.reduceProgression; exports.relateMotifs = _chunkHPVSH7SFcjs.relateMotifs; exports.romanToChord = _chunkSGLEQVJHcjs.romanToChord; exports.secondaryDominant = _chunkSGLEQVJHcjs.secondaryDominant; exports.secondaryDominantOf = _chunkSGLEQVJHcjs.secondaryDominantOf; exports.sectionsFromNotes = _chunkHPVSH7SFcjs.sectionsFromNotes; exports.spellAugmentedSixth = _chunkSGLEQVJHcjs.spellAugmentedSixth; exports.spellLine = _chunkHWHGOVO6cjs.spellLine; exports.structuralCadences = _chunkHPVSH7SFcjs.structuralCadences; exports.tensionCurve = _chunkHPVSH7SFcjs.tensionCurve; exports.tensionCurveFrom = _chunkHPVSH7SFcjs.tensionCurveFrom; exports.toVoiceNotes = _chunkSGLEQVJHcjs.toVoiceNotes;
109
113
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/libcantus/libcantus/dist/analyze/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,23FAAC","file":"/home/runner/work/libcantus/libcantus/dist/analyze/index.cjs"}
1
+ {"version":3,"sources":["/home/runner/work/libcantus/libcantus/dist/analyze/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACF,yDAA8B;AAC9B,iCAA8B;AAC9B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,+/FAAC","file":"/home/runner/work/libcantus/libcantus/dist/analyze/index.cjs"}