@tensamin/audio 0.1.9 → 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 CHANGED
@@ -101,11 +101,11 @@ vad: {
101
101
  energyVad?: {
102
102
  smoothing: number; // Default: 0.95
103
103
  initialNoiseFloor: number; // Default: 0.001
104
- noiseFloorAdaptRateQuiet: number; // Default: 0.05
104
+ noiseFloorAdaptRateQuiet: number; // Default: 0.005
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.0005
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
 
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-XO6B3D4A.mjs";
4
4
  import {
5
5
  EnergyVADPlugin
6
- } from "./chunk-3A2CTC4K.mjs";
6
+ } from "./chunk-B36JBXOK.mjs";
7
7
 
8
8
  // src/extensibility/plugins.ts
9
9
  var nsPlugins = /* @__PURE__ */ new Map();
@@ -3,11 +3,11 @@ var createEnergyVadWorkletCode = (vadConfig) => {
3
3
  const energyParams = vadConfig?.energyVad || {};
4
4
  const smoothing = energyParams.smoothing ?? 0.95;
5
5
  const initialNoiseFloor = energyParams.initialNoiseFloor ?? 1e-3;
6
- const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 0.05;
6
+ const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 5e-3;
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 ?? 5e-4;
10
+ const minEnergy = energyParams.minEnergy ?? 1e-3;
11
11
  return `
12
12
  class EnergyVadProcessor extends AudioWorkletProcessor {
13
13
  constructor() {
@@ -71,7 +71,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
71
71
  }
72
72
 
73
73
  // Ensure noise floor doesn't drop to absolute zero
74
- this.noiseFloor = Math.max(this.noiseFloor, 1e-5);
74
+ // 0.00005 is approx -86dB, very quiet but prevents SNR explosion
75
+ this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
75
76
 
76
77
  // Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
77
78
  const snr = this.energy / (this.noiseFloor + 1e-6);
@@ -83,8 +84,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
83
84
  let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
84
85
 
85
86
  // Apply absolute energy threshold
87
+ // We use a soft threshold to avoid abrupt cutting
86
88
  if (this.energy < this.minEnergy) {
87
- probability = 0;
89
+ const energyRatio = this.energy / (this.minEnergy + 1e-6);
90
+ probability *= Math.pow(energyRatio, 2); // Quadratic falloff
88
91
  }
89
92
 
90
93
  this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
@@ -26,11 +26,11 @@ var VADStateMachine = class {
26
26
  energyVad: {
27
27
  smoothing: config?.energyVad?.smoothing ?? 0.95,
28
28
  initialNoiseFloor: config?.energyVad?.initialNoiseFloor ?? 1e-3,
29
- noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 0.05,
29
+ noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 5e-3,
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 ?? 5e-4
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-KGCEV2VT.mjs";
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-FOGC2MFA.mjs";
12
+ } from "./chunk-3I4OQD2L.mjs";
13
13
 
14
14
  // src/pipeline/audio-pipeline.ts
15
15
  import mitt from "mitt";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAudioPipeline
3
- } from "./chunk-E7NH2QKZ.mjs";
3
+ } from "./chunk-I5AR7XQD.mjs";
4
4
 
5
5
  // src/livekit/integration.ts
6
6
  async function attachProcessingToTrack(track, config = {}) {
@@ -106,11 +106,11 @@ var createEnergyVadWorkletCode = (vadConfig) => {
106
106
  const energyParams = vadConfig?.energyVad || {};
107
107
  const smoothing = energyParams.smoothing ?? 0.95;
108
108
  const initialNoiseFloor = energyParams.initialNoiseFloor ?? 1e-3;
109
- const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 0.05;
109
+ const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 5e-3;
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 ?? 5e-4;
113
+ const minEnergy = energyParams.minEnergy ?? 1e-3;
114
114
  return `
115
115
  class EnergyVadProcessor extends AudioWorkletProcessor {
116
116
  constructor() {
@@ -174,7 +174,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
174
174
  }
175
175
 
176
176
  // Ensure noise floor doesn't drop to absolute zero
177
- this.noiseFloor = Math.max(this.noiseFloor, 1e-5);
177
+ // 0.00005 is approx -86dB, very quiet but prevents SNR explosion
178
+ this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
178
179
 
179
180
  // Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
180
181
  const snr = this.energy / (this.noiseFloor + 1e-6);
@@ -186,8 +187,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
186
187
  let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
187
188
 
188
189
  // Apply absolute energy threshold
190
+ // We use a soft threshold to avoid abrupt cutting
189
191
  if (this.energy < this.minEnergy) {
190
- probability = 0;
192
+ const energyRatio = this.energy / (this.minEnergy + 1e-6);
193
+ probability *= Math.pow(energyRatio, 2); // Quadratic falloff
191
194
  }
192
195
 
193
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-FOGC2MFA.mjs";
6
+ } from "../chunk-3I4OQD2L.mjs";
7
7
  import "../chunk-XO6B3D4A.mjs";
8
- import "../chunk-3A2CTC4K.mjs";
8
+ import "../chunk-B36JBXOK.mjs";
9
9
  export {
10
10
  getNoiseSuppressionPlugin,
11
11
  getVADPlugin,
package/dist/index.js CHANGED
@@ -158,11 +158,11 @@ var createEnergyVadWorkletCode = (vadConfig) => {
158
158
  const energyParams = vadConfig?.energyVad || {};
159
159
  const smoothing = energyParams.smoothing ?? 0.95;
160
160
  const initialNoiseFloor = energyParams.initialNoiseFloor ?? 1e-3;
161
- const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 0.05;
161
+ const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 5e-3;
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 ?? 5e-4;
165
+ const minEnergy = energyParams.minEnergy ?? 1e-3;
166
166
  return `
167
167
  class EnergyVadProcessor extends AudioWorkletProcessor {
168
168
  constructor() {
@@ -226,7 +226,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
226
226
  }
227
227
 
228
228
  // Ensure noise floor doesn't drop to absolute zero
229
- this.noiseFloor = Math.max(this.noiseFloor, 1e-5);
229
+ // 0.00005 is approx -86dB, very quiet but prevents SNR explosion
230
+ this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
230
231
 
231
232
  // Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
232
233
  const snr = this.energy / (this.noiseFloor + 1e-6);
@@ -238,8 +239,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
238
239
  let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
239
240
 
240
241
  // Apply absolute energy threshold
242
+ // We use a soft threshold to avoid abrupt cutting
241
243
  if (this.energy < this.minEnergy) {
242
- probability = 0;
244
+ const energyRatio = this.energy / (this.minEnergy + 1e-6);
245
+ probability *= Math.pow(energyRatio, 2); // Quadratic falloff
243
246
  }
244
247
 
245
248
  this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
@@ -374,11 +377,11 @@ var VADStateMachine = class {
374
377
  energyVad: {
375
378
  smoothing: config?.energyVad?.smoothing ?? 0.95,
376
379
  initialNoiseFloor: config?.energyVad?.initialNoiseFloor ?? 1e-3,
377
- noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 0.05,
380
+ noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 5e-3,
378
381
  noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
379
382
  minSNR: config?.energyVad?.minSNR ?? 10,
380
383
  snrRange: config?.energyVad?.snrRange ?? 10,
381
- minEnergy: config?.energyVad?.minEnergy ?? 5e-4
384
+ minEnergy: config?.energyVad?.minEnergy ?? 1e-3
382
385
  }
383
386
  };
384
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-ZISGHJDU.mjs";
4
+ } from "./chunk-RLZVZ6D6.mjs";
5
5
  import {
6
6
  createAudioPipeline
7
- } from "./chunk-E7NH2QKZ.mjs";
7
+ } from "./chunk-I5AR7XQD.mjs";
8
8
  import {
9
9
  VADStateMachine
10
- } from "./chunk-KGCEV2VT.mjs";
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-FOGC2MFA.mjs";
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-3A2CTC4K.mjs";
30
+ } from "./chunk-B36JBXOK.mjs";
31
31
  export {
32
32
  EnergyVADPlugin,
33
33
  RNNoisePlugin,
@@ -127,11 +127,11 @@ var createEnergyVadWorkletCode = (vadConfig) => {
127
127
  const energyParams = vadConfig?.energyVad || {};
128
128
  const smoothing = energyParams.smoothing ?? 0.95;
129
129
  const initialNoiseFloor = energyParams.initialNoiseFloor ?? 1e-3;
130
- const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 0.05;
130
+ const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 5e-3;
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 ?? 5e-4;
134
+ const minEnergy = energyParams.minEnergy ?? 1e-3;
135
135
  return `
136
136
  class EnergyVadProcessor extends AudioWorkletProcessor {
137
137
  constructor() {
@@ -195,7 +195,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
195
195
  }
196
196
 
197
197
  // Ensure noise floor doesn't drop to absolute zero
198
- this.noiseFloor = Math.max(this.noiseFloor, 1e-5);
198
+ // 0.00005 is approx -86dB, very quiet but prevents SNR explosion
199
+ this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
199
200
 
200
201
  // Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
201
202
  const snr = this.energy / (this.noiseFloor + 1e-6);
@@ -207,8 +208,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
207
208
  let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
208
209
 
209
210
  // Apply absolute energy threshold
211
+ // We use a soft threshold to avoid abrupt cutting
210
212
  if (this.energy < this.minEnergy) {
211
- probability = 0;
213
+ const energyRatio = this.energy / (this.minEnergy + 1e-6);
214
+ probability *= Math.pow(energyRatio, 2); // Quadratic falloff
212
215
  }
213
216
 
214
217
  this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
@@ -337,11 +340,11 @@ var VADStateMachine = class {
337
340
  energyVad: {
338
341
  smoothing: config?.energyVad?.smoothing ?? 0.95,
339
342
  initialNoiseFloor: config?.energyVad?.initialNoiseFloor ?? 1e-3,
340
- noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 0.05,
343
+ noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 5e-3,
341
344
  noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
342
345
  minSNR: config?.energyVad?.minSNR ?? 10,
343
346
  snrRange: config?.energyVad?.snrRange ?? 10,
344
- minEnergy: config?.energyVad?.minEnergy ?? 5e-4
347
+ minEnergy: config?.energyVad?.minEnergy ?? 1e-3
345
348
  }
346
349
  };
347
350
  this.lastSilenceTime = Date.now();
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  attachProcessingToTrack
3
- } from "../chunk-ZISGHJDU.mjs";
4
- import "../chunk-E7NH2QKZ.mjs";
5
- import "../chunk-KGCEV2VT.mjs";
3
+ } from "../chunk-RLZVZ6D6.mjs";
4
+ import "../chunk-I5AR7XQD.mjs";
5
+ import "../chunk-GFLVGUTU.mjs";
6
6
  import "../chunk-OZ7KMC4S.mjs";
7
- import "../chunk-FOGC2MFA.mjs";
7
+ import "../chunk-3I4OQD2L.mjs";
8
8
  import "../chunk-XO6B3D4A.mjs";
9
- import "../chunk-3A2CTC4K.mjs";
9
+ import "../chunk-B36JBXOK.mjs";
10
10
  export {
11
11
  attachProcessingToTrack
12
12
  };
@@ -125,11 +125,11 @@ var createEnergyVadWorkletCode = (vadConfig) => {
125
125
  const energyParams = vadConfig?.energyVad || {};
126
126
  const smoothing = energyParams.smoothing ?? 0.95;
127
127
  const initialNoiseFloor = energyParams.initialNoiseFloor ?? 1e-3;
128
- const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 0.05;
128
+ const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 5e-3;
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 ?? 5e-4;
132
+ const minEnergy = energyParams.minEnergy ?? 1e-3;
133
133
  return `
134
134
  class EnergyVadProcessor extends AudioWorkletProcessor {
135
135
  constructor() {
@@ -193,7 +193,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
193
193
  }
194
194
 
195
195
  // Ensure noise floor doesn't drop to absolute zero
196
- this.noiseFloor = Math.max(this.noiseFloor, 1e-5);
196
+ // 0.00005 is approx -86dB, very quiet but prevents SNR explosion
197
+ this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
197
198
 
198
199
  // Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
199
200
  const snr = this.energy / (this.noiseFloor + 1e-6);
@@ -205,8 +206,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
205
206
  let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
206
207
 
207
208
  // Apply absolute energy threshold
209
+ // We use a soft threshold to avoid abrupt cutting
208
210
  if (this.energy < this.minEnergy) {
209
- probability = 0;
211
+ const energyRatio = this.energy / (this.minEnergy + 1e-6);
212
+ probability *= Math.pow(energyRatio, 2); // Quadratic falloff
210
213
  }
211
214
 
212
215
  this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
@@ -335,11 +338,11 @@ var VADStateMachine = class {
335
338
  energyVad: {
336
339
  smoothing: config?.energyVad?.smoothing ?? 0.95,
337
340
  initialNoiseFloor: config?.energyVad?.initialNoiseFloor ?? 1e-3,
338
- noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 0.05,
341
+ noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 5e-3,
339
342
  noiseFloorAdaptRateLoud: config?.energyVad?.noiseFloorAdaptRateLoud ?? 0.01,
340
343
  minSNR: config?.energyVad?.minSNR ?? 10,
341
344
  snrRange: config?.energyVad?.snrRange ?? 10,
342
- minEnergy: config?.energyVad?.minEnergy ?? 5e-4
345
+ minEnergy: config?.energyVad?.minEnergy ?? 1e-3
343
346
  }
344
347
  };
345
348
  this.lastSilenceTime = Date.now();
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createAudioPipeline
3
- } from "../chunk-E7NH2QKZ.mjs";
4
- import "../chunk-KGCEV2VT.mjs";
3
+ } from "../chunk-I5AR7XQD.mjs";
4
+ import "../chunk-GFLVGUTU.mjs";
5
5
  import "../chunk-OZ7KMC4S.mjs";
6
- import "../chunk-FOGC2MFA.mjs";
6
+ import "../chunk-3I4OQD2L.mjs";
7
7
  import "../chunk-XO6B3D4A.mjs";
8
- import "../chunk-3A2CTC4K.mjs";
8
+ import "../chunk-B36JBXOK.mjs";
9
9
  export {
10
10
  createAudioPipeline
11
11
  };
package/dist/types.d.mts CHANGED
@@ -97,12 +97,12 @@ interface AudioProcessingConfig {
97
97
  initialNoiseFloor?: number;
98
98
  /**
99
99
  * Rate at which noise floor adapts to quiet signals (0-1).
100
- * Default: 0.05
100
+ * Default: 0.005 (slower downward drift)
101
101
  */
102
102
  noiseFloorAdaptRateQuiet?: number;
103
103
  /**
104
104
  * Rate at which noise floor adapts to loud signals (0-1).
105
- * Default: 0.01 (faster tracking of rising noise)
105
+ * Default: 0.01
106
106
  */
107
107
  noiseFloorAdaptRateLoud?: number;
108
108
  /**
@@ -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.0005
121
+ * Default: 0.001 (approx -60dB)
122
122
  */
123
123
  minEnergy?: number;
124
124
  };
package/dist/types.d.ts CHANGED
@@ -97,12 +97,12 @@ interface AudioProcessingConfig {
97
97
  initialNoiseFloor?: number;
98
98
  /**
99
99
  * Rate at which noise floor adapts to quiet signals (0-1).
100
- * Default: 0.05
100
+ * Default: 0.005 (slower downward drift)
101
101
  */
102
102
  noiseFloorAdaptRateQuiet?: number;
103
103
  /**
104
104
  * Rate at which noise floor adapts to loud signals (0-1).
105
- * Default: 0.01 (faster tracking of rising noise)
105
+ * Default: 0.01
106
106
  */
107
107
  noiseFloorAdaptRateLoud?: number;
108
108
  /**
@@ -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.0005
121
+ * Default: 0.001 (approx -60dB)
122
122
  */
123
123
  minEnergy?: number;
124
124
  };
@@ -27,11 +27,11 @@ var createEnergyVadWorkletCode = (vadConfig) => {
27
27
  const energyParams = vadConfig?.energyVad || {};
28
28
  const smoothing = energyParams.smoothing ?? 0.95;
29
29
  const initialNoiseFloor = energyParams.initialNoiseFloor ?? 1e-3;
30
- const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 0.05;
30
+ const noiseFloorAdaptRateQuiet = energyParams.noiseFloorAdaptRateQuiet ?? 5e-3;
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 ?? 5e-4;
34
+ const minEnergy = energyParams.minEnergy ?? 1e-3;
35
35
  return `
36
36
  class EnergyVadProcessor extends AudioWorkletProcessor {
37
37
  constructor() {
@@ -95,7 +95,8 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
95
95
  }
96
96
 
97
97
  // Ensure noise floor doesn't drop to absolute zero
98
- this.noiseFloor = Math.max(this.noiseFloor, 1e-5);
98
+ // 0.00005 is approx -86dB, very quiet but prevents SNR explosion
99
+ this.noiseFloor = Math.max(this.noiseFloor, 0.00005);
99
100
 
100
101
  // Calculate Signal-to-Noise Ratio (SNR) in dB using smoothed energy
101
102
  const snr = this.energy / (this.noiseFloor + 1e-6);
@@ -107,8 +108,10 @@ class EnergyVadProcessor extends AudioWorkletProcessor {
107
108
  let probability = Math.min(1, Math.max(0, (snrDb - this.minSNR) / this.snrRange));
108
109
 
109
110
  // Apply absolute energy threshold
111
+ // We use a soft threshold to avoid abrupt cutting
110
112
  if (this.energy < this.minEnergy) {
111
- probability = 0;
113
+ const energyRatio = this.energy / (this.minEnergy + 1e-6);
114
+ probability *= Math.pow(energyRatio, 2); // Quadratic falloff
112
115
  }
113
116
 
114
117
  this.port.postMessage({ probability, snr: snrDb, noiseFloor: this.noiseFloor, rms: this.energy });
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EnergyVADPlugin
3
- } from "../chunk-3A2CTC4K.mjs";
3
+ } from "../chunk-B36JBXOK.mjs";
4
4
  export {
5
5
  EnergyVADPlugin
6
6
  };
@@ -50,11 +50,11 @@ var VADStateMachine = class {
50
50
  energyVad: {
51
51
  smoothing: config?.energyVad?.smoothing ?? 0.95,
52
52
  initialNoiseFloor: config?.energyVad?.initialNoiseFloor ?? 1e-3,
53
- noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 0.05,
53
+ noiseFloorAdaptRateQuiet: config?.energyVad?.noiseFloorAdaptRateQuiet ?? 5e-3,
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 ?? 5e-4
57
+ minEnergy: config?.energyVad?.minEnergy ?? 1e-3
58
58
  }
59
59
  };
60
60
  this.lastSilenceTime = Date.now();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VADStateMachine
3
- } from "../chunk-KGCEV2VT.mjs";
3
+ } from "../chunk-GFLVGUTU.mjs";
4
4
  export {
5
5
  VADStateMachine
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tensamin/audio",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",