@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.264 → 1.0.266

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.
@@ -27,6 +27,10 @@ export declare class SpatialAudioChannel {
27
27
  private positionCache;
28
28
  private panSmoother;
29
29
  private isMasterMuted;
30
+ private lastGainValues;
31
+ private lastPanValues;
32
+ private readonly GAIN_CHANGE_THRESHOLD;
33
+ private readonly PAN_CHANGE_THRESHOLD;
30
34
  private mlNoiseSuppressor;
31
35
  private noiseSuppressionMode;
32
36
  constructor(config?: SpatialAudioConfig);
@@ -40,6 +44,7 @@ export declare class SpatialAudioChannel {
40
44
  setupParticipant(participantId: string, track: MediaStreamTrack, bypassSpatialization?: boolean): Promise<void>;
41
45
  /**
42
46
  * Update spatial audio for a participant
47
+ * OPTIMIZED: Only updates gain/pan when values change significantly
43
48
  */
44
49
  updateSpatialAudio(participantId: string, position: Position, direction?: {
45
50
  x: number;
@@ -29,6 +29,11 @@ class SpatialAudioChannel {
29
29
  initialized: false,
30
30
  };
31
31
  this.isMasterMuted = false;
32
+ // Gain/Pan caching to prevent unnecessary audio parameter updates
33
+ this.lastGainValues = new Map();
34
+ this.lastPanValues = new Map();
35
+ this.GAIN_CHANGE_THRESHOLD = 0.02; // 2% change required to update
36
+ this.PAN_CHANGE_THRESHOLD = 0.03; // 3% change required to update
32
37
  // ML Noise Suppression
33
38
  this.mlNoiseSuppressor = null;
34
39
  this.noiseSuppressionMode = 'none';
@@ -124,9 +129,13 @@ class SpatialAudioChannel {
124
129
  dynamicLowpass,
125
130
  stream,
126
131
  });
132
+ // Initialize gain cache for this participant at full volume
133
+ this.lastGainValues.set(participantId, 1.0);
134
+ this.lastPanValues.set(participantId, 0);
127
135
  }
128
136
  /**
129
137
  * Update spatial audio for a participant
138
+ * OPTIMIZED: Only updates gain/pan when values change significantly
130
139
  */
131
140
  updateSpatialAudio(participantId, position, direction) {
132
141
  const nodes = this.participantNodes.get(participantId);
@@ -140,7 +149,11 @@ class SpatialAudioChannel {
140
149
  const distance = (0, distance_calc_1.getDistanceBetween)(listenerPos, speakerHead);
141
150
  // Hard cutoff at max distance
142
151
  if (distance >= this.distanceConfig.maxDistance) {
143
- (0, gain_smoothing_1.applyGainSmooth)(nodes.gain, 0, this.audioContext, 0.033);
152
+ const lastGain = this.lastGainValues.get(participantId) ?? 1.0;
153
+ if (lastGain > 0.01) {
154
+ (0, gain_smoothing_1.applyGainSmooth)(nodes.gain, 0, this.audioContext, 0.1);
155
+ this.lastGainValues.set(participantId, 0);
156
+ }
144
157
  return;
145
158
  }
146
159
  // Calculate pan
@@ -153,11 +166,21 @@ class SpatialAudioChannel {
153
166
  maxDistance: this.distanceConfig.maxDistance,
154
167
  });
155
168
  const gainValue = gainPercent / 100;
156
- // Apply stereo panning
169
+ // Calculate pan value
157
170
  const panValue = (panning.right - panning.left) / 100;
158
- (0, gain_smoothing_1.applyStereoPanSmooth)(nodes.stereoPanner, panValue, this.audioContext, 0.05);
159
- // Apply gain
160
- (0, gain_smoothing_1.applyGainSmooth)(nodes.gain, gainValue, this.audioContext, 0.1);
171
+ // OPTIMIZATION: Only apply pan if it changed significantly
172
+ const lastPan = this.lastPanValues.get(participantId) ?? 0;
173
+ if (Math.abs(panValue - lastPan) > this.PAN_CHANGE_THRESHOLD) {
174
+ (0, gain_smoothing_1.applyStereoPanSmooth)(nodes.stereoPanner, panValue, this.audioContext, 0.08);
175
+ this.lastPanValues.set(participantId, panValue);
176
+ }
177
+ // OPTIMIZATION: Only apply gain if it changed significantly
178
+ // This prevents continuous setTargetAtTime calls which cause audio instability
179
+ const lastGain = this.lastGainValues.get(participantId) ?? 1.0;
180
+ if (Math.abs(gainValue - lastGain) > this.GAIN_CHANGE_THRESHOLD) {
181
+ (0, gain_smoothing_1.applyGainSmooth)(nodes.gain, gainValue, this.audioContext, 0.15);
182
+ this.lastGainValues.set(participantId, gainValue);
183
+ }
161
184
  }
162
185
  /**
163
186
  * Set listener position from LSD data
@@ -316,6 +339,8 @@ class SpatialAudioChannel {
316
339
  this.participantNodes.delete(participantId);
317
340
  this.panSmoother.clear(participantId);
318
341
  this.positionCache.clear(participantId);
342
+ this.lastGainValues.delete(participantId);
343
+ this.lastPanValues.delete(participantId);
319
344
  }
320
345
  }
321
346
  /**
package/dist/index.d.ts CHANGED
@@ -68,6 +68,10 @@ export declare class OdysseySpatialComms extends EventManager {
68
68
  dxLocal?: number;
69
69
  }): void;
70
70
  updateMediaState(mediaState: MediaState): void;
71
+ /**
72
+ * Stop screenshare - closes producer and notifies all consumers
73
+ */
74
+ stopScreenShare(): Promise<void>;
71
75
  setListenerPosition(position: Position, orientation: {
72
76
  forwardX: number;
73
77
  forwardY: number;
package/dist/index.js CHANGED
@@ -225,6 +225,34 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
225
225
  });
226
226
  }
227
227
  }
228
+ /**
229
+ * Stop screenshare - closes producer and notifies all consumers
230
+ */
231
+ async stopScreenShare() {
232
+ if (!this.localParticipant || !this.room)
233
+ return;
234
+ // Close local screenshare track
235
+ const screenshareTrack = this.localParticipant.screenshareTrack;
236
+ if (screenshareTrack) {
237
+ screenshareTrack.stop();
238
+ this.localParticipant.screenshareTrack = null;
239
+ }
240
+ // Close local screenshare producer
241
+ for (const [producerId, producer] of this.localParticipant.producers) {
242
+ if (producer.appData?.isScreenshare) {
243
+ producer.close();
244
+ this.localParticipant.producers.delete(producerId);
245
+ break;
246
+ }
247
+ }
248
+ // Notify server to close screenshare and notify consumers
249
+ return new Promise((resolve) => {
250
+ this.socket.emit("stop-screenshare", { participantId: this.localParticipant.participantId }, () => {
251
+ this.localParticipant.mediaState.sharescreen = false;
252
+ resolve();
253
+ });
254
+ });
255
+ }
228
256
  setListenerPosition(position, orientation) {
229
257
  this.spatialAudioManager.setListenerPosition(position, orientation);
230
258
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.264",
3
+ "version": "1.0.266",
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",