@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.
Files changed (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/cache.d.ts +36 -0
  4. package/dist/cache.d.ts.map +1 -0
  5. package/dist/cache.js +109 -0
  6. package/dist/cache.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +502 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/concurrency.d.ts +14 -0
  12. package/dist/concurrency.d.ts.map +1 -0
  13. package/dist/concurrency.js +107 -0
  14. package/dist/concurrency.js.map +1 -0
  15. package/dist/errors.d.ts +35 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +81 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/formant.d.ts +34 -0
  20. package/dist/formant.d.ts.map +1 -0
  21. package/dist/formant.js +622 -0
  22. package/dist/formant.js.map +1 -0
  23. package/dist/index.d.ts +40 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +23 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/io.d.ts +6 -0
  28. package/dist/io.d.ts.map +1 -0
  29. package/dist/io.js +144 -0
  30. package/dist/io.js.map +1 -0
  31. package/dist/kongyoroid.d.ts +82 -0
  32. package/dist/kongyoroid.d.ts.map +1 -0
  33. package/dist/kongyoroid.js +275 -0
  34. package/dist/kongyoroid.js.map +1 -0
  35. package/dist/limits.d.ts +18 -0
  36. package/dist/limits.d.ts.map +1 -0
  37. package/dist/limits.js +15 -0
  38. package/dist/limits.js.map +1 -0
  39. package/dist/mora.d.ts +28 -0
  40. package/dist/mora.d.ts.map +1 -0
  41. package/dist/mora.js +295 -0
  42. package/dist/mora.js.map +1 -0
  43. package/dist/notation.d.ts +15 -0
  44. package/dist/notation.d.ts.map +1 -0
  45. package/dist/notation.js +114 -0
  46. package/dist/notation.js.map +1 -0
  47. package/dist/pitch.d.ts +5 -0
  48. package/dist/pitch.d.ts.map +1 -0
  49. package/dist/pitch.js +36 -0
  50. package/dist/pitch.js.map +1 -0
  51. package/dist/player.d.ts +9 -0
  52. package/dist/player.d.ts.map +1 -0
  53. package/dist/player.js +81 -0
  54. package/dist/player.js.map +1 -0
  55. package/dist/request.d.ts +12 -0
  56. package/dist/request.d.ts.map +1 -0
  57. package/dist/request.js +115 -0
  58. package/dist/request.js.map +1 -0
  59. package/dist/schema.d.ts +9 -0
  60. package/dist/schema.d.ts.map +1 -0
  61. package/dist/schema.js +267 -0
  62. package/dist/schema.js.map +1 -0
  63. package/dist/score.d.ts +37 -0
  64. package/dist/score.d.ts.map +1 -0
  65. package/dist/score.js +166 -0
  66. package/dist/score.js.map +1 -0
  67. package/dist/text.d.ts +3 -0
  68. package/dist/text.d.ts.map +1 -0
  69. package/dist/text.js +54 -0
  70. package/dist/text.js.map +1 -0
  71. package/dist/types.d.ts +121 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +2 -0
  74. package/dist/types.js.map +1 -0
  75. package/dist/validate.d.ts +13 -0
  76. package/dist/validate.d.ts.map +1 -0
  77. package/dist/validate.js +59 -0
  78. package/dist/validate.js.map +1 -0
  79. package/dist/version.d.ts +3 -0
  80. package/dist/version.d.ts.map +1 -0
  81. package/dist/version.js +3 -0
  82. package/dist/version.js.map +1 -0
  83. package/dist/voicevox/api.d.ts +79 -0
  84. package/dist/voicevox/api.d.ts.map +1 -0
  85. package/dist/voicevox/api.js +176 -0
  86. package/dist/voicevox/api.js.map +1 -0
  87. package/dist/voicevox/client.d.ts +64 -0
  88. package/dist/voicevox/client.d.ts.map +1 -0
  89. package/dist/voicevox/client.js +321 -0
  90. package/dist/voicevox/client.js.map +1 -0
  91. package/dist/voicevox/dictionary.d.ts +21 -0
  92. package/dist/voicevox/dictionary.d.ts.map +1 -0
  93. package/dist/voicevox/dictionary.js +41 -0
  94. package/dist/voicevox/dictionary.js.map +1 -0
  95. package/dist/voicevox/song.d.ts +12 -0
  96. package/dist/voicevox/song.d.ts.map +1 -0
  97. package/dist/voicevox/song.js +45 -0
  98. package/dist/voicevox/song.js.map +1 -0
  99. package/dist/voicevox/speech.d.ts +17 -0
  100. package/dist/voicevox/speech.d.ts.map +1 -0
  101. package/dist/voicevox/speech.js +100 -0
  102. package/dist/voicevox/speech.js.map +1 -0
  103. package/dist/voicevox/styles.d.ts +15 -0
  104. package/dist/voicevox/styles.d.ts.map +1 -0
  105. package/dist/voicevox/styles.js +103 -0
  106. package/dist/voicevox/styles.js.map +1 -0
  107. package/dist/wav.d.ts +18 -0
  108. package/dist/wav.d.ts.map +1 -0
  109. package/dist/wav.js +198 -0
  110. package/dist/wav.js.map +1 -0
  111. package/examples/batch.jsonl +4 -0
  112. package/examples/song-notes.json +24 -0
  113. package/examples/song.json +12 -0
  114. package/examples/speech-kana.json +6 -0
  115. package/examples/speech.json +8 -0
  116. package/package.json +86 -0
@@ -0,0 +1,100 @@
1
+ import { mapConcurrent } from "../concurrency.js";
2
+ import { invalid } from "../errors.js";
3
+ import { LIMITS } from "../limits.js";
4
+ import { splitText } from "../text.js";
5
+ import { concatWav, inspectWav } from "../wav.js";
6
+ import { protocolError } from "./api.js";
7
+ export function querySeconds(query) {
8
+ let seconds = query.prePhonemeLength + query.postPhonemeLength;
9
+ for (const phrase of query.accent_phrases) {
10
+ const moras = phrase.pause_mora === null ? phrase.moras : [...phrase.moras, phrase.pause_mora];
11
+ for (const mora of moras) {
12
+ const pause = mora.vowel === "pau";
13
+ const base = pause && query.pauseLength !== null ? query.pauseLength : mora.vowel_length;
14
+ const vowel = pause ? base * query.pauseLengthScale : base;
15
+ seconds += (vowel + (mora.consonant_length ?? 0)) / query.speedScale;
16
+ }
17
+ }
18
+ return seconds;
19
+ }
20
+ export function applySpeechSettings(phrases, request, sampleRate, kana) {
21
+ return {
22
+ accent_phrases: phrases,
23
+ speedScale: request.speed,
24
+ pitchScale: request.pitch,
25
+ intonationScale: request.intonation,
26
+ volumeScale: request.volume,
27
+ prePhonemeLength: request.prePause,
28
+ postPhonemeLength: request.postPause,
29
+ pauseLength: request.pauseLength ?? null,
30
+ pauseLengthScale: request.pauseScale,
31
+ outputSamplingRate: sampleRate,
32
+ outputStereo: false,
33
+ kana,
34
+ };
35
+ }
36
+ export async function synthesizeSpeech(client, request, speaker, options = {}) {
37
+ const manifest = await client.manifest(options);
38
+ const sampleRate = request.sampleRate ?? manifest.defaultSamplingRate;
39
+ const chunks = request.kana === undefined ? splitText(request.text, request.split) : [request.text];
40
+ let budget = LIMITS.audioSeconds;
41
+ const parts = await mapConcurrent(chunks, options.concurrency ?? 2, async (chunk) => {
42
+ const query = request.kana === undefined
43
+ ? applySpeechSettings((await client.audioQuery(chunk, speaker.id, options)).accent_phrases, request, sampleRate, "")
44
+ : applySpeechSettings(await client.accentPhrases(request.kana, speaker.id, true, options), request, sampleRate, request.kana);
45
+ const kana = request.kana ?? chunkKana(query);
46
+ const seconds = querySeconds(query);
47
+ budget -= seconds;
48
+ if (budget < 0) {
49
+ invalid("$.text", `The text would produce more than ${LIMITS.audioSeconds} s of audio.`, "Split the text into separate requests.");
50
+ }
51
+ const audio = await client.synthesis(query, speaker.id, request.upspeak, options);
52
+ const info = inspectWav(audio);
53
+ if (info.channels !== 1 || info.sampleRate !== sampleRate) {
54
+ throw protocolError(`synthesis returned ${info.channels} channel(s) at ${info.sampleRate} Hz, expected mono ${sampleRate} Hz`);
55
+ }
56
+ return { audio, kana };
57
+ }, options.signal);
58
+ return {
59
+ audio: parts.length === 1 ? (parts[0]?.audio ?? new Uint8Array(0)) : concatWav(parts.map((part) => part.audio)),
60
+ kana: parts.map((part) => part.kana).join("/"),
61
+ chunks: parts.length,
62
+ sampleRate,
63
+ };
64
+ }
65
+ function chunkKana(query) {
66
+ if (query.kana.length > 0)
67
+ return query.kana;
68
+ let text = "";
69
+ for (const [phraseIndex, phrase] of query.accent_phrases.entries()) {
70
+ for (const [index, mora] of phrase.moras.entries()) {
71
+ if (/^[AIUEO]$/u.test(mora.vowel))
72
+ text += "_";
73
+ text += mora.text;
74
+ if (index + 1 === phrase.accent)
75
+ text += "'";
76
+ }
77
+ if (phrase.is_interrogative)
78
+ text += "?";
79
+ if (phraseIndex < query.accent_phrases.length - 1)
80
+ text += phrase.pause_mora === null ? "/" : "、";
81
+ }
82
+ return text;
83
+ }
84
+ export function accentPhrasesToKana(phrases) {
85
+ return chunkKana({
86
+ accent_phrases: phrases,
87
+ speedScale: 1,
88
+ pitchScale: 0,
89
+ intonationScale: 1,
90
+ volumeScale: 1,
91
+ prePhonemeLength: 0,
92
+ postPhonemeLength: 0,
93
+ pauseLength: null,
94
+ pauseLengthScale: 1,
95
+ outputSamplingRate: 24000,
96
+ outputStereo: false,
97
+ kana: "",
98
+ });
99
+ }
100
+ //# sourceMappingURL=speech.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speech.js","sourceRoot":"","sources":["../../src/voicevox/speech.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { OperationOptions, StyleRef, StyleSelection, VoiceStyle } from "../types.ts";
2
+ import type { VoicevoxClient } from "./client.ts";
3
+ export type StylePurpose = "speaker" | "singer" | "teacher";
4
+ export declare function toSelection(style: VoiceStyle): StyleSelection;
5
+ export declare function describeStyle(style: VoiceStyle): string;
6
+ export declare class StyleCatalog {
7
+ private readonly client;
8
+ private cache;
9
+ constructor(client: VoicevoxClient);
10
+ refresh(): void;
11
+ all(options?: OperationOptions): Promise<readonly VoiceStyle[]>;
12
+ byPurpose(purpose: StylePurpose, options?: OperationOptions): Promise<readonly VoiceStyle[]>;
13
+ resolve(ref: StyleRef | undefined, purpose: StylePurpose, options?: OperationOptions): Promise<StyleSelection>;
14
+ }
15
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/voicevox/styles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAa,UAAU,EAAE,MAAM,aAAa,CAAC;AACrG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAkB5D,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc,CAE7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEvD;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,KAAK,CAA6C;gBAEvC,MAAM,EAAE,cAAc;IAIlC,OAAO,IAAI,IAAI;IAIf,GAAG,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAmB7D,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAKhG,OAAO,CAClB,GAAG,EAAE,QAAQ,GAAG,SAAS,EACzB,OAAO,EAAE,YAAY,EACrB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,cAAc,CAAC;CA8D3B"}
@@ -0,0 +1,103 @@
1
+ import { invalid } from "../errors.js";
2
+ const ACCEPTED = {
3
+ speaker: ["talk", "streaming_talk"],
4
+ singer: ["frame_decode", "sing"],
5
+ teacher: ["singing_teacher", "sing"],
6
+ };
7
+ const PURPOSE_HINT = {
8
+ speaker: "Speech needs a style of type talk. Run the voices command to list them.",
9
+ singer: "Singing needs a style of type frame_decode or sing. Run voices --kind song to list them.",
10
+ teacher: "A teacher needs a style of type singing_teacher or sing. Run voices --kind song to list them.",
11
+ };
12
+ function normalize(text) {
13
+ return text.normalize("NFKC").trim().toLowerCase();
14
+ }
15
+ export function toSelection(style) {
16
+ return { id: style.id, name: style.name, character: style.character, type: style.type };
17
+ }
18
+ export function describeStyle(style) {
19
+ return `${style.id}: ${style.character}/${style.name} (${style.type})`;
20
+ }
21
+ export class StyleCatalog {
22
+ client;
23
+ cache;
24
+ constructor(client) {
25
+ this.client = client;
26
+ }
27
+ refresh() {
28
+ this.cache = undefined;
29
+ }
30
+ all(options = {}) {
31
+ this.cache ??= Promise.all([this.client.speakers(options), this.client.singers(options)])
32
+ .then(([speakers, singers]) => {
33
+ const seen = new Set();
34
+ const merged = [];
35
+ for (const style of [...speakers, ...singers]) {
36
+ if (seen.has(style.id))
37
+ continue;
38
+ seen.add(style.id);
39
+ merged.push(style);
40
+ }
41
+ return merged;
42
+ })
43
+ .catch((error) => {
44
+ this.cache = undefined;
45
+ throw error;
46
+ });
47
+ return this.cache;
48
+ }
49
+ async byPurpose(purpose, options = {}) {
50
+ const accepted = ACCEPTED[purpose];
51
+ return (await this.all(options)).filter((style) => accepted.includes(style.type));
52
+ }
53
+ async resolve(ref, purpose, options = {}) {
54
+ const path = `$.${purpose}`;
55
+ const all = await this.all(options);
56
+ const accepted = ACCEPTED[purpose];
57
+ const candidates = all.filter((style) => accepted.includes(style.type));
58
+ if (ref === undefined) {
59
+ const first = candidates[0];
60
+ if (first === undefined) {
61
+ invalid(path, `The engine offers no style usable as ${purpose}.`, PURPOSE_HINT[purpose]);
62
+ }
63
+ return toSelection(first);
64
+ }
65
+ if (typeof ref === "number") {
66
+ const exact = all.find((style) => style.id === ref);
67
+ if (exact === undefined) {
68
+ invalid(path, `No style has id ${ref}.`, PURPOSE_HINT[purpose]);
69
+ }
70
+ if (!accepted.includes(exact.type)) {
71
+ invalid(path, `Style ${describeStyle(exact)} cannot be used as ${purpose}.`, `${PURPOSE_HINT[purpose]} Usable: ${candidates.slice(0, 8).map(describeStyle).join(", ")}.`);
72
+ }
73
+ return toSelection(exact);
74
+ }
75
+ const query = normalize(ref);
76
+ const [characterPart, stylePart] = query.split(/[//]/u, 2);
77
+ const character = characterPart ?? query;
78
+ const byCharacter = candidates.filter((style) => normalize(style.character) === character);
79
+ if (byCharacter.length > 0) {
80
+ const firstOfCharacter = byCharacter[0];
81
+ if (firstOfCharacter !== undefined && (stylePart === undefined || stylePart.length === 0)) {
82
+ return toSelection(firstOfCharacter);
83
+ }
84
+ const exact = byCharacter.find((style) => normalize(style.name) === stylePart);
85
+ if (exact !== undefined)
86
+ return toSelection(exact);
87
+ invalid(path, `${ref}: character found but no ${purpose} style named ${JSON.stringify(stylePart)}.`, `Styles for this character: ${byCharacter.map((s) => `${s.name} (${s.id})`).join(", ")}.`);
88
+ }
89
+ const byStyleName = candidates.find((style) => normalize(style.name) === query);
90
+ if (byStyleName !== undefined)
91
+ return toSelection(byStyleName);
92
+ const partial = candidates.filter((style) => normalize(style.character).includes(character) || normalize(`${style.character}/${style.name}`).includes(query));
93
+ const characters = new Set(partial.map((style) => style.character));
94
+ const firstPartial = partial[0];
95
+ if (firstPartial !== undefined && characters.size === 1 && (stylePart === undefined || stylePart.length === 0)) {
96
+ return toSelection(firstPartial);
97
+ }
98
+ return invalid(path, `No ${purpose} style matches ${JSON.stringify(ref)}.`, partial.length > 0
99
+ ? `Did you mean: ${partial.slice(0, 8).map(describeStyle).join(", ")}?`
100
+ : `${PURPOSE_HINT[purpose]} Available: ${candidates.slice(0, 8).map(describeStyle).join(", ")}.`);
101
+ }
102
+ }
103
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/voicevox/styles.ts"],"names":[],"mappings":"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"}
package/dist/wav.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { AudioInfo } from "./types.ts";
2
+ export interface WavLayout extends AudioInfo {
3
+ readonly dataOffset: number;
4
+ readonly dataLength: number;
5
+ }
6
+ export declare function wavHeader(frames: number, sampleRate: number, channels?: number): Uint8Array;
7
+ export declare function encodePcm16(pcm: Float32Array, target?: Uint8Array, offset?: number): Uint8Array;
8
+ export declare function encodeWav(pcm: Float32Array, sampleRate: number): Uint8Array;
9
+ export declare function inspectWav(bytes: Uint8Array): WavLayout;
10
+ export declare function audioInfo(layout: WavLayout): AudioInfo;
11
+ export declare function decodeWav(bytes: Uint8Array): {
12
+ readonly info: AudioInfo;
13
+ readonly samples: Float32Array;
14
+ };
15
+ export declare function silenceWav(seconds: number, sampleRate: number): Uint8Array;
16
+ export declare function concatWav(parts: readonly Uint8Array[], gapSeconds?: number): Uint8Array;
17
+ export declare function pcm16Samples(bytes: Uint8Array): Int16Array;
18
+ //# sourceMappingURL=wav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wav.d.ts","sourceRoot":"","sources":["../src/wav.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,GAAG,UAAU,CAwB9F;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,GAAE,MAAU,GAAG,UAAU,CAUlG;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAK3E;AAUD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAoDvD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAStD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAczG;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAE1E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,UAAU,GAAE,MAAU,GAAG,UAAU,CA0B1F;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAe1D"}
package/dist/wav.js ADDED
@@ -0,0 +1,198 @@
1
+ import { KongyoroidError, invalid } from "./errors.js";
2
+ const RIFF = 0x52494646;
3
+ const WAVE = 0x57415645;
4
+ const FMT = 0x666d7420;
5
+ const DATA = 0x64617461;
6
+ export function wavHeader(frames, sampleRate, channels = 1) {
7
+ if (!Number.isSafeInteger(frames) || frames < 0 || frames * channels * 2 > 0xfffffff0) {
8
+ invalid("$.frames", "Frame count is not representable in a WAV file.");
9
+ }
10
+ if (!Number.isSafeInteger(sampleRate) || sampleRate < 1 || sampleRate > 384_000) {
11
+ invalid("$.sampleRate", "Sample rate is not representable in a WAV file.");
12
+ }
13
+ const dataBytes = frames * channels * 2;
14
+ const header = new Uint8Array(44);
15
+ const view = new DataView(header.buffer);
16
+ view.setUint32(0, RIFF);
17
+ view.setUint32(4, 36 + dataBytes, true);
18
+ view.setUint32(8, WAVE);
19
+ view.setUint32(12, FMT);
20
+ view.setUint32(16, 16, true);
21
+ view.setUint16(20, 1, true);
22
+ view.setUint16(22, channels, true);
23
+ view.setUint32(24, sampleRate, true);
24
+ view.setUint32(28, sampleRate * channels * 2, true);
25
+ view.setUint16(32, channels * 2, true);
26
+ view.setUint16(34, 16, true);
27
+ view.setUint32(36, DATA);
28
+ view.setUint32(40, dataBytes, true);
29
+ return header;
30
+ }
31
+ export function encodePcm16(pcm, target, offset = 0) {
32
+ const bytes = target ?? new Uint8Array(pcm.length * 2);
33
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
34
+ for (let index = 0; index < pcm.length; index++) {
35
+ const value = pcm[index] ?? 0;
36
+ if (!Number.isFinite(value))
37
+ invalid(`$.pcm[${index}]`, "PCM contains a non-finite sample.");
38
+ const clipped = value < -1 ? -1 : value > 1 ? 1 : value;
39
+ view.setInt16(offset + index * 2, Math.round(clipped * (clipped < 0 ? 32768 : 32767)), true);
40
+ }
41
+ return bytes;
42
+ }
43
+ export function encodeWav(pcm, sampleRate) {
44
+ const bytes = new Uint8Array(44 + pcm.length * 2);
45
+ bytes.set(wavHeader(pcm.length, sampleRate));
46
+ encodePcm16(pcm, bytes, 44);
47
+ return bytes;
48
+ }
49
+ function malformed(reason) {
50
+ throw new KongyoroidError({
51
+ code: "ENGINE_PROTOCOL",
52
+ message: `Invalid or unsupported WAV data: ${reason}.`,
53
+ retryable: false,
54
+ });
55
+ }
56
+ export function inspectWav(bytes) {
57
+ if (bytes.byteLength < 44)
58
+ malformed("shorter than a RIFF header");
59
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
60
+ if (view.getUint32(0) !== RIFF || view.getUint32(8) !== WAVE)
61
+ malformed("missing RIFF/WAVE signature");
62
+ const declared = view.getUint32(4, true) + 8;
63
+ if (declared > bytes.byteLength)
64
+ malformed(`RIFF declares ${declared} bytes but only ${bytes.byteLength} were received`);
65
+ const end = declared;
66
+ let format = 0;
67
+ let channels = 0;
68
+ let rate = 0;
69
+ let bits = 0;
70
+ let align = 0;
71
+ let dataOffset = -1;
72
+ let dataLength = -1;
73
+ let position = 12;
74
+ while (position + 8 <= end) {
75
+ const tag = view.getUint32(position);
76
+ const length = view.getUint32(position + 4, true);
77
+ const start = position + 8;
78
+ if (tag === FMT) {
79
+ if (format !== 0 || length < 16 || start + 16 > end)
80
+ malformed("bad fmt chunk");
81
+ format = view.getUint16(start, true);
82
+ channels = view.getUint16(start + 2, true);
83
+ rate = view.getUint32(start + 4, true);
84
+ align = view.getUint16(start + 12, true);
85
+ bits = view.getUint16(start + 14, true);
86
+ if (format === 0xfffe && length >= 26)
87
+ format = view.getUint16(start + 24, true);
88
+ }
89
+ else if (tag === DATA) {
90
+ if (dataOffset >= 0)
91
+ malformed("duplicate data chunk");
92
+ if (start + length > end)
93
+ malformed(`data chunk declares ${length} bytes past the end of the file`);
94
+ dataOffset = start;
95
+ dataLength = length;
96
+ }
97
+ position = start + length + (length % 2);
98
+ }
99
+ if (dataOffset < 0 || format === 0)
100
+ malformed("missing fmt or data chunk");
101
+ if (channels < 1 || channels > 2 || rate < 1000 || rate > 384_000)
102
+ malformed("unsupported channel count or rate");
103
+ if (!((format === 1 && bits === 16) || (format === 3 && bits === 32)))
104
+ malformed("only PCM16 or float32 supported");
105
+ if (align !== (channels * bits) / 8)
106
+ malformed("inconsistent block alignment");
107
+ const usable = dataLength - (dataLength % align);
108
+ const frames = usable / align;
109
+ return {
110
+ sampleRate: rate,
111
+ channels,
112
+ frames,
113
+ bitsPerSample: bits,
114
+ format: format === 1 ? "pcm" : "float",
115
+ durationSeconds: frames / rate,
116
+ dataOffset,
117
+ dataLength: usable,
118
+ };
119
+ }
120
+ export function audioInfo(layout) {
121
+ return {
122
+ sampleRate: layout.sampleRate,
123
+ channels: layout.channels,
124
+ frames: layout.frames,
125
+ bitsPerSample: layout.bitsPerSample,
126
+ format: layout.format,
127
+ durationSeconds: layout.durationSeconds,
128
+ };
129
+ }
130
+ export function decodeWav(bytes) {
131
+ const layout = inspectWav(bytes);
132
+ const view = new DataView(bytes.buffer, bytes.byteOffset + layout.dataOffset, layout.dataLength);
133
+ const samples = new Float32Array(layout.frames);
134
+ const channels = layout.channels;
135
+ for (let frame = 0; frame < layout.frames; frame++) {
136
+ let sum = 0;
137
+ for (let channel = 0; channel < channels; channel++) {
138
+ const index = frame * channels + channel;
139
+ sum += layout.format === "pcm" ? view.getInt16(index * 2, true) / 32768 : view.getFloat32(index * 4, true);
140
+ }
141
+ samples[frame] = sum / channels;
142
+ }
143
+ return { info: audioInfo(layout), samples };
144
+ }
145
+ export function silenceWav(seconds, sampleRate) {
146
+ return encodeWav(new Float32Array(Math.round(seconds * sampleRate)), sampleRate);
147
+ }
148
+ export function concatWav(parts, gapSeconds = 0) {
149
+ if (parts.length === 0)
150
+ invalid("$.parts", "Nothing to concatenate.");
151
+ const layouts = parts.map((part) => inspectWav(part));
152
+ const rate = layouts[0]?.sampleRate ?? 0;
153
+ for (const layout of layouts) {
154
+ if (layout.sampleRate !== rate)
155
+ malformed("sample rates differ between parts");
156
+ }
157
+ const gapFrames = Math.round(gapSeconds * rate);
158
+ let frames = 0;
159
+ for (const layout of layouts)
160
+ frames += layout.frames;
161
+ frames += gapFrames * (parts.length - 1);
162
+ const out = new Uint8Array(44 + frames * 2);
163
+ out.set(wavHeader(frames, rate));
164
+ let offset = 44;
165
+ for (const [index, part] of parts.entries()) {
166
+ const layout = layouts[index];
167
+ if (layout === undefined)
168
+ continue;
169
+ if (layout.format === "pcm" && layout.channels === 1) {
170
+ out.set(part.subarray(layout.dataOffset, layout.dataOffset + layout.dataLength), offset);
171
+ }
172
+ else {
173
+ encodePcm16(decodeWav(part).samples, out, offset);
174
+ }
175
+ offset += layout.frames * 2;
176
+ if (index < parts.length - 1)
177
+ offset += gapFrames * 2;
178
+ }
179
+ return out;
180
+ }
181
+ export function pcm16Samples(bytes) {
182
+ const layout = inspectWav(bytes);
183
+ if (layout.format !== "pcm" || layout.channels !== 1) {
184
+ const decoded = decodeWav(bytes).samples;
185
+ const out = new Int16Array(decoded.length);
186
+ for (let index = 0; index < decoded.length; index++) {
187
+ const value = Math.max(-1, Math.min(1, decoded[index] ?? 0));
188
+ out[index] = Math.round(value * (value < 0 ? 32768 : 32767));
189
+ }
190
+ return out;
191
+ }
192
+ const view = new DataView(bytes.buffer, bytes.byteOffset + layout.dataOffset, layout.dataLength);
193
+ const out = new Int16Array(layout.frames);
194
+ for (let index = 0; index < layout.frames; index++)
195
+ out[index] = view.getInt16(index * 2, true);
196
+ return out;
197
+ }
198
+ //# sourceMappingURL=wav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wav.js","sourceRoot":"","sources":["../src/wav.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ {"id":"greeting","request":{"kind":"speech","text":"おはようございます。","speaker":"ずんだもん"}}
2
+ {"id":"question","request":{"kind":"speech","text":"準備はできましたか?","speaker":"四国めたん","speed":0.9}}
3
+ {"id":"scale","request":{"kind":"song","notes":{"lyrics":"ドレミファソラシド","melody":"C4 D4 E4 F4 G4 A4 B4 C5","beats":"1 1 1 1 1 1 1 2"}}}
4
+ {"id":"builtin","request":{"kind":"speech","engine":"formant","text":"ないぞうえんじんで、よみあげます。","kana":"ナイゾーエ'ンジンデ、ヨミアゲマ'ス"}}
@@ -0,0 +1,24 @@
1
+ {
2
+ "kind": "song",
3
+ "engine": "formant",
4
+ "tempo": 90,
5
+ "transpose": -2,
6
+ "vibratoDepth": 35,
7
+ "notes": [
8
+ { "key": null, "beats": 0.5, "lyric": "" },
9
+ { "key": "E4", "beats": 1, "lyric": "さ" },
10
+ { "key": "E4", "beats": 1, "lyric": "く" },
11
+ { "key": "F4", "beats": 2, "lyric": "ら" },
12
+ { "key": "E4", "beats": 1, "lyric": "さ" },
13
+ { "key": "E4", "beats": 1, "lyric": "く" },
14
+ { "key": "F4", "beats": 2, "lyric": "ら" },
15
+ { "key": "E4", "beats": 1, "lyric": "や" },
16
+ { "key": "F4", "beats": 1, "lyric": "よ" },
17
+ { "key": "G4", "beats": 1, "lyric": "い" },
18
+ { "key": "G4", "beats": 1, "lyric": "の" },
19
+ { "key": "F4", "beats": 1, "lyric": "そ" },
20
+ { "key": "E4", "beats": 1, "lyric": "ら" },
21
+ { "key": "D4", "beats": 2, "lyric": "わ" },
22
+ { "key": "D4", "beats": 2, "lyric": "ー" }
23
+ ]
24
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "kind": "song",
3
+ "tempo": 100,
4
+ "notes": {
5
+ "lyrics": "きらきらひかるおそらのほしよ",
6
+ "melody": "C4 C4 G4 G4 A4 A4 G4 R F4 F4 E4 E4 D4 D4 C4 ~",
7
+ "beats": "1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"
8
+ },
9
+ "singer": "ずんだもん",
10
+ "leadIn": 0.3,
11
+ "leadOut": 0.5
12
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "kind": "speech",
3
+ "text": "橋の端で箸を使う",
4
+ "kana": "ハシノ'/ハシデ'/ハ'シオ/ツカ'ウ",
5
+ "speaker": 3
6
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "kind": "speech",
3
+ "text": "こんにちは。今日はいい天気ですね?\n明日も晴れるといいな。",
4
+ "speaker": "ずんだもん/ノーマル",
5
+ "speed": 1.1,
6
+ "intonation": 1.2,
7
+ "split": "sentence"
8
+ }
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@kongyo2/kongyoroid",
3
+ "version": "1.0.0",
4
+ "description": "Japanese speech and singing synthesis for LLM agents: a JSON-first CLI and typed library with a built-in deterministic formant engine and an optional VOICEVOX ENGINE adapter.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "kongyo2",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/kongyo2/kongyoroid.git"
11
+ },
12
+ "homepage": "https://github.com/kongyo2/kongyoroid#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/kongyo2/kongyoroid/issues"
15
+ },
16
+ "engines": {
17
+ "node": ">=22.4"
18
+ },
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
29
+ "bin": {
30
+ "kongyoroid": "./dist/cli.js"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "examples",
35
+ "AGENTS.md",
36
+ "LICENSE",
37
+ "README.md"
38
+ ],
39
+ "sideEffects": false,
40
+ "publishConfig": {
41
+ "access": "public",
42
+ "provenance": true
43
+ },
44
+ "keywords": [
45
+ "tts",
46
+ "text-to-speech",
47
+ "singing",
48
+ "singing-synthesis",
49
+ "voicevox",
50
+ "japanese",
51
+ "speech",
52
+ "agent",
53
+ "llm",
54
+ "cli",
55
+ "formant",
56
+ "kongyo2"
57
+ ],
58
+ "scripts": {
59
+ "clean": "node --input-type=module -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"",
60
+ "build": "npm run clean && tsc --pretty false",
61
+ "typecheck": "tsc --noEmit --pretty false",
62
+ "typecheck:test": "tsc -p tsconfig.test.json --pretty false",
63
+ "lint": "oxlint --deny-warnings --format agent",
64
+ "lint:fix": "oxlint --fix --deny-warnings --format agent",
65
+ "lint:typed": "oxlint --type-aware --type-check --deny-warnings --format agent",
66
+ "format": "prettier --write .",
67
+ "format:check": "prettier --check .",
68
+ "comments:check": "ts-comment-scanner --fail-on-comment src test scripts",
69
+ "test": "node --test --disable-warning=ExperimentalWarning \"test/**/*.test.ts\"",
70
+ "check": "npm run typecheck && npm run typecheck:test && npm run lint && npm run format:check && npm run comments:check && npm test",
71
+ "check:package": "attw --pack . --profile esm-only && publint --strict",
72
+ "verify:package": "node --disable-warning=ExperimentalWarning scripts/verify-package.ts",
73
+ "prepack": "npm run build"
74
+ },
75
+ "devDependencies": {
76
+ "@arethetypeswrong/cli": "0.18.5",
77
+ "@kongyo2/ts-comment-scanner": "1.6.0",
78
+ "@types/node": "22.20.1",
79
+ "ajv": "8.20.0",
80
+ "oxlint": "1.81.0",
81
+ "oxlint-tsgolint": "7.0.2001",
82
+ "prettier": "3.9.6",
83
+ "publint": "0.3.24",
84
+ "typescript": "6.0.3"
85
+ }
86
+ }