@qvac/tts-ggml 0.10.0 → 0.11.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.
@@ -0,0 +1,136 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * MOSS-Speech speech-to-speech for @qvac/tts-ggml.
5
+ *
6
+ * MOSS-Speech answers a spoken question with speech, with no text step in
7
+ * between: a 9B language model with separate text and audio branches reads
8
+ * the question's speech tokens and writes the reply's, and the codec speaks
9
+ * them in a 24 kHz voice (the codec's default voice, or a reference WAV).
10
+ *
11
+ * Usage:
12
+ * bare examples/moss-speech.js question.wav [reply-voice.wav]
13
+ *
14
+ * Examples:
15
+ * bare examples/moss-speech.js test/reference-audio/jfk.wav
16
+ * QVAC_TTS_MOSS_SPEECH_GPU=1 bare examples/moss-speech.js question.wav my-voice.wav
17
+ * QVAC_TTS_MOSS_SPEECH_TEXT=1 bare examples/moss-speech.js question.wav
18
+ *
19
+ * Expects the MOSS-Speech language model (moss-speech-q8_0.gguf or
20
+ * moss-speech-bf16.gguf) and its codec (moss-speech-codec-f16.gguf) under:
21
+ * models/
22
+ * Produce them with engines/tts/scripts/convert-moss-speech-to-gguf.py and
23
+ * convert-moss-speech-codec-to-gguf.py in qvac-fabric-speech.cpp until they
24
+ * are published to the model registry. Desktop only; use a GPU.
25
+ */
26
+
27
+ const path = require('bare-path')
28
+ const proc = require('bare-process')
29
+ const TTSGgml = require('../')
30
+ const { createWav, readWavAsFloat32 } = require('./wav-helper')
31
+ const { setLogger, releaseLogger } = require('../addonLogging')
32
+
33
+ const SPEECH_SAMPLE_RATE = 24000
34
+
35
+ const argv = global.Bare ? global.Bare.argv : process.argv
36
+ const questionArg = argv[2]
37
+ const voiceArg = argv[3]
38
+ const textReply = proc.env.QVAC_TTS_MOSS_SPEECH_TEXT === '1'
39
+
40
+ function fail(message) {
41
+ console.error(message)
42
+ if (global.Bare) global.Bare.exit(1)
43
+ else process.exit(1)
44
+ }
45
+
46
+ if (!questionArg) {
47
+ fail('Usage: moss-speech.js <question.wav> [reply-voice.wav]')
48
+ }
49
+
50
+ const pkgRoot = path.join(__dirname, '..')
51
+ const modelDir = path.join(pkgRoot, 'models')
52
+
53
+ function buildModel() {
54
+ return new TTSGgml({
55
+ engine: TTSGgml.ENGINE_MOSS_SPEECH,
56
+ files: { modelDir },
57
+ config: { useGPU: proc.env.QVAC_TTS_MOSS_SPEECH_GPU === '1' },
58
+ logger: console,
59
+ opts: { stats: true }
60
+ })
61
+ }
62
+
63
+ function replyVoiceFields() {
64
+ if (!voiceArg) return {}
65
+ const voice = readWavAsFloat32(path.resolve(voiceArg))
66
+ return { replyVoice: voice.samples, replyVoiceSampleRate: voice.sampleRate }
67
+ }
68
+
69
+ function reportStats(stats) {
70
+ if (!stats) return
71
+ console.log(
72
+ `Reply stats: totalTime=${stats.totalTime.toFixed(2)}s, ` +
73
+ `audioDuration=${stats.audioDurationMs}ms, promptTokens=${stats.promptTokens}, ` +
74
+ `replyTokens=${stats.replyTokens}, truncated=${stats.truncated}, ` +
75
+ `backendDevice=${stats.backendDevice}, backendId=${stats.backendId}`
76
+ )
77
+ }
78
+
79
+ async function collectReply(response) {
80
+ const reply = { pcm: [], text: '' }
81
+ await response
82
+ .onUpdate((data) => {
83
+ if (data && data.outputArray) reply.pcm = reply.pcm.concat(Array.from(data.outputArray))
84
+ if (data && typeof data.text === 'string') reply.text += data.text
85
+ })
86
+ .await()
87
+ return reply
88
+ }
89
+
90
+ async function main() {
91
+ setLogger((priority, message) => {
92
+ if (priority > 1) return
93
+ const names = { 0: 'ERROR', 1: 'WARNING', 2: 'INFO', 3: 'DEBUG', 4: 'OFF' }
94
+ const name = names[priority] || 'UNKNOWN'
95
+ console.log(`[${new Date().toISOString()}] [C++ log] [${name}]: ${message}`)
96
+ })
97
+
98
+ const outputFile = path.join(__dirname, 'moss-speech-reply.wav')
99
+ const question = readWavAsFloat32(path.resolve(questionArg))
100
+ const model = buildModel()
101
+
102
+ try {
103
+ console.log('Loading MOSS-Speech model...')
104
+ await model.load()
105
+ console.log('Model loaded.')
106
+
107
+ console.log(`Answering ${questionArg} (${(question.samples.length / question.sampleRate).toFixed(1)} s)`)
108
+ const response = await model.run({
109
+ type: 'text',
110
+ input: '',
111
+ audio: question.samples,
112
+ sampleRate: question.sampleRate,
113
+ textReply,
114
+ ...replyVoiceFields()
115
+ })
116
+ const reply = await collectReply(response)
117
+
118
+ console.log('Reply finished!')
119
+ if (reply.text) console.log(`Reply text: ${reply.text}`)
120
+ reportStats(response.stats)
121
+
122
+ if (reply.pcm.length > 0) {
123
+ createWav(reply.pcm, SPEECH_SAMPLE_RATE, outputFile)
124
+ console.log(`Finished writing to ${outputFile}`)
125
+ }
126
+ } finally {
127
+ await model.unload()
128
+ releaseLogger()
129
+ }
130
+ }
131
+
132
+ main().catch((err) => {
133
+ console.error(err)
134
+ if (global.Bare) global.Bare.exit(1)
135
+ else process.exit(1)
136
+ })
@@ -28,18 +28,41 @@
28
28
  const fs = require('bare-fs')
29
29
  const os = require('bare-os')
30
30
  const path = require('bare-path')
31
- const { spawn, spawnSync } = require('bare-subprocess')
32
31
  const { createWav } = require('./wav-helper')
33
32
 
33
+ const MISSING_SUBPROCESS_WARNING =
34
+ '[pcm-chunk-player] bare-subprocess is not installed, so audio will not play. ' +
35
+ 'Install it for live playback: `npm install bare-subprocess`.'
36
+
37
+ const subprocess = loadSubprocess()
38
+
34
39
  let _seq = 0
35
40
  let _hasFfplay
36
41
  let _hasPlay
37
42
  let _hasAplay
43
+ let _subprocessWarned = false
44
+
45
+ function loadSubprocess () {
46
+ try {
47
+ return require('bare-subprocess')
48
+ } catch {
49
+ return null
50
+ }
51
+ }
52
+
53
+ function hasSubprocess () {
54
+ if (subprocess !== null) return true
55
+ if (!_subprocessWarned) {
56
+ console.warn(MISSING_SUBPROCESS_WARNING)
57
+ _subprocessWarned = true
58
+ }
59
+ return false
60
+ }
38
61
 
39
62
  function syncOk (cmd, args) {
40
63
  try {
41
- const r = spawnSync(cmd, args, { stdio: ['ignore', 'ignore', 'ignore'] })
42
- return (r.status | 0) === 0
64
+ const r = subprocess.spawnSync(cmd, args, { stdio: ['ignore', 'ignore', 'ignore'] })
65
+ return !r.error && r.status === 0
43
66
  } catch {
44
67
  return false
45
68
  }
@@ -64,6 +87,7 @@ function detectAplay () {
64
87
  }
65
88
 
66
89
  function canPlayPcmChunks () {
90
+ if (!hasSubprocess()) return false
67
91
  if (detectFfplay()) return true
68
92
  if (detectPlay()) return true
69
93
  if (detectAplay()) return true
@@ -87,7 +111,7 @@ function unlinkQuiet (p) {
87
111
  function spawnAsync (cmd, args, opts) {
88
112
  return new Promise((resolve, reject) => {
89
113
  try {
90
- const child = spawn(cmd, args, opts)
114
+ const child = subprocess.spawn(cmd, args, opts)
91
115
  child.on('exit', (code) => resolve(code))
92
116
  child.on('error', reject)
93
117
  } catch (err) {
@@ -106,6 +130,7 @@ function spawnAsync (cmd, args, opts) {
106
130
  * `sampleRate` defaults to 24000 (Chatterbox native rate).
107
131
  */
108
132
  function createStreamingPlayer ({ sampleRate = 24000, channels = 1 } = {}) {
133
+ if (!hasSubprocess()) return null
109
134
  // sox `play` is preferred on darwin: on some macOS builds ffplay's
110
135
  // SDL output is silent for raw-piped audio; sox uses CoreAudio
111
136
  // directly and works reliably. (qvac-tts.cpp's README documents
@@ -164,7 +189,7 @@ function tryAplay (sampleRate, channels) {
164
189
  }
165
190
 
166
191
  function spawnStreamingPlayer (cmd, args) {
167
- const child = spawn(cmd, args, { stdio: ['pipe', 'ignore', 'pipe'] })
192
+ const child = subprocess.spawn(cmd, args, { stdio: ['pipe', 'ignore', 'pipe'] })
168
193
  let exited = false
169
194
  let exitResolve
170
195
  const exitPromise = new Promise((resolve) => { exitResolve = resolve })
@@ -255,7 +280,7 @@ function createAfplayFallback (sampleRate) {
255
280
 
256
281
  function playInt16ChunkSync (samples, sampleRate) {
257
282
  const arr = samples instanceof Int16Array ? samples : Int16Array.from(samples)
258
- if (arr.length === 0) return
283
+ if (arr.length === 0 || !hasSubprocess()) return
259
284
 
260
285
  const id = `${Date.now()}-${++_seq}`
261
286
  const tmpDir = os.tmpdir()
@@ -264,14 +289,14 @@ function playInt16ChunkSync (samples, sampleRate) {
264
289
  if (plat === 'darwin') {
265
290
  const tmpWav = path.join(tmpDir, `qvac-tts-stream-${id}.wav`)
266
291
  createWav(Array.from(arr), sampleRate, tmpWav)
267
- spawnSync('afplay', [tmpWav], { stdio: 'ignore' })
292
+ subprocess.spawnSync('afplay', [tmpWav], { stdio: 'ignore' })
268
293
  unlinkQuiet(tmpWav)
269
294
  return
270
295
  }
271
296
  if (detectFfplay()) {
272
297
  const tmpWav = path.join(tmpDir, `qvac-tts-stream-${id}.wav`)
273
298
  createWav(Array.from(arr), sampleRate, tmpWav)
274
- spawnSync(
299
+ subprocess.spawnSync(
275
300
  'ffplay',
276
301
  ['-nodisp', '-autoexit', '-loglevel', 'error', '-i', tmpWav],
277
302
  { stdio: 'ignore' }
@@ -282,7 +307,7 @@ function playInt16ChunkSync (samples, sampleRate) {
282
307
  if (detectAplay()) {
283
308
  const rawPath = path.join(tmpDir, `qvac-tts-stream-${id}.raw`)
284
309
  fs.writeFileSync(rawPath, toInt16Buffer(arr))
285
- spawnSync(
310
+ subprocess.spawnSync(
286
311
  'aplay',
287
312
  ['-q', '-t', 'raw', '-f', 'S16_LE', '-r', String(sampleRate), '-c', '1', rawPath],
288
313
  { stdio: 'ignore' }
@@ -293,7 +318,7 @@ function playInt16ChunkSync (samples, sampleRate) {
293
318
 
294
319
  async function playInt16Chunk (samples, sampleRate) {
295
320
  const arr = samples instanceof Int16Array ? samples : Int16Array.from(samples)
296
- if (arr.length === 0) return
321
+ if (arr.length === 0 || !hasSubprocess()) return
297
322
 
298
323
  const id = `${Date.now()}-${++_seq}`
299
324
  const tmpDir = os.tmpdir()
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type QvacResponse } from "@qvac/infer-base";
2
2
  import * as errorModule from "./lib/error";
3
3
  import { resolveBackendsDir as resolveBackendsDirImpl } from "./lib/backends";
4
- import { assessFit as assessFitImpl, type Audio8FitRequest, type MossFitRequest, type ChatterboxFitRequest, type CosyvoiceFitRequest, type ParlerFitRequest, type SupertonicFitRequest, type TtsFitEngine, type TtsFitRequest, type TtsFitResult, type TtsFitStatus } from "./lib/fit";
4
+ 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";
5
5
  import { type SentenceDelimiterPreset } from "./lib/textStreamAccumulator";
6
6
  declare const ENGINE_CHATTERBOX = "chatterbox";
7
7
  declare const ENGINE_SUPERTONIC = "supertonic";
@@ -9,6 +9,8 @@ declare const ENGINE_COSYVOICE3 = "cosyvoice3";
9
9
  declare const ENGINE_PARLER = "parler";
10
10
  declare const ENGINE_AUDIO8 = "audio8";
11
11
  declare const ENGINE_MOSS = "moss";
12
+ declare const ENGINE_MOSS_SFX = "moss-sfx";
13
+ declare const ENGINE_MOSS_SPEECH = "moss-speech";
12
14
  declare const ENGINE_POCKET = "pocket";
13
15
  declare const COSYVOICE_DIALECTS: {
14
16
  readonly cantonese: "广东话";
@@ -57,7 +59,8 @@ declare const EMOTIONS: readonly ["command", "anger", "narration", "conversation
57
59
  declare const PACES: readonly ["slow", "moderate", "fast"];
58
60
  type Emotion = (typeof EMOTIONS)[number];
59
61
  type Pace = (typeof PACES)[number];
60
- type EngineType = typeof ENGINE_CHATTERBOX | typeof ENGINE_SUPERTONIC | typeof ENGINE_COSYVOICE3 | typeof ENGINE_PARLER | typeof ENGINE_AUDIO8 | typeof ENGINE_MOSS | typeof ENGINE_POCKET;
62
+ declare const MOSS_SPEECH_ROLES: readonly ["system", "user", "assistant"];
63
+ 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;
61
64
  /**
62
65
  * Model file paths for the GGML TTS backend. Engine is auto-detected
63
66
  * from these fields (Chatterbox vs Supertonic) unless overridden via
@@ -120,6 +123,25 @@ interface TTSGgmlFiles {
120
123
  */
121
124
  mossCodecEncoder?: string;
122
125
  mossCodecEncoderPath?: string;
126
+ /**
127
+ * MOSS-SoundEffect GGUF (`moss-sfx-*.gguf`): text encoder, DiT and VAE in
128
+ * one file. Routes to the `moss-sfx` engine. Overrides `modelDir`.
129
+ */
130
+ mossSoundEffect?: string;
131
+ mossSoundEffectPath?: string;
132
+ /**
133
+ * MOSS-Speech language model GGUF (`moss-speech-*.gguf`, e.g.
134
+ * `moss-speech-q8_0.gguf`). Routes to the `moss-speech` engine together
135
+ * with `mossSpeechCodec`. Overrides `modelDir`.
136
+ */
137
+ mossSpeechModel?: string;
138
+ mossSpeechModelPath?: string;
139
+ /**
140
+ * MOSS-Speech codec GGUF (`moss-speech-codec-*.gguf`): speech tokenizer,
141
+ * reply decoder and the default reply voice. Overrides `modelDir`.
142
+ */
143
+ mossSpeechCodec?: string;
144
+ mossSpeechCodecPath?: string;
123
145
  /**
124
146
  * CosyVoice3 model directory holding the sub-model GGUFs
125
147
  * (`cosyvoice3-{llm,flow,hift}-*.gguf`) plus `voice.gguf`, `vocab.json` and
@@ -310,6 +332,66 @@ interface Audio8VoiceFields {
310
332
  /** Audio8: what `referenceAudio` says. Required when cloning. */
311
333
  referenceText?: string;
312
334
  }
335
+ /**
336
+ * MOSS-SoundEffect per-call generation controls (moss-sfx only). Each one is
337
+ * optional; unset `steps` / `guidance` / `shift` use the defaults stored in the
338
+ * model file (100 steps, guidance 4, shift 5).
339
+ */
340
+ interface MossSoundEffectFields {
341
+ /** Length of the sound effect, in (0, 30] seconds, rounded to 0.1 s. Defaults to 10. */
342
+ seconds?: number;
343
+ /** What the sound effect should avoid (classifier-free guidance negative). */
344
+ negativePrompt?: string;
345
+ /** Diffusion steps, 1..1000. More steps cost proportionally more time. */
346
+ steps?: number;
347
+ /** Classifier-free guidance scale, 1..50; 1 skips the negative branch. */
348
+ guidance?: number;
349
+ /** Flow-matching schedule shift, (0, 100]. */
350
+ shift?: number;
351
+ }
352
+ /** Mono PCM accepted by the MOSS-Speech engine: 16-bit integers or floats in [-1, 1]. */
353
+ type MossSpeechPcm = Int16Array | Float32Array;
354
+ /** One conversation turn for the MOSS-Speech engine: text or audio, never both. */
355
+ interface MossSpeechMessage {
356
+ role: (typeof MOSS_SPEECH_ROLES)[number];
357
+ text?: string;
358
+ audio?: MossSpeechPcm;
359
+ /** Sample rate of `audio`, 8000..192000 Hz. */
360
+ sampleRate?: number;
361
+ }
362
+ /**
363
+ * MOSS-Speech per-call fields (moss-speech only). The user turn is `audio`
364
+ * (with `sampleRate`) or the run `input` text; `messages` carries the earlier
365
+ * conversation.
366
+ */
367
+ interface MossSpeechFields {
368
+ /** The user's spoken turn, mono PCM. */
369
+ audio?: MossSpeechPcm;
370
+ /** Sample rate of `audio`, 8000..192000 Hz. */
371
+ sampleRate?: number;
372
+ /** Earlier turns, oldest first; the new user turn is appended after them. */
373
+ messages?: MossSpeechMessage[];
374
+ /** A system turn placed first; replaces the model's default system prompt. */
375
+ systemPrompt?: string;
376
+ /** Reply voice prompt (up to 60 s of mono PCM); the codec's default voice otherwise. */
377
+ replyVoice?: MossSpeechPcm;
378
+ /** Sample rate of `replyVoice`, 8000..192000 Hz. */
379
+ replyVoiceSampleRate?: number;
380
+ /** Reply with text only (no audio); the text comes back as `text`. */
381
+ textReply?: boolean;
382
+ /** Cut the spoken reply after this many seconds (0 = no cut). */
383
+ maxReplySeconds?: number;
384
+ /** Explicit bound on generated rows, 1..4096; omitted uses remaining model context. */
385
+ maxNewTokens?: number;
386
+ /** Greedy decoding instead of sampling. */
387
+ greedy?: boolean;
388
+ /** Sampling temperature, (0, 10] (default 0.7). */
389
+ temperature?: number;
390
+ /** Nucleus sampling, (0, 1] (default 0.95). */
391
+ topP?: number;
392
+ /** Top-k sampling, >= 0 (default 20). */
393
+ topK?: number;
394
+ }
313
395
  /**
314
396
  * CosyVoice3 per-call instruction. Same values as the constructor's
315
397
  * `instruct`; a per-call conditioning control replaces the configured one for
@@ -333,9 +415,10 @@ interface TTSGgmlOptions extends ParlerDescriptionFields, Audio8VoiceFields, TTS
333
415
  /** Chatterbox: directory of baked voice-conditioning tensors. */
334
416
  voiceDir?: string;
335
417
  /**
336
- * RNG seed for Chatterbox CFM/SineGen, Supertonic latent generation, or
337
- * Pocket's portable sampling RNG. Pocket accepts integers from 0 to
338
- * 4294967295 (inclusive).
418
+ * RNG seed for Chatterbox CFM/SineGen, Supertonic latent generation,
419
+ * the MOSS-SoundEffect diffusion noise (0 when unset, so an unseeded prompt
420
+ * repeats its clip), or Pocket's portable sampling RNG. Pocket accepts
421
+ * integers from 0 to 4294967295 (inclusive).
339
422
  */
340
423
  seed?: number;
341
424
  /**
@@ -590,6 +673,8 @@ interface TTSOutputChunk {
590
673
  isLast?: boolean;
591
674
  /** Signed 16-bit mono PCM audio payload. */
592
675
  outputArray: Int16Array;
676
+ /** MOSS-Speech: the reply's text channel (the whole answer with `textReply`). */
677
+ text?: string;
593
678
  /**
594
679
  * Output sample rate. The native engine rate (24000 for Chatterbox,
595
680
  * CosyVoice3 and MOSS; 44100 for Supertonic, Parler, and Audio8), or 48000
@@ -718,7 +803,7 @@ interface RunStreamingOptions extends ParlerDescriptionFields, Audio8VoiceFields
718
803
  }
719
804
  /** Input accepted by `runStreaming`. */
720
805
  type TextStreamInput = string | string[] | Iterable<string> | AsyncIterable<string>;
721
- interface TTSRunInput extends ParlerDescriptionFields, Audio8VoiceFields, TTSConditioningFields, CosyvoiceJobFields {
806
+ interface TTSRunInput extends ParlerDescriptionFields, Audio8VoiceFields, TTSConditioningFields, CosyvoiceJobFields, MossSoundEffectFields, MossSpeechFields {
722
807
  type?: string;
723
808
  input: string;
724
809
  streamOutput?: boolean;
@@ -750,6 +835,8 @@ declare class TTSGgml {
750
835
  static readonly ENGINE_PARLER = "parler";
751
836
  static readonly ENGINE_AUDIO8 = "audio8";
752
837
  static readonly ENGINE_MOSS = "moss";
838
+ static readonly ENGINE_MOSS_SFX = "moss-sfx";
839
+ static readonly ENGINE_MOSS_SPEECH = "moss-speech";
753
840
  static readonly ENGINE_POCKET = "pocket";
754
841
  opts: object;
755
842
  exclusiveRun: boolean;
@@ -829,6 +916,9 @@ declare class TTSGgml {
829
916
  private _mossBackbonePath?;
830
917
  private _mossCodecDecoderPath?;
831
918
  private _mossCodecEncoderPath?;
919
+ private _mossSoundEffectPath?;
920
+ private _mossSpeechModelPath?;
921
+ private _mossSpeechCodecPath?;
832
922
  private _dialogueReferences?;
833
923
  private _durationTokens?;
834
924
  private _referenceText?;
@@ -865,6 +955,10 @@ declare class TTSGgml {
865
955
  */
866
956
  private _assertEngineScopedOptions;
867
957
  private _assertAudio8OptionConsistency;
958
+ private _assertMossSoundEffectOptionConsistency;
959
+ private _assertMossSpeechOptionConsistency;
960
+ private _assertMossSpeechOutputRate;
961
+ private _assertMossSoundEffectOutputRate;
868
962
  private _assertMossOptionConsistency;
869
963
  private _assertNoMossOnlyOptions;
870
964
  private _assertMossDialogueReferences;
@@ -917,6 +1011,18 @@ declare class TTSGgml {
917
1011
  * streaming options. Returns undefined when none are present.
918
1012
  */
919
1013
  private _resolveAudio8JobFields;
1014
+ private _assertNoSpeechFields;
1015
+ private _assertNoOtherEngineFields;
1016
+ /**
1017
+ * Validate the MOSS-Speech call and fold the new user turn (spoken `audio`
1018
+ * or text `input`) and `systemPrompt` into the native `messages` list.
1019
+ */
1020
+ private _resolveSpeechJobFields;
1021
+ /**
1022
+ * Extract + validate the per-call MOSS-SoundEffect controls from a run
1023
+ * input. Returns undefined when none are present.
1024
+ */
1025
+ private _resolveSoundEffectJobFields;
920
1026
  /**
921
1027
  * The per-call fields of whichever engine is loaded, if any are set. Parler
922
1028
  * takes the full description/template surface, Audio8 its voice override,
@@ -969,6 +1075,8 @@ declare class TTSGgml {
969
1075
  private _buildParlerParams;
970
1076
  private _buildAudio8Params;
971
1077
  private _buildMossParams;
1078
+ private _buildMossSoundEffectParams;
1079
+ private _buildMossSpeechParams;
972
1080
  /** The knobs every engine in SAMPLING_ENGINES reads. */
973
1081
  private _assignSamplingParams;
974
1082
  /**
@@ -1072,6 +1180,7 @@ type NamespaceParlerFit = ParlerFitRequest;
1072
1180
  type NamespaceChatterboxFit = ChatterboxFitRequest;
1073
1181
  type NamespaceAudio8Fit = Audio8FitRequest;
1074
1182
  type NamespaceMossFit = MossFitRequest;
1183
+ type NamespaceMossSoundEffectFit = MossSoundEffectFitRequest;
1075
1184
  type NamespaceCosyvoiceFit = CosyvoiceFitRequest;
1076
1185
  declare namespace TTSGgml {
1077
1186
  export import QvacErrorAddonTTSGgml = errorModule.QvacErrorAddonTTSGgml;
@@ -1100,6 +1209,7 @@ declare namespace TTSGgml {
1100
1209
  type ChatterboxFitRequest = NamespaceChatterboxFit;
1101
1210
  type Audio8FitRequest = NamespaceAudio8Fit;
1102
1211
  type MossFitRequest = NamespaceMossFit;
1212
+ type MossSoundEffectFitRequest = NamespaceMossSoundEffectFit;
1103
1213
  type CosyvoiceFitRequest = NamespaceCosyvoiceFit;
1104
1214
  const resolveBackendsDir: typeof resolveBackendsDirImpl;
1105
1215
  const assessFit: typeof assessFitImpl;