echogarden 1.5.0 → 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 (150) hide show
  1. package/data/schemas/options.json +43 -6
  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/SemanticTextAlignment.js +1 -1
  7. package/dist/alignment/SemanticTextAlignment.js.map +1 -1
  8. package/dist/alignment/SpeechAlignment.d.ts +2 -2
  9. package/dist/alignment/SpeechAlignment.js +26 -3
  10. package/dist/alignment/SpeechAlignment.js.map +1 -1
  11. package/dist/api/API.d.ts +0 -1
  12. package/dist/api/Synthesis.d.ts +0 -1
  13. package/dist/api/TextTranslation.d.ts +21 -1
  14. package/dist/api/TextTranslation.js +99 -2
  15. package/dist/api/TextTranslation.js.map +1 -1
  16. package/dist/api/TimelineTranslationAlignment.js +1 -1
  17. package/dist/api/TimelineTranslationAlignment.js.map +1 -1
  18. package/dist/audio/AudioBufferConversion.d.ts +0 -1
  19. package/dist/audio/AudioPlayer.d.ts +0 -1
  20. package/dist/audio/AudioPlayer.js +62 -41
  21. package/dist/audio/AudioPlayer.js.map +1 -1
  22. package/dist/audio/AudioUtilities.d.ts +0 -1
  23. package/dist/cli/CLI.d.ts +1 -0
  24. package/dist/cli/CLI.js +61 -4
  25. package/dist/cli/CLI.js.map +1 -1
  26. package/dist/codecs/FFMpegTranscoder.d.ts +0 -1
  27. package/dist/codecs/TIMITCodec.d.ts +0 -1
  28. package/dist/codecs/WaveCodec.d.ts +0 -1
  29. package/dist/math/VectorMath.d.ts +4 -4
  30. package/dist/math/VectorMath.js +6 -6
  31. package/dist/nlp/ChineseSegmentation.js +4 -4
  32. package/dist/nlp/ChineseSegmentation.js.map +1 -1
  33. package/dist/nlp/Segmentation.d.ts +2 -2
  34. package/dist/nlp/Segmentation.js +20 -13
  35. package/dist/nlp/Segmentation.js.map +1 -1
  36. package/dist/recognition/OpenAICloudSTT.d.ts +2 -1
  37. package/dist/recognition/OpenAICloudSTT.js +30 -19
  38. package/dist/recognition/OpenAICloudSTT.js.map +1 -1
  39. package/dist/recognition/SileroSTT.d.ts +0 -1
  40. package/dist/recognition/WhisperCppSTT.d.ts +2 -2
  41. package/dist/recognition/WhisperCppSTT.js +19 -7
  42. package/dist/recognition/WhisperCppSTT.js.map +1 -1
  43. package/dist/recognition/WhisperSTT.d.ts +9 -6
  44. package/dist/recognition/WhisperSTT.js +218 -40
  45. package/dist/recognition/WhisperSTT.js.map +1 -1
  46. package/dist/server/Client.d.ts +0 -2
  47. package/dist/server/Worker.d.ts +0 -1
  48. package/dist/source-separation/MDXNetSourceSeparation.d.ts +0 -1
  49. package/dist/speech-embeddings/WavToVec2BertFeatureEmbeddings.d.ts +0 -1
  50. package/dist/speech-language-detection/SileroLanguageDetection.d.ts +0 -1
  51. package/dist/subtitles/Subtitles.js +2 -2
  52. package/dist/subtitles/Subtitles.js.map +1 -1
  53. package/dist/synthesis/GoogleCloudTTS.d.ts +0 -1
  54. package/dist/synthesis/GoogleTranslateTTS.d.ts +0 -1
  55. package/dist/synthesis/GoogleTranslateTTS.js +6 -21
  56. package/dist/synthesis/GoogleTranslateTTS.js.map +1 -1
  57. package/dist/synthesis/StreamlabsPollyTTS.d.ts +0 -1
  58. package/dist/synthesis/VitsTTS.d.ts +0 -1
  59. package/dist/synthesis/VitsTTS.js +30 -0
  60. package/dist/synthesis/VitsTTS.js.map +1 -1
  61. package/dist/text-translation/DeepLTextTranslation.d.ts +2 -0
  62. package/dist/text-translation/DeepLTextTranslation.js +67 -0
  63. package/dist/text-translation/DeepLTextTranslation.js.map +1 -0
  64. package/dist/text-translation/GoogleTranslateTextTranslation.d.ts +10 -0
  65. package/dist/text-translation/GoogleTranslateTextTranslation.js +554 -0
  66. package/dist/text-translation/GoogleTranslateTextTranslation.js.map +1 -0
  67. package/dist/text-translation/NLLBTextTranslation.d.ts +2 -1
  68. package/dist/text-translation/NLLBTextTranslation.js +248 -18
  69. package/dist/text-translation/NLLBTextTranslation.js.map +1 -1
  70. package/dist/utilities/BinaryArrayConversion.d.ts +0 -1
  71. package/dist/utilities/BrowserRequestHeaders.d.ts +6 -0
  72. package/dist/utilities/BrowserRequestHeaders.js +52 -0
  73. package/dist/utilities/BrowserRequestHeaders.js.map +1 -0
  74. package/dist/utilities/BufferFileReadStream.d.ts +20 -0
  75. package/dist/utilities/BufferFileReadStream.js +81 -0
  76. package/dist/utilities/BufferFileReadStream.js.map +1 -0
  77. package/dist/utilities/DynamicUint8Array.d.ts +9 -0
  78. package/dist/utilities/DynamicUint8Array.js +31 -0
  79. package/dist/utilities/DynamicUint8Array.js.map +1 -0
  80. package/dist/utilities/FileSystem.d.ts +0 -2
  81. package/dist/utilities/Hashing.d.ts +3 -10
  82. package/dist/utilities/Hashing.js +10 -127
  83. package/dist/utilities/Hashing.js.map +1 -1
  84. package/dist/utilities/LEB128.d.ts +15 -5
  85. package/dist/utilities/LEB128.js +199 -119
  86. package/dist/utilities/LEB128.js.map +1 -1
  87. package/dist/utilities/LPVarInt.d.ts +11 -0
  88. package/dist/utilities/LPVarInt.js +187 -0
  89. package/dist/utilities/LPVarInt.js.map +1 -0
  90. package/dist/utilities/OnnxUtilities.d.ts +0 -1
  91. package/dist/utilities/PVarInt.d.ts +4 -0
  92. package/dist/utilities/PVarInt.js +166 -0
  93. package/dist/utilities/PVarInt.js.map +1 -0
  94. package/dist/utilities/PackageManager.js +43 -22
  95. package/dist/utilities/PackageManager.js.map +1 -1
  96. package/dist/utilities/RandomGenerator.d.ts +3 -17
  97. package/dist/utilities/RandomGenerator.js +12 -81
  98. package/dist/utilities/RandomGenerator.js.map +1 -1
  99. package/dist/utilities/Timeline.d.ts +1 -0
  100. package/dist/utilities/Timeline.js +117 -20
  101. package/dist/utilities/Timeline.js.map +1 -1
  102. package/dist/utilities/Utilities.d.ts +1 -3
  103. package/dist/utilities/Utilities.js +30 -3
  104. package/dist/utilities/Utilities.js.map +1 -1
  105. package/dist/utilities/VarInt.d.ts +4 -0
  106. package/dist/utilities/VarInt.js +166 -0
  107. package/dist/utilities/VarInt.js.map +1 -0
  108. package/dist/utilities/VirtualFileReadStream.d.ts +20 -0
  109. package/dist/utilities/VirtualFileReadStream.js +79 -0
  110. package/dist/utilities/VirtualFileReadStream.js.map +1 -0
  111. package/dist/utilities/WebReader.js +7 -23
  112. package/dist/utilities/WebReader.js.map +1 -1
  113. package/dist/voice-activity-detection/SileroVAD.d.ts +0 -1
  114. package/docs/API.md +24 -0
  115. package/docs/Engines.md +8 -3
  116. package/docs/Options.md +20 -11
  117. package/docs/Tasklist.md +1 -13
  118. package/package.json +20 -24
  119. package/src/alignment/DTWMfccSequenceAlignment.ts +5 -5
  120. package/src/alignment/DTWSequenceAlignmentWindowed.ts +1 -3
  121. package/src/alignment/SemanticTextAlignment.ts +1 -1
  122. package/src/alignment/SpeechAlignment.ts +37 -6
  123. package/src/api/TextTranslation.ts +170 -2
  124. package/src/api/TimelineTranslationAlignment.ts +1 -1
  125. package/src/audio/AudioPlayer.ts +2 -0
  126. package/src/cli/CLI.ts +101 -7
  127. package/src/math/VectorMath.ts +6 -6
  128. package/src/nlp/ChineseSegmentation.ts +6 -4
  129. package/src/nlp/Segmentation.ts +18 -13
  130. package/src/recognition/OpenAICloudSTT.ts +47 -29
  131. package/src/recognition/WhisperCppSTT.ts +24 -9
  132. package/src/recognition/WhisperSTT.ts +354 -43
  133. package/src/subtitles/Subtitles.ts +2 -2
  134. package/src/synthesis/GoogleTranslateTTS.ts +7 -21
  135. package/src/synthesis/VitsTTS.ts +31 -3
  136. package/src/text-translation/DeepLTextTranslation.ts +88 -0
  137. package/src/text-translation/GoogleTranslateTextTranslation.ts +667 -0
  138. package/src/text-translation/NLLBTextTranslation.ts +260 -20
  139. package/src/typings/Fillers.d.ts +25 -2
  140. package/src/utilities/BrowserRequestHeaders.ts +59 -0
  141. package/src/utilities/DynamicUint8Array.ts +39 -0
  142. package/src/utilities/Hashing.ts +14 -167
  143. package/src/utilities/LEB128.ts +273 -148
  144. package/src/utilities/LPVarInt.ts +292 -0
  145. package/src/utilities/PackageManager.ts +45 -27
  146. package/src/utilities/RandomGenerator.ts +12 -113
  147. package/src/utilities/Timeline.ts +148 -23
  148. package/src/utilities/Utilities.ts +40 -3
  149. package/src/utilities/VirtualFileReadStream.ts +109 -0
  150. package/src/utilities/WebReader.ts +9 -23
@@ -1,8 +1,10 @@
1
- import { RawAudio } from '../audio/AudioUtilities.js';
2
1
  import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
3
- import { Logger } from '../utilities/Logger.js';
4
- import { extendDeep } from '../utilities/ObjectUtilities.js';
5
- import { Timeline, TimelineEntry } from '../utilities/Timeline.js';
2
+ import { RawAudio } from '../audio/AudioUtilities.js'
3
+ import { createVirtualFileReadStreamForBuffer } from '../utilities/VirtualFileReadStream.js'
4
+ import { Logger } from '../utilities/Logger.js'
5
+ import { extendDeep } from '../utilities/ObjectUtilities.js'
6
+ import { Timeline, TimelineEntry } from '../utilities/Timeline.js'
7
+ import { alignSegments } from '../api/Alignment.js'
6
8
 
7
9
  export async function recognize(rawAudio: RawAudio, languageCode: string, options: OpenAICloudSTTOptions, task: Task = 'transcribe') {
8
10
  const logger = new Logger()
@@ -11,41 +13,56 @@ export async function recognize(rawAudio: RawAudio, languageCode: string, option
11
13
 
12
14
  options = extendDeep(defaultOpenAICloudSTTOptions, options)
13
15
 
16
+ if (options.requestWordTimestamps === undefined) {
17
+ options.requestWordTimestamps = options.baseURL === undefined
18
+ }
19
+
20
+ if (options.model === undefined) {
21
+ if (options.baseURL === undefined) {
22
+ options.model = 'whisper-1'
23
+ } else {
24
+ throw new Error(`A custom provider for the OpenAI Cloud API requires specifying a model name`)
25
+ }
26
+ }
27
+
14
28
  const { default: OpenAI } = await import('openai')
15
29
  const openai = new OpenAI(options)
16
30
 
17
31
  logger.start('Encode audio to send')
18
32
  const ffmpegOptions = FFMpegTranscoder.getDefaultFFMpegOptionsForSpeech('mp3')
19
33
  const encodedAudio = await FFMpegTranscoder.encodeFromChannels(rawAudio, ffmpegOptions)
20
- const audioAsWaveBlob = new FileLikeBlob([encodedAudio], 'audio', Date.now(), { type: 'audio/mpeg' })
34
+ const virtualFileStream = createVirtualFileReadStreamForBuffer(encodedAudio, 'audio.mp3')
21
35
 
22
- logger.start('Request recognition from OpenAI Cloud API')
36
+ logger.start(options.baseURL ? `Send request to ${options.baseURL}` : 'Send request to OpenAI Cloud API')
23
37
 
24
38
  let response: VerboseResponse
25
39
 
26
- if (task =='transcribe') {
40
+ if (task == 'transcribe') {
41
+ const timestamp_granularities: ('word' | 'segment')[] | undefined =
42
+ options.requestWordTimestamps ? ['word', 'segment'] : undefined
43
+
27
44
  response = await openai.audio.transcriptions.create({
28
- file: audioAsWaveBlob,
29
- model: options.model!,
45
+ file: virtualFileStream,
46
+ model: options.model,
30
47
  language: languageCode,
31
48
  prompt: options.prompt,
32
49
  response_format: 'verbose_json',
33
50
  temperature: options.temperature,
34
- timestamp_granularities: ['word', 'segment']
35
- }) as VerboseResponse
51
+ timestamp_granularities,
52
+ }) as any as VerboseResponse
36
53
  } else if (task == 'translate') {
37
54
  response = await openai.audio.translations.create({
38
- file: audioAsWaveBlob,
39
- model: options.model!,
55
+ file: virtualFileStream,
56
+ model: options.model,
40
57
  prompt: options.prompt,
41
58
  response_format: 'verbose_json',
42
59
  temperature: options.temperature,
43
- }) as VerboseResponse
60
+ }) as any as VerboseResponse
44
61
  } else {
45
62
  throw new Error(`Invalid task`)
46
63
  }
47
64
 
48
- const transcript = response.text
65
+ const transcript = response.text.trim()
49
66
 
50
67
  let timeline: Timeline
51
68
 
@@ -57,12 +74,20 @@ export async function recognize(rawAudio: RawAudio, languageCode: string, option
57
74
  endTime: entry.end
58
75
  }))
59
76
  } else {
60
- timeline = response.segments.map<TimelineEntry>(entry => ({
77
+ const segmentTimeline = response.segments.map<TimelineEntry>(entry => ({
61
78
  type: 'segment',
62
79
  text: entry.text,
63
80
  startTime: entry.start,
64
81
  endTime: entry.end
65
82
  }))
83
+
84
+ if (task === 'transcribe') {
85
+ logger.start('Align segments')
86
+
87
+ timeline = await alignSegments(rawAudio, segmentTimeline, { language: languageCode })
88
+ } else {
89
+ timeline = segmentTimeline
90
+ }
66
91
  }
67
92
 
68
93
  logger.end()
@@ -70,17 +95,6 @@ export async function recognize(rawAudio: RawAudio, languageCode: string, option
70
95
  return { transcript, timeline }
71
96
  }
72
97
 
73
- class FileLikeBlob extends Blob {
74
- constructor(
75
- public readonly parts: BlobPart[],
76
- public readonly name: string,
77
- public readonly lastModified: number,
78
- options: BlobPropertyBag,
79
- ) {
80
- super(parts, options)
81
- }
82
- }
83
-
84
98
  interface VerboseResponse {
85
99
  task: string
86
100
  language: string
@@ -115,7 +129,7 @@ interface VerboseResponse {
115
129
  type Task = 'transcribe' | 'translate'
116
130
 
117
131
  export interface OpenAICloudSTTOptions {
118
- model?: 'whisper-1'
132
+ model?: 'whisper-1' | string
119
133
 
120
134
  apiKey?: string
121
135
  organization?: string
@@ -126,6 +140,8 @@ export interface OpenAICloudSTTOptions {
126
140
 
127
141
  timeout?: number
128
142
  maxRetries?: number
143
+
144
+ requestWordTimestamps?: boolean
129
145
  }
130
146
 
131
147
  export const defaultOpenAICloudSTTOptions: OpenAICloudSTTOptions = {
@@ -133,10 +149,12 @@ export const defaultOpenAICloudSTTOptions: OpenAICloudSTTOptions = {
133
149
  organization: undefined,
134
150
  baseURL: undefined,
135
151
 
136
- model: 'whisper-1',
152
+ model: undefined,
137
153
  temperature: 0,
138
154
  prompt: undefined,
139
155
 
140
156
  timeout: undefined,
141
157
  maxRetries: 10,
158
+
159
+ requestWordTimestamps: undefined,
142
160
  }
@@ -54,7 +54,7 @@ export async function recognize(
54
54
  }
55
55
  } else {
56
56
  if (options.enableGPU) {
57
- buildKind = 'cublas-11.8.0'
57
+ buildKind = 'cublas-12.4.0'
58
58
  } else {
59
59
  buildKind = 'cpu'
60
60
  }
@@ -240,6 +240,8 @@ async function parseResultObject(resultObject: WhisperCppVerboseResult, modelNam
240
240
 
241
241
  let currentCorrectionTimeOffset = 0
242
242
 
243
+ let lastTokenEndOffset = 0
244
+
243
245
  for (let segmentIndex = 0; segmentIndex < resultObject.transcription.length; segmentIndex++) {
244
246
  const segmentObject = resultObject.transcription[segmentIndex]
245
247
 
@@ -248,6 +250,17 @@ async function parseResultObject(resultObject: WhisperCppVerboseResult, modelNam
248
250
  for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
249
251
  const tokenObject = tokens[tokenIndex]
250
252
 
253
+ // Workaround whisper.cpp issue with missing offsets by falling back to last known end offset
254
+ // when they are not included
255
+ if (!tokenObject.offsets) {
256
+ tokenObject.offsets = {
257
+ from: lastTokenEndOffset,
258
+ to: lastTokenEndOffset,
259
+ }
260
+ } else {
261
+ lastTokenEndOffset = tokenObject.offsets.to
262
+ }
263
+
251
264
  if (tokenIndex === 0 && tokenObject.text === '[_BEG_]' && tokenObject.offsets.from === 0) {
252
265
  currentCorrectionTimeOffset = segmentObject.offsets.from / 1000
253
266
  }
@@ -370,7 +383,7 @@ export async function loadModelPackage(modelId: WhisperCppModelId | undefined, l
370
383
  return { modelName, modelPath }
371
384
  }
372
385
 
373
- export type WhisperCppBuild = 'cpu' | 'cublas-11.8.0' | 'cublas-12.4.0' | 'custom'
386
+ export type WhisperCppBuild = 'cpu' | 'cublas-12.4.0' | 'custom'
374
387
 
375
388
  export async function loadExecutablePackage(buildKind: WhisperCppBuild) {
376
389
  if (buildKind === 'custom') {
@@ -384,20 +397,20 @@ export async function loadExecutablePackage(buildKind: WhisperCppBuild) {
384
397
 
385
398
  if (buildKind.startsWith('cublas-')) {
386
399
  if (platform === 'win32' && arch === 'x64') {
387
- packageName = `whisper.cpp-binaries-windows-x64-${buildKind}-latest-patched`
400
+ packageName = `whisper.cpp-binaries-windows-x64-${buildKind}-latest`
388
401
  } else {
389
- throw new Error(`GPU builds (NVIDIA CUDA only) are currently only available as packages for Windows x64. Please specify a custom path to the binary in the 'executablePath' option.`)
402
+ throw new Error(`whisper.cpp GPU builds (NVIDIA CUDA only) are currently only available as packages for Windows x64. Please specify a custom path to a whisper.cpp 'main' binary in the 'executablePath' option.`)
390
403
  }
391
404
  } else if (buildKind === 'cpu') {
392
405
  if (platform === 'win32' && arch === 'x64') {
393
- packageName = `whisper.cpp-binaries-windows-x64-cpu-latest-patched`
406
+ packageName = `whisper.cpp-binaries-windows-x64-cpu-latest`
394
407
  } else if (platform === 'linux' && arch === 'x64') {
395
- packageName = `whisper.cpp-binaries-linux-x64-cpu-latest-patched`
408
+ packageName = `whisper.cpp-binaries-linux-x64-cpu-latest`
396
409
  } else {
397
- throw new Error(`Couldn't find a matching whisper.cpp binary package. Please specify a custom path to the binary in the 'executablePath' option.`)
410
+ throw new Error(`Couldn't find a matching whisper.cpp binary package. Please specify a custom path to a whisper.cpp 'main' binary in the 'executablePath' option.`)
398
411
  }
399
412
  } else {
400
- throw new Error(`Unknown build kind '${buildKind}'`)
413
+ throw new Error(`Unsupported build kind '${buildKind}'`)
401
414
  }
402
415
 
403
416
  const packagePath = await loadPackage(packageName)
@@ -553,4 +566,6 @@ export type WhisperCppModelId =
553
566
  'large-v2' |
554
567
  'large-v2-q5_0' |
555
568
  'large-v3' |
556
- 'large-v3-q5_0'
569
+ 'large-v3-q5_0' |
570
+ `large-v3-turbo` |
571
+ `large-v3-turbo-q5_0`