echogarden 0.12.2 → 1.0.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 (334) hide show
  1. package/README.md +15 -14
  2. package/data/schemas/options.json +398 -111
  3. package/dist/alignment/DTWMfccSequenceAlignment.d.ts +1 -1
  4. package/dist/alignment/DTWMfccSequenceAlignment.js +8 -8
  5. package/dist/alignment/DTWSequenceAlignment.d.ts +1 -1
  6. package/dist/alignment/DTWSequenceAlignment.js +1 -1
  7. package/dist/alignment/DTWSequenceAlignmentWindowed.d.ts +1 -1
  8. package/dist/alignment/DTWSequenceAlignmentWindowed.js +2 -2
  9. package/dist/alignment/LevenshteinSequenceAlignment.d.ts +1 -1
  10. package/dist/alignment/LevenshteinSequenceAlignment.js +1 -1
  11. package/dist/alignment/SpeechAlignment.d.ts +9 -10
  12. package/dist/alignment/SpeechAlignment.js +136 -105
  13. package/dist/alignment/SpeechAlignment.js.map +1 -1
  14. package/dist/api/API.d.ts +13 -12
  15. package/dist/api/API.js +14 -13
  16. package/dist/api/API.js.map +1 -1
  17. package/dist/api/APIOptions.d.ts +5 -4
  18. package/dist/api/Alignment.d.ts +15 -9
  19. package/dist/api/Alignment.js +88 -74
  20. package/dist/api/Alignment.js.map +1 -1
  21. package/dist/api/Common.js +1 -1
  22. package/dist/api/Denoising.d.ts +6 -6
  23. package/dist/api/Denoising.js +23 -23
  24. package/dist/api/Denoising.js.map +1 -1
  25. package/dist/api/LanguageDetection.d.ts +19 -12
  26. package/dist/api/LanguageDetection.js +88 -38
  27. package/dist/api/LanguageDetection.js.map +1 -1
  28. package/dist/api/Recognition.d.ts +16 -6
  29. package/dist/api/Recognition.js +129 -55
  30. package/dist/api/Recognition.js.map +1 -1
  31. package/dist/api/SourceSeparation.d.ts +17 -0
  32. package/dist/api/SourceSeparation.js +61 -0
  33. package/dist/api/SourceSeparation.js.map +1 -0
  34. package/dist/api/Synthesis.d.ts +18 -18
  35. package/dist/api/Synthesis.js +191 -164
  36. package/dist/api/Synthesis.js.map +1 -1
  37. package/dist/api/Translation.d.ts +19 -8
  38. package/dist/api/Translation.js +132 -35
  39. package/dist/api/Translation.js.map +1 -1
  40. package/dist/api/Vad.d.ts +10 -5
  41. package/dist/api/Vad.js +76 -38
  42. package/dist/api/Vad.js.map +1 -1
  43. package/dist/audio/AudioBufferConversion.d.ts +1 -1
  44. package/dist/audio/AudioBufferConversion.js +4 -4
  45. package/dist/audio/AudioPlayer.d.ts +1 -1
  46. package/dist/audio/AudioPlayer.js +26 -26
  47. package/dist/audio/AudioPlayer.js.map +1 -1
  48. package/dist/audio/AudioRecorder.d.ts +1 -1
  49. package/dist/audio/AudioRecorder.js +5 -5
  50. package/dist/audio/AudioUtilities.d.ts +13 -9
  51. package/dist/audio/AudioUtilities.js +86 -24
  52. package/dist/audio/AudioUtilities.js.map +1 -1
  53. package/dist/cli/CLI.d.ts +3 -3
  54. package/dist/cli/CLI.js +271 -162
  55. package/dist/cli/CLI.js.map +1 -1
  56. package/dist/cli/CLIConfigFile.js +8 -8
  57. package/dist/cli/CLILauncher.js +6 -6
  58. package/dist/cli/CLIOptionsSchema.js +2 -2
  59. package/dist/cli/CLIParser.js +5 -5
  60. package/dist/cli/CLIStarter.js +4 -4
  61. package/dist/codecs/FFMpegTranscoder.d.ts +2 -2
  62. package/dist/codecs/FFMpegTranscoder.js +37 -37
  63. package/dist/codecs/FFMpegTranscoder.js.map +1 -1
  64. package/dist/codecs/TIMITCodec.js +5 -5
  65. package/dist/codecs/WaveCodec.d.ts +1 -1
  66. package/dist/codecs/WaveCodec.js +22 -22
  67. package/dist/denoising/RNNoise.d.ts +1 -1
  68. package/dist/denoising/RNNoise.js +9 -9
  69. package/dist/dsp/BiquadFilter.d.ts +3 -2
  70. package/dist/dsp/BiquadFilter.js +18 -11
  71. package/dist/dsp/BiquadFilter.js.map +1 -1
  72. package/dist/dsp/DecayingPeakEstimator.d.ts +16 -0
  73. package/dist/dsp/DecayingPeakEstimator.js +23 -0
  74. package/dist/dsp/DecayingPeakEstimator.js.map +1 -0
  75. package/dist/dsp/FFT.d.ts +8 -4
  76. package/dist/dsp/FFT.js +76 -30
  77. package/dist/dsp/FFT.js.map +1 -1
  78. package/dist/dsp/KWeightingFilter.d.ts +9 -0
  79. package/dist/dsp/KWeightingFilter.js +40 -0
  80. package/dist/dsp/KWeightingFilter.js.map +1 -0
  81. package/dist/dsp/LoudnessEstimator.d.ts +21 -0
  82. package/dist/dsp/LoudnessEstimator.js +47 -0
  83. package/dist/dsp/LoudnessEstimator.js.map +1 -0
  84. package/dist/dsp/MFCC.d.ts +2 -2
  85. package/dist/dsp/MFCC.js +15 -15
  86. package/dist/dsp/MelSpectogram.d.ts +1 -1
  87. package/dist/dsp/MelSpectogram.js +6 -6
  88. package/dist/dsp/Rubberband.d.ts +11 -11
  89. package/dist/dsp/Rubberband.js +27 -27
  90. package/dist/dsp/Sonic.d.ts +1 -1
  91. package/dist/dsp/Sonic.js +3 -3
  92. package/dist/dsp/SpeexResampler.d.ts +1 -1
  93. package/dist/dsp/SpeexResampler.js +2 -2
  94. package/dist/math/VectorMath.d.ts +12 -8
  95. package/dist/math/VectorMath.js +35 -32
  96. package/dist/math/VectorMath.js.map +1 -1
  97. package/dist/nlp/ChineseSegmentation.js +2 -2
  98. package/dist/nlp/CompromiseNLP.js +3 -3
  99. package/dist/nlp/EspeakPhonemizer.js +30 -30
  100. package/dist/nlp/IPA.js +20 -20
  101. package/dist/nlp/JapaneseSegmentation.js +6 -6
  102. package/dist/nlp/Lexicon.d.ts +1 -1
  103. package/dist/nlp/Lexicon.js +7 -7
  104. package/dist/nlp/Segmentation.d.ts +3 -0
  105. package/dist/nlp/Segmentation.js +21 -14
  106. package/dist/nlp/Segmentation.js.map +1 -1
  107. package/dist/nlp/TextNormalizer.js +16 -16
  108. package/dist/recognition/AmazonTranscribeSTT.d.ts +2 -2
  109. package/dist/recognition/AmazonTranscribeSTT.js +13 -14
  110. package/dist/recognition/AmazonTranscribeSTT.js.map +1 -1
  111. package/dist/recognition/AzureCognitiveServicesSTT.js +5 -6
  112. package/dist/recognition/AzureCognitiveServicesSTT.js.map +1 -1
  113. package/dist/recognition/GoogleCloudSTT.d.ts +3 -3
  114. package/dist/recognition/GoogleCloudSTT.js +18 -18
  115. package/dist/recognition/OpenAICloudSTT.d.ts +19 -0
  116. package/dist/recognition/OpenAICloudSTT.js +81 -0
  117. package/dist/recognition/OpenAICloudSTT.js.map +1 -0
  118. package/dist/recognition/SileroSTT.d.ts +2 -2
  119. package/dist/recognition/SileroSTT.js +25 -25
  120. package/dist/recognition/VoskSTT.d.ts +2 -2
  121. package/dist/recognition/VoskSTT.js +8 -8
  122. package/dist/recognition/WhisperCppSTT.d.ts +88 -0
  123. package/dist/recognition/WhisperCppSTT.js +332 -0
  124. package/dist/recognition/WhisperCppSTT.js.map +1 -0
  125. package/dist/recognition/WhisperSTT.d.ts +49 -25
  126. package/dist/recognition/WhisperSTT.js +626 -481
  127. package/dist/recognition/WhisperSTT.js.map +1 -1
  128. package/dist/server/Client.d.ts +1 -1
  129. package/dist/server/Client.js +22 -22
  130. package/dist/server/Server.js +9 -9
  131. package/dist/server/Server.js.map +1 -1
  132. package/dist/server/Worker.d.ts +22 -22
  133. package/dist/server/Worker.js +36 -36
  134. package/dist/server/Worker.js.map +1 -1
  135. package/dist/server/WorkerStarter.js +2 -2
  136. package/dist/source-separation/MDXNetSourceSeparation.d.ts +11 -0
  137. package/dist/source-separation/MDXNetSourceSeparation.js +161 -0
  138. package/dist/source-separation/MDXNetSourceSeparation.js.map +1 -0
  139. package/dist/speech-language-detection/SileroLanguageDetection.d.ts +1 -1
  140. package/dist/speech-language-detection/SileroLanguageDetection.js +7 -7
  141. package/dist/subtitles/Subtitles.d.ts +10 -0
  142. package/dist/subtitles/Subtitles.js +2 -2
  143. package/dist/subtitles/Subtitles.js.map +1 -1
  144. package/dist/synthesis/AwsPollyTTS.d.ts +1 -1
  145. package/dist/synthesis/AwsPollyTTS.js +12 -12
  146. package/dist/synthesis/AzureCognitiveServicesTTS.js +7 -7
  147. package/dist/synthesis/CoquiServerTTS.js +10 -10
  148. package/dist/synthesis/CoquiServerTTS.js.map +1 -1
  149. package/dist/synthesis/ElevenlabsTTS.d.ts +23 -0
  150. package/dist/synthesis/ElevenlabsTTS.js +103 -0
  151. package/dist/synthesis/ElevenlabsTTS.js.map +1 -0
  152. package/dist/synthesis/EspeakTTS.d.ts +6 -5
  153. package/dist/synthesis/EspeakTTS.js +81 -69
  154. package/dist/synthesis/EspeakTTS.js.map +1 -1
  155. package/dist/synthesis/FliteTTS.d.ts +3 -3
  156. package/dist/synthesis/FliteTTS.js +154 -154
  157. package/dist/synthesis/FliteTTS.js.map +1 -1
  158. package/dist/synthesis/GoogleCloudTTS.d.ts +3 -3
  159. package/dist/synthesis/GoogleCloudTTS.js +17 -17
  160. package/dist/synthesis/GoogleCloudTTS.js.map +1 -1
  161. package/dist/synthesis/GoogleTranslateTTS.d.ts +1 -1
  162. package/dist/synthesis/GoogleTranslateTTS.js +103 -103
  163. package/dist/synthesis/MicrosoftEdgeTTS.d.ts +2 -2
  164. package/dist/synthesis/MicrosoftEdgeTTS.js +74 -74
  165. package/dist/synthesis/OpenAICloudTTS.d.ts +13 -0
  166. package/dist/synthesis/OpenAICloudTTS.js +169 -0
  167. package/dist/synthesis/OpenAICloudTTS.js.map +1 -0
  168. package/dist/synthesis/SamTTS.js +3 -3
  169. package/dist/synthesis/SapiTTS.d.ts +3 -3
  170. package/dist/synthesis/SapiTTS.js +26 -26
  171. package/dist/synthesis/StreamlabsPollyTTS.d.ts +2 -2
  172. package/dist/synthesis/StreamlabsPollyTTS.js +27 -27
  173. package/dist/synthesis/SvoxPicoTTS.d.ts +2 -2
  174. package/dist/synthesis/SvoxPicoTTS.js +65 -65
  175. package/dist/synthesis/SvoxPicoTTS.js.map +1 -1
  176. package/dist/synthesis/VitsTTS.d.ts +3 -3
  177. package/dist/synthesis/VitsTTS.js +378 -378
  178. package/dist/synthesis/VitsTTS.js.map +1 -1
  179. package/dist/tests/Test.js +2 -2
  180. package/dist/utilities/Compression.d.ts +5 -0
  181. package/dist/utilities/Compression.js +29 -13
  182. package/dist/utilities/Compression.js.map +1 -1
  183. package/dist/utilities/FileDownloader.d.ts +1 -1
  184. package/dist/utilities/FileDownloader.js +16 -16
  185. package/dist/utilities/FileSystem.js +7 -7
  186. package/dist/utilities/Locale.d.ts +7 -7
  187. package/dist/utilities/Locale.js +15 -15
  188. package/dist/utilities/Logger.js +3 -3
  189. package/dist/utilities/ObjectUtilities.js +19 -19
  190. package/dist/utilities/OpenPromise.js +2 -2
  191. package/dist/utilities/OpenPromise.js.map +1 -1
  192. package/dist/utilities/PackageManager.js +31 -0
  193. package/dist/utilities/PackageManager.js.map +1 -1
  194. package/dist/utilities/PathUtilities.js +8 -8
  195. package/dist/utilities/RandomGenerator.js +2 -2
  196. package/dist/utilities/SmoothEstimator.d.ts +8 -0
  197. package/dist/utilities/SmoothEstimator.js +25 -0
  198. package/dist/utilities/SmoothEstimator.js.map +1 -0
  199. package/dist/utilities/TarballMaker.js +8 -8
  200. package/dist/utilities/Timeline.d.ts +3 -2
  201. package/dist/utilities/Timeline.js +11 -11
  202. package/dist/utilities/Timeline.js.map +1 -1
  203. package/dist/utilities/Timer.js +4 -4
  204. package/dist/utilities/Utilities.d.ts +4 -0
  205. package/dist/utilities/Utilities.js +38 -15
  206. package/dist/utilities/Utilities.js.map +1 -1
  207. package/dist/utilities/WasmMemoryManager.js +7 -7
  208. package/dist/utilities/WebReader.js +23 -23
  209. package/dist/utilities/WikipediaReader.js +2 -2
  210. package/dist/voice-activity-detection/AdaptiveGateVAD.d.ts +28 -0
  211. package/dist/voice-activity-detection/AdaptiveGateVAD.js +138 -0
  212. package/dist/voice-activity-detection/AdaptiveGateVAD.js.map +1 -0
  213. package/dist/voice-activity-detection/SileroVAD.d.ts +1 -1
  214. package/dist/voice-activity-detection/SileroVAD.js +5 -5
  215. package/dist/voice-activity-detection/SileroVAD.js.map +1 -1
  216. package/dist/voice-activity-detection/WebRtcVAD.d.ts +1 -1
  217. package/dist/voice-activity-detection/WebRtcVAD.js +4 -4
  218. package/docs/API.md +29 -11
  219. package/docs/CLI.md +31 -7
  220. package/docs/Contributing.md +38 -0
  221. package/docs/Development.md +93 -19
  222. package/docs/Engines.md +28 -16
  223. package/docs/Licenses.md +4 -1
  224. package/docs/Options.md +158 -78
  225. package/docs/Releases.md +262 -0
  226. package/docs/Server.md +7 -7
  227. package/docs/Tasklist.md +95 -76
  228. package/docs/Technical.md +4 -4
  229. package/package.json +13 -14
  230. package/src/alignment/DTWMfccSequenceAlignment.ts +9 -9
  231. package/src/alignment/DTWSequenceAlignment.ts +2 -2
  232. package/src/alignment/DTWSequenceAlignmentWindowed.ts +3 -3
  233. package/src/alignment/LevenshteinSequenceAlignment.ts +2 -2
  234. package/src/alignment/SpeechAlignment.ts +204 -119
  235. package/src/api/API.ts +14 -13
  236. package/src/api/APIOptions.ts +12 -11
  237. package/src/api/Alignment.ts +147 -90
  238. package/src/api/Common.ts +1 -1
  239. package/src/api/Denoising.ts +28 -28
  240. package/src/api/LanguageDetection.ts +135 -48
  241. package/src/api/Recognition.ts +198 -59
  242. package/src/api/SourceSeparation.ts +99 -0
  243. package/src/api/Synthesis.ts +217 -181
  244. package/src/api/Translation.ts +193 -40
  245. package/src/api/Vad.ts +110 -41
  246. package/src/audio/AudioBufferConversion.ts +4 -4
  247. package/src/audio/AudioPlayer.ts +27 -27
  248. package/src/audio/AudioRecorder.ts +5 -5
  249. package/src/audio/AudioUtilities.ts +107 -24
  250. package/src/cli/CLI.ts +313 -164
  251. package/src/cli/CLIConfigFile.ts +8 -8
  252. package/src/cli/CLILauncher.ts +6 -6
  253. package/src/cli/CLIOptionsSchema.ts +2 -2
  254. package/src/cli/CLIParser.ts +5 -5
  255. package/src/cli/CLIStarter.ts +4 -4
  256. package/src/codecs/FFMpegTranscoder.ts +38 -38
  257. package/src/codecs/TIMITCodec.ts +5 -5
  258. package/src/codecs/WaveCodec.ts +22 -22
  259. package/src/denoising/RNNoise.ts +9 -9
  260. package/src/dsp/BiquadFilter.ts +19 -11
  261. package/src/dsp/DecayingPeakEstimator.ts +35 -0
  262. package/src/dsp/FFT.ts +103 -35
  263. package/src/dsp/KWeightingFilter.ts +43 -0
  264. package/src/dsp/LoudnessEstimator.ts +74 -0
  265. package/src/dsp/MFCC.ts +15 -15
  266. package/src/dsp/MelSpectogram.ts +7 -7
  267. package/src/dsp/Rubberband.ts +38 -38
  268. package/src/dsp/Sonic.ts +4 -4
  269. package/src/dsp/SpeexResampler.ts +2 -2
  270. package/src/math/VectorMath.ts +42 -33
  271. package/src/nlp/ChineseSegmentation.ts +3 -3
  272. package/src/nlp/CompromiseNLP.ts +3 -3
  273. package/src/nlp/EspeakPhonemizer.ts +30 -30
  274. package/src/nlp/IPA.ts +20 -20
  275. package/src/nlp/JapaneseSegmentation.ts +6 -6
  276. package/src/nlp/Lexicon.ts +8 -8
  277. package/src/nlp/Segmentation.ts +23 -14
  278. package/src/nlp/TextNormalizer.ts +16 -16
  279. package/src/recognition/AmazonTranscribeSTT.ts +16 -17
  280. package/src/recognition/AzureCognitiveServicesSTT.ts +8 -6
  281. package/src/recognition/GoogleCloudSTT.ts +21 -21
  282. package/src/recognition/OpenAICloudSTT.ts +142 -0
  283. package/src/recognition/SileroSTT.ts +26 -26
  284. package/src/recognition/VoskSTT.ts +10 -10
  285. package/src/recognition/WhisperCppSTT.ts +555 -0
  286. package/src/recognition/WhisperSTT.ts +760 -507
  287. package/src/server/Client.ts +23 -23
  288. package/src/server/Server.ts +9 -9
  289. package/src/server/Worker.ts +53 -53
  290. package/src/server/WorkerStarter.ts +2 -2
  291. package/src/source-separation/MDXNetSourceSeparation.ts +228 -0
  292. package/src/speech-language-detection/SileroLanguageDetection.ts +8 -8
  293. package/src/subtitles/Subtitles.ts +3 -3
  294. package/src/synthesis/AwsPollyTTS.ts +14 -14
  295. package/src/synthesis/AzureCognitiveServicesTTS.ts +10 -10
  296. package/src/synthesis/CoquiServerTTS.ts +10 -10
  297. package/src/synthesis/ElevenlabsTTS.ts +137 -0
  298. package/src/synthesis/EspeakTTS.ts +90 -71
  299. package/src/synthesis/FliteTTS.ts +157 -157
  300. package/src/synthesis/GoogleCloudTTS.ts +19 -19
  301. package/src/synthesis/GoogleTranslateTTS.ts +104 -104
  302. package/src/synthesis/MicrosoftEdgeTTS.ts +80 -80
  303. package/src/synthesis/OpenAICloudTTS.ts +196 -0
  304. package/src/synthesis/SamTTS.ts +3 -3
  305. package/src/synthesis/SapiTTS.ts +29 -29
  306. package/src/synthesis/StreamlabsPollyTTS.ts +29 -29
  307. package/src/synthesis/SvoxPicoTTS.ts +67 -67
  308. package/src/synthesis/VitsTTS.ts +380 -380
  309. package/src/tests/Test.ts +4 -4
  310. package/src/utilities/Compression.ts +34 -13
  311. package/src/utilities/FileDownloader.ts +19 -19
  312. package/src/utilities/FileSystem.ts +7 -7
  313. package/src/utilities/Locale.ts +22 -22
  314. package/src/utilities/Logger.ts +4 -4
  315. package/src/utilities/ObjectUtilities.ts +19 -19
  316. package/src/utilities/OpenPromise.ts +2 -2
  317. package/src/utilities/PackageManager.ts +40 -0
  318. package/src/utilities/PathUtilities.ts +8 -8
  319. package/src/utilities/RandomGenerator.ts +3 -3
  320. package/src/utilities/SmoothEstimator.ts +35 -0
  321. package/src/utilities/TarballMaker.ts +9 -9
  322. package/src/utilities/Timeline.ts +15 -13
  323. package/src/utilities/Timer.ts +4 -4
  324. package/src/utilities/Utilities.ts +49 -15
  325. package/src/utilities/WasmMemoryManager.ts +7 -7
  326. package/src/utilities/WebReader.ts +23 -23
  327. package/src/utilities/WikipediaReader.ts +2 -2
  328. package/src/voice-activity-detection/AdaptiveGateVAD.ts +202 -0
  329. package/src/voice-activity-detection/SileroVAD.ts +5 -5
  330. package/src/voice-activity-detection/WebRtcVAD.ts +5 -5
  331. package/dist/synthesis/ElevenLabsTTS.d.ts +0 -8
  332. package/dist/synthesis/ElevenLabsTTS.js +0 -82
  333. package/dist/synthesis/ElevenLabsTTS.js.map +0 -1
  334. package/src/synthesis/ElevenLabsTTS.ts +0 -104
@@ -1,46 +1,82 @@
1
- import { extendDeep } from "../utilities/ObjectUtilities.js"
2
-
3
- import { logToStderr } from "../utilities/Utilities.js"
4
- import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevel, trimAudioEnd } from "../audio/AudioUtilities.js"
5
- import { Logger } from "../utilities/Logger.js"
6
-
7
- import * as API from "./API.js"
8
- import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from "../utilities/Timeline.js"
9
- import { whisperOptionsDefaults, type WhisperOptions } from "../recognition/WhisperSTT.js"
10
- import { formatLanguageCodeWithName, getShortLanguageCode, normalizeLanguageCode } from "../utilities/Locale.js"
11
- import { loadPackage } from "../utilities/PackageManager.js"
12
- import chalk from "chalk"
13
- import { SubtitlesConfig, defaultSubtitlesBaseConfig } from "../subtitles/Subtitles.js"
1
+ import { extendDeep } from '../utilities/ObjectUtilities.js'
2
+
3
+ import { logToStderr } from '../utilities/Utilities.js'
4
+ import { AudioSourceParam, RawAudio, ensureRawAudio, normalizeAudioLevel, trimAudioEnd } from '../audio/AudioUtilities.js'
5
+ import { Logger } from '../utilities/Logger.js'
6
+
7
+ import * as API from './API.js'
8
+ import { Timeline, addWordTextOffsetsToTimeline, wordTimelineToSegmentSentenceTimeline } from '../utilities/Timeline.js'
9
+ import { type WhisperOptions } from '../recognition/WhisperSTT.js'
10
+ import { formatLanguageCodeWithName, getShortLanguageCode, normalizeLanguageCode } from '../utilities/Locale.js'
11
+ import { loadPackage } from '../utilities/PackageManager.js'
12
+ import chalk from 'chalk'
13
+ import { SubtitlesConfig, defaultSubtitlesBaseConfig } from '../subtitles/Subtitles.js'
14
+ import { OpenAICloudSTTOptions, defaultOpenAICloudSTTOptions } from '../recognition/OpenAICloudSTT.js'
15
+ import { WhisperCppOptions } from '../recognition/WhisperCppSTT.js'
14
16
 
15
17
  const log = logToStderr
16
18
 
17
19
  export async function recognize(input: AudioSourceParam, options: RecognitionOptions): Promise<RecognitionResult> {
18
20
  const logger = new Logger()
21
+
19
22
  const startTimestamp = logger.getTimestamp()
20
23
 
21
- logger.start("Prepare for recognition")
24
+ options = extendDeep(defaultRecognitionOptions, options)
22
25
 
23
26
  const inputRawAudio = await ensureRawAudio(input)
24
27
 
25
- let sourceRawAudio = await ensureRawAudio(inputRawAudio, 16000, 1)
28
+ let sourceRawAudio: RawAudio
29
+ let isolatedRawAudio: RawAudio | undefined
30
+ let backgroundRawAudio: RawAudio | undefined
31
+
32
+ if (options.isolate) {
33
+ logger.log(``)
34
+ logger.end();
35
+
36
+ ({ isolatedRawAudio, backgroundRawAudio } = await API.isolate(inputRawAudio, options.sourceSeparation!))
37
+
38
+ logger.end()
39
+ logger.log(``)
40
+
41
+ sourceRawAudio = await ensureRawAudio(isolatedRawAudio, 16000, 1)
42
+ } else {
43
+ sourceRawAudio = await ensureRawAudio(inputRawAudio, 16000, 1)
44
+ }
45
+
46
+ let sourceUncropTimeline: Timeline | undefined
47
+
48
+ if (options.crop) {
49
+ logger.start('Crop using voice activity detection');
50
+ ({ timeline: sourceUncropTimeline, croppedRawAudio: sourceRawAudio } = await API.detectVoiceActivity(sourceRawAudio, options.vad!))
51
+
52
+ logger.end()
53
+ }
54
+
55
+ logger.start('Prepare for recognition')
56
+
26
57
  sourceRawAudio = normalizeAudioLevel(sourceRawAudio)
27
58
  sourceRawAudio.audioChannels[0] = trimAudioEnd(sourceRawAudio.audioChannels[0])
28
59
 
29
- options = extendDeep(defaultRecognitionOptions, options)
30
-
31
60
  const engine = options.engine!
32
61
 
33
- if (!options.language) { // && options.engine != "whisper") {
34
- logger.start("No language specified. Detecting speech language")
35
- const { detectedLanguage } = await API.detectSpeechLanguage(inputRawAudio, options.languageDetection || {})
62
+ if (!options.language) { // && options.engine != 'whisper') {
63
+ logger.start('No language specified. Detecting speech language')
64
+ const { detectedLanguage } = await API.detectSpeechLanguage(sourceRawAudio, options.languageDetection!)
36
65
 
37
66
  logger.end()
38
67
  logger.logTitledMessage('Language detected', formatLanguageCodeWithName(detectedLanguage))
39
68
 
40
69
  options.language = detectedLanguage
70
+ } else {
71
+ logger.end()
72
+
73
+ const specifiedLanguageFormatted = formatLanguageCodeWithName(getShortLanguageCode(normalizeLanguageCode(options.language)))
74
+
75
+ logger.logTitledMessage('Language specified', specifiedLanguageFormatted)
41
76
  }
42
77
 
43
- let language = normalizeLanguageCode(options.language)
78
+ const languageCode = normalizeLanguageCode(options.language)
79
+ const shortLanguageCode = getShortLanguageCode(languageCode)
44
80
 
45
81
  let transcript: string
46
82
  let timeline: Timeline | undefined
@@ -48,28 +84,54 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
48
84
  logger.start(`Load ${engine} module`)
49
85
 
50
86
  switch (engine) {
51
- case "whisper": {
52
- const WhisperSTT = await import("../recognition/WhisperSTT.js")
87
+ case 'whisper': {
88
+ const WhisperSTT = await import('../recognition/WhisperSTT.js')
53
89
 
54
90
  const whisperOptions = options.whisper!
55
91
 
56
- const shortLanguageCode = getShortLanguageCode(language)
92
+ logger.end()
57
93
 
58
- const { modelName, modelDir, tokenizerDir } = await WhisperSTT.loadPackagesAndGetPaths(whisperOptions.model, shortLanguageCode)
94
+ const { modelName, modelDir } = await WhisperSTT.loadPackagesAndGetPaths(whisperOptions.model, shortLanguageCode)
59
95
 
60
- if (shortLanguageCode != "en" && modelName.endsWith(".en")) {
61
- throw new Error(`The model '${modelName}' is English only and cannot transcribe language '${shortLanguageCode}'`)
62
- }
96
+ logger.end();
97
+
98
+ ({ transcript, timeline } = await WhisperSTT.recognize(
99
+ sourceRawAudio,
100
+ modelName,
101
+ modelDir,
102
+ 'transcribe',
103
+ shortLanguageCode,
104
+ whisperOptions
105
+ ))
106
+
107
+ break
108
+ }
109
+
110
+ case 'whisper.cpp': {
111
+ const WhisperCppSTT = await import('../recognition/WhisperCppSTT.js')
112
+
113
+ const whisperCppOptions = options.whisperCpp!
114
+
115
+ logger.end()
116
+
117
+ const { modelName, modelPath } = await WhisperCppSTT.loadModelPackage(whisperCppOptions.model, shortLanguageCode)
63
118
 
64
119
  logger.end();
65
120
 
66
- ({ transcript, timeline } = await WhisperSTT.recognize(sourceRawAudio, modelName, modelDir, tokenizerDir, "transcribe", language, whisperOptions))
121
+ ({ transcript, timeline } = await WhisperCppSTT.recognize(
122
+ sourceRawAudio,
123
+ 'transcribe',
124
+ shortLanguageCode,
125
+ modelName,
126
+ modelPath,
127
+ whisperCppOptions,
128
+ ))
67
129
 
68
130
  break
69
131
  }
70
132
 
71
- case "vosk": {
72
- const VoskSTT = await import("../recognition/VoskSTT.js")
133
+ case 'vosk': {
134
+ const VoskSTT = await import('../recognition/VoskSTT.js')
73
135
 
74
136
  try {
75
137
  await import('@echogarden/vosk')
@@ -83,7 +145,7 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
83
145
  const modelPath = voskOptions.modelPath
84
146
 
85
147
  if (!modelPath) {
86
- throw new Error("Vosk models are not currently auto-downloaded. You'll need to download a model manually and set a model path in 'vosk.modelPath'.")
148
+ throw new Error(`Vosk models are not currently auto-downloaded. You'll need to download a model manually and set a model path in 'vosk.modelPath'.`)
87
149
  }
88
150
 
89
151
  logger.end();
@@ -93,15 +155,14 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
93
155
  break
94
156
  }
95
157
 
96
- case "silero": {
97
- const SileroSTT = await import("../recognition/SileroSTT.js")
158
+ case 'silero': {
159
+ const SileroSTT = await import('../recognition/SileroSTT.js')
98
160
 
99
161
  const sileroOptions = options.silero!
100
162
 
101
163
  let modelPath = sileroOptions.modelPath
102
164
 
103
165
  if (!modelPath) {
104
- const shortLanguageCode = getShortLanguageCode(language)
105
166
  const packageName = SileroSTT.languageCodeToPackageName[shortLanguageCode]
106
167
 
107
168
  if (!packageName) {
@@ -118,8 +179,8 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
118
179
  break
119
180
  }
120
181
 
121
- case "google-cloud": {
122
- const GoogleCloudSTT = await import("../recognition/GoogleCloudSTT.js")
182
+ case 'google-cloud': {
183
+ const GoogleCloudSTT = await import('../recognition/GoogleCloudSTT.js')
123
184
 
124
185
  const apiKey = options.googleCloud!.apiKey
125
186
 
@@ -129,57 +190,73 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
129
190
 
130
191
  logger.end();
131
192
 
132
- ({ transcript, timeline } = await GoogleCloudSTT.recognize(sourceRawAudio, apiKey, language))
193
+ ({ transcript, timeline } = await GoogleCloudSTT.recognize(sourceRawAudio, apiKey, shortLanguageCode))
133
194
 
134
195
  break
135
196
  }
136
197
 
137
- case "microsoft-azure": {
138
- const AzureCognitiveServicesSTT = await import("../recognition/AzureCognitiveServicesSTT.js")
198
+ case 'microsoft-azure': {
199
+ const AzureCognitiveServicesSTT = await import('../recognition/AzureCognitiveServicesSTT.js')
139
200
 
140
201
  const subscriptionKey = options.microsoftAzure!.subscriptionKey
141
202
 
142
203
  if (!subscriptionKey) {
143
- throw new Error(`No subscription key given`)
204
+ throw new Error(`No Microsoft Azure subscription key provided`)
144
205
  }
145
206
 
146
207
  const serviceRegion = options.microsoftAzure!.serviceRegion
147
208
 
148
209
  if (!serviceRegion) {
149
- throw new Error(`No service region given`)
210
+ throw new Error(`No Microsoft Azure service region provided`)
150
211
  }
151
212
 
152
213
  logger.end();
153
214
 
154
- ({ transcript, timeline } = await AzureCognitiveServicesSTT.recognize(sourceRawAudio, subscriptionKey, serviceRegion, language))
215
+ ({ transcript, timeline } = await AzureCognitiveServicesSTT.recognize(sourceRawAudio, subscriptionKey, serviceRegion, shortLanguageCode))
155
216
 
156
217
  break
157
218
  }
158
219
 
159
- case "amazon-transcribe": {
160
- const AmazonTranscribeSTT = await import("../recognition/AmazonTranscribeSTT.js")
220
+ case 'amazon-transcribe': {
221
+ const AmazonTranscribeSTT = await import('../recognition/AmazonTranscribeSTT.js')
161
222
 
162
223
  const region = options.amazonTranscribe!.region
163
224
 
164
225
  if (!region) {
165
- throw new Error(`No region given`)
226
+ throw new Error(`No Amazon Transcribe region provided`)
166
227
  }
167
228
 
168
229
  const accessKeyId = options.amazonTranscribe!.accessKeyId
169
230
 
170
231
  if (!accessKeyId) {
171
- throw new Error(`No access key id given`)
232
+ throw new Error(`No Amazon Transcribe access key id provided`)
172
233
  }
173
234
 
174
235
  const secretAccessKey = options.amazonTranscribe!.secretAccessKey
175
236
 
176
237
  if (!secretAccessKey) {
177
- throw new Error(`No secret access key given`)
238
+ throw new Error(`No Amazon Transcribe secret access key provided`)
178
239
  }
179
240
 
180
241
  logger.end();
181
242
 
182
- ({ transcript, timeline } = await AmazonTranscribeSTT.recgonize(sourceRawAudio, language, region, accessKeyId, secretAccessKey))
243
+ ({ transcript, timeline } = await AmazonTranscribeSTT.recgonize(sourceRawAudio, shortLanguageCode, region, accessKeyId, secretAccessKey))
244
+
245
+ break
246
+ }
247
+
248
+ case 'openai-cloud': {
249
+ const OpenAICloudSTT = await import('../recognition/OpenAICloudSTT.js')
250
+
251
+ const openAICloudSTTOptions = options.openAICloud!
252
+
253
+ if (!openAICloudSTTOptions.apiKey) {
254
+ throw new Error(`No OpanAI Cloud API key provided`)
255
+ }
256
+
257
+ logger.end();
258
+
259
+ ({ transcript, timeline } = await OpenAICloudSTT.recognize(sourceRawAudio, shortLanguageCode, openAICloudSTTOptions))
183
260
 
184
261
  break
185
262
  }
@@ -189,23 +266,42 @@ export async function recognize(input: AudioSourceParam, options: RecognitionOpt
189
266
  }
190
267
  }
191
268
 
269
+ // If the engine didn't return a timeline, align to get it
192
270
  if (!timeline) {
193
271
  logger.start(`Align audio to transcript`)
194
- const alignmentOptions: API.AlignmentOptions = extendDeep(options.alignment, { language: language })
272
+ const alignmentOptions: API.AlignmentOptions = extendDeep(options.alignment, { language: languageCode })
195
273
 
196
274
  const { wordTimeline } = await API.align(sourceRawAudio, transcript, alignmentOptions)
197
275
 
198
276
  timeline = wordTimeline
199
277
  }
200
278
 
279
+ // If the audio was cropped before recognition, map the timestamps back to the original audio
280
+ if (sourceUncropTimeline && sourceUncropTimeline.length > 0) {
281
+ API.convertCroppedToUncroppedTimeline(timeline, sourceUncropTimeline)
282
+ }
283
+
284
+ // Add text offsets
201
285
  addWordTextOffsetsToTimeline(timeline, transcript)
202
286
 
203
- const { segmentTimeline } = await wordTimelineToSegmentSentenceTimeline(timeline, transcript, language, 'single', 'preserve')
287
+ // Make segment timeline
288
+ const { segmentTimeline } = await wordTimelineToSegmentSentenceTimeline(timeline, transcript, languageCode, 'single', 'preserve')
204
289
 
205
290
  logger.end()
206
291
  logger.logDuration('Total recognition time', startTimestamp, chalk.magentaBright)
207
292
 
208
- return { transcript, timeline: segmentTimeline, wordTimeline: timeline, inputRawAudio, language }
293
+ return {
294
+ transcript,
295
+
296
+ timeline: segmentTimeline,
297
+ wordTimeline: timeline,
298
+
299
+ language: languageCode,
300
+
301
+ inputRawAudio,
302
+ isolatedRawAudio,
303
+ backgroundRawAudio,
304
+ }
209
305
  }
210
306
 
211
307
  export interface RecognitionResult {
@@ -213,10 +309,13 @@ export interface RecognitionResult {
213
309
  timeline: Timeline
214
310
  wordTimeline: Timeline
215
311
  language: string
312
+
216
313
  inputRawAudio: RawAudio
314
+ isolatedRawAudio?: RawAudio
315
+ backgroundRawAudio?: RawAudio
217
316
  }
218
317
 
219
- export type RecognitionEngine = "whisper" | "vosk" | "silero" | "google-cloud" | "microsoft-azure" | "amazon-transcribe"
318
+ export type RecognitionEngine = 'whisper' | 'whisper.cpp' | 'vosk' | 'silero' | 'google-cloud' | 'microsoft-azure' | 'amazon-transcribe' | 'openai-cloud'
220
319
 
221
320
  export interface RecognitionOptions {
222
321
  engine?: RecognitionEngine
@@ -225,14 +324,24 @@ export interface RecognitionOptions {
225
324
 
226
325
  maxAlternatives?: number
227
326
 
327
+ isolate?: boolean
328
+
329
+ crop?: boolean
330
+
228
331
  alignment?: API.AlignmentOptions
229
332
 
230
333
  languageDetection?: API.SpeechLanguageDetectionOptions
231
334
 
232
335
  subtitles?: SubtitlesConfig
233
336
 
337
+ vad?: API.VADOptions
338
+
339
+ sourceSeparation?: API.SourceSeparationOptions
340
+
234
341
  whisper?: WhisperOptions
235
342
 
343
+ whisperCpp?: WhisperCppOptions
344
+
236
345
  vosk?: {
237
346
  modelPath?: string
238
347
  }
@@ -259,22 +368,38 @@ export interface RecognitionOptions {
259
368
  accessKeyId?: string
260
369
  secretAccessKey?: string
261
370
  }
371
+
372
+ openAICloud?: OpenAICloudSTTOptions
262
373
  }
263
374
 
264
375
  export const defaultRecognitionOptions: RecognitionOptions = {
265
- engine: "whisper",
376
+ engine: 'whisper',
266
377
 
267
378
  language: undefined,
268
379
 
269
380
  maxAlternatives: 1,
270
381
 
271
- alignment: undefined,
382
+ isolate: false,
272
383
 
273
- languageDetection: undefined,
384
+ crop: true,
385
+
386
+ alignment: {
387
+ },
388
+
389
+ languageDetection: {
390
+ },
274
391
 
275
392
  subtitles: defaultSubtitlesBaseConfig,
276
393
 
277
- whisper: whisperOptionsDefaults,
394
+ vad: {
395
+ engine: 'adaptive-gate'
396
+ },
397
+
398
+ whisper: {
399
+ },
400
+
401
+ whisperCpp: {
402
+ },
278
403
 
279
404
  vosk: {
280
405
  modelPath: undefined
@@ -301,14 +426,22 @@ export const defaultRecognitionOptions: RecognitionOptions = {
301
426
  region: undefined,
302
427
  accessKeyId: undefined,
303
428
  secretAccessKey: undefined,
304
- }
429
+ },
430
+
431
+ openAICloud: defaultOpenAICloudSTTOptions
305
432
  }
306
433
 
307
434
  export const recognitionEngines: API.EngineMetadata[] = [
308
435
  {
309
436
  id: 'whisper',
310
437
  name: 'OpenAI Whisper',
311
- description: 'A high accuracy transformer-based architecture by OpenAI.',
438
+ description: 'A high accuracy transformer-based speech recognition architecture by OpenAI.',
439
+ type: 'local'
440
+ },
441
+ {
442
+ id: 'whisper.cpp',
443
+ name: 'OpenAI Whisper (C++ port)',
444
+ description: 'A C++ port of the Whisper speech recognition architecture.',
312
445
  type: 'local'
313
446
  },
314
447
  {
@@ -341,4 +474,10 @@ export const recognitionEngines: API.EngineMetadata[] = [
341
474
  description: 'Amazon cloud speech-to-text service.',
342
475
  type: 'cloud'
343
476
  },
477
+ {
478
+ id: 'openai-cloud',
479
+ name: 'OpenAI Cloud',
480
+ description: 'OpenAI cloud speech-to-text service.',
481
+ type: 'cloud'
482
+ },
344
483
  ]
@@ -0,0 +1,99 @@
1
+ import { AudioSourceParam, RawAudio, ensureRawAudio, subtractAudio } from '../audio/AudioUtilities.js';
2
+ import { Logger } from '../utilities/Logger.js';
3
+ import { extendDeep } from '../utilities/ObjectUtilities.js';
4
+ import { loadPackage } from '../utilities/PackageManager.js';
5
+ import { EngineMetadata } from './Common.js';
6
+ import chalk from 'chalk';
7
+ import { readdir } from '../utilities/FileSystem.js';
8
+ import path from 'node:path';
9
+
10
+ export async function isolate(input: AudioSourceParam, options: SourceSeparationOptions): Promise<SourceSeparationResult> {
11
+ const logger = new Logger()
12
+ const startTimestamp = logger.getTimestamp()
13
+
14
+ logger.start('Prepare for source separation')
15
+
16
+ const inputRawAudio = await ensureRawAudio(input)
17
+
18
+ let isolatedRawAudio: RawAudio
19
+ let backgroundRawAudio: RawAudio
20
+
21
+ options = extendDeep(defaultSourceSeparationOptions, options)
22
+
23
+ switch (options.engine) {
24
+ case 'mdx-net': {
25
+ const MDXNetSourceSeparation = await import('../source-separation/MDXNetSourceSeparation.js')
26
+
27
+ const mdxNetOptions = options.mdxNet!
28
+
29
+ const packageDir = await loadPackage(`mdxnet-${mdxNetOptions.model!}`)
30
+ const modelFilename = (await readdir(packageDir)).filter(name => name.endsWith('onnx'))[0]
31
+
32
+ if (!modelFilename) {
33
+ throw new Error(`Couldn't find an ONNX model file in package directory`)
34
+ }
35
+
36
+ const modelPath = path.join(packageDir, modelFilename)
37
+
38
+ logger.end()
39
+
40
+ const audioStereo44100 = await ensureRawAudio(inputRawAudio, 44100, 2)
41
+
42
+ isolatedRawAudio = await MDXNetSourceSeparation.isolate(audioStereo44100, modelPath)
43
+
44
+ logger.end()
45
+
46
+ logger.start(`Subtract from original waveform to extract background audio`)
47
+ backgroundRawAudio = subtractAudio(audioStereo44100, isolatedRawAudio)
48
+
49
+ break
50
+ }
51
+
52
+ default: {
53
+ throw new Error(`Engine '${options.engine}' is not supported`)
54
+ }
55
+ }
56
+
57
+ logger.end()
58
+ logger.log('')
59
+ logger.logDuration(`Total source separation time`, startTimestamp, chalk.magentaBright)
60
+
61
+ return {
62
+ inputRawAudio,
63
+ isolatedRawAudio,
64
+ backgroundRawAudio
65
+ }
66
+ }
67
+
68
+ export type SourceSeparationEngine = 'mdx-net'
69
+
70
+ export interface SourceSeparationOptions {
71
+ engine?: SourceSeparationEngine
72
+
73
+ mdxNet?: {
74
+ model?: string
75
+ }
76
+ }
77
+
78
+ export const defaultSourceSeparationOptions: SourceSeparationOptions = {
79
+ engine: 'mdx-net',
80
+
81
+ mdxNet: {
82
+ model: 'UVR_MDXNET_1_9703'
83
+ }
84
+ }
85
+
86
+ export interface SourceSeparationResult {
87
+ inputRawAudio: RawAudio
88
+ isolatedRawAudio: RawAudio
89
+ backgroundRawAudio: RawAudio
90
+ }
91
+
92
+ export const sourceSeparationEngines: EngineMetadata[] = [
93
+ {
94
+ id: 'mdx-net',
95
+ name: 'MDX-NET',
96
+ description: 'Deep learning source separation architecture by KUIELAB (Korea University).',
97
+ type: 'local'
98
+ },
99
+ ]