echogarden 1.6.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/schemas/options.json +50 -12
- package/dist/api/Alignment.js +2 -2
- package/dist/api/Alignment.js.map +1 -1
- package/dist/api/Denoising.js +5 -4
- package/dist/api/Denoising.js.map +1 -1
- package/dist/api/Recognition.js +2 -2
- package/dist/api/Recognition.js.map +1 -1
- package/dist/api/SourceSeparation.d.ts +2 -5
- package/dist/api/SourceSeparation.js +14 -13
- package/dist/api/SourceSeparation.js.map +1 -1
- package/dist/api/SpeechLanguageDetection.js +2 -2
- package/dist/api/SpeechLanguageDetection.js.map +1 -1
- package/dist/api/SpeechTranslation.js +2 -2
- package/dist/api/SpeechTranslation.js.map +1 -1
- package/dist/api/Synthesis.js +8 -6
- package/dist/api/Synthesis.js.map +1 -1
- package/dist/api/TextTranslation.d.ts +3 -1
- package/dist/api/TextTranslation.js +12 -6
- package/dist/api/TextTranslation.js.map +1 -1
- package/dist/api/TranslationAlignment.js +2 -2
- package/dist/api/TranslationAlignment.js.map +1 -1
- package/dist/audio/AudioUtilities.d.ts +5 -3
- package/dist/audio/AudioUtilities.js +39 -25
- package/dist/audio/AudioUtilities.js.map +1 -1
- package/dist/build-tools/MakeTarballsForInstalledPackages.d.ts +1 -0
- package/dist/build-tools/MakeTarballsForInstalledPackages.js +20 -0
- package/dist/build-tools/MakeTarballsForInstalledPackages.js.map +1 -0
- package/dist/cli/CLI.js +4 -3
- package/dist/cli/CLI.js.map +1 -1
- package/dist/dsp/FFT.d.ts +3 -3
- package/dist/dsp/FFT.js +55 -34
- package/dist/dsp/FFT.js.map +1 -1
- package/dist/nlp/IPA.d.ts +3 -3
- package/dist/nlp/Segmentation.js +2 -1
- package/dist/nlp/Segmentation.js.map +1 -1
- package/dist/nlp/TextNormalizer.d.ts +2 -0
- package/dist/nlp/TextNormalizer.js +51 -0
- package/dist/nlp/TextNormalizer.js.map +1 -1
- package/dist/recognition/WhisperSTT.d.ts +5 -0
- package/dist/recognition/WhisperSTT.js +19 -11
- package/dist/recognition/WhisperSTT.js.map +1 -1
- package/dist/source-separation/MDXNetSourceSeparation.d.ts +26 -3
- package/dist/source-separation/MDXNetSourceSeparation.js +159 -79
- package/dist/source-separation/MDXNetSourceSeparation.js.map +1 -1
- package/dist/subtitles/Subtitles.js +2 -1
- package/dist/subtitles/Subtitles.js.map +1 -1
- package/dist/synthesis/EspeakTTS.js +5 -5
- package/dist/synthesis/EspeakTTS.js.map +1 -1
- package/dist/tests/Test.js +0 -1
- package/dist/tests/Test.js.map +1 -1
- package/dist/text-translation/GoogleTranslateTextTranslation.d.ts +9 -3
- package/dist/text-translation/GoogleTranslateTextTranslation.js +59 -29
- package/dist/text-translation/GoogleTranslateTextTranslation.js.map +1 -1
- package/dist/utilities/OnnxUtilities.d.ts +1 -0
- package/dist/utilities/OnnxUtilities.js +5 -5
- package/dist/utilities/OnnxUtilities.js.map +1 -1
- package/dist/utilities/PackageManager.js +6 -6
- package/dist/utilities/PackageManager.js.map +1 -1
- package/dist/utilities/StringUtilities.d.ts +28 -0
- package/dist/utilities/StringUtilities.js +150 -0
- package/dist/utilities/StringUtilities.js.map +1 -0
- package/dist/utilities/TarballMaker.d.ts +3 -4
- package/dist/utilities/TarballMaker.js +6 -19
- package/dist/utilities/TarballMaker.js.map +1 -1
- package/dist/utilities/Timeline.js +2 -1
- package/dist/utilities/Timeline.js.map +1 -1
- package/dist/utilities/Utilities.d.ts +1 -33
- package/dist/utilities/Utilities.js +3 -176
- package/dist/utilities/Utilities.js.map +1 -1
- package/dist/utilities/WasmMemoryManager.d.ts +9 -1
- package/dist/utilities/WasmMemoryManager.js +24 -3
- package/dist/utilities/WasmMemoryManager.js.map +1 -1
- package/dist/utilities/WebReader.js +1 -1
- package/dist/utilities/WebReader.js.map +1 -1
- package/dist/utilities/WikipediaReader.js +1 -1
- package/dist/utilities/WikipediaReader.js.map +1 -1
- package/dist/utilities/WindowedList.d.ts +10 -0
- package/dist/utilities/WindowedList.js +36 -0
- package/dist/utilities/WindowedList.js.map +1 -0
- package/docs/Engines.md +1 -1
- package/docs/Options.md +16 -10
- package/package.json +11 -11
- package/src/alignment/SpeechAlignment.ts +1 -1
- package/src/api/Alignment.ts +2 -2
- package/src/api/Denoising.ts +5 -4
- package/src/api/Recognition.ts +3 -3
- package/src/api/SourceSeparation.ts +20 -19
- package/src/api/SpeechLanguageDetection.ts +2 -2
- package/src/api/SpeechTranslation.ts +2 -2
- package/src/api/Synthesis.ts +8 -6
- package/src/api/TextTranslation.ts +17 -9
- package/src/api/TranslationAlignment.ts +2 -2
- package/src/audio/AudioUtilities.ts +53 -33
- package/src/build-tools/MakeTarballsForInstalledPackages.ts +25 -0
- package/src/cli/CLI.ts +4 -3
- package/src/dsp/FFT.ts +65 -42
- package/src/nlp/Segmentation.ts +2 -1
- package/src/nlp/TextNormalizer.ts +60 -0
- package/src/recognition/WhisperSTT.ts +25 -12
- package/src/source-separation/MDXNetSourceSeparation.ts +218 -88
- package/src/subtitles/Subtitles.ts +2 -1
- package/src/synthesis/EspeakTTS.ts +5 -5
- package/src/tests/Test.ts +0 -4
- package/src/text-translation/GoogleTranslateTextTranslation.ts +91 -30
- package/src/typings/Fillers.d.ts +2 -0
- package/src/utilities/OnnxUtilities.ts +7 -8
- package/src/utilities/PackageManager.ts +6 -7
- package/src/utilities/StringUtilities.ts +203 -0
- package/src/utilities/TarballMaker.ts +6 -23
- package/src/utilities/Timeline.ts +2 -1
- package/src/utilities/Utilities.ts +4 -237
- package/src/utilities/WasmMemoryManager.ts +38 -4
- package/src/utilities/WebReader.ts +1 -1
- package/src/utilities/WikipediaReader.ts +1 -1
- package/src/utilities/WindowedList.ts +45 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class WindowedList {
|
|
2
|
+
maxWindowLength;
|
|
3
|
+
elements = [];
|
|
4
|
+
startOffset = 0;
|
|
5
|
+
constructor(maxWindowLength) {
|
|
6
|
+
this.maxWindowLength = maxWindowLength;
|
|
7
|
+
}
|
|
8
|
+
add(value) {
|
|
9
|
+
if (this.elements.length === this.maxWindowLength) {
|
|
10
|
+
this.elements.shift();
|
|
11
|
+
this.startOffset += 1;
|
|
12
|
+
}
|
|
13
|
+
this.elements.push(value);
|
|
14
|
+
}
|
|
15
|
+
get(index) {
|
|
16
|
+
if (index < this.startOffset) {
|
|
17
|
+
throw new Error(`Index is smaller than to window start offset.`);
|
|
18
|
+
}
|
|
19
|
+
if (index >= this.endOffset) {
|
|
20
|
+
throw new Error(`Index is beyond window end offset.`);
|
|
21
|
+
}
|
|
22
|
+
return this.elements[index - this.startOffset];
|
|
23
|
+
}
|
|
24
|
+
slice(startIndex, endIndex) {
|
|
25
|
+
const result = [];
|
|
26
|
+
endIndex = Math.min(endIndex, this.endOffset);
|
|
27
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
28
|
+
result.push(this.get(i));
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
get endOffset() {
|
|
33
|
+
return this.startOffset + this.elements.length;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=WindowedList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WindowedList.js","sourceRoot":"","sources":["../../src/utilities/WindowedList.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAY;IAII;IAH5B,QAAQ,GAAQ,EAAE,CAAA;IAClB,WAAW,GAAG,CAAC,CAAA;IAEf,YAA4B,eAAuB;QAAvB,oBAAe,GAAf,eAAe,CAAQ;IACnD,CAAC;IAED,GAAG,CAAC,KAAQ;QACX,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YACnD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAA;YAErB,IAAI,CAAC,WAAW,IAAI,CAAC,CAAA;QACtB,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,CAAC;IAED,GAAG,CAAC,KAAa;QAChB,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;QACjE,CAAC;QAED,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;QACtD,CAAC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;IAC/C,CAAC;IAED,KAAK,CAAC,UAAkB,EAAE,QAAgB;QACzC,MAAM,MAAM,GAAQ,EAAE,CAAA;QAEtB,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QAE7C,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACzB,CAAC;QAED,OAAO,MAAM,CAAA;IACd,CAAC;IAED,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA;IAC/C,CAAC;CACD"}
|
package/docs/Engines.md
CHANGED
|
@@ -81,7 +81,7 @@ These engines' goal is to match (or "align") a given spoken recording with a giv
|
|
|
81
81
|
|
|
82
82
|
**Cloud services (unofficial)**:
|
|
83
83
|
|
|
84
|
-
* Google Translate (`google-translate`): uses the [Google Translate mobile web UI](https://translate.google.com/m) to translate text from and to any one of its supported languages.
|
|
84
|
+
* Google Translate (`google-translate`): uses the [Google Translate mobile web UI](https://translate.google.com/m) to translate text from and to any one of its 243 supported languages.
|
|
85
85
|
|
|
86
86
|
## Speech-to-translated-transcript alignment
|
|
87
87
|
|
package/docs/Options.md
CHANGED
|
@@ -47,7 +47,7 @@ Applies to CLI operations: `speak`, `speak-file`, `speak-url`, `speak-wikipedia`
|
|
|
47
47
|
|
|
48
48
|
**VITS**:
|
|
49
49
|
* `vits.speakerId`: speaker ID, for VITS models that support multiple speakers. Defaults to `0`
|
|
50
|
-
* `vits.provider`: ONNX execution provider to use. Can be `cpu
|
|
50
|
+
* `vits.provider`: ONNX execution provider to use. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). Using GPU acceleration for VITS may or may not be faster than CPU, depending on your hardware. Defaults to `cpu`
|
|
51
51
|
|
|
52
52
|
**eSpeak**:
|
|
53
53
|
* `espeak.rate`: speech rate, in eSpeak units. Overrides `speed` when set
|
|
@@ -151,8 +151,8 @@ Applies to CLI operation: `transcribe`, API method: `recognize`
|
|
|
151
151
|
* `whisper.suppressRepetition`: attempt to suppress decoding of repeating token patterns. Defaults to `true`
|
|
152
152
|
* `whisper.repetitionThreshold`: minimal repetition / compressibility score to cause a part not to be auto-prompted to the next part. Defaults to `2.4`
|
|
153
153
|
* `whisper.decodeTimestampTokens`: enable/disable decoding of timestamp tokens. Setting to `false` can reduce the occurrence of hallucinations and token repetition loops, possibly due to the overall reduction in the number of tokens decoded. This has no impact on the accuracy of timestamps, since they are derived independently using cross-attention weights. However, there are cases where this can cause the model to end a part prematurely, especially in singing and less speech-like voice segments, or when there are multiple speakers. Defaults to `true`
|
|
154
|
-
* `whisper.encoderProvider`: identifier for the ONNX execution provider to use with the encoder model. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only) or `cuda` (Linux only). In general, GPU-based encoding should be significantly faster. Defaults to `cpu`, or `dml` if available
|
|
155
|
-
* `whisper.decoderProvider`: identifier for the ONNX execution provider to use with the decoder model. Can be `cpu`, `dml` (Windows only) or `cuda` (Linux only). Using GPU acceleration for the decoder may be faster than CPU, especially for larger models, but that depends on your particular combination of CPU and GPU. Defaults to `cpu`, and on Windows, `dml` if available for larger models (`small`, `medium`, `large`)
|
|
154
|
+
* `whisper.encoderProvider`: identifier for the ONNX execution provider to use with the encoder model. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). In general, GPU-based encoding should be significantly faster. Defaults to `cpu`, or `dml` if available
|
|
155
|
+
* `whisper.decoderProvider`: identifier for the ONNX execution provider to use with the decoder model. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). Using GPU acceleration for the decoder may be faster than CPU, especially for larger models, but that depends on your particular combination of CPU and GPU. Defaults to `cpu`, and on Windows, `dml` if available for larger models (`small`, `medium`, `large`)
|
|
156
156
|
* `whisper.seed`: provide a custom random seed for token selection when temperature is greater than 0. Uses a constant seed by default to ensure reproducibility
|
|
157
157
|
|
|
158
158
|
**Whisper.cpp**:
|
|
@@ -174,7 +174,7 @@ Applies to CLI operation: `transcribe`, API method: `recognize`
|
|
|
174
174
|
|
|
175
175
|
**Silero**:
|
|
176
176
|
* `silero.modelPath`: path to a Silero model. Note that latest `en`, `de`, `fr` and `uk` models are automatically installed when needed based on the selected language. This should only be used to manually specify a different model, otherwise specify `language` instead
|
|
177
|
-
* `silero.provider`: ONNX execution provider to use. Can be `cpu` or `
|
|
177
|
+
* `silero.provider`: ONNX execution provider to use. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). Defaults to `cpu`, or `dml` if available
|
|
178
178
|
|
|
179
179
|
**Google Cloud**:
|
|
180
180
|
* `googleCloud.apiKey`: Google Cloud API key (required)
|
|
@@ -234,11 +234,11 @@ Applies to CLI operation: `align`, API method: `align`
|
|
|
234
234
|
Applies to the `whisper` engine only. To provide Whisper options for `dtw-ra`, use `recognition.whisper` instead.
|
|
235
235
|
|
|
236
236
|
* `whisper.model`: Whisper model to use. Defaults to `tiny` or `tiny.en`
|
|
237
|
-
* `whisper.endTokenThreshold`: minimal probability to accept an end
|
|
237
|
+
* `whisper.endTokenThreshold`: minimal probability to accept an end token for a recognized part. The probability is measured via the softmax between the end token's logit and the second highest logit. You can try to adjust this threshold in cases the model is ending a part with too few, or many tokens decoded. Defaults to `0.9`. On the last audio part, it is always effectively set to `Infinity`, to ensure the remaining transcript tokens are decoded in full
|
|
238
|
+
* `whisper.maxTokensPerPart`: maximum number of tokens to decode per part. Should help avoid edge cases where the model never reaches an end token for the part, which otherwise may cause the model to decode too many tokens and eventually crash. Defaults to 250
|
|
238
239
|
* `whisper.encoderProvider`: encoder ONNX provider. See details in recognition section above
|
|
239
240
|
* `whisper.decoderProvider`: decoder ONNX provider. See details in recognition section above
|
|
240
241
|
|
|
241
|
-
|
|
242
242
|
## Speech-to-text translation
|
|
243
243
|
|
|
244
244
|
Applies to CLI operation: `translate-speech`, API method: `translateSpeech`
|
|
@@ -269,10 +269,16 @@ Applies to CLI operation: `translate-speech`, API method: `translateSpeech`
|
|
|
269
269
|
|
|
270
270
|
Applies to CLI operation: `translate-text`, API method: `translateText`
|
|
271
271
|
|
|
272
|
+
**General**:
|
|
272
273
|
* `engine`: only `google-translate` supported
|
|
273
274
|
* `sourceLanguage`: the source language code for the input text. Auto-detected if not set
|
|
274
275
|
* `targetLanguage`: the target language code for the output text. Required
|
|
275
276
|
* `languageDetection`: language detection options. Optional
|
|
277
|
+
* `plainText`: plain text processing options. Optional
|
|
278
|
+
|
|
279
|
+
**Google Translate**:
|
|
280
|
+
* `googleTranslate.tld`: top-level domain to request from. Defaults to `com`
|
|
281
|
+
* `googleTranslate.maxCharactersPerPart`: maximum number of characters in each part requested from the server. Defaults to 2000
|
|
276
282
|
|
|
277
283
|
## Speech-to-translated-transcript alignment
|
|
278
284
|
|
|
@@ -345,7 +351,7 @@ Applies to CLI operation: `detect-speech-langauge`, API method: `detectSpeechLan
|
|
|
345
351
|
* `whisper.decoderProvider`: decoder ONNX execution provider. See details in recognition section above
|
|
346
352
|
|
|
347
353
|
**Silero**:
|
|
348
|
-
* `silero.provider`: ONNX execution provider to use. Can be `cpu` or `
|
|
354
|
+
* `silero.provider`: ONNX execution provider to use. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). Using GPU may be faster, but the initialization overhead is larger. **Note**: `dml` provider seems to be unstable at the moment for this model. Defaults to `cpu`
|
|
349
355
|
|
|
350
356
|
### Text language detection
|
|
351
357
|
|
|
@@ -370,7 +376,7 @@ Applies to CLI operation: `detect-voice-activity`, API method: `detectVoiceActiv
|
|
|
370
376
|
|
|
371
377
|
**Silero**:
|
|
372
378
|
* `silero.frameDuration`: Silero frame duration (ms). Can be `30`, `60` or `90`. Defaults to `90`
|
|
373
|
-
* `silero.provider`: ONNX provider to use. Can be `cpu` or `
|
|
379
|
+
* `silero.provider`: ONNX provider to use. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). Using GPU is likely to be slower than CPU due to inference being independently executed on each audio frame. Defaults to `cpu` (recommended)
|
|
374
380
|
|
|
375
381
|
## Speech denoising
|
|
376
382
|
|
|
@@ -395,8 +401,8 @@ Applies to CLI operation: `isolate`, API method: `isolate`
|
|
|
395
401
|
|
|
396
402
|
**MDX-NET**:
|
|
397
403
|
|
|
398
|
-
* `mdxNet.model`: model to use. Currently available models are `UVR_MDXNET_1_9703`, `UVR_MDXNET_2_9682`, `UVR_MDXNET_3_9662`, `UVR_MDXNET_KARA`. Defaults to `UVR_MDXNET_1_9703`
|
|
399
|
-
* `mdxNet.provider`: ONNX execution provider to use. Can be `cpu
|
|
404
|
+
* `mdxNet.model`: model to use. Currently available models are `UVR_MDXNET_1_9703`, `UVR_MDXNET_2_9682`, `UVR_MDXNET_3_9662`, `UVR_MDXNET_KARA`, and higher quality models `UVR_MDXNET_Main` and `Kim_Vocal_2`. Defaults to `UVR_MDXNET_1_9703`
|
|
405
|
+
* `mdxNet.provider`: ONNX execution provider to use. Can be `cpu`, `dml` ([DirectML](https://microsoft.github.io/DirectML/)-based GPU acceleration - Windows only), or `cuda` (Linux only - requires [CUDA Toolkit 12.x](https://developer.nvidia.com/cuda-downloads) and [cuDNN 9.x](https://developer.nvidia.com/cudnn-downloads) to be installed). Defaults to `dml` if available (Windows) or `cpu` (other platforms)
|
|
400
406
|
|
|
401
407
|
# Common options
|
|
402
408
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "echogarden",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "An easy-to-use speech toolset. Includes tools for synthesis, recognition, alignment, speech translation, language detection, source separation and more.",
|
|
5
5
|
"author": "Rotem Dan",
|
|
6
6
|
"license": "GPL-3.0",
|
|
@@ -46,22 +46,22 @@
|
|
|
46
46
|
"LICENSE.md"
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
|
-
"cli": "node --experimental-wasi-unstable-preview1 --no-warnings ./dist/cli/CLIStarter.js",
|
|
50
|
-
"server": "node --experimental-wasi-unstable-preview1 --no-warnings ./dist/server/ServerStarter.js",
|
|
51
49
|
"test": "node --experimental-wasi-unstable-preview1 --no-warnings --trace-uncaught ./dist/tests/Test.js",
|
|
52
|
-
"generate-options-schema": "npx ts-json-schema-generator --path ./src/api/APIOptions.ts --unstable --type APIOptions --tsconfig ./tsconfig.json --out ./data/schemas/options.json"
|
|
50
|
+
"generate-options-schema": "npx ts-json-schema-generator --path ./src/api/APIOptions.ts --unstable --type APIOptions --tsconfig ./tsconfig.json --out ./data/schemas/options.json",
|
|
51
|
+
"make-tarballs": "node --no-warnings ./dist/build-tools/MakeTarballsForInstalledPackages.js"
|
|
53
52
|
},
|
|
54
53
|
"bin": {
|
|
55
54
|
"echogarden": "./dist/cli/CLILauncher.js"
|
|
56
55
|
},
|
|
57
56
|
"dependencies": {
|
|
58
|
-
"@aws-sdk/client-polly": "^3.
|
|
59
|
-
"@aws-sdk/client-transcribe-streaming": "^3.
|
|
57
|
+
"@aws-sdk/client-polly": "^3.669.0",
|
|
58
|
+
"@aws-sdk/client-transcribe-streaming": "^3.669.0",
|
|
60
59
|
"@echogarden/espeak-ng-emscripten": "^0.1.2",
|
|
61
60
|
"@echogarden/fasttext-wasm": "^0.1.0",
|
|
62
61
|
"@echogarden/flite-wasi": "^0.1.1",
|
|
63
62
|
"@echogarden/fvad-wasm": "^0.1.2",
|
|
64
63
|
"@echogarden/kissfft-wasm": "^0.1.1",
|
|
64
|
+
"@echogarden/pffft-wasm": "^0.3.0",
|
|
65
65
|
"@echogarden/rnnoise-wasm": "^0.1.1",
|
|
66
66
|
"@echogarden/rubberband-wasm": "^0.1.1",
|
|
67
67
|
"@echogarden/sonic-wasm": "^0.1.1",
|
|
@@ -74,14 +74,14 @@
|
|
|
74
74
|
"chalk": "^5.3.0",
|
|
75
75
|
"cldr-segmentation": "^2.2.1",
|
|
76
76
|
"command-exists": "^1.2.9",
|
|
77
|
-
"compromise": "^14.14.
|
|
77
|
+
"compromise": "^14.14.2",
|
|
78
78
|
"fs-extra": "^11.2.0",
|
|
79
79
|
"gaxios": "^6.7.1",
|
|
80
80
|
"graceful-fs": "^4.2.11",
|
|
81
81
|
"html-escaper": "^3.0.3",
|
|
82
82
|
"html-to-text": "^9.0.5",
|
|
83
83
|
"import-meta-resolve": "^4.1.0",
|
|
84
|
-
"jieba-wasm": "^2.
|
|
84
|
+
"jieba-wasm": "^2.2.0",
|
|
85
85
|
"jsdom": "^25.0.1",
|
|
86
86
|
"json5": "^2.2.3",
|
|
87
87
|
"kuromoji": "^0.1.2",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"moving-median": "^1.0.0",
|
|
90
90
|
"msgpack-lite": "^0.1.26",
|
|
91
91
|
"onnxruntime-node": "^1.19.2",
|
|
92
|
-
"openai": "^4.67.
|
|
92
|
+
"openai": "^4.67.3",
|
|
93
93
|
"sam-js": "^0.3.1",
|
|
94
94
|
"strip-ansi": "^7.1.0",
|
|
95
95
|
"tar": "^7.4.3",
|
|
@@ -116,11 +116,11 @@
|
|
|
116
116
|
"@types/graceful-fs": "^4.1.9",
|
|
117
117
|
"@types/jsdom": "^21.1.7",
|
|
118
118
|
"@types/msgpack-lite": "^0.1.11",
|
|
119
|
-
"@types/node": "^22.7.
|
|
119
|
+
"@types/node": "^22.7.5",
|
|
120
120
|
"@types/recursive-readdir": "^2.2.4",
|
|
121
121
|
"@types/tar": "^6.1.13",
|
|
122
122
|
"@types/ws": "^8.5.12",
|
|
123
123
|
"ts-json-schema-generator": "^2.3.0",
|
|
124
|
-
"typescript": "^5.6.
|
|
124
|
+
"typescript": "^5.6.3"
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -589,7 +589,7 @@ export async function createAlignmentReferenceUsingEspeakForFragments(fragments:
|
|
|
589
589
|
{
|
|
590
590
|
// Split fragments to chunks, process each chunk individually,
|
|
591
591
|
// and incrementally merge the chunks to the final result.
|
|
592
|
-
|
|
592
|
+
|
|
593
593
|
const maxCharactersInChunk = 1000
|
|
594
594
|
|
|
595
595
|
let timeOffset = 0
|
package/src/api/Alignment.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
3
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
4
|
-
import { AudioSourceParam, RawAudio, ensureRawAudio, getRawAudioDuration,
|
|
4
|
+
import { AudioSourceParam, RawAudio, ensureRawAudio, getRawAudioDuration, normalizeAudioLevelInPlace, trimAudioEnd } from '../audio/AudioUtilities.js'
|
|
5
5
|
import { Logger } from '../utilities/Logger.js'
|
|
6
6
|
|
|
7
7
|
import * as API from './API.js'
|
|
@@ -56,7 +56,7 @@ export async function align(input: AudioSourceParam, transcript: string, options
|
|
|
56
56
|
|
|
57
57
|
logger.start('Normalize and trim audio')
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
normalizeAudioLevelInPlace(sourceRawAudio)
|
|
60
60
|
sourceRawAudio.audioChannels[0] = trimAudioEnd(sourceRawAudio.audioChannels[0])
|
|
61
61
|
|
|
62
62
|
logger.end()
|
package/src/api/Denoising.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
|
-
import { AudioSourceParam, RawAudio,
|
|
3
|
+
import { AudioSourceParam, RawAudio, applyGainDecibelsInPlace, ensureRawAudio, getSamplePeakDecibels, mixAudio, normalizeAudioLevelInPlace } from '../audio/AudioUtilities.js'
|
|
4
4
|
import { Logger } from '../utilities/Logger.js'
|
|
5
5
|
|
|
6
6
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
@@ -59,13 +59,14 @@ export async function denoise(input: AudioSourceParam, options: DenoisingOptions
|
|
|
59
59
|
const dryMixGainDecibels = options.postProcessing!.dryMixGain!
|
|
60
60
|
|
|
61
61
|
const preMixPeakDecibels = getSamplePeakDecibels(denoisedAudio.audioChannels)
|
|
62
|
-
|
|
62
|
+
applyGainDecibelsInPlace(resampledRawAudio, dryMixGainDecibels)
|
|
63
|
+
denoisedAudio = mixAudio(denoisedAudio, resampledRawAudio)
|
|
63
64
|
const postMixPeakDecibels = getSamplePeakDecibels(denoisedAudio.audioChannels)
|
|
64
65
|
|
|
65
66
|
if (shouldNormalize) {
|
|
66
|
-
|
|
67
|
+
normalizeAudioLevelInPlace(denoisedAudio, targetPeakDecibels, maxGainIncreaseDecibels)
|
|
67
68
|
} else {
|
|
68
|
-
|
|
69
|
+
applyGainDecibelsInPlace(denoisedAudio, preMixPeakDecibels - postMixPeakDecibels)
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
logger.end()
|
package/src/api/Recognition.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
3
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
4
|
-
import { AudioSourceParam, RawAudio, ensureRawAudio,
|
|
4
|
+
import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevelInPlace, trimAudioEnd } from '../audio/AudioUtilities.js'
|
|
5
5
|
import { Logger } from '../utilities/Logger.js'
|
|
6
6
|
|
|
7
7
|
import * as API from './API.js'
|
|
@@ -59,7 +59,7 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
|
|
|
59
59
|
|
|
60
60
|
logger.start('Normalize and trim audio')
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
normalizeAudioLevelInPlace(sourceRawAudio)
|
|
63
63
|
sourceRawAudio.audioChannels[0] = trimAudioEnd(sourceRawAudio.audioChannels[0])
|
|
64
64
|
|
|
65
65
|
const engine = options.engine!
|
|
@@ -322,7 +322,7 @@ export interface RecognitionResult {
|
|
|
322
322
|
|
|
323
323
|
timeline: Timeline
|
|
324
324
|
wordTimeline: Timeline
|
|
325
|
-
|
|
325
|
+
|
|
326
326
|
language: string
|
|
327
327
|
|
|
328
328
|
inputRawAudio: RawAudio
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AudioSourceParam, RawAudio, ensureRawAudio, subtractAudio } from '../audio/AudioUtilities.js';
|
|
1
|
+
import { AudioSourceParam, RawAudio, attenuateIfClippingInPlace, ensureRawAudio, subtractAudio } from '../audio/AudioUtilities.js';
|
|
2
2
|
import { Logger } from '../utilities/Logger.js';
|
|
3
3
|
import { extendDeep } from '../utilities/ObjectUtilities.js';
|
|
4
4
|
import { loadPackage } from '../utilities/PackageManager.js';
|
|
@@ -6,13 +6,13 @@ import { EngineMetadata } from './Common.js';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { readdir } from '../utilities/FileSystem.js';
|
|
8
8
|
import path from 'node:path';
|
|
9
|
-
import {
|
|
9
|
+
import { defaultMDXNetOptions, getProfileForMDXNetModelName, MDXNetOptions } from '../source-separation/MDXNetSourceSeparation.js';
|
|
10
10
|
|
|
11
11
|
export async function isolate(input: AudioSourceParam, options: SourceSeparationOptions): Promise<SourceSeparationResult> {
|
|
12
12
|
const logger = new Logger()
|
|
13
13
|
const startTimestamp = logger.getTimestamp()
|
|
14
14
|
|
|
15
|
-
logger.
|
|
15
|
+
await logger.startAsync('Prepare for source separation')
|
|
16
16
|
|
|
17
17
|
const inputRawAudio = await ensureRawAudio(input)
|
|
18
18
|
|
|
@@ -27,8 +27,6 @@ export async function isolate(input: AudioSourceParam, options: SourceSeparation
|
|
|
27
27
|
|
|
28
28
|
const mdxNetOptions = options.mdxNet!
|
|
29
29
|
|
|
30
|
-
const executionProviders: OnnxExecutionProvider[] = mdxNetOptions.executionProvider ? [mdxNetOptions.executionProvider] : []
|
|
31
|
-
|
|
32
30
|
const packageDir = await loadPackage(`mdxnet-${mdxNetOptions.model!}`)
|
|
33
31
|
const modelFilename = (await readdir(packageDir)).filter(name => name.endsWith('onnx'))[0]
|
|
34
32
|
|
|
@@ -38,16 +36,20 @@ export async function isolate(input: AudioSourceParam, options: SourceSeparation
|
|
|
38
36
|
|
|
39
37
|
const modelPath = path.join(packageDir, modelFilename)
|
|
40
38
|
|
|
39
|
+
await logger.startAsync(`Convert audio to 44.1 kHz stereo`)
|
|
40
|
+
|
|
41
|
+
const inputRawAudio44100Stereo = await ensureRawAudio(inputRawAudio, 44100, 2)
|
|
42
|
+
|
|
41
43
|
logger.end()
|
|
42
44
|
|
|
43
|
-
const
|
|
45
|
+
const modelProfile = getProfileForMDXNetModelName(mdxNetOptions.model!)
|
|
44
46
|
|
|
45
|
-
isolatedRawAudio = await MDXNetSourceSeparation.isolate(
|
|
47
|
+
isolatedRawAudio = await MDXNetSourceSeparation.isolate(inputRawAudio44100Stereo, modelPath, modelProfile, mdxNetOptions)
|
|
46
48
|
|
|
47
49
|
logger.end()
|
|
48
50
|
|
|
49
|
-
logger.
|
|
50
|
-
backgroundRawAudio = subtractAudio(
|
|
51
|
+
await logger.startAsync(`Subtract from original waveform to extract background audio`)
|
|
52
|
+
backgroundRawAudio = subtractAudio(inputRawAudio44100Stereo, isolatedRawAudio)
|
|
51
53
|
|
|
52
54
|
break
|
|
53
55
|
}
|
|
@@ -57,8 +59,13 @@ export async function isolate(input: AudioSourceParam, options: SourceSeparation
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
await logger.startAsync(`Postprocess audio`)
|
|
63
|
+
|
|
64
|
+
attenuateIfClippingInPlace(isolatedRawAudio)
|
|
65
|
+
attenuateIfClippingInPlace(backgroundRawAudio)
|
|
66
|
+
|
|
60
67
|
logger.end()
|
|
61
|
-
|
|
68
|
+
|
|
62
69
|
logger.logDuration(`Total source separation time`, startTimestamp, chalk.magentaBright)
|
|
63
70
|
|
|
64
71
|
return {
|
|
@@ -73,19 +80,13 @@ export type SourceSeparationEngine = 'mdx-net'
|
|
|
73
80
|
export interface SourceSeparationOptions {
|
|
74
81
|
engine?: SourceSeparationEngine
|
|
75
82
|
|
|
76
|
-
mdxNet?:
|
|
77
|
-
model?: string
|
|
78
|
-
executionProvider?: OnnxExecutionProvider
|
|
79
|
-
}
|
|
83
|
+
mdxNet?: MDXNetOptions
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
export const defaultSourceSeparationOptions: SourceSeparationOptions = {
|
|
83
87
|
engine: 'mdx-net',
|
|
84
88
|
|
|
85
|
-
mdxNet:
|
|
86
|
-
model: 'UVR_MDXNET_1_9703',
|
|
87
|
-
executionProvider: undefined,
|
|
88
|
-
}
|
|
89
|
+
mdxNet: defaultMDXNetOptions,
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
export interface SourceSeparationResult {
|
|
@@ -98,7 +99,7 @@ export const sourceSeparationEngines: EngineMetadata[] = [
|
|
|
98
99
|
{
|
|
99
100
|
id: 'mdx-net',
|
|
100
101
|
name: 'MDX-NET',
|
|
101
|
-
description: 'Deep learning source separation architecture by KUIELAB (Korea University).',
|
|
102
|
+
description: 'Deep learning audio source separation architecture by KUIELAB (Korea University).',
|
|
102
103
|
type: 'local'
|
|
103
104
|
},
|
|
104
105
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { deepClone, extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
|
-
import { AudioSourceParam, RawAudio, ensureRawAudio, getRawAudioDuration,
|
|
3
|
+
import { AudioSourceParam, RawAudio, ensureRawAudio, getRawAudioDuration, normalizeAudioLevelInPlace, sliceRawAudioByTime, trimAudioEnd } from '../audio/AudioUtilities.js'
|
|
4
4
|
import { Logger } from '../utilities/Logger.js'
|
|
5
5
|
|
|
6
6
|
import * as API from './API.js'
|
|
@@ -28,7 +28,7 @@ export async function detectSpeechLanguage(input: AudioSourceParam, options: Spe
|
|
|
28
28
|
|
|
29
29
|
logger.start(`Resample audio to 16kHz mono`)
|
|
30
30
|
let sourceRawAudio = await ensureRawAudio(inputRawAudio, 16000, 1)
|
|
31
|
-
|
|
31
|
+
normalizeAudioLevelInPlace(sourceRawAudio)
|
|
32
32
|
sourceRawAudio.audioChannels[0] = trimAudioEnd(sourceRawAudio.audioChannels[0])
|
|
33
33
|
|
|
34
34
|
if (options.crop) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
3
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
4
|
-
import { AudioSourceParam, RawAudio, ensureRawAudio,
|
|
4
|
+
import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevelInPlace, trimAudioEnd } from '../audio/AudioUtilities.js'
|
|
5
5
|
import { Logger } from '../utilities/Logger.js'
|
|
6
6
|
|
|
7
7
|
import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
|
|
@@ -61,7 +61,7 @@ export async function translateSpeech(input: AudioSourceParam, options: SpeechTr
|
|
|
61
61
|
|
|
62
62
|
logger.start('Normalize and trim audio')
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
normalizeAudioLevelInPlace(sourceRawAudio)
|
|
65
65
|
sourceRawAudio.audioChannels[0] = trimAudioEnd(sourceRawAudio.audioChannels[0])
|
|
66
66
|
|
|
67
67
|
if (options.sourceLanguage) {
|
package/src/api/Synthesis.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { deepClone, extendDeep } from '../utilities/ObjectUtilities.js'
|
|
|
4
4
|
|
|
5
5
|
import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
|
|
6
6
|
|
|
7
|
-
import { clip,
|
|
8
|
-
import { RawAudio,
|
|
7
|
+
import { clip, sha256AsHex, stringifyAndFormatJson, logToStderr, yieldToEventLoop, runOperationWithRetries } from '../utilities/Utilities.js'
|
|
8
|
+
import { RawAudio, concatAudioSegments, downmixToMono, encodeRawAudioToWave, getSamplePeakDecibels, getEmptyRawAudio, getRawAudioDuration, trimAudioEnd, trimAudioStart, attenuateIfClippingInPlace, normalizeAudioLevelInPlace } from '../audio/AudioUtilities.js'
|
|
9
9
|
import { Logger } from '../utilities/Logger.js'
|
|
10
10
|
|
|
11
11
|
import { isWordOrSymbolWord, splitToParagraphs, splitToSentences } from '../nlp/Segmentation.js'
|
|
@@ -25,6 +25,8 @@ import { type EspeakOptions } from '../synthesis/EspeakTTS.js'
|
|
|
25
25
|
import { type OpenAICloudTTSOptions } from '../synthesis/OpenAICloudTTS.js'
|
|
26
26
|
import { type ElevenlabsTTSOptions } from '../synthesis/ElevenlabsTTS.js'
|
|
27
27
|
import { OnnxExecutionProvider } from '../utilities/OnnxUtilities.js'
|
|
28
|
+
import { simplifyPunctuationCharacters } from '../nlp/TextNormalizer.js'
|
|
29
|
+
import { convertHtmlToText } from '../utilities/StringUtilities.js'
|
|
28
30
|
|
|
29
31
|
const log = logToStderr
|
|
30
32
|
|
|
@@ -248,9 +250,9 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
|
|
|
248
250
|
resultRawAudio = { audioChannels: joinedAudioBuffers, sampleRate: segmentsRawAudio[0].sampleRate }
|
|
249
251
|
|
|
250
252
|
if (options.postProcessing!.normalizeAudio) {
|
|
251
|
-
|
|
253
|
+
normalizeAudioLevelInPlace(resultRawAudio, options.postProcessing!.targetPeak, options.postProcessing!.maxGainIncrease)
|
|
252
254
|
} else {
|
|
253
|
-
|
|
255
|
+
attenuateIfClippingInPlace(resultRawAudio)
|
|
254
256
|
}
|
|
255
257
|
} else {
|
|
256
258
|
resultRawAudio = getEmptyRawAudio(1, 24000)
|
|
@@ -864,9 +866,9 @@ async function synthesizeSegment(text: string, options: SynthesisOptions) {
|
|
|
864
866
|
synthesizedAudio = downmixToMono(synthesizedAudio)
|
|
865
867
|
|
|
866
868
|
if (options.postProcessing!.normalizeAudio) {
|
|
867
|
-
|
|
869
|
+
normalizeAudioLevelInPlace(synthesizedAudio, options.postProcessing!.targetPeak!, options.postProcessing!.maxGainIncrease!)
|
|
868
870
|
} else {
|
|
869
|
-
|
|
871
|
+
attenuateIfClippingInPlace(synthesizedAudio)
|
|
870
872
|
}
|
|
871
873
|
|
|
872
874
|
const preTrimSampleCount = synthesizedAudio.audioChannels[0].length
|
|
@@ -3,6 +3,7 @@ import { formatLanguageCodeWithName, normalizeIdentifierToLanguageCode, parseLan
|
|
|
3
3
|
import { Logger } from '../utilities/Logger.js'
|
|
4
4
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
5
5
|
import * as API from './API.js'
|
|
6
|
+
import { defaultGoogleTranslateTextTranslationOptions, type GoogleTranslateTextTranslationOptions } from '../text-translation/GoogleTranslateTextTranslation.js'
|
|
6
7
|
|
|
7
8
|
export async function translateText(inputText: string, options: TextTranslationOptions): Promise<TextTranslationResult> {
|
|
8
9
|
const logger = new Logger()
|
|
@@ -43,7 +44,7 @@ export async function translateText(inputText: string, options: TextTranslationO
|
|
|
43
44
|
|
|
44
45
|
logger.end()
|
|
45
46
|
|
|
46
|
-
logger.logTitledMessage(`Warning`, `The nllb engine is currently
|
|
47
|
+
logger.logTitledMessage(`Warning`, `The nllb text translation engine is currently a work-in-progress and doesn't work correctly.`, chalk.yellow, 'warning')
|
|
47
48
|
|
|
48
49
|
translationPairs = await NLLBTextTranslation.translateText(inputText, options.sourceLanguage, options.targetLanguage)
|
|
49
50
|
|
|
@@ -63,9 +64,11 @@ export async function translateText(inputText: string, options: TextTranslationO
|
|
|
63
64
|
case 'google-translate': {
|
|
64
65
|
const GoogleTranslateTextTranslation = await import('../text-translation/GoogleTranslateTextTranslation.js')
|
|
65
66
|
|
|
67
|
+
const googleTranslateOptions = options.googleTranslate!
|
|
68
|
+
|
|
66
69
|
logger.end();
|
|
67
70
|
|
|
68
|
-
({ translationPairs, translatedText } = await GoogleTranslateTextTranslation.translateText(inputText, options.sourceLanguage, options.targetLanguage))
|
|
71
|
+
({ translationPairs, translatedText } = await GoogleTranslateTextTranslation.translateText(inputText, options.sourceLanguage, options.targetLanguage, options.plainText!, googleTranslateOptions))
|
|
69
72
|
|
|
70
73
|
break
|
|
71
74
|
}
|
|
@@ -75,7 +78,7 @@ export async function translateText(inputText: string, options: TextTranslationO
|
|
|
75
78
|
|
|
76
79
|
logger.end()
|
|
77
80
|
|
|
78
|
-
logger.logTitledMessage(`Warning`, `The deepl engine is currently
|
|
81
|
+
logger.logTitledMessage(`Warning`, `The deepl text translation engine is currently a work-in-progress and doesn't work correctly.`, chalk.yellow, 'warning')
|
|
79
82
|
|
|
80
83
|
translationPairs = await DeepLTextTranslation.translateText(inputText, options.sourceLanguage, options.targetLanguage)
|
|
81
84
|
translatedText = ''
|
|
@@ -113,11 +116,12 @@ export interface TextTranslationOptions {
|
|
|
113
116
|
|
|
114
117
|
languageDetection?: API.TextLanguageDetectionOptions
|
|
115
118
|
|
|
119
|
+
plainText?: API.PlainTextOptions
|
|
120
|
+
|
|
116
121
|
nllb?: {
|
|
117
122
|
},
|
|
118
123
|
|
|
119
|
-
googleTranslate?:
|
|
120
|
-
},
|
|
124
|
+
googleTranslate?: GoogleTranslateTextTranslationOptions,
|
|
121
125
|
|
|
122
126
|
deepl?: {
|
|
123
127
|
},
|
|
@@ -148,12 +152,16 @@ export const defaultTextTranslationOptions: TextTranslationOptions = {
|
|
|
148
152
|
|
|
149
153
|
languageDetection: undefined,
|
|
150
154
|
|
|
151
|
-
|
|
155
|
+
plainText: {
|
|
156
|
+
paragraphBreaks: 'double',
|
|
157
|
+
whitespace: 'preserve'
|
|
152
158
|
},
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
nllb: {
|
|
155
161
|
},
|
|
156
162
|
|
|
163
|
+
googleTranslate: defaultGoogleTranslateTextTranslationOptions,
|
|
164
|
+
|
|
157
165
|
deepl: {
|
|
158
166
|
},
|
|
159
167
|
}
|
|
@@ -162,7 +170,7 @@ export const textTranslationEngines: API.EngineMetadata[] = [
|
|
|
162
170
|
{
|
|
163
171
|
id: 'nllb',
|
|
164
172
|
name: 'NLLB',
|
|
165
|
-
description: 'No Language Left Behind (NLLB) is a deep learning machine translation model by Facebook Research (
|
|
173
|
+
description: 'No Language Left Behind (NLLB) is a deep learning machine translation model by Facebook Research (work-in-progress, do not use).',
|
|
166
174
|
type: 'local'
|
|
167
175
|
},
|
|
168
176
|
{
|
|
@@ -174,7 +182,7 @@ export const textTranslationEngines: API.EngineMetadata[] = [
|
|
|
174
182
|
{
|
|
175
183
|
id: 'deepl',
|
|
176
184
|
name: 'DeepL',
|
|
177
|
-
description: 'Unoffical text translation API used by the DeepL web interface (
|
|
185
|
+
description: 'Unoffical text translation API used by the DeepL web interface (work-in-progress, do not use).',
|
|
178
186
|
type: 'cloud'
|
|
179
187
|
},
|
|
180
188
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
3
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
4
|
-
import { AudioSourceParam, RawAudio, ensureRawAudio,
|
|
4
|
+
import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevelInPlace, trimAudioEnd } from '../audio/AudioUtilities.js'
|
|
5
5
|
import { Logger } from '../utilities/Logger.js'
|
|
6
6
|
|
|
7
7
|
import * as API from './API.js'
|
|
@@ -53,7 +53,7 @@ export async function alignTranslation(input: AudioSourceParam, translatedTransc
|
|
|
53
53
|
|
|
54
54
|
logger.start('Normalize and trim audio')
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
normalizeAudioLevelInPlace(sourceRawAudio)
|
|
57
57
|
sourceRawAudio.audioChannels[0] = trimAudioEnd(sourceRawAudio.audioChannels[0])
|
|
58
58
|
|
|
59
59
|
logger.end()
|