echogarden 1.8.7 → 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 +135 -49
- 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 -6
- 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 +1 -47
- 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 -16
- package/dist/utilities/FileSystem.js +170 -109
- 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 -5
- package/dist/utilities/Utilities.js +69 -33
- 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 -4
- 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 +155 -53
- 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 -8
- package/src/synthesis/VitsTTS.ts +2 -2
- package/src/tests/Test.ts +1 -60
- 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 +213 -120
- 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 +79 -45
- package/src/utilities/VirtualFileReadStream.ts +5 -5
- package/src/utilities/WasmMemoryManager.ts +20 -6
- 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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { EncodeIntoResult } from "./TextEncodingsCommon.js"
|
|
2
|
+
|
|
3
|
+
export function encodeUtf32(text: string) {
|
|
4
|
+
const resultArray = new Uint32Array(text.length * 2)
|
|
5
|
+
|
|
6
|
+
const { written } = encodeUtf32Into(text, resultArray)
|
|
7
|
+
|
|
8
|
+
return resultArray.subarray(0, written)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function encodeUtf32Into(text: string, resultBuffer: Uint32Array): EncodeIntoResult {
|
|
12
|
+
const len = text.length
|
|
13
|
+
|
|
14
|
+
let readOffset = 0
|
|
15
|
+
let writeOffset = 0
|
|
16
|
+
|
|
17
|
+
while (readOffset < len && writeOffset < resultBuffer.length) {
|
|
18
|
+
const codepoint = text.codePointAt(readOffset)
|
|
19
|
+
|
|
20
|
+
if (codepoint === undefined) {
|
|
21
|
+
throw new Error(`Couldn't read a codepoint at offset ${readOffset}`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
resultBuffer[writeOffset++] = codepoint
|
|
25
|
+
|
|
26
|
+
if (codepoint > 0xffff) {
|
|
27
|
+
readOffset += 2
|
|
28
|
+
} else {
|
|
29
|
+
readOffset += 1
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return { read: readOffset, written: writeOffset }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function decodeUtf32(encodedString: Uint32Array) {
|
|
37
|
+
const maxChunkLength = 2 ** 10
|
|
38
|
+
|
|
39
|
+
const decoder = new ChunkedUtf32Decoder()
|
|
40
|
+
|
|
41
|
+
for (let offset = 0; offset < encodedString.length; offset += maxChunkLength) {
|
|
42
|
+
const chunk = encodedString.subarray(offset, offset + maxChunkLength)
|
|
43
|
+
|
|
44
|
+
decoder.writeChunk(chunk)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return decoder.toString()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class ChunkedUtf32Decoder {
|
|
51
|
+
private str = ''
|
|
52
|
+
|
|
53
|
+
writeChunk(chunk: Uint32Array) {
|
|
54
|
+
const decodedChunk = String.fromCodePoint(...chunk)
|
|
55
|
+
|
|
56
|
+
this.str += decodedChunk
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
toString() {
|
|
60
|
+
return this.str
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { EncodeIntoResult } from "./TextEncodingsCommon.js"
|
|
2
|
+
|
|
3
|
+
export function encodeUtf8(text: string) {
|
|
4
|
+
const textEncoder = new TextEncoder()
|
|
5
|
+
|
|
6
|
+
return textEncoder.encode(text)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function encodeUtf8Into(text: string, outputArray: Uint8Array): EncodeIntoResult {
|
|
10
|
+
const textEncoder = new TextEncoder()
|
|
11
|
+
|
|
12
|
+
const result = textEncoder.encodeInto(text, outputArray)
|
|
13
|
+
|
|
14
|
+
return result
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function decodeUtf8(encodedString: Uint8Array) {
|
|
18
|
+
const maxChunkLength = 2 ** 24
|
|
19
|
+
|
|
20
|
+
const decoder = new ChunkedUtf8Decoder()
|
|
21
|
+
|
|
22
|
+
for (let offset = 0; offset < encodedString.length; offset += maxChunkLength) {
|
|
23
|
+
const chunk = encodedString.subarray(offset, offset + maxChunkLength)
|
|
24
|
+
|
|
25
|
+
decoder.writeChunk(chunk)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return decoder.toString()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class ChunkedUtf8Decoder {
|
|
32
|
+
private str = ''
|
|
33
|
+
private readonly textDecoder = new TextDecoder('utf-8')
|
|
34
|
+
|
|
35
|
+
writeChunk(chunk: Uint8Array) {
|
|
36
|
+
const decodedChunk = this.textDecoder.decode(chunk)
|
|
37
|
+
|
|
38
|
+
this.str += decodedChunk
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
toString() {
|
|
42
|
+
return this.str
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
47
|
+
// Pure JavaScript implementations
|
|
48
|
+
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
49
|
+
function encodeUtf8Into_JS(str: string, outputArray: Uint8Array): EncodeIntoResult {
|
|
50
|
+
let readOffset = 0
|
|
51
|
+
let writeOffset = 0
|
|
52
|
+
|
|
53
|
+
while (readOffset < str.length) {
|
|
54
|
+
const charCode = str.codePointAt(readOffset++)!
|
|
55
|
+
|
|
56
|
+
if (charCode <= 0x7f) {
|
|
57
|
+
outputArray[writeOffset++] = charCode
|
|
58
|
+
} else if (charCode <= 0x7ff) {
|
|
59
|
+
outputArray[writeOffset++] = 0xc0 | (charCode >>> 6)
|
|
60
|
+
outputArray[writeOffset++] = 0x80 | (charCode & 63)
|
|
61
|
+
} else if (charCode <= 0xffff) {
|
|
62
|
+
outputArray[writeOffset++] = 0xe0 | (charCode >>> 12)
|
|
63
|
+
outputArray[writeOffset++] = 0x80 | ((charCode >>> 6) & 63)
|
|
64
|
+
outputArray[writeOffset++] = 0x80 | (charCode & 63)
|
|
65
|
+
} else if (charCode <= 0x10ffff) {
|
|
66
|
+
outputArray[writeOffset++] = 0xf0 | (charCode >>> 18)
|
|
67
|
+
outputArray[writeOffset++] = 0x80 | ((charCode >>> 12) & 63)
|
|
68
|
+
outputArray[writeOffset++] = 0x80 | ((charCode >>> 6) & 63)
|
|
69
|
+
outputArray[writeOffset++] = 0x80 | (charCode & 63)
|
|
70
|
+
|
|
71
|
+
readOffset++
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { read: str.length, written: writeOffset }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function decodeUtf8_JS(utf8Bytes: Uint8Array): string {
|
|
79
|
+
let decodedString = ''
|
|
80
|
+
|
|
81
|
+
let readOffset = 0
|
|
82
|
+
|
|
83
|
+
while (readOffset < utf8Bytes.length) {
|
|
84
|
+
const leadByte = utf8Bytes[readOffset++]
|
|
85
|
+
|
|
86
|
+
let outputCodePoint: number
|
|
87
|
+
|
|
88
|
+
if (leadByte >>> 7 === 0) {
|
|
89
|
+
outputCodePoint = leadByte
|
|
90
|
+
} else if (leadByte >>> 5 === 6) {
|
|
91
|
+
outputCodePoint =
|
|
92
|
+
(leadByte & 31) << 6 |
|
|
93
|
+
(utf8Bytes[readOffset++] & 63)
|
|
94
|
+
} else if (leadByte >>> 4 === 14) {
|
|
95
|
+
outputCodePoint =
|
|
96
|
+
(leadByte & 15) << 12 |
|
|
97
|
+
(utf8Bytes[readOffset++] & 63) << 6 |
|
|
98
|
+
(utf8Bytes[readOffset++] & 63)
|
|
99
|
+
} else if (leadByte >>> 3 === 30) {
|
|
100
|
+
outputCodePoint =
|
|
101
|
+
(leadByte & 7) << 18 |
|
|
102
|
+
(utf8Bytes[readOffset++] & 63) << 12 |
|
|
103
|
+
(utf8Bytes[readOffset++] & 63) << 6 |
|
|
104
|
+
(utf8Bytes[readOffset++] & 63)
|
|
105
|
+
} else {
|
|
106
|
+
throw new Error(`Invalid UTF-8 stream: An invalid lead byte value encountered at position ${readOffset}`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
decodedString += String.fromCodePoint(outputCodePoint)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (readOffset > utf8Bytes.length) {
|
|
113
|
+
throw new Error(`UTF-8 decoding failed. Byte sequence is truncated.`)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return decodedString
|
|
117
|
+
}
|
package/src/math/MedianFilter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
1
|
import { OpenPromise } from '../utilities/OpenPromise.js'
|
|
2
|
+
import { getDirName, joinPath } from '../utilities/PathUtilities.js'
|
|
3
3
|
import { resolveModuleScriptPath } from '../utilities/Utilities.js'
|
|
4
4
|
|
|
5
5
|
export async function splitJapaneseTextToWords_Kuromoji(text: string) {
|
|
@@ -23,7 +23,7 @@ async function getKuromojiTokenizer() {
|
|
|
23
23
|
const resultOpenPromise = new OpenPromise<any>()
|
|
24
24
|
|
|
25
25
|
const kuromojiScriptPath = await resolveModuleScriptPath('kuromoji')
|
|
26
|
-
const dictionaryPath =
|
|
26
|
+
const dictionaryPath = joinPath(getDirName(kuromojiScriptPath), '..', '/dict')
|
|
27
27
|
|
|
28
28
|
kuromoji.builder({ dicPath: dictionaryPath }).build(function (error: any, tokenizer: any) {
|
|
29
29
|
if (error) {
|
|
@@ -4,6 +4,7 @@ import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
|
|
|
4
4
|
import { Logger } from '../utilities/Logger.js'
|
|
5
5
|
import { Timeline } from '../utilities/Timeline.js'
|
|
6
6
|
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
7
|
+
import { encodeBase64 } from '../encodings/Base64.js'
|
|
7
8
|
|
|
8
9
|
export type AudioEncoding = 'LINEAR16' | 'FLAC' | 'MULAW' | 'AMR' | 'AMR' | 'AMR_WB' | 'OGG_OPUS' | 'SPEEX_WITH_HEADER_BYTE' | 'MP3' | 'WEBM_OPUS'
|
|
9
10
|
|
|
@@ -30,7 +31,7 @@ export async function recognize(rawAudio: RawAudio, apiKey: string, languageCode
|
|
|
30
31
|
},
|
|
31
32
|
|
|
32
33
|
audio: {
|
|
33
|
-
content: flac16Khz16bitMonoAudio
|
|
34
|
+
content: encodeBase64(flac16Khz16bitMonoAudio)
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -5,10 +5,10 @@ import { logToStderr } from '../utilities/Utilities.js'
|
|
|
5
5
|
import { Timeline } from '../utilities/Timeline.js'
|
|
6
6
|
import { RawAudio, getRawAudioDuration } from '../audio/AudioUtilities.js'
|
|
7
7
|
import { readAndParseJsonFile } from '../utilities/FileSystem.js'
|
|
8
|
-
import path from 'path'
|
|
9
8
|
|
|
10
9
|
import type * as Onnx from 'onnxruntime-node'
|
|
11
10
|
import { OnnxExecutionProvider, getOnnxSessionOptions } from '../utilities/OnnxUtilities.js'
|
|
11
|
+
import { joinPath } from '../utilities/PathUtilities.js'
|
|
12
12
|
|
|
13
13
|
const log = logToStderr
|
|
14
14
|
|
|
@@ -87,8 +87,8 @@ export class SileroSTT {
|
|
|
87
87
|
|
|
88
88
|
const Onnx = await import('onnxruntime-node')
|
|
89
89
|
|
|
90
|
-
const modelPath =
|
|
91
|
-
const labelsPath =
|
|
90
|
+
const modelPath = joinPath(this.modelDirectoryPath, 'model.onnx')
|
|
91
|
+
const labelsPath = joinPath(this.modelDirectoryPath, 'labels.json')
|
|
92
92
|
|
|
93
93
|
this.labels = await readAndParseJsonFile(labelsPath)
|
|
94
94
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
|
|
2
2
|
import * as AudioBufferConversion from '../audio/AudioBufferConversion.js'
|
|
3
3
|
import { Logger } from '../utilities/Logger.js'
|
|
4
|
-
import {
|
|
4
|
+
import { concatUint8Arrays, logToStderr } from '../utilities/Utilities.js'
|
|
5
5
|
import { Timeline } from '../utilities/Timeline.js'
|
|
6
6
|
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
7
7
|
|
|
@@ -36,8 +36,8 @@ export async function recognize(rawAudio: RawAudio, modelPath: string, verbose =
|
|
|
36
36
|
const recognitionStartTimestamp = logger.getTimestamp()
|
|
37
37
|
|
|
38
38
|
const pcmAudio = AudioBufferConversion.encodeToAudioBuffer(audioChannels, 16)
|
|
39
|
-
const trailingSilence =
|
|
40
|
-
const pcmAudioWithTrailingSilence =
|
|
39
|
+
const trailingSilence = new Uint8Array(sampleRate * 4)
|
|
40
|
+
const pcmAudioWithTrailingSilence = concatUint8Arrays([pcmAudio, trailingSilence])
|
|
41
41
|
const pcmAudioByteCount = pcmAudioWithTrailingSilence.length
|
|
42
42
|
|
|
43
43
|
const maxChunkSize = sampleRate * 2.0
|
|
@@ -5,9 +5,8 @@ import { type WhisperTask, type WhisperModelName } from './WhisperSTT.js'
|
|
|
5
5
|
import { getRandomHexString } from '../utilities/Utilities.js'
|
|
6
6
|
import { Timeline, TimelineEntryType } from '../utilities/Timeline.js'
|
|
7
7
|
import { tryParseTimeRangePatternWithHours } from '../subtitles/Subtitles.js'
|
|
8
|
-
import { getAppTempDir } from '../utilities/PathUtilities.js'
|
|
8
|
+
import { getAppTempDir, joinPath } from '../utilities/PathUtilities.js'
|
|
9
9
|
import { appName } from '../api/Common.js'
|
|
10
|
-
import path from 'node:path'
|
|
11
10
|
import { readAndParseJsonFile, remove } from '../utilities/FileSystem.js'
|
|
12
11
|
import { splitToLines } from '../nlp/Segmentation.js'
|
|
13
12
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
@@ -78,7 +77,7 @@ export async function recognize(
|
|
|
78
77
|
const sourceAsWave = encodeRawAudioToWave(sourceRawAudio)
|
|
79
78
|
|
|
80
79
|
const tempDirPath = getAppTempDir(appName)
|
|
81
|
-
const outJsonFilePathWithoutExtension =
|
|
80
|
+
const outJsonFilePathWithoutExtension = joinPath(tempDirPath, `${getRandomHexString(16)}`)
|
|
82
81
|
const outJsonFilePath = `${outJsonFilePathWithoutExtension}.json`
|
|
83
82
|
|
|
84
83
|
const args: string[] = [
|
|
@@ -396,7 +395,7 @@ export async function loadModelPackage(modelId: WhisperCppModelId | undefined, l
|
|
|
396
395
|
|
|
397
396
|
const packageName = `whisper.cpp-${modelId}`
|
|
398
397
|
const modelDir = await loadPackage(packageName)
|
|
399
|
-
const modelPath =
|
|
398
|
+
const modelPath = joinPath(modelDir, `ggml-${modelId}.bin`)
|
|
400
399
|
const modelName = getModelNameFromModelId(modelId)
|
|
401
400
|
|
|
402
401
|
return { modelName, modelPath }
|
|
@@ -440,7 +439,7 @@ export async function loadExecutablePackage(buildKind: WhisperCppBuild) {
|
|
|
440
439
|
filename += '.exe'
|
|
441
440
|
}
|
|
442
441
|
|
|
443
|
-
return
|
|
442
|
+
return joinPath(packagePath, filename)
|
|
444
443
|
}
|
|
445
444
|
|
|
446
445
|
function getModelNameFromModelId(modelId: WhisperCppModelId): WhisperModelName {
|
|
@@ -10,8 +10,7 @@ import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
|
10
10
|
import { Timeline, TimelineEntry } from '../utilities/Timeline.js'
|
|
11
11
|
import { AlignmentPath } from '../alignment/SpeechAlignment.js'
|
|
12
12
|
import { getRawAudioDuration, RawAudio, sliceRawAudio } from '../audio/AudioUtilities.js'
|
|
13
|
-
import {
|
|
14
|
-
import path from 'path'
|
|
13
|
+
import { readFileAsUtf8 } from '../utilities/FileSystem.js'
|
|
15
14
|
import type { LanguageDetectionResults } from '../api/API.js'
|
|
16
15
|
import { formatLanguageCodeWithName, getShortLanguageCode, languageCodeToName } from '../utilities/Locale.js'
|
|
17
16
|
import { loadPackage } from '../utilities/PackageManager.js'
|
|
@@ -25,6 +24,8 @@ import { getDeflateCompressionMetricsForString } from '../utilities/Compression.
|
|
|
25
24
|
import { dmlProviderAvailable, getOnnxSessionOptions, makeOnnxLikeFloat32Tensor, OnnxExecutionProvider, OnnxLikeFloat32Tensor } from '../utilities/OnnxUtilities.js'
|
|
26
25
|
import { murmurHash3_int32Input } from '../utilities/Hashing.js'
|
|
27
26
|
import { containsInvalidCodepoint, getTokenRepetitionScore } from '../utilities/StringUtilities.js'
|
|
27
|
+
import { decodeUtf8 } from '../encodings/Utf8.js'
|
|
28
|
+
import { joinPath } from '../utilities/PathUtilities.js'
|
|
28
29
|
|
|
29
30
|
export async function recognize(
|
|
30
31
|
sourceRawAudio: RawAudio,
|
|
@@ -1538,8 +1539,8 @@ export class Whisper {
|
|
|
1538
1539
|
|
|
1539
1540
|
const tiktokenModulePackagePath = await loadPackage('whisper-tiktoken-data')
|
|
1540
1541
|
|
|
1541
|
-
const tiktokenDataFilePath =
|
|
1542
|
-
let tiktokenData = await
|
|
1542
|
+
const tiktokenDataFilePath = joinPath(tiktokenModulePackagePath, this.isMultiligualModel ? 'multilingual.tiktoken' : 'gpt2.tiktoken')
|
|
1543
|
+
let tiktokenData = await readFileAsUtf8(tiktokenDataFilePath)
|
|
1543
1544
|
|
|
1544
1545
|
const tokenConfig = this.tokenConfig
|
|
1545
1546
|
|
|
@@ -1603,7 +1604,7 @@ export class Whisper {
|
|
|
1603
1604
|
|
|
1604
1605
|
await logger.startAsync(`Create encoder inference session for model '${this.modelName}' (ONNX provider: ${onnxProvidersString})`)
|
|
1605
1606
|
|
|
1606
|
-
const encoderFilePath =
|
|
1607
|
+
const encoderFilePath = joinPath(this.modelDir, 'encoder.onnx')
|
|
1607
1608
|
|
|
1608
1609
|
const Onnx = await import('onnxruntime-node')
|
|
1609
1610
|
|
|
@@ -1625,7 +1626,7 @@ export class Whisper {
|
|
|
1625
1626
|
|
|
1626
1627
|
await logger.startAsync(`Create decoder inference session for model '${this.modelName}' (ONNX provider: ${onnxProvidersString})`)
|
|
1627
1628
|
|
|
1628
|
-
const decoderFilePath =
|
|
1629
|
+
const decoderFilePath = joinPath(this.modelDir, 'decoder.onnx')
|
|
1629
1630
|
|
|
1630
1631
|
const Onnx = await import('onnxruntime-node')
|
|
1631
1632
|
|
|
@@ -1689,7 +1690,7 @@ export class Whisper {
|
|
|
1689
1690
|
}
|
|
1690
1691
|
|
|
1691
1692
|
try {
|
|
1692
|
-
return
|
|
1693
|
+
return decodeUtf8(this.tiktoken!.decode(new Uint32Array(tokens)))
|
|
1693
1694
|
} catch {
|
|
1694
1695
|
return '[TOKENIZER_FAILED]'
|
|
1695
1696
|
}
|
package/src/server/Client.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { SpeechTranslationOptions, SpeechTranslationResult } from '../api/Speech
|
|
|
11
11
|
import { Worker as WorkerThread } from 'node:worker_threads'
|
|
12
12
|
import { SpeechLanguageDetectionOptions, SpeechLanguageDetectionResult } from '../api/SpeechLanguageDetection.js'
|
|
13
13
|
import { TextLanguageDetectionOptions, TextLanguageDetectionResult } from '../api/TextLanguageDetection.js'
|
|
14
|
+
import { decodeUtf8 } from '../encodings/Utf8.js'
|
|
14
15
|
|
|
15
16
|
const log = logToStderr
|
|
16
17
|
|
|
@@ -23,14 +24,14 @@ export class Client {
|
|
|
23
24
|
if (sourceChannel instanceof WebSocket) {
|
|
24
25
|
sourceChannel.on('message', (messageData, isBinary) => {
|
|
25
26
|
if (!isBinary) {
|
|
26
|
-
log(`Received an unexpected string WebSocket message: '${(messageData as
|
|
27
|
+
log(`Received an unexpected string WebSocket message: '${decodeUtf8(messageData as Uint8Array)}'`)
|
|
27
28
|
return
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
let incomingMessage: any
|
|
31
32
|
|
|
32
33
|
try {
|
|
33
|
-
incomingMessage = decodeMsgPack(messageData as
|
|
34
|
+
incomingMessage = decodeMsgPack(messageData as Uint8Array)
|
|
34
35
|
} catch (e) {
|
|
35
36
|
log(`Failed to decode incoming message. Reason: ${e}`)
|
|
36
37
|
return
|
|
@@ -176,7 +177,7 @@ export class Client {
|
|
|
176
177
|
return requestOpenPromise.promise
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
async translateSpeech(input: string |
|
|
180
|
+
async translateSpeech(input: string | Uint8Array | RawAudio, options: SpeechTranslationOptions): Promise<SpeechTranslationResult> {
|
|
180
181
|
const requestOpenPromise = new OpenPromise<SpeechTranslationResult>()
|
|
181
182
|
|
|
182
183
|
const requestMessage: SpeechTranslationRequestMessage = {
|
package/src/server/Server.ts
CHANGED
|
@@ -2,13 +2,14 @@ import { WebSocketServer, WebSocket, ServerOptions as WsServerOptions } from 'ws
|
|
|
2
2
|
import { encode as encodeMsgPack, decode as decodeMsgPack } from 'msgpack-lite'
|
|
3
3
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
4
4
|
import { OpenPromise } from '../utilities/OpenPromise.js'
|
|
5
|
-
import {
|
|
5
|
+
import { existsSync, readFileAsBinary } from '../utilities/FileSystem.js'
|
|
6
6
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
7
7
|
import { sendMessageToWorker, addListenerToWorkerMessages, startNewWorkerThread, startMessageChannel } from './Worker.js'
|
|
8
8
|
import { Worker } from 'node:worker_threads'
|
|
9
9
|
import { IncomingMessage, ServerResponse } from 'node:http'
|
|
10
10
|
import chalk from 'chalk'
|
|
11
11
|
import { Logger } from '../utilities/Logger.js'
|
|
12
|
+
import { decodeUtf8 } from '../encodings/Utf8.js'
|
|
12
13
|
|
|
13
14
|
const log = logToStderr
|
|
14
15
|
|
|
@@ -37,8 +38,8 @@ export async function startServer(serverOptions: ServerOptions, onStarted: (opti
|
|
|
37
38
|
const { createServer } = await import('https')
|
|
38
39
|
|
|
39
40
|
const httpsServer = createServer({
|
|
40
|
-
cert: await
|
|
41
|
-
key: await
|
|
41
|
+
cert: Buffer.from(await readFileAsBinary(serverOptions.certPath!)),
|
|
42
|
+
key: Buffer.from(await readFileAsBinary(serverOptions.keyPath!))
|
|
42
43
|
}, onHttpRequest)
|
|
43
44
|
|
|
44
45
|
httpsServer.listen(serverOptions.port!)
|
|
@@ -107,14 +108,14 @@ export async function startServer(serverOptions: ServerOptions, onStarted: (opti
|
|
|
107
108
|
|
|
108
109
|
ws.on('message', (messageData, isBinary) => {
|
|
109
110
|
if (!isBinary) {
|
|
110
|
-
log(chalk.gray(`Received an unexpected string WebSocket message: '${(messageData as
|
|
111
|
+
log(chalk.gray(`Received an unexpected string WebSocket message: '${decodeUtf8(messageData as Uint8Array)}'`))
|
|
111
112
|
return
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
let incomingMessage: any
|
|
115
116
|
|
|
116
117
|
try {
|
|
117
|
-
incomingMessage = decodeMsgPack(messageData as
|
|
118
|
+
incomingMessage = decodeMsgPack(messageData as Uint8Array)
|
|
118
119
|
} catch (e) {
|
|
119
120
|
log(chalk.gray(`Failed to decode binary WebSocket message. Reason: ${e}`))
|
|
120
121
|
return
|
package/src/server/Worker.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestVoiceListResult, SynthesisOptions, SynthesisSegmentEventData, SynthesisResult, VoiceListRequestOptions, requestVoiceList, synthesize } from '../api/Synthesis.js'
|
|
2
|
-
import { Queue } from '../
|
|
2
|
+
import { Queue } from '../data-structures/Queue.js'
|
|
3
3
|
import { logToStderr, yieldToEventLoop } from '../utilities/Utilities.js'
|
|
4
4
|
import { AudioSourceParam } from '../audio/AudioUtilities.js'
|
|
5
5
|
import { RecognitionOptions, RecognitionResult, recognize } from '../api/Recognition.js'
|
|
@@ -5,7 +5,7 @@ import { logToStderr } from '../utilities/Utilities.js'
|
|
|
5
5
|
import { Logger } from '../utilities/Logger.js'
|
|
6
6
|
import { OnnxExecutionProvider, dmlProviderAvailable, getOnnxSessionOptions } from '../utilities/OnnxUtilities.js'
|
|
7
7
|
import chalk from 'chalk'
|
|
8
|
-
import { WindowedList } from '../
|
|
8
|
+
import { WindowedList } from '../data-structures/WindowedList.js'
|
|
9
9
|
import { logLevelGreaterOrEqualTo } from '../api/API.js'
|
|
10
10
|
|
|
11
11
|
const log = logToStderr
|
|
@@ -1,28 +1,57 @@
|
|
|
1
1
|
import { DtwGranularity, getMfccOptionsForGranularity } from "../alignment/SpeechAlignment.js";
|
|
2
2
|
import { RawAudio } from "../audio/AudioUtilities.js";
|
|
3
3
|
import { computeMFCCs, extendDefaultMfccOptions, MfccOptions } from "../dsp/MFCC.js";
|
|
4
|
+
import { euclideanDistance13Dim } from "../math/VectorMath.js";
|
|
4
5
|
import { Logger } from "../utilities/Logger.js";
|
|
5
6
|
|
|
6
|
-
export async function searchSpeech(sourceRawAudio: RawAudio,
|
|
7
|
+
export async function searchSpeech(sourceRawAudio: RawAudio, queryRawAudio: RawAudio) {
|
|
7
8
|
const logger = new Logger()
|
|
8
9
|
|
|
9
10
|
const granularity: DtwGranularity = 'low'
|
|
10
11
|
|
|
11
12
|
const mfccOptions = extendDefaultMfccOptions({ ...getMfccOptionsForGranularity(granularity), zeroFirstCoefficient: true }) as MfccOptions
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const referenceMfccs = await computeMFCCs(referenceRawAudio, mfccOptions)
|
|
14
|
+
logger.start('Compute query MFCC features')
|
|
15
|
+
const queryMfccs = await computeMFCCs(queryRawAudio, mfccOptions)
|
|
16
16
|
|
|
17
|
-
// Compute source MFCCs
|
|
18
17
|
logger.start('Compute source MFCC features')
|
|
19
18
|
const sourceMfccs = await computeMFCCs(sourceRawAudio, mfccOptions)
|
|
20
19
|
|
|
21
20
|
logger.start('Compute cost matrix')
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
const costMatrixColumns = computeCostMatrix(sourceMfccs, queryMfccs, euclideanDistance13Dim)
|
|
23
|
+
|
|
24
|
+
logger.start('Search')
|
|
25
|
+
|
|
26
|
+
const rowCount = sourceMfccs.length
|
|
27
|
+
const columnCount = queryMfccs.length
|
|
28
|
+
|
|
29
|
+
const maxSearchWindow = columnCount * 2
|
|
30
|
+
|
|
31
|
+
for (let rowStartOffset = 0; rowStartOffset < rowCount; rowStartOffset++) {
|
|
32
|
+
const rowEndOffset = Math.min(rowStartOffset + maxSearchWindow, rowCount)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
}
|
|
24
36
|
}
|
|
25
37
|
|
|
26
|
-
function computeCostMatrix<T, U>(sequence1: T[], sequence2: U[]) {
|
|
38
|
+
function computeCostMatrix<T, U>(sequence1: T[], sequence2: U[], costFunction: (a: T, b: U) => number) {
|
|
39
|
+
const rowCount = sequence1.length
|
|
40
|
+
const columnCount = sequence2.length
|
|
41
|
+
|
|
42
|
+
const costMatrixColumns: Float32Array[] = []
|
|
43
|
+
|
|
44
|
+
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
45
|
+
const column = new Float32Array(rowCount)
|
|
46
|
+
|
|
47
|
+
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
|
|
48
|
+
const cost = costFunction(sequence1[rowIndex], sequence2[columnIndex])
|
|
49
|
+
|
|
50
|
+
column[columnIndex] = cost
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
costMatrixColumns.push(column)
|
|
54
|
+
}
|
|
27
55
|
|
|
56
|
+
return costMatrixColumns
|
|
28
57
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { htmlToText } from 'html-to-text'
|
|
2
2
|
|
|
3
3
|
import { secondsToHMS, secondsToMS } from '../utilities/Utilities.js'
|
|
4
|
-
import {
|
|
4
|
+
import { isWordOrSymbolWord } from '../nlp/Segmentation.js'
|
|
5
5
|
import { charactersToWriteAhead } from '../audio/AudioPlayer.js'
|
|
6
6
|
import { Timeline, TimelineEntry } from '../utilities/Timeline.js'
|
|
7
|
-
import {
|
|
7
|
+
import { readFileAsUtf8 } from '../utilities/FileSystem.js'
|
|
8
8
|
import { deepClone } from '../utilities/ObjectUtilities.js'
|
|
9
9
|
import { formatHMS, formatMS, startsWithAnyOf } from '../utilities/StringUtilities.js'
|
|
10
10
|
|
|
11
11
|
export async function subtitlesFileToText(filename: string) {
|
|
12
|
-
return subtitlesToText(await
|
|
12
|
+
return subtitlesToText(await readFileAsUtf8(filename))
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function subtitlesToText(subtitles: string) {
|
|
@@ -7,6 +7,7 @@ import { escape } from 'html-escaper'
|
|
|
7
7
|
import { Logger } from '../utilities/Logger.js'
|
|
8
8
|
import { Timeline } from '../utilities/Timeline.js'
|
|
9
9
|
import { RawAudio, getRawAudioDuration } from '../audio/AudioUtilities.js'
|
|
10
|
+
import { concatUint8Arrays } from '../utilities/Utilities.js'
|
|
10
11
|
|
|
11
12
|
export async function synthesize(
|
|
12
13
|
text: string,
|
|
@@ -46,27 +47,29 @@ export async function synthesize(
|
|
|
46
47
|
return
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
const bufferSize = 2 ** 16
|
|
51
|
-
const buffers: Buffer[] = []
|
|
50
|
+
let encodedAudio: Uint8Array
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
if (false) {
|
|
53
|
+
const bufferSize = 2 ** 16
|
|
54
|
+
const buffers: Uint8Array[] = []
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
const amountRead = await audioOutputStream.read(buffer)
|
|
56
|
+
while (true) {
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
audioOutputStream.
|
|
60
|
-
break
|
|
61
|
-
}
|
|
58
|
+
const buffer = new Uint8Array(bufferSize)
|
|
59
|
+
const amountRead = await audioOutputStream.read(buffer)
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
if (amountRead == 0) {
|
|
62
|
+
audioOutputStream.close()
|
|
63
|
+
break
|
|
64
|
+
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
buffers.push(buffer.subarray(0, amountRead))
|
|
67
|
+
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
encodedAudio = concatUint8Arrays(buffers)
|
|
70
|
+
} else {
|
|
71
|
+
encodedAudio = new Uint8Array(result.audioData)
|
|
72
|
+
}
|
|
70
73
|
|
|
71
74
|
logger.end()
|
|
72
75
|
|
|
@@ -8,7 +8,7 @@ export async function synthesize(text: string, speakerId: string | null, serverU
|
|
|
8
8
|
const logger = new Logger()
|
|
9
9
|
logger.start('Request synthesis from Coqui Server')
|
|
10
10
|
|
|
11
|
-
const response = await request<
|
|
11
|
+
const response = await request<Uint8Array>({
|
|
12
12
|
url: `${serverURL}/api/tts`,
|
|
13
13
|
|
|
14
14
|
params: {
|
|
@@ -19,7 +19,7 @@ export async function synthesize(text: string, speakerId: string | null, serverU
|
|
|
19
19
|
responseType: 'arraybuffer'
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
-
const waveData =
|
|
22
|
+
const waveData = new Uint8Array(response.data)
|
|
23
23
|
|
|
24
24
|
const { rawAudio } = decodeWaveToRawAudio(waveData)
|
|
25
25
|
|
|
@@ -57,7 +57,7 @@ export async function synthesize(text: string, voiceId: string, modelId: string,
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
logger.start('Decode synthesized audio')
|
|
60
|
-
const rawAudio = await FFMpegTranscoder.decodeToChannels(
|
|
60
|
+
const rawAudio = await FFMpegTranscoder.decodeToChannels(new Uint8Array(response.data))
|
|
61
61
|
|
|
62
62
|
logger.end()
|
|
63
63
|
|
|
@@ -3,7 +3,6 @@ import { int16PcmToFloat32 } from '../audio/AudioBufferConversion.js'
|
|
|
3
3
|
import { Logger } from '../utilities/Logger.js'
|
|
4
4
|
import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js'
|
|
5
5
|
import { RawAudio, getEmptyRawAudio } from '../audio/AudioUtilities.js'
|
|
6
|
-
import { playAudioWithTimelinePhones } from '../audio/AudioPlayer.js'
|
|
7
6
|
import { getNormalizedFragmentsForSpeech, simplifyPunctuationCharacters } from '../nlp/TextNormalizer.js'
|
|
8
7
|
import { ipaPhoneToKirshenbaum } from '../nlp/PhoneConversion.js'
|
|
9
8
|
import { splitToWords, wordCharacterPattern } from '../nlp/Segmentation.js'
|
|
@@ -599,20 +598,6 @@ export const defaultEspeakOptions: EspeakOptions = {
|
|
|
599
598
|
insertSeparators: false
|
|
600
599
|
}
|
|
601
600
|
|
|
602
|
-
export async function testEspeakSynthesisWithPrePhonemizedInputs(text: string) {
|
|
603
|
-
const ipaPhonemizedSentence = (await phonemizeSentence(text, 'en-us')).flatMap(clause => clause)
|
|
604
|
-
const kirshenbaumPhonemizedSentence = (await phonemizeSentence(text, 'en-us', undefined, false)).flatMap(clause => clause)
|
|
605
|
-
log(kirshenbaumPhonemizedSentence)
|
|
606
|
-
|
|
607
|
-
const fragments = ipaPhonemizedSentence.map(word =>
|
|
608
|
-
word.map(phoneme =>
|
|
609
|
-
ipaPhoneToKirshenbaum(phoneme)).join('')).map(word => ` [[${word}]] `)
|
|
610
|
-
|
|
611
|
-
const { rawAudio, timeline } = await synthesizeFragments(fragments, defaultEspeakOptions)
|
|
612
|
-
|
|
613
|
-
await playAudioWithTimelinePhones(rawAudio, timeline)
|
|
614
|
-
}
|
|
615
|
-
|
|
616
601
|
export async function testKirshenbaumPhonemization(text: string) {
|
|
617
602
|
const ipaPhonemizedSentence = (await phonemizeSentence(text, 'en-us')).flatMap(clause => clause)
|
|
618
603
|
const kirshenbaumPhonemizedSentence = (await phonemizeSentence(text, 'en-us', undefined, false)).flatMap(clause => clause)
|