@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.25 → 1.0.26

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
@@ -83,6 +83,8 @@ sdk.setListenerFromLSD(listenerPos, cameraPos, lookAtPos);
83
83
 
84
84
  #### Noise-Cancellation Stack (What’s Included)
85
85
  1. **Adaptive denoiser worklet** – learns each participant’s noise floor in real time, then applies a multi-band downward expander plus dynamic low/high-pass shaping.
86
+ - `speechBoost` lifts the low/mid band only when speech confidence is high, keeping consonants bright without reintroducing floor noise.
87
+ - `highBandGate` + `highBandAttack/Release` clamp constant fan hiss in the 4–12 kHz band whenever speechPresence is low, so background whoosh never leaks through live mics.
86
88
  2. **Optional voice enhancement** – autocorrelation-derived confidence (inspired by the tuner article) can raise the reduction floor when speech is present to keep vocals bright.
87
89
  3. **Silence gate** – if energy stays below `silenceFloor` for a configurable hold window, the track ramps to true silence, then wakes instantly once voice energy returns.
88
90
  4. **Classic filters** – fixed high-pass/low-pass filters shave off rumble and hiss before signals reach the HRTF panner.
@@ -101,6 +103,10 @@ These layers run entirely in Web Audio, so you can ship “AirPods-style” back
101
103
  silenceFloor: 0.00075,
102
104
  silenceHoldMs: 520,
103
105
  silenceReleaseMs: 160,
106
+ speechBoost: 0.35,
107
+ highBandGate: 0.7,
108
+ highBandAttack: 0.25,
109
+ highBandRelease: 0.12,
104
110
  },
105
111
  });
106
112
  ```
@@ -23,6 +23,10 @@ type DenoiserOptions = {
23
23
  silenceFloor?: number;
24
24
  silenceHoldMs?: number;
25
25
  silenceReleaseMs?: number;
26
+ speechBoost?: number;
27
+ highBandGate?: number;
28
+ highBandAttack?: number;
29
+ highBandRelease?: number;
26
30
  };
27
31
  export type SpatialAudioOptions = {
28
32
  distance?: SpatialAudioDistanceConfig;
@@ -94,6 +94,10 @@ class SpatialAudioManager extends EventManager_1.EventManager {
94
94
  silenceFloor: this.options.denoiser?.silenceFloor,
95
95
  silenceHoldMs: this.options.denoiser?.silenceHoldMs,
96
96
  silenceReleaseMs: this.options.denoiser?.silenceReleaseMs,
97
+ speechBoost: this.options.denoiser?.speechBoost,
98
+ highBandGate: this.options.denoiser?.highBandGate,
99
+ highBandAttack: this.options.denoiser?.highBandAttack,
100
+ highBandRelease: this.options.denoiser?.highBandRelease,
97
101
  },
98
102
  });
99
103
  }
@@ -603,6 +607,10 @@ class SpatialAudioManager extends EventManager_1.EventManager {
603
607
  this.voiceBoost = this._sanitize(cfg.voiceBoost, 0, 1, 0.6);
604
608
  this.voiceSensitivity = this._sanitize(cfg.voiceSensitivity, 0.05, 0.9, 0.35);
605
609
  this.voiceEnhancement = cfg.voiceEnhancement === true;
610
+ this.speechBoost = this._sanitize(cfg.speechBoost, 0, 1.5, 0.35);
611
+ this.highBandGate = this._sanitize(cfg.highBandGate, 0, 1, 0.7);
612
+ this.highBandAttack = this._sanitize(cfg.highBandAttack, 0.01, 1, 0.25);
613
+ this.highBandRelease = this._sanitize(cfg.highBandRelease, 0.01, 1, 0.12);
606
614
  this.silenceFloor = this._sanitize(cfg.silenceFloor, 0.0002, 0.02, 0.00085);
607
615
  this.gateGraceSamples = Math.round(sampleRate * 0.45);
608
616
  this.postSpeechHoldSamples = Math.round(sampleRate * 0.35);
@@ -649,6 +657,8 @@ class SpatialAudioManager extends EventManager_1.EventManager {
649
657
  muteGain: 1,
650
658
  graceSamplesRemaining: this.gateGraceSamples,
651
659
  postSpeechHold: 0,
660
+ highBandEnv: this.silenceFloor,
661
+ broadbandEnv: this.silenceFloor,
652
662
  };
653
663
  }
654
664
  return this.channelState[index];
@@ -820,13 +830,27 @@ class SpatialAudioManager extends EventManager_1.EventManager {
820
830
  let processed = sample * state.gain;
821
831
 
822
832
  state.lpState = this.hfAlpha * state.lpState + (1 - this.hfAlpha) * processed;
823
- const highComponent = processed - state.lpState;
833
+ const lowComponent = state.lpState;
834
+ const highComponent = processed - lowComponent;
835
+
836
+ // Track broadband/high-band envelopes for multi-band gating
837
+ state.broadbandEnv += (Math.abs(processed) - state.broadbandEnv) * 0.12;
838
+ const highEnvDelta = Math.abs(highComponent) - state.highBandEnv;
839
+ const highEnvCoef = highEnvDelta > 0 ? this.highBandAttack : this.highBandRelease;
840
+ state.highBandEnv += highEnvDelta * highEnvCoef;
841
+
824
842
  const hissRatio = Math.min(
825
843
  1,
826
- Math.abs(highComponent) / (Math.abs(state.lpState) + 1e-5)
844
+ Math.abs(highComponent) / (Math.abs(lowComponent) + 1e-5)
827
845
  );
828
846
  const hissGain = 1 - hissRatio * (this.hissCut * (1 - 0.4 * speechPresence));
829
- processed = state.lpState + highComponent * hissGain;
847
+
848
+ const highEnvRatio = state.highBandEnv / (state.broadbandEnv + 1e-5);
849
+ const gateAmount = this.highBandGate * Math.max(0, highEnvRatio - speechPresence * 0.5);
850
+ const gatedHigh = highComponent * hissGain * (1 - gateAmount);
851
+
852
+ const speechLift = 1 + this.speechBoost * speechPresence;
853
+ processed = lowComponent * speechLift + gatedHigh;
830
854
 
831
855
  const muteTarget = state.isSilenced ? 0.05 : 1;
832
856
  const smoothing = state.isSilenced ? 0.12 : 0.42;
@@ -885,6 +909,10 @@ registerProcessor('odyssey-denoise', OdysseyDenoiseProcessor);
885
909
  silenceFloor: 0.00075,
886
910
  silenceHoldMs: 520,
887
911
  silenceReleaseMs: 160,
912
+ speechBoost: 0.35,
913
+ highBandGate: 0.7,
914
+ highBandAttack: 0.25,
915
+ highBandRelease: 0.12,
888
916
  };
889
917
  return {
890
918
  distance: {
@@ -910,6 +938,10 @@ registerProcessor('odyssey-denoise', OdysseyDenoiseProcessor);
910
938
  silenceFloor: options?.denoiser?.silenceFloor ?? denoiserDefaults.silenceFloor,
911
939
  silenceHoldMs: options?.denoiser?.silenceHoldMs ?? denoiserDefaults.silenceHoldMs,
912
940
  silenceReleaseMs: options?.denoiser?.silenceReleaseMs ?? denoiserDefaults.silenceReleaseMs,
941
+ speechBoost: options?.denoiser?.speechBoost ?? denoiserDefaults.speechBoost,
942
+ highBandGate: options?.denoiser?.highBandGate ?? denoiserDefaults.highBandGate,
943
+ highBandAttack: options?.denoiser?.highBandAttack ?? denoiserDefaults.highBandAttack,
944
+ highBandRelease: options?.denoiser?.highBandRelease ?? denoiserDefaults.highBandRelease,
913
945
  },
914
946
  };
915
947
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "Odyssey Spatial Audio & Video SDK using MediaSoup for real-time communication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",