@framers/agentos 0.1.46 → 0.1.47
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 +7 -7
- package/dist/cognitive_substrate/IGMI.d.ts +2 -0
- package/dist/cognitive_substrate/IGMI.d.ts.map +1 -1
- package/dist/cognitive_substrate/IGMI.js.map +1 -1
- package/dist/cognitive_substrate/personas/IPersonaDefinition.d.ts +2 -0
- package/dist/cognitive_substrate/personas/IPersonaDefinition.d.ts.map +1 -1
- package/dist/core/audio/AdaptiveVAD.d.ts +147 -0
- package/dist/core/audio/AdaptiveVAD.d.ts.map +1 -0
- package/dist/core/audio/AdaptiveVAD.js +239 -0
- package/dist/core/audio/AdaptiveVAD.js.map +1 -0
- package/dist/core/audio/AudioProcessor.d.ts +121 -0
- package/dist/core/audio/AudioProcessor.d.ts.map +1 -0
- package/dist/core/audio/AudioProcessor.js +299 -0
- package/dist/core/audio/AudioProcessor.js.map +1 -0
- package/dist/core/audio/EnvironmentalCalibrator.d.ts +187 -0
- package/dist/core/audio/EnvironmentalCalibrator.d.ts.map +1 -0
- package/dist/core/audio/EnvironmentalCalibrator.js +360 -0
- package/dist/core/audio/EnvironmentalCalibrator.js.map +1 -0
- package/dist/core/audio/SilenceDetector.d.ts +111 -0
- package/dist/core/audio/SilenceDetector.d.ts.map +1 -0
- package/dist/core/audio/SilenceDetector.js +178 -0
- package/dist/core/audio/SilenceDetector.js.map +1 -0
- package/dist/core/llm/IPromptEngine.d.ts +2 -0
- package/dist/core/llm/IPromptEngine.d.ts.map +1 -1
- package/dist/core/llm/IPromptEngine.js.map +1 -1
- package/dist/core/llm/providers/implementations/OpenAIProvider.d.ts.map +1 -1
- package/dist/core/llm/providers/implementations/OpenAIProvider.js +8 -1
- package/dist/core/llm/providers/implementations/OpenAIProvider.js.map +1 -1
- package/dist/extensions/ExtensionManager.d.ts.map +1 -1
- package/dist/extensions/ExtensionManager.js +9 -1
- package/dist/extensions/ExtensionManager.js.map +1 -1
- package/dist/extensions/types.d.ts +20 -2
- package/dist/extensions/types.d.ts.map +1 -1
- package/dist/extensions/types.js +4 -0
- package/dist/extensions/types.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/CognitiveMemoryManager.d.ts +133 -0
- package/dist/memory/CognitiveMemoryManager.d.ts.map +1 -0
- package/dist/memory/CognitiveMemoryManager.js +519 -0
- package/dist/memory/CognitiveMemoryManager.js.map +1 -0
- package/dist/memory/config.d.ts +135 -0
- package/dist/memory/config.d.ts.map +1 -0
- package/dist/memory/config.js +28 -0
- package/dist/memory/config.js.map +1 -0
- package/dist/memory/consolidation/ConsolidationPipeline.d.ts +70 -0
- package/dist/memory/consolidation/ConsolidationPipeline.d.ts.map +1 -0
- package/dist/memory/consolidation/ConsolidationPipeline.js +301 -0
- package/dist/memory/consolidation/ConsolidationPipeline.js.map +1 -0
- package/dist/memory/context/CompactionEngine.d.ts +21 -0
- package/dist/memory/context/CompactionEngine.d.ts.map +1 -0
- package/dist/memory/context/CompactionEngine.js +35 -0
- package/dist/memory/context/CompactionEngine.js.map +1 -0
- package/dist/memory/context/CompactionLog.d.ts +50 -0
- package/dist/memory/context/CompactionLog.d.ts.map +1 -0
- package/dist/memory/context/CompactionLog.js +139 -0
- package/dist/memory/context/CompactionLog.js.map +1 -0
- package/dist/memory/context/ContextWindowManager.d.ts +114 -0
- package/dist/memory/context/ContextWindowManager.d.ts.map +1 -0
- package/dist/memory/context/ContextWindowManager.js +225 -0
- package/dist/memory/context/ContextWindowManager.js.map +1 -0
- package/dist/memory/context/RollingSummaryChain.d.ts +53 -0
- package/dist/memory/context/RollingSummaryChain.d.ts.map +1 -0
- package/dist/memory/context/RollingSummaryChain.js +193 -0
- package/dist/memory/context/RollingSummaryChain.js.map +1 -0
- package/dist/memory/context/index.d.ts +15 -0
- package/dist/memory/context/index.d.ts.map +1 -0
- package/dist/memory/context/index.js +14 -0
- package/dist/memory/context/index.js.map +1 -0
- package/dist/memory/context/strategies/HierarchicalStrategy.d.ts +25 -0
- package/dist/memory/context/strategies/HierarchicalStrategy.d.ts.map +1 -0
- package/dist/memory/context/strategies/HierarchicalStrategy.js +240 -0
- package/dist/memory/context/strategies/HierarchicalStrategy.js.map +1 -0
- package/dist/memory/context/strategies/HybridStrategy.d.ts +26 -0
- package/dist/memory/context/strategies/HybridStrategy.d.ts.map +1 -0
- package/dist/memory/context/strategies/HybridStrategy.js +245 -0
- package/dist/memory/context/strategies/HybridStrategy.js.map +1 -0
- package/dist/memory/context/strategies/SlidingSummaryStrategy.d.ts +22 -0
- package/dist/memory/context/strategies/SlidingSummaryStrategy.d.ts.map +1 -0
- package/dist/memory/context/strategies/SlidingSummaryStrategy.js +203 -0
- package/dist/memory/context/strategies/SlidingSummaryStrategy.js.map +1 -0
- package/dist/memory/context/types.d.ts +120 -0
- package/dist/memory/context/types.d.ts.map +1 -0
- package/dist/memory/context/types.js +17 -0
- package/dist/memory/context/types.js.map +1 -0
- package/dist/memory/decay/DecayModel.d.ts +87 -0
- package/dist/memory/decay/DecayModel.d.ts.map +1 -0
- package/dist/memory/decay/DecayModel.js +117 -0
- package/dist/memory/decay/DecayModel.js.map +1 -0
- package/dist/memory/decay/RetrievalPriorityScorer.d.ts +63 -0
- package/dist/memory/decay/RetrievalPriorityScorer.d.ts.map +1 -0
- package/dist/memory/decay/RetrievalPriorityScorer.js +110 -0
- package/dist/memory/decay/RetrievalPriorityScorer.js.map +1 -0
- package/dist/memory/encoding/ContentFeatureDetector.d.ts +37 -0
- package/dist/memory/encoding/ContentFeatureDetector.d.ts.map +1 -0
- package/dist/memory/encoding/ContentFeatureDetector.js +176 -0
- package/dist/memory/encoding/ContentFeatureDetector.js.map +1 -0
- package/dist/memory/encoding/EncodingModel.d.ts +67 -0
- package/dist/memory/encoding/EncodingModel.d.ts.map +1 -0
- package/dist/memory/encoding/EncodingModel.js +171 -0
- package/dist/memory/encoding/EncodingModel.js.map +1 -0
- package/dist/memory/extension/CognitiveMemoryExtension.d.ts +18 -0
- package/dist/memory/extension/CognitiveMemoryExtension.d.ts.map +1 -0
- package/dist/memory/extension/CognitiveMemoryExtension.js +131 -0
- package/dist/memory/extension/CognitiveMemoryExtension.js.map +1 -0
- package/dist/memory/graph/GraphologyMemoryGraph.d.ts +29 -0
- package/dist/memory/graph/GraphologyMemoryGraph.d.ts.map +1 -0
- package/dist/memory/graph/GraphologyMemoryGraph.js +224 -0
- package/dist/memory/graph/GraphologyMemoryGraph.js.map +1 -0
- package/dist/memory/graph/IMemoryGraph.d.ts +70 -0
- package/dist/memory/graph/IMemoryGraph.d.ts.map +1 -0
- package/dist/memory/graph/IMemoryGraph.js +15 -0
- package/dist/memory/graph/IMemoryGraph.js.map +1 -0
- package/dist/memory/graph/KnowledgeGraphMemoryGraph.d.ts +38 -0
- package/dist/memory/graph/KnowledgeGraphMemoryGraph.d.ts.map +1 -0
- package/dist/memory/graph/KnowledgeGraphMemoryGraph.js +264 -0
- package/dist/memory/graph/KnowledgeGraphMemoryGraph.js.map +1 -0
- package/dist/memory/graph/SpreadingActivation.d.ts +36 -0
- package/dist/memory/graph/SpreadingActivation.d.ts.map +1 -0
- package/dist/memory/graph/SpreadingActivation.js +100 -0
- package/dist/memory/graph/SpreadingActivation.js.map +1 -0
- package/dist/memory/index.d.ts +52 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +43 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/observation/MemoryObserver.d.ts +59 -0
- package/dist/memory/observation/MemoryObserver.d.ts.map +1 -0
- package/dist/memory/observation/MemoryObserver.js +136 -0
- package/dist/memory/observation/MemoryObserver.js.map +1 -0
- package/dist/memory/observation/MemoryReflector.d.ts +51 -0
- package/dist/memory/observation/MemoryReflector.d.ts.map +1 -0
- package/dist/memory/observation/MemoryReflector.js +184 -0
- package/dist/memory/observation/MemoryReflector.js.map +1 -0
- package/dist/memory/observation/ObservationBuffer.d.ts +51 -0
- package/dist/memory/observation/ObservationBuffer.d.ts.map +1 -0
- package/dist/memory/observation/ObservationBuffer.js +81 -0
- package/dist/memory/observation/ObservationBuffer.js.map +1 -0
- package/dist/memory/prompt/MemoryFormatters.d.ts +22 -0
- package/dist/memory/prompt/MemoryFormatters.d.ts.map +1 -0
- package/dist/memory/prompt/MemoryFormatters.js +113 -0
- package/dist/memory/prompt/MemoryFormatters.js.map +1 -0
- package/dist/memory/prompt/MemoryPromptAssembler.d.ts +40 -0
- package/dist/memory/prompt/MemoryPromptAssembler.d.ts.map +1 -0
- package/dist/memory/prompt/MemoryPromptAssembler.js +180 -0
- package/dist/memory/prompt/MemoryPromptAssembler.js.map +1 -0
- package/dist/memory/prospective/ProspectiveMemoryManager.d.ts +83 -0
- package/dist/memory/prospective/ProspectiveMemoryManager.d.ts.map +1 -0
- package/dist/memory/prospective/ProspectiveMemoryManager.js +128 -0
- package/dist/memory/prospective/ProspectiveMemoryManager.js.map +1 -0
- package/dist/memory/store/MemoryStore.d.ts +76 -0
- package/dist/memory/store/MemoryStore.d.ts.map +1 -0
- package/dist/memory/store/MemoryStore.js +320 -0
- package/dist/memory/store/MemoryStore.js.map +1 -0
- package/dist/memory/types.d.ts +184 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +14 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/working/CognitiveWorkingMemory.d.ts +87 -0
- package/dist/memory/working/CognitiveWorkingMemory.d.ts.map +1 -0
- package/dist/memory/working/CognitiveWorkingMemory.js +230 -0
- package/dist/memory/working/CognitiveWorkingMemory.js.map +1 -0
- package/dist/rag/EmbeddingManager.d.ts.map +1 -1
- package/dist/rag/EmbeddingManager.js +8 -1
- package/dist/rag/EmbeddingManager.js.map +1 -1
- package/dist/speech/SpeechProviderRegistry.d.ts +17 -0
- package/dist/speech/SpeechProviderRegistry.d.ts.map +1 -0
- package/dist/speech/SpeechProviderRegistry.js +47 -0
- package/dist/speech/SpeechProviderRegistry.js.map +1 -0
- package/dist/speech/SpeechRuntime.d.ts +28 -0
- package/dist/speech/SpeechRuntime.d.ts.map +1 -0
- package/dist/speech/SpeechRuntime.js +138 -0
- package/dist/speech/SpeechRuntime.js.map +1 -0
- package/dist/speech/SpeechSession.d.ts +37 -0
- package/dist/speech/SpeechSession.d.ts.map +1 -0
- package/dist/speech/SpeechSession.js +285 -0
- package/dist/speech/SpeechSession.js.map +1 -0
- package/dist/speech/audio.d.ts +3 -0
- package/dist/speech/audio.d.ts.map +1 -0
- package/dist/speech/audio.js +39 -0
- package/dist/speech/audio.js.map +1 -0
- package/dist/speech/index.d.ts +11 -0
- package/dist/speech/index.d.ts.map +1 -0
- package/dist/speech/index.js +11 -0
- package/dist/speech/index.js.map +1 -0
- package/dist/speech/providerCatalog.d.ts +7 -0
- package/dist/speech/providerCatalog.d.ts.map +1 -0
- package/dist/speech/providerCatalog.js +243 -0
- package/dist/speech/providerCatalog.js.map +1 -0
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.d.ts +20 -0
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.d.ts.map +1 -0
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.js +29 -0
- package/dist/speech/providers/BuiltInAdaptiveVadProvider.js.map +1 -0
- package/dist/speech/providers/ElevenLabsTextToSpeechProvider.d.ts +20 -0
- package/dist/speech/providers/ElevenLabsTextToSpeechProvider.d.ts.map +1 -0
- package/dist/speech/providers/ElevenLabsTextToSpeechProvider.js +95 -0
- package/dist/speech/providers/ElevenLabsTextToSpeechProvider.js.map +1 -0
- package/dist/speech/providers/OpenAITextToSpeechProvider.d.ts +20 -0
- package/dist/speech/providers/OpenAITextToSpeechProvider.d.ts.map +1 -0
- package/dist/speech/providers/OpenAITextToSpeechProvider.js +75 -0
- package/dist/speech/providers/OpenAITextToSpeechProvider.js.map +1 -0
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.d.ts +18 -0
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.d.ts.map +1 -0
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.js +109 -0
- package/dist/speech/providers/OpenAIWhisperSpeechToTextProvider.js.map +1 -0
- package/dist/speech/types.d.ts +270 -0
- package/dist/speech/types.d.ts.map +1 -0
- package/dist/speech/types.js +2 -0
- package/dist/speech/types.js.map +1 -0
- package/package.json +22 -2
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
// backend/agentos/core/audio/EnvironmentalCalibrator.ts
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
/**
|
|
4
|
+
* EnvironmentalCalibrator (Web Version) - Adapts to acoustic environment in real-time
|
|
5
|
+
* using Web Audio APIs for initial calibration and processing raw frames for continuous updates.
|
|
6
|
+
*/
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
|
8
|
+
export class EnvironmentalCalibrator extends EventEmitter {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new EnvironmentalCalibrator instance.
|
|
11
|
+
* @param {CalibrationConfig} config - Configuration options.
|
|
12
|
+
*/
|
|
13
|
+
constructor(config = {}) {
|
|
14
|
+
super();
|
|
15
|
+
this.currentProfile = null;
|
|
16
|
+
this.profileHistory = [];
|
|
17
|
+
this.rmsValuesForContinuousAdapt = []; // Stores RMS of recent frames for continuous adaptation
|
|
18
|
+
this.lastProfileUpdateTimeMs = Date.now();
|
|
19
|
+
this.lastVoiceActivityTimeMs = Date.now(); // For resetting backoff
|
|
20
|
+
this.isDuringInitialCalibration = false;
|
|
21
|
+
// Web Audio API related properties for initial calibration
|
|
22
|
+
this.calibrationAudioContext = null;
|
|
23
|
+
this.calibrationSourceNode = null;
|
|
24
|
+
this.calibrationProcessorNode = null;
|
|
25
|
+
this.calibrationAnalyserNode = null;
|
|
26
|
+
this.config = {
|
|
27
|
+
initialCalibrationMs: config.initialCalibrationMs || 3000,
|
|
28
|
+
calibrationBufferSize: config.calibrationBufferSize || 4096,
|
|
29
|
+
minRmsSamplesForContinuousUpdate: config.minRmsSamplesForContinuousUpdate || 50,
|
|
30
|
+
initialUpdateIntervalMs: config.initialUpdateIntervalMs || 1000,
|
|
31
|
+
backoffMultiplier: config.backoffMultiplier || 1.5,
|
|
32
|
+
maxBackoffIntervalMs: config.maxBackoffIntervalMs || 30000,
|
|
33
|
+
minBackoffIntervalMs: config.minBackoffIntervalMs || 500,
|
|
34
|
+
rmsHistoryBufferSize: config.rmsHistoryBufferSize || 50,
|
|
35
|
+
thresholdSensitivityFactor: config.thresholdSensitivityFactor || 1.0,
|
|
36
|
+
enableFrequencyAnalysis: config.enableFrequencyAnalysis ?? true,
|
|
37
|
+
fftSize: config.fftSize || 256,
|
|
38
|
+
sampleRate: config.sampleRate || 16000,
|
|
39
|
+
};
|
|
40
|
+
this.currentBackoffIntervalMs = this.config.initialUpdateIntervalMs;
|
|
41
|
+
this.anomalyDetector = new AnomalyDetector();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Performs initial environment calibration using a MediaStream.
|
|
45
|
+
* Sets up a temporary Web Audio pipeline to analyze the stream.
|
|
46
|
+
* @param {MediaStream} audioStream - The live audio input stream for calibration.
|
|
47
|
+
* @returns {Promise<NoiseProfile>} A promise that resolves with the initial noise profile,
|
|
48
|
+
* or rejects if calibration fails.
|
|
49
|
+
*/
|
|
50
|
+
async calibrate(audioStream) {
|
|
51
|
+
if (this.isDuringInitialCalibration) {
|
|
52
|
+
console.warn("Calibration is already in progress.");
|
|
53
|
+
return Promise.reject(new Error("Calibration already in progress."));
|
|
54
|
+
}
|
|
55
|
+
console.log(`🎤 Starting environmental calibration for ${this.config.initialCalibrationMs}ms (Web Audio)...`);
|
|
56
|
+
this.isDuringInitialCalibration = true;
|
|
57
|
+
this.emit('calibration:started');
|
|
58
|
+
const collectedRmsSamples = [];
|
|
59
|
+
const collectedFrequencySamples = [];
|
|
60
|
+
let processedDuration = 0;
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
try {
|
|
63
|
+
this.calibrationAudioContext = new (window.AudioContext || window.webkitAudioContext)({
|
|
64
|
+
sampleRate: this.config.sampleRate, // Attempt to use configured sample rate
|
|
65
|
+
});
|
|
66
|
+
// Check actual sample rate
|
|
67
|
+
const actualSampleRate = this.calibrationAudioContext.sampleRate;
|
|
68
|
+
if (Math.abs(actualSampleRate - this.config.sampleRate) > 100) {
|
|
69
|
+
console.warn(`Calibrator: AudioContext using sample rate ${actualSampleRate}Hz, configured was ${this.config.sampleRate}Hz.`);
|
|
70
|
+
}
|
|
71
|
+
this.calibrationSourceNode = this.calibrationAudioContext.createMediaStreamSource(audioStream);
|
|
72
|
+
this.calibrationProcessorNode = this.calibrationAudioContext.createScriptProcessor(this.config.calibrationBufferSize, 1, // input channels
|
|
73
|
+
1 // output channels
|
|
74
|
+
);
|
|
75
|
+
if (this.config.enableFrequencyAnalysis) {
|
|
76
|
+
this.calibrationAnalyserNode = this.calibrationAudioContext.createAnalyser();
|
|
77
|
+
this.calibrationAnalyserNode.fftSize = this.config.fftSize;
|
|
78
|
+
this.calibrationSourceNode.connect(this.calibrationAnalyserNode);
|
|
79
|
+
this.calibrationAnalyserNode.connect(this.calibrationProcessorNode);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this.calibrationSourceNode.connect(this.calibrationProcessorNode);
|
|
83
|
+
}
|
|
84
|
+
this.calibrationProcessorNode.connect(this.calibrationAudioContext.destination); // Keep graph alive
|
|
85
|
+
this.calibrationProcessorNode.onaudioprocess = (event) => {
|
|
86
|
+
if (!this.isDuringInitialCalibration)
|
|
87
|
+
return; // Stop processing if calibration ended prematurely
|
|
88
|
+
const inputData = event.inputBuffer.getChannelData(0);
|
|
89
|
+
const frameDuration = event.inputBuffer.duration * 1000; // Duration of this chunk in ms
|
|
90
|
+
processedDuration += frameDuration;
|
|
91
|
+
const rms = this.calculateRMS(inputData);
|
|
92
|
+
collectedRmsSamples.push(rms);
|
|
93
|
+
if (this.config.enableFrequencyAnalysis && this.calibrationAnalyserNode) {
|
|
94
|
+
const freqData = new Float32Array(this.calibrationAnalyserNode.frequencyBinCount);
|
|
95
|
+
this.calibrationAnalyserNode.getFloatFrequencyData(freqData); // Get dB values
|
|
96
|
+
collectedFrequencySamples.push(freqData);
|
|
97
|
+
}
|
|
98
|
+
const progress = Math.min(processedDuration / this.config.initialCalibrationMs, 1);
|
|
99
|
+
this.emit('calibration:progress', progress, rms);
|
|
100
|
+
if (processedDuration >= this.config.initialCalibrationMs) {
|
|
101
|
+
this.isDuringInitialCalibration = false; // Mark as finished
|
|
102
|
+
// Finalize and clean up immediately after flag is set
|
|
103
|
+
try {
|
|
104
|
+
const profile = this.analyzeCalibrationSamples(collectedRmsSamples, collectedFrequencySamples);
|
|
105
|
+
this.currentProfile = profile;
|
|
106
|
+
this.profileHistory.push(profile);
|
|
107
|
+
this.lastProfileUpdateTimeMs = Date.now();
|
|
108
|
+
this.rmsValuesForContinuousAdapt = collectedRmsSamples.slice(-this.config.rmsHistoryBufferSize); // Pre-fill buffer
|
|
109
|
+
this.emit('calibration:complete', profile);
|
|
110
|
+
console.log('✅ Calibration complete (Web Audio):', {
|
|
111
|
+
environment: profile.environmentType,
|
|
112
|
+
baselineRMS: profile.baselineRMS.toFixed(4),
|
|
113
|
+
});
|
|
114
|
+
resolve(profile);
|
|
115
|
+
}
|
|
116
|
+
catch (analysisError) {
|
|
117
|
+
console.error("Error analyzing calibration data:", analysisError);
|
|
118
|
+
this.emit('calibration:error', analysisError);
|
|
119
|
+
reject(analysisError);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
this.cleanupCalibrationAudioNodes();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error('❌ Error setting up Web Audio for calibration:', error);
|
|
129
|
+
this.isDuringInitialCalibration = false;
|
|
130
|
+
this.emit('calibration:error', error);
|
|
131
|
+
this.cleanupCalibrationAudioNodes(); // Ensure cleanup on setup error
|
|
132
|
+
reject(error);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/** Cleans up Web Audio nodes used specifically for initial calibration. */
|
|
137
|
+
cleanupCalibrationAudioNodes() {
|
|
138
|
+
this.calibrationProcessorNode?.disconnect();
|
|
139
|
+
this.calibrationAnalyserNode?.disconnect();
|
|
140
|
+
this.calibrationSourceNode?.disconnect();
|
|
141
|
+
// It's good practice to close the AudioContext if it was created solely for calibration
|
|
142
|
+
// and is not shared. If shared, this responsibility lies elsewhere.
|
|
143
|
+
if (this.calibrationAudioContext && this.calibrationAudioContext.state !== 'closed') {
|
|
144
|
+
this.calibrationAudioContext.close().catch(e => console.warn("Error closing calibration AudioContext:", e));
|
|
145
|
+
}
|
|
146
|
+
this.calibrationAudioContext = null;
|
|
147
|
+
this.calibrationProcessorNode = null;
|
|
148
|
+
this.calibrationAnalyserNode = null;
|
|
149
|
+
this.calibrationSourceNode = null;
|
|
150
|
+
// console.debug("Calibration audio nodes cleaned up.");
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Analyzes collected RMS and frequency samples to generate a NoiseProfile.
|
|
154
|
+
* @param rmsSamples - Array of RMS values from calibration.
|
|
155
|
+
* @param frequencySamples - Array of frequency data arrays from calibration.
|
|
156
|
+
* @returns {NoiseProfile} The calculated noise profile.
|
|
157
|
+
*/
|
|
158
|
+
analyzeCalibrationSamples(rmsSamples, frequencySamples) {
|
|
159
|
+
if (rmsSamples.length === 0) {
|
|
160
|
+
throw new Error("Cannot analyze empty RMS samples for calibration.");
|
|
161
|
+
}
|
|
162
|
+
const sortedRms = [...rmsSamples].sort((a, b) => a - b);
|
|
163
|
+
const baselineRMS = this.calculatePercentile(sortedRms, 0.25); // Robust baseline
|
|
164
|
+
const peakRMS = this.calculatePercentile(sortedRms, 0.95);
|
|
165
|
+
const noiseStdDev = this.calculateStdDev(rmsSamples, baselineRMS);
|
|
166
|
+
let avgFrequencyProfile = undefined;
|
|
167
|
+
if (this.config.enableFrequencyAnalysis && frequencySamples.length > 0 && this.calibrationAnalyserNode) {
|
|
168
|
+
const numBins = this.calibrationAnalyserNode.frequencyBinCount;
|
|
169
|
+
avgFrequencyProfile = new Float32Array(numBins);
|
|
170
|
+
for (let i = 0; i < numBins; i++) {
|
|
171
|
+
let sumForBin = 0;
|
|
172
|
+
for (const freqSample of frequencySamples) {
|
|
173
|
+
sumForBin += freqSample[i]; // These are typically dB values
|
|
174
|
+
}
|
|
175
|
+
avgFrequencyProfile[i] = sumForBin / frequencySamples.length;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const environmentType = this.classifyEnvironment(baselineRMS, peakRMS, noiseStdDev);
|
|
179
|
+
const { speechThreshold, silenceThreshold } = this.calculateAdaptiveThresholds(baselineRMS, peakRMS, noiseStdDev, environmentType);
|
|
180
|
+
return {
|
|
181
|
+
baselineRMS,
|
|
182
|
+
peakRMS,
|
|
183
|
+
noiseStdDev,
|
|
184
|
+
frequencyProfile: avgFrequencyProfile,
|
|
185
|
+
environmentType,
|
|
186
|
+
confidenceScore: this.calculateConfidence(rmsSamples, noiseStdDev),
|
|
187
|
+
timestamp: Date.now(),
|
|
188
|
+
suggestedSpeechThreshold: speechThreshold,
|
|
189
|
+
suggestedSilenceThreshold: silenceThreshold,
|
|
190
|
+
framesAnalyzedCount: rmsSamples.length,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Processes a single audio frame for continuous adaptation after initial calibration.
|
|
195
|
+
* @param {Float32Array} audioFrame - A chunk of raw audio data (PCM).
|
|
196
|
+
*/
|
|
197
|
+
continuousAdaptation(audioFrame) {
|
|
198
|
+
if (this.isDuringInitialCalibration || !this.currentProfile) {
|
|
199
|
+
// console.warn("Calibrator: Cannot perform continuous adaptation during initial calibration or without a profile.");
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (!audioFrame || audioFrame.length === 0)
|
|
203
|
+
return;
|
|
204
|
+
const rms = this.calculateRMS(audioFrame);
|
|
205
|
+
this.addToRmsHistory(rms);
|
|
206
|
+
const now = Date.now();
|
|
207
|
+
const timeSinceLastUpdate = now - this.lastProfileUpdateTimeMs;
|
|
208
|
+
if (timeSinceLastUpdate >= this.currentBackoffIntervalMs && this.rmsValuesForContinuousAdapt.length >= this.config.minRmsSamplesForContinuousUpdate) {
|
|
209
|
+
const avgRMSInHistory = this.rmsValuesForContinuousAdapt.reduce((s, v) => s + v, 0) / this.rmsValuesForContinuousAdapt.length;
|
|
210
|
+
const deviationFromProfile = Math.abs(avgRMSInHistory - this.currentProfile.baselineRMS);
|
|
211
|
+
// More sensitive change detection for continuous adaptation: 30% change in baseline or if std dev changes a lot
|
|
212
|
+
const significantChangeThreshold = this.currentProfile.baselineRMS * 0.3;
|
|
213
|
+
const currentStdDev = this.calculateStdDev(this.rmsValuesForContinuousAdapt);
|
|
214
|
+
const stdDevChange = Math.abs(currentStdDev - this.currentProfile.noiseStdDev) / (this.currentProfile.noiseStdDev || 0.001);
|
|
215
|
+
if (deviationFromProfile > significantChangeThreshold || stdDevChange > 0.5) { // Or 50% change in std dev
|
|
216
|
+
// Re-calculate profile based on current rmsValuesForContinuousAdapt
|
|
217
|
+
// For frequency profile, we'd ideally need a way to get it from the current frame if enabled,
|
|
218
|
+
// or decide not to update it during continuous adaptation without a live AnalyserNode.
|
|
219
|
+
// For simplicity, continuous adaptation here focuses on RMS-based metrics.
|
|
220
|
+
const updatedProfile = this.updateProfileFromRmsHistory(this.rmsValuesForContinuousAdapt, this.currentProfile);
|
|
221
|
+
const oldEnvironment = this.currentProfile.environmentType;
|
|
222
|
+
this.currentProfile = updatedProfile;
|
|
223
|
+
this.profileHistory.push(updatedProfile);
|
|
224
|
+
this.emit('profile:updated', updatedProfile);
|
|
225
|
+
if (oldEnvironment !== updatedProfile.environmentType) {
|
|
226
|
+
this.emit('environment:changed', updatedProfile.environmentType, oldEnvironment, updatedProfile);
|
|
227
|
+
console.log(`🔄 Environment changed (continuous): ${oldEnvironment} → ${updatedProfile.environmentType}`);
|
|
228
|
+
}
|
|
229
|
+
this.currentBackoffIntervalMs = this.config.minBackoffIntervalMs; // Reset backoff
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
this.currentBackoffIntervalMs = Math.min(this.currentBackoffIntervalMs * this.config.backoffMultiplier, this.config.maxBackoffIntervalMs);
|
|
233
|
+
}
|
|
234
|
+
this.lastProfileUpdateTimeMs = now;
|
|
235
|
+
}
|
|
236
|
+
this.detectAnomalies(rms);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Helper to update profile based on current RMS history (primarily for continuous adaptation).
|
|
240
|
+
*/
|
|
241
|
+
updateProfileFromRmsHistory(rmsHistory, baseProfile) {
|
|
242
|
+
const sortedRms = [...rmsHistory].sort((a, b) => a - b);
|
|
243
|
+
const baselineRMS = this.calculatePercentile(sortedRms, 0.25);
|
|
244
|
+
const peakRMS = this.calculatePercentile(sortedRms, 0.95);
|
|
245
|
+
const noiseStdDev = this.calculateStdDev(rmsHistory, baselineRMS);
|
|
246
|
+
const environmentType = this.classifyEnvironment(baselineRMS, peakRMS, noiseStdDev);
|
|
247
|
+
const { speechThreshold, silenceThreshold } = this.calculateAdaptiveThresholds(baselineRMS, peakRMS, noiseStdDev, environmentType);
|
|
248
|
+
// Note: Frequency profile is not updated here unless a live AnalyserNode frame is passed.
|
|
249
|
+
// It retains the frequency profile from the initial calibration or last full update.
|
|
250
|
+
return {
|
|
251
|
+
...baseProfile, // Retain other fields like original frequencyProfile
|
|
252
|
+
baselineRMS,
|
|
253
|
+
peakRMS,
|
|
254
|
+
noiseStdDev,
|
|
255
|
+
environmentType,
|
|
256
|
+
suggestedSpeechThreshold: speechThreshold,
|
|
257
|
+
suggestedSilenceThreshold: silenceThreshold,
|
|
258
|
+
confidenceScore: this.calculateConfidence(rmsHistory, noiseStdDev),
|
|
259
|
+
timestamp: Date.now(),
|
|
260
|
+
framesAnalyzedCount: rmsHistory.length,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
/** Classifies the environment based on noise characteristics. */
|
|
264
|
+
classifyEnvironment(baselineRMS, peakRMS, stdDev) {
|
|
265
|
+
const dynamicRange = peakRMS - baselineRMS;
|
|
266
|
+
const variability = baselineRMS > 0.0001 ? stdDev / baselineRMS : stdDev / 0.0001;
|
|
267
|
+
if (baselineRMS < 0.008 && dynamicRange < 0.02 && variability < 0.5)
|
|
268
|
+
return 'quiet';
|
|
269
|
+
if (baselineRMS < 0.025 && dynamicRange < 0.05 && variability < 0.7)
|
|
270
|
+
return 'normal';
|
|
271
|
+
if (baselineRMS < 0.05 || dynamicRange < 0.1 || variability > 0.6)
|
|
272
|
+
return 'noisy';
|
|
273
|
+
return 'very_noisy';
|
|
274
|
+
}
|
|
275
|
+
/** Calculates adaptive speech and silence thresholds. */
|
|
276
|
+
calculateAdaptiveThresholds(baselineRMS, peakRMS, stdDev, environment) {
|
|
277
|
+
const multipliers = {
|
|
278
|
+
quiet: { speechFactor: 2.8, silenceFactor: 1.8, stdDevFactor: 1.2 },
|
|
279
|
+
normal: { speechFactor: 3.2, silenceFactor: 2.0, stdDevFactor: 1.5 },
|
|
280
|
+
noisy: { speechFactor: 3.8, silenceFactor: 2.5, stdDevFactor: 1.8 },
|
|
281
|
+
very_noisy: { speechFactor: 4.5, silenceFactor: 3.0, stdDevFactor: 2.2 }
|
|
282
|
+
};
|
|
283
|
+
const envConfig = multipliers[environment];
|
|
284
|
+
const adaptiveMargin = stdDev * envConfig.stdDevFactor * this.config.thresholdSensitivityFactor;
|
|
285
|
+
const speechThreshold = baselineRMS * envConfig.speechFactor * this.config.thresholdSensitivityFactor + adaptiveMargin;
|
|
286
|
+
const silenceThreshold = baselineRMS * envConfig.silenceFactor * this.config.thresholdSensitivityFactor + adaptiveMargin / 2;
|
|
287
|
+
const minSpeechOverSilence = Math.max(baselineRMS * 1.1, 0.001);
|
|
288
|
+
const finalSilenceThreshold = Math.max(silenceThreshold, baselineRMS + 0.0005);
|
|
289
|
+
const finalSpeechThreshold = Math.max(speechThreshold, finalSilenceThreshold + minSpeechOverSilence);
|
|
290
|
+
return { speechThreshold: finalSpeechThreshold, silenceThreshold: finalSilenceThreshold };
|
|
291
|
+
}
|
|
292
|
+
detectAnomalies(currentFrameRms) {
|
|
293
|
+
const anomalies = this.anomalyDetector.detect(currentFrameRms, this.currentProfile, this.rmsValuesForContinuousAdapt);
|
|
294
|
+
anomalies.forEach(anomaly => {
|
|
295
|
+
this.emit('anomaly:detected', anomaly.type, anomaly.details, this.currentProfile);
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
/** Records voice activity detection to reset backoff. */
|
|
299
|
+
onVoiceActivityDetected() {
|
|
300
|
+
this.lastVoiceActivityTimeMs = Date.now();
|
|
301
|
+
this.currentBackoffIntervalMs = this.config.minBackoffIntervalMs;
|
|
302
|
+
}
|
|
303
|
+
getCurrentProfile() {
|
|
304
|
+
return this.currentProfile ? { ...this.currentProfile } : null; // Return a copy
|
|
305
|
+
}
|
|
306
|
+
addToRmsHistory(rms) {
|
|
307
|
+
this.rmsValuesForContinuousAdapt.push(rms);
|
|
308
|
+
if (this.rmsValuesForContinuousAdapt.length > this.config.rmsHistoryBufferSize) {
|
|
309
|
+
this.rmsValuesForContinuousAdapt.shift();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
calculateRMS(audioFrame) {
|
|
313
|
+
let sumOfSquares = 0;
|
|
314
|
+
for (let i = 0; i < audioFrame.length; i++)
|
|
315
|
+
sumOfSquares += audioFrame[i] * audioFrame[i];
|
|
316
|
+
return Math.sqrt(sumOfSquares / audioFrame.length);
|
|
317
|
+
}
|
|
318
|
+
calculatePercentile(sortedData, percentile) {
|
|
319
|
+
if (sortedData.length === 0)
|
|
320
|
+
return 0;
|
|
321
|
+
const index = Math.floor(sortedData.length * percentile);
|
|
322
|
+
return sortedData[Math.min(index, sortedData.length - 1)];
|
|
323
|
+
}
|
|
324
|
+
calculateStdDev(data, mean) {
|
|
325
|
+
if (data.length < 2)
|
|
326
|
+
return 0;
|
|
327
|
+
const m = mean !== undefined ? mean : data.reduce((s, v) => s + v, 0) / data.length;
|
|
328
|
+
const variance = data.reduce((acc, val) => acc + (val - m) ** 2, 0) / data.length;
|
|
329
|
+
return Math.sqrt(variance);
|
|
330
|
+
}
|
|
331
|
+
calculateConfidence(rmsValues, stdDev) {
|
|
332
|
+
if (rmsValues.length === 0)
|
|
333
|
+
return 0;
|
|
334
|
+
const dataQuantityFactor = Math.min(rmsValues.length / this.config.rmsHistoryBufferSize, 1.0); // For continuous, or initialCalibrationFrames for initial
|
|
335
|
+
const meanRms = rmsValues.reduce((s, v) => s + v, 0) / rmsValues.length;
|
|
336
|
+
let stabilityFactor = 0.5;
|
|
337
|
+
if (meanRms > 0.0001)
|
|
338
|
+
stabilityFactor = Math.max(0, 1 - (stdDev / meanRms));
|
|
339
|
+
if (meanRms < 0.01 && stdDev < 0.005)
|
|
340
|
+
stabilityFactor = Math.max(stabilityFactor, 0.75);
|
|
341
|
+
return (dataQuantityFactor * 0.6 + stabilityFactor * 0.4);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/** AnomalyDetector (simplified for client-side). */
|
|
345
|
+
class AnomalyDetector {
|
|
346
|
+
detect(currentRMS, profile, _rmsHistory) {
|
|
347
|
+
if (!profile)
|
|
348
|
+
return [];
|
|
349
|
+
const anomalies = [];
|
|
350
|
+
if (currentRMS > profile.peakRMS * 2.5 && currentRMS > 0.05) {
|
|
351
|
+
anomalies.push({ type: 'sudden_loud_noise', details: { level: currentRMS, profilePeak: profile.peakRMS } });
|
|
352
|
+
}
|
|
353
|
+
if (profile.environmentType !== 'quiet' && currentRMS < profile.baselineRMS * 0.1 && profile.baselineRMS > 0.005) {
|
|
354
|
+
anomalies.push({ type: 'sudden_silence_or_mute', details: { level: currentRMS, profileBaseline: profile.baselineRMS } });
|
|
355
|
+
}
|
|
356
|
+
// More advanced anomaly detection could be added here.
|
|
357
|
+
return anomalies;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=EnvironmentalCalibrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentalCalibrator.js","sourceRoot":"","sources":["../../../src/core/audio/EnvironmentalCalibrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { VADResult } from './AdaptiveVAD';
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Intelligent silence detection for continuous listening scenarios.
|
|
5
|
+
* Interprets events and states from AdaptiveVAD to determine meaningful silences
|
|
6
|
+
* like pauses and utterance endings, suitable for a web-based client.
|
|
7
|
+
* @module agentos/core/audio/SilenceDetector
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for the SilenceDetector.
|
|
11
|
+
*/
|
|
12
|
+
export interface SilenceDetectorConfig {
|
|
13
|
+
/**
|
|
14
|
+
* Minimum duration of continuous silence (ms) after speech has ended
|
|
15
|
+
* to be considered a "significant pause". This might indicate the user is thinking
|
|
16
|
+
* or expecting a response.
|
|
17
|
+
* @default 1500 ms
|
|
18
|
+
*/
|
|
19
|
+
significantPauseThresholdMs?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Maximum duration of continuous silence (ms) after speech has ended
|
|
22
|
+
* before considering the user's utterance fully complete.
|
|
23
|
+
* This should typically be longer than `significantPauseThresholdMs`.
|
|
24
|
+
* @default 3000 ms
|
|
25
|
+
*/
|
|
26
|
+
utteranceEndThresholdMs?: number;
|
|
27
|
+
/**
|
|
28
|
+
* After VAD signals `speech_start`, how long (ms) must silence persist
|
|
29
|
+
* before it's considered for `significant_pause` or `utterance_end`.
|
|
30
|
+
* This prevents cutting off very short speech segments immediately if followed by silence.
|
|
31
|
+
* Should be less than `significantPauseThresholdMs`.
|
|
32
|
+
* @default 500 ms
|
|
33
|
+
*/
|
|
34
|
+
minSilenceTimeToConsiderAfterSpeech?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Polling interval in milliseconds to check silence duration if no new VAD events occur.
|
|
37
|
+
* This ensures long silences are detected even if VAD remains in a 'no_voice_activity' state.
|
|
38
|
+
* @default 250 ms
|
|
39
|
+
*/
|
|
40
|
+
silenceCheckIntervalMs?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Events emitted by the SilenceDetector.
|
|
44
|
+
*/
|
|
45
|
+
export interface SilenceDetectorEvents {
|
|
46
|
+
/** Emitted when a significant pause is detected after speech. */
|
|
47
|
+
'significant_pause_detected': (pauseDurationMs: number) => void;
|
|
48
|
+
/** Emitted when an utterance is considered ended due to prolonged silence after speech. */
|
|
49
|
+
'utterance_end_detected': (totalSilenceDurationMs: number) => void;
|
|
50
|
+
/** Emitted when VAD indicates silence immediately following a speech segment. */
|
|
51
|
+
'post_speech_silence_started': () => void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* SilenceDetector - Interprets VAD events to detect meaningful conversational silences.
|
|
55
|
+
*/
|
|
56
|
+
export declare class SilenceDetector extends EventEmitter {
|
|
57
|
+
private config;
|
|
58
|
+
private vadIsCurrentlySpeaking;
|
|
59
|
+
private silenceAfterSpeechStartTimeMs;
|
|
60
|
+
private lastSpeechEndTimeMs;
|
|
61
|
+
private significantPauseAlreadyEmitted;
|
|
62
|
+
private silenceCheckIntervalTimer;
|
|
63
|
+
on<U extends keyof SilenceDetectorEvents>(event: U, listener: SilenceDetectorEvents[U]): this;
|
|
64
|
+
emit<U extends keyof SilenceDetectorEvents>(event: U, ...args: Parameters<SilenceDetectorEvents[U]>): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new SilenceDetector instance.
|
|
67
|
+
* @param {SilenceDetectorConfig} config - Configuration options.
|
|
68
|
+
*/
|
|
69
|
+
constructor(config?: SilenceDetectorConfig);
|
|
70
|
+
/**
|
|
71
|
+
* Handles the `speech_start` event from AdaptiveVAD.
|
|
72
|
+
* @param {VADResult} vadResult - The VAD result associated with speech start.
|
|
73
|
+
*/
|
|
74
|
+
handleSpeechStart(_vadResult: VADResult): void;
|
|
75
|
+
/**
|
|
76
|
+
* Handles the `voice_activity` event from AdaptiveVAD.
|
|
77
|
+
* Call this for every frame VAD identifies as speech.
|
|
78
|
+
* @param {VADResult} vadResult - The VAD result for the active voice frame.
|
|
79
|
+
*/
|
|
80
|
+
handleVoiceActivity(_vadResult: VADResult): void;
|
|
81
|
+
/**
|
|
82
|
+
* Handles the `no_voice_activity` event from AdaptiveVAD.
|
|
83
|
+
* Call this for every frame VAD identifies as non-speech.
|
|
84
|
+
* @param {VADResult} vadResult - The VAD result for the non-speech frame.
|
|
85
|
+
*/
|
|
86
|
+
handleNoVoiceActivity(_vadResult: VADResult): void;
|
|
87
|
+
/**
|
|
88
|
+
* Handles the `speech_end` event from AdaptiveVAD.
|
|
89
|
+
* This signifies VAD has determined a speech segment is over due to its internal pause limits.
|
|
90
|
+
* @param {VADResult} vadResult - The VAD result associated with speech end.
|
|
91
|
+
* @param {number} speechDurationMs - The duration of the speech segment as determined by VAD.
|
|
92
|
+
*/
|
|
93
|
+
handleSpeechEnd(_vadResult: VADResult, _speechDurationMs: number): void;
|
|
94
|
+
private clearSilenceState;
|
|
95
|
+
private startSilenceCheckTimer;
|
|
96
|
+
private stopSilenceCheckTimer;
|
|
97
|
+
/**
|
|
98
|
+
* Called periodically by the interval timer to check current silence duration.
|
|
99
|
+
*/
|
|
100
|
+
private checkSilenceDuration;
|
|
101
|
+
/**
|
|
102
|
+
* Resets the SilenceDetector's internal state.
|
|
103
|
+
* Should be called when a conversation or voice session is fully reset.
|
|
104
|
+
*/
|
|
105
|
+
reset(): void;
|
|
106
|
+
/**
|
|
107
|
+
* Call this when the component is being destroyed to clean up timers.
|
|
108
|
+
*/
|
|
109
|
+
dispose(): void;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=SilenceDetector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SilenceDetector.d.ts","sourceRoot":"","sources":["../../../src/core/audio/SilenceDetector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAErC;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC;;;;;;OAMG;IACH,mCAAmC,CAAC,EAAE,MAAM,CAAC;IAE7C;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,4BAA4B,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,2FAA2F;IAC3F,wBAAwB,EAAE,CAAC,sBAAsB,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,iFAAiF;IACjF,6BAA6B,EAAE,MAAM,IAAI,CAAC;CAC3C;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,sBAAsB,CAAkB;IAChD,OAAO,CAAC,6BAA6B,CAAuB;IAC5D,OAAO,CAAC,mBAAmB,CAAuB;IAElD,OAAO,CAAC,8BAA8B,CAAkB;IACxD,OAAO,CAAC,yBAAyB,CAA+B;IAEhD,EAAE,CAAC,CAAC,SAAS,MAAM,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,IAAI;IAI7F,IAAI,CAAC,CAAC,SAAS,MAAM,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO;IAI7H;;;OAGG;gBACS,MAAM,GAAE,qBAA0B;IAqB9C;;;OAGG;IACI,iBAAiB,CAAC,UAAU,EAAE,SAAS,GAAG,IAAI;IAOrD;;;;OAIG;IACI,mBAAmB,CAAC,UAAU,EAAE,SAAS,GAAG,IAAI;IAQvD;;;;OAIG;IACI,qBAAqB,CAAC,UAAU,EAAE,SAAS,GAAG,IAAI;IAsBzD;;;;;OAKG;IACI,eAAe,CAAC,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,GAAG,IAAI;IAgB9E,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,qBAAqB;IAQ7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoC5B;;;OAGG;IACI,KAAK,IAAI,IAAI;IAOpB;;OAEG;IACI,OAAO,IAAI,IAAI;CAIvB"}
|