echogarden 0.12.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -14
- package/data/schemas/options.json +398 -111
- package/dist/alignment/DTWMfccSequenceAlignment.d.ts +1 -1
- package/dist/alignment/DTWMfccSequenceAlignment.js +8 -8
- package/dist/alignment/DTWSequenceAlignment.d.ts +1 -1
- package/dist/alignment/DTWSequenceAlignment.js +1 -1
- package/dist/alignment/DTWSequenceAlignmentWindowed.d.ts +1 -1
- package/dist/alignment/DTWSequenceAlignmentWindowed.js +2 -2
- package/dist/alignment/LevenshteinSequenceAlignment.d.ts +1 -1
- package/dist/alignment/LevenshteinSequenceAlignment.js +1 -1
- package/dist/alignment/SpeechAlignment.d.ts +9 -10
- package/dist/alignment/SpeechAlignment.js +136 -105
- package/dist/alignment/SpeechAlignment.js.map +1 -1
- package/dist/api/API.d.ts +13 -12
- package/dist/api/API.js +14 -13
- package/dist/api/API.js.map +1 -1
- package/dist/api/APIOptions.d.ts +5 -4
- package/dist/api/Alignment.d.ts +15 -9
- package/dist/api/Alignment.js +88 -74
- package/dist/api/Alignment.js.map +1 -1
- package/dist/api/Common.js +1 -1
- package/dist/api/Denoising.d.ts +6 -6
- package/dist/api/Denoising.js +23 -23
- package/dist/api/Denoising.js.map +1 -1
- package/dist/api/LanguageDetection.d.ts +19 -12
- package/dist/api/LanguageDetection.js +88 -38
- package/dist/api/LanguageDetection.js.map +1 -1
- package/dist/api/Recognition.d.ts +16 -6
- package/dist/api/Recognition.js +129 -55
- package/dist/api/Recognition.js.map +1 -1
- package/dist/api/SourceSeparation.d.ts +17 -0
- package/dist/api/SourceSeparation.js +61 -0
- package/dist/api/SourceSeparation.js.map +1 -0
- package/dist/api/Synthesis.d.ts +18 -18
- package/dist/api/Synthesis.js +191 -164
- package/dist/api/Synthesis.js.map +1 -1
- package/dist/api/Translation.d.ts +19 -8
- package/dist/api/Translation.js +132 -35
- package/dist/api/Translation.js.map +1 -1
- package/dist/api/Vad.d.ts +10 -5
- package/dist/api/Vad.js +76 -38
- package/dist/api/Vad.js.map +1 -1
- package/dist/audio/AudioBufferConversion.d.ts +1 -1
- package/dist/audio/AudioBufferConversion.js +4 -4
- package/dist/audio/AudioPlayer.d.ts +1 -1
- package/dist/audio/AudioPlayer.js +26 -26
- package/dist/audio/AudioPlayer.js.map +1 -1
- package/dist/audio/AudioRecorder.d.ts +1 -1
- package/dist/audio/AudioRecorder.js +5 -5
- package/dist/audio/AudioUtilities.d.ts +13 -9
- package/dist/audio/AudioUtilities.js +86 -24
- package/dist/audio/AudioUtilities.js.map +1 -1
- package/dist/cli/CLI.d.ts +3 -3
- package/dist/cli/CLI.js +271 -162
- package/dist/cli/CLI.js.map +1 -1
- package/dist/cli/CLIConfigFile.js +8 -8
- package/dist/cli/CLILauncher.js +6 -6
- package/dist/cli/CLIOptionsSchema.js +2 -2
- package/dist/cli/CLIParser.js +5 -5
- package/dist/cli/CLIStarter.js +4 -4
- package/dist/codecs/FFMpegTranscoder.d.ts +2 -2
- package/dist/codecs/FFMpegTranscoder.js +37 -37
- package/dist/codecs/FFMpegTranscoder.js.map +1 -1
- package/dist/codecs/TIMITCodec.js +5 -5
- package/dist/codecs/WaveCodec.d.ts +1 -1
- package/dist/codecs/WaveCodec.js +22 -22
- package/dist/denoising/RNNoise.d.ts +1 -1
- package/dist/denoising/RNNoise.js +9 -9
- package/dist/dsp/BiquadFilter.d.ts +3 -2
- package/dist/dsp/BiquadFilter.js +18 -11
- package/dist/dsp/BiquadFilter.js.map +1 -1
- package/dist/dsp/DecayingPeakEstimator.d.ts +16 -0
- package/dist/dsp/DecayingPeakEstimator.js +23 -0
- package/dist/dsp/DecayingPeakEstimator.js.map +1 -0
- package/dist/dsp/FFT.d.ts +8 -4
- package/dist/dsp/FFT.js +76 -30
- package/dist/dsp/FFT.js.map +1 -1
- package/dist/dsp/KWeightingFilter.d.ts +9 -0
- package/dist/dsp/KWeightingFilter.js +40 -0
- package/dist/dsp/KWeightingFilter.js.map +1 -0
- package/dist/dsp/LoudnessEstimator.d.ts +21 -0
- package/dist/dsp/LoudnessEstimator.js +47 -0
- package/dist/dsp/LoudnessEstimator.js.map +1 -0
- package/dist/dsp/MFCC.d.ts +2 -2
- package/dist/dsp/MFCC.js +15 -15
- package/dist/dsp/MelSpectogram.d.ts +1 -1
- package/dist/dsp/MelSpectogram.js +6 -6
- package/dist/dsp/Rubberband.d.ts +11 -11
- package/dist/dsp/Rubberband.js +27 -27
- package/dist/dsp/Sonic.d.ts +1 -1
- package/dist/dsp/Sonic.js +3 -3
- package/dist/dsp/SpeexResampler.d.ts +1 -1
- package/dist/dsp/SpeexResampler.js +2 -2
- package/dist/math/VectorMath.d.ts +12 -8
- package/dist/math/VectorMath.js +35 -32
- package/dist/math/VectorMath.js.map +1 -1
- package/dist/nlp/ChineseSegmentation.js +2 -2
- package/dist/nlp/CompromiseNLP.js +3 -3
- package/dist/nlp/EspeakPhonemizer.js +30 -30
- package/dist/nlp/IPA.js +20 -20
- package/dist/nlp/JapaneseSegmentation.js +6 -6
- package/dist/nlp/Lexicon.d.ts +1 -1
- package/dist/nlp/Lexicon.js +7 -7
- package/dist/nlp/Segmentation.d.ts +3 -0
- package/dist/nlp/Segmentation.js +21 -14
- package/dist/nlp/Segmentation.js.map +1 -1
- package/dist/nlp/TextNormalizer.js +16 -16
- package/dist/recognition/AmazonTranscribeSTT.d.ts +2 -2
- package/dist/recognition/AmazonTranscribeSTT.js +13 -14
- package/dist/recognition/AmazonTranscribeSTT.js.map +1 -1
- package/dist/recognition/AzureCognitiveServicesSTT.js +5 -6
- package/dist/recognition/AzureCognitiveServicesSTT.js.map +1 -1
- package/dist/recognition/GoogleCloudSTT.d.ts +3 -3
- package/dist/recognition/GoogleCloudSTT.js +18 -18
- package/dist/recognition/OpenAICloudSTT.d.ts +19 -0
- package/dist/recognition/OpenAICloudSTT.js +81 -0
- package/dist/recognition/OpenAICloudSTT.js.map +1 -0
- package/dist/recognition/SileroSTT.d.ts +2 -2
- package/dist/recognition/SileroSTT.js +25 -25
- package/dist/recognition/VoskSTT.d.ts +2 -2
- package/dist/recognition/VoskSTT.js +8 -8
- package/dist/recognition/WhisperCppSTT.d.ts +88 -0
- package/dist/recognition/WhisperCppSTT.js +332 -0
- package/dist/recognition/WhisperCppSTT.js.map +1 -0
- package/dist/recognition/WhisperSTT.d.ts +49 -25
- package/dist/recognition/WhisperSTT.js +626 -481
- package/dist/recognition/WhisperSTT.js.map +1 -1
- package/dist/server/Client.d.ts +1 -1
- package/dist/server/Client.js +22 -22
- package/dist/server/Server.js +9 -9
- package/dist/server/Server.js.map +1 -1
- package/dist/server/Worker.d.ts +22 -22
- package/dist/server/Worker.js +36 -36
- package/dist/server/Worker.js.map +1 -1
- package/dist/server/WorkerStarter.js +2 -2
- package/dist/source-separation/MDXNetSourceSeparation.d.ts +11 -0
- package/dist/source-separation/MDXNetSourceSeparation.js +161 -0
- package/dist/source-separation/MDXNetSourceSeparation.js.map +1 -0
- package/dist/speech-language-detection/SileroLanguageDetection.d.ts +1 -1
- package/dist/speech-language-detection/SileroLanguageDetection.js +7 -7
- package/dist/subtitles/Subtitles.d.ts +10 -0
- package/dist/subtitles/Subtitles.js +2 -2
- package/dist/subtitles/Subtitles.js.map +1 -1
- package/dist/synthesis/AwsPollyTTS.d.ts +1 -1
- package/dist/synthesis/AwsPollyTTS.js +12 -12
- package/dist/synthesis/AzureCognitiveServicesTTS.js +7 -7
- package/dist/synthesis/CoquiServerTTS.js +10 -10
- package/dist/synthesis/CoquiServerTTS.js.map +1 -1
- package/dist/synthesis/ElevenlabsTTS.d.ts +23 -0
- package/dist/synthesis/ElevenlabsTTS.js +103 -0
- package/dist/synthesis/ElevenlabsTTS.js.map +1 -0
- package/dist/synthesis/EspeakTTS.d.ts +6 -5
- package/dist/synthesis/EspeakTTS.js +81 -69
- package/dist/synthesis/EspeakTTS.js.map +1 -1
- package/dist/synthesis/FliteTTS.d.ts +3 -3
- package/dist/synthesis/FliteTTS.js +154 -154
- package/dist/synthesis/FliteTTS.js.map +1 -1
- package/dist/synthesis/GoogleCloudTTS.d.ts +3 -3
- package/dist/synthesis/GoogleCloudTTS.js +17 -17
- package/dist/synthesis/GoogleCloudTTS.js.map +1 -1
- package/dist/synthesis/GoogleTranslateTTS.d.ts +1 -1
- package/dist/synthesis/GoogleTranslateTTS.js +103 -103
- package/dist/synthesis/MicrosoftEdgeTTS.d.ts +2 -2
- package/dist/synthesis/MicrosoftEdgeTTS.js +74 -74
- package/dist/synthesis/OpenAICloudTTS.d.ts +13 -0
- package/dist/synthesis/OpenAICloudTTS.js +169 -0
- package/dist/synthesis/OpenAICloudTTS.js.map +1 -0
- package/dist/synthesis/SamTTS.js +3 -3
- package/dist/synthesis/SapiTTS.d.ts +3 -3
- package/dist/synthesis/SapiTTS.js +26 -26
- package/dist/synthesis/StreamlabsPollyTTS.d.ts +2 -2
- package/dist/synthesis/StreamlabsPollyTTS.js +27 -27
- package/dist/synthesis/SvoxPicoTTS.d.ts +2 -2
- package/dist/synthesis/SvoxPicoTTS.js +65 -65
- package/dist/synthesis/SvoxPicoTTS.js.map +1 -1
- package/dist/synthesis/VitsTTS.d.ts +3 -3
- package/dist/synthesis/VitsTTS.js +378 -378
- package/dist/synthesis/VitsTTS.js.map +1 -1
- package/dist/tests/Test.js +2 -2
- package/dist/utilities/Compression.d.ts +5 -0
- package/dist/utilities/Compression.js +29 -13
- package/dist/utilities/Compression.js.map +1 -1
- package/dist/utilities/FileDownloader.d.ts +1 -1
- package/dist/utilities/FileDownloader.js +16 -16
- package/dist/utilities/FileSystem.js +7 -7
- package/dist/utilities/Locale.d.ts +7 -7
- package/dist/utilities/Locale.js +15 -15
- package/dist/utilities/Logger.js +3 -3
- package/dist/utilities/ObjectUtilities.js +19 -19
- package/dist/utilities/OpenPromise.js +2 -2
- package/dist/utilities/OpenPromise.js.map +1 -1
- package/dist/utilities/PackageManager.js +31 -0
- package/dist/utilities/PackageManager.js.map +1 -1
- package/dist/utilities/PathUtilities.js +8 -8
- package/dist/utilities/RandomGenerator.js +2 -2
- package/dist/utilities/SmoothEstimator.d.ts +8 -0
- package/dist/utilities/SmoothEstimator.js +25 -0
- package/dist/utilities/SmoothEstimator.js.map +1 -0
- package/dist/utilities/TarballMaker.js +8 -8
- package/dist/utilities/Timeline.d.ts +3 -2
- package/dist/utilities/Timeline.js +11 -11
- package/dist/utilities/Timeline.js.map +1 -1
- package/dist/utilities/Timer.js +4 -4
- package/dist/utilities/Utilities.d.ts +4 -0
- package/dist/utilities/Utilities.js +38 -15
- package/dist/utilities/Utilities.js.map +1 -1
- package/dist/utilities/WasmMemoryManager.js +7 -7
- package/dist/utilities/WebReader.js +23 -23
- package/dist/utilities/WikipediaReader.js +2 -2
- package/dist/voice-activity-detection/AdaptiveGateVAD.d.ts +28 -0
- package/dist/voice-activity-detection/AdaptiveGateVAD.js +138 -0
- package/dist/voice-activity-detection/AdaptiveGateVAD.js.map +1 -0
- package/dist/voice-activity-detection/SileroVAD.d.ts +1 -1
- package/dist/voice-activity-detection/SileroVAD.js +5 -5
- package/dist/voice-activity-detection/SileroVAD.js.map +1 -1
- package/dist/voice-activity-detection/WebRtcVAD.d.ts +1 -1
- package/dist/voice-activity-detection/WebRtcVAD.js +4 -4
- package/docs/API.md +29 -11
- package/docs/CLI.md +31 -7
- package/docs/Contributing.md +38 -0
- package/docs/Development.md +93 -19
- package/docs/Engines.md +28 -16
- package/docs/Licenses.md +4 -1
- package/docs/Options.md +158 -78
- package/docs/Releases.md +262 -0
- package/docs/Server.md +7 -7
- package/docs/Tasklist.md +95 -76
- package/docs/Technical.md +4 -4
- package/package.json +13 -14
- package/src/alignment/DTWMfccSequenceAlignment.ts +9 -9
- package/src/alignment/DTWSequenceAlignment.ts +2 -2
- package/src/alignment/DTWSequenceAlignmentWindowed.ts +3 -3
- package/src/alignment/LevenshteinSequenceAlignment.ts +2 -2
- package/src/alignment/SpeechAlignment.ts +204 -119
- package/src/api/API.ts +14 -13
- package/src/api/APIOptions.ts +12 -11
- package/src/api/Alignment.ts +147 -90
- package/src/api/Common.ts +1 -1
- package/src/api/Denoising.ts +28 -28
- package/src/api/LanguageDetection.ts +135 -48
- package/src/api/Recognition.ts +198 -59
- package/src/api/SourceSeparation.ts +99 -0
- package/src/api/Synthesis.ts +217 -181
- package/src/api/Translation.ts +193 -40
- package/src/api/Vad.ts +110 -41
- package/src/audio/AudioBufferConversion.ts +4 -4
- package/src/audio/AudioPlayer.ts +27 -27
- package/src/audio/AudioRecorder.ts +5 -5
- package/src/audio/AudioUtilities.ts +107 -24
- package/src/cli/CLI.ts +313 -164
- package/src/cli/CLIConfigFile.ts +8 -8
- package/src/cli/CLILauncher.ts +6 -6
- package/src/cli/CLIOptionsSchema.ts +2 -2
- package/src/cli/CLIParser.ts +5 -5
- package/src/cli/CLIStarter.ts +4 -4
- package/src/codecs/FFMpegTranscoder.ts +38 -38
- package/src/codecs/TIMITCodec.ts +5 -5
- package/src/codecs/WaveCodec.ts +22 -22
- package/src/denoising/RNNoise.ts +9 -9
- package/src/dsp/BiquadFilter.ts +19 -11
- package/src/dsp/DecayingPeakEstimator.ts +35 -0
- package/src/dsp/FFT.ts +103 -35
- package/src/dsp/KWeightingFilter.ts +43 -0
- package/src/dsp/LoudnessEstimator.ts +74 -0
- package/src/dsp/MFCC.ts +15 -15
- package/src/dsp/MelSpectogram.ts +7 -7
- package/src/dsp/Rubberband.ts +38 -38
- package/src/dsp/Sonic.ts +4 -4
- package/src/dsp/SpeexResampler.ts +2 -2
- package/src/math/VectorMath.ts +42 -33
- package/src/nlp/ChineseSegmentation.ts +3 -3
- package/src/nlp/CompromiseNLP.ts +3 -3
- package/src/nlp/EspeakPhonemizer.ts +30 -30
- package/src/nlp/IPA.ts +20 -20
- package/src/nlp/JapaneseSegmentation.ts +6 -6
- package/src/nlp/Lexicon.ts +8 -8
- package/src/nlp/Segmentation.ts +23 -14
- package/src/nlp/TextNormalizer.ts +16 -16
- package/src/recognition/AmazonTranscribeSTT.ts +16 -17
- package/src/recognition/AzureCognitiveServicesSTT.ts +8 -6
- package/src/recognition/GoogleCloudSTT.ts +21 -21
- package/src/recognition/OpenAICloudSTT.ts +142 -0
- package/src/recognition/SileroSTT.ts +26 -26
- package/src/recognition/VoskSTT.ts +10 -10
- package/src/recognition/WhisperCppSTT.ts +555 -0
- package/src/recognition/WhisperSTT.ts +760 -507
- package/src/server/Client.ts +23 -23
- package/src/server/Server.ts +9 -9
- package/src/server/Worker.ts +53 -53
- package/src/server/WorkerStarter.ts +2 -2
- package/src/source-separation/MDXNetSourceSeparation.ts +228 -0
- package/src/speech-language-detection/SileroLanguageDetection.ts +8 -8
- package/src/subtitles/Subtitles.ts +3 -3
- package/src/synthesis/AwsPollyTTS.ts +14 -14
- package/src/synthesis/AzureCognitiveServicesTTS.ts +10 -10
- package/src/synthesis/CoquiServerTTS.ts +10 -10
- package/src/synthesis/ElevenlabsTTS.ts +137 -0
- package/src/synthesis/EspeakTTS.ts +90 -71
- package/src/synthesis/FliteTTS.ts +157 -157
- package/src/synthesis/GoogleCloudTTS.ts +19 -19
- package/src/synthesis/GoogleTranslateTTS.ts +104 -104
- package/src/synthesis/MicrosoftEdgeTTS.ts +80 -80
- package/src/synthesis/OpenAICloudTTS.ts +196 -0
- package/src/synthesis/SamTTS.ts +3 -3
- package/src/synthesis/SapiTTS.ts +29 -29
- package/src/synthesis/StreamlabsPollyTTS.ts +29 -29
- package/src/synthesis/SvoxPicoTTS.ts +67 -67
- package/src/synthesis/VitsTTS.ts +380 -380
- package/src/tests/Test.ts +4 -4
- package/src/utilities/Compression.ts +34 -13
- package/src/utilities/FileDownloader.ts +19 -19
- package/src/utilities/FileSystem.ts +7 -7
- package/src/utilities/Locale.ts +22 -22
- package/src/utilities/Logger.ts +4 -4
- package/src/utilities/ObjectUtilities.ts +19 -19
- package/src/utilities/OpenPromise.ts +2 -2
- package/src/utilities/PackageManager.ts +40 -0
- package/src/utilities/PathUtilities.ts +8 -8
- package/src/utilities/RandomGenerator.ts +3 -3
- package/src/utilities/SmoothEstimator.ts +35 -0
- package/src/utilities/TarballMaker.ts +9 -9
- package/src/utilities/Timeline.ts +15 -13
- package/src/utilities/Timer.ts +4 -4
- package/src/utilities/Utilities.ts +49 -15
- package/src/utilities/WasmMemoryManager.ts +7 -7
- package/src/utilities/WebReader.ts +23 -23
- package/src/utilities/WikipediaReader.ts +2 -2
- package/src/voice-activity-detection/AdaptiveGateVAD.ts +202 -0
- package/src/voice-activity-detection/SileroVAD.ts +5 -5
- package/src/voice-activity-detection/WebRtcVAD.ts +5 -5
- package/dist/synthesis/ElevenLabsTTS.d.ts +0 -8
- package/dist/synthesis/ElevenLabsTTS.js +0 -82
- package/dist/synthesis/ElevenLabsTTS.js.map +0 -1
- package/src/synthesis/ElevenLabsTTS.ts +0 -104
package/src/dsp/FFT.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { RawAudio } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
2
|
+
import { ComplexNumber, sumVector } from '../math/VectorMath.js'
|
|
3
|
+
import { concatFloat32Arrays } from '../utilities/Utilities.js'
|
|
4
|
+
import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js'
|
|
4
5
|
|
|
5
6
|
let kissFFTInstance: any
|
|
6
7
|
|
|
7
|
-
export async function stftr(samples: Float32Array, fftOrder: number, windowSize: number,
|
|
8
|
+
export async function stftr(samples: Float32Array, fftOrder: number, windowSize: number, hopSize: number, windowType: WindowType) {
|
|
8
9
|
if (fftOrder % 2 != 0 || windowSize % 2 != 0) {
|
|
9
|
-
throw new Error(
|
|
10
|
+
throw new Error('FFT order and window size must multiples of 2')
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
if (windowSize > fftOrder) {
|
|
13
|
-
throw new Error(
|
|
14
|
+
throw new Error('Window size must be lesser or equal to the FFT size')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (hopSize > windowSize) {
|
|
18
|
+
throw new Error('Hop size must be lesser or equal to the window size')
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
const halfWindowSize = windowSize / 2
|
|
@@ -32,7 +37,7 @@ export async function stftr(samples: Float32Array, fftOrder: number, windowSize:
|
|
|
32
37
|
|
|
33
38
|
const frames: Float32Array[] = []
|
|
34
39
|
|
|
35
|
-
for (let offset = 0; offset < sampleCount; offset +=
|
|
40
|
+
for (let offset = 0; offset < sampleCount; offset += hopSize) {
|
|
36
41
|
const windowSamples = samples.subarray(offset, offset + windowSize)
|
|
37
42
|
frameBufferRef.clear()
|
|
38
43
|
|
|
@@ -54,53 +59,77 @@ export async function stftr(samples: Float32Array, fftOrder: number, windowSize:
|
|
|
54
59
|
return frames
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
export async function stiftr(binsForFrames: Float32Array[], fftOrder: number, windowSize: number, hopSize: number, windowType: WindowType, expectedOutputLength
|
|
62
|
+
export async function stiftr(binsForFrames: Float32Array[], fftOrder: number, windowSize: number, hopSize: number, windowType: WindowType, expectedOutputLength?: number) {
|
|
58
63
|
if (fftOrder % 2 != 0 || windowSize % 2 != 0) {
|
|
59
|
-
throw new Error(
|
|
64
|
+
throw new Error('FFT order and window size must multiples of 2')
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
if (windowSize > fftOrder) {
|
|
63
|
-
throw new Error(
|
|
68
|
+
throw new Error('Window size must be lesser or equal to the FFT size')
|
|
64
69
|
}
|
|
65
70
|
|
|
71
|
+
if (hopSize > windowSize) {
|
|
72
|
+
throw new Error('Hop size must be lesser or equal to the window size')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const frameCount = binsForFrames.length
|
|
76
|
+
|
|
66
77
|
const halfWindowSize = windowSize / 2
|
|
67
78
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
const windowWeights = getWindowWeights(windowType, windowSize)
|
|
80
|
+
|
|
81
|
+
const outSampleCount = hopSize * frameCount
|
|
71
82
|
|
|
72
|
-
if (
|
|
73
|
-
|
|
83
|
+
if (expectedOutputLength == null) {
|
|
84
|
+
expectedOutputLength = outSampleCount
|
|
74
85
|
}
|
|
75
86
|
|
|
87
|
+
const outSamples = new Float32Array(outSampleCount)
|
|
88
|
+
|
|
76
89
|
const m = await getKissFFTInstance()
|
|
77
90
|
const wasmMemory = new WasmMemoryManager(m)
|
|
78
91
|
|
|
79
92
|
const statePtr = m._kiss_fftr_alloc(fftOrder, 1, 0, 0)
|
|
80
93
|
wasmMemory.wrapPointer(statePtr)
|
|
81
94
|
|
|
82
|
-
const outSamples = new Float32Array(binsForFrames.length * hopSize)
|
|
83
|
-
|
|
84
95
|
const frameBufferRef = wasmMemory.allocFloat32Array(fftOrder)
|
|
85
96
|
const binsRef = wasmMemory.allocFloat32Array(fftOrder * 2)
|
|
86
97
|
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
const sumOfSquaredWeightsForSample = new Float32Array(outSampleCount)
|
|
99
|
+
|
|
100
|
+
for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
|
101
|
+
const binsForFrame = binsForFrames[frameIndex]
|
|
89
102
|
binsRef.clear()
|
|
90
|
-
binsRef.view.set(
|
|
103
|
+
binsRef.view.set(binsForFrame)
|
|
91
104
|
|
|
92
105
|
frameBufferRef.clear()
|
|
93
106
|
m._kiss_fftri(statePtr, binsRef.address, frameBufferRef.address)
|
|
94
|
-
|
|
95
107
|
const frameSamples = frameBufferRef.view
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
|
|
109
|
+
const frameStartOffset = frameIndex * hopSize
|
|
110
|
+
|
|
111
|
+
for (let windowOffset = 0; windowOffset < windowSize; windowOffset++) {
|
|
112
|
+
const frameSample = frameSamples[windowOffset]
|
|
113
|
+
const weight = windowWeights[windowOffset]
|
|
114
|
+
|
|
115
|
+
const writePosition = frameStartOffset + windowOffset
|
|
116
|
+
|
|
117
|
+
outSamples[writePosition] += frameSample * weight
|
|
118
|
+
|
|
119
|
+
sumOfSquaredWeightsForSample[writePosition] += weight ** 2
|
|
98
120
|
}
|
|
99
121
|
}
|
|
100
122
|
|
|
101
123
|
wasmMemory.freeAll()
|
|
102
124
|
|
|
103
|
-
|
|
125
|
+
// Divide by sum of weight squares for each samples
|
|
126
|
+
for (let i = 0; i < outSamples.length; i++) {
|
|
127
|
+
outSamples[i] /= sumOfSquaredWeightsForSample[i] + 1e-8
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const outSamplesTrimmed = outSamples.slice(halfWindowSize, halfWindowSize + expectedOutputLength)
|
|
131
|
+
|
|
132
|
+
return outSamplesTrimmed
|
|
104
133
|
}
|
|
105
134
|
|
|
106
135
|
export function getBinFrequencies(binCount: number, maxFrequency: number) {
|
|
@@ -133,6 +162,45 @@ export function fftFrameToPowerSpectrum(fftFrame: Float32Array) {
|
|
|
133
162
|
return powerSpectrum
|
|
134
163
|
}
|
|
135
164
|
|
|
165
|
+
export function binBufferToComplex(bins: Float32Array, extendAndMirror = false) {
|
|
166
|
+
const complexBins: ComplexNumber[] = []
|
|
167
|
+
|
|
168
|
+
for (let i = 0; i < bins.length; i += 2) {
|
|
169
|
+
complexBins.push({
|
|
170
|
+
real: bins[i],
|
|
171
|
+
imaginary: bins[i + 1]
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (extendAndMirror) {
|
|
176
|
+
const fftSize = bins.length - 2
|
|
177
|
+
|
|
178
|
+
for (let i = complexBins.length; i < fftSize; i++) {
|
|
179
|
+
const complexBinToMirror = complexBins[fftSize - i]
|
|
180
|
+
|
|
181
|
+
complexBins.push({
|
|
182
|
+
real: complexBinToMirror.real,
|
|
183
|
+
imaginary: -complexBinToMirror.imaginary
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return complexBins
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function complexToBinBuffer(complexBins: ComplexNumber[]) {
|
|
192
|
+
const binBuffer = new Float32Array(complexBins.length * 2)
|
|
193
|
+
|
|
194
|
+
for (let i = 0, outIndex = 0; i < complexBins.length; i++) {
|
|
195
|
+
const complexBin = complexBins[i]
|
|
196
|
+
|
|
197
|
+
binBuffer[outIndex++] = complexBin.real
|
|
198
|
+
binBuffer[outIndex++] = complexBin.imaginary
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return binBuffer
|
|
202
|
+
}
|
|
203
|
+
|
|
136
204
|
export async function getKissFFTInstance() {
|
|
137
205
|
if (!kissFFTInstance) {
|
|
138
206
|
const { default: initializer } = await import('@echogarden/kissfft-wasm')
|
|
@@ -143,20 +211,20 @@ export async function getKissFFTInstance() {
|
|
|
143
211
|
return kissFFTInstance
|
|
144
212
|
}
|
|
145
213
|
|
|
146
|
-
function getWindowWeights(windowType: WindowType, windowSize: number) {
|
|
214
|
+
export function getWindowWeights(windowType: WindowType, windowSize: number) {
|
|
147
215
|
const weights = new Float32Array(windowSize)
|
|
148
216
|
|
|
149
|
-
|
|
150
|
-
//const innerMultiplier = (2 * Math.PI) / (windowSize - 1)
|
|
217
|
+
const innerFactor = (2 * Math.PI) / (windowSize - 1)
|
|
151
218
|
|
|
219
|
+
if (windowType == 'hann') {
|
|
152
220
|
for (let i = 0; i < windowSize; i++) {
|
|
153
|
-
weights[i] = 0.5 * (1 - Math.cos(2 * Math.PI * (i / (windowSize - 1))))
|
|
154
|
-
|
|
221
|
+
//weights[i] = 0.5 * (1 - Math.cos(2 * Math.PI * (i / (windowSize - 1))))
|
|
222
|
+
weights[i] = 0.5 * (1 - Math.cos(innerFactor * i))
|
|
155
223
|
}
|
|
156
|
-
} else if (windowType ==
|
|
224
|
+
} else if (windowType == 'hamming') {
|
|
157
225
|
for (let i = 0; i < windowSize; i++) {
|
|
158
|
-
weights[i] = 0.54 - (0.46 * Math.cos(2 * Math.PI * (i / (windowSize - 1))))
|
|
159
|
-
|
|
226
|
+
//weights[i] = 0.54 - (0.46 * Math.cos(2 * Math.PI * (i / (windowSize - 1))))
|
|
227
|
+
weights[i] = 0.54 - (0.46 * Math.cos(innerFactor * i))
|
|
160
228
|
}
|
|
161
229
|
} else {
|
|
162
230
|
throw new Error(`Unsupported window function type: ${windowType}`)
|
|
@@ -166,14 +234,14 @@ function getWindowWeights(windowType: WindowType, windowSize: number) {
|
|
|
166
234
|
}
|
|
167
235
|
|
|
168
236
|
export async function testFFT1(rawAudio: RawAudio) {
|
|
169
|
-
const { resampleAudioSpeex } = await import(
|
|
237
|
+
const { resampleAudioSpeex } = await import('./SpeexResampler.js')
|
|
170
238
|
|
|
171
239
|
const samples = (await resampleAudioSpeex(rawAudio, 16000)).audioChannels[0]
|
|
172
240
|
|
|
173
241
|
const fftOrder = 512
|
|
174
242
|
const windowSize = 320
|
|
175
243
|
const hopLength = windowSize / 2
|
|
176
|
-
const windowType: WindowType =
|
|
244
|
+
const windowType: WindowType = 'hann'
|
|
177
245
|
|
|
178
246
|
const bins = await stftr(samples, fftOrder, windowSize, hopLength, windowType)
|
|
179
247
|
const normalizedBins = bins.map(bin => bin.map(x => x / fftOrder))
|
|
@@ -184,4 +252,4 @@ export async function testFFT1(rawAudio: RawAudio) {
|
|
|
184
252
|
return recoveredRawAudio
|
|
185
253
|
}
|
|
186
254
|
|
|
187
|
-
export type WindowType =
|
|
255
|
+
export type WindowType = 'hann' | 'hamming'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BiquadFilter, createHighpassFilter, createHighshelfFilter } from './BiquadFilter.js';
|
|
2
|
+
|
|
3
|
+
export class KWeightingFilter {
|
|
4
|
+
readonly highShelfFilter: BiquadFilter
|
|
5
|
+
readonly highPassFilter: BiquadFilter
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
public readonly sampleRate: number,
|
|
9
|
+
public readonly useStandard44100Filters = false) {
|
|
10
|
+
|
|
11
|
+
if (useStandard44100Filters) {
|
|
12
|
+
// These parameter values are taken from ITU-R BS.1770-2
|
|
13
|
+
// and designed only for a 44100 Hz sampling rate:
|
|
14
|
+
this.highShelfFilter = new BiquadFilter({
|
|
15
|
+
b0: 1.53512485958697,
|
|
16
|
+
b1: -2.69169618940638,
|
|
17
|
+
b2: 1.19839281085285,
|
|
18
|
+
a1: -1.69065929318241,
|
|
19
|
+
a2: 0.73248077421585,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
this.highPassFilter = new BiquadFilter({
|
|
23
|
+
b0: 1.0,
|
|
24
|
+
b1: -2.0,
|
|
25
|
+
b2: 1.0,
|
|
26
|
+
a1: -1.99004745483398,
|
|
27
|
+
a2: 0.99007225036621,
|
|
28
|
+
})
|
|
29
|
+
} else {
|
|
30
|
+
this.highShelfFilter = createHighshelfFilter(sampleRate, 2000.0, 4.0)
|
|
31
|
+
this.highPassFilter = createHighpassFilter(sampleRate, 1.5, 0.01)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
process(sample: number): number {
|
|
36
|
+
let outputSample = sample
|
|
37
|
+
|
|
38
|
+
outputSample = this.highShelfFilter.filter(outputSample)
|
|
39
|
+
outputSample = this.highPassFilter.filter(outputSample)
|
|
40
|
+
|
|
41
|
+
return outputSample
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { decibelsToGainFactor, gainFactorToDecibels } from '../audio/AudioUtilities.js';
|
|
2
|
+
import { SmoothEstimator } from '../utilities/SmoothEstimator.js';
|
|
3
|
+
import { KWeightingFilter } from './KWeightingFilter.js';
|
|
4
|
+
|
|
5
|
+
export class LoudnessEstimator {
|
|
6
|
+
readonly channelFilters: KWeightingFilter[] = []
|
|
7
|
+
readonly channelMeanSquares: SmoothEstimator[] = []
|
|
8
|
+
|
|
9
|
+
readonly minPower: number
|
|
10
|
+
|
|
11
|
+
constructor(public readonly options: LoudnessEstimatorOptions) {
|
|
12
|
+
const initialMeanSquares = decibelsToGainFactor(options.initialEstimate) ** 2
|
|
13
|
+
|
|
14
|
+
const ticksPerSecond = this.options.sampleRate * this.options.channelCount
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < options.channelCount; i++) {
|
|
17
|
+
const weightingFilter =
|
|
18
|
+
new KWeightingFilter(options.sampleRate)
|
|
19
|
+
|
|
20
|
+
const channelMeanSquares =
|
|
21
|
+
new SmoothEstimator(options.positiveAdaptationRate / ticksPerSecond, options.negativeAdaptationRate / ticksPerSecond, initialMeanSquares)
|
|
22
|
+
|
|
23
|
+
this.channelFilters.push(weightingFilter)
|
|
24
|
+
this.channelMeanSquares.push(channelMeanSquares)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
this.minPower = decibelsToGainFactor(options.minimumLoudness) ** 2
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
process(sample: number, channel: number) {
|
|
31
|
+
let filteredSample: number
|
|
32
|
+
|
|
33
|
+
if (this.options.applyKWeighting) {
|
|
34
|
+
filteredSample = this.channelFilters[channel].process(sample)
|
|
35
|
+
} else {
|
|
36
|
+
filteredSample = sample
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const filteredSampleSquared = filteredSample ** 2
|
|
40
|
+
|
|
41
|
+
const channelMeanSquares = this.channelMeanSquares[channel]
|
|
42
|
+
|
|
43
|
+
channelMeanSquares.update(filteredSampleSquared)
|
|
44
|
+
|
|
45
|
+
channelMeanSquares.estimate = Math.max(channelMeanSquares.estimate, this.minPower)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get currentLoudness() {
|
|
49
|
+
let totalMeanSquares = 0
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < this.options.channelCount; i++) {
|
|
52
|
+
totalMeanSquares += this.channelMeanSquares[i].estimate
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const rms = Math.sqrt(totalMeanSquares / this.options.channelCount)
|
|
56
|
+
const rmsDecibels = gainFactorToDecibels(rms)
|
|
57
|
+
|
|
58
|
+
return rmsDecibels
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
getCurrentRMSForChannel(channel: number) {
|
|
62
|
+
return Math.sqrt(this.channelMeanSquares[channel].estimate)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface LoudnessEstimatorOptions {
|
|
67
|
+
sampleRate: number
|
|
68
|
+
channelCount: number
|
|
69
|
+
positiveAdaptationRate: number
|
|
70
|
+
negativeAdaptationRate: number
|
|
71
|
+
initialEstimate: number
|
|
72
|
+
minimumLoudness: number
|
|
73
|
+
applyKWeighting: boolean
|
|
74
|
+
}
|
package/src/dsp/MFCC.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { extendDeep } from
|
|
2
|
-
import { Logger } from
|
|
3
|
-
import { resampleAudioSpeex } from
|
|
4
|
-
import { computeMelSpectogram } from
|
|
5
|
-
import { RawAudio, powerToDecibels } from
|
|
6
|
-
import { normalizeVectors } from
|
|
1
|
+
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
2
|
+
import { Logger } from '../utilities/Logger.js'
|
|
3
|
+
import { resampleAudioSpeex } from './SpeexResampler.js'
|
|
4
|
+
import { computeMelSpectogram } from './MelSpectogram.js'
|
|
5
|
+
import { RawAudio, powerToDecibels } from '../audio/AudioUtilities.js'
|
|
6
|
+
import { normalizeVectors } from '../math/VectorMath.js'
|
|
7
7
|
|
|
8
8
|
export async function computeMFCCs(monoAudio: RawAudio, options: MfccOptions = {}) {
|
|
9
9
|
const logger = new Logger()
|
|
10
|
-
logger.start(
|
|
10
|
+
logger.start('Initialize options')
|
|
11
11
|
|
|
12
12
|
if (monoAudio.audioChannels.length != 1) {
|
|
13
|
-
throw new Error(
|
|
13
|
+
throw new Error('Audio must be mono')
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
options = extendDefaultMfccOptions(options)
|
|
@@ -39,20 +39,20 @@ export async function computeMFCCs(monoAudio: RawAudio, options: MfccOptions = {
|
|
|
39
39
|
let mfccs: number[][]
|
|
40
40
|
|
|
41
41
|
if (emphasisFactor > 0) {
|
|
42
|
-
logger.start(
|
|
42
|
+
logger.start('Apply emphasis')
|
|
43
43
|
resampledAudio.audioChannels[0] = applyEmphasis(resampledAudio.audioChannels[0], emphasisFactor)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
logger.start(
|
|
46
|
+
logger.start('Compute Mel spectogram')
|
|
47
47
|
const { melSpectogram } = await computeMelSpectogram(resampledAudio, fftOrder, windowSize, hopLength, filterbankCount, lowerFrequencyHz, upperFrequencyHz)
|
|
48
48
|
|
|
49
|
-
logger.start(
|
|
49
|
+
logger.start('Extract MFCCs from Mel spectogram')
|
|
50
50
|
const mfccsFloat32 = melSpectogramToMFCCs(melSpectogram, featureCount)
|
|
51
51
|
|
|
52
52
|
mfccs = mfccsFloat32.map(mfcc => Array.from(mfcc))
|
|
53
53
|
|
|
54
54
|
if (options.normalize!) {
|
|
55
|
-
logger.start(
|
|
55
|
+
logger.start('Normalize MFCCs')
|
|
56
56
|
|
|
57
57
|
const { normalizedVectors, mean, stdDeviation } = normalizeVectors(mfccs)
|
|
58
58
|
mfccs = normalizedVectors
|
|
@@ -60,7 +60,7 @@ export async function computeMFCCs(monoAudio: RawAudio, options: MfccOptions = {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
if (lifteringFactor > 0) {
|
|
63
|
-
logger.start(
|
|
63
|
+
logger.start('Apply liftering to MFCCs')
|
|
64
64
|
mfccs = applyLiftering(mfccs, lifteringFactor)
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -84,13 +84,13 @@ export function melSpectogramToMFCCs(melSpectogram: Float32Array[], mfccFeatureC
|
|
|
84
84
|
return mfccs
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
export function melSpectrumToMFCC(melSpectrum: Float32Array, mfccFeatureCount: number, dctMatrix: Float32Array[], normalization:
|
|
87
|
+
export function melSpectrumToMFCC(melSpectrum: Float32Array, mfccFeatureCount: number, dctMatrix: Float32Array[], normalization: 'none' | 'orthonormal' = 'orthonormal') {
|
|
88
88
|
const melBandCount = melSpectrum.length
|
|
89
89
|
|
|
90
90
|
let firstFeatureNormalizationFactor: number
|
|
91
91
|
let nonfirstFeatureNormalizationFactor: number
|
|
92
92
|
|
|
93
|
-
if (normalization ==
|
|
93
|
+
if (normalization == 'orthonormal') {
|
|
94
94
|
firstFeatureNormalizationFactor = Math.sqrt(1 / (4 * mfccFeatureCount))
|
|
95
95
|
nonfirstFeatureNormalizationFactor = Math.sqrt(1 / (2 * mfccFeatureCount))
|
|
96
96
|
} else {
|
package/src/dsp/MelSpectogram.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { RawAudio } from
|
|
2
|
-
import { Logger } from
|
|
3
|
-
import * as FFT from
|
|
1
|
+
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
2
|
+
import { Logger } from '../utilities/Logger.js'
|
|
3
|
+
import * as FFT from './FFT.js'
|
|
4
4
|
|
|
5
5
|
export async function computeMelSpectogram(rawAudio: RawAudio, fftOrder: number, windowSize: number, hopLength: number, filterbankCount: number, lowerFrequencyHz: number, upperFrequencyHz: number) {
|
|
6
6
|
const logger = new Logger()
|
|
7
7
|
|
|
8
|
-
logger.start(
|
|
8
|
+
logger.start('Compute mel filterbank')
|
|
9
9
|
const binCount = (fftOrder / 2) + 2
|
|
10
10
|
const nyquistFrequency = rawAudio.sampleRate / 2
|
|
11
11
|
const binFrequencies = FFT.getBinFrequencies(binCount, nyquistFrequency)
|
|
@@ -24,11 +24,11 @@ export async function computeMelSpectogram(rawAudio: RawAudio, fftOrder: number,
|
|
|
24
24
|
export async function computeMelSpectogramUsingFilterbanks(rawAudio: RawAudio, fftOrder: number, windowSize: number, hopLength: number, filterbanks: Filterbank[]) {
|
|
25
25
|
const logger = new Logger()
|
|
26
26
|
|
|
27
|
-
logger.start(
|
|
27
|
+
logger.start('Compute short-time FFTs')
|
|
28
28
|
const audioSamples = rawAudio.audioChannels[0]
|
|
29
|
-
const fftFrames = await FFT.stftr(audioSamples, fftOrder, windowSize, hopLength,
|
|
29
|
+
const fftFrames = await FFT.stftr(audioSamples, fftOrder, windowSize, hopLength, 'hann')
|
|
30
30
|
|
|
31
|
-
logger.start(
|
|
31
|
+
logger.start('Convert FFT frames to a mel spectogram')
|
|
32
32
|
const melSpectogram = fftFramesToMelSpectogram(fftFrames, filterbanks)
|
|
33
33
|
|
|
34
34
|
logger.end()
|
package/src/dsp/Rubberband.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { RawAudio } from
|
|
2
|
-
import { extendDeep } from
|
|
3
|
-
import { concatFloat32Arrays } from
|
|
4
|
-
import { Float32ArrayRef, WasmMemoryManager } from
|
|
1
|
+
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
2
|
+
import { extendDeep } from '../utilities/ObjectUtilities.js'
|
|
3
|
+
import { concatFloat32Arrays } from '../utilities/Utilities.js'
|
|
4
|
+
import { Float32ArrayRef, WasmMemoryManager } from '../utilities/WasmMemoryManager.js'
|
|
5
5
|
|
|
6
6
|
let rubberbandInstance: any
|
|
7
7
|
|
|
@@ -123,51 +123,51 @@ export async function getRubberbandInstance() {
|
|
|
123
123
|
export function rubberBandOptionsToFlags(options: RubberbandOptions) {
|
|
124
124
|
let flags = 0
|
|
125
125
|
|
|
126
|
-
if (options.stretch ==
|
|
126
|
+
if (options.stretch == 'precise') {
|
|
127
127
|
flags += RubberBandOptionFlag.StretchPrecise
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
if (options.transients ==
|
|
130
|
+
if (options.transients == 'mixed') {
|
|
131
131
|
flags += RubberBandOptionFlag.TransientsMixed
|
|
132
|
-
} else if (options.transients ==
|
|
132
|
+
} else if (options.transients == 'smooth') {
|
|
133
133
|
flags += RubberBandOptionFlag.TransientsSmooth
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
if (options.detector ==
|
|
136
|
+
if (options.detector == 'percussive') {
|
|
137
137
|
flags += RubberBandOptionFlag.DetectorPercussive
|
|
138
|
-
} else if (options.detector ==
|
|
138
|
+
} else if (options.detector == 'soft') {
|
|
139
139
|
flags += RubberBandOptionFlag.DetectorSoft
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
if (options.phase ==
|
|
142
|
+
if (options.phase == 'independent') {
|
|
143
143
|
flags += RubberBandOptionFlag.PhaseIndependent
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
if (options.window ==
|
|
146
|
+
if (options.window == 'short') {
|
|
147
147
|
flags += RubberBandOptionFlag.WindowShort
|
|
148
|
-
} else if (options.window ==
|
|
148
|
+
} else if (options.window == 'long') {
|
|
149
149
|
flags += RubberBandOptionFlag.WindowLong
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
if (options.smoothing ==
|
|
152
|
+
if (options.smoothing == 'on') {
|
|
153
153
|
flags += RubberBandOptionFlag.SmoothingOn
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
if (options.formant ==
|
|
156
|
+
if (options.formant == 'preserved') {
|
|
157
157
|
flags += RubberBandOptionFlag.FormantPreserved
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
if (options.pitch ==
|
|
160
|
+
if (options.pitch == 'high-quality') {
|
|
161
161
|
flags += RubberBandOptionFlag.PitchHighQuality
|
|
162
|
-
} else if (options.pitch ==
|
|
162
|
+
} else if (options.pitch == 'high-consistency') {
|
|
163
163
|
flags += RubberBandOptionFlag.PitchHighConsistency
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
if (options.channels ==
|
|
166
|
+
if (options.channels == 'together') {
|
|
167
167
|
flags += RubberBandOptionFlag.ChannelsTogether
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
if (options.engine ==
|
|
170
|
+
if (options.engine == 'finer') {
|
|
171
171
|
flags += RubberBandOptionFlag.EngineFiner
|
|
172
172
|
}
|
|
173
173
|
|
|
@@ -223,27 +223,27 @@ export enum RubberBandPresetOption {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
export const defaultRubberbandOptions: RubberbandOptions = {
|
|
226
|
-
stretch:
|
|
227
|
-
transients:
|
|
228
|
-
detector:
|
|
229
|
-
phase:
|
|
230
|
-
window:
|
|
231
|
-
smoothing:
|
|
232
|
-
formant:
|
|
233
|
-
pitch:
|
|
234
|
-
channels:
|
|
235
|
-
engine:
|
|
226
|
+
stretch: 'elastic',
|
|
227
|
+
transients: 'crisp',
|
|
228
|
+
detector: 'compound',
|
|
229
|
+
phase: 'laminar',
|
|
230
|
+
window: 'standard',
|
|
231
|
+
smoothing: 'off',
|
|
232
|
+
formant: 'shited',
|
|
233
|
+
pitch: 'high-speed',
|
|
234
|
+
channels: 'apart',
|
|
235
|
+
engine: 'faster'
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
export type RubberbandOptions = {
|
|
239
|
-
stretch?:
|
|
240
|
-
transients?:
|
|
241
|
-
detector?:
|
|
242
|
-
phase?:
|
|
243
|
-
window?:
|
|
244
|
-
smoothing?:
|
|
245
|
-
formant?:
|
|
246
|
-
pitch?:
|
|
247
|
-
channels?:
|
|
248
|
-
engine?:
|
|
239
|
+
stretch?: 'elastic' | 'precise'
|
|
240
|
+
transients?: 'crisp' | 'mixed' | 'smooth'
|
|
241
|
+
detector?: 'compound' | 'percussive' | 'soft'
|
|
242
|
+
phase?: 'laminar' | 'independent'
|
|
243
|
+
window?: 'standard' | 'long' | 'short'
|
|
244
|
+
smoothing?: 'off' | 'on'
|
|
245
|
+
formant?: 'shited' | 'preserved'
|
|
246
|
+
pitch?: 'high-speed' | 'high-quality' | 'high-consistency'
|
|
247
|
+
channels?: 'apart' | 'together'
|
|
248
|
+
engine?: 'faster' | 'finer'
|
|
249
249
|
}
|
package/src/dsp/Sonic.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RawAudio } from
|
|
2
|
-
import { WasmMemoryManager } from
|
|
1
|
+
import { RawAudio } from '../audio/AudioUtilities.js'
|
|
2
|
+
import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js'
|
|
3
3
|
|
|
4
4
|
let sonicInstance: any
|
|
5
5
|
|
|
@@ -22,13 +22,13 @@ export async function stretchTimePitch(rawAudio: RawAudio, speed: number, pitchS
|
|
|
22
22
|
const writeSuccess = m._sonicWriteFloatToStream(streamPtr, inputSamplesRef.address, inputSampleCount)
|
|
23
23
|
|
|
24
24
|
if (writeSuccess != 1) {
|
|
25
|
-
throw new Error(
|
|
25
|
+
throw new Error('Sonic error: failed write to stream')
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const flushSuccess = m._sonicFlushStream(streamPtr)
|
|
29
29
|
|
|
30
30
|
if (flushSuccess != 1) {
|
|
31
|
-
throw new Error(
|
|
31
|
+
throw new Error('Sonic error: failed flushing stream')
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const samplesAvailable = m._sonicSamplesAvailable(streamPtr)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RawAudio, cloneRawAudio } from
|
|
2
|
-
import { WasmMemoryManager } from
|
|
1
|
+
import { RawAudio, cloneRawAudio } from '../audio/AudioUtilities.js'
|
|
2
|
+
import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js'
|
|
3
3
|
|
|
4
4
|
let speexResamplerInstance: any
|
|
5
5
|
|