echogarden 1.4.4 → 1.6.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 (240) hide show
  1. package/data/schemas/options.json +310 -25
  2. package/dist/alignment/DTWMfccSequenceAlignment.d.ts +1 -1
  3. package/dist/alignment/DTWMfccSequenceAlignment.js +5 -5
  4. package/dist/alignment/DTWSequenceAlignmentWindowed.js +1 -3
  5. package/dist/alignment/DTWSequenceAlignmentWindowed.js.map +1 -1
  6. package/dist/alignment/{TextAlignment.d.ts → SemanticTextAlignment.d.ts} +4 -2
  7. package/dist/alignment/SemanticTextAlignment.js +336 -0
  8. package/dist/alignment/SemanticTextAlignment.js.map +1 -0
  9. package/dist/alignment/SpeechAlignment.d.ts +4 -3
  10. package/dist/alignment/SpeechAlignment.js +130 -39
  11. package/dist/alignment/SpeechAlignment.js.map +1 -1
  12. package/dist/api/API.d.ts +7 -3
  13. package/dist/api/API.js +7 -2
  14. package/dist/api/API.js.map +1 -1
  15. package/dist/api/APIOptions.d.ts +4 -1
  16. package/dist/api/Alignment.d.ts +1 -1
  17. package/dist/api/Alignment.js +13 -5
  18. package/dist/api/Alignment.js.map +1 -1
  19. package/dist/api/LanguageDetectionCommon.d.ts +6 -0
  20. package/dist/api/LanguageDetectionCommon.js +2 -0
  21. package/dist/api/LanguageDetectionCommon.js.map +1 -0
  22. package/dist/api/Recognition.js.map +1 -1
  23. package/dist/api/{LanguageDetection.d.ts → SpeechLanguageDetection.d.ts} +1 -25
  24. package/dist/api/{LanguageDetection.js → SpeechLanguageDetection.js} +1 -68
  25. package/dist/api/SpeechLanguageDetection.js.map +1 -0
  26. package/dist/api/{Translation.js → SpeechTranslation.js} +3 -3
  27. package/dist/api/SpeechTranslation.js.map +1 -0
  28. package/dist/api/Synthesis.d.ts +0 -1
  29. package/dist/api/Synthesis.js +4 -4
  30. package/dist/api/TextLanguageDetection.d.ts +21 -0
  31. package/dist/api/TextLanguageDetection.js +67 -0
  32. package/dist/api/TextLanguageDetection.js.map +1 -0
  33. package/dist/api/TextTranslation.d.ts +25 -0
  34. package/dist/api/TextTranslation.js +101 -0
  35. package/dist/api/TextTranslation.js.map +1 -0
  36. package/dist/api/TimelineTranslationAlignment.d.ts +23 -0
  37. package/dist/api/TimelineTranslationAlignment.js +92 -0
  38. package/dist/api/TimelineTranslationAlignment.js.map +1 -0
  39. package/dist/api/TranscriptAndTranslationAlignment.d.ts +35 -0
  40. package/dist/api/TranscriptAndTranslationAlignment.js +78 -0
  41. package/dist/api/TranscriptAndTranslationAlignment.js.map +1 -0
  42. package/dist/api/TranslationAlignment.d.ts +4 -3
  43. package/dist/api/TranslationAlignment.js +9 -8
  44. package/dist/api/TranslationAlignment.js.map +1 -1
  45. package/dist/api/VoiceActivityDetection.js +16 -1
  46. package/dist/api/VoiceActivityDetection.js.map +1 -1
  47. package/dist/audio/AudioBufferConversion.d.ts +0 -1
  48. package/dist/audio/AudioPlayer.d.ts +0 -1
  49. package/dist/audio/AudioPlayer.js +62 -41
  50. package/dist/audio/AudioPlayer.js.map +1 -1
  51. package/dist/audio/AudioUtilities.d.ts +0 -1
  52. package/dist/cli/CLI.d.ts +28 -7
  53. package/dist/cli/CLI.js +265 -37
  54. package/dist/cli/CLI.js.map +1 -1
  55. package/dist/codecs/FFMpegTranscoder.d.ts +0 -1
  56. package/dist/codecs/FFMpegTranscoder.js +7 -0
  57. package/dist/codecs/FFMpegTranscoder.js.map +1 -1
  58. package/dist/codecs/TIMITCodec.d.ts +0 -1
  59. package/dist/codecs/WaveCodec.d.ts +0 -1
  60. package/dist/dsp/FFT.d.ts +1 -1
  61. package/dist/dsp/FFT.js +6 -0
  62. package/dist/dsp/FFT.js.map +1 -1
  63. package/dist/dsp/KWeightingFilter.js +1 -1
  64. package/dist/dsp/KWeightingFilter.js.map +1 -1
  65. package/dist/dsp/MelSpectogram.d.ts +3 -2
  66. package/dist/dsp/MelSpectogram.js +14 -8
  67. package/dist/dsp/MelSpectogram.js.map +1 -1
  68. package/dist/math/VectorMath.d.ts +9 -9
  69. package/dist/math/VectorMath.js +10 -10
  70. package/dist/math/VectorMath.js.map +1 -1
  71. package/dist/nlp/ChineseSegmentation.js +4 -4
  72. package/dist/nlp/ChineseSegmentation.js.map +1 -1
  73. package/dist/nlp/Segmentation.d.ts +2 -2
  74. package/dist/nlp/Segmentation.js +20 -13
  75. package/dist/nlp/Segmentation.js.map +1 -1
  76. package/dist/recognition/OpenAICloudSTT.d.ts +2 -1
  77. package/dist/recognition/OpenAICloudSTT.js +30 -19
  78. package/dist/recognition/OpenAICloudSTT.js.map +1 -1
  79. package/dist/recognition/SileroSTT.d.ts +0 -1
  80. package/dist/recognition/WhisperCppSTT.d.ts +3 -3
  81. package/dist/recognition/WhisperCppSTT.js +21 -9
  82. package/dist/recognition/WhisperCppSTT.js.map +1 -1
  83. package/dist/recognition/WhisperSTT.d.ts +9 -6
  84. package/dist/recognition/WhisperSTT.js +227 -46
  85. package/dist/recognition/WhisperSTT.js.map +1 -1
  86. package/dist/server/Client.d.ts +3 -4
  87. package/dist/server/Client.js.map +1 -1
  88. package/dist/server/Worker.d.ts +3 -3
  89. package/dist/server/Worker.js +3 -2
  90. package/dist/server/Worker.js.map +1 -1
  91. package/dist/source-separation/MDXNetSourceSeparation.d.ts +0 -1
  92. package/dist/source-separation/MDXNetSourceSeparation.js +1 -1
  93. package/dist/source-separation/MDXNetSourceSeparation.js.map +1 -1
  94. package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.d.ts +12 -0
  95. package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.js +68 -0
  96. package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.js.map +1 -0
  97. package/dist/speech-language-detection/SileroLanguageDetection.d.ts +1 -2
  98. package/dist/speech-language-detection/SileroLanguageDetection.js +1 -1
  99. package/dist/speech-language-detection/SileroLanguageDetection.js.map +1 -1
  100. package/dist/subtitles/Subtitles.js +2 -2
  101. package/dist/subtitles/Subtitles.js.map +1 -1
  102. package/dist/synthesis/GoogleCloudTTS.d.ts +0 -1
  103. package/dist/synthesis/GoogleTranslateTTS.d.ts +0 -1
  104. package/dist/synthesis/GoogleTranslateTTS.js +6 -21
  105. package/dist/synthesis/GoogleTranslateTTS.js.map +1 -1
  106. package/dist/synthesis/StreamlabsPollyTTS.d.ts +0 -1
  107. package/dist/synthesis/VitsTTS.d.ts +0 -1
  108. package/dist/synthesis/VitsTTS.js +30 -0
  109. package/dist/synthesis/VitsTTS.js.map +1 -1
  110. package/dist/tests/Test.js +0 -31
  111. package/dist/tests/Test.js.map +1 -1
  112. package/dist/text-language-detection/FastTextLanguageDetection.d.ts +1 -1
  113. package/dist/text-language-detection/FastTextLanguageDetection.js.map +1 -1
  114. package/dist/text-language-detection/TinyLDLanguageDetection.d.ts +1 -1
  115. package/dist/text-language-detection/TinyLDLanguageDetection.js.map +1 -1
  116. package/dist/text-translation/DeepLTextTranslation.d.ts +2 -0
  117. package/dist/text-translation/DeepLTextTranslation.js +67 -0
  118. package/dist/text-translation/DeepLTextTranslation.js.map +1 -0
  119. package/dist/text-translation/GoogleTranslateTextTranslation.d.ts +10 -0
  120. package/dist/text-translation/GoogleTranslateTextTranslation.js +554 -0
  121. package/dist/text-translation/GoogleTranslateTextTranslation.js.map +1 -0
  122. package/dist/text-translation/NLLBTextTranslation.d.ts +2 -1
  123. package/dist/text-translation/NLLBTextTranslation.js +249 -19
  124. package/dist/text-translation/NLLBTextTranslation.js.map +1 -1
  125. package/dist/utilities/BinaryArrayConversion.d.ts +0 -1
  126. package/dist/utilities/BrowserRequestHeaders.d.ts +6 -0
  127. package/dist/utilities/BrowserRequestHeaders.js +52 -0
  128. package/dist/utilities/BrowserRequestHeaders.js.map +1 -0
  129. package/dist/utilities/BufferFileReadStream.d.ts +20 -0
  130. package/dist/utilities/BufferFileReadStream.js +81 -0
  131. package/dist/utilities/BufferFileReadStream.js.map +1 -0
  132. package/dist/utilities/DynamicUint8Array.d.ts +9 -0
  133. package/dist/utilities/DynamicUint8Array.js +31 -0
  134. package/dist/utilities/DynamicUint8Array.js.map +1 -0
  135. package/dist/utilities/FileSystem.d.ts +0 -2
  136. package/dist/utilities/Hashing.d.ts +3 -10
  137. package/dist/utilities/Hashing.js +10 -127
  138. package/dist/utilities/Hashing.js.map +1 -1
  139. package/dist/utilities/LEB128.d.ts +15 -5
  140. package/dist/utilities/LEB128.js +199 -119
  141. package/dist/utilities/LEB128.js.map +1 -1
  142. package/dist/utilities/LPVarInt.d.ts +11 -0
  143. package/dist/utilities/LPVarInt.js +187 -0
  144. package/dist/utilities/LPVarInt.js.map +1 -0
  145. package/dist/utilities/Locale.d.ts +1 -1
  146. package/dist/utilities/Locale.js +1 -1
  147. package/dist/utilities/OnnxUtilities.d.ts +1 -2
  148. package/dist/utilities/PVarInt.d.ts +4 -0
  149. package/dist/utilities/PVarInt.js +166 -0
  150. package/dist/utilities/PVarInt.js.map +1 -0
  151. package/dist/utilities/PackageManager.js +48 -25
  152. package/dist/utilities/PackageManager.js.map +1 -1
  153. package/dist/utilities/RandomGenerator.d.ts +3 -17
  154. package/dist/utilities/RandomGenerator.js +12 -81
  155. package/dist/utilities/RandomGenerator.js.map +1 -1
  156. package/dist/utilities/Timeline.d.ts +2 -0
  157. package/dist/utilities/Timeline.js +129 -20
  158. package/dist/utilities/Timeline.js.map +1 -1
  159. package/dist/utilities/Utilities.d.ts +1 -3
  160. package/dist/utilities/Utilities.js +30 -3
  161. package/dist/utilities/Utilities.js.map +1 -1
  162. package/dist/utilities/VarInt.d.ts +4 -0
  163. package/dist/utilities/VarInt.js +166 -0
  164. package/dist/utilities/VarInt.js.map +1 -0
  165. package/dist/utilities/VirtualFileReadStream.d.ts +20 -0
  166. package/dist/utilities/VirtualFileReadStream.js +79 -0
  167. package/dist/utilities/VirtualFileReadStream.js.map +1 -0
  168. package/dist/utilities/WebReader.js +7 -23
  169. package/dist/utilities/WebReader.js.map +1 -1
  170. package/dist/voice-activity-detection/SileroVAD.d.ts +0 -1
  171. package/docs/API.md +105 -3
  172. package/docs/CLI.md +51 -1
  173. package/docs/Engines.md +32 -3
  174. package/docs/Options.md +53 -12
  175. package/docs/Tasklist.md +1 -13
  176. package/package.json +20 -24
  177. package/src/alignment/DTWMfccSequenceAlignment.ts +5 -5
  178. package/src/alignment/DTWSequenceAlignmentWindowed.ts +1 -3
  179. package/src/alignment/SemanticTextAlignment.ts +467 -0
  180. package/src/alignment/SpeechAlignment.ts +214 -56
  181. package/src/api/API.ts +18 -2
  182. package/src/api/APIOptions.ts +14 -1
  183. package/src/api/Alignment.ts +31 -9
  184. package/src/api/LanguageDetectionCommon.ts +7 -0
  185. package/src/api/Recognition.ts +2 -0
  186. package/src/api/{LanguageDetection.ts → SpeechLanguageDetection.ts} +1 -119
  187. package/src/api/{Translation.ts → SpeechTranslation.ts} +2 -2
  188. package/src/api/Synthesis.ts +4 -4
  189. package/src/api/TextLanguageDetection.ts +116 -0
  190. package/src/api/TextTranslation.ts +177 -0
  191. package/src/api/TimelineTranslationAlignment.ts +162 -0
  192. package/src/api/TranscriptAndTranslationAlignment.ts +164 -0
  193. package/src/api/TranslationAlignment.ts +12 -10
  194. package/src/api/VoiceActivityDetection.ts +24 -3
  195. package/src/audio/AudioPlayer.ts +2 -0
  196. package/src/cli/CLI.ts +376 -40
  197. package/src/codecs/FFMpegTranscoder.ts +6 -0
  198. package/src/dsp/FFT.ts +8 -2
  199. package/src/dsp/KWeightingFilter.ts +1 -1
  200. package/src/dsp/MelSpectogram.ts +17 -8
  201. package/src/math/VectorMath.ts +15 -15
  202. package/src/nlp/ChineseSegmentation.ts +6 -4
  203. package/src/nlp/Segmentation.ts +18 -13
  204. package/src/recognition/OpenAICloudSTT.ts +47 -29
  205. package/src/recognition/WhisperCppSTT.ts +26 -11
  206. package/src/recognition/WhisperSTT.ts +364 -49
  207. package/src/server/Client.ts +3 -2
  208. package/src/server/Worker.ts +3 -2
  209. package/src/source-separation/MDXNetSourceSeparation.ts +1 -1
  210. package/src/speech-embeddings/WavToVec2BertFeatureEmbeddings.ts +107 -0
  211. package/src/speech-language-detection/SileroLanguageDetection.ts +2 -1
  212. package/src/subtitles/Subtitles.ts +2 -2
  213. package/src/synthesis/GoogleTranslateTTS.ts +7 -21
  214. package/src/synthesis/VitsTTS.ts +31 -3
  215. package/src/tests/Test.ts +1 -38
  216. package/src/text-language-detection/FastTextLanguageDetection.ts +1 -1
  217. package/src/text-language-detection/TinyLDLanguageDetection.ts +1 -1
  218. package/src/text-translation/DeepLTextTranslation.ts +88 -0
  219. package/src/text-translation/GoogleTranslateTextTranslation.ts +667 -0
  220. package/src/text-translation/NLLBTextTranslation.ts +261 -21
  221. package/src/typings/Fillers.d.ts +25 -2
  222. package/src/utilities/BrowserRequestHeaders.ts +59 -0
  223. package/src/utilities/DynamicUint8Array.ts +39 -0
  224. package/src/utilities/Hashing.ts +14 -167
  225. package/src/utilities/LEB128.ts +273 -148
  226. package/src/utilities/LPVarInt.ts +292 -0
  227. package/src/utilities/Locale.ts +1 -1
  228. package/src/utilities/OnnxUtilities.ts +1 -1
  229. package/src/utilities/PackageManager.ts +51 -30
  230. package/src/utilities/RandomGenerator.ts +12 -113
  231. package/src/utilities/Timeline.ts +162 -23
  232. package/src/utilities/Utilities.ts +40 -3
  233. package/src/utilities/VirtualFileReadStream.ts +109 -0
  234. package/src/utilities/WebReader.ts +9 -23
  235. package/dist/alignment/TextAlignment.js +0 -156
  236. package/dist/alignment/TextAlignment.js.map +0 -1
  237. package/dist/api/LanguageDetection.js.map +0 -1
  238. package/dist/api/Translation.js.map +0 -1
  239. package/src/alignment/TextAlignment.ts +0 -234
  240. /package/dist/api/{Translation.d.ts → SpeechTranslation.d.ts} +0 -0
@@ -1,231 +1,356 @@
1
+ import { DynamicUint8Array } from "./DynamicUint8Array.js"
1
2
  import { logToStderr } from "./Utilities.js"
2
3
 
4
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
5
+ // Encode unsigned integer
6
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
7
+ export function encodeUnsignedInt(value: number | bigint, outEncodedData: DynamicUint8Array) {
8
+ if (value < 0) {
9
+ throw new Error(`The negative value ${value} can't be encoded as an unsigned LEB128 integer.`)
10
+ }
11
+
12
+ if (typeof value === 'number') {
13
+ if (value < (2 ** 31)) {
14
+ return encodeUnsignedInt31(value, outEncodedData)
15
+ } else {
16
+ return encodeUnsignedBigInt(BigInt(value), outEncodedData)
17
+ }
18
+ } else {
19
+ return encodeUnsignedBigInt(value, outEncodedData)
20
+ }
21
+ }
22
+
23
+ function encodeUnsignedInt31(value: number, outEncodedData: DynamicUint8Array) {
24
+ value = value >>> 0
25
+
26
+ if (value < (2 ** 7)) {
27
+ outEncodedData.add(
28
+ value
29
+ )
30
+ } else if (value < (2 ** 14)) {
31
+ outEncodedData.addMany(
32
+ (value & 0b01111111) | 0b10000000,
33
+ value >>> 7
34
+ )
35
+ } else if (value < (2 ** 21)) {
36
+ outEncodedData.addMany(
37
+ (value & 0b01111111) | 0b10000000,
38
+ ((value >>> 7) & 0b01111111) | 0b10000000,
39
+ value >>> 14
40
+ )
41
+ } else if (value < (2 ** 28)) {
42
+ outEncodedData.addMany(
43
+ (value & 0b01111111) | 0b10000000,
44
+ ((value >>> 7) & 0b01111111) | 0b10000000,
45
+ ((value >>> 14) & 0b01111111) | 0b10000000,
46
+ value >>> 21
47
+ )
48
+ } else {
49
+ outEncodedData.addMany(
50
+ (value & 0b01111111) | 0b10000000,
51
+ ((value >>> 7) & 0b01111111) | 0b10000000,
52
+ ((value >>> 14) & 0b01111111) | 0b10000000,
53
+ ((value >>> 21) & 0b01111111) | 0b10000000,
54
+ value >>> 28
55
+ )
56
+ }
57
+
58
+ return outEncodedData
59
+ }
60
+
61
+ function encodeUnsignedBigInt(value: bigint, outEncodedData: DynamicUint8Array) {
62
+ while (true) {
63
+ const lowest7Bits = Number(value & 0b01111111n)
64
+
65
+ value = value >> 7n
66
+
67
+ if (value === 0n) {
68
+ outEncodedData.add(lowest7Bits)
69
+
70
+ return outEncodedData
71
+ } else {
72
+ outEncodedData.add(lowest7Bits | 0b10000000)
73
+ }
74
+ }
75
+ }
76
+
3
77
  ////////////////////////////////////////////////////////////////////////////////////
4
- // Encode
78
+ // Decode unsigned integer
5
79
  ////////////////////////////////////////////////////////////////////////////////////
6
- export function encodeSignedInt32(value: number, outEncodedData: number[]) {
7
- if (value < -2147483648 || value > 2147483647) {
8
- throw new Error('Value must be between -2147483648 and 2147483647')
80
+ export function decodeUnsignedInt31Fast(encodedData: ArrayLike<number>, readOffset: number): DecodedValueAndReadOffset {
81
+ const byte0 = encodedData[readOffset++]
82
+
83
+ if ((byte0 & 0b10000000) === 0) {
84
+ const decodedValue =
85
+ byte0
86
+
87
+ return { decodedValue, readOffset }
88
+ }
89
+
90
+ const byte1 = encodedData[readOffset++]
91
+
92
+ if ((byte1 & 0b10000000) === 0) {
93
+ const decodedValue =
94
+ (byte0 & 0b01111111) |
95
+ (byte1 & 0b01111111) << 7
96
+
97
+ return { decodedValue, readOffset }
98
+ }
99
+
100
+ const byte2 = encodedData[readOffset++]
101
+
102
+ if ((byte2 & 0b10000000) === 0) {
103
+ const decodedValue =
104
+ (byte0 & 0b01111111) |
105
+ (byte1 & 0b01111111) << 7 |
106
+ (byte2 & 0b01111111) << 14
107
+
108
+ return { decodedValue, readOffset }
109
+ }
110
+
111
+ const byte3 = encodedData[readOffset++]
112
+
113
+ if ((byte3 & 0b10000000) === 0) {
114
+ const decodedValue =
115
+ (byte0 & 0b01111111) |
116
+ (byte1 & 0b01111111) << 7 |
117
+ (byte2 & 0b01111111) << 14 |
118
+ (byte3 & 0b01111111) << 21
119
+
120
+ return { decodedValue, readOffset }
121
+ }
122
+
123
+ const byte4 = encodedData[readOffset++]
124
+
125
+ if ((byte4 & 0b10000000) === 0) {
126
+ const decodedValue =
127
+ (byte0 & 0b01111111) |
128
+ (byte1 & 0b01111111) << 7 |
129
+ (byte2 & 0b01111111) << 14 |
130
+ (byte3 & 0b01111111) << 21 |
131
+ (byte4 & 0b01111111) << 28
132
+
133
+ return { decodedValue, readOffset }
134
+ }
135
+
136
+ if (readOffset >= encodedData.length) {
137
+ throw new Error(`Invalid LEB128 data. Last encoded byte sequence is truncated.`)
138
+ } else {
139
+ throw new Error(`LEB128 sequence can't be decoded. Encoded byte sequence represents a value that extends beyond the range of a unsigned 32 bit integer.`)
140
+ }
141
+ }
142
+
143
+ ////////////////////////////////////////////////////////////////////////////////////
144
+ // Encode signed integer
145
+ ////////////////////////////////////////////////////////////////////////////////////
146
+ export function encodeSignedInt32(value: number, outEncodedData: DynamicUint8Array) {
147
+ if (value < -(2 ** 31) || value > (2 ** 31)) {
148
+ throw new Error('Value must be between -(2^31) and 2^31 - 1')
9
149
  }
10
150
 
11
151
  while (true) {
12
- const lowest7Bits = value & 127
152
+ const lowest7Bits = value & 0b01111111
13
153
 
14
154
  value >>= 7
15
155
 
16
156
  if (
17
- (value === 0 && (lowest7Bits & 64) === 0) ||
18
- (value === -1 && (lowest7Bits & 64) !== 0)) {
19
- outEncodedData.push(lowest7Bits)
157
+ (value === 0 && (lowest7Bits & 0b01000000) === 0) ||
158
+ (value === -1 && (lowest7Bits & 0b01000000) !== 0)) {
159
+ outEncodedData.add(lowest7Bits)
20
160
 
21
161
  return outEncodedData
22
162
  } else {
23
- outEncodedData.push(lowest7Bits | 128)
163
+ outEncodedData.add(lowest7Bits | 0b10000000)
24
164
  }
25
165
  }
26
166
  }
27
167
 
28
- export function encodeSignedInt32sFast(value: number, outEncodedData: number[]) {
29
- const absValue = Math.abs(value)
30
- //const absMask = value >> 31
31
- //const absValue = (value ^ absMask) - absMask
168
+ export function encodeSignedInt32Fast(value: number, outEncodedData: DynamicUint8Array) {
169
+ const absValue = Math.abs(value | 0)
32
170
 
33
171
  if (absValue < (2 ** 6)) {
34
- outEncodedData.push(
35
- (value & 127)
172
+ outEncodedData.add(
173
+ (value & 0b01111111)
36
174
  )
37
175
  } else if (absValue < (2 ** 13)) {
38
- outEncodedData.push(
39
- (value & 127) | 128,
40
- (value >> 7) & 127
176
+ outEncodedData.addMany(
177
+ (value & 0b01111111) | 0b10000000,
178
+ (value >> 7) & 0b01111111
41
179
  )
42
180
  } else if (absValue < (2 ** 20)) {
43
- outEncodedData.push(
44
- (value & 127) | 128,
45
- ((value >> 7) & 127) | 128,
46
- (value >> 14) & 127
181
+ outEncodedData.addMany(
182
+ (value & 0b01111111) | 0b10000000,
183
+ ((value >> 7) & 0b01111111) | 0b10000000,
184
+ (value >> 14) & 0b01111111
47
185
  )
48
186
  } else if (absValue < (2 ** 27)) {
49
- outEncodedData.push(
50
- (value & 127) | 128,
51
- ((value >> 7) & 127) | 128,
52
- ((value >> 14) & 127) | 128,
53
- (value >> 21) & 127
54
- )
55
- } else if (value < (2 ** 31) && value >= -(2 ** 31)) {
56
- outEncodedData.push(
57
- (value & 127) | 128,
58
- ((value >> 7) & 127) | 128,
59
- ((value >> 14) & 127) | 128,
60
- ((value >> 21) & 127) | 128,
61
- (value >> 28) & 127
187
+ outEncodedData.addMany(
188
+ (value & 0b01111111) | 0b10000000,
189
+ ((value >> 7) & 0b01111111) | 0b10000000,
190
+ ((value >> 14) & 0b01111111) | 0b10000000,
191
+ (value >> 21) & 0b01111111
62
192
  )
63
193
  } else {
64
- throw new Error(`Value must be between -2147483648 and 2147483647`)
194
+ outEncodedData.addMany(
195
+ (value & 0b01111111) | 0b10000000,
196
+ ((value >> 7) & 0b01111111) | 0b10000000,
197
+ ((value >> 14) & 0b01111111) | 0b10000000,
198
+ ((value >> 21) & 0b01111111) | 0b10000000,
199
+ (value >> 28) & 0b01111111
200
+ )
65
201
  }
202
+
203
+ return outEncodedData
66
204
  }
67
205
 
68
206
  ////////////////////////////////////////////////////////////////////////////////////
69
- // Decode
207
+ // Decode signed integer
70
208
  ////////////////////////////////////////////////////////////////////////////////////
71
- export function decodeSignedInt32s(encodedData: ArrayLike<number>, outDecodedValues: number[]) {
72
- for (let readIndex = 0; readIndex < encodedData.length;) {
73
- let currentDecodedValue = 0
74
- let shiftAmount = 0
75
-
76
- while (true) {
77
- const encodedByte = encodedData[readIndex++]
78
- const lowest7Bits = encodedByte & 127
79
-
80
- currentDecodedValue |= lowest7Bits << shiftAmount
81
-
82
- // If 8th bit is 0, then this is the last byte in the sequence
83
- if ((encodedByte & 128) === 0) {
84
- // If 7th bit is 1, then the value is negative
85
- if ((encodedByte & 64) !== 0) {
86
- // If the value should be negative
87
- // Ensure that the value is encoded as a negative number by
88
- // setting all higher bits to 1
89
- currentDecodedValue |= -1 << Math.min(shiftAmount + 7, 31)
90
- }
91
-
92
- break
93
- }
209
+ export function decodeSignedInt32(encodedData: ArrayLike<number>, readOffset: number): DecodedValueAndReadOffset {
210
+ let decodedValue = 0
211
+ let shiftAmount = 0
94
212
 
95
- if (readIndex === encodedData.length) {
96
- throw new Error(`Invalid LEB128 data. Last encoded byte sequence is truncated.`)
213
+ while (true) {
214
+ const encodedByte = encodedData[readOffset++]
215
+ const lowest7Bits = encodedByte & 0b01111111
216
+
217
+ decodedValue |= lowest7Bits << shiftAmount
218
+
219
+ // If 8th bit is 0, then this is the last byte in the sequence
220
+ if ((encodedByte & 0b10000000) === 0) {
221
+ // If 7th bit is 1, then the value is negative
222
+ if ((encodedByte & 0b01000000) !== 0) {
223
+ // If the value should be negative
224
+ // Ensure that the value is encoded as a negative number by
225
+ // setting all higher bits to 1
226
+ decodedValue |= -1 << Math.min(shiftAmount + 7, 31)
97
227
  }
98
228
 
99
- shiftAmount += 7
229
+ return { decodedValue, readOffset }
230
+ }
100
231
 
101
- if (shiftAmount > 31) {
102
- throw new Error(`LEB128 sequence can't be decoded. Byte sequence extends beyond the range of a signed 32 bit integer.`)
103
- }
232
+ if (readOffset === encodedData.length) {
233
+ throw new Error(`Invalid LEB128 data. Last encoded byte sequence is truncated.`)
104
234
  }
105
235
 
106
- outDecodedValues.push(currentDecodedValue)
107
- }
236
+ shiftAmount += 7
108
237
 
109
- return outDecodedValues
238
+ if (shiftAmount > 31) {
239
+ throw new Error(`LEB128 sequence can't be decoded. Byte sequence extends beyond the range of a signed 32 bit integer.`)
240
+ }
241
+ }
110
242
  }
111
243
 
112
- export function decodeSignedInt32sFast(encodedData: ArrayLike<number>, outDecodedValues: number[]) {
113
- for (let readIndex = 0; readIndex < encodedData.length;) {
114
- const byte0 = encodedData[readIndex++]
115
-
116
- if ((byte0 & 128) === 0) {
117
- let decodedValue =
118
- (byte0 & 127)
119
-
120
- if ((byte0 & 64) !== 0) {
121
- decodedValue |= -1 << 7
122
- }
244
+ export function decodeSignedInt32Fast(encodedData: ArrayLike<number>, readOffset: number) {
245
+ const byte0 = encodedData[readOffset++]
123
246
 
124
- outDecodedValues.push(decodedValue)
247
+ if ((byte0 & 0b10000000) === 0) {
248
+ let decodedValue =
249
+ byte0
125
250
 
126
- continue
251
+ if ((byte0 & 0b01000000) !== 0) {
252
+ decodedValue |= -1 << 7
127
253
  }
128
254
 
129
- const byte1 = encodedData[readIndex++]
130
-
131
- if ((byte1 & 128) === 0) {
132
- let decodedValue =
133
- (byte0 & 127) |
134
- (byte1 & 127) << 7
255
+ return { decodedValue, readOffset }
256
+ }
135
257
 
136
- if ((byte1 & 64) !== 0) {
137
- decodedValue |= -1 << 14
138
- }
258
+ const byte1 = encodedData[readOffset++]
139
259
 
140
- outDecodedValues.push(decodedValue)
260
+ if ((byte1 & 0b10000000) === 0) {
261
+ let decodedValue =
262
+ (byte0 & 0b01111111) |
263
+ (byte1 & 0b01111111) << 7
141
264
 
142
- continue
265
+ if ((byte1 & 0b01000000) !== 0) {
266
+ decodedValue |= -1 << 14
143
267
  }
144
268
 
145
- const byte2 = encodedData[readIndex++]
146
-
147
- if ((byte2 & 128) === 0) {
148
- let decodedValue =
149
- (byte0 & 127) |
150
- (byte1 & 127) << 7 |
151
- (byte2 & 127) << 14
269
+ return { decodedValue, readOffset }
270
+ }
152
271
 
153
- if ((byte2 & 64) !== 0) {
154
- decodedValue |= -1 << 21
155
- }
272
+ const byte2 = encodedData[readOffset++]
156
273
 
157
- outDecodedValues.push(decodedValue)
274
+ if ((byte2 & 0b10000000) === 0) {
275
+ let decodedValue =
276
+ (byte0 & 0b01111111) |
277
+ (byte1 & 0b01111111) << 7 |
278
+ (byte2 & 0b01111111) << 14
158
279
 
159
- continue
280
+ if ((byte2 & 0b01000000) !== 0) {
281
+ decodedValue |= -1 << 21
160
282
  }
161
283
 
162
- const byte3 = encodedData[readIndex++]
163
-
164
- if ((byte3 & 128) === 0) {
165
- let decodedValue =
166
- (byte0 & 127) |
167
- (byte1 & 127) << 7 |
168
- (byte2 & 127) << 14 |
169
- (byte3 & 127) << 21
284
+ return { decodedValue, readOffset }
285
+ }
170
286
 
171
- if ((byte3 & 64) !== 0) {
172
- decodedValue |= -1 << 28
173
- }
287
+ const byte3 = encodedData[readOffset++]
174
288
 
175
- outDecodedValues.push(decodedValue)
289
+ if ((byte3 & 0b10000000) === 0) {
290
+ let decodedValue =
291
+ (byte0 & 0b01111111) |
292
+ (byte1 & 0b01111111) << 7 |
293
+ (byte2 & 0b01111111) << 14 |
294
+ (byte3 & 0b01111111) << 21
176
295
 
177
- continue
296
+ if ((byte3 & 0b01000000) !== 0) {
297
+ decodedValue |= -1 << 28
178
298
  }
179
299
 
180
- const byte4 = encodedData[readIndex++]
181
-
182
- if ((byte4 & 128) === 0) {
183
- let decodedValue =
184
- (byte0 & 127) |
185
- (byte1 & 127) << 7 |
186
- (byte2 & 127) << 14 |
187
- (byte3 & 127) << 21 |
188
- (byte4 & 127) << 28
300
+ return { decodedValue, readOffset }
301
+ }
189
302
 
190
- if ((byte4 & 64) !== 0) {
191
- decodedValue |= -1 << 31
192
- }
303
+ const byte4 = encodedData[readOffset++]
193
304
 
194
- outDecodedValues.push(decodedValue)
305
+ if ((byte4 & 0b10000000) === 0) {
306
+ let decodedValue =
307
+ (byte0 & 0b01111111) |
308
+ (byte1 & 0b01111111) << 7 |
309
+ (byte2 & 0b01111111) << 14 |
310
+ (byte3 & 0b01111111) << 21 |
311
+ (byte4 & 0b01111111) << 28
195
312
 
196
- continue
313
+ if ((byte4 & 0b01000000) !== 0) {
314
+ decodedValue |= -1 << 31
197
315
  }
198
316
 
199
- if (readIndex >= encodedData.length) {
200
- throw new Error(`Invalid LEB128 data. Last encoded byte sequence is truncated.`)
201
- } else {
202
- throw new Error(`LEB128 sequence can't be decoded. Encoded byte sequence represents a value that extends beyond the range of a signed 32 bit integer.`)
203
- }
317
+ return { decodedValue, readOffset }
204
318
  }
205
319
 
206
- return outDecodedValues
320
+ if (readOffset >= encodedData.length) {
321
+ throw new Error(`Invalid LEB128 data. Last encoded byte sequence is truncated.`)
322
+ } else {
323
+ throw new Error(`LEB128 sequence can't be decoded. Encoded byte sequence represents a value that extends beyond the range of a signed 32 bit integer.`)
324
+ }
325
+ }
326
+
327
+ ////////////////////////////////////////////////////////////////////////////////////
328
+ // Types
329
+ ////////////////////////////////////////////////////////////////////////////////////
330
+
331
+ export interface DecodedValueAndReadOffset {
332
+ decodedValue: number
333
+ readOffset: number
207
334
  }
208
335
 
209
336
  ////////////////////////////////////////////////////////////////////////////////////
210
337
  // Tests
211
338
  ////////////////////////////////////////////////////////////////////////////////////
212
- export function testLeb128() {
213
- const encodedBytes: number[] = []
214
- const decodedValues: number[] = []
339
+ export function testLeb128Signed() {
340
+ const encodedBytes = new DynamicUint8Array()
215
341
 
216
342
  function runTest(testValue: number) {
217
- encodedBytes.length = 0
218
- decodedValues.length = 0
343
+ encodedBytes.clear()
219
344
 
220
- encodeSignedInt32sFast(testValue, encodedBytes)
221
- decodeSignedInt32sFast(encodedBytes, decodedValues)
345
+ encodeSignedInt32Fast(testValue, encodedBytes)
346
+ const { decodedValue } = decodeSignedInt32Fast(encodedBytes.data, 0)
222
347
 
223
- if (decodedValues[0] !== testValue) {
224
- throw new Error(`Expected ${testValue} but got ${decodedValues[0]}`)
348
+ if (decodedValue !== testValue) {
349
+ throw new Error(`Expected ${testValue} but got ${decodedValue}`)
225
350
  }
226
351
  }
227
352
 
228
- for (let i = -(2 ** 22); i < 2 ** 22; i++) {
353
+ for (let i = -(2 ** 26); i < 2 ** 26; i++) {
229
354
  if (i % 1000000 === 0) {
230
355
  logToStderr(i)
231
356
  }