echogarden 2.5.2 → 2.7.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/data/lexicons/heteronyms.en.json +39 -5
- package/data/lexicons/words.en.json +1336 -1470
- package/dist/api/SourceSeparation.js +1 -1
- package/dist/audio/AudioBufferConversion.d.ts +5 -6
- package/dist/audio/AudioBufferConversion.js +16 -248
- package/dist/audio/AudioBufferConversion.js.map +1 -1
- package/dist/audio/AudioPlayer.js.map +1 -1
- package/dist/audio/AudioRecorder.js +1 -1
- package/dist/audio/AudioRecorder.js.map +1 -1
- package/dist/audio/AudioUtilities.d.ts +3 -9
- package/dist/audio/AudioUtilities.js +4 -3
- package/dist/audio/AudioUtilities.js.map +1 -1
- package/dist/codecs/FFMpegTranscoder.d.ts +1 -4
- package/dist/codecs/TIMITCodec.js +1 -2
- package/dist/codecs/TIMITCodec.js.map +1 -1
- package/dist/encodings/Ascii.js +1 -1
- package/dist/encodings/Ascii.js.map +1 -1
- package/dist/encodings/Utf16.js +1 -1
- package/dist/encodings/Utf16.js.map +1 -1
- package/dist/encodings/Utf8.js +1 -1
- package/dist/encodings/Utf8.js.map +1 -1
- package/dist/math/VectorMath.js +8 -7
- package/dist/math/VectorMath.js.map +1 -1
- package/dist/nlp/CompromiseNLP.js +4 -1
- package/dist/nlp/CompromiseNLP.js.map +1 -1
- package/dist/nlp/Lexicon.d.ts +1 -1
- package/dist/nlp/Lexicon.js +4 -1
- package/dist/nlp/Lexicon.js.map +1 -1
- package/dist/nlp/PhoneConversion.js +17 -5
- package/dist/nlp/PhoneConversion.js.map +1 -1
- package/dist/recognition/WhisperCppSTT.js +6 -3
- package/dist/recognition/WhisperCppSTT.js.map +1 -1
- package/dist/recognition/WhisperSTT.js +18 -17
- package/dist/recognition/WhisperSTT.js.map +1 -1
- package/dist/synthesis/AwsPollyTTS.d.ts +1 -4
- package/dist/synthesis/CoquiServerTTS.d.ts +1 -4
- package/dist/synthesis/DeepgramTTS.d.ts +1 -4
- package/dist/synthesis/ElevenLabsTTS.d.ts +1 -4
- package/dist/synthesis/FliteTTS.d.ts +1 -4
- package/dist/synthesis/GnuSpeechTTS.d.ts +1 -7
- package/dist/synthesis/GoogleCloudTTS.d.ts +1 -4
- package/dist/synthesis/SapiTTS.js +1 -2
- package/dist/synthesis/SapiTTS.js.map +1 -1
- package/dist/synthesis/SvoxPicoTTS.js +1 -2
- package/dist/synthesis/SvoxPicoTTS.js.map +1 -1
- package/dist/utilities/PackageManager.js +4 -3
- package/dist/utilities/PackageManager.js.map +1 -1
- package/dist/utilities/StringUtilities.d.ts +2 -2
- package/dist/utilities/StringUtilities.js +7 -7
- package/dist/utilities/StringUtilities.js.map +1 -1
- package/dist/utilities/Utilities.d.ts +1 -0
- package/dist/utilities/Utilities.js +48 -0
- package/dist/utilities/Utilities.js.map +1 -1
- package/dist/utilities/WasmMemoryManager.d.ts +1 -1
- package/docs/Options.md +2 -2
- package/package.json +7 -7
- package/src/api/SourceSeparation.ts +1 -1
- package/src/audio/AudioBufferConversion.ts +17 -263
- package/src/audio/AudioPlayer.ts +1 -1
- package/src/audio/AudioRecorder.ts +1 -1
- package/src/audio/AudioUtilities.ts +5 -3
- package/src/codecs/TIMITCodec.ts +1 -2
- package/src/encodings/Ascii.ts +1 -1
- package/src/encodings/Utf16.ts +1 -1
- package/src/encodings/Utf8.ts +1 -1
- package/src/math/VectorMath.ts +9 -7
- package/src/nlp/CompromiseNLP.ts +5 -1
- package/src/nlp/Lexicon.ts +6 -2
- package/src/nlp/PhoneConversion.ts +20 -6
- package/src/recognition/WhisperCppSTT.ts +5 -3
- package/src/recognition/WhisperSTT.ts +19 -18
- package/src/synthesis/SapiTTS.ts +1 -2
- package/src/synthesis/SvoxPicoTTS.ts +1 -2
- package/src/utilities/PackageManager.ts +4 -3
- package/src/utilities/StringUtilities.ts +7 -7
- package/src/utilities/Utilities.ts +64 -0
- package/dist/codecs/WaveCodec.d.ts +0 -19
- package/dist/codecs/WaveCodec.js +0 -224
- package/dist/codecs/WaveCodec.js.map +0 -1
- package/dist/utilities/BinaryArrayConversion.d.ts +0 -14
- package/dist/utilities/BinaryArrayConversion.js +0 -92
- package/dist/utilities/BinaryArrayConversion.js.map +0 -1
- package/src/codecs/WaveCodec.ts +0 -281
- package/src/utilities/BinaryArrayConversion.ts +0 -117
|
@@ -6,8 +6,8 @@ import * as AudioBufferConversion from './AudioBufferConversion.js'
|
|
|
6
6
|
import { Timer } from '../utilities/Timer.js'
|
|
7
7
|
import { logToStderr } from '../utilities/Utilities.js'
|
|
8
8
|
import { OpenPromise } from '../utilities/OpenPromise.js'
|
|
9
|
-
import { SampleFormat } from '../codecs/WaveCodec.js'
|
|
10
9
|
import { tryResolvingSoxPath } from './SoxPath.js'
|
|
10
|
+
import { SampleFormat } from './AudioBufferConversion.js'
|
|
11
11
|
|
|
12
12
|
const log = logToStderr
|
|
13
13
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as FFMpegTranscoder from '../codecs/FFMpegTranscoder.js'
|
|
2
|
-
import { SampleFormat,
|
|
2
|
+
import { SampleFormat, BitDepth, encodeWaveFromFloat32Channels, decodeWaveToFloat32Channels } from '@echogarden/wave-codec'
|
|
3
3
|
import { resampleAudioSpeex } from '../dsp/SpeexResampler.js'
|
|
4
4
|
import { Timeline } from '../utilities/Timeline.js'
|
|
5
5
|
import { concatFloat32Arrays } from '../utilities/Utilities.js'
|
|
@@ -8,11 +8,13 @@ import { concatFloat32Arrays } from '../utilities/Utilities.js'
|
|
|
8
8
|
// Wave encoding and decoding
|
|
9
9
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
10
10
|
export function encodeRawAudioToWave(rawAudio: RawAudio, bitDepth: BitDepth = 16, sampleFormat: SampleFormat = SampleFormat.PCM, speakerPositionMask = 0) {
|
|
11
|
-
return
|
|
11
|
+
return encodeWaveFromFloat32Channels(rawAudio.audioChannels, rawAudio.sampleRate, bitDepth, sampleFormat, speakerPositionMask)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function decodeWaveToRawAudio(waveFileBuffer: Uint8Array, ignoreTruncatedChunks = true, ignoreOverflowingDataChunks = true) {
|
|
15
|
-
|
|
15
|
+
const rawAudio = decodeWaveToFloat32Channels(waveFileBuffer, ignoreTruncatedChunks, ignoreOverflowingDataChunks)
|
|
16
|
+
|
|
17
|
+
return { rawAudio }
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
package/src/codecs/TIMITCodec.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { decodeToChannels } from '../audio/AudioBufferConversion.js'
|
|
1
|
+
import { decodeToChannels, SampleFormat } from '../audio/AudioBufferConversion.js'
|
|
2
2
|
import { decodeAscii } from '../encodings/Ascii.js'
|
|
3
3
|
import { readFileAsBinary } from '../utilities/FileSystem.js'
|
|
4
|
-
import { SampleFormat } from './WaveCodec.js'
|
|
5
4
|
|
|
6
5
|
export async function decodeTimitAudioFile(filename: string) {
|
|
7
6
|
return decodeTimitAudio(await readFileAsBinary(filename))
|
package/src/encodings/Ascii.ts
CHANGED
|
@@ -49,7 +49,7 @@ export class ChunkedAsciiDecoder {
|
|
|
49
49
|
private readonly textDecoder = new TextDecoder('windows-1252')
|
|
50
50
|
|
|
51
51
|
writeChunk(chunk: Uint8Array) {
|
|
52
|
-
const decodedChunk = this.textDecoder.decode(chunk)
|
|
52
|
+
const decodedChunk = this.textDecoder.decode(chunk, { stream: true })
|
|
53
53
|
|
|
54
54
|
this.str += decodedChunk
|
|
55
55
|
}
|
package/src/encodings/Utf16.ts
CHANGED
|
@@ -41,7 +41,7 @@ export class ChunkedUtf16Decoder {
|
|
|
41
41
|
private readonly textDecoder = new TextDecoder('utf-16le')
|
|
42
42
|
|
|
43
43
|
writeChunk(chunk: Uint16Array) {
|
|
44
|
-
const decodedChunk = this.textDecoder.decode(chunk)
|
|
44
|
+
const decodedChunk = this.textDecoder.decode(chunk, { stream: true })
|
|
45
45
|
|
|
46
46
|
this.str += decodedChunk
|
|
47
47
|
}
|
package/src/encodings/Utf8.ts
CHANGED
|
@@ -33,7 +33,7 @@ export class ChunkedUtf8Decoder {
|
|
|
33
33
|
private readonly textDecoder = new TextDecoder('utf-8')
|
|
34
34
|
|
|
35
35
|
writeChunk(chunk: Uint8Array) {
|
|
36
|
-
const decodedChunk = this.textDecoder.decode(chunk)
|
|
36
|
+
const decodedChunk = this.textDecoder.decode(chunk, { stream: true })
|
|
37
37
|
|
|
38
38
|
this.str += decodedChunk
|
|
39
39
|
}
|
package/src/math/VectorMath.ts
CHANGED
|
@@ -727,6 +727,8 @@ export function sigmoid(x: number) {
|
|
|
727
727
|
}
|
|
728
728
|
|
|
729
729
|
export function softmax(logits: ArrayLike<number>, temperature = 1.0) {
|
|
730
|
+
temperature = Math.max(temperature, 0.00001)
|
|
731
|
+
|
|
730
732
|
const logitCount = logits.length
|
|
731
733
|
|
|
732
734
|
if (logitCount === 0) {
|
|
@@ -743,23 +745,23 @@ export function softmax(logits: ArrayLike<number>, temperature = 1.0) {
|
|
|
743
745
|
}
|
|
744
746
|
}
|
|
745
747
|
|
|
746
|
-
const temperatureReciprocal = 1 /
|
|
748
|
+
const temperatureReciprocal = 1 / temperature
|
|
747
749
|
|
|
748
750
|
const results = new Float32Array(logitCount)
|
|
749
751
|
|
|
750
|
-
let
|
|
752
|
+
let sumOfExponentiatedLogits = 0.0
|
|
751
753
|
|
|
752
754
|
for (let i = 0; i < logitCount; i++) {
|
|
753
|
-
const
|
|
755
|
+
const logit = logits[i]
|
|
754
756
|
|
|
755
|
-
const
|
|
757
|
+
const eToLogit = Math.exp((logit - maxValue) * temperatureReciprocal)
|
|
756
758
|
|
|
757
|
-
|
|
759
|
+
sumOfExponentiatedLogits += eToLogit
|
|
758
760
|
|
|
759
|
-
results[i] =
|
|
761
|
+
results[i] = eToLogit
|
|
760
762
|
}
|
|
761
763
|
|
|
762
|
-
const sumOfExponentiatedValuesReciprocal = 1 / (
|
|
764
|
+
const sumOfExponentiatedValuesReciprocal = 1 / (sumOfExponentiatedLogits + 1e-20)
|
|
763
765
|
|
|
764
766
|
for (let i = 0; i < logitCount; i++) {
|
|
765
767
|
results[i] *= sumOfExponentiatedValuesReciprocal
|
package/src/nlp/CompromiseNLP.ts
CHANGED
|
@@ -79,12 +79,16 @@ export function tryMatchInLexicon(term: CompromiseParsedTerm, lexicon: Lexicon,
|
|
|
79
79
|
const termText = term.text
|
|
80
80
|
const lowerCaseTermText = termText.toLocaleLowerCase()
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
let entry = lexiconForLanguage[lowerCaseTermText]
|
|
83
83
|
|
|
84
84
|
if (!entry) {
|
|
85
85
|
return undefined
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
if (!Array.isArray(entry)) {
|
|
89
|
+
entry = [entry]
|
|
90
|
+
}
|
|
91
|
+
|
|
88
92
|
for (const substitutionEntry of entry) {
|
|
89
93
|
if (!substitutionEntry.pos || substitutionEntry.pos.includes(term.pos)) {
|
|
90
94
|
const substitutionPhonemesText = substitutionEntry?.pronunciation?.espeak?.[espeakVoice]
|
package/src/nlp/Lexicon.ts
CHANGED
|
@@ -30,12 +30,16 @@ export function tryGetLexiconSubstitution(sentenceWords: string[], wordIndex: nu
|
|
|
30
30
|
return undefined
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
let lexiconEntry = lexiconForLanguage[word]
|
|
34
34
|
|
|
35
35
|
if (!lexiconEntry) {
|
|
36
36
|
return undefined
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
if (!Array.isArray(lexiconEntry)) {
|
|
40
|
+
lexiconEntry = [lexiconEntry]
|
|
41
|
+
}
|
|
42
|
+
|
|
39
43
|
for (let i = 0; i < lexiconEntry.length; i++) {
|
|
40
44
|
const candidateEntry = lexiconEntry[i]
|
|
41
45
|
|
|
@@ -100,7 +104,7 @@ export type Lexicon = {
|
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
export type LexiconForLanguage = {
|
|
103
|
-
[word: string]: LexiconEntry[]
|
|
107
|
+
[word: string]: LexiconEntry | LexiconEntry[]
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
export type LexiconEntry = {
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
export function ipaPhoneToKirshenbaum(ipaPhone: string) {
|
|
2
2
|
let result = ''
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
if (ipaPhone[0] === 'ˈ' || ipaPhone[0] === 'ˌ') {
|
|
5
|
+
result += ipaToKirshenbaum[ipaPhone[0]]
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
ipaPhone = ipaPhone.substring(1)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const convertedFullPhone = ipaToKirshenbaum[ipaPhone]
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
if (convertedFullPhone) {
|
|
13
|
+
result += convertedFullPhone
|
|
14
|
+
} else {
|
|
15
|
+
for (const char of ipaPhone) {
|
|
16
|
+
const convertedChar = ipaToKirshenbaum[char]
|
|
17
|
+
|
|
18
|
+
if (convertedChar === undefined) {
|
|
19
|
+
throw new Error(`Couldn't convert IPA character '${char}' (part of phone '${ipaPhone}') to the Kirshenbaum notation`)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
result += convertedChar ?? '_'
|
|
23
|
+
}
|
|
12
24
|
}
|
|
13
25
|
|
|
14
26
|
return result
|
|
@@ -252,6 +264,8 @@ const ipaToTimit: { [p: string]: string[] | undefined } = {
|
|
|
252
264
|
'ɾ': ['dx'],
|
|
253
265
|
}
|
|
254
266
|
|
|
267
|
+
// Kirshenbaum is an ASCII encoding of IPA
|
|
268
|
+
// The variant used by eSpeak is used here, and has many differences to standard Kirshenbaum
|
|
255
269
|
export const ipaToKirshenbaum: Record<string, string> = {
|
|
256
270
|
//// Vowels
|
|
257
271
|
|
|
@@ -405,7 +405,7 @@ export type WhisperCppBuild = 'cpu' | 'cublas-12.4.0' | 'custom'
|
|
|
405
405
|
|
|
406
406
|
export async function loadExecutablePackage(buildKind: WhisperCppBuild) {
|
|
407
407
|
if (buildKind === 'custom') {
|
|
408
|
-
throw new Error(`A 'custom' build kind requires providing a custom path to the whisper
|
|
408
|
+
throw new Error(`A 'custom' build kind requires providing a custom path to the 'whisper-cli' executable in the 'executablePath' option.`)
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
const platform = process.platform
|
|
@@ -416,8 +416,10 @@ export async function loadExecutablePackage(buildKind: WhisperCppBuild) {
|
|
|
416
416
|
if (buildKind.startsWith('cublas-')) {
|
|
417
417
|
if (platform === 'win32' && arch === 'x64') {
|
|
418
418
|
packageName = `whisper.cpp-binaries-windows-x64-${buildKind}-latest`
|
|
419
|
+
} else if (platform === 'linux' && arch === 'x64') {
|
|
420
|
+
packageName = `whisper.cpp-binaries-linux-x64-${buildKind}-latest`
|
|
419
421
|
} else {
|
|
420
|
-
throw new Error(`whisper.cpp GPU builds (NVIDIA CUDA only) are currently only available as packages for Windows x64. Please specify a custom path to a whisper.cpp 'main' binary in the 'executablePath' option.`)
|
|
422
|
+
throw new Error(`whisper.cpp GPU builds (NVIDIA CUDA only) are currently only available as packages for Windows x64 and Linux x64. Please specify a custom path to a whisper.cpp 'main' binary in the 'executablePath' option.`)
|
|
421
423
|
}
|
|
422
424
|
} else if (buildKind === 'cpu') {
|
|
423
425
|
if (platform === 'win32' && arch === 'x64') {
|
|
@@ -433,7 +435,7 @@ export async function loadExecutablePackage(buildKind: WhisperCppBuild) {
|
|
|
433
435
|
|
|
434
436
|
const packagePath = await loadPackage(packageName)
|
|
435
437
|
|
|
436
|
-
let filename = 'main'
|
|
438
|
+
let filename = 'whisper-cli' // used to be called 'main' but 'main' is now deprecated
|
|
437
439
|
|
|
438
440
|
if (platform === 'win32') {
|
|
439
441
|
filename += '.exe'
|
|
@@ -2,8 +2,8 @@ import type * as Onnx from 'onnxruntime-node'
|
|
|
2
2
|
|
|
3
3
|
import { Logger } from '../utilities/Logger.js'
|
|
4
4
|
import { computeMelSpectogramUsingFilterbanks, Filterbank } from '../dsp/MelSpectogram.js'
|
|
5
|
-
import { clip,
|
|
6
|
-
import { indexOfMax, logOfVector, logSumExp, meanOfVector, softmax,
|
|
5
|
+
import { clip, getIntegerRange, getTopKIndexes, splitFloat32Array, yieldToEventLoop } from '../utilities/Utilities.js'
|
|
6
|
+
import { indexOfMax, logOfVector, logSumExp, meanOfVector, softmax, sumOfSquaresForVector, sumVector } from '../math/VectorMath.js'
|
|
7
7
|
|
|
8
8
|
import { alignDTWWindowed } from '../alignment/DTWSequenceAlignmentWindowed.js'
|
|
9
9
|
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
@@ -1019,36 +1019,37 @@ export class Whisper {
|
|
|
1019
1019
|
}
|
|
1020
1020
|
|
|
1021
1021
|
// Find top candidates
|
|
1022
|
-
const
|
|
1023
|
-
Array.from(nonTimestampTokenLogits).map((logit, index) => ({ token: index, logit }))
|
|
1022
|
+
const sortedTopCandidateTokens = getTopKIndexes(nonTimestampTokenLogits, options.topCandidateCount!, true)
|
|
1024
1023
|
|
|
1025
|
-
|
|
1024
|
+
let topCandidates = Array.from(sortedTopCandidateTokens).map(token => {
|
|
1025
|
+
const logit = nonTimestampTokenLogits[token]
|
|
1026
1026
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1027
|
+
return {
|
|
1028
|
+
token,
|
|
1029
|
+
logit,
|
|
1030
|
+
text: this.tokenToText(token, true)
|
|
1031
|
+
}
|
|
1032
|
+
})
|
|
1033
1033
|
|
|
1034
1034
|
// Apply repetition suppression if enabled
|
|
1035
1035
|
if (options.suppressRepetition) {
|
|
1036
|
-
// Using some hardcoded constants, for now
|
|
1036
|
+
// Using some hardcoded constants, for now:
|
|
1037
1037
|
const tokenWindowSize = 30
|
|
1038
1038
|
const thresholdMatchLength = 4
|
|
1039
|
-
const
|
|
1039
|
+
const thresholdCycleRepetitionCount = 3
|
|
1040
1040
|
|
|
1041
1041
|
const filteredCandidates: typeof topCandidates = []
|
|
1042
1042
|
|
|
1043
1043
|
for (const candidate of topCandidates) {
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1044
|
+
const decodedTextTokens = decodedTokens.filter(token => this.isTextToken(token))
|
|
1045
|
+
|
|
1046
|
+
const lastDecodedTextTokens = decodedTextTokens
|
|
1047
|
+
.slice(Math.max(decodedTextTokens.length - tokenWindowSize, 0))
|
|
1046
1048
|
.reverse()
|
|
1047
|
-
.slice(0, tokenWindowSize)
|
|
1048
1049
|
|
|
1049
|
-
const {
|
|
1050
|
+
const { longestMatchLength, longestCycleRepetitionCount } = getTokenRepetitionScore([candidate.token, ...lastDecodedTextTokens])
|
|
1050
1051
|
|
|
1051
|
-
if (
|
|
1052
|
+
if (longestMatchLength >= thresholdMatchLength || longestCycleRepetitionCount >= thresholdCycleRepetitionCount) {
|
|
1052
1053
|
continue
|
|
1053
1054
|
}
|
|
1054
1055
|
|
package/src/synthesis/SapiTTS.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { SynthesisVoice } from '../api/API.js'
|
|
2
|
-
import { decodeToChannels } from '../audio/AudioBufferConversion.js'
|
|
2
|
+
import { decodeToChannels, SampleFormat } from '../audio/AudioBufferConversion.js'
|
|
3
3
|
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
4
|
-
import { SampleFormat } from '../codecs/WaveCodec.js'
|
|
5
4
|
import { getShortLanguageCode, lcidToIsoLanguageCode } from '../utilities/Locale.js'
|
|
6
5
|
import { Logger } from '../utilities/Logger.js'
|
|
7
6
|
import { Timeline, TimelineEntry } from '../utilities/Timeline.js'
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SynthesisVoice } from '../api/API.js'
|
|
2
|
-
import { decodeToChannels } from '../audio/AudioBufferConversion.js'
|
|
3
|
-
import { SampleFormat } from '../codecs/WaveCodec.js'
|
|
2
|
+
import { decodeToChannels, SampleFormat } from '../audio/AudioBufferConversion.js'
|
|
4
3
|
import { bandwidthToQFactor } from '../dsp/BiquadFilter.js'
|
|
5
4
|
import { Logger } from '../utilities/Logger.js'
|
|
6
5
|
import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js'
|
|
@@ -197,9 +197,10 @@ const packageVersionTagResolutionLookup: { [packageName: string]: string } = {
|
|
|
197
197
|
'whisper.cpp-large-v3-turbo-q5_0': '20241003',
|
|
198
198
|
|
|
199
199
|
// whisper.cpp binaries
|
|
200
|
-
'whisper.cpp-binaries-
|
|
201
|
-
'whisper.cpp-binaries-windows-x64-
|
|
202
|
-
'whisper.cpp-binaries-
|
|
200
|
+
'whisper.cpp-binaries-windows-x64-cpu-latest': '20250502',
|
|
201
|
+
'whisper.cpp-binaries-windows-x64-cublas-12.4.0-latest': '20250502',
|
|
202
|
+
'whisper.cpp-binaries-linux-x64-cpu-latest': '20250502',
|
|
203
|
+
'whisper.cpp-binaries-linux-x64-cublas-12.4.0-latest': '20250502',
|
|
203
204
|
|
|
204
205
|
// E5 models
|
|
205
206
|
'xenova-multilingual-e5-small-q8': '20240504',
|
|
@@ -148,24 +148,24 @@ export function getTokenRepetitionScore(tokens: string[] | number[]) {
|
|
|
148
148
|
matchLengthForCycleLength.push(score)
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
let
|
|
152
|
-
let
|
|
151
|
+
let longestMatchLength = -Infinity
|
|
152
|
+
let longestCycleRepetitionCount = -Infinity
|
|
153
153
|
|
|
154
154
|
for (let i = 1; i <= matchLengthForCycleLength.length; i++) {
|
|
155
155
|
const matchLength = matchLengthForCycleLength[i]
|
|
156
156
|
|
|
157
|
-
if (matchLength >
|
|
158
|
-
|
|
157
|
+
if (matchLength > longestMatchLength) {
|
|
158
|
+
longestMatchLength = matchLength
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
const cycleCount = (matchLength / i) + 1
|
|
162
162
|
|
|
163
|
-
if (cycleCount >
|
|
164
|
-
|
|
163
|
+
if (cycleCount > longestCycleRepetitionCount) {
|
|
164
|
+
longestCycleRepetitionCount = cycleCount
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
return {
|
|
168
|
+
return { longestMatchLength, longestCycleRepetitionCount }
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
export async function convertHtmlToText(html: string) {
|
|
@@ -511,3 +511,67 @@ export function encodeHTMLAngleBrackets(text: string) {
|
|
|
511
511
|
.replaceAll('>', '>')
|
|
512
512
|
.replaceAll('&', '&')
|
|
513
513
|
}
|
|
514
|
+
|
|
515
|
+
export function getTopKIndexes(values: ArrayLike<number>, topCount: number, sort = true) {
|
|
516
|
+
if (topCount < 1) {
|
|
517
|
+
throw new Error(`Top count must be at least 1`)
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const topKIndexes = new Uint32Array(Math.min(topCount, values.length))
|
|
521
|
+
|
|
522
|
+
// Initialize top k indexes with the first k elements
|
|
523
|
+
// (or less, if value list is shorter)
|
|
524
|
+
for (let i = 0; i < topKIndexes.length; i++) {
|
|
525
|
+
topKIndexes[i] = i
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Return if value list is shorter or equal in length to topCount
|
|
529
|
+
if (values.length <= topCount) {
|
|
530
|
+
return topKIndexes
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
////
|
|
534
|
+
|
|
535
|
+
let positionOfMinimum = -1
|
|
536
|
+
let valueOfMinimum = -Infinity
|
|
537
|
+
|
|
538
|
+
// Method to scan the top-k array and update the latest minimum value position and value
|
|
539
|
+
function updateMinimum() {
|
|
540
|
+
positionOfMinimum = 0
|
|
541
|
+
valueOfMinimum = values[topKIndexes[0]]
|
|
542
|
+
|
|
543
|
+
for (let i = 1; i < topKIndexes.length; i++) {
|
|
544
|
+
const value = values[topKIndexes[i]]
|
|
545
|
+
|
|
546
|
+
if (value < valueOfMinimum) {
|
|
547
|
+
positionOfMinimum = i
|
|
548
|
+
valueOfMinimum = value
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
updateMinimum()
|
|
554
|
+
|
|
555
|
+
// Add remaining elements to the list, if needed
|
|
556
|
+
for (let insertedElementIndex = topCount; insertedElementIndex < values.length; insertedElementIndex++) {
|
|
557
|
+
const insertedElementValue = values[insertedElementIndex]
|
|
558
|
+
|
|
559
|
+
// If the inserted element's value is lesser or equal to the value
|
|
560
|
+
// of the smallest value on the list, skip it
|
|
561
|
+
if (insertedElementValue <= valueOfMinimum) {
|
|
562
|
+
continue
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Replace the minimum element with the inserted element
|
|
566
|
+
topKIndexes[positionOfMinimum] = insertedElementIndex
|
|
567
|
+
|
|
568
|
+
// Update the position and value of the minimum element
|
|
569
|
+
updateMinimum()
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (sort) {
|
|
573
|
+
topKIndexes.sort((a, b) => values[b] - values[a])
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return topKIndexes
|
|
577
|
+
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { RawAudio } from '../audio/AudioUtilities.js';
|
|
2
|
-
export declare function encodeWave(rawAudio: RawAudio, bitDepth?: BitDepth, sampleFormat?: SampleFormat, speakerPositionMask?: number): Uint8Array<ArrayBufferLike>;
|
|
3
|
-
export declare function decodeWave(waveData: Uint8Array, ignoreTruncatedChunks?: boolean, ignoreOverflowingDataChunks?: boolean): {
|
|
4
|
-
rawAudio: {
|
|
5
|
-
audioChannels: Float32Array<ArrayBufferLike>[];
|
|
6
|
-
sampleRate: number;
|
|
7
|
-
};
|
|
8
|
-
sourceSampleFormat: SampleFormat;
|
|
9
|
-
sourceBitDepth: BitDepth;
|
|
10
|
-
sourceSpeakerPositionMask: number;
|
|
11
|
-
};
|
|
12
|
-
export declare function repairWave(waveData: Uint8Array): Uint8Array<ArrayBufferLike>;
|
|
13
|
-
export declare enum SampleFormat {
|
|
14
|
-
PCM = 1,
|
|
15
|
-
Float = 3,
|
|
16
|
-
Alaw = 6,
|
|
17
|
-
Mulaw = 7
|
|
18
|
-
}
|
|
19
|
-
export type BitDepth = 8 | 16 | 24 | 32 | 64;
|