echogarden 2.6.0 → 2.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.
Files changed (153) hide show
  1. package/data/lexicons/heteronyms.en.json +6 -2
  2. package/data/lexicons/words.en.json +379 -19
  3. package/dist/alignment/SemanticTextAlignment.js +6 -7
  4. package/dist/alignment/SemanticTextAlignment.js.map +1 -1
  5. package/dist/api/Alignment.js +2 -2
  6. package/dist/api/Alignment.js.map +1 -1
  7. package/dist/api/Recognition.js +2 -2
  8. package/dist/api/Recognition.js.map +1 -1
  9. package/dist/api/SourceSeparation.js +1 -1
  10. package/dist/api/SpeechTranslation.js +2 -2
  11. package/dist/api/SpeechTranslation.js.map +1 -1
  12. package/dist/api/Synthesis.js +7 -7
  13. package/dist/api/Synthesis.js.map +1 -1
  14. package/dist/api/TimelineTranslationAlignment.js +2 -2
  15. package/dist/api/TimelineTranslationAlignment.js.map +1 -1
  16. package/dist/api/TranslationAlignment.js +2 -2
  17. package/dist/api/TranslationAlignment.js.map +1 -1
  18. package/dist/audio/AudioBufferConversion.d.ts +5 -6
  19. package/dist/audio/AudioBufferConversion.js +16 -248
  20. package/dist/audio/AudioBufferConversion.js.map +1 -1
  21. package/dist/audio/AudioPlayer.js +2 -2
  22. package/dist/audio/AudioPlayer.js.map +1 -1
  23. package/dist/audio/AudioRecorder.js +1 -1
  24. package/dist/audio/AudioRecorder.js.map +1 -1
  25. package/dist/audio/AudioUtilities.d.ts +2 -8
  26. package/dist/audio/AudioUtilities.js +4 -3
  27. package/dist/audio/AudioUtilities.js.map +1 -1
  28. package/dist/cli/CLI.js +4 -4
  29. package/dist/cli/CLI.js.map +1 -1
  30. package/dist/codecs/FFMpegTranscoder.d.ts +1 -4
  31. package/dist/codecs/TIMITCodec.js +1 -2
  32. package/dist/codecs/TIMITCodec.js.map +1 -1
  33. package/dist/denoising/RNNoise.js +5 -5
  34. package/dist/denoising/RNNoise.js.map +1 -1
  35. package/dist/dsp/FFT.js +13 -19
  36. package/dist/dsp/FFT.js.map +1 -1
  37. package/dist/dsp/Rubberband.js +5 -5
  38. package/dist/dsp/Rubberband.js.map +1 -1
  39. package/dist/dsp/Sonic.js +6 -6
  40. package/dist/dsp/Sonic.js.map +1 -1
  41. package/dist/dsp/SpeexResampler.js +11 -11
  42. package/dist/dsp/SpeexResampler.js.map +1 -1
  43. package/dist/encodings/Ascii.js +1 -1
  44. package/dist/encodings/Ascii.js.map +1 -1
  45. package/dist/encodings/Utf16.js +1 -1
  46. package/dist/encodings/Utf16.js.map +1 -1
  47. package/dist/encodings/Utf8.js +1 -1
  48. package/dist/encodings/Utf8.js.map +1 -1
  49. package/dist/nlp/EspeakPhonemizer.js +1 -1
  50. package/dist/nlp/EspeakPhonemizer.js.map +1 -1
  51. package/dist/nlp/Segmentation.d.ts +13 -10
  52. package/dist/nlp/Segmentation.js +129 -106
  53. package/dist/nlp/Segmentation.js.map +1 -1
  54. package/dist/nlp/TextNormalizer.js +74 -42
  55. package/dist/nlp/TextNormalizer.js.map +1 -1
  56. package/dist/recognition/AmazonTranscribeSTT.js +2 -2
  57. package/dist/recognition/AmazonTranscribeSTT.js.map +1 -1
  58. package/dist/recognition/SileroSTT.js +2 -2
  59. package/dist/recognition/SileroSTT.js.map +1 -1
  60. package/dist/recognition/WhisperSTT.js +4 -16
  61. package/dist/recognition/WhisperSTT.js.map +1 -1
  62. package/dist/subtitles/Subtitles.js +52 -7
  63. package/dist/subtitles/Subtitles.js.map +1 -1
  64. package/dist/synthesis/AwsPollyTTS.d.ts +1 -4
  65. package/dist/synthesis/CoquiServerTTS.d.ts +1 -4
  66. package/dist/synthesis/DeepgramTTS.d.ts +1 -4
  67. package/dist/synthesis/ElevenLabsTTS.d.ts +1 -4
  68. package/dist/synthesis/ElevenLabsTTS.js +11 -10
  69. package/dist/synthesis/ElevenLabsTTS.js.map +1 -1
  70. package/dist/synthesis/EspeakTTS.js +8 -8
  71. package/dist/synthesis/EspeakTTS.js.map +1 -1
  72. package/dist/synthesis/FliteTTS.d.ts +1 -4
  73. package/dist/synthesis/GnuSpeechTTS.d.ts +1 -7
  74. package/dist/synthesis/GoogleCloudTTS.d.ts +1 -4
  75. package/dist/synthesis/KokoroTTS.js +21 -10
  76. package/dist/synthesis/KokoroTTS.js.map +1 -1
  77. package/dist/synthesis/SapiTTS.js +1 -2
  78. package/dist/synthesis/SapiTTS.js.map +1 -1
  79. package/dist/synthesis/SvoxPicoTTS.js +25 -25
  80. package/dist/synthesis/SvoxPicoTTS.js.map +1 -1
  81. package/dist/text-translation/DeepLTextTranslation.js +4 -3
  82. package/dist/text-translation/DeepLTextTranslation.js.map +1 -1
  83. package/dist/text-translation/NLLBTextTranslation.js +7 -6
  84. package/dist/text-translation/NLLBTextTranslation.js.map +1 -1
  85. package/dist/utilities/StringUtilities.d.ts +1 -1
  86. package/dist/utilities/StringUtilities.js +5 -5
  87. package/dist/utilities/StringUtilities.js.map +1 -1
  88. package/dist/utilities/Timeline.d.ts +2 -3
  89. package/dist/utilities/Timeline.js +96 -147
  90. package/dist/utilities/Timeline.js.map +1 -1
  91. package/dist/utilities/WikipediaReader.js +3 -3
  92. package/dist/utilities/WikipediaReader.js.map +1 -1
  93. package/dist/voice-activity-detection/WebRtcVAD.js +4 -4
  94. package/dist/voice-activity-detection/WebRtcVAD.js.map +1 -1
  95. package/docs/Tasklist.md +1 -6
  96. package/package.json +13 -11
  97. package/src/alignment/SemanticTextAlignment.ts +6 -7
  98. package/src/api/Alignment.ts +2 -2
  99. package/src/api/Recognition.ts +2 -2
  100. package/src/api/SourceSeparation.ts +1 -1
  101. package/src/api/SpeechTranslation.ts +2 -2
  102. package/src/api/Synthesis.ts +7 -7
  103. package/src/api/TimelineTranslationAlignment.ts +2 -2
  104. package/src/api/TranslationAlignment.ts +2 -2
  105. package/src/audio/AudioBufferConversion.ts +17 -263
  106. package/src/audio/AudioPlayer.ts +3 -3
  107. package/src/audio/AudioRecorder.ts +1 -1
  108. package/src/audio/AudioUtilities.ts +5 -3
  109. package/src/cli/CLI.ts +4 -4
  110. package/src/codecs/TIMITCodec.ts +1 -2
  111. package/src/denoising/RNNoise.ts +5 -5
  112. package/src/dsp/FFT.ts +22 -19
  113. package/src/dsp/Rubberband.ts +5 -5
  114. package/src/dsp/Sonic.ts +6 -6
  115. package/src/dsp/SpeexResampler.ts +11 -11
  116. package/src/encodings/Ascii.ts +1 -1
  117. package/src/encodings/Utf16.ts +1 -1
  118. package/src/encodings/Utf8.ts +1 -1
  119. package/src/nlp/EspeakPhonemizer.ts +1 -1
  120. package/src/nlp/Segmentation.ts +146 -111
  121. package/src/nlp/TextNormalizer.ts +94 -52
  122. package/src/recognition/AmazonTranscribeSTT.ts +2 -2
  123. package/src/recognition/SileroSTT.ts +2 -2
  124. package/src/recognition/WhisperSTT.ts +4 -18
  125. package/src/subtitles/Subtitles.ts +69 -8
  126. package/src/synthesis/ElevenLabsTTS.ts +12 -11
  127. package/src/synthesis/EspeakTTS.ts +9 -8
  128. package/src/synthesis/KokoroTTS.ts +24 -12
  129. package/src/synthesis/SapiTTS.ts +1 -2
  130. package/src/synthesis/SvoxPicoTTS.ts +27 -25
  131. package/src/text-translation/DeepLTextTranslation.ts +4 -3
  132. package/src/text-translation/NLLBTextTranslation.ts +8 -6
  133. package/src/typings/Fillers.d.ts +0 -16
  134. package/src/utilities/StringUtilities.ts +5 -6
  135. package/src/utilities/Timeline.ts +100 -170
  136. package/src/utilities/WikipediaReader.ts +3 -3
  137. package/src/voice-activity-detection/WebRtcVAD.ts +5 -4
  138. package/dist/codecs/WaveCodec.d.ts +0 -19
  139. package/dist/codecs/WaveCodec.js +0 -224
  140. package/dist/codecs/WaveCodec.js.map +0 -1
  141. package/dist/nlp/CompromiseNLP.d.ts +0 -15
  142. package/dist/nlp/CompromiseNLP.js +0 -79
  143. package/dist/nlp/CompromiseNLP.js.map +0 -1
  144. package/dist/utilities/BinaryArrayConversion.d.ts +0 -14
  145. package/dist/utilities/BinaryArrayConversion.js +0 -92
  146. package/dist/utilities/BinaryArrayConversion.js.map +0 -1
  147. package/dist/utilities/WasmMemoryManager.d.ts +0 -153
  148. package/dist/utilities/WasmMemoryManager.js +0 -440
  149. package/dist/utilities/WasmMemoryManager.js.map +0 -1
  150. package/src/codecs/WaveCodec.ts +0 -281
  151. package/src/nlp/CompromiseNLP.ts +0 -119
  152. package/src/utilities/BinaryArrayConversion.ts +0 -117
  153. package/src/utilities/WasmMemoryManager.ts +0 -566
@@ -1,4 +1,4 @@
1
- import { splitToParagraphs, wordCharacterPattern } from '../nlp/Segmentation.js';
1
+ import { splitToParagraphs, wordCharacterRegExp } from '../nlp/Segmentation.js';
2
2
  import { Logger } from './Logger.js';
3
3
  export async function parseWikipediaArticle(articleName, language) {
4
4
  const logger = new Logger();
@@ -12,13 +12,13 @@ export async function parseWikipediaArticle(articleName, language) {
12
12
  const sectionsText = [];
13
13
  for (const section of sections) {
14
14
  const sectionTitle = section.title();
15
- if (wordCharacterPattern.test(sectionTitle)) {
15
+ if (wordCharacterRegExp.test(sectionTitle)) {
16
16
  sectionsText.push(sectionTitle);
17
17
  }
18
18
  const sectionParagraphs = splitToParagraphs(section.text(), 'single', 'preserve');
19
19
  for (const paragraph of sectionParagraphs) {
20
20
  const paragraphText = paragraph;
21
- if (wordCharacterPattern.test(paragraphText)) {
21
+ if (wordCharacterRegExp.test(paragraphText)) {
22
22
  sectionsText.push(paragraphText);
23
23
  }
24
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WikipediaReader.js","sourceRoot":"","sources":["../../src/utilities/WikipediaReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAmB,EAAE,QAAgB;IAChF,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;IAE3B,MAAM,MAAM,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;IAErD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IAEtD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;IAEvD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;IACpC,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;QAEpC,IAAI,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7C,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAChC,CAAC;QAED,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;QAEjF,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC3C,MAAM,aAAa,GAAG,SAAS,CAAA;YAE/B,IAAI,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC9C,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACjC,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,CAAC,GAAG,EAAE,CAAA;IAEZ,OAAO,YAAY,CAAA;AACpB,CAAC"}
1
+ {"version":3,"file":"WikipediaReader.js","sourceRoot":"","sources":["../../src/utilities/WikipediaReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAmB,EAAE,QAAgB;IAChF,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;IAE3B,MAAM,MAAM,CAAC,UAAU,CAAC,4BAA4B,CAAC,CAAA;IAErD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAA;IAEtD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;IAEvD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;IACpC,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;QAEpC,IAAI,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5C,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAChC,CAAC;QAED,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;QAEjF,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;YAC3C,MAAM,aAAa,GAAG,SAAS,CAAA;YAE/B,IAAI,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC7C,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACjC,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,CAAC,GAAG,EAAE,CAAA;IAEZ,OAAO,YAAY,CAAA;AACpB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import * as AudioBufferConversion from '../audio/AudioBufferConversion.js';
2
- import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js';
2
+ import { wrapEmscriptenModuleHeap } from 'wasm-heap-manager';
3
3
  export async function detectVoiceActivity(rawAudio, frameDuration = 10, mode = 0) {
4
4
  if (rawAudio.sampleRate != 16000) {
5
5
  throw new Error('Audio sample rate must be 16KHz');
@@ -9,7 +9,7 @@ export async function detectVoiceActivity(rawAudio, frameDuration = 10, mode = 0
9
9
  }
10
10
  export async function fvad(samples, sampleRate, frameDuration, mode) {
11
11
  const m = await getFvadInstance();
12
- const wasmMemory = new WasmMemoryManager(m);
12
+ const wasmHeap = wrapEmscriptenModuleHeap(m);
13
13
  const fvad_new = m._fvad_new;
14
14
  const fvad_free = m._fvad_free;
15
15
  const fvad_reset = m._fvad_reset;
@@ -26,7 +26,7 @@ export async function fvad(samples, sampleRate, frameDuration, mode) {
26
26
  throw new Error(`fvad_set_mode failed for mode ${mode}`);
27
27
  }
28
28
  const frameSampleCount = Math.floor(sampleRate * (frameDuration / 1000));
29
- const frameSamplesRef = wasmMemory.allocInt16Array(frameSampleCount);
29
+ const frameSamplesRef = wasmHeap.allocInt16Array(frameSampleCount);
30
30
  const result = [];
31
31
  for (let sampleOffset = 0; sampleOffset < samples.length; sampleOffset += frameSampleCount) {
32
32
  const frame = samples.subarray(sampleOffset, sampleOffset + frameSampleCount);
@@ -39,7 +39,7 @@ export async function fvad(samples, sampleRate, frameDuration, mode) {
39
39
  result.push(fvadResult);
40
40
  }
41
41
  fvad_free(instancePtr);
42
- wasmMemory.freeAll();
42
+ wasmHeap.freeAll();
43
43
  return result;
44
44
  }
45
45
  let fvadInstance;
@@ -1 +1 @@
1
- {"version":3,"file":"WebRtcVAD.js","sourceRoot":"","sources":["../../src/voice-activity-detection/WebRtcVAD.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WebRtcVAD.js","sourceRoot":"","sources":["../../src/voice-activity-detection/WebRtcVAD.ts"],"names":[],"mappings":"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"}
package/docs/Tasklist.md CHANGED
@@ -7,7 +7,6 @@
7
7
  * IPA -> Kirshenbaum translation is still not completely similar to what is output by eSpeak. Also, in rare situations, it outputs characters that are not accepted by eSpeak and eSpeak errors. Investigate when that happens and how to improve on this
8
8
 
9
9
  ### Subtitles
10
- * Phrase splitting may split on number separators like the `,` in `100,000`. The new segmentation library would resolve that
11
10
 
12
11
  ### Browser extension
13
12
  * Investigate why WebSpeech events sometimes completely stop working in the middle of an utterance for no apparent reason. Sometimes this is permanent, until the extension is restarted. Is this a browser issue?
@@ -78,7 +77,6 @@
78
77
 
79
78
  ### API
80
79
  * Validate timelines to ensure timestamps are always increasing: no negative timestamps or timestamps over the duration of the audio. No sentences without words, etc. and correct if needed
81
- * See whether it's possible to detect and include / remove Emoji characters in timelines
82
80
  * Add support for phrases in timelines
83
81
  * Accept voice list caching options in `SynthesisOptions`
84
82
 
@@ -93,7 +91,6 @@
93
91
 
94
92
  ### Subtitles
95
93
  * Split long words if needed
96
- * Clauses shouldn't be split in the middle of numbers, like the `,` in `123,456`
97
94
  * Decide how many punctuation characters to allow before breaking to a new line (currently it's infinite)
98
95
  * If a subtitle is too short and at the end of the audio, try to extend it back if possible (for example, if the previous subtitle is already extended, take back from it)
99
96
  * Add more clause separators, for even more special cases
@@ -104,7 +101,6 @@
104
101
  * Option to disable alignment (only for some engines). Alternative: use a low granularity DTW setting that is very fast to compute
105
102
  * Find places to add commas (",") to improve speech fluency. VITS voices don't normally add speech breaks if there is no punctuation
106
103
  * An isolated dash " - " can be converted to a " , " to ensure there's a break in the speech
107
- * Ensure abbreviations like "Ph.d" or similar names are segmented and read correctly (does `cldr` treat it as a word? Maybe eSpeak doesn't recognize it as a word). "C#" and ".NET" as well
108
104
  * Find a way to manually reset voice list cache
109
105
  * When synthesized text isn't pre-split to sentences, apply sentence splits by using the existing method to convert the output of word timelines to sentence/segment timelines
110
106
  * Some `sapi` voices and `msspeech` languages output phones that are converted to Microsoft alphabet, not IPA symbols. Try to see if these can be translated to IPA
@@ -120,7 +116,7 @@
120
116
  ### Synthesis / preprocessing
121
117
  * Full date normalization (e.g. `21 August 2023`, `21 Aug 2023`, `August 21, 2023`)
122
118
  * Add support for capitalized-only rules, and possibly also all uppercase / all lowercase rules
123
- * Add support for multiple words in `precededBy` and `succeededBy`
119
+ * Add support for multiple consecutive words in `precededBy` and `followedBy` conditions
124
120
  * Support substituting to graphemes in lexicons, not only phonemes
125
121
  * Cache lexicons to avoid parsing the JSON each time it is loaded (this may not be needed for if the file is relatively small)
126
122
  * Is it possible to pre-phonemize common words like "the" or is it a bad idea / not necessary?
@@ -159,7 +155,6 @@
159
155
 
160
156
  ### Source separation / MDX-NET
161
157
  * Option to customize overlap
162
- * Add more models
163
158
 
164
159
  ### Server
165
160
  * Option to allow or disallow local file paths as arguments to API methods (as a security safeguard)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echogarden",
3
- "version": "2.6.0",
3
+ "version": "2.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",
@@ -52,27 +52,27 @@
52
52
  "echogarden": "./dist/cli/CLILauncher.js"
53
53
  },
54
54
  "dependencies": {
55
- "@aws-sdk/client-polly": "^3.799.0",
56
- "@aws-sdk/client-transcribe-streaming": "^3.799.0",
57
- "@echogarden/audio-io": "^0.3.0",
55
+ "@aws-sdk/client-polly": "^3.810.0",
56
+ "@aws-sdk/client-transcribe-streaming": "^3.810.0",
57
+ "@echogarden/audio-io": "^0.4.1",
58
58
  "@echogarden/espeak-ng-emscripten": "^0.3.3",
59
59
  "@echogarden/fasttext-wasm": "^0.1.0",
60
60
  "@echogarden/flite-wasi": "^0.1.1",
61
61
  "@echogarden/fvad-wasm": "^0.2.0",
62
62
  "@echogarden/gnuspeech-wasm": "^0.2.1",
63
+ "@echogarden/icu-segmentation-wasm": "^0.2.1",
63
64
  "@echogarden/pffft-wasm": "^0.4.2",
64
65
  "@echogarden/rnnoise-wasm": "^0.2.0",
65
66
  "@echogarden/rubberband-wasm": "^0.2.0",
66
67
  "@echogarden/sonic-wasm": "^0.2.0",
67
68
  "@echogarden/speex-resampler-wasm": "^0.3.0",
68
69
  "@echogarden/svoxpico-wasm": "^0.2.0",
69
- "@echogarden/transformers-nodejs-lite": "^2.17.1-lite.3",
70
+ "@echogarden/text-segmentation": "^0.3.1",
71
+ "@echogarden/transformers-nodejs-lite": "^2.17.1-lite.4",
72
+ "@echogarden/wave-codec": "^0.3.3",
70
73
  "@mozilla/readability": "^0.6.0",
71
- "alawmulaw": "^6.0.0",
72
74
  "chalk": "^5.4.1",
73
- "cldr-segmentation": "^2.2.1",
74
75
  "command-exists": "^1.2.9",
75
- "compromise": "^14.14.4",
76
76
  "fs-extra": "^11.3.0",
77
77
  "gaxios": "^6.7.1",
78
78
  "graceful-fs": "^4.2.11",
@@ -84,14 +84,16 @@
84
84
  "kuromoji": "^0.1.2",
85
85
  "microsoft-cognitiveservices-speech-sdk": "^1.43.1",
86
86
  "msgpack-lite": "^0.1.26",
87
- "onnxruntime-node": "^1.21.1",
88
- "openai": "^4.97.0",
87
+ "onnxruntime-node": "^1.22.0",
88
+ "openai": "^4.98.0",
89
+ "regexp-composer": "^0.3.0",
89
90
  "sam-js": "^0.3.1",
90
91
  "strip-ansi": "^7.1.0",
91
92
  "tar": "^7.4.3",
92
93
  "tiktoken": "^1.0.21",
93
94
  "tinyld": "^1.3.4",
94
95
  "wasm-feature-detect": "^1.8.0",
96
+ "wasm-heap-manager": "^0.2.2",
95
97
  "ws": "^8.18.2",
96
98
  "wtf_wikipedia": "^10.4.0"
97
99
  },
@@ -112,7 +114,7 @@
112
114
  "@types/graceful-fs": "^4.1.9",
113
115
  "@types/jsdom": "^21.1.7",
114
116
  "@types/msgpack-lite": "^0.1.11",
115
- "@types/node": "^22.15.3",
117
+ "@types/node": "^22.15.18",
116
118
  "@types/tar": "^6.1.13",
117
119
  "@types/ws": "^8.18.1",
118
120
  "ts-json-schema-generator": "^2.4.0",
@@ -3,7 +3,7 @@ import { Logger } from '../utilities/Logger.js'
3
3
  import { loadPackage } from '../utilities/PackageManager.js'
4
4
  import { alignDTWWindowed } from './DTWSequenceAlignmentWindowed.js'
5
5
  import { cosineDistance } from '../math/VectorMath.js'
6
- import { isPunctuation, isWord, splitToSentences, splitToWords } from '../nlp/Segmentation.js'
6
+ import { includesPunctuation, isWord, parseText } from '../nlp/Segmentation.js'
7
7
  import { Timeline, extractEntries } from '../utilities/Timeline.js'
8
8
 
9
9
  export async function alignTimelineToTextSemantically(timeline: Timeline, text: string, textLangCode: string) {
@@ -26,13 +26,12 @@ export async function alignTimelineToTextSemantically(timeline: Timeline, text:
26
26
 
27
27
  const timelineWordEntriesFiltered = timelineWordEntryGroups.flat()
28
28
 
29
- const textSentences = splitToSentences(text, textLangCode)
29
+ const segmentedText = await parseText(text, textLangCode)
30
30
 
31
31
  const textWordGroups: string[][] = []
32
32
 
33
- for (const sentenceText of textSentences) {
34
- let wordGroup = await splitToWords(sentenceText, textLangCode)
35
- wordGroup = wordGroup.filter(word => isWord(word))
33
+ for (const sentenceEntry of segmentedText.sentences) {
34
+ const wordGroup = sentenceEntry.words.nonPunctuationWords
36
35
 
37
36
  textWordGroups.push(wordGroup)
38
37
  }
@@ -197,8 +196,8 @@ export async function alignWordsToWordsSemantically(wordsGroups1: string[][], wo
197
196
 
198
197
  // Align
199
198
  function costFunction(a: TokenEmbeddingData, b: TokenEmbeddingData) {
200
- const aIsPunctuation = isPunctuation(a.text)
201
- const bIsPunctuation = isPunctuation(b.text)
199
+ const aIsPunctuation = includesPunctuation(a.text)
200
+ const bIsPunctuation = includesPunctuation(b.text)
202
201
 
203
202
  if (aIsPunctuation === bIsPunctuation) {
204
203
  return cosineDistance(a.embeddingVector, b.embeddingVector)
@@ -5,7 +5,7 @@ import { AudioSourceParam, RawAudio, ensureRawAudio, getRawAudioDuration, normal
5
5
  import { Logger } from '../utilities/Logger.js'
6
6
 
7
7
  import * as API from './API.js'
8
- import { Timeline, addTimeOffsetToTimeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
8
+ import { Timeline, addTimeOffsetToTimeline, addWordTextOffsetsToTimelineInPlace, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
9
9
  import { formatLanguageCodeWithName, getDefaultDialectForLanguageCodeIfPossible, getShortLanguageCode, parseLangIdentifier } from '../utilities/Locale.js'
10
10
  import { type WhisperAlignmentOptions } from '../recognition/WhisperSTT.js'
11
11
  import chalk from 'chalk'
@@ -329,7 +329,7 @@ export async function align(input: AudioSourceParam, transcript: string, options
329
329
  }
330
330
 
331
331
  // Add text offsets
332
- addWordTextOffsetsToTimeline(mappedTimeline, transcript)
332
+ addWordTextOffsetsToTimelineInPlace(mappedTimeline, transcript)
333
333
 
334
334
  // Make segment timeline
335
335
  const { segmentTimeline } = await wordTimelineToSegmentSentenceTimeline(mappedTimeline, transcript, language, options.plainText?.paragraphBreaks, options.plainText?.whitespace)
@@ -5,7 +5,7 @@ import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevelInPlace,
5
5
  import { Logger } from '../utilities/Logger.js'
6
6
 
7
7
  import * as API from './API.js'
8
- import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
8
+ import { Timeline, addWordTextOffsetsToTimelineInPlace, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
9
9
  import { formatLanguageCodeWithName, parseLangIdentifier } from '../utilities/Locale.js'
10
10
  import { loadPackage } from '../utilities/PackageManager.js'
11
11
  import chalk from 'chalk'
@@ -312,7 +312,7 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
312
312
  }
313
313
 
314
314
  // Add text offsets
315
- addWordTextOffsetsToTimeline(timeline, transcript)
315
+ addWordTextOffsetsToTimelineInPlace(timeline, transcript)
316
316
 
317
317
  // Make segment timeline
318
318
  const { segmentTimeline } = await wordTimelineToSegmentSentenceTimeline(timeline, transcript, languageCode, 'single', 'preserve')
@@ -48,7 +48,7 @@ export async function isolate(input: AudioSourceParam, options: SourceSeparation
48
48
  // Release memory for the converted input audio since it's not needed anymore
49
49
  inputRawAudioAs44100Stereo = undefined
50
50
 
51
- await logger.startAsync(`Convert isolated audio to back original sample rate (${inputRawAudio.sampleRate} Hz) and channel count (${inputRawAudio.audioChannels.length})`)
51
+ await logger.startAsync(`Convert isolated audio back to original sample rate (${inputRawAudio.sampleRate} Hz) and channel count (${inputRawAudio.audioChannels.length})`)
52
52
  isolatedRawAudio = await ensureRawAudio(isolatedRawAudio, inputRawAudio.sampleRate, inputRawAudio.audioChannels.length)
53
53
 
54
54
  await logger.startAsync(`Subtract from original waveform to extract background audio`)
@@ -4,7 +4,7 @@ import { logToStderr } from '../utilities/Utilities.js'
4
4
  import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevelInPlace, trimAudioEnd } from '../audio/AudioUtilities.js'
5
5
  import { Logger } from '../utilities/Logger.js'
6
6
 
7
- import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
7
+ import { Timeline, addWordTextOffsetsToTimelineInPlace, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
8
8
  import { type WhisperOptions } from '../recognition/WhisperSTT.js'
9
9
  import { formatLanguageCodeWithName, getShortLanguageCode, normalizeIdentifierToLanguageCode, parseLangIdentifier } from '../utilities/Locale.js'
10
10
  import { EngineMetadata } from './Common.js'
@@ -201,7 +201,7 @@ export async function translateSpeech(input: AudioSourceParam, options: SpeechTr
201
201
  }
202
202
 
203
203
  if (wordTimeline) {
204
- addWordTextOffsetsToTimeline(wordTimeline, transcript)
204
+ addWordTextOffsetsToTimelineInPlace(wordTimeline, transcript)
205
205
  }
206
206
 
207
207
  if (!segmentTimeline) {
@@ -6,7 +6,7 @@ import { clip, sha256AsHex, stringifyAndFormatJson, logToStderr, yieldToEventLoo
6
6
  import { RawAudio, concatAudioSegments, downmixToMono, encodeRawAudioToWave, getSamplePeakDecibels, getEmptyRawAudio, getRawAudioDuration, trimAudioEnd, trimAudioStart, attenuateIfClippingInPlace, normalizeAudioLevelInPlace } from '../audio/AudioUtilities.js'
7
7
  import { Logger } from '../utilities/Logger.js'
8
8
 
9
- import { isWordOrSymbolWord, splitToParagraphs, splitToSentences } from '../nlp/Segmentation.js'
9
+ import { isWordOrSymbolWord, parseText, splitToParagraphs } from '../nlp/Segmentation.js'
10
10
  import { type RubberbandOptions } from '../dsp/Rubberband.js'
11
11
  import { loadLexiconsForLanguage } from '../nlp/Lexicon.js'
12
12
 
@@ -116,9 +116,9 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
116
116
  let timeOffset = 0
117
117
 
118
118
  for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
119
- const segmentText = segments[segmentIndex].trim()
119
+ const segmentText = segments[segmentIndex]
120
120
 
121
- logger.log(`\n${chalk.magentaBright(`Synthesizing segment ${segmentIndex + 1}/${segments.length}`)}: '${segmentText}'`)
121
+ logger.log(`\n${chalk.magentaBright(`Synthesizing segment ${segmentIndex + 1}/${segments.length}`)}: '${segmentText.trim()}'`)
122
122
 
123
123
  const segmentStartTime = timeOffset
124
124
 
@@ -132,9 +132,9 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
132
132
 
133
133
  let sentences: string[]
134
134
 
135
- if ((options.splitToSentences || options.engine == 'vits') && !options.ssml) {
136
- sentences = splitToSentences(segmentText, options.language!)
137
- sentences = sentences.filter(sentence => sentence.trim() != '')
135
+ if ((options.splitToSentences || options.engine === 'vits' || options.engine === 'kokoro') && !options.ssml) {
136
+ const parsedText = await parseText(segmentText, options.language!)
137
+ sentences = parsedText.sentences.map(sentenceEntry => sentenceEntry.text)
138
138
 
139
139
  if (sentences.length == 0) {
140
140
  sentences = ['']
@@ -156,7 +156,7 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
156
156
 
157
157
  const sentenceText = sentences[sentenceIndex].trim()
158
158
 
159
- logger.log(`\n${chalk.magentaBright(`Synthesizing sentence ${sentenceIndex + 1}/${sentences.length}`)}: "${sentenceText}"`)
159
+ logger.log(`\n${chalk.magentaBright(`Synthesizing sentence ${sentenceIndex + 1}/${sentences.length}`)}: "${sentenceText.trim()}"`)
160
160
 
161
161
  const sentenceStartTime = timeOffset
162
162
 
@@ -4,7 +4,7 @@ import { SubtitlesConfig } from '../subtitles/Subtitles.js'
4
4
  import { formatLanguageCodeWithName, getShortLanguageCode, parseLangIdentifier } from '../utilities/Locale.js'
5
5
  import { Logger } from '../utilities/Logger.js'
6
6
  import { extendDeep } from '../utilities/ObjectUtilities.js'
7
- import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
7
+ import { Timeline, addWordTextOffsetsToTimelineInPlace, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
8
8
  import * as API from './API.js'
9
9
 
10
10
  export async function alignTimelineTranslation(inputTimeline: Timeline, translatedTranscript: string, options: TimelineTranslationAlignmentOptions): Promise<TimelineTranslationAlignmentResult> {
@@ -95,7 +95,7 @@ export async function alignTimelineTranslation(inputTimeline: Timeline, translat
95
95
 
96
96
  logger.start(`Postprocess timeline`)
97
97
 
98
- addWordTextOffsetsToTimeline(mappedWordTimeline, translatedTranscript)
98
+ addWordTextOffsetsToTimelineInPlace(mappedWordTimeline, translatedTranscript)
99
99
 
100
100
  const { segmentTimeline: mappedTimeline } = await wordTimelineToSegmentSentenceTimeline(mappedWordTimeline, translatedTranscript, targetLanguage)
101
101
 
@@ -5,7 +5,7 @@ import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevelInPlace,
5
5
  import { Logger } from '../utilities/Logger.js'
6
6
 
7
7
  import * as API from './API.js'
8
- import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
8
+ import { Timeline, addWordTextOffsetsToTimelineInPlace, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
9
9
  import { formatLanguageCodeWithName, getShortLanguageCode, normalizeIdentifierToLanguageCode, parseLangIdentifier } from '../utilities/Locale.js'
10
10
  import { type WhisperAlignmentOptions } from '../recognition/WhisperSTT.js'
11
11
  import chalk from 'chalk'
@@ -124,7 +124,7 @@ export async function alignTranslation(input: AudioSourceParam, translatedTransc
124
124
  }
125
125
 
126
126
  // Add text offsets
127
- addWordTextOffsetsToTimeline(mappedTimeline, translatedTranscript)
127
+ addWordTextOffsetsToTimelineInPlace(mappedTimeline, translatedTranscript)
128
128
 
129
129
  // Make segment timeline
130
130
  const { segmentTimeline } = await wordTimelineToSegmentSentenceTimeline(mappedTimeline, translatedTranscript, sourceLanguage, options.plainText?.paragraphBreaks, options.plainText?.whitespace)