@qvac/tts-ggml 0.13.0 → 0.14.1

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 (69) hide show
  1. package/README.md +84 -11
  2. package/docs/pocket-tts.md +12 -10
  3. package/examples/audio8-streaming.js +74 -0
  4. package/index.d.ts +43 -1130
  5. package/index.js +129 -3041
  6. package/lib/addonEvents.d.ts +26 -0
  7. package/lib/addonEvents.js +51 -0
  8. package/lib/conditioning.d.ts +50 -0
  9. package/lib/conditioning.js +184 -0
  10. package/lib/engineDetection.d.ts +14 -0
  11. package/lib/engineDetection.js +110 -0
  12. package/lib/engineIds.d.ts +15 -0
  13. package/lib/engineIds.js +39 -0
  14. package/lib/engineParams.d.ts +3 -0
  15. package/lib/engineParams.js +34 -0
  16. package/lib/engineSetup.d.ts +153 -0
  17. package/lib/engineSetup.js +2 -0
  18. package/lib/engines/audio8.d.ts +83 -0
  19. package/lib/engines/audio8.js +262 -0
  20. package/lib/engines/chatterbox.d.ts +10 -0
  21. package/lib/engines/chatterbox.js +112 -0
  22. package/lib/engines/cosyvoice.d.ts +87 -0
  23. package/lib/engines/cosyvoice.js +267 -0
  24. package/lib/engines/moss.d.ts +26 -0
  25. package/lib/engines/moss.js +177 -0
  26. package/lib/engines/mossSoundEffect.d.ts +41 -0
  27. package/lib/engines/mossSoundEffect.js +117 -0
  28. package/lib/engines/mossSpeech.d.ts +86 -0
  29. package/lib/engines/mossSpeech.js +228 -0
  30. package/lib/engines/parler.d.ts +71 -0
  31. package/lib/engines/parler.js +287 -0
  32. package/lib/engines/supertonic.d.ts +11 -0
  33. package/lib/engines/supertonic.js +115 -0
  34. package/lib/exclusiveQueue.d.ts +16 -0
  35. package/lib/exclusiveQueue.js +45 -0
  36. package/lib/jobFields.d.ts +20 -0
  37. package/lib/jobFields.js +73 -0
  38. package/lib/modelFiles.d.ts +207 -0
  39. package/lib/modelFiles.js +117 -0
  40. package/lib/nativeParams.d.ts +12 -0
  41. package/lib/nativeParams.js +73 -0
  42. package/lib/optionValidation.d.ts +2 -0
  43. package/lib/optionValidation.js +103 -0
  44. package/lib/options.d.ts +4 -0
  45. package/lib/options.js +17 -0
  46. package/lib/pocketLifecycle.d.ts +67 -0
  47. package/lib/pocketLifecycle.js +170 -0
  48. package/lib/reload.d.ts +12 -0
  49. package/lib/reload.js +76 -0
  50. package/lib/sentenceStream.d.ts +85 -0
  51. package/lib/sentenceStream.js +367 -0
  52. package/lib/setup.d.ts +7 -0
  53. package/lib/setup.js +169 -0
  54. package/lib/streamingSupport.d.ts +8 -0
  55. package/lib/streamingSupport.js +77 -0
  56. package/lib/types.d.ts +465 -0
  57. package/lib/types.js +2 -0
  58. package/lib/voiceControls.d.ts +12 -0
  59. package/lib/voiceControls.js +23 -0
  60. package/package.json +11 -10
  61. package/test/integration/audio8-streaming.test.js +66 -0
  62. package/test/integration/audio8.test.js +6 -12
  63. package/test/integration/gpu-smoke.test.js +2 -11
  64. package/test/integration/lavasr-enhancer.test.js +2 -15
  65. package/test/integration/moss-sfx.test.js +29 -4
  66. package/test/integration/moss.test.js +1 -1
  67. package/test/utils/desktopGpuBackend.js +21 -0
  68. package/test/utils/runTTS.js +1 -1
  69. package/tts.d.ts +1 -0
package/index.d.ts CHANGED
@@ -1,823 +1,9 @@
1
1
  import { type QvacResponse } from "@qvac/infer-base";
2
2
  import * as errorModule from "./lib/error";
3
- import { assessFit as assessFitImpl, type Audio8FitRequest, type MossFitRequest, type MossSoundEffectFitRequest, type ChatterboxFitRequest, type CosyvoiceFitRequest, type ParlerFitRequest, type SupertonicFitRequest, type TtsFitEngine, type TtsFitRequest, type TtsFitResult, type TtsFitStatus } from "./lib/fit";
4
- import { type SentenceDelimiterPreset } from "./lib/textStreamAccumulator";
5
- declare const ENGINE_CHATTERBOX = "chatterbox";
6
- declare const ENGINE_SUPERTONIC = "supertonic";
7
- declare const ENGINE_COSYVOICE3 = "cosyvoice3";
8
- declare const ENGINE_PARLER = "parler";
9
- declare const ENGINE_AUDIO8 = "audio8";
10
- declare const ENGINE_MOSS = "moss";
11
- declare const ENGINE_MOSS_SFX = "moss-sfx";
12
- declare const ENGINE_MOSS_SPEECH = "moss-speech";
13
- declare const ENGINE_POCKET = "pocket";
14
- declare const COSYVOICE_DIALECTS: {
15
- readonly cantonese: "广东话";
16
- readonly northeastern: "东北话";
17
- readonly gansu: "甘肃话";
18
- readonly guizhou: "贵州话";
19
- readonly henan: "河南话";
20
- readonly hubei: "湖北话";
21
- readonly hunan: "湖南话";
22
- readonly jiangxi: "江西话";
23
- readonly minnan: "闽南话";
24
- readonly ningxia: "宁夏话";
25
- readonly shanxi: "山西话";
26
- readonly shaanxi: "陕西话";
27
- readonly shandong: "山东话";
28
- readonly shanghai: "上海话";
29
- readonly sichuan: "四川话";
30
- readonly tianjin: "天津话";
31
- readonly yunnan: "云南话";
32
- };
33
- declare const COSYVOICE_VOLUMES: {
34
- readonly loud: "Please say a sentence as loudly as possible.";
35
- readonly soft: "Please say a sentence in a very soft voice.";
36
- };
37
- declare const COSYVOICE_STYLES: {
38
- readonly peppa: "我想体验一下小猪佩奇风格,可以吗?";
39
- readonly robot: "你可以尝试用机器人的方式解答吗?";
40
- };
41
- /**
42
- * CosyVoice3 controls that have no canonical cross-engine vocabulary yet.
43
- * Emotion and speaking rate are NOT here -- use the top-level `emotion` /
44
- * `pace` options, which work the same way on every engine that supports them.
45
- * Exactly one field takes effect per synthesis, resolved by precedence
46
- * dialect > volume > style. Pass a raw string instead for an arbitrary
47
- * instruction (advanced escape hatch).
48
- */
49
- interface CosyvoiceInstruct {
50
- /** Chinese dialect; renders "请用{dialect}表达。". */
51
- dialect?: keyof typeof COSYVOICE_DIALECTS;
52
- /** Loudness. */
53
- volume?: keyof typeof COSYVOICE_VOLUMES;
54
- /** Playful style preset. */
55
- style?: keyof typeof COSYVOICE_STYLES;
56
- }
57
- declare const EMOTIONS: readonly ["command", "anger", "narration", "conversation", "disgust", "fear", "happy", "neutral", "proper noun", "news", "sad", "surprise"];
58
- declare const PACES: readonly ["slow", "moderate", "fast"];
59
- type Emotion = (typeof EMOTIONS)[number];
60
- type Pace = (typeof PACES)[number];
61
- declare const MOSS_SPEECH_ROLES: readonly ["system", "user", "assistant"];
62
- type EngineType = typeof ENGINE_CHATTERBOX | typeof ENGINE_SUPERTONIC | typeof ENGINE_COSYVOICE3 | typeof ENGINE_PARLER | typeof ENGINE_AUDIO8 | typeof ENGINE_MOSS | typeof ENGINE_MOSS_SFX | typeof ENGINE_MOSS_SPEECH | typeof ENGINE_POCKET;
63
- /**
64
- * Model file paths for the GGML TTS backend. Engine is auto-detected
65
- * from these fields (Chatterbox vs Supertonic) unless overridden via
66
- * `TTSGgmlOptions.engine`. All paths must be absolute and are passed
67
- * through to the native layer as-is.
68
- */
69
- interface TTSGgmlFiles {
70
- pocketFlowModel?: string;
71
- pocketMimiModel?: string;
72
- pocketFrontend?: string;
73
- pocketVoice?: string;
74
- /**
75
- * Bundle root. For Chatterbox, expected to contain
76
- * `chatterbox-t3-turbo.gguf` + `chatterbox-s3gen.gguf` (turbo) or
77
- * `chatterbox-t3-mtl.gguf` + `chatterbox-s3gen-mtl.gguf` (multilingual).
78
- * For Supertonic, expected to contain `supertonic.gguf`.
79
- */
80
- modelDir?: string;
81
- /** Chatterbox T3 (text to speech tokens) GGUF path. Overrides `modelDir`. */
82
- t3Model?: string;
83
- t3ModelPath?: string;
84
- t3?: string;
85
- /** Chatterbox S3Gen + HiFT (speech tokens to 24 kHz wav) GGUF path. Overrides `modelDir`. */
86
- s3genModel?: string;
87
- s3genModelPath?: string;
88
- s3gen?: string;
89
- /** Supertonic single-file GGUF path. Overrides `modelDir`. */
90
- supertonicModel?: string;
91
- supertonicModelPath?: string;
92
- supertonic?: string;
93
- /** Parler single-file GGUF path (mini/large/indic). Overrides `modelDir`. */
94
- parlerModel?: string;
95
- parlerModelPath?: string;
96
- parler?: string;
97
- /** Audio8 DualAR language model GGUF path. Overrides `modelDir`. */
98
- audio8Lm?: string;
99
- audio8LmPath?: string;
100
- /** Audio8 codec synthesis half (codes to 44.1 kHz wav). Overrides `modelDir`. */
101
- audio8CodecDecoder?: string;
102
- audio8CodecDecoderPath?: string;
103
- /**
104
- * Audio8 codec analysis half (wav to codes). Only needed to clone a voice
105
- * from a recording; a text-only deployment can leave it out.
106
- */
107
- audio8CodecEncoder?: string;
108
- audio8CodecEncoderPath?: string;
109
- /**
110
- * MOSS Delay backbone GGUF path: MOSS-TTS (`moss-tts-delay-*.gguf`) or the
111
- * MOSS-TTSD dialogue checkpoint (`moss-ttsd-*.gguf`). Overrides `modelDir`.
112
- */
113
- mossBackbone?: string;
114
- mossBackbonePath?: string;
115
- /** MOSS codec synthesis half (codes to 24 kHz wav). Overrides `modelDir`. */
116
- mossCodecDecoder?: string;
117
- mossCodecDecoderPath?: string;
118
- /**
119
- * MOSS codec analysis half (wav to codes). Only needed to clone a voice
120
- * from `referenceAudio` or for `dialogueReferences`; a text-only deployment
121
- * can leave it out.
122
- */
123
- mossCodecEncoder?: string;
124
- mossCodecEncoderPath?: string;
125
- /**
126
- * MOSS-SoundEffect GGUF (`moss-sfx-*.gguf`): text encoder, DiT and VAE in
127
- * one file. Routes to the `moss-sfx` engine. Overrides `modelDir`.
128
- */
129
- mossSoundEffect?: string;
130
- mossSoundEffectPath?: string;
131
- /**
132
- * MOSS-Speech language model GGUF (`moss-speech-*.gguf`, e.g.
133
- * `moss-speech-q8_0.gguf`). Routes to the `moss-speech` engine together
134
- * with `mossSpeechCodec`. Overrides `modelDir`.
135
- */
136
- mossSpeechModel?: string;
137
- mossSpeechModelPath?: string;
138
- /**
139
- * MOSS-Speech codec GGUF (`moss-speech-codec-*.gguf`): speech tokenizer,
140
- * reply decoder and the default reply voice. Overrides `modelDir`.
141
- */
142
- mossSpeechCodec?: string;
143
- mossSpeechCodecPath?: string;
144
- /**
145
- * CosyVoice3 model directory holding the sub-model GGUFs
146
- * (`cosyvoice3-{llm,flow,hift}-*.gguf`) plus `voice.gguf`, `vocab.json` and
147
- * `merges.txt`. Routes to the CosyVoice3 engine. Falls back to the shared
148
- * `modelDir` when unset.
149
- */
150
- cosyvoiceModelDir?: string;
151
- /** CosyVoice3 per-component GGUF paths (override discovery under the model dir). */
152
- cosyvoiceLlmModel?: string;
153
- cosyvoiceLlmModelPath?: string;
154
- cosyvoiceFlowModel?: string;
155
- cosyvoiceFlowModelPath?: string;
156
- cosyvoiceHiftModel?: string;
157
- cosyvoiceHiftModelPath?: string;
158
- /**
159
- * CosyVoice3 voice-cloning add-on GGUFs, required only when
160
- * `referenceAudio` is set: the speech_tokenizer_v3 speech tokenizer
161
- * (`cosyvoice3-s3tok-*.gguf`) and the CAM++ speaker encoder
162
- * (`cosyvoice3-campplus-*.gguf`). Auto-discovered under
163
- * `cosyvoiceModelDir` by those name prefixes when unset.
164
- */
165
- cosyvoiceS3tokModel?: string;
166
- cosyvoiceS3tokModelPath?: string;
167
- cosyvoiceCampplusModel?: string;
168
- cosyvoiceCampplusModelPath?: string;
169
- /**
170
- * CosyVoice3 Qwen2 BPE text frontend (`vocab.json` + `merges.txt`) and the
171
- * baked default-voice GGUF (`voice.gguf`). Each is resolved under the model
172
- * dir when unset; `cosyvoiceVoiceModel` is how a different baked voice is
173
- * selected without a separate model directory.
174
- */
175
- cosyvoiceVocab?: string;
176
- cosyvoiceVocabPath?: string;
177
- cosyvoiceMerges?: string;
178
- cosyvoiceMergesPath?: string;
179
- cosyvoiceVoiceModel?: string;
180
- cosyvoiceVoiceModelPath?: string;
181
- /**
182
- * LavaSR enhancer GGUF: single-file Vocos bandwidth extension produced by
183
- * tts-cpp/scripts/convert-lavasr-enhancer-to-gguf.py. When supplied, output
184
- * is neurally upsampled to 48 kHz (the canonical way to enable enhancement;
185
- * `enhancer.enhancerPath` is the only alternative).
186
- */
187
- lavasrEnhancer?: string;
188
- /**
189
- * LavaSR denoiser GGUF: UL-UNAS speech denoiser produced by
190
- * tts-cpp/scripts/convert-lavasr-denoiser-to-gguf.py. Runs before the
191
- * enhancer and is rate-preserving (the canonical way to enable denoising;
192
- * `denoiser.denoiserPath` is the only alternative).
193
- *
194
- * The tts-cpp UL-UNAS forward is implemented in qvac-fabric-speech.cpp
195
- * PR #78 (scalar CPU port, validated bit-close to the ONNX reference).
196
- */
197
- lavasrDenoiser?: string;
198
- /** Optional directory containing baked Chatterbox voice profiles. */
199
- voicesDir?: string;
200
- /**
201
- * Chatterbox MTL only: directory holding the compiled MeCab/IPAdic
202
- * dictionary used for Japanese morphological segmentation. Forwarded to
203
- * tts-cpp's `EngineOptions::mecab_dict_path`. Alias: top-level
204
- * `mecabDictPath`.
205
- */
206
- mecabDictDir?: string;
207
- mecabDictPath?: string;
208
- /**
209
- * Chatterbox MTL only: path to the Cangjie TSV used for Chinese
210
- * romanisation. Forwarded to tts-cpp's `EngineOptions::cangjie_tsv_path`.
211
- */
212
- cangjieTsvPath?: string;
213
- cangjieTsv?: string;
214
- }
215
- interface TTSGgmlRuntimeConfig {
216
- /**
217
- * Language code; default "en". Chatterbox MTL accepts
218
- * es/fr/de/pt/it/zh/ja/ko/... CosyVoice3: reserved / not yet effective — the
219
- * text-normalization frontend is not yet integrated, so it is accepted but
220
- * not acted on.
221
- */
222
- language?: string;
223
- /**
224
- * Route inference through a GPU backend (Metal / Vulkan / OpenCL) if
225
- * available. Defaults to `false`. Audio8 uses Vulkan on Linux and Windows;
226
- * CosyVoice3 selects Metal on Apple, Vulkan on desktop Linux / Windows, and
227
- * OpenCL/Adreno on Android (Mali / Xclipse decline to CPU); the other
228
- * GPU-capable engines select a backend for the host platform.
229
- */
230
- useGPU?: boolean;
231
- /**
232
- * Desired output sample rate in Hz (8000-192000); omit to keep the engine's
233
- * native rate. Resamples the native output (24 kHz for Chatterbox and
234
- * CosyVoice3; 44.1 kHz for Supertonic, Parler, and Audio8), or the 48 kHz
235
- * LavaSR-enhanced signal, before emitting. `TTSOutputChunk.sampleRate`
236
- * reports the resulting rate.
237
- *
238
- * CosyVoice3 native chunk streaming emits at 24 kHz: a different rate is
239
- * only accepted there when the LavaSR enhancer is active, because the
240
- * enhancer's overlap-reprocess window resamples without chunk seams.
241
- *
242
- * MOSS emits its native 24 kHz only and rejects any other rate.
243
- */
244
- outputSampleRate?: number;
245
- backendsDir?: string;
246
- openclCacheDir?: string;
247
- vulkanCacheDir?: string;
248
- }
249
- /**
250
- * LavaSR enhancer config. The discriminated `type` leaves room for future
251
- * enhancer kinds; v1 ships `lavasr`. Enhancement is enabled by providing a
252
- * GGUF path here or via `files.lavasrEnhancer`.
253
- */
254
- interface LavaSREnhancerOptions {
255
- type: "lavasr";
256
- /** Enhancer GGUF path (alternative to `files.lavasrEnhancer`). */
257
- enhancerPath?: string;
258
- }
259
- /**
260
- * LavaSR denoiser config. V1 ships the `lavasr` UL-UNAS denoiser. Denoising
261
- * is enabled by providing a GGUF path here or via `files.lavasrDenoiser`.
262
- * It runs before the enhancer and preserves the sample rate.
263
- */
264
- interface LavaSRDenoiserOptions {
265
- type: "lavasr";
266
- /** Denoiser GGUF path (alternative to `files.lavasrDenoiser`). */
267
- denoiserPath?: string;
268
- }
269
- /**
270
- * Cross-engine conditioning. Accepted at construction and on `reload()` by
271
- * every engine that supports them, and per call by Parler and CosyVoice3. A
272
- * value outside the canonical vocabulary, outside the engine's supported
273
- * subset, or on a channel the engine cannot change per call, throws naming the
274
- * alternative -- nothing is silently degraded.
275
- */
276
- interface TTSConditioningFields {
277
- /** Speaking style. Parler: all 12. CosyVoice3: anger|happy|neutral|sad. */
278
- emotion?: Emotion;
279
- /**
280
- * Speaking rate. Parler / CosyVoice3 / Supertonic. Supertonic conditions its
281
- * engine at construction, so its pace only moves there or via `reload()`.
282
- */
283
- pace?: Pace;
284
- }
285
- /**
286
- * Parler voice-description inputs. Either a free-text `description` (alias
287
- * `voiceDescription`) or the template fields, rendered natively through
288
- * tts-cpp's build_description(); mixing the two at the same level is rejected.
289
- * Accepted at construction, on `reload()`, and per call (Parler only).
290
- * `emotion` and `pace` moved to TTSConditioningFields -- Parler still renders
291
- * both, but they are no longer Parler-only at the JS surface.
292
- */
293
- interface ParlerDescriptionFields {
294
- description?: string;
295
- voiceDescription?: string;
296
- /** Parler voice-template field; also Supertonic's baked voice id. */
297
- voice?: string;
298
- pitch?: string;
299
- expressivity?: string;
300
- noise?: string;
301
- reverb?: string;
302
- quality?: string;
303
- }
304
- /**
305
- * Voice cloning reference. Audio8's codec encoder turns `referenceAudio` into
306
- * codes and they are prepended to the prompt as the speaker's own history, so
307
- * no speaker encoder and no enrolment step are involved. `referenceText` is
308
- * required alongside it there: the model conditions on it as the turn the
309
- * recording answers, and a wrong one degrades the clone. Accepted at
310
- * construction, on `reload()`, and per call (Audio8 only).
311
- */
312
- interface Audio8VoiceFields {
313
- /**
314
- * Chatterbox: voice-cloning reference audio path (wav). CosyVoice3:
315
- * zero-shot / cross-lingual cloning reference (0.5-30 s hard limits,
316
- * 5-15 s of clean speech recommended; multichannel input is downmixed to
317
- * mono) — the native front-end tokenizes it (speech_tokenizer_v3),
318
- * extracts the CAM++ speaker embedding and prompt mel at load, replacing
319
- * the baked voice; requires the `cosyvoiceS3tokModel` +
320
- * `cosyvoiceCampplusModel` files and fails the load (never silently falls
321
- * back) when they are missing or the audio is unusable. Pair with
322
- * `promptText` (the verbatim transcript) for zero-shot or omit it for
323
- * cross-lingual. The reference is fixed at construction: `reload()`
324
- * re-bakes the same recording (it is forwarded to the new addon instance)
325
- * but cannot switch to a different one, so changing voices means a new
326
- * instance. Audio8: the recording to clone, with `referenceText`
327
- * alongside it. MOSS: the recording to clone, sampled at 24 kHz and
328
- * fixed at construction; needs `files.mossCodecEncoder`.
329
- */
330
- referenceAudio?: string;
331
- /** Audio8: what `referenceAudio` says. Required when cloning. */
332
- referenceText?: string;
333
- }
334
- /**
335
- * MOSS-SoundEffect per-call generation controls (moss-sfx only). Each one is
336
- * optional; unset `steps` / `guidance` / `shift` use the defaults stored in the
337
- * model file (100 steps, guidance 4, shift 5).
338
- */
339
- interface MossSoundEffectFields {
340
- /** Length of the sound effect, in (0, 30] seconds, rounded to 0.1 s. Defaults to 10. */
341
- seconds?: number;
342
- /** What the sound effect should avoid (classifier-free guidance negative). */
343
- negativePrompt?: string;
344
- /** Diffusion steps, 1..1000. More steps cost proportionally more time. */
345
- steps?: number;
346
- /** Classifier-free guidance scale, 1..50; 1 skips the negative branch. */
347
- guidance?: number;
348
- /** Flow-matching schedule shift, (0, 100]. */
349
- shift?: number;
350
- }
351
- /** Mono PCM accepted by the MOSS-Speech engine: 16-bit integers or floats in [-1, 1]. */
352
- type MossSpeechPcm = Int16Array | Float32Array;
353
- /** One conversation turn for the MOSS-Speech engine: text or audio, never both. */
354
- interface MossSpeechMessage {
355
- role: (typeof MOSS_SPEECH_ROLES)[number];
356
- text?: string;
357
- audio?: MossSpeechPcm;
358
- /** Sample rate of `audio`, 8000..192000 Hz. */
359
- sampleRate?: number;
360
- }
361
- /**
362
- * MOSS-Speech per-call fields (moss-speech only). The user turn is `audio`
363
- * (with `sampleRate`) or the run `input` text; `messages` carries the earlier
364
- * conversation.
365
- */
366
- interface MossSpeechFields {
367
- /** The user's spoken turn, mono PCM. */
368
- audio?: MossSpeechPcm;
369
- /** Sample rate of `audio`, 8000..192000 Hz. */
370
- sampleRate?: number;
371
- /** Earlier turns, oldest first; the new user turn is appended after them. */
372
- messages?: MossSpeechMessage[];
373
- /** A system turn placed first; replaces the model's default system prompt. */
374
- systemPrompt?: string;
375
- /** Reply voice prompt (up to 60 s of mono PCM); the codec's default voice otherwise. */
376
- replyVoice?: MossSpeechPcm;
377
- /** Sample rate of `replyVoice`, 8000..192000 Hz. */
378
- replyVoiceSampleRate?: number;
379
- /** Reply with text only (no audio); the text comes back as `text`. */
380
- textReply?: boolean;
381
- /** Cut the spoken reply after this many seconds (0 = no cut). */
382
- maxReplySeconds?: number;
383
- /** Explicit bound on generated rows, 1..4096; omitted uses remaining model context. */
384
- maxNewTokens?: number;
385
- /** Greedy decoding instead of sampling. */
386
- greedy?: boolean;
387
- /** Sampling temperature, (0, 10] (default 0.7). */
388
- temperature?: number;
389
- /** Nucleus sampling, (0, 1] (default 0.95). */
390
- topP?: number;
391
- /** Top-k sampling, >= 0 (default 20). */
392
- topK?: number;
393
- }
394
- /**
395
- * CosyVoice3 per-call instruction. Same values as the constructor's
396
- * `instruct`; a per-call conditioning control replaces the configured one for
397
- * that synthesis, and one control takes effect per synthesis.
398
- */
399
- interface CosyvoiceJobFields {
400
- instruct?: string | CosyvoiceInstruct;
401
- }
402
- interface TTSGgmlOptions extends ParlerDescriptionFields, Audio8VoiceFields, TTSConditioningFields {
403
- /** Pocket: generation/context controls; native sampling uses a portable RNG. */
404
- maxTokens?: number;
405
- noiseClamp?: number;
406
- eosThreshold?: number;
407
- framesAfterEos?: number;
408
- files?: TTSGgmlFiles;
409
- config?: TTSGgmlRuntimeConfig;
410
- logger?: object;
411
- lazySessionLoading?: boolean;
412
- /** Explicit engine selection. Auto-detected from `files` when omitted. */
413
- engine?: EngineType;
414
- /** Chatterbox: directory of baked voice-conditioning tensors. */
415
- voiceDir?: string;
416
- /**
417
- * RNG seed for Chatterbox CFM/SineGen, Supertonic latent generation,
418
- * the MOSS-SoundEffect diffusion noise (0 when unset, so an unseeded prompt
419
- * repeats its clip), or Pocket's portable sampling RNG. Pocket accepts
420
- * integers from 0 to 4294967295 (inclusive).
421
- */
422
- seed?: number;
423
- /**
424
- * Move N layers to the GPU backend. Chatterbox: pass 99 to move everything.
425
- * Supertonic: pass 99 to offload on GPU-capable hosts, including Android.
426
- * Audio8: pass 99 to use Vulkan on Linux and Windows.
427
- * MOSS: any non-zero value selects the GPU backend.
428
- * CosyVoice3: pass 99 to offload on Metal (macOS / iOS), Vulkan (desktop
429
- * Linux / Windows), or OpenCL/Adreno (Android); other hosts fall back to
430
- * CPU by policy.
431
- */
432
- nGpuLayers?: number;
433
- /**
434
- * Chatterbox: cap on the T3 context length (prompt + generated speech
435
- * tokens, 25 tokens ~= 1 second of audio). The KV cache is allocated up
436
- * front at this length, so the cap directly bounds memory. Pass 0 to use
437
- * the GGUF's full context; negative values are rejected.
438
- * Pocket: FlowLM context capacity; accepts integers from 1 to 8192.
439
- */
440
- nCtx?: number;
441
- /**
442
- * Chatterbox-only T3 KV-cache storage dtype: `f32` | `f16` | `q8_0`.
443
- * `f16` is the safe cross-backend default. `q8_0` is smaller and faster on
444
- * supported backends, but is opt-in because not every backend implements
445
- * its required operations.
446
- */
447
- kvCacheType?: "f32" | "f16" | "q8_0";
448
- /** Override `std::thread::hardware_concurrency()`. */
449
- threads?: number;
450
- /**
451
- * Native streaming chunk size; 0 disables. Chatterbox / CosyVoice3: speech
452
- * tokens per chunk. MOSS: codec frames per chunk (12.5 per second).
453
- * Supertonic: text tokens (Unicode code points) per chunk, about 50 for
454
- * English (CJK is denser, 25-30). Supertonic native streaming cannot be
455
- * combined with the LavaSR enhancer or denoiser.
456
- */
457
- streamChunkTokens?: number;
458
- /**
459
- * Chatterbox / CosyVoice3 / Supertonic smaller first chunk for low
460
- * first-audio-out latency.
461
- */
462
- streamFirstChunkTokens?: number;
463
- /**
464
- * Supertonic-only: boundary-snap window for clause and whitespace chunk
465
- * boundaries, as a percentage of the chunk target (engine default 20).
466
- */
467
- streamChunkTolerancePct?: number;
468
- /**
469
- * Supertonic-only: floor on every streamed chunk's size in text tokens
470
- * (engine default 30); shorter trailing chunks merge into the previous one.
471
- */
472
- streamMinChunkTokens?: number;
473
- /**
474
- * Chatterbox: sliding-window S3Gen for native streaming — keep only this many
475
- * already-emitted speech tokens of left context per chunk, which bounds the
476
- * per-chunk cost on long utterances (typical 25-50; 0 = cumulative prefix).
477
- * CosyVoice3: reserved / not yet effective — the pinned tts-cpp engine
478
- * accepts the value but does not read it.
479
- */
480
- streamLeftContextTokens?: number;
481
- /**
482
- * Chatterbox CFM Euler step count for native streaming chunks. CosyVoice3:
483
- * reserved / not yet effective — the engine runs a fixed 10-step schedule
484
- * and ignores this.
485
- */
486
- cfmSteps?: number;
487
- /**
488
- * Chatterbox-only CFM Euler step count for batch synthesis; 0 = library
489
- * default (2-step meanflow on Turbo, the model's full schedule on
490
- * multilingual). The multilingual engine does not floor this, so values well
491
- * below its schedule under-integrate.
492
- */
493
- batchCfmSteps?: number;
494
- /**
495
- * Chatterbox-only cap on speech tokens T3 decodes per synthesis (25 tokens ~=
496
- * 1 second); engine default 1000 (~40 s). Longer single-call audio also needs
497
- * `nCtx` to cover prompt plus generated tokens, or use `maxSentenceChars`.
498
- */
499
- nPredict?: number;
500
- /**
501
- * Chatterbox-only sentence auto-split: run T3 + S3Gen per segment of at most
502
- * this many bytes (the reference CLI uses 180; 0 = off). Bounds each T3
503
- * sequence, so `nPredict` applies per segment.
504
- */
505
- maxSentenceChars?: number;
506
- /**
507
- * Chatterbox-only raised-cosine crossfade between auto-split batch segments,
508
- * in milliseconds (engine default 30). Native streaming stays gapless.
509
- */
510
- crossfadeMs?: number;
511
- /** Chatterbox-only T3 repetition penalty (engine default 1.2; 1 = off). */
512
- repeatPenalty?: number;
513
- /**
514
- * Chatterbox multilingual only: prosody intensity, above 0 more expressive,
515
- * below 0 flatter (engine default 0.5). The Turbo variant ignores it.
516
- */
517
- exaggeration?: number;
518
- /**
519
- * Chatterbox multilingual only: T3 classifier-free guidance scale (engine
520
- * default 0.5; 0 disables). Separate from `cfgRate`, which steers S3Gen.
521
- */
522
- cfgWeight?: number;
523
- /** Chatterbox multilingual only: min-p sampling threshold (0 = off). */
524
- minP?: number;
525
- /**
526
- * Chatterbox-only S3Gen classifier-free-guidance rate. The diffusion loop
527
- * normally runs a batched conditioned + unconditioned pass combined by this
528
- * rate. `0` skips the unconditioned pass; a positive value overrides the
529
- * model's baked rate. Omit it to retain the baked rate.
530
- */
531
- cfgRate?: number;
532
- /**
533
- * CosyVoice3: verbatim transcript of `referenceAudio`, selecting the
534
- * cloning mode per the upstream frontends — set it for zero-shot (the LM
535
- * is prompted with transcript + reference speech tokens; best fidelity in
536
- * the reference's own language), omit it for cross-lingual (timbre-only
537
- * conditioning; best when synthesizing a different language than the
538
- * reference). Without `referenceAudio` it still overrides the baked
539
- * voice's transcript metadata for the LM prompt.
540
- */
541
- promptText?: string;
542
- /**
543
- * CosyVoice3: natural-language control (instruct2) — Chinese dialect, emotion,
544
- * speed, volume, or style. Pass a structured object (e.g. `{ dialect:
545
- * 'cantonese' }`, `{ emotion: 'happy' }`) which renders to the trained
546
- * instruction, or a raw string for an arbitrary instruction. Applied on top of
547
- * the selected voice's timbre; one control takes effect per synthesis.
548
- */
549
- instruct?: string | CosyvoiceInstruct;
550
- /**
551
- * Supertonic voice id baked into the GGUF, such as `F1` or `M1`. CosyVoice3:
552
- * reserved / not yet effective — named-voice selection is not yet wired.
553
- */
554
- voice?: string;
555
- /** Alias for `voice` for compatibility with `@qvac/tts-onnx`. */
556
- voiceName?: string;
557
- /**
558
- * Supertonic-only: external voice JSON (`{ style_ttl, style_dp }`, e.g. a
559
- * cloned voice) that overrides the baked `voice` preset. The engine checks
560
- * the tensor sizes against the loaded model.
561
- */
562
- voiceJsonPath?: string;
563
- /**
564
- * Supertonic-only: text synthesized once at load so GPU pipelines (and a
565
- * Core ML vocoder sidecar) are ready before the first `run()`; skipped on a
566
- * plain CPU run. Use a sentence of representative length. Wins over the
567
- * `vulkanCacheDir` default pre-warm.
568
- */
569
- prewarmText?: string;
570
- /**
571
- * Supertonic / CosyVoice3 Vulkan adapter index, also used by their LavaSR
572
- * enhancer: 0 (default) = first adapter, N = the Nth, -1 = auto-pick by free
573
- * VRAM preferring a discrete adapter. Only consulted on Vulkan.
574
- */
575
- vulkanDevice?: number;
576
- /**
577
- * CosyVoice3-only: treat the baked-voice prompt frames as attention-only
578
- * conditioning in the flow, for a faster flow whose output deviates slightly
579
- * from the reference (engine default off).
580
- */
581
- flowCutPrompt?: boolean;
582
- /** Supertonic CFM steps (0 uses GGUF default); Pocket sampling steps (1–64, default 1). */
583
- steps?: number;
584
- /** Alias for `steps` for compatibility with `@qvac/tts-onnx`. */
585
- numInferenceSteps?: number;
586
- /**
587
- * Speech-rate / duration multiplier (1.0 = unchanged, less than 1 slower,
588
- * greater than 1 faster). Supertonic scales its native duration predictor.
589
- * Chatterbox applies pitch-preserving WSOLA time-stretch, bounded to
590
- * [0.25, 4.0].
591
- */
592
- speed?: number;
593
- /** Supertonic optional `.npy` initial-noise tensor path. */
594
- noiseNpyPath?: string;
595
- /**
596
- * LavaSR neural speech enhancement. Opt-in CPU/GGML bandwidth extension to
597
- * 48 kHz, enabled by a GGUF path here or through `files.lavasrEnhancer`.
598
- * Works for every engine, including the native chunk streaming of
599
- * Chatterbox, Parler and CosyVoice3.
600
- */
601
- enhancer?: LavaSREnhancerOptions;
602
- /**
603
- * LavaSR neural speech denoiser (UL-UNAS). Opt-in preprocessing that runs
604
- * before the enhancer and preserves the sample rate. Enabled by a GGUF path
605
- * here or through `files.lavasrDenoiser`; rejected with native chunk
606
- * streaming (batch synthesis only).
607
- */
608
- denoiser?: LavaSRDenoiserOptions;
609
- /**
610
- * Directory the addon scans for dynamically loaded ggml backends, as given.
611
- * Unset scans the addon's own: the one its platform package or the app
612
- * installed next to the native module.
613
- */
614
- backendsDir?: string;
615
- /** Directory where ggml-opencl persists its compiled program binary. */
616
- openclCacheDir?: string;
617
- /**
618
- * Supertonic + `useGPU: true` only: directory where the Vulkan backend
619
- * persists its compiled pipeline cache (`GGML_VK_PIPELINE_CACHE_DIR`).
620
- * Unset means no cross-process cache or load-time pre-warm.
621
- */
622
- vulkanCacheDir?: string;
623
- /** Chatterbox MTL MeCab/IPAdic dictionary directory for Japanese. */
624
- mecabDictPath?: string;
625
- mecabDictDir?: string;
626
- /** Chatterbox MTL Cangjie TSV path for Chinese. */
627
- cangjieTsvPath?: string;
628
- /**
629
- * Parler, Audio8 and Chatterbox sampling knobs; each unset defers to the
630
- * engine's own defaults (Parler: temperature 1.0, top-k 50; Audio8:
631
- * temperature 0.7, top-k 50, top-p 0.9; Chatterbox: temperature 0.8,
632
- * top-k 1000, top-p 0.95, where temperature 0 decodes greedily and top-k 0
633
- * disables the cutoff). Audio8 filters by top-k/top-p on the raw logits and
634
- * only then applies the temperature, following its reference.
635
- * Pocket: sampling temperature; accepts finite values from 0 to 10.
636
- */
637
- temperature?: number;
638
- topK?: number;
639
- topP?: number;
640
- /**
641
- * Generation-length cap in decoder frames; 0 = engine default. Parler runs
642
- * ~86 frames/s, Audio8 ~21.5.
643
- */
644
- maxFrames?: number;
645
- /** Audio8: take the argmax instead of sampling. */
646
- greedy?: boolean;
647
- /**
648
- * MOSS: target length in codec frames (12.5 per second), from 0 to 2015
649
- * (about 161 s); 0 or unset keeps the length free. Set at construction or
650
- * with `reload()`, not per call.
651
- */
652
- durationTokens?: number;
653
- /**
654
- * MOSS-TTSD dialogue: one 24 kHz reference recording per speaker, in the
655
- * order the text tags them (`[S1]`, `[S2]`, ...). The model continues the
656
- * references, so the input text must open with each reference's transcript
657
- * under its tag, followed by the lines to generate; sentence streaming is
658
- * therefore rejected (use `run()` or `streamChunkTokens`). Needs
659
- * `files.mossCodecEncoder`, excludes `referenceAudio`, and is fixed for the
660
- * instance. With a `modelDir`, requires a `moss-ttsd-*.gguf` backbone.
661
- */
662
- dialogueReferences?: string[];
663
- minNewTokens?: number;
664
- /** Parler prompt digit expansion (engine default: enabled). */
665
- normalizeNumbers?: boolean;
666
- opts?: object;
667
- exclusiveRun?: boolean;
668
- }
669
- interface InferenceState {
670
- configLoaded: boolean;
671
- weightsLoaded: boolean;
672
- destroyed: boolean;
673
- }
674
- interface TTSOutputChunk {
675
- chunkIndex?: number;
676
- isLast?: boolean;
677
- /** Signed 16-bit mono PCM audio payload. */
678
- outputArray: Int16Array;
679
- /** MOSS-Speech: the reply's text channel (the whole answer with `textReply`). */
680
- text?: string;
681
- /**
682
- * Output sample rate. The native engine rate (24000 for Chatterbox,
683
- * CosyVoice3 and MOSS; 44100 for Supertonic, Parler, and Audio8), or 48000
684
- * when the LavaSR enhancer is active.
685
- */
686
- sampleRate?: number;
687
- }
688
- interface RuntimeStats {
689
- firstAudioMs?: number;
690
- totalTime: number;
691
- tokensPerSecond: number;
692
- realTimeFactor: number;
693
- audioDurationMs: number;
694
- totalSamples: number;
695
- /** Active compute device after load-time backend selection. 0 = CPU, 1 = GPU. */
696
- backendDevice?: number;
697
- /** Stable backend code: 0=CPU, 1=Metal, 2=CUDA, 3=Vulkan, 4=OpenCL, 99=other GPU. */
698
- backendId?: number;
699
- /** LavaSR enhancer compute device. -1 = not loaded, 0 = CPU, 1 = GPU. */
700
- enhancerBackendDevice?: number;
701
- /** LavaSR enhancer backend code, using the same values as `backendId`. */
702
- enhancerBackendId?: number;
703
- /** LavaSR denoiser compute device. -1 = not loaded, 0 = CPU, 1 = GPU. */
704
- denoiserBackendDevice?: number;
705
- /** LavaSR denoiser backend code, using the same values as `backendId`. */
706
- denoiserBackendId?: number;
707
- /** 1 when a present GPU is unsupported by engine policy; 0 otherwise. */
708
- gpuUnsupported?: number;
709
- /**
710
- * Audio8 and MOSS only: codec frames generated (Audio8 on a fixed 46 ms
711
- * grid, MOSS at 12.5 per second). This is the unit their `tokensPerSecond`
712
- * counts, in batch and in streaming alike.
713
- */
714
- generatedFrames?: number;
715
- /**
716
- * Audio8 only, macOS / iOS: 1 while an Apple Core ML sidecar for the codec's
717
- * synthesis stack is attached (a compiled `audio8-codec-decoder.mlmodelc`
718
- * next to the decoder GGUF); 0 without one, or once a failing sidecar has
719
- * been retired. Streams report the last chunk that supplied this field.
720
- */
721
- codecSidecarLoaded?: number;
722
- /**
723
- * Audio8 only: 1 when this synthesis ran the codec's synthesis stack on the
724
- * Apple Core ML sidecar -- a compiled `audio8-codec-decoder.mlmodelc` next
725
- * to the decoder GGUF on macOS / iOS -- 0 when it ran on the ggml backend
726
- * `backendId` reports (which the language model always uses). A loaded
727
- * sidecar that cannot serve a call falls back to ggml and reports 0 for it.
728
- * Streams report the last chunk that supplied this field, not a sum.
729
- */
730
- codecOnCoreml?: number;
731
- /** Chatterbox only: T3 decode wall time of the last synthesis, in ms. */
732
- t3Ms?: number;
733
- /** Chatterbox only: S3Gen + HiFT wall time of the last synthesis, in ms. */
734
- s3genMs?: number;
735
- /** Chatterbox only: speech tokens T3 emitted in the last synthesis. */
736
- t3Tokens?: number;
737
- /**
738
- * CosyVoice3 / Audio8: the engine's own wall time for the last synthesis, in
739
- * ms (the sum of its stages), excluding the addon's post-processing.
740
- */
741
- stageTotalMs?: number;
742
- /** CosyVoice3 stage wall times of the last synthesis, in ms. */
743
- lmPrefillMs?: number;
744
- lmDecodeMs?: number;
745
- flowFrontendMs?: number;
746
- ditEulerMs?: number;
747
- hiftF0Ms?: number;
748
- hiftSourceMs?: number;
749
- hiftStftMs?: number;
750
- hiftDecodeMs?: number;
751
- /**
752
- * CosyVoice3 work counters of the last synthesis: LM decode steps, speech
753
- * tokens generated, flow frames in (prompt + generated), mel frames out,
754
- * text ids in the LM prefill, and prompt speech tokens the LM continued from.
755
- */
756
- decodeSteps?: number;
757
- speechTokens?: number;
758
- flowFrames?: number;
759
- melFrames?: number;
760
- textIds?: number;
761
- promptSpeechTokens?: number;
762
- /** Audio8 stage wall times of the last synthesis, in ms. */
763
- voiceEncodeMs?: number;
764
- promptMs?: number;
765
- prefillMs?: number;
766
- sampleMs?: number;
767
- fastDecodeMs?: number;
768
- slowDecodeMs?: number;
769
- codecLatentMs?: number;
770
- codecSynthMs?: number;
771
- resampleMs?: number;
772
- }
773
- /**
774
- * tts-cpp's canonical conditioning vocabulary and each engine's supported
775
- * subset, keyed by engine type (`TTSGgml.getVoiceControls()`).
776
- */
777
- interface VoiceControlsCatalog {
778
- emotions: string[];
779
- paces: string[];
780
- engines: Record<string, {
781
- emotions: string[];
782
- paces: string[];
783
- }>;
784
- }
785
- interface SentenceStreamChunkMeta {
786
- chunkIndex?: number;
787
- sentenceChunk?: string;
788
- /**
789
- * True on the final pre-chunked synthesis output. Undefined for async
790
- * iterator streaming where the final chunk is not known up front.
791
- */
792
- isLast?: boolean;
793
- }
794
- interface SentenceStreamOptions extends ParlerDescriptionFields, Audio8VoiceFields, TTSConditioningFields, CosyvoiceJobFields {
795
- /** BCP-47 locale for `Intl.Segmenter` when available. */
796
- locale?: string;
797
- /** Maximum graphemes per chunk; defaults to 300, or 120 for Korean. */
798
- maxChunkScalars?: number;
799
- }
800
- interface RunStreamingOptions extends ParlerDescriptionFields, Audio8VoiceFields, TTSConditioningFields, CosyvoiceJobFields {
801
- accumulateSentences?: boolean;
802
- sentenceDelimiter?: RegExp;
803
- sentenceDelimiterPreset?: SentenceDelimiterPreset;
804
- maxBufferScalars?: number;
805
- flushAfterMs?: number;
806
- }
807
- /** Input accepted by `runStreaming`. */
808
- type TextStreamInput = string | string[] | Iterable<string> | AsyncIterable<string>;
809
- interface TTSRunInput extends ParlerDescriptionFields, Audio8VoiceFields, TTSConditioningFields, CosyvoiceJobFields, MossSoundEffectFields, MossSpeechFields {
810
- type?: string;
811
- input: string;
812
- streamOutput?: boolean;
813
- locale?: string;
814
- maxChunkScalars?: number;
815
- /**
816
- * Cancels non-streaming `run()`. An already-aborted signal rejects without
817
- * native dispatch. Ignored by all streaming paths.
818
- */
819
- signal?: AbortSignal;
820
- }
3
+ import type * as Fit from "./lib/fit";
4
+ import { type EngineType } from "./lib/engineIds";
5
+ import type * as PublicTypes from "./lib/types";
6
+ import type { InferenceState, RunStreamingOptions, SentenceStreamChunkMeta, SentenceStreamOptions, TextStreamInput, TTSGgmlOptions, TTSOutputChunk, TTSRunInput, VoiceControlsCatalog } from "./lib/types";
821
7
  /**
822
8
  * GGML-backed TTS via the `tts-cpp` library. Wraps the chatterbox,
823
9
  * supertonic, parler, cosyvoice3, audio8 and moss engines behind a single
@@ -848,190 +34,15 @@ declare class TTSGgml {
848
34
  addon: unknown;
849
35
  private readonly _job;
850
36
  private readonly _runExclusive;
851
- private _ttsInferenceQueueWaiter;
852
- private _sentenceStreamCtx;
853
- private _config;
854
- private _pocketJobPending;
855
- private _pocketCancelPromise;
856
- private _pocketLifecycleInProgress;
857
- private _pocketParams;
858
- private _pocketOptions;
859
- private _pocketFiles;
37
+ private readonly _exclusiveStreams;
38
+ /** Everything resolved from the constructor options; reload rewrites parts of it. */
39
+ private readonly _setup;
40
+ private readonly _sentenceStream;
41
+ private readonly _events;
42
+ /** The Pocket execution rules, or null for every other engine. */
43
+ private readonly _pocket;
860
44
  private _lazySessionLoading;
861
- private _outputSampleRate;
862
- private _engineType;
863
- private _voicesDir?;
864
- private _supertonicModelPath?;
865
- private _t3ModelPath?;
866
- private _s3genModelPath?;
867
- private _cosyvoiceModelDir?;
868
- private _cosyvoiceLlmModelPath?;
869
- private _cosyvoiceFlowModelPath?;
870
- private _cosyvoiceHiftModelPath?;
871
- private _cosyvoiceS3tokModelPath?;
872
- private _cosyvoiceCampplusModelPath?;
873
- private _mecabDictPath?;
874
- private _cangjieTsvPath?;
875
- private _referenceAudio?;
876
- private _voiceDir?;
877
- private _seed?;
878
- private _nGpuLayers?;
879
- private _nCtx?;
880
- private _kvCacheType?;
881
- private _threads?;
882
- private _streamChunkTokens?;
883
- private _streamFirstChunkTokens?;
884
- private _streamLeftContextTokens?;
885
- private _cfmSteps?;
886
- private _cfgRate?;
887
- private _batchCfmSteps?;
888
- private _nPredict?;
889
- private _maxSentenceChars?;
890
- private _crossfadeMs?;
891
- private _repeatPenalty?;
892
- private _exaggeration?;
893
- private _cfgWeight?;
894
- private _minP?;
895
- private _streamChunkTolerancePct?;
896
- private _streamMinChunkTokens?;
897
- private _voiceJsonPath?;
898
- private _prewarmText?;
899
- private _vulkanDevice?;
900
- private _flowCutPrompt?;
901
- private _cosyvoiceVocabPath?;
902
- private _cosyvoiceMergesPath?;
903
- private _cosyvoiceVoiceModelPath?;
904
- private _promptText?;
905
- private _instruct?;
906
- private _voice?;
907
- private _steps?;
908
- private _speed?;
909
- private _noiseNpyPath?;
910
- private _enhancerGgufPath?;
911
- private _denoiserGgufPath?;
912
- private _backendsDir?;
913
- private _openclCacheDir?;
914
- private _vulkanCacheDir?;
915
- private _parlerModelPath?;
916
- private _audio8LmPath?;
917
- private _audio8CodecDecoderPath?;
918
- private _audio8CodecEncoderPath?;
919
- private _mossBackbonePath?;
920
- private _mossCodecDecoderPath?;
921
- private _mossCodecEncoderPath?;
922
- private _mossSoundEffectPath?;
923
- private _mossSpeechModelPath?;
924
- private _mossSpeechCodecPath?;
925
- private _dialogueReferences?;
926
- private _durationTokens?;
927
- private _referenceText?;
928
- private _greedy?;
929
- private _description?;
930
- private _emotion?;
931
- private _pitch?;
932
- private _pace?;
933
- private _expressivity?;
934
- private _noise?;
935
- private _reverb?;
936
- private _quality?;
937
- private _temperature?;
938
- private _topK?;
939
- private _topP?;
940
- private _maxFrames?;
941
- private _minNewTokens?;
942
- private _normalizeNumbers?;
943
45
  constructor(options?: TTSGgmlOptions);
944
- private _resolveEngineAndModelPaths;
945
- private _resolveAudio8ModelPaths;
946
- private _mossBackbonePatterns;
947
- private _findMossBackbone;
948
- private _resolveMossModelPaths;
949
- private _assignMossVoiceOptions;
950
- private _assignSynthesisOptions;
951
- private _assertEngineStreamingSupport;
952
- private _requestsChunkStreaming;
953
- private _assertParlerOptionConsistency;
954
- private _assertSamplerOptionSupport;
955
- /**
956
- * Options only some engines read. Set on any other engine they would be
957
- * dropped without effect, so they are rejected by name instead.
958
- */
959
- private _assertEngineScopedOptions;
960
- private _assertAudio8OptionConsistency;
961
- private _assertMossSoundEffectOptionConsistency;
962
- private _assertMossSpeechOptionConsistency;
963
- private _assertMossSpeechOutputRate;
964
- private _assertMossSoundEffectOutputRate;
965
- private _assertMossOptionConsistency;
966
- private _assertNoMossOnlyOptions;
967
- private _assertMossDialogueReferences;
968
- private _assertSentenceStreamingAllowed;
969
- private _assertMossOutputRate;
970
- private _assertMossVoiceConsistent;
971
- /**
972
- * A recording without its transcript is accepted by the model but degrades
973
- * the clone silently, and a transcript alone has nothing to attach to, so
974
- * both halves have to arrive together.
975
- */
976
- private _assertAudio8VoiceConsistent;
977
- /**
978
- * `promptText` is deliberately not required: its absence selects
979
- * cross-lingual mode. With a model dir present but no cloning GGUFs in it,
980
- * the native load fail-closes instead.
981
- */
982
- private _assertCosyvoiceCloneConsistent;
983
- private _assertCosyvoiceOptionConsistency;
984
- /**
985
- * Validate the cross-engine emotion/pace surface against this engine, and
986
- * enforce CosyVoice3's one-instruction-per-synthesis rule.
987
- */
988
- private _assertConditioningConsistency;
989
- /**
990
- * The per-call surface of a non-Parler engine: only the cross-engine
991
- * emotion/pace it declares support for, never Parler's template fields.
992
- */
993
- private _resolveConditioningJobFields;
994
- /**
995
- * CosyVoice3's per-call instruction, rendered like the constructor's. The
996
- * native layer reads it next to emotion/pace, and any of the three replaces
997
- * the configured conditioning for that synthesis.
998
- */
999
- private _resolveJobInstruct;
1000
- /**
1001
- * Parler's per-call surface: description/template fields, where a per-call
1002
- * template cannot be merged with a constructor-level free-text description.
1003
- */
1004
- private _resolveParlerJobFields;
1005
- /**
1006
- * The voice a per-call override actually synthesizes with. Mirrors
1007
- * Audio8Model::resolveVoice: a per-call recording replaces both halves, so
1008
- * it cannot inherit the configured transcript, which describes a different
1009
- * recording; a per-call transcript alone corrects the configured one.
1010
- */
1011
- private _mergeAudio8Voice;
1012
- /**
1013
- * Extract + validate the per-call Audio8 voice fields from a run input or
1014
- * streaming options. Returns undefined when none are present.
1015
- */
1016
- private _resolveAudio8JobFields;
1017
- private _assertNoSpeechFields;
1018
- private _assertNoOtherEngineFields;
1019
- /**
1020
- * Validate the MOSS-Speech call and fold the new user turn (spoken `audio`
1021
- * or text `input`) and `systemPrompt` into the native `messages` list.
1022
- */
1023
- private _resolveSpeechJobFields;
1024
- /**
1025
- * Extract + validate the per-call MOSS-SoundEffect controls from a run
1026
- * input. Returns undefined when none are present.
1027
- */
1028
- private _resolveSoundEffectJobFields;
1029
- /**
1030
- * The per-call fields of whichever engine is loaded, if any are set. Parler
1031
- * takes the full description/template surface, Audio8 its voice override,
1032
- * and every engine the cross-engine conditioning it supports.
1033
- */
1034
- private _resolveJobFields;
1035
46
  getEngineType(): EngineType;
1036
47
  getApiDefinition(): string;
1037
48
  getState(): InferenceState;
@@ -1058,95 +69,23 @@ declare class TTSGgml {
1058
69
  * small streamed fragments are coalesced.
1059
70
  */
1060
71
  runStreaming(textStream: TextStreamInput, options?: RunStreamingOptions): Promise<QvacResponse<TTSOutputChunk & SentenceStreamChunkMeta>>;
1061
- private _enqueueExclusiveTtsResponse;
1062
- private _resolveRunStreamingOptions;
1063
- private _normalizeTextStream;
1064
- private _runTextStreamOrchestrator;
1065
- private _sentenceStreamTextIterableDrive;
1066
- /**
1067
- * Audio8 and MOSS report `tokensPerSecond` as codec frames per second, so
1068
- * the streaming aggregate has to count frames too rather than characters.
1069
- */
1070
- private _pacesOnFrames;
72
+ /** Streams line up behind each other under `exclusiveRun`; otherwise they start at once. */
73
+ private _startStream;
1071
74
  private _runStreamOrchestrator;
1072
- private _sentenceStreamDriveBody;
1073
75
  private _load;
1074
76
  private _buildTtsParams;
1075
- private _buildCosyvoiceParams;
1076
- private _buildChatterboxParams;
1077
- private _buildSupertonicParams;
1078
- private _buildParlerParams;
1079
- private _buildAudio8Params;
1080
- private _buildMossParams;
1081
- private _buildMossSoundEffectParams;
1082
- private _buildMossSpeechParams;
1083
- /** The knobs every engine in SAMPLING_ENGINES reads. */
1084
- private _assignSamplingParams;
1085
- /**
1086
- * Backend and output plumbing for the engines that take no `language`,
1087
- * where `_assignCommonNativeParams` would be the wrong shape.
1088
- */
1089
- private _assignBackendParams;
1090
- private _assignCommonNativeParams;
1091
- /** LavaSR post-processing paths, shared by every engine that supports them. */
1092
- private _assignLavasrParams;
77
+ /** A native instance that reports through this wrapper's output callback. */
78
+ private _spawnAddon;
1093
79
  private _createAddon;
1094
80
  unload(): Promise<void>;
1095
81
  private _unloadModel;
1096
82
  destroy(): Promise<void>;
83
+ private _withPocketLifecycle;
1097
84
  private _runInternal;
1098
- private _mergeSentenceStreamStats;
1099
- private _rejectActiveChunk;
1100
- private _endJobWithStats;
1101
85
  private _addonOutputCallback;
1102
- private _handleAddonError;
1103
- private _handleAddonOutput;
1104
- private _enrichStreamChunk;
1105
- private _handleAddonStats;
1106
- private _waitPocketCancel;
1107
- private _withPocketLifecycle;
1108
- private _checkPocketReload;
1109
- private _checkPocketRequest;
1110
86
  private _dispatchJob;
1111
87
  cancel(): Promise<void>;
1112
- private _failAndClearActiveResponse;
1113
- /** Everything reload() may overwrite, so a rejected reload can undo itself. */
1114
- private _captureReloadableState;
1115
- private _restoreReloadableState;
1116
- private _applyReloadableRuntimeConfig;
1117
- private _assertMossReloadKeepsVoice;
1118
- private _applyMossReload;
1119
- private _applyReloadableConditioning;
1120
- private _applyReloadableParlerConfig;
1121
- /**
1122
- * Apply the new configuration and build the native parameters from it. A
1123
- * rejected value leaves the instance exactly as it was, so a later partial
1124
- * reload is not validated against state the caller never accepted.
1125
- */
1126
- private _applyReloadableConfig;
1127
- private _reloadPocket;
1128
88
  reload(newConfig?: Record<string, unknown>): Promise<void>;
1129
- /**
1130
- * The voice a reload lands on. Same rule as _mergeAudio8Voice and
1131
- * Audio8Model::resolveVoice: a new recording replaces both halves, because
1132
- * the configured transcript describes the recording being replaced. Reload
1133
- * reads `undefined` as "not supplied", so an explicit empty string reaches
1134
- * the guard instead of being ignored.
1135
- */
1136
- private _mergeAudio8ReloadVoice;
1137
- /**
1138
- * The knobs a reload lands on, merged the same way as the voice so the
1139
- * whole set can be checked before any of it is written.
1140
- */
1141
- private _mergeAudio8ReloadSampling;
1142
- private _applyAudio8Sampling;
1143
- /**
1144
- * Audio8 voice + sampling knobs are reloadable; they rebuild the engine's
1145
- * sampler and speaker history. Both merges are checked before either is
1146
- * written, so a rejected reload leaves the instance exactly as it was
1147
- * rather than half-moved onto the configuration that was refused.
1148
- */
1149
- private _applyAudio8Reload;
1150
89
  static getModelKey(_params?: unknown): string;
1151
90
  /**
1152
91
  * tts-cpp's canonical emotion / pace vocabulary and each engine's supported
@@ -1159,61 +98,35 @@ declare class TTSGgml {
1159
98
  private _optionalAddon;
1160
99
  private _getLogger;
1161
100
  }
1162
- type NamespaceFiles = TTSGgmlFiles;
1163
- type NamespaceRuntimeConfig = TTSGgmlRuntimeConfig;
1164
- type NamespaceOptions = TTSGgmlOptions;
1165
- type NamespaceEnhancerOptions = LavaSREnhancerOptions;
1166
- type NamespaceDenoiserOptions = LavaSRDenoiserOptions;
1167
- type NamespaceRuntimeStats = RuntimeStats;
1168
- type NamespaceOutputChunk = TTSOutputChunk;
1169
- type NamespaceSentenceStreamChunkMeta = SentenceStreamChunkMeta;
1170
- type NamespaceSentenceStreamOptions = SentenceStreamOptions;
1171
- type NamespaceRunStreamingOptions = RunStreamingOptions;
1172
- type NamespaceTextStreamInput = TextStreamInput;
1173
- type NamespaceRunInput = TTSRunInput;
1174
- type NamespaceInferenceState = InferenceState;
1175
- type NamespaceCosyvoiceInstruct = CosyvoiceInstruct;
1176
- type NamespaceVoiceControlsCatalog = VoiceControlsCatalog;
1177
- type NamespaceFitEngine = TtsFitEngine;
1178
- type NamespaceFitRequest = TtsFitRequest;
1179
- type NamespaceFitResult = TtsFitResult;
1180
- type NamespaceFitStatus = TtsFitStatus;
1181
- type NamespaceSupertonicFit = SupertonicFitRequest;
1182
- type NamespaceParlerFit = ParlerFitRequest;
1183
- type NamespaceChatterboxFit = ChatterboxFitRequest;
1184
- type NamespaceAudio8Fit = Audio8FitRequest;
1185
- type NamespaceMossFit = MossFitRequest;
1186
- type NamespaceMossSoundEffectFit = MossSoundEffectFitRequest;
1187
- type NamespaceCosyvoiceFit = CosyvoiceFitRequest;
1188
101
  declare namespace TTSGgml {
1189
102
  export import QvacErrorAddonTTSGgml = errorModule.QvacErrorAddonTTSGgml;
1190
103
  export import ERR_CODES = errorModule.ERR_CODES;
1191
- type TTSGgmlFiles = NamespaceFiles;
1192
- type TTSGgmlRuntimeConfig = NamespaceRuntimeConfig;
1193
- type TTSGgmlOptions = NamespaceOptions;
1194
- type LavaSREnhancerOptions = NamespaceEnhancerOptions;
1195
- type LavaSRDenoiserOptions = NamespaceDenoiserOptions;
1196
- type RuntimeStats = NamespaceRuntimeStats;
1197
- type TTSOutputChunk = NamespaceOutputChunk;
1198
- type SentenceStreamChunkMeta = NamespaceSentenceStreamChunkMeta;
1199
- type SentenceStreamOptions = NamespaceSentenceStreamOptions;
1200
- type RunStreamingOptions = NamespaceRunStreamingOptions;
1201
- type TextStreamInput = NamespaceTextStreamInput;
1202
- type TTSRunInput = NamespaceRunInput;
1203
- type InferenceState = NamespaceInferenceState;
1204
- type CosyvoiceInstruct = NamespaceCosyvoiceInstruct;
1205
- type VoiceControlsCatalog = NamespaceVoiceControlsCatalog;
1206
- type TtsFitEngine = NamespaceFitEngine;
1207
- type TtsFitRequest = NamespaceFitRequest;
1208
- type TtsFitResult = NamespaceFitResult;
1209
- type TtsFitStatus = NamespaceFitStatus;
1210
- type SupertonicFitRequest = NamespaceSupertonicFit;
1211
- type ParlerFitRequest = NamespaceParlerFit;
1212
- type ChatterboxFitRequest = NamespaceChatterboxFit;
1213
- type Audio8FitRequest = NamespaceAudio8Fit;
1214
- type MossFitRequest = NamespaceMossFit;
1215
- type MossSoundEffectFitRequest = NamespaceMossSoundEffectFit;
1216
- type CosyvoiceFitRequest = NamespaceCosyvoiceFit;
1217
- const assessFit: typeof assessFitImpl;
104
+ type TTSGgmlFiles = PublicTypes.TTSGgmlFiles;
105
+ type TTSGgmlRuntimeConfig = PublicTypes.TTSGgmlRuntimeConfig;
106
+ type TTSGgmlOptions = PublicTypes.TTSGgmlOptions;
107
+ type LavaSREnhancerOptions = PublicTypes.LavaSREnhancerOptions;
108
+ type LavaSRDenoiserOptions = PublicTypes.LavaSRDenoiserOptions;
109
+ type RuntimeStats = PublicTypes.RuntimeStats;
110
+ type TTSOutputChunk = PublicTypes.TTSOutputChunk;
111
+ type SentenceStreamChunkMeta = PublicTypes.SentenceStreamChunkMeta;
112
+ type SentenceStreamOptions = PublicTypes.SentenceStreamOptions;
113
+ type RunStreamingOptions = PublicTypes.RunStreamingOptions;
114
+ type TextStreamInput = PublicTypes.TextStreamInput;
115
+ type TTSRunInput = PublicTypes.TTSRunInput;
116
+ type InferenceState = PublicTypes.InferenceState;
117
+ type CosyvoiceInstruct = PublicTypes.CosyvoiceInstruct;
118
+ type VoiceControlsCatalog = PublicTypes.VoiceControlsCatalog;
119
+ type TtsFitEngine = Fit.TtsFitEngine;
120
+ type TtsFitRequest = Fit.TtsFitRequest;
121
+ type TtsFitResult = Fit.TtsFitResult;
122
+ type TtsFitStatus = Fit.TtsFitStatus;
123
+ type SupertonicFitRequest = Fit.SupertonicFitRequest;
124
+ type ParlerFitRequest = Fit.ParlerFitRequest;
125
+ type ChatterboxFitRequest = Fit.ChatterboxFitRequest;
126
+ type Audio8FitRequest = Fit.Audio8FitRequest;
127
+ type MossFitRequest = Fit.MossFitRequest;
128
+ type MossSoundEffectFitRequest = Fit.MossSoundEffectFitRequest;
129
+ type CosyvoiceFitRequest = Fit.CosyvoiceFitRequest;
130
+ const assessFit: typeof Fit.assessFit;
1218
131
  }
1219
132
  export = TTSGgml;