@moolam/bindings-speech 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 +202 -0
- package/README.md +41 -0
- package/bin/speech-cert.mjs +11 -0
- package/certification/README.md +18 -0
- package/certification/device-profiles/mid-range-android.json +12 -0
- package/certification/profile.json +33 -0
- package/certification/prove-speech-cert.mjs +11 -0
- package/certification/reports/prove.green1.speech.cert.json +92 -0
- package/certification/reports/prove.seeded-red.speech.cert.json +70 -0
- package/certification/reports/speech.cert.json +92 -0
- package/certification/run-speech-cert.mjs +11 -0
- package/certification/schemas/speech.cert.report.schema.json +149 -0
- package/certification/voice-rtt.baseline.json +12 -0
- package/dist/edge_stt_harness.d.ts +86 -0
- package/dist/edge_stt_harness.d.ts.map +1 -0
- package/dist/edge_stt_harness.js +311 -0
- package/dist/edge_stt_harness.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/speech_certification.d.ts +149 -0
- package/dist/speech_certification.d.ts.map +1 -0
- package/dist/speech_certification.js +490 -0
- package/dist/speech_certification.js.map +1 -0
- package/dist/stt_binding.d.ts +148 -0
- package/dist/stt_binding.d.ts.map +1 -0
- package/dist/stt_binding.js +400 -0
- package/dist/stt_binding.js.map +1 -0
- package/dist/tts_binding.d.ts +187 -0
- package/dist/tts_binding.d.ts.map +1 -0
- package/dist/tts_binding.js +565 -0
- package/dist/tts_binding.js.map +1 -0
- package/dist/voice_rtt_proof.d.ts +112 -0
- package/dist/voice_rtt_proof.d.ts.map +1 -0
- package/dist/voice_rtt_proof.js +241 -0
- package/dist/voice_rtt_proof.js.map +1 -0
- package/dist/whisper_ffi.d.ts +44 -0
- package/dist/whisper_ffi.d.ts.map +1 -0
- package/dist/whisper_ffi.js +104 -0
- package/dist/whisper_ffi.js.map +1 -0
- package/fixtures/indic/audio/en-classroom.pcm +0 -0
- package/fixtures/indic/audio/hi-classroom-noise.pcm +0 -0
- package/fixtures/indic/audio/hi-en-codeswitch.pcm +0 -0
- package/fixtures/indic/audio/hi-greeting.pcm +0 -0
- package/fixtures/indic/audio/short-hi.pcm +0 -0
- package/fixtures/indic/audio/ta-greeting.pcm +0 -0
- package/fixtures/indic/catalog.json +75 -0
- package/fixtures/indic/supported-languages.json +8 -0
- package/fixtures/tts/tts-voices.model-card.json +41 -0
- package/fixtures/tts/voices.json +24 -0
- package/package.json +55 -0
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local TTS behind SpeechInterface.synthesize.
|
|
3
|
+
*
|
|
4
|
+
* supportedLanguages lists only languages with loaded voice models.
|
|
5
|
+
* Unsupported BCP-47 codes route to the declared fallback language and
|
|
6
|
+
* surface `outcome: "fallback"` telemetry — never throw, never silent
|
|
7
|
+
* English substitution without that signal.
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
export const TTS_PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
14
|
+
export const DEFAULT_TTS_VOICES_MANIFEST = path.join(TTS_PACKAGE_ROOT, "fixtures", "tts", "voices.json");
|
|
15
|
+
/** Human+machine Indic TTS coverage card (language → voice + fallback policy). */
|
|
16
|
+
export const DEFAULT_TTS_MODEL_CARD = path.join(TTS_PACKAGE_ROOT, "fixtures", "tts", "tts-voices.model-card.json");
|
|
17
|
+
export const LOCAL_TTS_ENGINE = "local-tts-v1";
|
|
18
|
+
export const TTS_SAMPLE_RATE_HZ = 16_000;
|
|
19
|
+
export const TTS_STREAM_CHUNK_LIMIT = 64;
|
|
20
|
+
/** Max UTF-16 code units accepted per synthesize call (NFR / scalability). */
|
|
21
|
+
export const TTS_TEXT_CHAR_LIMIT = 4_096;
|
|
22
|
+
/** PCM samples per streamed audio chunk (~40ms @ 16kHz). */
|
|
23
|
+
export const TTS_SAMPLES_PER_CHUNK = 640;
|
|
24
|
+
export class LocalTtsError extends Error {
|
|
25
|
+
failureClass;
|
|
26
|
+
constructor(message, failureClass) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "LocalTtsError";
|
|
29
|
+
this.failureClass = failureClass;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const DEVANAGARI = /[\u0900-\u097F]/u;
|
|
33
|
+
const LATIN = /[A-Za-z]/u;
|
|
34
|
+
/**
|
|
35
|
+
* In-process local TTS stand-in: streams PCM chunks; mixed-script text
|
|
36
|
+
* does not crash. Production injects a real on-device TTS addon.
|
|
37
|
+
*/
|
|
38
|
+
export function createInProcessLocalTtsBackend() {
|
|
39
|
+
let seq = 0;
|
|
40
|
+
return {
|
|
41
|
+
kind: "in-process",
|
|
42
|
+
async load(modelId) {
|
|
43
|
+
if (!modelId.trim())
|
|
44
|
+
throw new Error("tts model id is required");
|
|
45
|
+
seq += 1;
|
|
46
|
+
return { id: `tts-inproc-${seq}` };
|
|
47
|
+
},
|
|
48
|
+
async unload() {
|
|
49
|
+
/* no-op */
|
|
50
|
+
},
|
|
51
|
+
async synthesize(_handle, params) {
|
|
52
|
+
if (params.signal?.aborted) {
|
|
53
|
+
throw new Error("tts synthesize aborted");
|
|
54
|
+
}
|
|
55
|
+
const rate = Math.min(2, Math.max(0.5, params.speakingRate));
|
|
56
|
+
// Duration scales with text length; mixed-script is fine.
|
|
57
|
+
const mixed = DEVANAGARI.test(params.text) && LATIN.test(params.text);
|
|
58
|
+
const baseMs = Math.max(80, Math.min(8_000, Math.ceil(params.text.length * 40 * (1 / rate))));
|
|
59
|
+
const durationMs = mixed ? baseMs + 40 : baseMs;
|
|
60
|
+
const sampleRate = params.sampleRateHz;
|
|
61
|
+
const totalSamples = Math.max(TTS_SAMPLES_PER_CHUNK, Math.floor((sampleRate * durationMs) / 1000));
|
|
62
|
+
// Prefix carries voice/language metadata for debug seams — not learner text.
|
|
63
|
+
const marker = new TextEncoder().encode(`tts.${params.language}.${params.voiceId}`);
|
|
64
|
+
const pcm = new Uint8Array(totalSamples * 2);
|
|
65
|
+
pcm.set(marker.slice(0, Math.min(marker.length, pcm.length)));
|
|
66
|
+
const freq = params.language.startsWith("hi")
|
|
67
|
+
? 196
|
|
68
|
+
: params.language.startsWith("ta")
|
|
69
|
+
? 220
|
|
70
|
+
: 247;
|
|
71
|
+
for (let i = Math.ceil(marker.length / 2); i < totalSamples; i++) {
|
|
72
|
+
const t = i / sampleRate;
|
|
73
|
+
const v = Math.floor(Math.sin(2 * Math.PI * freq * t) * 1200);
|
|
74
|
+
pcm[i * 2] = v & 0xff;
|
|
75
|
+
pcm[i * 2 + 1] = (v >> 8) & 0xff;
|
|
76
|
+
}
|
|
77
|
+
const chunks = [];
|
|
78
|
+
const bytesPerChunk = TTS_SAMPLES_PER_CHUNK * 2;
|
|
79
|
+
for (let offset = 0; offset < pcm.byteLength && chunks.length < TTS_STREAM_CHUNK_LIMIT; offset += bytesPerChunk) {
|
|
80
|
+
chunks.push(pcm.subarray(offset, Math.min(offset + bytesPerChunk, pcm.byteLength)));
|
|
81
|
+
}
|
|
82
|
+
if (chunks.length === 0) {
|
|
83
|
+
chunks.push(pcm);
|
|
84
|
+
}
|
|
85
|
+
return { chunks, sampleRateHz: sampleRate };
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function loadTtsVoicesManifest(manifestPath = DEFAULT_TTS_VOICES_MANIFEST) {
|
|
90
|
+
if (!existsSync(manifestPath)) {
|
|
91
|
+
throw new LocalTtsError(`TTS voices manifest missing at ${manifestPath}`, "config");
|
|
92
|
+
}
|
|
93
|
+
let raw;
|
|
94
|
+
try {
|
|
95
|
+
raw = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
throw new LocalTtsError(`TTS voices manifest unreadable: ${err instanceof Error ? err.message : String(err)}`, "config");
|
|
99
|
+
}
|
|
100
|
+
const m = raw;
|
|
101
|
+
if (typeof m.schemaVersion !== "string" ||
|
|
102
|
+
typeof m.fallbackLanguage !== "string" ||
|
|
103
|
+
!m.fallbackLanguage.trim() ||
|
|
104
|
+
!Array.isArray(m.voices) ||
|
|
105
|
+
m.voices.length === 0) {
|
|
106
|
+
throw new LocalTtsError("TTS voices manifest must declare schemaVersion, fallbackLanguage, non-empty voices[]", "config");
|
|
107
|
+
}
|
|
108
|
+
const voices = [];
|
|
109
|
+
for (const v of m.voices.slice(0, TTS_STREAM_CHUNK_LIMIT)) {
|
|
110
|
+
if (typeof v?.voiceId !== "string" ||
|
|
111
|
+
!v.voiceId.trim() ||
|
|
112
|
+
typeof v.language !== "string" ||
|
|
113
|
+
!v.language.trim() ||
|
|
114
|
+
!Number.isFinite(v.sampleRateHz) ||
|
|
115
|
+
v.sampleRateHz <= 0) {
|
|
116
|
+
throw new LocalTtsError("TTS voice card requires voiceId, language, positive sampleRateHz", "config");
|
|
117
|
+
}
|
|
118
|
+
voices.push({
|
|
119
|
+
voiceId: v.voiceId.trim(),
|
|
120
|
+
language: v.language.trim(),
|
|
121
|
+
sampleRateHz: v.sampleRateHz,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const langs = new Set(voices.map((v) => v.language));
|
|
125
|
+
if (!langs.has(m.fallbackLanguage.trim())) {
|
|
126
|
+
throw new LocalTtsError(`fallbackLanguage ${m.fallbackLanguage} has no loaded voice model`, "config");
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
schemaVersion: m.schemaVersion,
|
|
130
|
+
engine: typeof m.engine === "string" ? m.engine : LOCAL_TTS_ENGINE,
|
|
131
|
+
fallbackLanguage: m.fallbackLanguage.trim(),
|
|
132
|
+
voices,
|
|
133
|
+
...(typeof m.mixedScriptPolicy === "string"
|
|
134
|
+
? { mixedScriptPolicy: m.mixedScriptPolicy }
|
|
135
|
+
: {}),
|
|
136
|
+
...(typeof m.description === "string" ? { description: m.description } : {}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/** Languages actually backed by a loaded voice model (truthful declaration). */
|
|
140
|
+
export function languagesFromVoices(voices) {
|
|
141
|
+
const out = [];
|
|
142
|
+
const seen = new Set();
|
|
143
|
+
for (const v of voices) {
|
|
144
|
+
if (!seen.has(v.language)) {
|
|
145
|
+
seen.add(v.language);
|
|
146
|
+
out.push(v.language);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return out.slice(0, TTS_STREAM_CHUNK_LIMIT);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Load the TTS voice model card and require parity with the voices manifest
|
|
153
|
+
* (language set, voiceIds, fallbackLanguage). Coverage is never aspirational.
|
|
154
|
+
*/
|
|
155
|
+
export function loadTtsVoiceModelCard(cardPath = DEFAULT_TTS_MODEL_CARD, voicesManifestPath = DEFAULT_TTS_VOICES_MANIFEST) {
|
|
156
|
+
if (!existsSync(cardPath)) {
|
|
157
|
+
throw new LocalTtsError(`TTS voice model card missing at ${cardPath}`, "config");
|
|
158
|
+
}
|
|
159
|
+
let raw;
|
|
160
|
+
try {
|
|
161
|
+
raw = JSON.parse(readFileSync(cardPath, "utf8"));
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
throw new LocalTtsError(`TTS voice model card unreadable: ${err instanceof Error ? err.message : String(err)}`, "config");
|
|
165
|
+
}
|
|
166
|
+
const c = raw;
|
|
167
|
+
if (typeof c.schemaVersion !== "string" ||
|
|
168
|
+
typeof c.engine !== "string" ||
|
|
169
|
+
(c.locality !== "on-device" && c.locality !== "self-hosted") ||
|
|
170
|
+
typeof c.description !== "string" ||
|
|
171
|
+
typeof c.fallbackLanguage !== "string" ||
|
|
172
|
+
!c.fallbackLanguage.trim() ||
|
|
173
|
+
typeof c.fallbackPolicy?.unsupportedBcp47 !== "string" ||
|
|
174
|
+
typeof c.fallbackPolicy?.emptyText !== "string" ||
|
|
175
|
+
typeof c.fallbackPolicy?.mixedScript !== "string" ||
|
|
176
|
+
!Array.isArray(c.coverage) ||
|
|
177
|
+
c.coverage.length === 0 ||
|
|
178
|
+
typeof c.observability?.event !== "string" ||
|
|
179
|
+
typeof c.observability?.neverEmit !== "string" ||
|
|
180
|
+
!Array.isArray(c.observability?.requiredFields) ||
|
|
181
|
+
typeof c.voicesManifestRelpath !== "string") {
|
|
182
|
+
throw new LocalTtsError("TTS voice model card missing required coverage / fallback policy fields", "config");
|
|
183
|
+
}
|
|
184
|
+
const coverage = [];
|
|
185
|
+
for (const row of c.coverage.slice(0, TTS_STREAM_CHUNK_LIMIT)) {
|
|
186
|
+
if (typeof row?.language !== "string" ||
|
|
187
|
+
!row.language.trim() ||
|
|
188
|
+
typeof row.voiceId !== "string" ||
|
|
189
|
+
!row.voiceId.trim() ||
|
|
190
|
+
!Number.isFinite(row.sampleRateHz) ||
|
|
191
|
+
row.sampleRateHz <= 0 ||
|
|
192
|
+
typeof row.script !== "string" ||
|
|
193
|
+
!row.script.trim() ||
|
|
194
|
+
typeof row.role !== "string" ||
|
|
195
|
+
!row.role.trim()) {
|
|
196
|
+
throw new LocalTtsError("TTS model card coverage row requires language, voiceId, sampleRateHz, script, role", "config");
|
|
197
|
+
}
|
|
198
|
+
coverage.push({
|
|
199
|
+
language: row.language.trim(),
|
|
200
|
+
voiceId: row.voiceId.trim(),
|
|
201
|
+
sampleRateHz: row.sampleRateHz,
|
|
202
|
+
script: row.script.trim(),
|
|
203
|
+
role: row.role.trim(),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const card = {
|
|
207
|
+
schemaVersion: c.schemaVersion,
|
|
208
|
+
engine: c.engine,
|
|
209
|
+
locality: c.locality,
|
|
210
|
+
description: c.description,
|
|
211
|
+
fallbackLanguage: c.fallbackLanguage.trim(),
|
|
212
|
+
fallbackPolicy: {
|
|
213
|
+
unsupportedBcp47: c.fallbackPolicy.unsupportedBcp47,
|
|
214
|
+
emptyText: c.fallbackPolicy.emptyText,
|
|
215
|
+
mixedScript: c.fallbackPolicy.mixedScript,
|
|
216
|
+
},
|
|
217
|
+
coverage,
|
|
218
|
+
observability: {
|
|
219
|
+
event: c.observability.event,
|
|
220
|
+
neverEmit: c.observability.neverEmit,
|
|
221
|
+
requiredFields: c.observability.requiredFields.map(String),
|
|
222
|
+
},
|
|
223
|
+
voicesManifestRelpath: c.voicesManifestRelpath,
|
|
224
|
+
};
|
|
225
|
+
const manifest = loadTtsVoicesManifest(voicesManifestPath);
|
|
226
|
+
assertTtsModelCardMatchesVoices(card, manifest);
|
|
227
|
+
return card;
|
|
228
|
+
}
|
|
229
|
+
/** Language → voiceId rows for README / hosts (order matches model card). */
|
|
230
|
+
export function languageVoiceCoverageTable(card = loadTtsVoiceModelCard()) {
|
|
231
|
+
return card.coverage.map((row) => ({
|
|
232
|
+
language: row.language,
|
|
233
|
+
voiceId: row.voiceId,
|
|
234
|
+
role: row.role,
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
export function assertTtsModelCardMatchesVoices(card, manifest) {
|
|
238
|
+
if (card.engine !== manifest.engine) {
|
|
239
|
+
throw new LocalTtsError(`model card engine ${card.engine} ≠ voices manifest ${manifest.engine}`, "config");
|
|
240
|
+
}
|
|
241
|
+
if (card.fallbackLanguage !== manifest.fallbackLanguage) {
|
|
242
|
+
throw new LocalTtsError(`model card fallbackLanguage ${card.fallbackLanguage} ≠ voices ${manifest.fallbackLanguage}`, "config");
|
|
243
|
+
}
|
|
244
|
+
const cardLangs = card.coverage.map((r) => r.language).sort().join(",");
|
|
245
|
+
const voiceLangs = languagesFromVoices(manifest.voices).slice().sort().join(",");
|
|
246
|
+
if (cardLangs !== voiceLangs) {
|
|
247
|
+
throw new LocalTtsError(`model card languages [${cardLangs}] ≠ voices [${voiceLangs}]`, "config");
|
|
248
|
+
}
|
|
249
|
+
for (const row of card.coverage) {
|
|
250
|
+
const voice = manifest.voices.find((v) => v.language === row.language);
|
|
251
|
+
if (!voice || voice.voiceId !== row.voiceId) {
|
|
252
|
+
throw new LocalTtsError(`model card ${row.language}→${row.voiceId} missing or mismatched in voices manifest`, "config");
|
|
253
|
+
}
|
|
254
|
+
if (voice.sampleRateHz !== row.sampleRateHz) {
|
|
255
|
+
throw new LocalTtsError(`model card sampleRateHz for ${row.language} mismatches voices manifest`, "config");
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (!card.coverage.some((r) => r.language === card.fallbackLanguage)) {
|
|
259
|
+
throw new LocalTtsError("model card fallbackLanguage must appear in coverage", "config");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
export function resolveTtsVoice(args) {
|
|
263
|
+
const requested = args.requestedLanguage.trim();
|
|
264
|
+
const byId = args.voiceId?.trim()
|
|
265
|
+
? args.voices.find((v) => v.voiceId === args.voiceId.trim())
|
|
266
|
+
: undefined;
|
|
267
|
+
if (byId && byId.language === requested) {
|
|
268
|
+
return {
|
|
269
|
+
voice: byId,
|
|
270
|
+
effectiveLanguage: byId.language,
|
|
271
|
+
usedFallback: false,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const match = args.voices.find((v) => v.language === requested);
|
|
275
|
+
if (match) {
|
|
276
|
+
return {
|
|
277
|
+
voice: match,
|
|
278
|
+
effectiveLanguage: match.language,
|
|
279
|
+
usedFallback: false,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
const fallback = args.voices.find((v) => v.language === args.fallbackLanguage) ??
|
|
283
|
+
args.voices[0];
|
|
284
|
+
if (!fallback) {
|
|
285
|
+
throw new LocalTtsError("no TTS voices loaded", "config");
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
voice: fallback,
|
|
289
|
+
effectiveLanguage: fallback.language,
|
|
290
|
+
usedFallback: true,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
export class LocalTtsBinding {
|
|
294
|
+
#subjectId;
|
|
295
|
+
#deviceId;
|
|
296
|
+
#voices;
|
|
297
|
+
#languages;
|
|
298
|
+
#fallbackLanguage;
|
|
299
|
+
#backend;
|
|
300
|
+
#handle;
|
|
301
|
+
#onTelemetry;
|
|
302
|
+
#mixedScriptPolicy;
|
|
303
|
+
#unloaded = false;
|
|
304
|
+
constructor(args) {
|
|
305
|
+
this.#subjectId = args.subjectId;
|
|
306
|
+
this.#deviceId = args.deviceId;
|
|
307
|
+
this.#voices = [...args.voices];
|
|
308
|
+
this.#languages = languagesFromVoices(this.#voices);
|
|
309
|
+
this.#fallbackLanguage = args.fallbackLanguage;
|
|
310
|
+
this.#backend = args.backend;
|
|
311
|
+
this.#handle = args.handle;
|
|
312
|
+
if (args.onTelemetry)
|
|
313
|
+
this.#onTelemetry = args.onTelemetry;
|
|
314
|
+
if (args.mixedScriptPolicy)
|
|
315
|
+
this.#mixedScriptPolicy = args.mixedScriptPolicy;
|
|
316
|
+
}
|
|
317
|
+
get supportedLanguages() {
|
|
318
|
+
return [...this.#languages];
|
|
319
|
+
}
|
|
320
|
+
get fallbackLanguage() {
|
|
321
|
+
return this.#fallbackLanguage;
|
|
322
|
+
}
|
|
323
|
+
get voices() {
|
|
324
|
+
return this.#voices.map((v) => ({ ...v }));
|
|
325
|
+
}
|
|
326
|
+
get subjectId() {
|
|
327
|
+
return this.#subjectId;
|
|
328
|
+
}
|
|
329
|
+
get deviceId() {
|
|
330
|
+
return this.#deviceId;
|
|
331
|
+
}
|
|
332
|
+
get engine() {
|
|
333
|
+
return LOCAL_TTS_ENGINE;
|
|
334
|
+
}
|
|
335
|
+
get mixedScriptPolicy() {
|
|
336
|
+
return this.#mixedScriptPolicy;
|
|
337
|
+
}
|
|
338
|
+
#emit(partial) {
|
|
339
|
+
this.#onTelemetry?.({
|
|
340
|
+
event: "bindings_speech.tts",
|
|
341
|
+
subjectId: this.#subjectId,
|
|
342
|
+
deviceId: this.#deviceId,
|
|
343
|
+
engine: LOCAL_TTS_ENGINE,
|
|
344
|
+
...partial,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
#assertLoaded() {
|
|
348
|
+
if (this.#unloaded) {
|
|
349
|
+
throw new LocalTtsError("local TTS binding unloaded", "not_loaded");
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
async unload() {
|
|
353
|
+
if (this.#unloaded)
|
|
354
|
+
return;
|
|
355
|
+
this.#unloaded = true;
|
|
356
|
+
await this.#backend.unload(this.#handle);
|
|
357
|
+
this.#emit({ op: "unload", outcome: "ok" });
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* STT stub so SpeechInterface is complete for CK-05.1 when using TTS-first
|
|
361
|
+
* hosts. Full STT is {@link WhisperCppSpeechBinding}.
|
|
362
|
+
*/
|
|
363
|
+
async *transcribe(audio) {
|
|
364
|
+
this.#assertLoaded();
|
|
365
|
+
let chunks = 0;
|
|
366
|
+
for await (const _ of audio) {
|
|
367
|
+
chunks += 1;
|
|
368
|
+
if (chunks >= TTS_STREAM_CHUNK_LIMIT)
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
const lang = this.#fallbackLanguage;
|
|
372
|
+
yield {
|
|
373
|
+
text: "…",
|
|
374
|
+
language: lang,
|
|
375
|
+
startMs: 0,
|
|
376
|
+
endMs: 1,
|
|
377
|
+
confidence: 0.5,
|
|
378
|
+
isFinal: false,
|
|
379
|
+
};
|
|
380
|
+
yield {
|
|
381
|
+
text: "…",
|
|
382
|
+
language: lang,
|
|
383
|
+
startMs: 0,
|
|
384
|
+
endMs: Math.max(1, chunks),
|
|
385
|
+
confidence: 0.7,
|
|
386
|
+
isFinal: true,
|
|
387
|
+
};
|
|
388
|
+
this.#emit({
|
|
389
|
+
op: "transcribe",
|
|
390
|
+
outcome: "ok",
|
|
391
|
+
chunkCount: 2,
|
|
392
|
+
languageCount: this.#languages.length,
|
|
393
|
+
detail: "tts_binding_stt_stub",
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
async *synthesize(text, options) {
|
|
397
|
+
this.#assertLoaded();
|
|
398
|
+
if (typeof text !== "string" || text.trim().length === 0) {
|
|
399
|
+
this.#emit({
|
|
400
|
+
op: "synthesize",
|
|
401
|
+
outcome: "error",
|
|
402
|
+
failureClass: "validation",
|
|
403
|
+
detail: "empty_text",
|
|
404
|
+
});
|
|
405
|
+
throw new LocalTtsError("synthesize requires non-empty text", "validation");
|
|
406
|
+
}
|
|
407
|
+
if (text.length > TTS_TEXT_CHAR_LIMIT) {
|
|
408
|
+
this.#emit({
|
|
409
|
+
op: "synthesize",
|
|
410
|
+
outcome: "error",
|
|
411
|
+
failureClass: "validation",
|
|
412
|
+
detail: "text_too_long",
|
|
413
|
+
});
|
|
414
|
+
throw new LocalTtsError(`synthesize text exceeds ${TTS_TEXT_CHAR_LIMIT} characters`, "validation");
|
|
415
|
+
}
|
|
416
|
+
const requested = options.language?.trim() ?? "";
|
|
417
|
+
if (!requested) {
|
|
418
|
+
this.#emit({
|
|
419
|
+
op: "synthesize",
|
|
420
|
+
outcome: "error",
|
|
421
|
+
failureClass: "validation",
|
|
422
|
+
detail: "language_required",
|
|
423
|
+
});
|
|
424
|
+
throw new LocalTtsError("synthesize options.language is required (BCP-47)", "validation");
|
|
425
|
+
}
|
|
426
|
+
try {
|
|
427
|
+
const resolved = resolveTtsVoice({
|
|
428
|
+
voices: this.#voices,
|
|
429
|
+
fallbackLanguage: this.#fallbackLanguage,
|
|
430
|
+
requestedLanguage: requested,
|
|
431
|
+
...(options.voiceId ? { voiceId: options.voiceId } : {}),
|
|
432
|
+
});
|
|
433
|
+
const speakingRate = typeof options.speakingRate === "number" &&
|
|
434
|
+
Number.isFinite(options.speakingRate)
|
|
435
|
+
? options.speakingRate
|
|
436
|
+
: 1;
|
|
437
|
+
const native = await this.#backend.synthesize(this.#handle, {
|
|
438
|
+
text,
|
|
439
|
+
language: resolved.effectiveLanguage,
|
|
440
|
+
voiceId: resolved.voice.voiceId,
|
|
441
|
+
sampleRateHz: resolved.voice.sampleRateHz,
|
|
442
|
+
speakingRate,
|
|
443
|
+
});
|
|
444
|
+
let chunkCount = 0;
|
|
445
|
+
for (const data of native.chunks) {
|
|
446
|
+
if (data.byteLength === 0)
|
|
447
|
+
continue;
|
|
448
|
+
chunkCount += 1;
|
|
449
|
+
yield {
|
|
450
|
+
data,
|
|
451
|
+
sampleRateHz: native.sampleRateHz,
|
|
452
|
+
};
|
|
453
|
+
if (chunkCount >= TTS_STREAM_CHUNK_LIMIT)
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
if (chunkCount === 0) {
|
|
457
|
+
throw new LocalTtsError("TTS backend yielded no audio", "native");
|
|
458
|
+
}
|
|
459
|
+
this.#emit({
|
|
460
|
+
op: "synthesize",
|
|
461
|
+
outcome: resolved.usedFallback ? "fallback" : "ok",
|
|
462
|
+
languageCount: this.#languages.length,
|
|
463
|
+
chunkCount,
|
|
464
|
+
effectiveLanguage: resolved.effectiveLanguage,
|
|
465
|
+
requestedLanguage: requested,
|
|
466
|
+
voiceId: resolved.voice.voiceId,
|
|
467
|
+
usedFallback: resolved.usedFallback,
|
|
468
|
+
...(resolved.usedFallback
|
|
469
|
+
? { detail: "unsupported_language_fallback" }
|
|
470
|
+
: {}),
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
catch (err) {
|
|
474
|
+
if (err instanceof LocalTtsError)
|
|
475
|
+
throw err;
|
|
476
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
477
|
+
this.#emit({
|
|
478
|
+
op: "synthesize",
|
|
479
|
+
outcome: "error",
|
|
480
|
+
failureClass: "native",
|
|
481
|
+
detail: detail.slice(0, 160),
|
|
482
|
+
});
|
|
483
|
+
throw err;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Load local TTS: voices manifest → truthful supportedLanguages → FFI seam.
|
|
489
|
+
*/
|
|
490
|
+
export async function loadLocalTts(options) {
|
|
491
|
+
const subjectId = options.subjectId?.trim();
|
|
492
|
+
const deviceId = options.deviceId?.trim();
|
|
493
|
+
if (!subjectId) {
|
|
494
|
+
throw new LocalTtsError("subjectId is required", "config");
|
|
495
|
+
}
|
|
496
|
+
if (!deviceId) {
|
|
497
|
+
throw new LocalTtsError("deviceId is required", "config");
|
|
498
|
+
}
|
|
499
|
+
const manifest = loadTtsVoicesManifest(options.voicesManifestPath ?? DEFAULT_TTS_VOICES_MANIFEST);
|
|
500
|
+
// Coverage card must match loaded voices (no aspirational languages).
|
|
501
|
+
if (!options.voicesManifestPath) {
|
|
502
|
+
loadTtsVoiceModelCard(DEFAULT_TTS_MODEL_CARD, DEFAULT_TTS_VOICES_MANIFEST);
|
|
503
|
+
}
|
|
504
|
+
const backend = options.backend ?? createInProcessLocalTtsBackend();
|
|
505
|
+
const emit = options.onTelemetry;
|
|
506
|
+
try {
|
|
507
|
+
const handle = await backend.load(`${manifest.engine}:voices`);
|
|
508
|
+
const binding = new LocalTtsBinding({
|
|
509
|
+
subjectId,
|
|
510
|
+
deviceId,
|
|
511
|
+
voices: manifest.voices,
|
|
512
|
+
fallbackLanguage: manifest.fallbackLanguage,
|
|
513
|
+
backend,
|
|
514
|
+
handle,
|
|
515
|
+
...(options.onTelemetry ? { onTelemetry: options.onTelemetry } : {}),
|
|
516
|
+
...(manifest.mixedScriptPolicy
|
|
517
|
+
? { mixedScriptPolicy: manifest.mixedScriptPolicy }
|
|
518
|
+
: {}),
|
|
519
|
+
});
|
|
520
|
+
emit?.({
|
|
521
|
+
event: "bindings_speech.tts",
|
|
522
|
+
op: "load",
|
|
523
|
+
outcome: "ok",
|
|
524
|
+
subjectId,
|
|
525
|
+
deviceId,
|
|
526
|
+
engine: LOCAL_TTS_ENGINE,
|
|
527
|
+
languageCount: binding.supportedLanguages.length,
|
|
528
|
+
});
|
|
529
|
+
return binding;
|
|
530
|
+
}
|
|
531
|
+
catch (err) {
|
|
532
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
533
|
+
emit?.({
|
|
534
|
+
event: "bindings_speech.tts",
|
|
535
|
+
op: "load",
|
|
536
|
+
outcome: "error",
|
|
537
|
+
subjectId,
|
|
538
|
+
deviceId,
|
|
539
|
+
engine: LOCAL_TTS_ENGINE,
|
|
540
|
+
failureClass: err instanceof LocalTtsError ? err.failureClass : "native",
|
|
541
|
+
detail: detail.slice(0, 160),
|
|
542
|
+
});
|
|
543
|
+
throw err;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
/** Conformance factory for CK-05 against the local TTS binding. */
|
|
547
|
+
export function createLocalTtsSpeechHarnessFactory(options = {}) {
|
|
548
|
+
return async (ctx) => {
|
|
549
|
+
const speech = await loadLocalTts({
|
|
550
|
+
subjectId: ctx?.subjectId?.trim() ||
|
|
551
|
+
options.subjectId?.trim() ||
|
|
552
|
+
"cert.speech.tts",
|
|
553
|
+
deviceId: ctx?.deviceId?.trim() ||
|
|
554
|
+
options.deviceId?.trim() ||
|
|
555
|
+
"ci-speech-tts",
|
|
556
|
+
...(options.voicesManifestPath
|
|
557
|
+
? { voicesManifestPath: options.voicesManifestPath }
|
|
558
|
+
: {}),
|
|
559
|
+
...(options.backend ? { backend: options.backend } : {}),
|
|
560
|
+
...(options.onTelemetry ? { onTelemetry: options.onTelemetry } : {}),
|
|
561
|
+
});
|
|
562
|
+
return { speech };
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
//# sourceMappingURL=tts_binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tts_binding.js","sourceRoot":"","sources":["../src/tts_binding.ts"],"names":[],"mappings":"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"}
|