@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.60 → 1.0.61

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.
@@ -74,6 +74,12 @@ export declare class SpatialAudioManager extends EventManager {
74
74
  */
75
75
  setupSpatialAudioForParticipant(participantId: string, track: MediaStreamTrack, bypassSpatialization?: boolean): Promise<void>;
76
76
  private startMonitoring;
77
+ /**
78
+ * Toggle spatialization for a participant (for huddle/spatial switching)
79
+ * @param participantId The participant to update
80
+ * @param enableSpatialization True for spatial audio, false for non-spatial (huddle)
81
+ */
82
+ setParticipantSpatialization(participantId: string, enableSpatialization: boolean): void;
77
83
  /**
78
84
  * Update spatial audio position and orientation for a participant
79
85
  *
@@ -225,6 +225,40 @@ class SpatialAudioManager extends EventManager_1.EventManager {
225
225
  }, 2000); // Check every 2 seconds
226
226
  this.monitoringIntervals.set(participantId, interval);
227
227
  }
228
+ /**
229
+ * Toggle spatialization for a participant (for huddle/spatial switching)
230
+ * @param participantId The participant to update
231
+ * @param enableSpatialization True for spatial audio, false for non-spatial (huddle)
232
+ */
233
+ setParticipantSpatialization(participantId, enableSpatialization) {
234
+ const nodes = this.participantNodes.get(participantId);
235
+ if (!nodes) {
236
+ console.warn(`[SpatialAudio] No nodes found for participant ${participantId}`);
237
+ return;
238
+ }
239
+ // Disconnect and reconnect audio chain
240
+ try {
241
+ // Disconnect from current destination
242
+ nodes.proximityGain.disconnect();
243
+ if (enableSpatialization) {
244
+ // Connect through panner for 3D spatial audio
245
+ nodes.proximityGain.connect(nodes.panner);
246
+ nodes.panner.connect(nodes.analyser);
247
+ console.log(`🎯 [SpatialAudio] Enabled spatialization for ${participantId.substring(0, 8)}`);
248
+ }
249
+ else {
250
+ // Bypass panner for non-spatial (huddle) audio
251
+ nodes.proximityGain.connect(nodes.analyser);
252
+ console.log(`🔊 [SpatialAudio] Disabled spatialization (huddle mode) for ${participantId.substring(0, 8)}`);
253
+ }
254
+ // Rest of the chain remains the same
255
+ nodes.analyser.connect(nodes.gain);
256
+ nodes.gain.connect(this.masterGainNode);
257
+ }
258
+ catch (error) {
259
+ console.error(`[SpatialAudio] Error toggling spatialization for ${participantId}:`, error);
260
+ }
261
+ }
228
262
  /**
229
263
  * Update spatial audio position and orientation for a participant
230
264
  *
@@ -322,7 +356,9 @@ class SpatialAudioManager extends EventManager_1.EventManager {
322
356
  const fwdY = forwardY / forwardLen;
323
357
  const fwdZ = forwardZ / forwardLen;
324
358
  // Calculate right vector (cross product of world up and forward)
325
- const worldUp = { x: 0, y: 0, z: 1 }; // Unreal Z-up
359
+ // Web Audio API uses Y-up coordinate system, Unreal uses Z-up
360
+ // We need to transform: Unreal (X,Y,Z) -> WebAudio (X,Z,-Y)
361
+ const worldUp = { x: 0, y: 1, z: 0 }; // Web Audio Y-up
326
362
  const rightX = worldUp.y * fwdZ - worldUp.z * fwdY;
327
363
  const rightY = worldUp.z * fwdX - worldUp.x * fwdZ;
328
364
  const rightZ = worldUp.x * fwdY - worldUp.y * fwdX;
@@ -334,8 +370,8 @@ class SpatialAudioManager extends EventManager_1.EventManager {
334
370
  forwardY: fwdY,
335
371
  forwardZ: fwdZ,
336
372
  upX: 0,
337
- upY: 0,
338
- upZ: 1,
373
+ upY: 1,
374
+ upZ: 0,
339
375
  });
340
376
  return;
341
377
  }
package/dist/index.js CHANGED
@@ -383,11 +383,16 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
383
383
  return; // Exit early to prevent any audio processing
384
384
  }
385
385
  else {
386
- // Setup spatial audio with full 3D positioning
387
- await this.spatialAudioManager.setupSpatialAudioForParticipant(participant.participantId, track, false // Always enable spatial audio
386
+ // Check if participant is in a huddle (non-spatial channel)
387
+ const participantChannel = participant.currentChannel || "spatial";
388
+ const isInHuddle = participantChannel !== "spatial";
389
+ // Setup spatial audio - bypass 3D positioning for huddle members
390
+ await this.spatialAudioManager.setupSpatialAudioForParticipant(participant.participantId, track, isInHuddle // Bypass spatialization if in huddle
388
391
  );
389
- // Update spatial audio position
390
- this.spatialAudioManager.updateSpatialAudio(participant.participantId, data.position);
392
+ // Only update spatial position if in spatial channel
393
+ if (!isInHuddle) {
394
+ this.spatialAudioManager.updateSpatialAudio(participant.participantId, data.position);
395
+ }
391
396
  }
392
397
  // NOW resume the consumer after audio pipeline is ready
393
398
  this.mediasoupManager
@@ -496,6 +501,9 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
496
501
  const participant = this.room?.participants.get(data.participantId);
497
502
  if (participant) {
498
503
  participant.currentChannel = data.channelId;
504
+ // Update spatialization based on channel
505
+ const isInSpatialChannel = data.channelId === "spatial";
506
+ this.spatialAudioManager.setParticipantSpatialization(data.participantId, isInSpatialChannel);
499
507
  // If this participant is now in a different channel from us, clear their screenshare
500
508
  const myChannel = this.localParticipant?.currentChannel || "spatial";
501
509
  const theirChannel = data.channelId || "spatial";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.60",
3
+ "version": "1.0.61",
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",