@kongyo2/kongyoroid 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/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/cache.d.ts +36 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +109 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +502 -0
- package/dist/cli.js.map +1 -0
- package/dist/concurrency.d.ts +14 -0
- package/dist/concurrency.d.ts.map +1 -0
- package/dist/concurrency.js +107 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +81 -0
- package/dist/errors.js.map +1 -0
- package/dist/formant.d.ts +34 -0
- package/dist/formant.d.ts.map +1 -0
- package/dist/formant.js +622 -0
- package/dist/formant.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +6 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +144 -0
- package/dist/io.js.map +1 -0
- package/dist/kongyoroid.d.ts +82 -0
- package/dist/kongyoroid.d.ts.map +1 -0
- package/dist/kongyoroid.js +275 -0
- package/dist/kongyoroid.js.map +1 -0
- package/dist/limits.d.ts +18 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +15 -0
- package/dist/limits.js.map +1 -0
- package/dist/mora.d.ts +28 -0
- package/dist/mora.d.ts.map +1 -0
- package/dist/mora.js +295 -0
- package/dist/mora.js.map +1 -0
- package/dist/notation.d.ts +15 -0
- package/dist/notation.d.ts.map +1 -0
- package/dist/notation.js +114 -0
- package/dist/notation.js.map +1 -0
- package/dist/pitch.d.ts +5 -0
- package/dist/pitch.d.ts.map +1 -0
- package/dist/pitch.js +36 -0
- package/dist/pitch.js.map +1 -0
- package/dist/player.d.ts +9 -0
- package/dist/player.d.ts.map +1 -0
- package/dist/player.js +81 -0
- package/dist/player.js.map +1 -0
- package/dist/request.d.ts +12 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/request.js +115 -0
- package/dist/request.js.map +1 -0
- package/dist/schema.d.ts +9 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +267 -0
- package/dist/schema.js.map +1 -0
- package/dist/score.d.ts +37 -0
- package/dist/score.d.ts.map +1 -0
- package/dist/score.js +166 -0
- package/dist/score.js.map +1 -0
- package/dist/text.d.ts +3 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +54 -0
- package/dist/text.js.map +1 -0
- package/dist/types.d.ts +121 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +13 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +59 -0
- package/dist/validate.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/dist/voicevox/api.d.ts +79 -0
- package/dist/voicevox/api.d.ts.map +1 -0
- package/dist/voicevox/api.js +176 -0
- package/dist/voicevox/api.js.map +1 -0
- package/dist/voicevox/client.d.ts +64 -0
- package/dist/voicevox/client.d.ts.map +1 -0
- package/dist/voicevox/client.js +321 -0
- package/dist/voicevox/client.js.map +1 -0
- package/dist/voicevox/dictionary.d.ts +21 -0
- package/dist/voicevox/dictionary.d.ts.map +1 -0
- package/dist/voicevox/dictionary.js +41 -0
- package/dist/voicevox/dictionary.js.map +1 -0
- package/dist/voicevox/song.d.ts +12 -0
- package/dist/voicevox/song.d.ts.map +1 -0
- package/dist/voicevox/song.js +45 -0
- package/dist/voicevox/song.js.map +1 -0
- package/dist/voicevox/speech.d.ts +17 -0
- package/dist/voicevox/speech.d.ts.map +1 -0
- package/dist/voicevox/speech.js +100 -0
- package/dist/voicevox/speech.js.map +1 -0
- package/dist/voicevox/styles.d.ts +15 -0
- package/dist/voicevox/styles.d.ts.map +1 -0
- package/dist/voicevox/styles.js +103 -0
- package/dist/voicevox/styles.js.map +1 -0
- package/dist/wav.d.ts +18 -0
- package/dist/wav.d.ts.map +1 -0
- package/dist/wav.js +198 -0
- package/dist/wav.js.map +1 -0
- package/examples/batch.jsonl +4 -0
- package/examples/song-notes.json +24 -0
- package/examples/song.json +12 -0
- package/examples/speech-kana.json +6 -0
- package/examples/speech.json +8 -0
- package/package.json +86 -0
package/dist/mora.js
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { unsupported } from "./errors.js";
|
|
2
|
+
const rows = [
|
|
3
|
+
["ヴォ", "v", "o"],
|
|
4
|
+
["ヴェ", "v", "e"],
|
|
5
|
+
["ヴィ", "v", "i"],
|
|
6
|
+
["ヴァ", "v", "a"],
|
|
7
|
+
["ヴ", "v", "u"],
|
|
8
|
+
["ン", null, "N"],
|
|
9
|
+
["ワ", "w", "a"],
|
|
10
|
+
["ロ", "r", "o"],
|
|
11
|
+
["レ", "r", "e"],
|
|
12
|
+
["ル", "r", "u"],
|
|
13
|
+
["リョ", "ry", "o"],
|
|
14
|
+
["リュ", "ry", "u"],
|
|
15
|
+
["リャ", "ry", "a"],
|
|
16
|
+
["リェ", "ry", "e"],
|
|
17
|
+
["リィ", "ry", "i"],
|
|
18
|
+
["リ", "r", "i"],
|
|
19
|
+
["ラ", "r", "a"],
|
|
20
|
+
["ヨ", "y", "o"],
|
|
21
|
+
["ユ", "y", "u"],
|
|
22
|
+
["ヤ", "y", "a"],
|
|
23
|
+
["モ", "m", "o"],
|
|
24
|
+
["メ", "m", "e"],
|
|
25
|
+
["ム", "m", "u"],
|
|
26
|
+
["ミョ", "my", "o"],
|
|
27
|
+
["ミュ", "my", "u"],
|
|
28
|
+
["ミャ", "my", "a"],
|
|
29
|
+
["ミェ", "my", "e"],
|
|
30
|
+
["ミィ", "my", "i"],
|
|
31
|
+
["ミ", "m", "i"],
|
|
32
|
+
["マ", "m", "a"],
|
|
33
|
+
["ポ", "p", "o"],
|
|
34
|
+
["ボ", "b", "o"],
|
|
35
|
+
["ホ", "h", "o"],
|
|
36
|
+
["ペ", "p", "e"],
|
|
37
|
+
["ベ", "b", "e"],
|
|
38
|
+
["ヘ", "h", "e"],
|
|
39
|
+
["プ", "p", "u"],
|
|
40
|
+
["ブ", "b", "u"],
|
|
41
|
+
["フォ", "f", "o"],
|
|
42
|
+
["フェ", "f", "e"],
|
|
43
|
+
["フィ", "f", "i"],
|
|
44
|
+
["ファ", "f", "a"],
|
|
45
|
+
["フ", "f", "u"],
|
|
46
|
+
["ピョ", "py", "o"],
|
|
47
|
+
["ピュ", "py", "u"],
|
|
48
|
+
["ピャ", "py", "a"],
|
|
49
|
+
["ピェ", "py", "e"],
|
|
50
|
+
["ピィ", "py", "i"],
|
|
51
|
+
["ピ", "p", "i"],
|
|
52
|
+
["ビョ", "by", "o"],
|
|
53
|
+
["ビュ", "by", "u"],
|
|
54
|
+
["ビャ", "by", "a"],
|
|
55
|
+
["ビェ", "by", "e"],
|
|
56
|
+
["ビィ", "by", "i"],
|
|
57
|
+
["ビ", "b", "i"],
|
|
58
|
+
["ヒョ", "hy", "o"],
|
|
59
|
+
["ヒュ", "hy", "u"],
|
|
60
|
+
["ヒャ", "hy", "a"],
|
|
61
|
+
["ヒェ", "hy", "e"],
|
|
62
|
+
["ヒィ", "hy", "i"],
|
|
63
|
+
["ヒ", "h", "i"],
|
|
64
|
+
["パ", "p", "a"],
|
|
65
|
+
["バ", "b", "a"],
|
|
66
|
+
["ハ", "h", "a"],
|
|
67
|
+
["ノ", "n", "o"],
|
|
68
|
+
["ネ", "n", "e"],
|
|
69
|
+
["ヌ", "n", "u"],
|
|
70
|
+
["ニョ", "ny", "o"],
|
|
71
|
+
["ニュ", "ny", "u"],
|
|
72
|
+
["ニャ", "ny", "a"],
|
|
73
|
+
["ニェ", "ny", "e"],
|
|
74
|
+
["ニィ", "ny", "i"],
|
|
75
|
+
["ニ", "n", "i"],
|
|
76
|
+
["ナ", "n", "a"],
|
|
77
|
+
["ドゥ", "d", "u"],
|
|
78
|
+
["ド", "d", "o"],
|
|
79
|
+
["トゥ", "t", "u"],
|
|
80
|
+
["ト", "t", "o"],
|
|
81
|
+
["デョ", "dy", "o"],
|
|
82
|
+
["デュ", "dy", "u"],
|
|
83
|
+
["デャ", "dy", "a"],
|
|
84
|
+
["デェ", "dy", "e"],
|
|
85
|
+
["ディ", "d", "i"],
|
|
86
|
+
["デ", "d", "e"],
|
|
87
|
+
["テョ", "ty", "o"],
|
|
88
|
+
["テュ", "ty", "u"],
|
|
89
|
+
["テャ", "ty", "a"],
|
|
90
|
+
["テェ", "ty", "e"],
|
|
91
|
+
["ティ", "t", "i"],
|
|
92
|
+
["テ", "t", "e"],
|
|
93
|
+
["ツォ", "ts", "o"],
|
|
94
|
+
["ツェ", "ts", "e"],
|
|
95
|
+
["ツィ", "ts", "i"],
|
|
96
|
+
["ツァ", "ts", "a"],
|
|
97
|
+
["ツ", "ts", "u"],
|
|
98
|
+
["ッ", null, "cl"],
|
|
99
|
+
["チョ", "ch", "o"],
|
|
100
|
+
["チュ", "ch", "u"],
|
|
101
|
+
["チャ", "ch", "a"],
|
|
102
|
+
["チェ", "ch", "e"],
|
|
103
|
+
["チ", "ch", "i"],
|
|
104
|
+
["ダ", "d", "a"],
|
|
105
|
+
["タ", "t", "a"],
|
|
106
|
+
["ゾ", "z", "o"],
|
|
107
|
+
["ソ", "s", "o"],
|
|
108
|
+
["ゼ", "z", "e"],
|
|
109
|
+
["セ", "s", "e"],
|
|
110
|
+
["ズィ", "z", "i"],
|
|
111
|
+
["ズ", "z", "u"],
|
|
112
|
+
["スィ", "s", "i"],
|
|
113
|
+
["ス", "s", "u"],
|
|
114
|
+
["ジョ", "j", "o"],
|
|
115
|
+
["ジュ", "j", "u"],
|
|
116
|
+
["ジャ", "j", "a"],
|
|
117
|
+
["ジェ", "j", "e"],
|
|
118
|
+
["ジ", "j", "i"],
|
|
119
|
+
["ショ", "sh", "o"],
|
|
120
|
+
["シュ", "sh", "u"],
|
|
121
|
+
["シャ", "sh", "a"],
|
|
122
|
+
["シェ", "sh", "e"],
|
|
123
|
+
["シ", "sh", "i"],
|
|
124
|
+
["ザ", "z", "a"],
|
|
125
|
+
["サ", "s", "a"],
|
|
126
|
+
["ゴ", "g", "o"],
|
|
127
|
+
["コ", "k", "o"],
|
|
128
|
+
["ゲ", "g", "e"],
|
|
129
|
+
["ケ", "k", "e"],
|
|
130
|
+
["グヮ", "gw", "a"],
|
|
131
|
+
["グォ", "gw", "o"],
|
|
132
|
+
["グェ", "gw", "e"],
|
|
133
|
+
["グゥ", "gw", "u"],
|
|
134
|
+
["グィ", "gw", "i"],
|
|
135
|
+
["グ", "g", "u"],
|
|
136
|
+
["クヮ", "kw", "a"],
|
|
137
|
+
["クォ", "kw", "o"],
|
|
138
|
+
["クェ", "kw", "e"],
|
|
139
|
+
["クゥ", "kw", "u"],
|
|
140
|
+
["クィ", "kw", "i"],
|
|
141
|
+
["ク", "k", "u"],
|
|
142
|
+
["ギョ", "gy", "o"],
|
|
143
|
+
["ギュ", "gy", "u"],
|
|
144
|
+
["ギャ", "gy", "a"],
|
|
145
|
+
["ギェ", "gy", "e"],
|
|
146
|
+
["ギィ", "gy", "i"],
|
|
147
|
+
["ギ", "g", "i"],
|
|
148
|
+
["キョ", "ky", "o"],
|
|
149
|
+
["キュ", "ky", "u"],
|
|
150
|
+
["キャ", "ky", "a"],
|
|
151
|
+
["キェ", "ky", "e"],
|
|
152
|
+
["キィ", "ky", "i"],
|
|
153
|
+
["キ", "k", "i"],
|
|
154
|
+
["ガ", "g", "a"],
|
|
155
|
+
["カ", "k", "a"],
|
|
156
|
+
["オ", null, "o"],
|
|
157
|
+
["エ", null, "e"],
|
|
158
|
+
["ウォ", "w", "o"],
|
|
159
|
+
["ウェ", "w", "e"],
|
|
160
|
+
["ウゥ", "w", "u"],
|
|
161
|
+
["ウィ", "w", "i"],
|
|
162
|
+
["ウ", null, "u"],
|
|
163
|
+
["イェ", "y", "e"],
|
|
164
|
+
["イ", null, "i"],
|
|
165
|
+
["ア", null, "a"],
|
|
166
|
+
["ヴョ", "by", "o"],
|
|
167
|
+
["ヴュ", "by", "u"],
|
|
168
|
+
["ヴャ", "by", "a"],
|
|
169
|
+
["ヲ", null, "o"],
|
|
170
|
+
["ヱ", null, "e"],
|
|
171
|
+
["ヰ", null, "i"],
|
|
172
|
+
["ヮ", "w", "a"],
|
|
173
|
+
["ョ", "y", "o"],
|
|
174
|
+
["ュ", "y", "u"],
|
|
175
|
+
["ヅ", "z", "u"],
|
|
176
|
+
["ヂョ", "j", "o"],
|
|
177
|
+
["ヂュ", "j", "u"],
|
|
178
|
+
["ヂャ", "j", "a"],
|
|
179
|
+
["ヂェ", "j", "e"],
|
|
180
|
+
["ヂ", "j", "i"],
|
|
181
|
+
["グァ", "gw", "a"],
|
|
182
|
+
["クァ", "kw", "a"],
|
|
183
|
+
["ヶ", "k", "e"],
|
|
184
|
+
["ャ", "y", "a"],
|
|
185
|
+
["ォ", null, "o"],
|
|
186
|
+
["ェ", null, "e"],
|
|
187
|
+
["ゥ", null, "u"],
|
|
188
|
+
["ィ", null, "i"],
|
|
189
|
+
["ァ", null, "a"],
|
|
190
|
+
];
|
|
191
|
+
const table = new Map();
|
|
192
|
+
for (const [kana, consonant, vowel] of rows)
|
|
193
|
+
table.set(kana, { consonant, vowel });
|
|
194
|
+
export const MORA_TABLE = table;
|
|
195
|
+
const VOWEL_KANA = {
|
|
196
|
+
a: "ア",
|
|
197
|
+
i: "イ",
|
|
198
|
+
u: "ウ",
|
|
199
|
+
e: "エ",
|
|
200
|
+
o: "オ",
|
|
201
|
+
N: "ン",
|
|
202
|
+
cl: "ッ",
|
|
203
|
+
pau: "",
|
|
204
|
+
};
|
|
205
|
+
const UNVOICED_KANA = { A: "ア", I: "イ", U: "ウ", E: "エ", O: "オ" };
|
|
206
|
+
export function vowelToKana(vowel) {
|
|
207
|
+
switch (vowel) {
|
|
208
|
+
case "A":
|
|
209
|
+
case "I":
|
|
210
|
+
case "U":
|
|
211
|
+
case "E":
|
|
212
|
+
case "O":
|
|
213
|
+
return UNVOICED_KANA[vowel];
|
|
214
|
+
default:
|
|
215
|
+
return VOWEL_KANA[vowel];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export function toKatakana(text) {
|
|
219
|
+
let out = "";
|
|
220
|
+
for (const char of text.normalize("NFKC")) {
|
|
221
|
+
const code = char.codePointAt(0) ?? 0;
|
|
222
|
+
out += code >= 0x3041 && code <= 0x3096 ? String.fromCodePoint(code + 0x60) : char;
|
|
223
|
+
}
|
|
224
|
+
return out;
|
|
225
|
+
}
|
|
226
|
+
export function lookupMora(kana) {
|
|
227
|
+
return table.get(kana);
|
|
228
|
+
}
|
|
229
|
+
const PAUSE_WEIGHTS = new Map([
|
|
230
|
+
["、", 1],
|
|
231
|
+
[",", 1],
|
|
232
|
+
["。", 2],
|
|
233
|
+
[".", 2],
|
|
234
|
+
["!", 2],
|
|
235
|
+
["?", 2],
|
|
236
|
+
[":", 1],
|
|
237
|
+
[";", 1],
|
|
238
|
+
["…", 1.5],
|
|
239
|
+
["‥", 1],
|
|
240
|
+
["・", 0.5],
|
|
241
|
+
["\n", 2],
|
|
242
|
+
]);
|
|
243
|
+
const LONG_VOWEL_MARKS = new Set(["ー", "−", "-", "~", "〜"]);
|
|
244
|
+
export function isLongVowelMark(char) {
|
|
245
|
+
return LONG_VOWEL_MARKS.has(char);
|
|
246
|
+
}
|
|
247
|
+
export function kanaToUnits(text, path = "$.text") {
|
|
248
|
+
const chars = Array.from(toKatakana(text));
|
|
249
|
+
const units = [];
|
|
250
|
+
let index = 0;
|
|
251
|
+
while (index < chars.length) {
|
|
252
|
+
const char = chars[index] ?? "";
|
|
253
|
+
const pauseWeight = PAUSE_WEIGHTS.get(char);
|
|
254
|
+
if (pauseWeight !== undefined) {
|
|
255
|
+
units.push({ kind: "pause", text: char, weight: pauseWeight });
|
|
256
|
+
index += 1;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (/^\s$/u.test(char)) {
|
|
260
|
+
index += 1;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
if (isLongVowelMark(char)) {
|
|
264
|
+
const previous = units.at(-1);
|
|
265
|
+
if (previous === undefined || previous.kind !== "mora" || previous.vowel === "cl" || previous.vowel === "pau") {
|
|
266
|
+
unsupported(`${path}[${index}]`, "A long-vowel mark must follow a voiced mora.");
|
|
267
|
+
}
|
|
268
|
+
units.push({ kind: "mora", text: vowelToKana(previous.vowel), consonant: null, vowel: previous.vowel });
|
|
269
|
+
index += 1;
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
const pair = char + (chars[index + 1] ?? "");
|
|
273
|
+
const twoChar = chars.length > index + 1 ? table.get(pair) : undefined;
|
|
274
|
+
if (twoChar !== undefined) {
|
|
275
|
+
units.push({ kind: "mora", text: pair, consonant: twoChar.consonant, vowel: twoChar.vowel });
|
|
276
|
+
index += 2;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const single = table.get(char);
|
|
280
|
+
if (single === undefined) {
|
|
281
|
+
unsupported(`${path}[${index}]`, `Unsupported character ${JSON.stringify(char)}; only kana, long-vowel marks, and punctuation are accepted here.`, "Use the voicevox engine for kanji text, or write the reading in hiragana or katakana.");
|
|
282
|
+
}
|
|
283
|
+
units.push({ kind: "mora", text: char, consonant: single.consonant, vowel: single.vowel });
|
|
284
|
+
index += 1;
|
|
285
|
+
}
|
|
286
|
+
return units;
|
|
287
|
+
}
|
|
288
|
+
export function kanaToMoras(text, path = "$.text") {
|
|
289
|
+
const moras = [];
|
|
290
|
+
for (const unit of kanaToUnits(text, path))
|
|
291
|
+
if (unit.kind === "mora")
|
|
292
|
+
moras.push(unit);
|
|
293
|
+
return moras;
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=mora.js.map
|
package/dist/mora.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mora.js","sourceRoot":"","sources":["../src/mora.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA4C1C,MAAM,IAAI,GAA4D;IACpE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAChB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACf,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC;IAChB,CAAC,IAAI,EAAE,GAAG,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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Consonant, UnvoicedVowel, Vowel } from "./mora.ts";
|
|
2
|
+
export interface NotationMora {
|
|
3
|
+
readonly text: string;
|
|
4
|
+
readonly consonant: Consonant | null;
|
|
5
|
+
readonly vowel: Vowel | UnvoicedVowel;
|
|
6
|
+
}
|
|
7
|
+
export interface AccentPhrase {
|
|
8
|
+
readonly moras: readonly NotationMora[];
|
|
9
|
+
readonly accent: number;
|
|
10
|
+
readonly pause: boolean;
|
|
11
|
+
readonly interrogative: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function parseKanaNotation(text: string, path?: string): readonly AccentPhrase[];
|
|
14
|
+
export declare function formatKanaNotation(phrases: readonly AccentPhrase[]): string;
|
|
15
|
+
//# sourceMappingURL=notation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notation.d.ts","sourceRoot":"","sources":["../src/notation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAGjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AA4ED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAiB,GAAG,SAAS,YAAY,EAAE,CAwBhG;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAY3E"}
|
package/dist/notation.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { invalid } from "./errors.js";
|
|
2
|
+
import { isLongVowelMark, lookupMora, toKatakana, vowelToKana } from "./mora.js";
|
|
3
|
+
const ACCENT = "'";
|
|
4
|
+
const UNVOICE = "_";
|
|
5
|
+
const PHRASE = "/";
|
|
6
|
+
const PAUSE = "、";
|
|
7
|
+
const DEVOICED = {
|
|
8
|
+
a: "A",
|
|
9
|
+
i: "I",
|
|
10
|
+
u: "U",
|
|
11
|
+
e: "E",
|
|
12
|
+
o: "O",
|
|
13
|
+
};
|
|
14
|
+
function unvoice(vowel, path, text) {
|
|
15
|
+
if (vowel === "N" || vowel === "cl" || vowel === "pau") {
|
|
16
|
+
return invalid(path, `Only vowels can be devoiced with "_": ${text}.`);
|
|
17
|
+
}
|
|
18
|
+
return DEVOICED[vowel];
|
|
19
|
+
}
|
|
20
|
+
function parsePhrase(phrase, path) {
|
|
21
|
+
const chars = Array.from(phrase);
|
|
22
|
+
const moras = [];
|
|
23
|
+
let accent;
|
|
24
|
+
let index = 0;
|
|
25
|
+
while (index < chars.length) {
|
|
26
|
+
const char = chars[index] ?? "";
|
|
27
|
+
if (char === ACCENT) {
|
|
28
|
+
if (moras.length === 0)
|
|
29
|
+
invalid(path, `An accent mark cannot start a phrase: ${phrase}.`);
|
|
30
|
+
if (accent !== undefined)
|
|
31
|
+
invalid(path, `A phrase can carry only one accent mark: ${phrase}.`);
|
|
32
|
+
accent = moras.length;
|
|
33
|
+
index += 1;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (isLongVowelMark(char)) {
|
|
37
|
+
const previous = moras.at(-1);
|
|
38
|
+
if (previous === undefined || previous.vowel === "cl" || previous.vowel === "pau") {
|
|
39
|
+
invalid(path, `A long-vowel mark must follow a voiced mora: ${phrase}.`);
|
|
40
|
+
}
|
|
41
|
+
moras.push({ text: vowelToKana(previous.vowel), consonant: null, vowel: previous.vowel });
|
|
42
|
+
index += 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const devoiced = char === UNVOICE;
|
|
46
|
+
const start = devoiced ? index + 1 : index;
|
|
47
|
+
const head = chars[start];
|
|
48
|
+
const pair = head === undefined ? "" : head + (chars[start + 1] ?? "");
|
|
49
|
+
const twoChar = chars.length > start + 1 && chars[start + 1] !== ACCENT ? lookupMora(pair) : undefined;
|
|
50
|
+
const match = twoChar ?? (head === undefined ? undefined : lookupMora(head));
|
|
51
|
+
const text = twoChar === undefined ? (head ?? "") : pair;
|
|
52
|
+
if (match === undefined || head === undefined) {
|
|
53
|
+
invalid(path, `Unrecognized reading ${JSON.stringify(chars.slice(index, index + 2).join(""))} in phrase ${JSON.stringify(phrase)}.`, "Write readings in katakana; separate accent phrases with / and mark the accent nucleus with '.");
|
|
54
|
+
}
|
|
55
|
+
moras.push({
|
|
56
|
+
text,
|
|
57
|
+
consonant: match.consonant,
|
|
58
|
+
vowel: devoiced ? unvoice(match.vowel, path, text) : match.vowel,
|
|
59
|
+
});
|
|
60
|
+
index = start + Array.from(text).length;
|
|
61
|
+
}
|
|
62
|
+
if (accent === undefined) {
|
|
63
|
+
invalid(path, `Every accent phrase needs exactly one accent mark: ${phrase}.`, "Example: コンニチワ' or ズ'ンダモン.");
|
|
64
|
+
}
|
|
65
|
+
return { moras, accent };
|
|
66
|
+
}
|
|
67
|
+
export function parseKanaNotation(text, path = "$.kana") {
|
|
68
|
+
const normalized = toKatakana(text).replaceAll("?", "?").replaceAll(",", PAUSE).replaceAll(/\s+/gu, "");
|
|
69
|
+
if (normalized.length === 0)
|
|
70
|
+
invalid(path, "Kana notation must not be empty.");
|
|
71
|
+
const phrases = [];
|
|
72
|
+
let start = 0;
|
|
73
|
+
const chars = Array.from(normalized);
|
|
74
|
+
for (let index = 0; index <= chars.length; index++) {
|
|
75
|
+
const char = chars[index];
|
|
76
|
+
if (index < chars.length && char !== PHRASE && char !== PAUSE)
|
|
77
|
+
continue;
|
|
78
|
+
const phrasePath = `${path}[${phrases.length}]`;
|
|
79
|
+
const raw = chars.slice(start, index).join("");
|
|
80
|
+
if (raw.length === 0 && index === chars.length && phrases.length > 0)
|
|
81
|
+
break;
|
|
82
|
+
if (raw.length === 0)
|
|
83
|
+
invalid(phrasePath, `Accent phrase ${phrases.length + 1} is empty.`);
|
|
84
|
+
start = index + 1;
|
|
85
|
+
const interrogative = raw.includes("?");
|
|
86
|
+
if (interrogative && raw.indexOf("?") !== raw.length - 1) {
|
|
87
|
+
invalid(phrasePath, `A question mark may only end an accent phrase: ${raw}.`);
|
|
88
|
+
}
|
|
89
|
+
const body = interrogative ? raw.slice(0, -1) : raw;
|
|
90
|
+
if (body.length === 0)
|
|
91
|
+
invalid(phrasePath, `Accent phrase ${phrases.length + 1} is empty.`);
|
|
92
|
+
const parsed = parsePhrase(body, phrasePath);
|
|
93
|
+
phrases.push({ ...parsed, pause: char === PAUSE, interrogative });
|
|
94
|
+
}
|
|
95
|
+
return phrases;
|
|
96
|
+
}
|
|
97
|
+
export function formatKanaNotation(phrases) {
|
|
98
|
+
let text = "";
|
|
99
|
+
for (const [index, phrase] of phrases.entries()) {
|
|
100
|
+
for (const [moraIndex, mora] of phrase.moras.entries()) {
|
|
101
|
+
if (mora.vowel === mora.vowel.toUpperCase() && mora.vowel !== "N" && mora.vowel.length === 1)
|
|
102
|
+
text += UNVOICE;
|
|
103
|
+
text += mora.text;
|
|
104
|
+
if (moraIndex + 1 === phrase.accent)
|
|
105
|
+
text += ACCENT;
|
|
106
|
+
}
|
|
107
|
+
if (phrase.interrogative)
|
|
108
|
+
text += "?";
|
|
109
|
+
if (index < phrases.length - 1)
|
|
110
|
+
text += phrase.pause ? PAUSE : PHRASE;
|
|
111
|
+
}
|
|
112
|
+
return text;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=notation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notation.js","sourceRoot":"","sources":["../src/notation.ts"],"names":[],"mappings":"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"}
|
package/dist/pitch.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const A4_HZ: number;
|
|
2
|
+
export declare function noteToMidi(value: number | string, path?: string): number;
|
|
3
|
+
export declare function midiToNoteName(midi: number): string;
|
|
4
|
+
export declare function midiToHz(midi: number): number;
|
|
5
|
+
//# sourceMappingURL=pitch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pitch.d.ts","sourceRoot":"","sources":["../src/pitch.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,EAAE,MAAY,CAAC;AAMjC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,GAAE,MAAgB,GAAG,MAAM,CA4BjF;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C"}
|
package/dist/pitch.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { invalid } from "./errors.js";
|
|
2
|
+
export const A4_HZ = 440;
|
|
3
|
+
const SEMITONES = { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 };
|
|
4
|
+
const NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
5
|
+
const NOTE_NAME = /^([A-Ga-g])(#|♯|b|♭|x)?(-?\d)$/u;
|
|
6
|
+
export function noteToMidi(value, path = "$.key") {
|
|
7
|
+
if (typeof value === "number") {
|
|
8
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > 127) {
|
|
9
|
+
invalid(path, "A MIDI key must be an integer in [0, 127].", "Use a note name such as C4 or an integer such as 60.");
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
const text = value.trim().normalize("NFKC");
|
|
14
|
+
if (/^-?\d+$/u.test(text))
|
|
15
|
+
return noteToMidi(Number(text), path);
|
|
16
|
+
const match = NOTE_NAME.exec(text);
|
|
17
|
+
if (match === null) {
|
|
18
|
+
invalid(path, `Unrecognized note ${JSON.stringify(value)}.`, "Use scientific pitch such as C4, F#4, Bb3 (octave -1 to 9) or a MIDI integer 0–127.");
|
|
19
|
+
}
|
|
20
|
+
const letter = (match[1] ?? "C").toUpperCase();
|
|
21
|
+
const accidental = match[2] ?? "";
|
|
22
|
+
const octave = Number(match[3]);
|
|
23
|
+
const shift = accidental === "#" || accidental === "♯" ? 1 : accidental === "x" ? 2 : accidental === "" ? 0 : -1;
|
|
24
|
+
const midi = (octave + 1) * 12 + (SEMITONES[letter] ?? 0) + shift;
|
|
25
|
+
if (midi < 0 || midi > 127)
|
|
26
|
+
invalid(path, `Note ${value} is outside the MIDI range 0–127.`);
|
|
27
|
+
return midi;
|
|
28
|
+
}
|
|
29
|
+
export function midiToNoteName(midi) {
|
|
30
|
+
const rounded = Math.round(midi);
|
|
31
|
+
return `${NAMES[((rounded % 12) + 12) % 12] ?? "C"}${Math.floor(rounded / 12) - 1}`;
|
|
32
|
+
}
|
|
33
|
+
export function midiToHz(midi) {
|
|
34
|
+
return A4_HZ * 2 ** ((midi - 69) / 12);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=pitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pitch.js","sourceRoot":"","sources":["../src/pitch.ts"],"names":[],"mappings":"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"}
|
package/dist/player.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface PlayerCommand {
|
|
2
|
+
readonly command: string;
|
|
3
|
+
readonly args: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function playerCandidates(path: string, os?: NodeJS.Platform): readonly PlayerCommand[];
|
|
6
|
+
export declare function playWav(path: string, signal?: AbortSignal): Promise<{
|
|
7
|
+
readonly player: string;
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=player.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAE,MAAM,CAAC,QAAmB,GAAG,SAAS,aAAa,EAAE,CAwBvG;AAkCD,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBtG"}
|
package/dist/player.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { platform } from "node:process";
|
|
3
|
+
import { KongyoroidError, aborted } from "./errors.js";
|
|
4
|
+
export function playerCandidates(path, os = platform) {
|
|
5
|
+
switch (os) {
|
|
6
|
+
case "darwin":
|
|
7
|
+
return [{ command: "afplay", args: [path] }];
|
|
8
|
+
case "win32":
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
command: "powershell",
|
|
12
|
+
args: [
|
|
13
|
+
"-NoProfile",
|
|
14
|
+
"-NonInteractive",
|
|
15
|
+
"-Command",
|
|
16
|
+
`(New-Object System.Media.SoundPlayer -ArgumentList @('${path.replaceAll("'", "''")}')).PlaySync()`,
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
default:
|
|
21
|
+
return [
|
|
22
|
+
{ command: "paplay", args: [path] },
|
|
23
|
+
{ command: "aplay", args: ["-q", path] },
|
|
24
|
+
{ command: "ffplay", args: ["-nodisp", "-autoexit", "-loglevel", "error", path] },
|
|
25
|
+
{ command: "play", args: ["-q", path] },
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function attempt(candidate, signal) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const child = spawn(candidate.command, candidate.args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
32
|
+
let stderr = "";
|
|
33
|
+
child.stderr?.on("data", (chunk) => {
|
|
34
|
+
stderr += chunk.toString("utf8").slice(0, 2000);
|
|
35
|
+
});
|
|
36
|
+
const onAbort = () => {
|
|
37
|
+
child.kill("SIGTERM");
|
|
38
|
+
};
|
|
39
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
40
|
+
child.once("error", (error) => {
|
|
41
|
+
signal?.removeEventListener("abort", onAbort);
|
|
42
|
+
if (error.code === "ENOENT")
|
|
43
|
+
resolve("missing");
|
|
44
|
+
else
|
|
45
|
+
reject(new KongyoroidError({ code: "PLAYER_UNAVAILABLE", message: error.message, retryable: false }, error));
|
|
46
|
+
});
|
|
47
|
+
child.once("exit", (code, signalName) => {
|
|
48
|
+
signal?.removeEventListener("abort", onAbort);
|
|
49
|
+
if (signal?.aborted)
|
|
50
|
+
reject(aborted("Playback cancelled."));
|
|
51
|
+
else if (code === 0)
|
|
52
|
+
resolve("ok");
|
|
53
|
+
else
|
|
54
|
+
reject(new KongyoroidError({
|
|
55
|
+
code: "PLAYER_UNAVAILABLE",
|
|
56
|
+
message: `${candidate.command} exited with ${code ?? signalName ?? "unknown"}: ${stderr.trim()}`,
|
|
57
|
+
retryable: false,
|
|
58
|
+
}));
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export async function playWav(path, signal) {
|
|
63
|
+
const candidates = playerCandidates(path);
|
|
64
|
+
const tryFrom = async (index) => {
|
|
65
|
+
const candidate = candidates[index];
|
|
66
|
+
if (candidate === undefined) {
|
|
67
|
+
throw new KongyoroidError({
|
|
68
|
+
code: "PLAYER_UNAVAILABLE",
|
|
69
|
+
message: `No audio player found (tried ${candidates.map((c) => c.command).join(", ")}).`,
|
|
70
|
+
retryable: false,
|
|
71
|
+
hint: "Install one of the listed players or open the WAV file with your own tool.",
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (signal?.aborted)
|
|
75
|
+
throw aborted("Playback cancelled.");
|
|
76
|
+
const result = await attempt(candidate, signal);
|
|
77
|
+
return result === "ok" ? { player: candidate.command } : tryFrom(index + 1);
|
|
78
|
+
};
|
|
79
|
+
return tryFrom(0);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player.js","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EngineSelector, ResolvedRequest, ResolvedSong, ResolvedSpeech, SongRequest, SpeechRequest, StyleRef } from "./types.ts";
|
|
2
|
+
import type { JsonObject } from "./validate.ts";
|
|
3
|
+
export declare function parseEngine(value: unknown, path?: string): EngineSelector;
|
|
4
|
+
export declare function parseStyleRef(value: unknown, path: string): StyleRef;
|
|
5
|
+
export declare function parseSpeechRequest(o: JsonObject): ResolvedSpeech;
|
|
6
|
+
export declare function parseSongRequest(o: JsonObject): ResolvedSong;
|
|
7
|
+
export declare function parseRequest(value: unknown): ResolvedRequest;
|
|
8
|
+
export declare function speechRequest(input: Omit<SpeechRequest, "kind">): SpeechRequest;
|
|
9
|
+
export declare function songRequest(input: Omit<SongRequest, "kind">): SongRequest;
|
|
10
|
+
export declare function parseJson(text: string, path?: string): unknown;
|
|
11
|
+
export declare function effectiveSampleRate(request: ResolvedRequest, engineDefault?: number): number;
|
|
12
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,YAAY,EACZ,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,EACT,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKhD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,MAAmB,GAAG,cAAc,CAErF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAQpE;AAyBD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,UAAU,GAAG,cAAc,CAuBhE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,GAAG,YAAY,CA0B5D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAI5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,aAAa,CAE/E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,WAAW,CAEzE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAY,GAAG,OAAO,CASnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,aAAa,GAAE,MAA4B,GAAG,MAAM,CAEjH"}
|