echogarden 0.11.11 → 0.11.13

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 (130) hide show
  1. package/data/schemas/options.json +16 -0
  2. package/dist/alignment/DTWMfccSequenceAlignment.js +2 -2
  3. package/dist/alignment/DTWMfccSequenceAlignment.js.map +1 -1
  4. package/dist/alignment/SpeechAlignment.d.ts +1 -1
  5. package/dist/alignment/SpeechAlignment.js +15 -3
  6. package/dist/alignment/SpeechAlignment.js.map +1 -1
  7. package/dist/api/Alignment.js +3 -3
  8. package/dist/api/Alignment.js.map +1 -1
  9. package/dist/api/LanguageDetection.js +1 -1
  10. package/dist/api/LanguageDetection.js.map +1 -1
  11. package/dist/api/Recognition.js +3 -3
  12. package/dist/api/Recognition.js.map +1 -1
  13. package/dist/api/Synthesis.js +7 -6
  14. package/dist/api/Synthesis.js.map +1 -1
  15. package/dist/api/Translation.js +3 -3
  16. package/dist/api/Translation.js.map +1 -1
  17. package/dist/audio/AudioUtilities.d.ts +5 -2
  18. package/dist/audio/AudioUtilities.js +50 -22
  19. package/dist/audio/AudioUtilities.js.map +1 -1
  20. package/dist/cli/CLI.js +2 -2
  21. package/dist/cli/CLI.js.map +1 -1
  22. package/dist/dsp/SpeexResampler.js +1 -1
  23. package/dist/recognition/WhisperSTT.js +2 -2
  24. package/dist/recognition/WhisperSTT.js.map +1 -1
  25. package/dist/subtitles/Subtitles.d.ts +10 -7
  26. package/dist/subtitles/Subtitles.js +268 -207
  27. package/dist/subtitles/Subtitles.js.map +1 -1
  28. package/docs/Options.md +4 -2
  29. package/package.json +12 -11
  30. package/src/alignment/DTWMfccSequenceAlignment.ts +43 -0
  31. package/src/alignment/DTWSequenceAlignment.ts +121 -0
  32. package/src/alignment/DTWSequenceAlignmentWindowed.ts +210 -0
  33. package/src/alignment/LevenshteinSequenceAlignment.ts +126 -0
  34. package/src/alignment/SpeechAlignment.ts +488 -0
  35. package/src/api/API.ts +12 -0
  36. package/src/api/APIOptions.ts +15 -0
  37. package/src/api/Alignment.ts +329 -0
  38. package/src/api/Common.ts +16 -0
  39. package/src/api/Denoising.ts +120 -0
  40. package/src/api/LanguageDetection.ts +286 -0
  41. package/src/api/Recognition.ts +344 -0
  42. package/src/api/Synthesis.ts +1735 -0
  43. package/src/api/Translation.ts +143 -0
  44. package/src/api/Vad.ts +172 -0
  45. package/src/audio/AudioBufferConversion.ts +248 -0
  46. package/src/audio/AudioPlayer.ts +358 -0
  47. package/src/audio/AudioRecorder.ts +91 -0
  48. package/src/audio/AudioUtilities.ts +392 -0
  49. package/src/audio/SoxPath.ts +24 -0
  50. package/src/cli/CLI.ts +1360 -0
  51. package/src/cli/CLIConfigFile.ts +91 -0
  52. package/src/cli/CLILauncher.ts +26 -0
  53. package/src/cli/CLIOptionsSchema.ts +54 -0
  54. package/src/cli/CLIParser.ts +41 -0
  55. package/src/cli/CLIStarter.ts +40 -0
  56. package/src/codecs/FFMpegTranscoder.ts +214 -0
  57. package/src/codecs/TIMITCodec.ts +17 -0
  58. package/src/codecs/WaveCodec.ts +260 -0
  59. package/src/denoising/RNNoise.ts +95 -0
  60. package/src/dsp/BiquadFilter.ts +488 -0
  61. package/src/dsp/FFT.ts +187 -0
  62. package/src/dsp/MFCC.ts +227 -0
  63. package/src/dsp/MelSpectogram.ts +145 -0
  64. package/src/dsp/Rubberband.ts +249 -0
  65. package/src/dsp/Sonic.ts +59 -0
  66. package/src/dsp/SpeexResampler.ts +79 -0
  67. package/src/math/VectorMath.ts +812 -0
  68. package/src/nlp/ChineseSegmentation.ts +68 -0
  69. package/src/nlp/CompromiseNLP.ts +113 -0
  70. package/src/nlp/EspeakPhonemizer.ts +168 -0
  71. package/src/nlp/IPA.ts +139 -0
  72. package/src/nlp/JapaneseSegmentation.ts +53 -0
  73. package/src/nlp/Lexicon.ts +119 -0
  74. package/src/nlp/PhoneConversion.ts +508 -0
  75. package/src/nlp/Segmentation.ts +237 -0
  76. package/src/nlp/TextNormalizer.ts +160 -0
  77. package/src/recognition/AmazonTranscribeSTT.ts +112 -0
  78. package/src/recognition/AzureCognitiveServicesSTT.ts +76 -0
  79. package/src/recognition/GoogleCloudSTT.ts +92 -0
  80. package/src/recognition/SileroSTT.ts +173 -0
  81. package/src/recognition/VoskSTT.ts +112 -0
  82. package/src/recognition/WhisperSTT.ts +1518 -0
  83. package/src/server/Client.ts +297 -0
  84. package/src/server/Server.ts +178 -0
  85. package/src/server/ServerStarter.ts +12 -0
  86. package/src/server/Worker.ts +400 -0
  87. package/src/server/WorkerStarter.ts +38 -0
  88. package/src/speech-language-detection/SileroLanguageDetection.ts +105 -0
  89. package/src/subtitles/Subtitles.ts +478 -0
  90. package/src/synthesis/AwsPollyTTS.ts +78 -0
  91. package/src/synthesis/AzureCognitiveServicesTTS.ts +146 -0
  92. package/src/synthesis/CoquiServerTTS.ts +29 -0
  93. package/src/synthesis/ElevenLabsTTS.ts +104 -0
  94. package/src/synthesis/EspeakTTS.ts +552 -0
  95. package/src/synthesis/FliteTTS.ts +387 -0
  96. package/src/synthesis/GoogleCloudTTS.ts +112 -0
  97. package/src/synthesis/GoogleTranslateTTS.ts +210 -0
  98. package/src/synthesis/MicrosoftEdgeTTS.ts +298 -0
  99. package/src/synthesis/SamTTS.ts +30 -0
  100. package/src/synthesis/SapiTTS.ts +222 -0
  101. package/src/synthesis/StreamlabsPollyTTS.ts +114 -0
  102. package/src/synthesis/SvoxPicoTTS.ts +318 -0
  103. package/src/synthesis/VitsTTS.ts +734 -0
  104. package/src/tests/Test.ts +24 -0
  105. package/src/text-language-detection/FastTextLanguageDetection.ts +53 -0
  106. package/src/text-language-detection/TinyLDLanguageDetection.ts +16 -0
  107. package/src/typings/Fillers.d.ts +41 -0
  108. package/src/utilities/BinaryArrayConversion.ts +159 -0
  109. package/src/utilities/Compression.ts +91 -0
  110. package/src/utilities/FileDownloader.ts +201 -0
  111. package/src/utilities/FileSystem.ts +265 -0
  112. package/src/utilities/Hashing.ts +230 -0
  113. package/src/utilities/Locale.ts +119 -0
  114. package/src/utilities/Logger.ts +72 -0
  115. package/src/utilities/NdArrayUtilities.ts +31 -0
  116. package/src/utilities/ObjectUtilities.ts +169 -0
  117. package/src/utilities/OpenPromise.ts +13 -0
  118. package/src/utilities/PackageManager.ts +97 -0
  119. package/src/utilities/Queue.ts +17 -0
  120. package/src/utilities/RandomGenerator.ts +237 -0
  121. package/src/utilities/SignalChannel.ts +22 -0
  122. package/src/utilities/TarballMaker.ts +68 -0
  123. package/src/utilities/Timeline.ts +231 -0
  124. package/src/utilities/Timer.ts +93 -0
  125. package/src/utilities/Utilities.ts +574 -0
  126. package/src/utilities/WasmMemoryManager.ts +516 -0
  127. package/src/utilities/WebReader.ts +55 -0
  128. package/src/utilities/WikipediaReader.ts +41 -0
  129. package/src/voice-activity-detection/SileroVAD.ts +86 -0
  130. package/src/voice-activity-detection/WebRtcVAD.ts +76 -0
@@ -0,0 +1,734 @@
1
+ import type { InferenceSession } from 'onnxruntime-node'
2
+ import { SynthesisVoice } from '../api/API.js'
3
+ import { Logger } from "../utilities/Logger.js"
4
+ import { RawAudio, getEmptyRawAudio, getRawAudioDuration } from "../audio/AudioUtilities.js"
5
+ import { Lexicon } from "../nlp/Lexicon.js"
6
+ import { Timeline } from "../utilities/Timeline.js"
7
+ import { readAndParseJsonFile, readdir } from "../utilities/FileSystem.js"
8
+ import path from 'node:path'
9
+ import { EspeakOptions, defaultEspeakOptions } from '../synthesis/EspeakTTS.js'
10
+
11
+ const cachedInstanceLookup = new Map<string, VitsTTS>()
12
+
13
+ export async function synthesizeSentence(text: string, voiceName: string, modelPath: string, lengthScale: number, speakerId = 0, lexicons?: Lexicon[]) {
14
+ const cacheLookupKey = modelPath
15
+
16
+ let vitsTTS: VitsTTS | undefined = cachedInstanceLookup.get(cacheLookupKey)
17
+
18
+ if (!vitsTTS) {
19
+ vitsTTS = new VitsTTS(voiceName, modelPath)
20
+ await vitsTTS.initialize()
21
+
22
+ cachedInstanceLookup.clear()
23
+ cachedInstanceLookup.set(cacheLookupKey, vitsTTS)
24
+ }
25
+
26
+ const result = await vitsTTS.synthesizeSentence(text, lengthScale, speakerId, lexicons)
27
+
28
+ return result
29
+ }
30
+
31
+ export class VitsTTS {
32
+ voiceName: string
33
+ modelPath: string
34
+
35
+ modelSession?: InferenceSession
36
+ metadata?: any
37
+ phonemeMap?: Map<string, number[]>
38
+
39
+ constructor(voiceName: string, modelPath: string) {
40
+ this.voiceName = voiceName
41
+ this.modelPath = modelPath
42
+ }
43
+
44
+ async initialize() {
45
+ const logger = new Logger()
46
+ await logger.startAsync("Initialize VITS ONNX synthesis model")
47
+
48
+ const onnxOptions: InferenceSession.SessionOptions = {
49
+ logSeverityLevel: 3
50
+ }
51
+
52
+ const { default: Onnx } = await import('onnxruntime-node')
53
+
54
+ const filesInModelPath = await readdir(this.modelPath)
55
+ const onnxModelFilename = filesInModelPath.find(filename => filename.endsWith(".onnx"))
56
+
57
+ if (!onnxModelFilename) {
58
+ throw new Error(`Couldn't file any ONNX model file in ${this.modelPath}`)
59
+ }
60
+
61
+ const onnxModelFilepath = path.join(this.modelPath, onnxModelFilename)
62
+
63
+ this.modelSession = await Onnx.InferenceSession.create(onnxModelFilepath, onnxOptions)
64
+ this.metadata = await readAndParseJsonFile(`${onnxModelFilepath}.json`)
65
+
66
+ this.phonemeMap = new Map<string, number[]>()
67
+
68
+ for (const key in this.metadata.phoneme_id_map) {
69
+ this.phonemeMap.set(key, this.metadata.phoneme_id_map[key])
70
+ }
71
+
72
+ logger.end()
73
+ }
74
+
75
+ async synthesizeSentence(sentence: string, lengthScale: number, speakerId = 0, lexicons?: Lexicon[]) {
76
+ const logger = new Logger()
77
+
78
+ if (!this.modelSession) {
79
+ throw new Error("Model has not been initialized")
80
+ }
81
+
82
+ await logger.startAsync("Prepare for synthesis")
83
+
84
+ const metadata = this.metadata
85
+ const phonemeMap = this.phonemeMap!
86
+ const espeakVoice = metadata.espeak.voice as string
87
+ const languageCode = espeakVoice
88
+ const outputSampleRate = metadata.audio.sample_rate
89
+ const baseLengthScale = metadata.inference.length_scale || 1.0
90
+
91
+ lengthScale *= baseLengthScale
92
+
93
+ sentence = //simplifyPunctuationCharacters(sentence.trim())
94
+ sentence
95
+ .replaceAll("(", ", ")
96
+ .replaceAll(")", ", ")
97
+ .replaceAll("—", ", ")
98
+
99
+ const Espeak = await import("../synthesis/EspeakTTS.js")
100
+
101
+ logger.end()
102
+
103
+ const espeakOptions: EspeakOptions = { ...defaultEspeakOptions, voice: espeakVoice, useKlatt: false }
104
+ const { referenceSynthesizedAudio, referenceTimeline, fragments, phonemizedFragmentsSubstitutions, phonemizedSentence } = await Espeak.preprocessAndSynthesize(sentence, languageCode, espeakOptions, lexicons)
105
+
106
+ if (phonemizedSentence.length == 0) {
107
+ logger.end()
108
+
109
+ return {
110
+ rawAudio: getEmptyRawAudio(1, outputSampleRate),
111
+ timeline: [],
112
+ referenceSynthesizedAudio: getEmptyRawAudio(1, outputSampleRate),
113
+ referenceTimeline: [] as Timeline
114
+ }
115
+ }
116
+
117
+ await logger.startAsync("Encode phonemes to identifiers")
118
+
119
+ const clauseEndBreaker = ","
120
+ let sentenceEndBreaker = "."
121
+
122
+ if (sentence.endsWith("?") || sentence.endsWith("?\"")) {
123
+ sentenceEndBreaker = "?"
124
+ } else if (sentence.endsWith("!") || sentence.endsWith("!\"")) {
125
+ sentenceEndBreaker = "!"
126
+ }
127
+
128
+ const phonemeCharacterSeparatorId = phonemeMap.get("_")!
129
+ const wordSeparatorId = phonemeMap.get(" ")!
130
+ const startId = phonemeMap.get("^")!
131
+ const endId = phonemeMap.get("$")!
132
+
133
+ const clauseEndBreakerId = phonemeMap.get(clauseEndBreaker)!
134
+ const sentenceEndBreakerId = phonemeMap.get(sentenceEndBreaker)!
135
+
136
+ const ids: number[] = [...startId, ...phonemeCharacterSeparatorId]
137
+
138
+ for (let clauseIndex = 0; clauseIndex < phonemizedSentence.length; clauseIndex++) {
139
+ const clause = phonemizedSentence[clauseIndex]
140
+
141
+ for (const word of clause) {
142
+ for (const phoneme of word) {
143
+ for (const phonemeCharacter of phoneme) {
144
+ const id = phonemeMap.get(phonemeCharacter)
145
+
146
+ if (id == null) {
147
+ //logger.log(`No id found for subphoneme "${char}"`)
148
+ continue
149
+ }
150
+
151
+ ids.push(...id, ...phonemeCharacterSeparatorId)
152
+ }
153
+ }
154
+
155
+ if (clauseIndex < phonemizedSentence.length - 1) {
156
+ ids.push(...wordSeparatorId, ...phonemeCharacterSeparatorId)
157
+ }
158
+ }
159
+
160
+ if (clauseIndex < phonemizedSentence.length - 1) {
161
+ ids.push(...clauseEndBreakerId, ...phonemeCharacterSeparatorId)
162
+ }
163
+ }
164
+
165
+ ids.push(...sentenceEndBreakerId, ...phonemeCharacterSeparatorId, ...endId)
166
+
167
+ //logger.log(ids)
168
+
169
+ const bigIntIds = new BigInt64Array(ids.map(id => BigInt(id)))
170
+ const idLengths = new BigInt64Array([BigInt(bigIntIds.length)])
171
+
172
+ await logger.startAsync("Generate audio using synthesis model")
173
+
174
+ const { default: Onnx } = await import('onnxruntime-node')
175
+
176
+ const inputTensor = new Onnx.Tensor('int64', bigIntIds, [1, bigIntIds.length])
177
+ const inputLengthsTensor = new Onnx.Tensor('int64', idLengths, [1])
178
+ const scalesTensor = new Onnx.Tensor('float32', [metadata.inference.noise_scale, lengthScale, metadata.inference.noise_w], [3])
179
+ const speakerIdTensor = new Onnx.Tensor('int64', new BigInt64Array([BigInt(speakerId)]), [1])
180
+
181
+ const modelInputs = { input: inputTensor, input_lengths: inputLengthsTensor, scales: scalesTensor, sid: speakerIdTensor }
182
+
183
+ const modelResults = await this.modelSession.run(modelInputs)
184
+ const modelOutput = modelResults["output"]
185
+
186
+ const modelOutputAudioSamples = modelOutput['data'] as Float32Array
187
+
188
+ const synthesizedAudio: RawAudio = { audioChannels: [modelOutputAudioSamples], sampleRate: outputSampleRate }
189
+
190
+ await logger.startAsync("Align with reference synthesized audio")
191
+
192
+ const { alignUsingDtw } = await import("../alignment/SpeechAlignment.js")
193
+
194
+ const referenceWordTimeline = referenceTimeline.flatMap(clause => clause.timeline!)
195
+
196
+ const dtwWindowDuration = Math.max(5, Math.ceil(0.2 * getRawAudioDuration(synthesizedAudio)))
197
+ const mappedTimeline = await alignUsingDtw(synthesizedAudio, referenceSynthesizedAudio, referenceWordTimeline, ['high'], [dtwWindowDuration])
198
+
199
+ logger.end()
200
+
201
+ return { rawAudio: synthesizedAudio, timeline: mappedTimeline, referenceSynthesizedAudio, referenceTimeline }
202
+ }
203
+ }
204
+
205
+ export const voiceList: SynthesisVoice[] = [
206
+ {
207
+ name: "ca_ES-upc_ona-x_low",
208
+ languages: ["ca-ES", "ca"],
209
+ gender: "female",
210
+ },
211
+ {
212
+ name: "ca_ES-upc_ona-medium",
213
+ languages: ["ca-ES", "ca"],
214
+ gender: "female",
215
+ },
216
+ {
217
+ name: "ca_ES-upc_pau-x_low",
218
+ languages: ["ca-ES", "ca"],
219
+ gender: "male",
220
+ },
221
+
222
+ {
223
+ name: "cs_CZ-jirka-medium",
224
+ languages: ["cs-CZ", "cs"],
225
+ gender: "male",
226
+ },
227
+
228
+ {
229
+ name: "da_DK-nst_talesyntese-medium",
230
+ languages: ["da-DK", "da"],
231
+ gender: "male",
232
+ },
233
+
234
+ {
235
+ name: "de_DE-thorsten-low",
236
+ languages: ["de-DE", "de"],
237
+ gender: "male",
238
+ },
239
+ {
240
+ name: "de_DE-thorsten-medium",
241
+ languages: ["de-DE", "de"],
242
+ gender: "male",
243
+ },
244
+ {
245
+ name: "de_DE-thorsten_emotional-medium",
246
+ languages: ["de-DE", "de"],
247
+ gender: "male",
248
+ speakerCount: 8
249
+ },
250
+ {
251
+ name: "de_DE-thorsten-high",
252
+ languages: ["de-DE", "de"],
253
+ gender: "male",
254
+ },
255
+ {
256
+ name: "de_DE-eva_k-x_low",
257
+ languages: ["de-DE", "de"],
258
+ gender: "female",
259
+ },
260
+ {
261
+ name: "de_DE-ramona-low",
262
+ languages: ["de-DE", "de"],
263
+ gender: "female",
264
+ },
265
+ {
266
+ name: "de_DE-pavoque-low",
267
+ languages: ["de-DE", "de"],
268
+ gender: "male",
269
+ },
270
+ {
271
+ name: "de_DE-kerstin-low",
272
+ languages: ["de-DE", "de"],
273
+ gender: "female",
274
+ },
275
+ {
276
+ name: "de_DE-karlsson-low",
277
+ languages: ["de-DE", "de"],
278
+ gender: "male",
279
+ },
280
+
281
+ {
282
+ name: "el_GR-rapunzelina-low",
283
+ languages: ["el-GR", "el"],
284
+ gender: "female",
285
+ },
286
+
287
+ {
288
+ name: "en_GB-alan-low",
289
+ languages: ["en-GB", "en"],
290
+ gender: "male",
291
+ },
292
+ {
293
+ name: "en_GB-alan-medium",
294
+ languages: ["en-GB", "en"],
295
+ gender: "male",
296
+ },
297
+ {
298
+ name: "en_GB-semaine-medium",
299
+ languages: ["en-GB", "en"],
300
+ gender: "unknown",
301
+ speakerCount: 4
302
+ },
303
+ {
304
+ name: "en_GB-danny-low",
305
+ languages: ["en-GB", "en"],
306
+ gender: "male",
307
+ },
308
+ {
309
+ name: "en_GB-alba-medium",
310
+ languages: ["en-GB", "en"],
311
+ gender: "female",
312
+ },
313
+ {
314
+ name: "en_GB-aru-medium",
315
+ languages: ["en-GB", "en"],
316
+ gender: "unknown",
317
+ speakerCount: 12,
318
+ },
319
+ {
320
+ name: "en_GB-southern_english_female-low",
321
+ languages: ["en-GB", "en"],
322
+ gender: "female",
323
+ },
324
+ {
325
+ name: "en_GB-northern_english_male-medium",
326
+ languages: ["en-GB", "en"],
327
+ gender: "male",
328
+ },
329
+ {
330
+ name: "en_GB-vctk-medium",
331
+ languages: ["en-GB", "en"],
332
+ gender: "unknown",
333
+ speakerCount: 109,
334
+ },
335
+ {
336
+ name: "en_GB-jenny_dioco-medium",
337
+ languages: ["en-GB", "en"],
338
+ gender: "female",
339
+ },
340
+
341
+ {
342
+ name: "en_US-amy-low",
343
+ languages: ["en-US", "en"],
344
+ gender: "female",
345
+ },
346
+ {
347
+ name: "en_US-amy-medium",
348
+ languages: ["en-US", "en"],
349
+ gender: "female",
350
+ },
351
+ {
352
+ name: "en_US-kathleen-low",
353
+ languages: ["en-US", "en"],
354
+ gender: "female",
355
+ },
356
+ {
357
+ name: "en_US-lessac-low",
358
+ languages: ["en-US", "en"],
359
+ gender: "female",
360
+ },
361
+ {
362
+ name: "en_US-lessac-medium",
363
+ languages: ["en-US", "en"],
364
+ gender: "female",
365
+ },
366
+ {
367
+ name: "en_US-lessac-high",
368
+ languages: ["en-US", "en"],
369
+ gender: "female",
370
+ },
371
+ {
372
+ name: "en_US-libritts-high",
373
+ languages: ["en-US", "en"],
374
+ gender: "unknown",
375
+ speakerCount: 904,
376
+ },
377
+ {
378
+ name: "en_US-ryan-low",
379
+ languages: ["en-US", "en"],
380
+ gender: "male",
381
+ },
382
+ {
383
+ name: "en_US-ryan-medium",
384
+ languages: ["en-US", "en"],
385
+ gender: "male",
386
+ },
387
+ {
388
+ name: "en_US-ryan-high",
389
+ languages: ["en-US", "en"],
390
+ gender: "male",
391
+ },
392
+ {
393
+ name: "en_US-joe-medium",
394
+ languages: ["en-US", "en"],
395
+ gender: "male",
396
+ },
397
+ {
398
+ name: "en_US-kusal-medium",
399
+ languages: ["en-US", "en"],
400
+ gender: "male",
401
+ },
402
+ {
403
+ name: "en_US-arctic-medium",
404
+ languages: ["en-US", "en"],
405
+ gender: "unknown",
406
+ speakerCount: 18
407
+ },
408
+ {
409
+ name: "en_US-l2arctic-medium",
410
+ languages: ["en-US", "en"],
411
+ gender: "unknown",
412
+ speakerCount: 24
413
+ },
414
+
415
+ {
416
+ name: "es_ES-carlfm-x_low",
417
+ languages: ["es-ES", "es"],
418
+ gender: "male",
419
+ },
420
+ {
421
+ name: "es_ES-sharvard-medium",
422
+ languages: ["es-ES", "es"],
423
+ gender: "unknown",
424
+ speakerCount: 2
425
+ },
426
+ {
427
+ name: "es_ES-davefx-medium",
428
+ languages: ["es-ES", "es"],
429
+ gender: "male",
430
+ },
431
+ {
432
+ name: "es_ES-mls_9972-low",
433
+ languages: ["es-ES", "es"],
434
+ gender: "male",
435
+ },
436
+ {
437
+ name: "es_ES-mls_10246-low",
438
+ languages: ["es-ES", "es"],
439
+ gender: "male",
440
+ },
441
+
442
+ {
443
+ name: "es_MX-ald-medium",
444
+ languages: ["es-MX", "es"],
445
+ gender: "male",
446
+ },
447
+
448
+ {
449
+ name: "fi_FI-harri-low",
450
+ languages: ["fi-FI", "fi"],
451
+ gender: "female",
452
+ },
453
+ {
454
+ name: "fi_FI-harri-medium",
455
+ languages: ["fi-FI", "fi"],
456
+ gender: "female",
457
+ },
458
+
459
+ {
460
+ name: "fr_FR-siwis-low",
461
+ languages: ["fr-FR", "fr"],
462
+ gender: "female",
463
+ },
464
+ {
465
+ name: "fr_FR-siwis-medium",
466
+ languages: ["fr-FR", "fr"],
467
+ gender: "female",
468
+ },
469
+ {
470
+ name: "fr_FR-mls_1840-low",
471
+ languages: ["fr-FR", "fr"],
472
+ gender: "male",
473
+ },
474
+ {
475
+ name: "fr_FR-gilles-low",
476
+ languages: ["fr-FR", "fr"],
477
+ gender: "male",
478
+ },
479
+ {
480
+ name: "fr_FR-upmc-medium",
481
+ languages: ["fr-FR", "fr"],
482
+ gender: "unknown",
483
+ speakerCount: 2
484
+ },
485
+
486
+ {
487
+ name: "hu_HU-anna-medium",
488
+ languages: ["hu-HU", "hu"],
489
+ gender: "female",
490
+ },
491
+
492
+ {
493
+ name: "is_IS-ugla-medium",
494
+ languages: ["is-IS", "is"],
495
+ gender: "female",
496
+ },
497
+ {
498
+ name: "is_IS-steinn-medium",
499
+ languages: ["is-IS", "is"],
500
+ gender: "male",
501
+ },
502
+ {
503
+ name: "is_IS-salka-medium",
504
+ languages: ["is-IS", "is"],
505
+ gender: "female",
506
+ },
507
+ {
508
+ name: "is_IS-bui-medium",
509
+ languages: ["is-IS", "is"],
510
+ gender: "male",
511
+ },
512
+
513
+ {
514
+ name: "it_IT-riccardo-x_low",
515
+ languages: ["it-IT", "it"],
516
+ gender: "male",
517
+ },
518
+
519
+ {
520
+ name: "ka_GE-natia-medium",
521
+ languages: ["ka-GE", "ka"],
522
+ gender: "female",
523
+ },
524
+
525
+ {
526
+ name: "kk_KZ-iseke-x_low",
527
+ languages: ["kk-KZ", "kk"],
528
+ gender: "male",
529
+ },
530
+ {
531
+ name: "kk_KZ-raya-x_low",
532
+ languages: ["kk-KZ", "kk"],
533
+ gender: "male",
534
+ },
535
+ {
536
+ name: "kk_KZ-issai-high",
537
+ languages: ["kk-KZ", "kk"],
538
+ gender: "unknown",
539
+ speakerCount: 6,
540
+ },
541
+
542
+ {
543
+ name: "lb_LU-marylux-medium",
544
+ languages: ["lb-LU", "lb"],
545
+ gender: "female",
546
+ },
547
+
548
+ {
549
+ name: "ne_NP-google-medium",
550
+ languages: ["ne-NP", "ne"],
551
+ gender: "female",
552
+ speakerCount: 18,
553
+ },
554
+ {
555
+ name: "ne_NP-google-x_low",
556
+ languages: ["ne-NP", "ne"],
557
+ gender: "female",
558
+ speakerCount: 18,
559
+ },
560
+
561
+ {
562
+ name: "nl_NL-mls_5809-low",
563
+ languages: ["nl-NL", "nl"],
564
+ gender: "female",
565
+ },
566
+ {
567
+ name: "nl_NL-mls_7432-low",
568
+ languages: ["nl-NL", "nl"],
569
+ gender: "female",
570
+ },
571
+
572
+ {
573
+ name: "nl_BE-nathalie-x_low",
574
+ languages: ["nl-BE", "nl"],
575
+ gender: "female",
576
+ },
577
+ {
578
+ name: "nl_BE-nathalie-medium",
579
+ languages: ["nl-BE", "nl"],
580
+ gender: "female",
581
+ },
582
+ {
583
+ name: "nl_BE-rdh-medium",
584
+ languages: ["nl-BE", "nl"],
585
+ gender: "male",
586
+ },
587
+ {
588
+ name: "nl_BE-rdh-x_low",
589
+ languages: ["nl-BE", "nl"],
590
+ gender: "male",
591
+ },
592
+
593
+
594
+ {
595
+ name: "no_NO-talesyntese-medium",
596
+ languages: ["no-NO", "no"],
597
+ gender: "male",
598
+ },
599
+
600
+ {
601
+ name: "pl_PL-mls_6892-low",
602
+ languages: ["pl-PL", "pl"],
603
+ gender: "male",
604
+ },
605
+ {
606
+ name: "pl_PL-darkman-medium",
607
+ languages: ["pl-PL", "pl"],
608
+ gender: "male",
609
+ },
610
+ {
611
+ name: "pl_PL-gosia-medium",
612
+ languages: ["pl-PL", "pl"],
613
+ gender: "female",
614
+ },
615
+
616
+ {
617
+ name: "pt_BR-edresson-low",
618
+ languages: ["pt-BR", "pt"],
619
+ gender: "male",
620
+ },
621
+ {
622
+ name: "pt_BR-faber-medium",
623
+ languages: ["pt-BR", "pt"],
624
+ gender: "male",
625
+ },
626
+
627
+ {
628
+ name: "pt_PT-tugao-medium",
629
+ languages: ["pt-PT", "pt"],
630
+ gender: "male",
631
+ },
632
+
633
+ {
634
+ name: "ro_RO-mihai-medium",
635
+ languages: ["ro-RO", "ro"],
636
+ gender: "male",
637
+ },
638
+
639
+ {
640
+ name: "ru_RU-ruslan-medium",
641
+ languages: ["ru-RU", "ru"],
642
+ gender: "male",
643
+ },
644
+ {
645
+ name: "ru_RU-irinia-medium",
646
+ languages: ["ru-RU", "ru"],
647
+ gender: "female",
648
+ },
649
+ {
650
+ name: "ru_RU-denis-medium",
651
+ languages: ["ru-RU", "ru"],
652
+ gender: "male",
653
+ },
654
+ {
655
+ name: "ru_RU-dmitri-medium",
656
+ languages: ["ru-RU", "ru"],
657
+ gender: "male",
658
+ },
659
+
660
+ {
661
+ name: "sk_SK-lili-medium",
662
+ languages: ["sk-SK", "sk"],
663
+ gender: "female",
664
+ },
665
+
666
+ {
667
+ name: "sr_RS-serbski_institut-medium",
668
+ languages: ["sr-RS", "sr"],
669
+ gender: "male",
670
+ speakerCount: 2
671
+ },
672
+
673
+ {
674
+ name: "sv_SE-nst-medium",
675
+ languages: ["sv-SE", "sv"],
676
+ gender: "male",
677
+ },
678
+
679
+ {
680
+ name: "sw_CD-lanfrica-medium",
681
+ languages: ["sw-CD", "sw"],
682
+ gender: "male",
683
+ },
684
+
685
+ {
686
+ name: "tr_TR-dfki-medium",
687
+ languages: ["tr-TR", "tr"],
688
+ gender: "male",
689
+ },
690
+ {
691
+ name: "tr_TR-fahrettin-medium",
692
+ languages: ["tr-TR", "tr"],
693
+ gender: "male",
694
+ },
695
+
696
+ {
697
+ name: "uk_UA-lada-x_low",
698
+ languages: ["uk-UA", "uk"],
699
+ gender: "female",
700
+ },
701
+ {
702
+ name: "uk_UA-ukrainian_tts-medium",
703
+ languages: ["uk-UA", "uk"],
704
+ gender: "unknown",
705
+ speakerCount: 3,
706
+ },
707
+ {
708
+ name: "vi_VN-vivos-x_low",
709
+ languages: ["vi-VN", "vi"],
710
+ gender: "unknown",
711
+ speakerCount: 65,
712
+ },
713
+ {
714
+ name: "vi_VN-25hours-single-low",
715
+ languages: ["vi-VN", "vi"],
716
+ gender: "female",
717
+ },
718
+ {
719
+ name: "vi_VN-vais1000-medium",
720
+ languages: ["vi-VN", "vi"],
721
+ gender: "female",
722
+ },
723
+
724
+ {
725
+ name: "zh_CN-huayan-x_low",
726
+ languages: ["zh-CN", "zh"],
727
+ gender: "female",
728
+ },
729
+ {
730
+ name: "zh_CN-huayan-medium",
731
+ languages: ["zh-CN", "zh"],
732
+ gender: "female",
733
+ },
734
+ ]