echogarden 2.0.12 → 2.0.14

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/docs/Tasklist.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  ## Bugs
4
4
 
5
-
6
- ### eSpeak
5
+ ### eSpeak-ng
7
6
 
8
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
9
8
 
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
  ### Browser extension
11
13
  * 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?
12
14
  * If a request is made and the server takes too much time to respond, the service worker may sleep and the request never canceled
@@ -16,28 +18,24 @@
16
18
 
17
19
  ### External bugs
18
20
 
19
- * `espeak-ng`: 'Oh dear!”' is read as "oh dear exclamation mark", because of the special quote character following the exclamation mark
20
21
  * `espeak-ng`: [Marker right after sentence end is not reported as an event](https://github.com/espeak-ng/espeak-ng/issues/920)
21
- * `espeak-ng`: On Japanese text, it says "Chinese character" or "Japanese character" for characters it doesn't know
22
+ * `espeak-ng`: On Japanese text, it says "Chinese letter" or "Japanese letter" for characters it doesn't support
22
23
  * `espeak-ng`: Broken markers on the Korean voice
23
24
  * `wtf_wikipedia` Sometimes fails on `getResult.js` without throwing a humanly readable error
24
25
  * `wtf_wikipedia` Sometimes captures markup like `.svg` etc.
25
26
  * `msspeech`: Initialization fails on Chinese and Japanese voices (but not Korean)
26
27
  * `compromise`: Slow initialization time. Currently, it takes more than a second
27
- * Chromium doesn't fire timer events when cursor is positioned over scrollbar or body margins
28
- * `whisper.cpp`: Timestamps aren't very accurate when `enableDTW` is set. There's a constant lag
29
- * Node.js WASI for `flite` on Node `v21.7.2` and `v20.12.1` is intermittently crashing the process when `run` is called
28
+ * Browser extension: Chromium doesn't fire timer events when cursor is positioned over scrollbar or body margins
30
29
 
31
30
  ## Features and enhancements
32
31
 
33
32
  ### CLI
34
33
  * Show names of files written to disk. This is useful for cases where a file is auto-renamed to prevent overwriting existing data
35
34
  * Restrict input media file extensions to ensure that invalid files are not passed to FFmpeg
36
- * Consider what to do with non-supported templates like `[hello]`
37
35
  * Show a message when a new version is available
38
36
  * Figure out which terminal outputs should go to stdout, or if that's a good idea at all
39
37
  * Print available synthesis voices when no voice matches (or suggest near matches)
40
- * `transcribe` may also accept `http://` and `https://` URLs and pull the remote media file
38
+ * `transcribe`: accept `http://` and `https://` URLs and pull the remote media file
41
39
  * Make `enum` options case-insensitive if possible
42
40
  * More fine-grained intermediate progress report for operations
43
41
  * Suggest possible correction on the error of not using `=`, e.g. `speed 0.9` instead of `speed=0.9`
@@ -93,13 +91,11 @@
93
91
  ### Text language detection
94
92
  * Deploy and add the new n-gram based text language detection model
95
93
 
96
- ### Segmentation
97
- * See if it's possible or useful to reliably use eSpeak as a segmentation engine.
98
-
99
94
  ### Subtitles
100
- * Split long words if needed. This is especially important for Chinese and Japanese
101
- * 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)
95
+ * Split long words if needed
96
+ * Clauses shouldn't be split in the middle of numbers, like the `,` in `123,456`
102
97
  * Decide how many punctuation characters to allow before breaking to a new line (currently it's infinite)
98
+ * 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)
103
99
  * Add more clause separators, for even more special cases
104
100
  * Add option to output usable word or phoneme-level caption files (investigate how it's done on YouTube auto-captions)
105
101
  * Parse VTT's language
@@ -155,7 +151,6 @@
155
151
  ### Alignment
156
152
 
157
153
  ### Alignment / DTW
158
- * Accept percentages like `20%` in the `windowDuration` option
159
154
  * For the `granularity` option, add more granularities like `xxx-low` and `xxxx-low` (should the naming be changed? Maybe transition to a new naming scheme?)
160
155
  * Add and test official support for more than 6 hours of audio
161
156
 
@@ -255,17 +250,16 @@
255
250
  * [PlayHT](https://play.ht/) speech synthesis cloud service
256
251
  * [Deepgram](https://deepgram.com/) cloud text-to-speech API
257
252
  * [Assembly AI](https://www.assemblyai.com/) cloud speech recognition API
253
+ * [Picovoice Orca](https://github.com/Picovoice/orca) local text-to-speech
258
254
  * Coqui STT server connection
259
255
  * [MarbleNet VAD](https://github.com/NVIDIA/NeMo/blob/main/tutorials/asr/Online_Offline_Microphone_VAD_Demo.ipynb), included of the NVIDIA NeMo framework, can be exported to ONNX
260
256
  * Silero text enhancement engine can be ported to ONNX
261
- * See what can be done for supporting WinRT speech: in particular `windows.media.speechsynthesis` and `windows.media.speechrecognition` support, possibly using NodeRT or some other method
262
257
  * Figure out how to support `julius` speech recognition via WASM
263
258
  * Any way to support RHVoice?
264
259
 
265
260
  ## Maybe?
266
261
 
267
262
  * Using a machine translation model to provide speech translation to languages other than English
268
- * Is it possible to get sentence boundaries without punctuation using NLP techniques like part-of-speech tagging?
269
263
 
270
264
  ## May or may not be good ideas
271
265
 
@@ -274,6 +268,7 @@
274
268
 
275
269
  ## Other ideas
276
270
 
271
+ * Speaker diarization
277
272
  * Support alignment of EPUB 3 eBooks with a corresponding audiobook
278
273
  * Voice cloning
279
274
  * Speech-to-speech voice conversion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echogarden",
3
- "version": "2.0.12",
3
+ "version": "2.0.14",
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,9 +52,9 @@
52
52
  "echogarden": "./dist/cli/CLILauncher.js"
53
53
  },
54
54
  "dependencies": {
55
- "@aws-sdk/client-polly": "^3.699.0",
56
- "@aws-sdk/client-transcribe-streaming": "^3.699.0",
57
- "@echogarden/audio-io": "^0.2.3",
55
+ "@aws-sdk/client-polly": "^3.716.0",
56
+ "@aws-sdk/client-transcribe-streaming": "^3.716.0",
57
+ "@echogarden/audio-io": "^0.3.0",
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",
@@ -68,7 +68,7 @@
68
68
  "@echogarden/transformers-nodejs-lite": "^2.17.1-lite.3",
69
69
  "@mozilla/readability": "^0.5.0",
70
70
  "alawmulaw": "^6.0.0",
71
- "chalk": "^5.3.0",
71
+ "chalk": "^5.4.1",
72
72
  "cldr-segmentation": "^2.2.1",
73
73
  "command-exists": "^1.2.9",
74
74
  "compromise": "^14.14.3",
@@ -81,14 +81,14 @@
81
81
  "jsdom": "^25.0.1",
82
82
  "json5": "^2.2.3",
83
83
  "kuromoji": "^0.1.2",
84
- "microsoft-cognitiveservices-speech-sdk": "^1.41.0",
84
+ "microsoft-cognitiveservices-speech-sdk": "^1.42.0",
85
85
  "msgpack-lite": "^0.1.26",
86
86
  "onnxruntime-node": "^1.20.1",
87
- "openai": "^4.76.0",
87
+ "openai": "^4.77.0",
88
88
  "sam-js": "^0.3.1",
89
89
  "strip-ansi": "^7.1.0",
90
90
  "tar": "^7.4.3",
91
- "tiktoken": "^1.0.17",
91
+ "tiktoken": "^1.0.18",
92
92
  "tinyld": "^1.3.4",
93
93
  "wasm-feature-detect": "^1.8.0",
94
94
  "ws": "^8.18.0",
@@ -111,7 +111,7 @@
111
111
  "@types/graceful-fs": "^4.1.9",
112
112
  "@types/jsdom": "^21.1.7",
113
113
  "@types/msgpack-lite": "^0.1.11",
114
- "@types/node": "^22.10.1",
114
+ "@types/node": "^22.10.2",
115
115
  "@types/tar": "^6.1.13",
116
116
  "@types/ws": "^8.5.13",
117
117
  "ts-json-schema-generator": "^2.3.0",
@@ -1,4 +1,4 @@
1
- import { TypedArray, TypedArrayConstructor } from "../typings/TypedArray.js"
1
+ import { TypedArray, TypedArrayConstructor } from '../typings/TypedArray.js'
2
2
 
3
3
  export class DynamicTypedArray<T extends TypedArray> {
4
4
  elements: TypedArray
@@ -9,14 +9,14 @@ export class DynamicTypedArray<T extends TypedArray> {
9
9
  }
10
10
 
11
11
  add(newElement: number) {
12
- const length = this.length
12
+ const newLength = this.length + 1
13
13
 
14
- if (length === this.elements.length) {
15
- this.ensureCapacity(length + 1)
14
+ if (newLength > this.capacity) {
15
+ this.ensureCapacity(newLength)
16
16
  }
17
17
 
18
- this.elements[length] = newElement
19
- this.length += 1
18
+ this.elements[this.length] = newElement
19
+ this.length = newLength
20
20
  }
21
21
 
22
22
  addMany(...newElements: number[]) {
@@ -24,16 +24,18 @@ export class DynamicTypedArray<T extends TypedArray> {
24
24
  }
25
25
 
26
26
  addArray(newElements: ArrayLike<number>) {
27
- const addedCount = newElements.length
27
+ const newLength = this.length + newElements.length
28
28
 
29
- this.ensureCapacity(this.length + addedCount)
29
+ if (newLength > this.capacity) {
30
+ this.ensureCapacity(newLength)
31
+ }
30
32
 
31
33
  this.elements.set(newElements, this.length)
32
- this.length += addedCount
34
+ this.length = newLength
33
35
  }
34
36
 
35
37
  ensureCapacity(requiredCapacity: number) {
36
- if (requiredCapacity > this.elements.length) {
38
+ if (requiredCapacity > this.capacity) {
37
39
  const newCapacity = requiredCapacity * 2
38
40
 
39
41
  const newElements = new this.TypedArrayConstructor(newCapacity)
@@ -43,6 +45,10 @@ export class DynamicTypedArray<T extends TypedArray> {
43
45
  }
44
46
  }
45
47
 
48
+ get capacity() {
49
+ return this.elements.length
50
+ }
51
+
46
52
  toTypedArray() {
47
53
  return this.elements.subarray(0, this.length) as T
48
54
  }
@@ -1569,7 +1569,7 @@ export class Whisper {
1569
1569
 
1570
1570
  const timestampTokensCount = 1501
1571
1571
 
1572
- for (let i = 0; i < timestampTokensCount; i++) {
1572
+ for (let i = 0; i <= timestampTokensCount; i++) {
1573
1573
  const tokenIndex = this.tokenConfig.timestampTokensStart + i
1574
1574
  const tokenTime = this.timestampTokenToSeconds(tokenIndex)
1575
1575
 
@@ -1727,11 +1727,15 @@ export class Whisper {
1727
1727
  throw new Error(`Invalid timestamp token: ${timestampToken}`)
1728
1728
  }
1729
1729
 
1730
- return (timestampToken - this.tokenConfig.timestampTokensStart) * 0.02
1730
+ let seconds = (timestampToken - this.tokenConfig.timestampTokensStart) * 0.02
1731
+ seconds = clip(seconds, 0.0, 30.0)
1732
+
1733
+ return seconds
1731
1734
  }
1732
1735
 
1733
1736
  isValidToken(token: number) {
1734
- return token < this.tokenConfig.timestampTokensEnd
1737
+ //return token < this.tokenConfig.timestampTokensEnd
1738
+ return token <= this.tokenConfig.timestampTokensEnd
1735
1739
  }
1736
1740
 
1737
1741
  assertIsValidToken(token: number) {
@@ -1,11 +0,0 @@
1
- import { DynamicUint8Array } from "../data-structures/DynamicTypedArray.js";
2
- export declare function encodeUnsignedInt31(value: number, outEncodedData: DynamicUint8Array): void;
3
- export declare function decodeUnsignedInt31(encodedData: ArrayLike<number>, readOffset: number): DecodedValueAndReadOffset;
4
- export declare function encodeSignedInt32(value: number, outEncodedData: DynamicUint8Array): void;
5
- export declare function decodeSignedInt32(encodedData: ArrayLike<number>, readOffset: number): DecodedValueAndReadOffset;
6
- export interface DecodedValueAndReadOffset {
7
- decodedValue: number;
8
- readOffset: number;
9
- }
10
- export declare function testLPVarintSigned(): void;
11
- export declare function testLPVarintUnsigned(): void;
@@ -1,187 +0,0 @@
1
- import { createDynamicUint8Array } from "../data-structures/DynamicTypedArray.js";
2
- import { logToStderr } from "../utilities/Utilities.js";
3
- ////////////////////////////////////////////////////////////////////////////////////
4
- // Encode unsigned integer
5
- ////////////////////////////////////////////////////////////////////////////////////
6
- export function encodeUnsignedInt31(value, outEncodedData) {
7
- value = value >>> 0;
8
- if (value < (2 ** 7)) {
9
- outEncodedData.add(value);
10
- }
11
- else if (value < (2 ** 14)) {
12
- outEncodedData.addMany((value & 0b00111111) | 0b10000000, value >>> 6);
13
- }
14
- else if (value < (2 ** 21)) {
15
- outEncodedData.addMany((value & 0b00011111) | 0b11000000, value >>> 5, value >>> 13);
16
- }
17
- else if (value < (2 ** 28)) {
18
- outEncodedData.addMany((value & 0b00001111) | 0b11100000, value >>> 4, value >>> 12, value >>> 20);
19
- }
20
- else {
21
- outEncodedData.addMany(0b11110000, value, value >>> 8, value >>> 16, value >>> 24);
22
- }
23
- }
24
- ////////////////////////////////////////////////////////////////////////////////////
25
- // Decode unsigned integer
26
- ////////////////////////////////////////////////////////////////////////////////////
27
- export function decodeUnsignedInt31(encodedData, readOffset) {
28
- readOffset = readOffset | 0;
29
- const byte0 = encodedData[readOffset++];
30
- if ((byte0 & 0b10000000) === 0) {
31
- // 1 byte
32
- let decodedValue = byte0;
33
- return { decodedValue, readOffset };
34
- }
35
- const byte1 = encodedData[readOffset++];
36
- if ((byte0 & 0b01000000) === 0) {
37
- // 2 bytes
38
- let decodedValue = (byte0 & 0b00111111) |
39
- (byte1 << 6);
40
- return { decodedValue, readOffset };
41
- }
42
- const byte2 = encodedData[readOffset++];
43
- if ((byte0 & 0b00100000) === 0) {
44
- // 3 bytes
45
- let decodedValue = (byte0 & 0b00011111) |
46
- (byte1 << 5) |
47
- (byte2 << 13);
48
- return { decodedValue, readOffset };
49
- }
50
- const byte3 = encodedData[readOffset++];
51
- if ((byte0 & 0b00010000) === 0) {
52
- // 4 bytes
53
- let decodedValue = (byte0 & 0b00001111) |
54
- (byte1 << 4) |
55
- (byte2 << 12) |
56
- (byte3 << 20);
57
- return { decodedValue, readOffset };
58
- }
59
- const byte4 = encodedData[readOffset++];
60
- if (byte0 === 0b11110000) {
61
- // 5 bytes
62
- let decodedValue = (byte1) |
63
- (byte2 << 8) |
64
- (byte3 << 16) |
65
- (byte4 << 24);
66
- return { decodedValue, readOffset };
67
- }
68
- throw new Error(`Encountered a value that is encoded with more than 5 bytes (beyond Unsigned Int31 range).`);
69
- }
70
- ////////////////////////////////////////////////////////////////////////////////////
71
- // Encode signed integer
72
- ////////////////////////////////////////////////////////////////////////////////////
73
- export function encodeSignedInt32(value, outEncodedData) {
74
- const absValue = Math.abs(value | 0);
75
- if (absValue < (2 ** 6)) {
76
- outEncodedData.add(value & 0b01111111);
77
- }
78
- else if (absValue < (2 ** 13)) {
79
- outEncodedData.addMany((value & 0b00111111) | 0b10000000, value >> 6);
80
- }
81
- else if (absValue < (2 ** 20)) {
82
- outEncodedData.addMany((value & 0b00011111) | 0b11000000, value >> 5, value >> 13);
83
- }
84
- else if (absValue < (2 ** 27)) {
85
- outEncodedData.addMany((value & 0b00001111) | 0b11100000, value >> 4, value >> 12, value >> 20);
86
- }
87
- else {
88
- outEncodedData.addMany(0b11110000, value, value >> 8, value >> 16, value >> 24);
89
- }
90
- }
91
- ////////////////////////////////////////////////////////////////////////////////////
92
- // Decode signed integer
93
- ////////////////////////////////////////////////////////////////////////////////////
94
- export function decodeSignedInt32(encodedData, readOffset) {
95
- const byte0 = encodedData[readOffset++];
96
- if ((byte0 & 0b10000000) === 0) {
97
- // 1 byte
98
- let decodedValue = byte0;
99
- if ((byte0 & 0b01000000) !== 0) {
100
- decodedValue |= (-1 << 7);
101
- }
102
- return { decodedValue, readOffset };
103
- }
104
- const byte1 = encodedData[readOffset++];
105
- if ((byte0 & 0b01000000) === 0) {
106
- // 2 bytes
107
- let decodedValue = (byte0 & 0b00111111) |
108
- (byte1 << 6);
109
- if ((byte1 & 0b10000000) !== 0) {
110
- decodedValue |= (-1 << 14);
111
- }
112
- return { decodedValue, readOffset };
113
- }
114
- const byte2 = encodedData[readOffset++];
115
- if ((byte0 & 0b00100000) === 0) {
116
- // 3 bytes
117
- let decodedValue = (byte0 & 0b00011111) |
118
- (byte1 << 5) |
119
- (byte2 << 13);
120
- if ((byte2 & 0b10000000) !== 0) {
121
- decodedValue |= (-1 << 21);
122
- }
123
- return { decodedValue, readOffset };
124
- }
125
- const byte3 = encodedData[readOffset++];
126
- if ((byte0 & 0b00010000) === 0) {
127
- // 4 bytes
128
- let decodedValue = (byte0 & 0b00001111) |
129
- (byte1 << 4) |
130
- (byte2 << 12) |
131
- (byte3 << 20);
132
- if ((byte3 & 0b10000000) !== 0) {
133
- decodedValue |= (-1 << 28);
134
- }
135
- return { decodedValue, readOffset };
136
- }
137
- const byte4 = encodedData[readOffset++];
138
- if (byte0 === 0b11110000) {
139
- // 5 bytes
140
- let decodedValue = (byte1) |
141
- (byte2 << 8) |
142
- (byte3 << 16) |
143
- (byte4 << 24);
144
- return { decodedValue, readOffset };
145
- }
146
- throw new Error(`Encountered a value that is encoded with more than 5 bytes (beyond int32 range).`);
147
- }
148
- ////////////////////////////////////////////////////////////////////////////////////
149
- // Tests
150
- ////////////////////////////////////////////////////////////////////////////////////
151
- export function testLPVarintSigned() {
152
- const encodedBytes = createDynamicUint8Array();
153
- function runTest(testValue) {
154
- encodedBytes.clear();
155
- encodeSignedInt32(testValue, encodedBytes);
156
- const { decodedValue } = decodeSignedInt32(encodedBytes.elements, 0);
157
- if (decodedValue !== testValue) {
158
- throw new Error(`Expected ${testValue} but got ${decodedValue}`);
159
- }
160
- }
161
- for (let i = -(2 ** 26); i < 2 ** 26; i++) {
162
- if (i % 1000000 === 0) {
163
- logToStderr(i);
164
- }
165
- runTest(i);
166
- }
167
- const x = 1;
168
- }
169
- export function testLPVarintUnsigned() {
170
- const encodedBytes = createDynamicUint8Array();
171
- function runTest(testValue) {
172
- encodedBytes.clear();
173
- encodeUnsignedInt31(testValue, encodedBytes);
174
- const { decodedValue } = decodeUnsignedInt31(encodedBytes.elements, 0);
175
- if (decodedValue !== testValue) {
176
- throw new Error(`Expected ${testValue} but got ${decodedValue}`);
177
- }
178
- }
179
- for (let i = 0; i < 2 ** 31; i++) {
180
- if (i % 1000000 === 0) {
181
- logToStderr(i);
182
- }
183
- runTest(i);
184
- }
185
- const x = 1;
186
- }
187
- //# sourceMappingURL=LPVarInt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LPVarInt.js","sourceRoot":"","sources":["../../src/encodings/LPVarInt.ts"],"names":[],"mappings":"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"}