@tensamin/audio 0.1.10 → 0.1.11
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 +3 -3
- package/dist/{chunk-Z3QBDLTM.mjs → chunk-3I4OQD2L.mjs} +1 -1
- package/dist/{chunk-SMNOCQYR.mjs → chunk-B36JBXOK.mjs} +6 -4
- package/dist/{chunk-VCQMZVO3.mjs → chunk-GFLVGUTU.mjs} +1 -1
- package/dist/{chunk-CD5XFC5M.mjs → chunk-I5AR7XQD.mjs} +2 -2
- package/dist/{chunk-IL4F7WVW.mjs → chunk-RLZVZ6D6.mjs} +1 -1
- package/dist/extensibility/plugins.js +6 -4
- package/dist/extensibility/plugins.mjs +2 -2
- package/dist/index.js +7 -5
- package/dist/index.mjs +5 -5
- package/dist/livekit/integration.js +7 -5
- package/dist/livekit/integration.mjs +5 -5
- package/dist/pipeline/audio-pipeline.js +7 -5
- package/dist/pipeline/audio-pipeline.mjs +4 -4
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/vad/vad-node.js +6 -4
- package/dist/vad/vad-node.mjs +1 -1
- package/dist/vad/vad-state.js +1 -1
- package/dist/vad/vad-state.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ vad: {
|
|
|
105
105
|
noiseFloorAdaptRateLoud: number; // Default: 0.01
|
|
106
106
|
minSNR: number; // Default: 10.0 (dB)
|
|
107
107
|
snrRange: number; // Default: 10.0 (dB)
|
|
108
|
-
minEnergy: number; // Default: 0.
|
|
108
|
+
minEnergy: number; // Default: 0.001
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
111
|
```
|
|
@@ -116,7 +116,7 @@ vad: {
|
|
|
116
116
|
- `stopThreshold`: Probability threshold to mute audio (Default: 0.3, ~13dB SNR)
|
|
117
117
|
- `hangoverMs`: Delay before muting after speech stops (Default: 300ms)
|
|
118
118
|
- `preRollMs`: Audio buffer duration before speech onset
|
|
119
|
-
- `minSpeechDurationMs`: Minimum duration to consider as valid speech
|
|
119
|
+
- `minSpeechDurationMs`: Minimum duration to consider as valid speech (Default: 150ms)
|
|
120
120
|
- `minSilenceDurationMs`: Minimum silence duration between speech segments
|
|
121
121
|
|
|
122
122
|
**Energy VAD Parameters:**
|
|
@@ -124,7 +124,7 @@ vad: {
|
|
|
124
124
|
- `smoothing`: Energy calculation smoothing factor (0-1)
|
|
125
125
|
- `minSNR`: Minimum signal-to-noise ratio in dB for speech detection
|
|
126
126
|
- `snrRange`: Range in dB for probability scaling from minSNR
|
|
127
|
-
- `minEnergy`: Minimum absolute RMS energy to consider as speech
|
|
127
|
+
- `minEnergy`: Minimum absolute RMS energy to consider as speech (Default: 0.001, ~-60dB)
|
|
128
128
|
|
|
129
129
|
### Output Control
|
|
130
130
|
|
|
@@ -7,7 +7,7 @@ var createEnergyVadWorkletCode = (vadConfig) => {
|
|
|
7
7
|
const noiseFloorAdaptRateLoud = energyParams.noiseFloorAdaptRateLoud ?? 0.01;
|
|
8
8
|
const minSNR = energyParams.minSNR ?? 10;
|
|
9
9
|
const snrRange = energyParams.snrRange ?? 10;
|
|
10
|
-
const minEnergy = energyParams.minEnergy ??
|
|
10
|
+
const minEnergy = energyParams.minEnergy ?? 1e-3;
|
|
11
11
|
return `
|
|
12
12
|
class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
13
13
|
constructor() {
|
|
@@ -71,8 +71,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
// Ensure noise floor doesn't drop to absolute zero
|
|
74
|
-
// 0.
|
|
75
|
-
this.noiseFloor = Math.max(this.noiseFloor, 0.
|
|
74
|
+
// 0.00005 is approx -86dB, very quiet but prevents SNR explosion
|
|
75
|
+
this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
|
|
76
76
|
|
|
77
77
|
// Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
|
|
78
78
|
const snr = this.energy / (this.noiseFloor + 1e-6);
|
|
@@ -84,8 +84,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
84
84
|
let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
|
|
85
85
|
|
|
86
86
|
// Apply absolute energy threshold
|
|
87
|
+
// We use a soft threshold to avoid abrupt cutting
|
|
87
88
|
if (this.energy < this.minEnergy) {
|
|
88
|
-
|
|
89
|
+
const energyRatio = this.energy / (this.minEnergy + 1e-6);
|
|
90
|
+
probability *= Math.pow(energyRatio, 2); // Quadratic falloff
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
|
|
@@ -30,7 +30,7 @@ var VADStateMachine = class {
|
|
|
30
30
|
noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
|
|
31
31
|
minSNR: config?.energyVad?.minSNR ?? 10,
|
|
32
32
|
snrRange: config?.energyVad?.snrRange ?? 10,
|
|
33
|
-
minEnergy: config?.energyVad?.minEnergy ??
|
|
33
|
+
minEnergy: config?.energyVad?.minEnergy ?? 1e-3
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
this.lastSilenceTime = Date.now();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VADStateMachine
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GFLVGUTU.mjs";
|
|
4
4
|
import {
|
|
5
5
|
getAudioContext,
|
|
6
6
|
registerPipeline,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
getNoiseSuppressionPlugin,
|
|
11
11
|
getVADPlugin
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-3I4OQD2L.mjs";
|
|
13
13
|
|
|
14
14
|
// src/pipeline/audio-pipeline.ts
|
|
15
15
|
import mitt from "mitt";
|
|
@@ -110,7 +110,7 @@ var createEnergyVadWorkletCode = (vadConfig) => {
|
|
|
110
110
|
const noiseFloorAdaptRateLoud = energyParams.noiseFloorAdaptRateLoud ?? 0.01;
|
|
111
111
|
const minSNR = energyParams.minSNR ?? 10;
|
|
112
112
|
const snrRange = energyParams.snrRange ?? 10;
|
|
113
|
-
const minEnergy = energyParams.minEnergy ??
|
|
113
|
+
const minEnergy = energyParams.minEnergy ?? 1e-3;
|
|
114
114
|
return `
|
|
115
115
|
class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
116
116
|
constructor() {
|
|
@@ -174,8 +174,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// Ensure noise floor doesn't drop to absolute zero
|
|
177
|
-
// 0.
|
|
178
|
-
this.noiseFloor = Math.max(this.noiseFloor, 0.
|
|
177
|
+
// 0.00005 is approx -86dB, very quiet but prevents SNR explosion
|
|
178
|
+
this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
|
|
179
179
|
|
|
180
180
|
// Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
|
|
181
181
|
const snr = this.energy / (this.noiseFloor + 1e-6);
|
|
@@ -187,8 +187,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
187
187
|
let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
|
|
188
188
|
|
|
189
189
|
// Apply absolute energy threshold
|
|
190
|
+
// We use a soft threshold to avoid abrupt cutting
|
|
190
191
|
if (this.energy < this.minEnergy) {
|
|
191
|
-
|
|
192
|
+
const energyRatio = this.energy / (this.minEnergy + 1e-6);
|
|
193
|
+
probability *= Math.pow(energyRatio, 2); // Quadratic falloff
|
|
192
194
|
}
|
|
193
195
|
|
|
194
196
|
this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
getVADPlugin,
|
|
4
4
|
registerNoiseSuppressionPlugin,
|
|
5
5
|
registerVADPlugin
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-3I4OQD2L.mjs";
|
|
7
7
|
import "../chunk-XO6B3D4A.mjs";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-B36JBXOK.mjs";
|
|
9
9
|
export {
|
|
10
10
|
getNoiseSuppressionPlugin,
|
|
11
11
|
getVADPlugin,
|
package/dist/index.js
CHANGED
|
@@ -162,7 +162,7 @@ var createEnergyVadWorkletCode = (vadConfig) => {
|
|
|
162
162
|
const noiseFloorAdaptRateLoud = energyParams.noiseFloorAdaptRateLoud ?? 0.01;
|
|
163
163
|
const minSNR = energyParams.minSNR ?? 10;
|
|
164
164
|
const snrRange = energyParams.snrRange ?? 10;
|
|
165
|
-
const minEnergy = energyParams.minEnergy ??
|
|
165
|
+
const minEnergy = energyParams.minEnergy ?? 1e-3;
|
|
166
166
|
return `
|
|
167
167
|
class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
168
168
|
constructor() {
|
|
@@ -226,8 +226,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// Ensure noise floor doesn't drop to absolute zero
|
|
229
|
-
// 0.
|
|
230
|
-
this.noiseFloor = Math.max(this.noiseFloor, 0.
|
|
229
|
+
// 0.00005 is approx -86dB, very quiet but prevents SNR explosion
|
|
230
|
+
this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
|
|
231
231
|
|
|
232
232
|
// Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
|
|
233
233
|
const snr = this.energy / (this.noiseFloor + 1e-6);
|
|
@@ -239,8 +239,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
239
239
|
let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
|
|
240
240
|
|
|
241
241
|
// Apply absolute energy threshold
|
|
242
|
+
// We use a soft threshold to avoid abrupt cutting
|
|
242
243
|
if (this.energy < this.minEnergy) {
|
|
243
|
-
|
|
244
|
+
const energyRatio = this.energy / (this.minEnergy + 1e-6);
|
|
245
|
+
probability *= Math.pow(energyRatio, 2); // Quadratic falloff
|
|
244
246
|
}
|
|
245
247
|
|
|
246
248
|
this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
|
|
@@ -379,7 +381,7 @@ var VADStateMachine = class {
|
|
|
379
381
|
noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
|
|
380
382
|
minSNR: config?.energyVad?.minSNR ?? 10,
|
|
381
383
|
snrRange: config?.energyVad?.snrRange ?? 10,
|
|
382
|
-
minEnergy: config?.energyVad?.minEnergy ??
|
|
384
|
+
minEnergy: config?.energyVad?.minEnergy ?? 1e-3
|
|
383
385
|
}
|
|
384
386
|
};
|
|
385
387
|
this.lastSilenceTime = Date.now();
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "./chunk-WBQAMGXK.mjs";
|
|
2
2
|
import {
|
|
3
3
|
attachProcessingToTrack
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RLZVZ6D6.mjs";
|
|
5
5
|
import {
|
|
6
6
|
createAudioPipeline
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-I5AR7XQD.mjs";
|
|
8
8
|
import {
|
|
9
9
|
VADStateMachine
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-GFLVGUTU.mjs";
|
|
11
11
|
import {
|
|
12
12
|
closeAudioContext,
|
|
13
13
|
getAudioContext,
|
|
@@ -21,13 +21,13 @@ import {
|
|
|
21
21
|
getVADPlugin,
|
|
22
22
|
registerNoiseSuppressionPlugin,
|
|
23
23
|
registerVADPlugin
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-3I4OQD2L.mjs";
|
|
25
25
|
import {
|
|
26
26
|
RNNoisePlugin
|
|
27
27
|
} from "./chunk-XO6B3D4A.mjs";
|
|
28
28
|
import {
|
|
29
29
|
EnergyVADPlugin
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-B36JBXOK.mjs";
|
|
31
31
|
export {
|
|
32
32
|
EnergyVADPlugin,
|
|
33
33
|
RNNoisePlugin,
|
|
@@ -131,7 +131,7 @@ var createEnergyVadWorkletCode = (vadConfig) => {
|
|
|
131
131
|
const noiseFloorAdaptRateLoud = energyParams.noiseFloorAdaptRateLoud ?? 0.01;
|
|
132
132
|
const minSNR = energyParams.minSNR ?? 10;
|
|
133
133
|
const snrRange = energyParams.snrRange ?? 10;
|
|
134
|
-
const minEnergy = energyParams.minEnergy ??
|
|
134
|
+
const minEnergy = energyParams.minEnergy ?? 1e-3;
|
|
135
135
|
return `
|
|
136
136
|
class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
137
137
|
constructor() {
|
|
@@ -195,8 +195,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
// Ensure noise floor doesn't drop to absolute zero
|
|
198
|
-
// 0.
|
|
199
|
-
this.noiseFloor = Math.max(this.noiseFloor, 0.
|
|
198
|
+
// 0.00005 is approx -86dB, very quiet but prevents SNR explosion
|
|
199
|
+
this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
|
|
200
200
|
|
|
201
201
|
// Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
|
|
202
202
|
const snr = this.energy / (this.noiseFloor + 1e-6);
|
|
@@ -208,8 +208,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
208
208
|
let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
|
|
209
209
|
|
|
210
210
|
// Apply absolute energy threshold
|
|
211
|
+
// We use a soft threshold to avoid abrupt cutting
|
|
211
212
|
if (this.energy < this.minEnergy) {
|
|
212
|
-
|
|
213
|
+
const energyRatio = this.energy / (this.minEnergy + 1e-6);
|
|
214
|
+
probability *= Math.pow(energyRatio, 2); // Quadratic falloff
|
|
213
215
|
}
|
|
214
216
|
|
|
215
217
|
this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
|
|
@@ -342,7 +344,7 @@ var VADStateMachine = class {
|
|
|
342
344
|
noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
|
|
343
345
|
minSNR: config?.energyVad?.minSNR ?? 10,
|
|
344
346
|
snrRange: config?.energyVad?.snrRange ?? 10,
|
|
345
|
-
minEnergy: config?.energyVad?.minEnergy ??
|
|
347
|
+
minEnergy: config?.energyVad?.minEnergy ?? 1e-3
|
|
346
348
|
}
|
|
347
349
|
};
|
|
348
350
|
this.lastSilenceTime = Date.now();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
attachProcessingToTrack
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-RLZVZ6D6.mjs";
|
|
4
|
+
import "../chunk-I5AR7XQD.mjs";
|
|
5
|
+
import "../chunk-GFLVGUTU.mjs";
|
|
6
6
|
import "../chunk-OZ7KMC4S.mjs";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-3I4OQD2L.mjs";
|
|
8
8
|
import "../chunk-XO6B3D4A.mjs";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-B36JBXOK.mjs";
|
|
10
10
|
export {
|
|
11
11
|
attachProcessingToTrack
|
|
12
12
|
};
|
|
@@ -129,7 +129,7 @@ var createEnergyVadWorkletCode = (vadConfig) => {
|
|
|
129
129
|
const noiseFloorAdaptRateLoud = energyParams.noiseFloorAdaptRateLoud ?? 0.01;
|
|
130
130
|
const minSNR = energyParams.minSNR ?? 10;
|
|
131
131
|
const snrRange = energyParams.snrRange ?? 10;
|
|
132
|
-
const minEnergy = energyParams.minEnergy ??
|
|
132
|
+
const minEnergy = energyParams.minEnergy ?? 1e-3;
|
|
133
133
|
return `
|
|
134
134
|
class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
135
135
|
constructor() {
|
|
@@ -193,8 +193,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
// Ensure noise floor doesn't drop to absolute zero
|
|
196
|
-
// 0.
|
|
197
|
-
this.noiseFloor = Math.max(this.noiseFloor, 0.
|
|
196
|
+
// 0.00005 is approx -86dB, very quiet but prevents SNR explosion
|
|
197
|
+
this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
|
|
198
198
|
|
|
199
199
|
// Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
|
|
200
200
|
const snr = this.energy / (this.noiseFloor + 1e-6);
|
|
@@ -206,8 +206,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
206
206
|
let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
|
|
207
207
|
|
|
208
208
|
// Apply absolute energy threshold
|
|
209
|
+
// We use a soft threshold to avoid abrupt cutting
|
|
209
210
|
if (this.energy < this.minEnergy) {
|
|
210
|
-
|
|
211
|
+
const energyRatio = this.energy / (this.minEnergy + 1e-6);
|
|
212
|
+
probability *= Math.pow(energyRatio, 2); // Quadratic falloff
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
|
|
@@ -340,7 +342,7 @@ var VADStateMachine = class {
|
|
|
340
342
|
noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
|
|
341
343
|
minSNR: config?.energyVad?.minSNR ?? 10,
|
|
342
344
|
snrRange: config?.energyVad?.snrRange ?? 10,
|
|
343
|
-
minEnergy: config?.energyVad?.minEnergy ??
|
|
345
|
+
minEnergy: config?.energyVad?.minEnergy ?? 1e-3
|
|
344
346
|
}
|
|
345
347
|
};
|
|
346
348
|
this.lastSilenceTime = Date.now();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createAudioPipeline
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-I5AR7XQD.mjs";
|
|
4
|
+
import "../chunk-GFLVGUTU.mjs";
|
|
5
5
|
import "../chunk-OZ7KMC4S.mjs";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-3I4OQD2L.mjs";
|
|
7
7
|
import "../chunk-XO6B3D4A.mjs";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-B36JBXOK.mjs";
|
|
9
9
|
export {
|
|
10
10
|
createAudioPipeline
|
|
11
11
|
};
|
package/dist/types.d.mts
CHANGED
|
@@ -118,7 +118,7 @@ interface AudioProcessingConfig {
|
|
|
118
118
|
/**
|
|
119
119
|
* Minimum absolute RMS energy to consider as speech.
|
|
120
120
|
* Prevents triggering on very quiet background noise in silent rooms.
|
|
121
|
-
* Default: 0.
|
|
121
|
+
* Default: 0.001 (approx -60dB)
|
|
122
122
|
*/
|
|
123
123
|
minEnergy?: number;
|
|
124
124
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ interface AudioProcessingConfig {
|
|
|
118
118
|
/**
|
|
119
119
|
* Minimum absolute RMS energy to consider as speech.
|
|
120
120
|
* Prevents triggering on very quiet background noise in silent rooms.
|
|
121
|
-
* Default: 0.
|
|
121
|
+
* Default: 0.001 (approx -60dB)
|
|
122
122
|
*/
|
|
123
123
|
minEnergy?: number;
|
|
124
124
|
};
|
package/dist/vad/vad-node.js
CHANGED
|
@@ -31,7 +31,7 @@ var createEnergyVadWorkletCode = (vadConfig) => {
|
|
|
31
31
|
const noiseFloorAdaptRateLoud = energyParams.noiseFloorAdaptRateLoud ?? 0.01;
|
|
32
32
|
const minSNR = energyParams.minSNR ?? 10;
|
|
33
33
|
const snrRange = energyParams.snrRange ?? 10;
|
|
34
|
-
const minEnergy = energyParams.minEnergy ??
|
|
34
|
+
const minEnergy = energyParams.minEnergy ?? 1e-3;
|
|
35
35
|
return `
|
|
36
36
|
class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
37
37
|
constructor() {
|
|
@@ -95,8 +95,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
// Ensure noise floor doesn't drop to absolute zero
|
|
98
|
-
// 0.
|
|
99
|
-
this.noiseFloor = Math.max(this.noiseFloor, 0.
|
|
98
|
+
// 0.00005 is approx -86dB, very quiet but prevents SNR explosion
|
|
99
|
+
this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
|
|
100
100
|
|
|
101
101
|
// Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
|
|
102
102
|
const snr = this.energy / (this.noiseFloor + 1e-6);
|
|
@@ -108,8 +108,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
|
|
|
108
108
|
let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
|
|
109
109
|
|
|
110
110
|
// Apply absolute energy threshold
|
|
111
|
+
// We use a soft threshold to avoid abrupt cutting
|
|
111
112
|
if (this.energy < this.minEnergy) {
|
|
112
|
-
|
|
113
|
+
const energyRatio = this.energy / (this.minEnergy + 1e-6);
|
|
114
|
+
probability *= Math.pow(energyRatio, 2); // Quadratic falloff
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
|
package/dist/vad/vad-node.mjs
CHANGED
package/dist/vad/vad-state.js
CHANGED
|
@@ -54,7 +54,7 @@ var VADStateMachine = class {
|
|
|
54
54
|
noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
|
|
55
55
|
minSNR: config?.energyVad?.minSNR ?? 10,
|
|
56
56
|
snrRange: config?.energyVad?.snrRange ?? 10,
|
|
57
|
-
minEnergy: config?.energyVad?.minEnergy ??
|
|
57
|
+
minEnergy: config?.energyVad?.minEnergy ?? 1e-3
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
this.lastSilenceTime = Date.now();
|
package/dist/vad/vad-state.mjs
CHANGED