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
|
@@ -2,11 +2,11 @@ import { splitToParagraphs, wordCharacterPattern } from '../nlp/Segmentation.js'
|
|
|
2
2
|
import { Logger } from './Logger.js';
|
|
3
3
|
export async function parseWikipediaArticle(articleName, language) {
|
|
4
4
|
const logger = new Logger();
|
|
5
|
-
logger.startAsync(
|
|
5
|
+
logger.startAsync('Fetching Wikipedia article');
|
|
6
6
|
const { default: wtf } = await import('wtf_wikipedia');
|
|
7
7
|
const document = await wtf.fetch(articleName, language);
|
|
8
8
|
if (!document) {
|
|
9
|
-
throw new Error(
|
|
9
|
+
throw new Error('Error fetching Wikipedia article');
|
|
10
10
|
}
|
|
11
11
|
const sections = document.sections();
|
|
12
12
|
const sectionsText = [];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RawAudio } from '../audio/AudioUtilities.js';
|
|
2
|
+
import { BiquadFilter } from '../dsp/BiquadFilter.js';
|
|
3
|
+
import { DecayingPeakEstimator } from '../dsp/DecayingPeakEstimator.js';
|
|
4
|
+
import { LoudnessEstimator } from '../dsp/LoudnessEstimator.js';
|
|
5
|
+
import { Timeline } from '../utilities/Timeline.js';
|
|
6
|
+
export declare function detectVoiceActivity(rawAudio: RawAudio, options: AdaptiveGateVADOptions): Promise<Timeline>;
|
|
7
|
+
export declare class AdaptiveGateVAD {
|
|
8
|
+
readonly sampleRate: number;
|
|
9
|
+
readonly channelCount: number;
|
|
10
|
+
readonly options: AdaptiveGateVADOptions;
|
|
11
|
+
channelHighpassFilters: BiquadFilter[];
|
|
12
|
+
channelLowpassFilters: BiquadFilter[];
|
|
13
|
+
loudnessEstimator: LoudnessEstimator;
|
|
14
|
+
minimumLoudnessEstimator: DecayingPeakEstimator;
|
|
15
|
+
maximumLoudnessEstimator: DecayingPeakEstimator;
|
|
16
|
+
constructor(sampleRate: number, channelCount: number, options: AdaptiveGateVADOptions);
|
|
17
|
+
process(sample: number, channelIndex: number): void;
|
|
18
|
+
}
|
|
19
|
+
export interface AdaptiveGateVADOptions {
|
|
20
|
+
lowCutoff?: number;
|
|
21
|
+
highCutoff?: number;
|
|
22
|
+
positiveAdaptationRate?: number;
|
|
23
|
+
negativeAdaptationRate?: number;
|
|
24
|
+
peakLoudnessDecay?: number;
|
|
25
|
+
backwardExtensionDuration?: number;
|
|
26
|
+
relativeThreshold?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare const defaultAdaptiveGateOptions: AdaptiveGateVADOptions;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { getRawAudioDuration } from '../audio/AudioUtilities.js';
|
|
2
|
+
import { createHighpassFilter, createLowpassFilter } from '../dsp/BiquadFilter.js';
|
|
3
|
+
import { DecayingPeakEstimator } from '../dsp/DecayingPeakEstimator.js';
|
|
4
|
+
import { LoudnessEstimator } from '../dsp/LoudnessEstimator.js';
|
|
5
|
+
import { extendDeep } from '../utilities/ObjectUtilities.js';
|
|
6
|
+
import { logToStderr } from '../utilities/Utilities.js';
|
|
7
|
+
const log = logToStderr;
|
|
8
|
+
export async function detectVoiceActivity(rawAudio, options) {
|
|
9
|
+
const channelCount = rawAudio.audioChannels.length;
|
|
10
|
+
const sampleCount = rawAudio.audioChannels[0].length;
|
|
11
|
+
const sampleRate = rawAudio.sampleRate;
|
|
12
|
+
const audioDuration = getRawAudioDuration(rawAudio);
|
|
13
|
+
options = extendDeep(defaultAdaptiveGateOptions, options);
|
|
14
|
+
const gateVAD = new AdaptiveGateVAD(sampleRate, channelCount, options);
|
|
15
|
+
const frameDuration = 0.01;
|
|
16
|
+
const frameRecords = [];
|
|
17
|
+
for (let sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) {
|
|
18
|
+
const timePosition = sampleIndex / sampleRate;
|
|
19
|
+
for (let channelIndex = 0; channelIndex < channelCount; channelIndex++) {
|
|
20
|
+
const sample = rawAudio.audioChannels[channelIndex][sampleIndex];
|
|
21
|
+
gateVAD.process(sample, channelIndex);
|
|
22
|
+
}
|
|
23
|
+
if (frameRecords.length == 0 ||
|
|
24
|
+
timePosition > frameRecords[frameRecords.length - 1].timePosition + frameDuration) {
|
|
25
|
+
const record = {
|
|
26
|
+
timePosition,
|
|
27
|
+
loudness: gateVAD.loudnessEstimator.currentLoudness,
|
|
28
|
+
minimumLoudness: gateVAD.minimumLoudnessEstimator.currentPeak,
|
|
29
|
+
maximumLoudness: gateVAD.maximumLoudnessEstimator.currentPeak,
|
|
30
|
+
};
|
|
31
|
+
frameRecords.push(record);
|
|
32
|
+
//log(`${timePosition.toFixed(3)}: loudness: ${record.loudness.toFixed(2)}dB, min: ${record.minimumLoudness.toFixed(2)}dB, max: ${record.maximumLoudness.toFixed(2)}dB dynamic range: ${record.dynamicRange.toFixed(2)}dB`)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const frameActive = [];
|
|
36
|
+
for (let i = 0; i < frameRecords.length; i++) {
|
|
37
|
+
frameActive[i] = false;
|
|
38
|
+
}
|
|
39
|
+
{
|
|
40
|
+
const backwardExtensionFrameCount = Math.floor(options.backwardExtensionDuration / frameDuration);
|
|
41
|
+
const relativeThreshold = options.relativeThreshold;
|
|
42
|
+
let extendedActivityStartIndex = frameRecords.length;
|
|
43
|
+
for (let i = frameRecords.length - 1; i >= 0; i--) {
|
|
44
|
+
const record = frameRecords[i];
|
|
45
|
+
const referenceLoudness = Math.max(record.maximumLoudness, -30);
|
|
46
|
+
let isActive = false;
|
|
47
|
+
if (i >= extendedActivityStartIndex) {
|
|
48
|
+
isActive = true;
|
|
49
|
+
}
|
|
50
|
+
if (record.loudness >= referenceLoudness + relativeThreshold) {
|
|
51
|
+
isActive = true;
|
|
52
|
+
extendedActivityStartIndex = Math.max(i - backwardExtensionFrameCount, 0);
|
|
53
|
+
}
|
|
54
|
+
frameActive[i] = isActive;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const timeline = [];
|
|
58
|
+
for (let i = 0; i < frameRecords.length; i++) {
|
|
59
|
+
const record = frameRecords[i];
|
|
60
|
+
const isActive = frameActive[i];
|
|
61
|
+
const activityText = isActive ? 'active' : 'inactive';
|
|
62
|
+
const startTime = record.timePosition;
|
|
63
|
+
const endTime = Math.min(startTime + frameDuration, audioDuration);
|
|
64
|
+
if (timeline.length == 0 || timeline[timeline.length - 1].text != activityText) {
|
|
65
|
+
timeline.push({
|
|
66
|
+
type: 'segment',
|
|
67
|
+
text: activityText,
|
|
68
|
+
startTime,
|
|
69
|
+
endTime,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
timeline[timeline.length - 1].endTime = endTime;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return timeline;
|
|
77
|
+
}
|
|
78
|
+
export class AdaptiveGateVAD {
|
|
79
|
+
sampleRate;
|
|
80
|
+
channelCount;
|
|
81
|
+
options;
|
|
82
|
+
channelHighpassFilters;
|
|
83
|
+
channelLowpassFilters;
|
|
84
|
+
loudnessEstimator;
|
|
85
|
+
minimumLoudnessEstimator;
|
|
86
|
+
maximumLoudnessEstimator;
|
|
87
|
+
constructor(sampleRate, channelCount, options) {
|
|
88
|
+
this.sampleRate = sampleRate;
|
|
89
|
+
this.channelCount = channelCount;
|
|
90
|
+
this.options = options;
|
|
91
|
+
this.channelHighpassFilters = [];
|
|
92
|
+
this.channelLowpassFilters = [];
|
|
93
|
+
for (let i = 0; i < this.channelCount; i++) {
|
|
94
|
+
this.channelHighpassFilters.push(createHighpassFilter(this.sampleRate, options.lowCutoff));
|
|
95
|
+
this.channelLowpassFilters.push(createLowpassFilter(this.sampleRate, options.highCutoff));
|
|
96
|
+
}
|
|
97
|
+
this.loudnessEstimator = new LoudnessEstimator({
|
|
98
|
+
sampleRate: this.sampleRate,
|
|
99
|
+
channelCount: this.channelCount,
|
|
100
|
+
positiveAdaptationRate: options.positiveAdaptationRate,
|
|
101
|
+
negativeAdaptationRate: options.negativeAdaptationRate,
|
|
102
|
+
initialEstimate: -60,
|
|
103
|
+
minimumLoudness: -60,
|
|
104
|
+
applyKWeighting: false,
|
|
105
|
+
});
|
|
106
|
+
const ticksPerSecond = this.sampleRate * this.channelCount;
|
|
107
|
+
this.minimumLoudnessEstimator = new DecayingPeakEstimator({
|
|
108
|
+
kind: 'minimum',
|
|
109
|
+
decayPerSecond: options.peakLoudnessDecay,
|
|
110
|
+
initialPeak: -60,
|
|
111
|
+
}, ticksPerSecond);
|
|
112
|
+
this.maximumLoudnessEstimator = new DecayingPeakEstimator({
|
|
113
|
+
kind: 'maximum',
|
|
114
|
+
decayPerSecond: options.peakLoudnessDecay,
|
|
115
|
+
initialPeak: -60,
|
|
116
|
+
}, ticksPerSecond);
|
|
117
|
+
}
|
|
118
|
+
process(sample, channelIndex) {
|
|
119
|
+
sample = this.channelHighpassFilters[channelIndex].filter(sample);
|
|
120
|
+
sample = this.channelLowpassFilters[channelIndex].filter(sample);
|
|
121
|
+
this.loudnessEstimator.process(sample, channelIndex);
|
|
122
|
+
const currentLoudness = this.loudnessEstimator.currentLoudness;
|
|
123
|
+
this.minimumLoudnessEstimator.process(currentLoudness);
|
|
124
|
+
if (currentLoudness >= -60) {
|
|
125
|
+
this.maximumLoudnessEstimator.process(currentLoudness);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export const defaultAdaptiveGateOptions = {
|
|
130
|
+
lowCutoff: 100,
|
|
131
|
+
highCutoff: 1000,
|
|
132
|
+
positiveAdaptationRate: 400.0,
|
|
133
|
+
negativeAdaptationRate: 10.0,
|
|
134
|
+
peakLoudnessDecay: 4.0,
|
|
135
|
+
backwardExtensionDuration: 0.2,
|
|
136
|
+
relativeThreshold: -15,
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=AdaptiveGateVAD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdaptiveGateVAD.js","sourceRoot":"","sources":["../../src/voice-activity-detection/AdaptiveGateVAD.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference path="../../src/typings/Fillers.d.ts" />
|
|
2
2
|
import Onnx from 'onnxruntime-node';
|
|
3
3
|
import { RawAudio } from '../audio/AudioUtilities.js';
|
|
4
|
-
export declare function detectVoiceActivity(rawAudio: RawAudio, modelPath: string, frameDuration
|
|
4
|
+
export declare function detectVoiceActivity(rawAudio: RawAudio, modelPath: string, frameDuration: 30 | 60 | 90): Promise<number[]>;
|
|
5
5
|
export declare class SileroVAD {
|
|
6
6
|
session?: Onnx.InferenceSession;
|
|
7
7
|
modelStateH: Onnx.Tensor;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import Onnx from 'onnxruntime-node';
|
|
2
2
|
import { concatFloat32Arrays } from '../utilities/Utilities.js';
|
|
3
3
|
let sileroVad;
|
|
4
|
-
export async function detectVoiceActivity(rawAudio, modelPath, frameDuration
|
|
4
|
+
export async function detectVoiceActivity(rawAudio, modelPath, frameDuration) {
|
|
5
5
|
if (rawAudio.sampleRate != 16000) {
|
|
6
|
-
throw new Error(
|
|
6
|
+
throw new Error('Audio sample rate must be 16KHz');
|
|
7
7
|
}
|
|
8
8
|
const audioSamples = rawAudio.audioChannels[0];
|
|
9
9
|
const frameLength = Math.floor(16000 * (frameDuration / 1000));
|
|
@@ -43,9 +43,9 @@ export class SileroVAD {
|
|
|
43
43
|
//const inputs = { input: inputTensor, h0: this.modelStateH, c0: this.modelStateC }
|
|
44
44
|
const inputs = { input: inputTensor, sr: this.modelSampleRate, h: this.modelStateH, c: this.modelStateC };
|
|
45
45
|
const results = await this.session.run(inputs);
|
|
46
|
-
const probability = results[
|
|
47
|
-
this.modelStateH = results[
|
|
48
|
-
this.modelStateC = results[
|
|
46
|
+
const probability = results['output'].data[0];
|
|
47
|
+
this.modelStateH = results['hn'];
|
|
48
|
+
this.modelStateC = results['cn'];
|
|
49
49
|
return probability;
|
|
50
50
|
}
|
|
51
51
|
async initializeSession(modelPath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SileroVAD.js","sourceRoot":"","sources":["../../src/voice-activity-detection/SileroVAD.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,kBAAkB,CAAA;AAEnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAG/D,IAAI,SAAoB,CAAA;AAExB,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAkB,EAAE,SAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"SileroVAD.js","sourceRoot":"","sources":["../../src/voice-activity-detection/SileroVAD.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { RawAudio } from
|
|
1
|
+
import { RawAudio } from '../audio/AudioUtilities.js';
|
|
2
2
|
export declare function detectVoiceActivity(rawAudio: RawAudio, frameDuration?: 10 | 20 | 30, mode?: 0 | 1 | 2 | 3): Promise<(0 | 1)[]>;
|
|
3
3
|
export declare function fvad(samples: Int16Array, sampleRate: number, frameDuration: 10 | 20 | 30, mode: 0 | 1 | 2 | 3): Promise<any[]>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as AudioBufferConversion from
|
|
2
|
-
import { WasmMemoryManager } from
|
|
1
|
+
import * as AudioBufferConversion from '../audio/AudioBufferConversion.js';
|
|
2
|
+
import { WasmMemoryManager } from '../utilities/WasmMemoryManager.js';
|
|
3
3
|
export async function detectVoiceActivity(rawAudio, frameDuration = 10, mode = 0) {
|
|
4
4
|
if (rawAudio.sampleRate != 16000) {
|
|
5
|
-
throw new Error(
|
|
5
|
+
throw new Error('Audio sample rate must be 16KHz');
|
|
6
6
|
}
|
|
7
7
|
const frameClassifications = await fvad(AudioBufferConversion.float32ToInt16Pcm(rawAudio.audioChannels[0]), rawAudio.sampleRate, frameDuration, mode);
|
|
8
8
|
return frameClassifications;
|
|
@@ -34,7 +34,7 @@ export async function fvad(samples, sampleRate, frameDuration, mode) {
|
|
|
34
34
|
frameSamplesRef.view.set(frame);
|
|
35
35
|
const fvadResult = fvad_process(instancePtr, frameSamplesRef.address, frameSampleCount);
|
|
36
36
|
if (fvadResult == -1) {
|
|
37
|
-
throw new Error(
|
|
37
|
+
throw new Error('fvad_process failed');
|
|
38
38
|
}
|
|
39
39
|
result.push(fvadResult);
|
|
40
40
|
}
|
package/docs/API.md
CHANGED
|
@@ -19,11 +19,11 @@ import * as Echogarden from 'echogarden'
|
|
|
19
19
|
|
|
20
20
|
All methods, properties and arguments have TypeScript type information. You can use it to get more detailed and up-to-date type information that may not be covered in the documentation.
|
|
21
21
|
|
|
22
|
-
### Related
|
|
22
|
+
### Related pages
|
|
23
23
|
* [Options reference](Options.md)
|
|
24
|
-
* [
|
|
25
|
-
* [
|
|
26
|
-
* [
|
|
24
|
+
* [List of all supported engines](Engines.md)
|
|
25
|
+
* [Quick guide for the command line interface](CLI.md)
|
|
26
|
+
* [WebSocket server guide](Server.md)
|
|
27
27
|
|
|
28
28
|
## Synthesis
|
|
29
29
|
|
|
@@ -195,7 +195,7 @@ Detects language of text.
|
|
|
195
195
|
|
|
196
196
|
### `detectVoiceActivity(input, options)`
|
|
197
197
|
|
|
198
|
-
Detects voice activity in audio (non
|
|
198
|
+
Detects voice activity in audio (non-real-time).
|
|
199
199
|
|
|
200
200
|
* `input`: Can be an audio file path (`string`), encoded audio (`Buffer` or `Uint8array`) or a raw audio object (`RawAudio`)
|
|
201
201
|
* `options`: Voice activity detection options object
|
|
@@ -209,10 +209,10 @@ Detects voice activity in audio (non real-time).
|
|
|
209
209
|
|
|
210
210
|
## Speech denoising
|
|
211
211
|
|
|
212
|
-
Tries to reduce background noise in spoken audio.
|
|
213
|
-
|
|
214
212
|
### `denoise(input, options)`
|
|
215
213
|
|
|
214
|
+
Tries to reduce background noise in spoken audio.
|
|
215
|
+
|
|
216
216
|
* `input`: Can be an audio file path (`string`), encoded audio (`Buffer` or `Uint8array`) or a raw audio object (`RawAudio`)
|
|
217
217
|
* `options`: Denoising options object
|
|
218
218
|
|
|
@@ -223,6 +223,24 @@ Tries to reduce background noise in spoken audio.
|
|
|
223
223
|
}
|
|
224
224
|
```
|
|
225
225
|
|
|
226
|
+
## Source separation
|
|
227
|
+
|
|
228
|
+
### `isolate(input, options)`
|
|
229
|
+
|
|
230
|
+
Attempts to isolate an individual [audio stem](https://en.wikipedia.org/wiki/Stem_(audio)), like human voice, or one or more musical instruments (depending on model training), from the given waveform.
|
|
231
|
+
|
|
232
|
+
* `input`: Can be an audio file path (`string`), encoded audio (`Buffer` or `Uint8array`) or a raw audio object (`RawAudio`)
|
|
233
|
+
* `options`: Source separation options object
|
|
234
|
+
|
|
235
|
+
#### Returns (via promise):
|
|
236
|
+
```ts
|
|
237
|
+
{
|
|
238
|
+
inputRawAudio: RawAudio
|
|
239
|
+
isolatedRawAudio: RawAudio
|
|
240
|
+
backgroundRawAudio: RawAudio
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
226
244
|
## Subtitles
|
|
227
245
|
|
|
228
246
|
### `timelineToSubtitles(timeline, options)`
|
|
@@ -256,7 +274,7 @@ Set a global option.
|
|
|
256
274
|
|
|
257
275
|
Supported keys:
|
|
258
276
|
|
|
259
|
-
* `'ffmpegPath'`: override
|
|
277
|
+
* `'ffmpegPath'`: override FFmpeg executable path
|
|
260
278
|
* `'soxPath'`: override SoX executable path
|
|
261
279
|
|
|
262
280
|
### `getGlobalOption(key)`
|
|
@@ -265,7 +283,7 @@ Get a global option.
|
|
|
265
283
|
|
|
266
284
|
Supported keys:
|
|
267
285
|
|
|
268
|
-
* `'ffmpegPath'`: get
|
|
286
|
+
* `'ffmpegPath'`: get FFmpeg executable path
|
|
269
287
|
* `'soxPath'`: get SoX executable path
|
|
270
288
|
|
|
271
289
|
#### Returns:
|
|
@@ -274,5 +292,5 @@ The value associated with the given key.
|
|
|
274
292
|
|
|
275
293
|
## TODO
|
|
276
294
|
|
|
277
|
-
Expose more methods that may be useful for developers, like phonemization, etc.
|
|
278
|
-
|
|
295
|
+
* Expose more methods that may be useful for developers, like phonemization, etc.
|
|
296
|
+
* Expose audio playback used in CLI, possibly with timeline synchronization support.
|
package/docs/CLI.md
CHANGED
|
@@ -8,13 +8,17 @@ echogarden [command] [one or more inputs..] [one or more outputs...] [options...
|
|
|
8
8
|
|
|
9
9
|
Here's a quick tour of the main operations available via the CLI.
|
|
10
10
|
|
|
11
|
-
Each command can accept one or more options, in the form `--[optionName]=[value]` (The `=` is required).
|
|
11
|
+
Each command can accept one or more options, in the form `--[optionName]=[value]` (The `=` is required).
|
|
12
12
|
|
|
13
13
|
**Keyboard shortcuts**:
|
|
14
14
|
* While the program is running, you can press `esc` to exit immediately
|
|
15
15
|
* When audio is playing, you can press `enter` to skip it
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### Related pages
|
|
18
|
+
* [Options reference](Options.md)
|
|
19
|
+
* [List of all supported engines](Engines.md)
|
|
20
|
+
|
|
21
|
+
## Text-to-speech
|
|
18
22
|
|
|
19
23
|
**Task**: given a text file, synthesize spoken audio for it.
|
|
20
24
|
|
|
@@ -58,7 +62,7 @@ Synthesize a Wikipedia article, in any of its language editions:
|
|
|
58
62
|
echogarden speak-wikipedia "Psychologie" --language=fr
|
|
59
63
|
```
|
|
60
64
|
|
|
61
|
-
## Speech
|
|
65
|
+
## Speech-to-text
|
|
62
66
|
|
|
63
67
|
**Task**: given an audio recording containing speech, find a textual transcription that best matches it.
|
|
64
68
|
|
|
@@ -72,7 +76,7 @@ This would transcribe the audio file `speech.mp3` and store the resulting transc
|
|
|
72
76
|
echogarden transcribe speech.mp3 result.txt result.srt result.json
|
|
73
77
|
```
|
|
74
78
|
|
|
75
|
-
## Speech
|
|
79
|
+
## Speech-to-transcript alignment
|
|
76
80
|
|
|
77
81
|
**Task**: given an audio file and its transcript, try to approximate the timing of the start and end of each spoken word (and its subparts).
|
|
78
82
|
|
|
@@ -120,7 +124,7 @@ echogarden align speech.mp3 transcript.txt parts/[segment].m4a parts/[segment].s
|
|
|
120
124
|
|
|
121
125
|
### Splitting based on sentence boundaries (future)
|
|
122
126
|
|
|
123
|
-
Splitting based on sentences, using a `[sentence]` placeholder, is currently on the to-do list. Please let me know if you find this feature important and I'll prioritize it.
|
|
127
|
+
Splitting based on sentences, using a `[sentence]` placeholder, is currently on the to-do list. Please let me know if you find this feature important, and I'll prioritize it.
|
|
124
128
|
|
|
125
129
|
## Audio playback
|
|
126
130
|
By default, audio isn't played in the terminal when an output file is specified, you can override this behavior by adding `--play`:
|
|
@@ -135,7 +139,7 @@ echogarden transcribe speech.mp3 --no-play
|
|
|
135
139
|
|
|
136
140
|
## File overwriting
|
|
137
141
|
|
|
138
|
-
By default, the CLI doesn't overwrite existing files. If an output file `out.mp3` already exists, it will save it as `
|
|
142
|
+
By default, the CLI doesn't overwrite existing files. If an output file `out.mp3` already exists, it will save it as `out_001.mp3`.
|
|
139
143
|
|
|
140
144
|
To have existing files be overwritten, you can pass the `--overwrite` option.
|
|
141
145
|
|
|
@@ -237,7 +241,7 @@ echogarden detect-voice-activity speech.mp3 timeline.json
|
|
|
237
241
|
|
|
238
242
|
### Speech denoising
|
|
239
243
|
|
|
240
|
-
**Task**:
|
|
244
|
+
**Task**: attempt to reduce the amount of background noise in a spoken recording.
|
|
241
245
|
|
|
242
246
|
This would apply denoising and play the denoised audio:
|
|
243
247
|
```bash
|
|
@@ -249,6 +253,26 @@ This would apply denoising, and save the denoised audio to a file:
|
|
|
249
253
|
echogarden denoise speech.mp3 denoised-speech.mp3
|
|
250
254
|
```
|
|
251
255
|
|
|
256
|
+
### Source separation
|
|
257
|
+
|
|
258
|
+
**Task**: try to isolate a vocal track (or other type of track, depending on model used), from the audio.
|
|
259
|
+
|
|
260
|
+
This would apply source separation and play the isolated audio:
|
|
261
|
+
```bash
|
|
262
|
+
echogarden isolate voice-with-music.mp3
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
This would apply source separation, and save both the isolated and background audio:
|
|
266
|
+
```bash
|
|
267
|
+
echogarden isolate voice-with-music.mp3 voice-isolated.mp3
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Written files would be:
|
|
271
|
+
```
|
|
272
|
+
voice-isolated.mp3
|
|
273
|
+
voice-isolated.background.mp3
|
|
274
|
+
```
|
|
275
|
+
|
|
252
276
|
## Information and lists
|
|
253
277
|
|
|
254
278
|
### `list-engines`
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# How to help
|
|
2
|
+
|
|
3
|
+
So far, this project has been the solo work of a single person.
|
|
4
|
+
|
|
5
|
+
However, there are many areas where contributions can be made.
|
|
6
|
+
|
|
7
|
+
## Report any issue or bug you encounter
|
|
8
|
+
|
|
9
|
+
First, check the issue tracker, as well as the [task list](Tasklist.md) to see if the problem is already known to me. The task list allows me to efficiently document and organize a large quantity of small issues, enhancements or ideas that would otherwise flood an issue tracker with lots of unimportant entries, be ignored, or forgotten entirely.
|
|
10
|
+
|
|
11
|
+
If you find the issue you're encountering in the task list, you can still open an issue to discuss it. This allows me to know that someone cares about a particular issue, and I may give it higher priority.
|
|
12
|
+
|
|
13
|
+
There might be some obvious errors that have gone unreported. Especially if:
|
|
14
|
+
* You're using the macOS architecture: I don't have access to a macOS machine, so personally I did not and cannot perform testing on that platform.
|
|
15
|
+
* You're using cloud services: There may be changes in the service that will require updating the code. I don't often test they work correctly, since my trial periods in Google, Microsoft and Amazon have all expired, thus testing requires me to use paid requests.
|
|
16
|
+
|
|
17
|
+
In any case, please let me know if you get any unexpected error message or surprising behavior that you care about, and I'll try to prioritize it, if possible.
|
|
18
|
+
|
|
19
|
+
## Report or help fix odd TTS pronunciations and other fail cases
|
|
20
|
+
|
|
21
|
+
When you encounter an odd pronunciation in a VITS voice, there are several possible causes:
|
|
22
|
+
|
|
23
|
+
1. An incorrect phonemization produced by the eSpeak engine. Fortunately, it can be overridden by adding a corrected pronunciation to an Echogarden lexicon. You can pass one or more custom lexicons files to the VITS engine via `vits.customLexiconPaths` and see if it solves the problem. The lexicon format is the same as in [this file](https://github.com/echogarden-project/echogarden/blob/main/data/lexicons/heteronyms.en.json) - you can use it as a reference.
|
|
24
|
+
1. This word has multiple different pronunciations based on context (a heteronym). In that case, it may be possible resolve the pronunciations based on context, by using the preceding and succeeding words as indicators. This is supported by the lexicon in the `precededBy`, `notPrecededBy`, `succeededBy`, `notSucceededBy` properties.
|
|
25
|
+
1. An issue with model training, which may need to be forwarded to the original authors.
|
|
26
|
+
|
|
27
|
+
If the problem is serious, you can report it, and we'll see what we can do.
|
|
28
|
+
|
|
29
|
+
## Fork and make changes to the codebase
|
|
30
|
+
|
|
31
|
+
See guide for [setting up a development environment](Development.md).
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Notes about licensing
|
|
35
|
+
|
|
36
|
+
The code is currently licensed under GPL-3, mainly due to one of its core dependencies, `eSpeak-NG`, having this license.
|
|
37
|
+
|
|
38
|
+
In the future, I may want to re-license parts (or all) of the code to a more permissive license like MIT, if that turns out to be possible. If you make an external contribution, I would appreciate if you also agree to license it under the MIT license, so a future transition would be easier.
|
package/docs/Development.md
CHANGED
|
@@ -1,33 +1,107 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Setting up a development environment
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Here's a quick guide on how to set up a development environment for making and testing changes to the Echogarden codebase.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Related pages**:
|
|
6
|
+
* [How to help](Contributing.md)
|
|
7
|
+
* [Technical overview](Techincal.md)
|
|
8
|
+
* [Node.js API reference](API.md)
|
|
6
9
|
|
|
7
|
-
##
|
|
10
|
+
## Quick start
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
* Fork or clone the repository (`git clone https://github.com/echogarden-project/echogarden`)
|
|
13
|
+
* Ensure you have [Node.js](https://nodejs.org/en/download) installed
|
|
14
|
+
* Ensure you have TypeScript installed (`npm install typescript -g`)
|
|
15
|
+
* Run `npm install` in the project base directory
|
|
16
|
+
* Compile using `tsc .` at the project base directory
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
## Auto-compiling in Visual Studio Code
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
* You're using the macOS platform: I don't have access to a macOS machine, and thus almost no real testing has been done over that platform.
|
|
15
|
-
* You're using cloud services: There may be changes in the service that will require updating the code. I don't often test they work correctly, since my trial periods in Google, Microsoft and Amazon have all expired, thus testing requires me to use payed requests.
|
|
20
|
+
Create the `.vscode` subdirectory at the project base directory
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
Add a `.vscode/tasks.json` file to run the TypeScript compiler in watch mode:
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
// See http://go.microsoft.com/fwlink/?LinkId=733558
|
|
26
|
+
// for the documentation about the tasks.json format
|
|
27
|
+
"version": "2.0.0",
|
|
28
|
+
"command": "tsc.cmd",
|
|
29
|
+
"args": [
|
|
30
|
+
"-w",
|
|
31
|
+
"-p",
|
|
32
|
+
"."
|
|
33
|
+
],
|
|
34
|
+
"problemMatcher": "$tsc-watch",
|
|
35
|
+
"isBackground": true,
|
|
36
|
+
"tasks": [
|
|
37
|
+
{
|
|
38
|
+
"label": "node",
|
|
39
|
+
"type": "shell",
|
|
40
|
+
"command": "tsc",
|
|
41
|
+
"args": [
|
|
42
|
+
"-w",
|
|
43
|
+
"-p",
|
|
44
|
+
"."
|
|
45
|
+
],
|
|
46
|
+
"isBackground": true,
|
|
47
|
+
"problemMatcher": "$tsc-watch",
|
|
48
|
+
"group": {
|
|
49
|
+
"kind": "build",
|
|
50
|
+
"isDefault": true
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
18
56
|
|
|
19
|
-
##
|
|
57
|
+
## Running the local code
|
|
20
58
|
|
|
21
|
-
|
|
59
|
+
In the project directory, type:
|
|
22
60
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
61
|
+
```
|
|
62
|
+
npx echogarden speak "Hello World!"
|
|
63
|
+
```
|
|
26
64
|
|
|
27
|
-
|
|
65
|
+
Adding `npx` would start the CLI directly from the local code.
|
|
28
66
|
|
|
29
|
-
##
|
|
67
|
+
## Step-debugging in VS Code
|
|
30
68
|
|
|
31
|
-
|
|
69
|
+
Ensure the project is compiled (using the watch task above is highly recommended).
|
|
32
70
|
|
|
33
|
-
|
|
71
|
+
Add a `.vscode/launch.json` file to launch the CLI in debug mode:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"version": "0.2.0",
|
|
76
|
+
"configurations": [
|
|
77
|
+
{
|
|
78
|
+
"type": "node",
|
|
79
|
+
"request": "launch",
|
|
80
|
+
"name": "Launch Program",
|
|
81
|
+
"skipFiles": [
|
|
82
|
+
"<node_internals>/**"
|
|
83
|
+
],
|
|
84
|
+
"program": "${workspaceFolder}/dist/cli/CLIStarter.js",
|
|
85
|
+
"outputCapture": "std",
|
|
86
|
+
"console": "integratedTerminal",
|
|
87
|
+
"runtimeArgs": ["--no-warnings", "--no-experimental-fetch", "--experimental-wasi-unstable-preview1", "--trace-uncaught"],
|
|
88
|
+
|
|
89
|
+
"args": ["speak", "Hello World!", "--debug"]
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Press F5 to start debugging.
|
|
96
|
+
|
|
97
|
+
You can change `"args": ["speak", "Hello World!", "--debug"]` to any command line arguments you want to test. Adding the `--debug` CLI option ensures that errors are shown with full stack traces.
|
|
98
|
+
|
|
99
|
+
## Updating the options schema
|
|
100
|
+
|
|
101
|
+
If you add, modify or remove options from the API, that are exposed to the CLI, you should run:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
npm run generate-options-schema
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
To update the JSON schema used when parsing command line options in the CLI. Otherwise, the CLI may not recognize the modified option names or types.
|