echogarden 1.8.6 → 2.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.
- package/README.md +23 -18
- package/data/schemas/options.json +52 -47
- package/dist/alignment/DTWSequenceAlignment.d.ts +1 -1
- package/dist/alignment/DTWSequenceAlignment.js +5 -5
- package/dist/alignment/DTWSequenceAlignment.js.map +1 -1
- package/dist/alignment/SpeechAlignment.js +6 -6
- package/dist/alignment/SpeechAlignment.js.map +1 -1
- package/dist/api/Alignment.d.ts +1 -1
- package/dist/api/Alignment.js +49 -11
- package/dist/api/Alignment.js.map +1 -1
- package/dist/api/Denoising.d.ts +4 -2
- package/dist/api/Denoising.js +65 -13
- package/dist/api/Denoising.js.map +1 -1
- package/dist/api/SourceSeparation.js +9 -6
- package/dist/api/SourceSeparation.js.map +1 -1
- package/dist/api/SpeechLanguageDetection.js +4 -4
- package/dist/api/SpeechLanguageDetection.js.map +1 -1
- package/dist/api/Synthesis.d.ts +2 -2
- package/dist/api/Synthesis.js +10 -7
- package/dist/api/Synthesis.js.map +1 -1
- package/dist/api/VoiceActivityDetection.js +2 -2
- package/dist/api/VoiceActivityDetection.js.map +1 -1
- package/dist/audio/AudioBufferConversion.d.ts +2 -2
- package/dist/audio/AudioBufferConversion.js +77 -43
- package/dist/audio/AudioBufferConversion.js.map +1 -1
- package/dist/audio/AudioPlayer.d.ts +7 -5
- package/dist/audio/AudioPlayer.js +136 -50
- package/dist/audio/AudioPlayer.js.map +1 -1
- package/dist/audio/AudioUtilities.d.ts +4 -3
- package/dist/audio/AudioUtilities.js +30 -15
- package/dist/audio/AudioUtilities.js.map +1 -1
- package/dist/audio/SoxPath.js +3 -3
- package/dist/audio/SoxPath.js.map +1 -1
- package/dist/build-tools/MakeTarballsForInstalledPackages.js +3 -3
- package/dist/build-tools/MakeTarballsForInstalledPackages.js.map +1 -1
- package/dist/cli/CLI.js +30 -36
- package/dist/cli/CLI.js.map +1 -1
- package/dist/cli/CLIConfigFile.js +2 -2
- package/dist/cli/CLIConfigFile.js.map +1 -1
- package/dist/cli/CLIOptions.d.ts +2 -0
- package/dist/cli/CLIOptions.js +1 -1
- package/dist/cli/CLIOptions.js.map +1 -1
- package/dist/codecs/FFMpegTranscoder.d.ts +3 -3
- package/dist/codecs/FFMpegTranscoder.js +6 -6
- package/dist/codecs/FFMpegTranscoder.js.map +1 -1
- package/dist/codecs/TIMITCodec.d.ts +1 -1
- package/dist/codecs/TIMITCodec.js +4 -3
- package/dist/codecs/TIMITCodec.js.map +1 -1
- package/dist/codecs/WaveCodec.d.ts +3 -3
- package/dist/codecs/WaveCodec.js +37 -34
- package/dist/codecs/WaveCodec.js.map +1 -1
- package/dist/data-structures/DynamicTypedArray.d.ts +17 -0
- package/dist/data-structures/DynamicTypedArray.js +47 -0
- package/dist/data-structures/DynamicTypedArray.js.map +1 -0
- package/dist/data-structures/Queue.js.map +1 -0
- package/dist/data-structures/WindowedList.js.map +1 -0
- package/dist/denoising/NSNet2.d.ts +26 -0
- package/dist/denoising/NSNet2.js +128 -0
- package/dist/denoising/NSNet2.js.map +1 -0
- package/dist/denoising/RNNoise.js +3 -3
- package/dist/denoising/RNNoise.js.map +1 -1
- package/dist/dsp/FFT.d.ts +6 -1
- package/dist/dsp/FFT.js +17 -0
- package/dist/dsp/FFT.js.map +1 -1
- package/dist/encodings/Ascii.d.ts +10 -0
- package/dist/encodings/Ascii.js +41 -0
- package/dist/encodings/Ascii.js.map +1 -0
- package/dist/encodings/Base64.d.ts +5 -0
- package/dist/encodings/Base64.js +114 -0
- package/dist/encodings/Base64.js.map +1 -0
- package/dist/encodings/Hex.d.ts +3 -0
- package/dist/encodings/Hex.js +52 -0
- package/dist/encodings/Hex.js.map +1 -0
- package/dist/{utilities → encodings}/LEB128.d.ts +1 -1
- package/dist/{utilities → encodings}/LEB128.js +4 -4
- package/dist/encodings/LEB128.js.map +1 -0
- package/dist/{utilities → encodings}/LPVarInt.d.ts +1 -1
- package/dist/{utilities → encodings}/LPVarInt.js +6 -6
- package/dist/encodings/LPVarInt.js.map +1 -0
- package/dist/encodings/TextEncodingsCommon.d.ts +4 -0
- package/dist/encodings/TextEncodingsCommon.js +2 -0
- package/dist/encodings/TextEncodingsCommon.js.map +1 -0
- package/dist/encodings/Utf16.d.ts +10 -0
- package/dist/encodings/Utf16.js +36 -0
- package/dist/encodings/Utf16.js.map +1 -0
- package/dist/encodings/Utf32.d.ts +9 -0
- package/dist/encodings/Utf32.js +44 -0
- package/dist/encodings/Utf32.js.map +1 -0
- package/dist/encodings/Utf8.d.ts +10 -0
- package/dist/encodings/Utf8.js +97 -0
- package/dist/encodings/Utf8.js.map +1 -0
- package/dist/math/MedianFilter.js.map +1 -1
- package/dist/nlp/JapaneseSegmentation.js +2 -2
- package/dist/nlp/JapaneseSegmentation.js.map +1 -1
- package/dist/recognition/GoogleCloudSTT.js +2 -1
- package/dist/recognition/GoogleCloudSTT.js.map +1 -1
- package/dist/recognition/SileroSTT.js +3 -3
- package/dist/recognition/SileroSTT.js.map +1 -1
- package/dist/recognition/VoskSTT.js +3 -3
- package/dist/recognition/VoskSTT.js.map +1 -1
- package/dist/recognition/WhisperCppSTT.js +4 -5
- package/dist/recognition/WhisperCppSTT.js.map +1 -1
- package/dist/recognition/WhisperSTT.js +8 -7
- package/dist/recognition/WhisperSTT.js.map +1 -1
- package/dist/server/Client.d.ts +1 -1
- package/dist/server/Client.js +2 -1
- package/dist/server/Client.js.map +1 -1
- package/dist/server/Server.js +5 -4
- package/dist/server/Server.js.map +1 -1
- package/dist/server/Worker.js +1 -1
- package/dist/server/Worker.js.map +1 -1
- package/dist/source-separation/MDXNetSourceSeparation.js +1 -1
- package/dist/source-separation/MDXNetSourceSeparation.js.map +1 -1
- package/dist/speech-search/DTWSpeechSearch.d.ts +1 -1
- package/dist/speech-search/DTWSpeechSearch.js +25 -6
- package/dist/speech-search/DTWSpeechSearch.js.map +1 -1
- package/dist/subtitles/Subtitles.js +2 -2
- package/dist/subtitles/Subtitles.js.map +1 -1
- package/dist/synthesis/AzureCognitiveServicesTTS.js +17 -18
- package/dist/synthesis/AzureCognitiveServicesTTS.js.map +1 -1
- package/dist/synthesis/CoquiServerTTS.js +1 -1
- package/dist/synthesis/CoquiServerTTS.js.map +1 -1
- package/dist/synthesis/ElevenlabsTTS.js +1 -1
- package/dist/synthesis/ElevenlabsTTS.js.map +1 -1
- package/dist/synthesis/EspeakTTS.d.ts +0 -1
- package/dist/synthesis/EspeakTTS.js +0 -9
- package/dist/synthesis/EspeakTTS.js.map +1 -1
- package/dist/synthesis/FliteTTS.js +7 -8
- package/dist/synthesis/FliteTTS.js.map +1 -1
- package/dist/synthesis/GoogleCloudTTS.d.ts +1 -1
- package/dist/synthesis/GoogleCloudTTS.js +2 -1
- package/dist/synthesis/GoogleCloudTTS.js.map +1 -1
- package/dist/synthesis/GoogleTranslateTTS.d.ts +1 -1
- package/dist/synthesis/GoogleTranslateTTS.js +4 -3
- package/dist/synthesis/GoogleTranslateTTS.js.map +1 -1
- package/dist/synthesis/MicrosoftEdgeTTS.js +32 -7
- package/dist/synthesis/MicrosoftEdgeTTS.js.map +1 -1
- package/dist/synthesis/SapiTTS.js +1 -1
- package/dist/synthesis/SapiTTS.js.map +1 -1
- package/dist/synthesis/StreamlabsPollyTTS.d.ts +1 -1
- package/dist/synthesis/StreamlabsPollyTTS.js +1 -1
- package/dist/synthesis/StreamlabsPollyTTS.js.map +1 -1
- package/dist/synthesis/SvoxPicoTTS.js +6 -5
- package/dist/synthesis/SvoxPicoTTS.js.map +1 -1
- package/dist/synthesis/VitsTTS.js +2 -2
- package/dist/synthesis/VitsTTS.js.map +1 -1
- package/dist/tests/Test.js +0 -25
- package/dist/tests/Test.js.map +1 -1
- package/dist/text-language-detection/FastTextLanguageDetection.js +2 -2
- package/dist/text-language-detection/FastTextLanguageDetection.js.map +1 -1
- package/dist/typings/TypedArray.d.ts +4 -0
- package/dist/typings/TypedArray.js +2 -0
- package/dist/typings/TypedArray.js.map +1 -0
- package/dist/utilities/BinaryArrayConversion.d.ts +12 -22
- package/dist/utilities/BinaryArrayConversion.js +40 -90
- package/dist/utilities/BinaryArrayConversion.js.map +1 -1
- package/dist/utilities/BinaryUtilities.d.ts +13 -0
- package/dist/utilities/BinaryUtilities.js +113 -0
- package/dist/utilities/BinaryUtilities.js.map +1 -0
- package/dist/utilities/Compression.js +7 -6
- package/dist/utilities/Compression.js.map +1 -1
- package/dist/utilities/FileDownloader.js +26 -47
- package/dist/utilities/FileDownloader.js.map +1 -1
- package/dist/utilities/FileReader.d.ts +14 -0
- package/dist/utilities/FileReader.js +71 -0
- package/dist/utilities/FileReader.js.map +1 -0
- package/dist/utilities/FileSystem.d.ts +19 -17
- package/dist/utilities/FileSystem.js +170 -106
- package/dist/utilities/FileSystem.js.map +1 -1
- package/dist/utilities/FileWriter.d.ts +12 -0
- package/dist/utilities/FileWriter.js +60 -0
- package/dist/utilities/FileWriter.js.map +1 -0
- package/dist/utilities/NpmUtilities.d.ts +1 -0
- package/dist/utilities/NpmUtilities.js +14 -0
- package/dist/utilities/NpmUtilities.js.map +1 -0
- package/dist/utilities/PackageManager.js +7 -5
- package/dist/utilities/PackageManager.js.map +1 -1
- package/dist/utilities/PathUtilities.d.ts +8 -0
- package/dist/utilities/PathUtilities.js +28 -7
- package/dist/utilities/PathUtilities.js.map +1 -1
- package/dist/utilities/SignalChannel.d.ts +3 -1
- package/dist/utilities/SignalChannel.js +9 -5
- package/dist/utilities/SignalChannel.js.map +1 -1
- package/dist/utilities/StringBuilder.d.ts +10 -0
- package/dist/utilities/StringBuilder.js +39 -0
- package/dist/utilities/StringBuilder.js.map +1 -0
- package/dist/utilities/StringUtilities.js.map +1 -1
- package/dist/utilities/TarballMaker.js +6 -7
- package/dist/utilities/TarballMaker.js.map +1 -1
- package/dist/utilities/Timer.js +2 -2
- package/dist/utilities/Timer.js.map +1 -1
- package/dist/utilities/Utilities.d.ts +11 -4
- package/dist/utilities/Utilities.js +70 -18
- package/dist/utilities/Utilities.js.map +1 -1
- package/dist/utilities/VirtualFileReadStream.d.ts +3 -3
- package/dist/utilities/VirtualFileReadStream.js.map +1 -1
- package/dist/utilities/WasmMemoryManager.d.ts +5 -2
- package/dist/utilities/WasmMemoryManager.js +15 -3
- package/dist/utilities/WasmMemoryManager.js.map +1 -1
- package/docs/API.md +1 -1
- package/docs/Licenses.md +3 -0
- package/docs/Options.md +9 -3
- package/docs/Tasklist.md +0 -1
- package/docs/Technical.md +2 -2
- package/package.json +20 -22
- package/src/alignment/DTWSequenceAlignment.ts +5 -5
- package/src/alignment/SpeechAlignment.ts +6 -6
- package/src/api/Alignment.ts +65 -12
- package/src/api/Denoising.ts +97 -17
- package/src/api/SourceSeparation.ts +11 -8
- package/src/api/SpeechLanguageDetection.ts +4 -4
- package/src/api/Synthesis.ts +15 -11
- package/src/api/VoiceActivityDetection.ts +2 -2
- package/src/audio/AudioBufferConversion.ts +84 -45
- package/src/audio/AudioPlayer.ts +156 -54
- package/src/audio/AudioUtilities.ts +38 -22
- package/src/audio/SoxPath.ts +3 -3
- package/src/build-tools/MakeTarballsForInstalledPackages.ts +3 -3
- package/src/cli/CLI.ts +30 -36
- package/src/cli/CLIConfigFile.ts +2 -2
- package/src/cli/CLIOptions.ts +4 -1
- package/src/codecs/FFMpegTranscoder.ts +11 -11
- package/src/codecs/TIMITCodec.ts +5 -4
- package/src/codecs/WaveCodec.ts +42 -39
- package/src/data-structures/DynamicTypedArray.ts +64 -0
- package/src/denoising/NSNet2.ts +182 -0
- package/src/denoising/RNNoise.ts +3 -3
- package/src/dsp/FFT.ts +21 -1
- package/src/encodings/Ascii.ts +60 -0
- package/src/encodings/Base64.ts +157 -0
- package/src/encodings/Hex.ts +67 -0
- package/src/{utilities → encodings}/LEB128.ts +4 -4
- package/src/{utilities → encodings}/LPVarInt.ts +6 -6
- package/src/encodings/TextEncodingsCommon.ts +4 -0
- package/src/encodings/Utf16.ts +52 -0
- package/src/encodings/Utf32.ts +62 -0
- package/src/encodings/Utf8.ts +117 -0
- package/src/math/MedianFilter.ts +0 -2
- package/src/nlp/JapaneseSegmentation.ts +2 -2
- package/src/recognition/GoogleCloudSTT.ts +2 -1
- package/src/recognition/SileroSTT.ts +3 -3
- package/src/recognition/VoskSTT.ts +3 -3
- package/src/recognition/WhisperCppSTT.ts +4 -5
- package/src/recognition/WhisperSTT.ts +8 -7
- package/src/server/Client.ts +4 -3
- package/src/server/Server.ts +6 -5
- package/src/server/Worker.ts +1 -1
- package/src/source-separation/MDXNetSourceSeparation.ts +1 -1
- package/src/speech-search/DTWSpeechSearch.ts +36 -7
- package/src/subtitles/Subtitles.ts +3 -3
- package/src/synthesis/AzureCognitiveServicesTTS.ts +18 -15
- package/src/synthesis/CoquiServerTTS.ts +2 -2
- package/src/synthesis/ElevenlabsTTS.ts +1 -1
- package/src/synthesis/EspeakTTS.ts +0 -15
- package/src/synthesis/FliteTTS.ts +7 -8
- package/src/synthesis/GoogleCloudTTS.ts +3 -2
- package/src/synthesis/GoogleTranslateTTS.ts +5 -4
- package/src/synthesis/MicrosoftEdgeTTS.ts +47 -15
- package/src/synthesis/SapiTTS.ts +1 -1
- package/src/synthesis/StreamlabsPollyTTS.ts +1 -1
- package/src/synthesis/SvoxPicoTTS.ts +8 -7
- package/src/synthesis/VitsTTS.ts +2 -2
- package/src/tests/Test.ts +0 -30
- package/src/text-language-detection/FastTextLanguageDetection.ts +2 -2
- package/src/typings/Fillers.d.ts +2 -4
- package/src/typings/TypedArray.ts +5 -0
- package/src/utilities/BinaryArrayConversion.ts +51 -125
- package/src/utilities/BinaryUtilities.ts +138 -0
- package/src/utilities/Compression.ts +7 -6
- package/src/utilities/FileDownloader.ts +27 -52
- package/src/utilities/FileReader.ts +89 -0
- package/src/utilities/FileSystem.ts +215 -116
- package/src/utilities/FileWriter.ts +72 -0
- package/src/utilities/NpmUtilities.ts +23 -0
- package/src/utilities/PackageManager.ts +8 -5
- package/src/utilities/PathUtilities.ts +36 -7
- package/src/utilities/SignalChannel.ts +14 -7
- package/src/utilities/StringBuilder.ts +45 -0
- package/src/utilities/StringUtilities.ts +2 -0
- package/src/utilities/TarballMaker.ts +6 -7
- package/src/utilities/Timer.ts +4 -2
- package/src/utilities/Utilities.ts +80 -23
- package/src/utilities/VirtualFileReadStream.ts +5 -5
- package/src/utilities/WasmMemoryManager.ts +21 -5
- package/tsconfig.json +96 -0
- package/dist/utilities/DynamicUint8Array.d.ts +0 -9
- package/dist/utilities/DynamicUint8Array.js +0 -31
- package/dist/utilities/DynamicUint8Array.js.map +0 -1
- package/dist/utilities/LEB128.js.map +0 -1
- package/dist/utilities/LPVarInt.js.map +0 -1
- package/dist/utilities/Queue.js.map +0 -1
- package/dist/utilities/WindowedList.js.map +0 -1
- package/src/utilities/DynamicUint8Array.ts +0 -39
- /package/dist/{utilities → data-structures}/Queue.d.ts +0 -0
- /package/dist/{utilities → data-structures}/Queue.js +0 -0
- /package/dist/{utilities → data-structures}/WindowedList.d.ts +0 -0
- /package/dist/{utilities → data-structures}/WindowedList.js +0 -0
- /package/src/{utilities → data-structures}/Queue.ts +0 -0
- /package/src/{utilities → data-structures}/WindowedList.ts +0 -0
package/src/api/Alignment.ts
CHANGED
|
@@ -92,10 +92,12 @@ export async function align(input: AudioSourceParam, transcript: string, options
|
|
|
92
92
|
let granularities: DtwGranularity[]
|
|
93
93
|
let windowDurations: number[]
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
granularities =
|
|
95
|
+
const dtwOptions = options.dtw!
|
|
96
|
+
|
|
97
|
+
if (typeof dtwOptions.granularity == 'string') {
|
|
98
|
+
granularities = [dtwOptions.granularity]
|
|
99
|
+
} else if (Array.isArray(dtwOptions.granularity)) {
|
|
100
|
+
granularities = dtwOptions.granularity
|
|
99
101
|
} else {
|
|
100
102
|
if (sourceAudioDuration < 1 * 60) {
|
|
101
103
|
// If up to 1 minute, set granularity to high, single pass
|
|
@@ -112,17 +114,68 @@ export async function align(input: AudioSourceParam, transcript: string, options
|
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
if (dtwOptions.windowDuration) {
|
|
118
|
+
function tryParsePercentageWindowDuration(durationString: string) {
|
|
119
|
+
durationString = durationString.trim()
|
|
120
|
+
|
|
121
|
+
const parseResult = durationString.match(/^([0-9]+)%$/)
|
|
122
|
+
|
|
123
|
+
if (parseResult == null) {
|
|
124
|
+
throw new Error(`A DTW window duration, when provided as a string, must be formatted as an integer percentage value like '15%'.`)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const percentageValue = parseInt(parseResult[1])
|
|
128
|
+
|
|
129
|
+
if (percentageValue == null || isNaN(percentageValue) || percentageValue <= 0 || percentageValue > 100) {
|
|
130
|
+
throw new Error(`'A DTW window duration, when provided as a percentage value, must be between 0 (non-inclusive) and 100 (inclusive).`)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let durationSeconds = percentageValue / 100 * sourceAudioDuration
|
|
134
|
+
durationSeconds = Math.ceil(durationSeconds)
|
|
135
|
+
durationSeconds = Math.min(durationSeconds, sourceAudioDuration)
|
|
136
|
+
|
|
137
|
+
return durationSeconds
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (typeof dtwOptions.windowDuration === 'number') {
|
|
141
|
+
const duration = Math.min(dtwOptions.windowDuration, sourceAudioDuration)
|
|
142
|
+
|
|
143
|
+
windowDurations = [duration]
|
|
144
|
+
} else if (typeof dtwOptions.windowDuration === 'string') {
|
|
145
|
+
const durationString = dtwOptions.windowDuration.trim()
|
|
146
|
+
|
|
147
|
+
const durationSeconds = tryParsePercentageWindowDuration(durationString)
|
|
148
|
+
|
|
149
|
+
windowDurations = [durationSeconds]
|
|
150
|
+
} else if (Array.isArray(dtwOptions.windowDuration)) {
|
|
151
|
+
const durationsValues = dtwOptions.windowDuration
|
|
152
|
+
|
|
153
|
+
if (durationsValues.length < 1) {
|
|
154
|
+
throw new Error(`DTW window durations, when given as an array, must have at least one element.`)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const durations: number[] = []
|
|
158
|
+
|
|
159
|
+
for (const durationValue of durationsValues) {
|
|
160
|
+
let durationSeconds: number
|
|
161
|
+
|
|
162
|
+
if (typeof durationValue === 'number') {
|
|
163
|
+
durationSeconds = durationValue
|
|
164
|
+
durationSeconds = Math.min(durationSeconds, sourceAudioDuration)
|
|
165
|
+
} else {
|
|
166
|
+
durationSeconds = tryParsePercentageWindowDuration(durationValue)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
durations.push(durationSeconds)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
windowDurations = durations
|
|
120
173
|
} else {
|
|
121
|
-
throw new Error(`'dtw.windowDuration' must be a number or
|
|
174
|
+
throw new Error(`'dtw.windowDuration' must be a number or a percentage string, or array of numbers / percentage strings.`)
|
|
122
175
|
}
|
|
123
176
|
} else {
|
|
124
177
|
if (granularities.length > 2) {
|
|
125
|
-
throw new Error(`More than two passes requested, this requires window durations to be explicitly specified for each pass. For example 'dtw.windowDuration=[
|
|
178
|
+
throw new Error(`More than two passes requested, this requires window durations to be explicitly specified for each pass. For example 'dtw.windowDuration=['20%',60,10]'.`)
|
|
126
179
|
}
|
|
127
180
|
|
|
128
181
|
if (sourceAudioDuration < 5 * 60) {
|
|
@@ -361,7 +414,7 @@ export interface AlignmentOptions {
|
|
|
361
414
|
|
|
362
415
|
dtw?: {
|
|
363
416
|
granularity?: DtwGranularity | DtwGranularity[]
|
|
364
|
-
windowDuration?: number | number[]
|
|
417
|
+
windowDuration?: number | string | (string | number)[]
|
|
365
418
|
phoneAlignmentMethod?: PhoneAlignmentMethod
|
|
366
419
|
}
|
|
367
420
|
|
package/src/api/Denoising.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
2
|
|
|
3
|
-
import { AudioSourceParam, RawAudio, applyGainDecibelsInPlace, ensureRawAudio, getSamplePeakDecibels, mixAudio, normalizeAudioLevelInPlace } from '../audio/AudioUtilities.js'
|
|
3
|
+
import { AudioSourceParam, RawAudio, applyGainDecibels, applyGainDecibelsInPlace, attenuateIfClippingInPlace, ensureRawAudio, getSamplePeakDecibels, mixAudio, normalizeAudioLevelInPlace } from '../audio/AudioUtilities.js'
|
|
4
4
|
import { Logger } from '../utilities/Logger.js'
|
|
5
5
|
|
|
6
6
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
7
7
|
import { resampleAudioSpeex } from '../dsp/SpeexResampler.js'
|
|
8
8
|
import { EngineMetadata } from './Common.js'
|
|
9
9
|
import chalk from 'chalk'
|
|
10
|
+
import { defaultNSNet2Options, NSNet2Options } from '../denoising/NSNet2.js'
|
|
11
|
+
import { loadPackage } from '../utilities/PackageManager.js'
|
|
10
12
|
|
|
11
13
|
const log = logToStderr
|
|
12
14
|
|
|
@@ -18,26 +20,34 @@ export async function denoise(input: AudioSourceParam, options: DenoisingOptions
|
|
|
18
20
|
|
|
19
21
|
const inputRawAudio = await ensureRawAudio(input)
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
logger.start(`Resample audio to ${processingSampleRate} Hz`)
|
|
24
|
-
const resampledRawAudio = await resampleAudioSpeex(inputRawAudio, processingSampleRate, 3)
|
|
25
|
-
|
|
26
|
-
logger.start(`Initialize ${options.method} module`)
|
|
23
|
+
logger.start(`Initialize ${options.engine} module`)
|
|
27
24
|
|
|
28
25
|
let denoisedAudio: RawAudio
|
|
29
26
|
|
|
30
|
-
switch (options.
|
|
27
|
+
switch (options.engine) {
|
|
31
28
|
case 'rnnoise': {
|
|
32
29
|
const RNNoise = await import('../denoising/RNNoise.js')
|
|
33
30
|
logger.end()
|
|
34
31
|
|
|
32
|
+
const processingSampleRate = 48000
|
|
33
|
+
|
|
34
|
+
logger.start(`Resample audio to ${processingSampleRate} Hz`)
|
|
35
|
+
const inputRawAudioResampled = await resampleAudioSpeex(inputRawAudio, processingSampleRate, 0)
|
|
36
|
+
|
|
35
37
|
const denoisedAudioChannels: Float32Array[] = []
|
|
36
38
|
|
|
37
|
-
for (
|
|
39
|
+
for (let channelIndex = 0; channelIndex < inputRawAudioResampled.audioChannels.length; channelIndex++) {
|
|
40
|
+
const audioChannel = inputRawAudioResampled.audioChannels[channelIndex]
|
|
41
|
+
|
|
38
42
|
const audioChannelRawAudio: RawAudio = { audioChannels: [audioChannel], sampleRate: processingSampleRate }
|
|
39
43
|
|
|
44
|
+
logger.end()
|
|
45
|
+
logger.logTitledMessage(`Denoise audio channel`, `${channelIndex}`, chalk.magentaBright)
|
|
46
|
+
|
|
40
47
|
const { denoisedRawAudio, frameVadProbabilities } = await RNNoise.denoiseAudio(audioChannelRawAudio)
|
|
48
|
+
|
|
49
|
+
logger.end()
|
|
50
|
+
|
|
41
51
|
denoisedAudioChannels.push(denoisedRawAudio.audioChannels[0])
|
|
42
52
|
}
|
|
43
53
|
|
|
@@ -46,11 +56,68 @@ export async function denoise(input: AudioSourceParam, options: DenoisingOptions
|
|
|
46
56
|
break
|
|
47
57
|
}
|
|
48
58
|
|
|
59
|
+
case 'nsnet2': {
|
|
60
|
+
const NSNet2 = await import('../denoising/NSNet2.js')
|
|
61
|
+
logger.end()
|
|
62
|
+
|
|
63
|
+
const nsnet2Options = options.nsnet2!
|
|
64
|
+
|
|
65
|
+
let processingSampleRate: number
|
|
66
|
+
let packageName: string
|
|
67
|
+
|
|
68
|
+
if (nsnet2Options.model === 'baseline-16khz') {
|
|
69
|
+
processingSampleRate = 16000
|
|
70
|
+
|
|
71
|
+
packageName = 'nsnet2-20ms-baseline'
|
|
72
|
+
} else if (nsnet2Options.model === 'baseline-48khz') {
|
|
73
|
+
processingSampleRate = 48000
|
|
74
|
+
|
|
75
|
+
packageName = 'nsnet2-20ms-48k-baseline'
|
|
76
|
+
} else {
|
|
77
|
+
throw new Error(`Unknown model name: ${nsnet2Options.model}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!nsnet2Options.modelDirectoryPath) {
|
|
81
|
+
nsnet2Options.modelDirectoryPath = await loadPackage(packageName)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
logger.start(`Resample audio to ${processingSampleRate} Hz`)
|
|
85
|
+
const inputRawAudioResampled = await resampleAudioSpeex(inputRawAudio, processingSampleRate, 0)
|
|
86
|
+
|
|
87
|
+
const denoisedAudioChannels: Float32Array[] = []
|
|
88
|
+
|
|
89
|
+
for (let channelIndex = 0; channelIndex < inputRawAudioResampled.audioChannels.length; channelIndex++) {
|
|
90
|
+
const audioChannel = inputRawAudioResampled.audioChannels[channelIndex]
|
|
91
|
+
|
|
92
|
+
const audioChannelRawAudio: RawAudio = { audioChannels: [audioChannel], sampleRate: processingSampleRate }
|
|
93
|
+
|
|
94
|
+
logger.end()
|
|
95
|
+
|
|
96
|
+
logger.logTitledMessage(`Denoise audio channel`, `${channelIndex}`, chalk.magentaBright)
|
|
97
|
+
|
|
98
|
+
const { denoisedAudio } = await NSNet2.denoiseAudio(audioChannelRawAudio, nsnet2Options)
|
|
99
|
+
|
|
100
|
+
logger.end()
|
|
101
|
+
|
|
102
|
+
denoisedAudioChannels.push(denoisedAudio.audioChannels[0])
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
denoisedAudio = { audioChannels: denoisedAudioChannels, sampleRate: processingSampleRate }
|
|
106
|
+
|
|
107
|
+
break
|
|
108
|
+
}
|
|
109
|
+
|
|
49
110
|
default: {
|
|
50
|
-
throw new Error(`
|
|
111
|
+
throw new Error(`Engine '${options.engine}' is not recognized.`)
|
|
51
112
|
}
|
|
52
113
|
}
|
|
53
114
|
|
|
115
|
+
logger.logTitledMessage(`Postprocess`, ``, chalk.magentaBright)
|
|
116
|
+
|
|
117
|
+
logger.start(`Resample denoised audio (${denoisedAudio.sampleRate} Hz) back to original sample rate (${inputRawAudio.sampleRate} Hz)`)
|
|
118
|
+
|
|
119
|
+
denoisedAudio = await ensureRawAudio(denoisedAudio, inputRawAudio.sampleRate, inputRawAudio.audioChannels.length)
|
|
120
|
+
|
|
54
121
|
logger.start('Postprocess audio')
|
|
55
122
|
|
|
56
123
|
const shouldNormalize = options.postProcessing!.normalizeAudio!
|
|
@@ -58,9 +125,11 @@ export async function denoise(input: AudioSourceParam, options: DenoisingOptions
|
|
|
58
125
|
const maxGainIncreaseDecibels = options.postProcessing!.maxGainIncrease!
|
|
59
126
|
const dryMixGainDecibels = options.postProcessing!.dryMixGain!
|
|
60
127
|
|
|
128
|
+
attenuateIfClippingInPlace(denoisedAudio)
|
|
129
|
+
|
|
61
130
|
const preMixPeakDecibels = getSamplePeakDecibels(denoisedAudio.audioChannels)
|
|
62
|
-
|
|
63
|
-
denoisedAudio = mixAudio(denoisedAudio,
|
|
131
|
+
const inputRawAudioWithGain = applyGainDecibels(inputRawAudio, dryMixGainDecibels)
|
|
132
|
+
denoisedAudio = mixAudio(denoisedAudio, inputRawAudioWithGain)
|
|
64
133
|
const postMixPeakDecibels = getSamplePeakDecibels(denoisedAudio.audioChannels)
|
|
65
134
|
|
|
66
135
|
if (shouldNormalize) {
|
|
@@ -85,10 +154,11 @@ export interface DenoisingResult {
|
|
|
85
154
|
inputRawAudio: RawAudio
|
|
86
155
|
}
|
|
87
156
|
|
|
88
|
-
export type
|
|
157
|
+
export type DenoisingEngine = 'rnnoise' | 'nsnet2'
|
|
89
158
|
|
|
90
159
|
export interface DenoisingOptions {
|
|
91
|
-
|
|
160
|
+
engine?: DenoisingEngine,
|
|
161
|
+
|
|
92
162
|
postProcessing?: {
|
|
93
163
|
normalizeAudio: boolean
|
|
94
164
|
targetPeak: number
|
|
@@ -96,17 +166,21 @@ export interface DenoisingOptions {
|
|
|
96
166
|
|
|
97
167
|
dryMixGain?: number
|
|
98
168
|
}
|
|
169
|
+
|
|
170
|
+
nsnet2?: NSNet2Options
|
|
99
171
|
}
|
|
100
172
|
|
|
101
173
|
export const defaultDenoisingOptions: DenoisingOptions = {
|
|
102
|
-
|
|
174
|
+
engine: 'rnnoise',
|
|
103
175
|
|
|
104
176
|
postProcessing: {
|
|
105
177
|
normalizeAudio: false,
|
|
106
178
|
targetPeak: -3,
|
|
107
179
|
maxGainIncrease: 30,
|
|
108
|
-
dryMixGain: -
|
|
109
|
-
}
|
|
180
|
+
dryMixGain: -100,
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
nsnet2: defaultNSNet2Options,
|
|
110
184
|
}
|
|
111
185
|
|
|
112
186
|
export const denoisingEngines: EngineMetadata[] = [
|
|
@@ -115,5 +189,11 @@ export const denoisingEngines: EngineMetadata[] = [
|
|
|
115
189
|
name: 'RNNoise',
|
|
116
190
|
description: 'A noise suppression library based on a recurrent neural network.',
|
|
117
191
|
type: 'local'
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
id: 'nsnet2',
|
|
195
|
+
name: 'Noise Suppression Net 2',
|
|
196
|
+
description: 'Noise suppression models used as baselines for the ICASSP 2021 Deep Noise Suppression challenge.',
|
|
197
|
+
type: 'local'
|
|
118
198
|
}
|
|
119
199
|
]
|
|
@@ -5,15 +5,13 @@ import { loadPackage } from '../utilities/PackageManager.js';
|
|
|
5
5
|
import { EngineMetadata } from './Common.js';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { readdir } from '../utilities/FileSystem.js';
|
|
8
|
-
import path from 'node:path';
|
|
9
8
|
import { defaultMDXNetOptions, getProfileForMDXNetModelName, MDXNetOptions } from '../source-separation/MDXNetSourceSeparation.js';
|
|
9
|
+
import { joinPath } from '../utilities/PathUtilities.js';
|
|
10
10
|
|
|
11
11
|
export async function isolate(input: AudioSourceParam, options: SourceSeparationOptions): Promise<SourceSeparationResult> {
|
|
12
12
|
const logger = new Logger()
|
|
13
13
|
const startTimestamp = logger.getTimestamp()
|
|
14
14
|
|
|
15
|
-
await logger.startAsync('Prepare for source separation')
|
|
16
|
-
|
|
17
15
|
const inputRawAudio = await ensureRawAudio(input)
|
|
18
16
|
|
|
19
17
|
let isolatedRawAudio: RawAudio
|
|
@@ -34,22 +32,27 @@ export async function isolate(input: AudioSourceParam, options: SourceSeparation
|
|
|
34
32
|
throw new Error(`Couldn't find an ONNX model file in package directory`)
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
const modelPath =
|
|
35
|
+
const modelPath = joinPath(packageDir, modelFilename)
|
|
38
36
|
|
|
39
37
|
await logger.startAsync(`Convert audio to 44.1 kHz stereo`)
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
let inputRawAudioAs44100Stereo: RawAudio | undefined = await ensureRawAudio(inputRawAudio, 44100, 2)
|
|
42
40
|
|
|
43
41
|
logger.end()
|
|
44
42
|
|
|
45
43
|
const modelProfile = getProfileForMDXNetModelName(mdxNetOptions.model!)
|
|
46
44
|
|
|
47
|
-
isolatedRawAudio = await MDXNetSourceSeparation.isolate(
|
|
48
|
-
|
|
45
|
+
isolatedRawAudio = await MDXNetSourceSeparation.isolate(inputRawAudioAs44100Stereo, modelPath, modelProfile, mdxNetOptions)
|
|
49
46
|
logger.end()
|
|
50
47
|
|
|
48
|
+
// Release memory for the converted input audio since it's not needed anymore
|
|
49
|
+
inputRawAudioAs44100Stereo = undefined
|
|
50
|
+
|
|
51
|
+
await logger.startAsync(`Convert isolated audio to back original sample rate (${inputRawAudio.sampleRate} Hz) and channel count (${inputRawAudio.audioChannels.length})`)
|
|
52
|
+
isolatedRawAudio = await ensureRawAudio(isolatedRawAudio, inputRawAudio.sampleRate, inputRawAudio.audioChannels.length)
|
|
53
|
+
|
|
51
54
|
await logger.startAsync(`Subtract from original waveform to extract background audio`)
|
|
52
|
-
backgroundRawAudio = subtractAudio(
|
|
55
|
+
backgroundRawAudio = subtractAudio(inputRawAudio, isolatedRawAudio)
|
|
53
56
|
|
|
54
57
|
break
|
|
55
58
|
}
|
|
@@ -5,7 +5,6 @@ import { Logger } from '../utilities/Logger.js'
|
|
|
5
5
|
|
|
6
6
|
import * as API from './API.js'
|
|
7
7
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
8
|
-
import path from 'path'
|
|
9
8
|
import { type WhisperLanguageDetectionOptions } from '../recognition/WhisperSTT.js'
|
|
10
9
|
import { formatLanguageCodeWithName, languageCodeToName } from '../utilities/Locale.js'
|
|
11
10
|
import { loadPackage } from '../utilities/PackageManager.js'
|
|
@@ -14,6 +13,7 @@ import { type WhisperCppOptions } from '../recognition/WhisperCppSTT.js'
|
|
|
14
13
|
import { type SileroLanguageDetectionOptions } from '../speech-language-detection/SileroLanguageDetection.js'
|
|
15
14
|
import { OnnxExecutionProvider } from '../utilities/OnnxUtilities.js'
|
|
16
15
|
import { LanguageDetectionResults } from './LanguageDetectionCommon.js'
|
|
16
|
+
import { joinPath } from '../utilities/PathUtilities.js'
|
|
17
17
|
|
|
18
18
|
const log = logToStderr
|
|
19
19
|
|
|
@@ -55,9 +55,9 @@ export async function detectSpeechLanguage(input: AudioSourceParam, options: Spe
|
|
|
55
55
|
|
|
56
56
|
const modelDir = await loadPackage('silero-lang-classifier-95')
|
|
57
57
|
|
|
58
|
-
const modelPath =
|
|
59
|
-
const languageDictionaryPath =
|
|
60
|
-
const languageGroupDictionaryPath =
|
|
58
|
+
const modelPath = joinPath(modelDir, 'lang_classifier_95.onnx')
|
|
59
|
+
const languageDictionaryPath = joinPath(modelDir, 'lang_dict_95.json')
|
|
60
|
+
const languageGroupDictionaryPath = joinPath(modelDir, 'lang_group_dict_95.json')
|
|
61
61
|
const onnxExecutionProviders: OnnxExecutionProvider[] = sileroOptions.provider ? [sileroOptions.provider] : []
|
|
62
62
|
|
|
63
63
|
const languageResults = await SileroLanguageDetection.detectLanguage(
|
package/src/api/Synthesis.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
|
|
3
1
|
import { deepClone, extendDeep } from '../utilities/ObjectUtilities.js'
|
|
4
2
|
|
|
5
3
|
import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
|
|
@@ -27,6 +25,8 @@ import { type ElevenlabsTTSOptions } from '../synthesis/ElevenlabsTTS.js'
|
|
|
27
25
|
import { OnnxExecutionProvider } from '../utilities/OnnxUtilities.js'
|
|
28
26
|
import { simplifyPunctuationCharacters } from '../nlp/TextNormalizer.js'
|
|
29
27
|
import { convertHtmlToText } from '../utilities/StringUtilities.js'
|
|
28
|
+
import { joinPath, resolvePath } from '../utilities/PathUtilities.js'
|
|
29
|
+
import { Timer } from '../utilities/Timer.js'
|
|
30
30
|
|
|
31
31
|
const log = logToStderr
|
|
32
32
|
|
|
@@ -55,6 +55,8 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
|
|
|
55
55
|
const logger = new Logger()
|
|
56
56
|
options = extendDeep(defaultSynthesisOptions, options)
|
|
57
57
|
|
|
58
|
+
const synthesisStartTime = Timer.currentTime
|
|
59
|
+
|
|
58
60
|
if (!options.language && !options.voice) {
|
|
59
61
|
logger.start('No language or voice specified. Detect language')
|
|
60
62
|
|
|
@@ -261,7 +263,7 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
|
|
|
261
263
|
async function convertToTargetCodecIfNeeded(rawAudio: RawAudio) {
|
|
262
264
|
const targetCodec = options.outputAudioFormat?.codec
|
|
263
265
|
|
|
264
|
-
let output: RawAudio |
|
|
266
|
+
let output: RawAudio | Uint8Array
|
|
265
267
|
|
|
266
268
|
if (targetCodec) {
|
|
267
269
|
logger.start(`Convert to ${targetCodec} codec`)
|
|
@@ -283,6 +285,8 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
|
|
|
283
285
|
|
|
284
286
|
logger.end()
|
|
285
287
|
|
|
288
|
+
logger.logDuration('Total synthesis time', synthesisStartTime, chalk.magentaBright)
|
|
289
|
+
|
|
286
290
|
return {
|
|
287
291
|
audio: resultAudio,
|
|
288
292
|
timeline,
|
|
@@ -292,7 +296,7 @@ async function synthesizeSegments(segments: string[], options: SynthesisOptions,
|
|
|
292
296
|
}
|
|
293
297
|
|
|
294
298
|
export interface SynthesisResult {
|
|
295
|
-
audio: RawAudio |
|
|
299
|
+
audio: RawAudio | Uint8Array
|
|
296
300
|
timeline: Timeline
|
|
297
301
|
language: string
|
|
298
302
|
voice: string
|
|
@@ -427,8 +431,8 @@ async function synthesizeSegment(text: string, options: SynthesisOptions) {
|
|
|
427
431
|
|
|
428
432
|
const { textAnalysisFilename, signalGenerationFilename } = SvoxPicoTTS.getResourceFilenamesForLanguage(language)
|
|
429
433
|
|
|
430
|
-
const resourceFilePath =
|
|
431
|
-
const signalGenerationFilePath =
|
|
434
|
+
const resourceFilePath = resolvePath(voicePackagePath!, textAnalysisFilename)
|
|
435
|
+
const signalGenerationFilePath = resolvePath(voicePackagePath!, signalGenerationFilename)
|
|
432
436
|
|
|
433
437
|
const { rawAudio } = await SvoxPicoTTS.synthesize(preparedText, resourceFilePath, signalGenerationFilePath)
|
|
434
438
|
|
|
@@ -955,7 +959,7 @@ async function synthesizeSegment(text: string, options: SynthesisOptions) {
|
|
|
955
959
|
|
|
956
960
|
logger.end()
|
|
957
961
|
|
|
958
|
-
logger.logDuration('
|
|
962
|
+
logger.logDuration('Segment synthesis time', startTimestamp, chalk.magentaBright)
|
|
959
963
|
|
|
960
964
|
return { synthesizedAudio, timeline }
|
|
961
965
|
}
|
|
@@ -1273,11 +1277,11 @@ export async function requestVoiceList(options: VoiceListRequestOptions): Promis
|
|
|
1273
1277
|
|
|
1274
1278
|
if (!cacheDir) {
|
|
1275
1279
|
const appDataDir = getAppDataDir(appName)
|
|
1276
|
-
cacheDir =
|
|
1280
|
+
cacheDir = joinPath(appDataDir, 'voice-list-cache')
|
|
1277
1281
|
await ensureDir(cacheDir)
|
|
1278
1282
|
}
|
|
1279
1283
|
|
|
1280
|
-
const cacheFilePath =
|
|
1284
|
+
const cacheFilePath = joinPath(cacheDir, `${options.engine}.voices.json`)
|
|
1281
1285
|
|
|
1282
1286
|
async function loadVoiceList() {
|
|
1283
1287
|
let voiceList: SynthesisVoice[] = []
|
|
@@ -1544,7 +1548,7 @@ export async function requestVoiceList(options: VoiceListRequestOptions): Promis
|
|
|
1544
1548
|
|
|
1545
1549
|
|
|
1546
1550
|
if (cacheFilePath) {
|
|
1547
|
-
await writeFileSafe(cacheFilePath, stringifyAndFormatJson(voiceList))
|
|
1551
|
+
await writeFileSafe(cacheFilePath, await stringifyAndFormatJson(voiceList))
|
|
1548
1552
|
}
|
|
1549
1553
|
|
|
1550
1554
|
return voiceList
|
|
@@ -1671,7 +1675,7 @@ export const defaultVoiceListRequestOptions: VoiceListRequestOptions = {
|
|
|
1671
1675
|
export interface SynthesisSegmentEventData {
|
|
1672
1676
|
index: number
|
|
1673
1677
|
total: number
|
|
1674
|
-
audio: RawAudio |
|
|
1678
|
+
audio: RawAudio | Uint8Array
|
|
1675
1679
|
timeline: Timeline
|
|
1676
1680
|
transcript: string
|
|
1677
1681
|
language: string
|
|
@@ -5,13 +5,13 @@ import { AudioSourceParam, RawAudio, cropToTimeline, ensureRawAudio, } from '../
|
|
|
5
5
|
import { Logger } from '../utilities/Logger.js'
|
|
6
6
|
|
|
7
7
|
import { Timeline } from '../utilities/Timeline.js'
|
|
8
|
-
import path from 'path'
|
|
9
8
|
import { loadPackage } from '../utilities/PackageManager.js'
|
|
10
9
|
import { EngineMetadata } from './Common.js'
|
|
11
10
|
import chalk from 'chalk'
|
|
12
11
|
import { type AdaptiveGateVADOptions } from '../voice-activity-detection/AdaptiveGateVAD.js'
|
|
13
12
|
import { type WhisperVADOptions } from '../recognition/WhisperSTT.js'
|
|
14
13
|
import { OnnxExecutionProvider } from '../utilities/OnnxUtilities.js'
|
|
14
|
+
import { joinPath } from '../utilities/PathUtilities.js'
|
|
15
15
|
|
|
16
16
|
const log = logToStderr
|
|
17
17
|
|
|
@@ -54,7 +54,7 @@ export async function detectVoiceActivity(input: AudioSourceParam, options: VADO
|
|
|
54
54
|
|
|
55
55
|
const modelDir = await loadPackage('silero-vad')
|
|
56
56
|
|
|
57
|
-
const modelPath =
|
|
57
|
+
const modelPath = joinPath(modelDir, 'silero-vad.onnx')
|
|
58
58
|
const frameDuration = sileroOptions.frameDuration!
|
|
59
59
|
|
|
60
60
|
const onnxExecutionProviders: OnnxExecutionProvider[] = sileroOptions.provider ? [sileroOptions.provider] : []
|