@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.258 → 1.0.260
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 +45 -1
- package/dist/audio/AudioNodeFactory.d.ts +130 -0
- package/dist/audio/AudioNodeFactory.js +158 -0
- package/dist/audio/AudioPipeline.d.ts +89 -0
- package/dist/audio/AudioPipeline.js +138 -0
- package/dist/{MLNoiseSuppressor.d.ts → audio/MLNoiseSuppressor.d.ts} +7 -7
- package/dist/{MLNoiseSuppressor.js → audio/MLNoiseSuppressor.js} +19 -52
- package/dist/audio/index.d.ts +6 -0
- package/dist/audio/index.js +22 -0
- package/dist/channels/huddle/HuddleChannel.d.ts +87 -0
- package/dist/channels/huddle/HuddleChannel.js +152 -0
- package/dist/channels/huddle/HuddleTypes.d.ts +85 -0
- package/dist/channels/huddle/HuddleTypes.js +25 -0
- package/dist/channels/huddle/index.d.ts +5 -0
- package/dist/channels/huddle/index.js +21 -0
- package/dist/channels/index.d.ts +5 -0
- package/dist/channels/index.js +21 -0
- package/dist/channels/spatial/SpatialAudioChannel.d.ts +144 -0
- package/dist/channels/spatial/SpatialAudioChannel.js +476 -0
- package/dist/channels/spatial/SpatialAudioTypes.d.ts +85 -0
- package/dist/channels/spatial/SpatialAudioTypes.js +42 -0
- package/dist/channels/spatial/index.d.ts +5 -0
- package/dist/channels/spatial/index.js +21 -0
- package/dist/{EventManager.d.ts → core/EventManager.d.ts} +4 -2
- package/dist/{EventManager.js → core/EventManager.js} +5 -3
- package/dist/{MediasoupManager.d.ts → core/MediasoupManager.d.ts} +10 -4
- package/dist/{MediasoupManager.js → core/MediasoupManager.js} +56 -44
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +21 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +43 -9
- package/dist/sdk/index.d.ts +36 -0
- package/dist/sdk/index.js +121 -0
- package/dist/types/events.d.ts +154 -0
- package/dist/{types.js → types/events.js} +3 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.js +23 -0
- package/dist/types/participant.d.ts +65 -0
- package/dist/types/participant.js +5 -0
- package/dist/types/position.d.ts +47 -0
- package/dist/types/position.js +9 -0
- package/dist/types/room.d.ts +82 -0
- package/dist/types/room.js +5 -0
- package/dist/utils/audio/clarity-score.d.ts +33 -0
- package/dist/utils/audio/clarity-score.js +81 -0
- package/dist/utils/audio/index.d.ts +5 -0
- package/dist/utils/audio/index.js +21 -0
- package/dist/utils/audio/voice-filter.d.ts +30 -0
- package/dist/utils/audio/voice-filter.js +70 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +23 -0
- package/dist/utils/position/coordinates.d.ts +37 -0
- package/dist/utils/position/coordinates.js +61 -0
- package/dist/utils/position/index.d.ts +6 -0
- package/dist/utils/position/index.js +22 -0
- package/dist/utils/position/normalize.d.ts +37 -0
- package/dist/utils/position/normalize.js +78 -0
- package/dist/utils/position/snap.d.ts +51 -0
- package/dist/utils/position/snap.js +81 -0
- package/dist/utils/smoothing/gain-smoothing.d.ts +45 -0
- package/dist/utils/smoothing/gain-smoothing.js +77 -0
- package/dist/utils/smoothing/index.d.ts +5 -0
- package/dist/utils/smoothing/index.js +21 -0
- package/dist/utils/smoothing/pan-smoothing.d.ts +43 -0
- package/dist/utils/smoothing/pan-smoothing.js +85 -0
- package/dist/utils/spatial/angle-calc.d.ts +24 -0
- package/dist/utils/spatial/angle-calc.js +69 -0
- package/dist/utils/spatial/distance-calc.d.ts +33 -0
- package/dist/utils/spatial/distance-calc.js +48 -0
- package/dist/utils/spatial/gain-calc.d.ts +37 -0
- package/dist/utils/spatial/gain-calc.js +52 -0
- package/dist/utils/spatial/head-position.d.ts +32 -0
- package/dist/utils/spatial/head-position.js +76 -0
- package/dist/utils/spatial/index.d.ts +9 -0
- package/dist/utils/spatial/index.js +25 -0
- package/dist/utils/spatial/listener-calc.d.ts +28 -0
- package/dist/utils/spatial/listener-calc.js +74 -0
- package/dist/utils/spatial/pan-calc.d.ts +48 -0
- package/dist/utils/spatial/pan-calc.js +80 -0
- package/package.json +1 -1
- package/dist/SpatialAudioManager.d.ts +0 -271
- package/dist/SpatialAudioManager.js +0 -1512
- package/dist/types.d.ts +0 -73
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pan Calculations
|
|
3
|
+
*
|
|
4
|
+
* Functions for calculating stereo panning based on listener/source positions
|
|
5
|
+
*/
|
|
6
|
+
import { Position, ListenerRight } from '../../types/position';
|
|
7
|
+
/**
|
|
8
|
+
* Panning values for left/right channels
|
|
9
|
+
*/
|
|
10
|
+
export interface Panning {
|
|
11
|
+
left: number;
|
|
12
|
+
right: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Calculate listener's right-ear vector from yaw rotation
|
|
16
|
+
*
|
|
17
|
+
* COORDINATE SYSTEM: X=right, Y=up, Z=forward (datum at 0,0,0)
|
|
18
|
+
*
|
|
19
|
+
* Rotation convention (right-hand rule around Y-axis):
|
|
20
|
+
* yaw = 0° → facing +Z (forward), right ear points to +X
|
|
21
|
+
* yaw = 90° → facing +X (right), right ear points to -Z
|
|
22
|
+
* yaw = 180° → facing -Z (backward), right ear points to -X
|
|
23
|
+
* yaw = 270° → facing -X (left), right ear points to +Z
|
|
24
|
+
*
|
|
25
|
+
* @param yawDegrees Yaw rotation in degrees
|
|
26
|
+
* @returns Unit vector pointing to listener's right ear
|
|
27
|
+
*/
|
|
28
|
+
export declare function calculateListenerRight(yawDegrees: number): ListenerRight;
|
|
29
|
+
/**
|
|
30
|
+
* Calculate pan value from listener and source positions
|
|
31
|
+
*
|
|
32
|
+
* Uses dot product projection onto listener's right-ear axis:
|
|
33
|
+
* dxLocal = vecToSource · listenerRight
|
|
34
|
+
*
|
|
35
|
+
* @param listenerPos Listener position
|
|
36
|
+
* @param sourcePos Sound source position
|
|
37
|
+
* @param listenerRight Listener's right-ear unit vector
|
|
38
|
+
* @returns Pan value from -1 (full left) to +1 (full right)
|
|
39
|
+
*/
|
|
40
|
+
export declare function calculatePanFromPositions(listenerPos: Position, sourcePos: Position, listenerRight: ListenerRight): number;
|
|
41
|
+
/**
|
|
42
|
+
* Convert pan value (-1 to +1) to left/right channel percentages
|
|
43
|
+
*
|
|
44
|
+
* @param pan Pan value from -1 (full left) to +1 (full right)
|
|
45
|
+
* @param dxLocal Optional dxLocal value (unused, for compatibility)
|
|
46
|
+
* @returns Panning percentages for left and right channels
|
|
47
|
+
*/
|
|
48
|
+
export declare function panValueToPanning(pan: number, dxLocal?: number): Panning;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pan Calculations
|
|
4
|
+
*
|
|
5
|
+
* Functions for calculating stereo panning based on listener/source positions
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.calculateListenerRight = calculateListenerRight;
|
|
9
|
+
exports.calculatePanFromPositions = calculatePanFromPositions;
|
|
10
|
+
exports.panValueToPanning = panValueToPanning;
|
|
11
|
+
/**
|
|
12
|
+
* Calculate listener's right-ear vector from yaw rotation
|
|
13
|
+
*
|
|
14
|
+
* COORDINATE SYSTEM: X=right, Y=up, Z=forward (datum at 0,0,0)
|
|
15
|
+
*
|
|
16
|
+
* Rotation convention (right-hand rule around Y-axis):
|
|
17
|
+
* yaw = 0° → facing +Z (forward), right ear points to +X
|
|
18
|
+
* yaw = 90° → facing +X (right), right ear points to -Z
|
|
19
|
+
* yaw = 180° → facing -Z (backward), right ear points to -X
|
|
20
|
+
* yaw = 270° → facing -X (left), right ear points to +Z
|
|
21
|
+
*
|
|
22
|
+
* @param yawDegrees Yaw rotation in degrees
|
|
23
|
+
* @returns Unit vector pointing to listener's right ear
|
|
24
|
+
*/
|
|
25
|
+
function calculateListenerRight(yawDegrees) {
|
|
26
|
+
const yawRad = (yawDegrees * Math.PI) / 180;
|
|
27
|
+
// Right ear vector - CLOCKWISE rotation (standard game engine convention)
|
|
28
|
+
return {
|
|
29
|
+
x: Math.cos(yawRad),
|
|
30
|
+
z: -Math.sin(yawRad), // NEGATIVE for clockwise rotation
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Calculate pan value from listener and source positions
|
|
35
|
+
*
|
|
36
|
+
* Uses dot product projection onto listener's right-ear axis:
|
|
37
|
+
* dxLocal = vecToSource · listenerRight
|
|
38
|
+
*
|
|
39
|
+
* @param listenerPos Listener position
|
|
40
|
+
* @param sourcePos Sound source position
|
|
41
|
+
* @param listenerRight Listener's right-ear unit vector
|
|
42
|
+
* @returns Pan value from -1 (full left) to +1 (full right)
|
|
43
|
+
*/
|
|
44
|
+
function calculatePanFromPositions(listenerPos, sourcePos, listenerRight) {
|
|
45
|
+
// Calculate relative vector (speaker relative to listener)
|
|
46
|
+
const vecToSource = {
|
|
47
|
+
x: sourcePos.x - listenerPos.x,
|
|
48
|
+
z: sourcePos.z - listenerPos.z,
|
|
49
|
+
};
|
|
50
|
+
// Project onto listener's right-ear axis using dot product
|
|
51
|
+
// Positive = sound is to the RIGHT of listener
|
|
52
|
+
// Negative = sound is to the LEFT of listener
|
|
53
|
+
const dxLocal = vecToSource.x * listenerRight.x + vecToSource.z * listenerRight.z;
|
|
54
|
+
// Calculate dzLocal (forward/back component)
|
|
55
|
+
// For CLOCKWISE rotation: Forward = right rotated 90° CW: (x,z) -> (-z,x)
|
|
56
|
+
const listenerForward = { x: -listenerRight.z, z: listenerRight.x };
|
|
57
|
+
const dzLocal = vecToSource.x * listenerForward.x + vecToSource.z * listenerForward.z;
|
|
58
|
+
// TRUE 360° SPATIAL AUDIO PANNING
|
|
59
|
+
// Calculate angle from listener to source using atan2
|
|
60
|
+
const angleToSource = Math.atan2(dxLocal, dzLocal); // Radians: -π to +π
|
|
61
|
+
const rawPanValue = Math.sin(angleToSource); // -1 to +1
|
|
62
|
+
return rawPanValue;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convert pan value (-1 to +1) to left/right channel percentages
|
|
66
|
+
*
|
|
67
|
+
* @param pan Pan value from -1 (full left) to +1 (full right)
|
|
68
|
+
* @param dxLocal Optional dxLocal value (unused, for compatibility)
|
|
69
|
+
* @returns Panning percentages for left and right channels
|
|
70
|
+
*/
|
|
71
|
+
function panValueToPanning(pan, dxLocal) {
|
|
72
|
+
const clamped = Math.max(-1, Math.min(1, pan));
|
|
73
|
+
// Map pan to asymmetric gains while keeping center at 100/100
|
|
74
|
+
const left = 100 * (1 - Math.max(0, clamped));
|
|
75
|
+
const right = 100 * (1 + Math.min(0, clamped));
|
|
76
|
+
return {
|
|
77
|
+
left: Math.max(0, Math.min(100, left)),
|
|
78
|
+
right: Math.max(0, Math.min(100, right)),
|
|
79
|
+
};
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import { EventManager } from "./EventManager";
|
|
2
|
-
import { Position } from "./types";
|
|
3
|
-
type SpatialAudioDistanceConfig = {
|
|
4
|
-
refDistance?: number;
|
|
5
|
-
maxDistance?: number;
|
|
6
|
-
rolloffFactor?: number;
|
|
7
|
-
unit?: "auto" | "meters" | "centimeters";
|
|
8
|
-
};
|
|
9
|
-
type DenoiserOptions = {
|
|
10
|
-
enabled?: boolean;
|
|
11
|
-
threshold?: number;
|
|
12
|
-
noiseFloor?: number;
|
|
13
|
-
release?: number;
|
|
14
|
-
attack?: number;
|
|
15
|
-
holdMs?: number;
|
|
16
|
-
maxReduction?: number;
|
|
17
|
-
hissCut?: number;
|
|
18
|
-
expansionRatio?: number;
|
|
19
|
-
learnRate?: number;
|
|
20
|
-
voiceBoost?: number;
|
|
21
|
-
voiceSensitivity?: number;
|
|
22
|
-
voiceEnhancement?: boolean;
|
|
23
|
-
silenceFloor?: number;
|
|
24
|
-
silenceHoldMs?: number;
|
|
25
|
-
silenceReleaseMs?: number;
|
|
26
|
-
speechBoost?: number;
|
|
27
|
-
highBandGate?: number;
|
|
28
|
-
highBandAttack?: number;
|
|
29
|
-
highBandRelease?: number;
|
|
30
|
-
};
|
|
31
|
-
export type SpatialAudioOptions = {
|
|
32
|
-
distance?: SpatialAudioDistanceConfig;
|
|
33
|
-
denoiser?: DenoiserOptions;
|
|
34
|
-
};
|
|
35
|
-
export declare class SpatialAudioManager extends EventManager {
|
|
36
|
-
private static readonly BUILD_STAMP;
|
|
37
|
-
private audioContext;
|
|
38
|
-
private participantNodes;
|
|
39
|
-
private masterGainNode;
|
|
40
|
-
private monitoringIntervals;
|
|
41
|
-
private compressor;
|
|
42
|
-
private options;
|
|
43
|
-
private denoiseWorkletReady;
|
|
44
|
-
private denoiseWorkletUrl?;
|
|
45
|
-
private listenerPosition;
|
|
46
|
-
private listenerInitialized;
|
|
47
|
-
private listenerDirection;
|
|
48
|
-
private listenerRight;
|
|
49
|
-
private lastLogTime?;
|
|
50
|
-
private localParticipantId;
|
|
51
|
-
private isMasterMuted;
|
|
52
|
-
private smoothedPanValues;
|
|
53
|
-
private lastPanValue;
|
|
54
|
-
private lastSpatialUpdateTime;
|
|
55
|
-
private _spatialDebugTimes;
|
|
56
|
-
private panSmoothingFactor;
|
|
57
|
-
private panChangeThreshold;
|
|
58
|
-
private panCenterDeadZone;
|
|
59
|
-
private cachedSpeakerPositions;
|
|
60
|
-
private cachedListenerPosition;
|
|
61
|
-
private listenerPositionInitialized;
|
|
62
|
-
private positionSnapThreshold;
|
|
63
|
-
private _listenerDebugLogTime?;
|
|
64
|
-
private mlSuppressor;
|
|
65
|
-
private mlModelReady;
|
|
66
|
-
constructor(options?: SpatialAudioOptions);
|
|
67
|
-
getAudioContext(): AudioContext;
|
|
68
|
-
/**
|
|
69
|
-
* Initialize ML-based noise suppression (TensorFlow.js)
|
|
70
|
-
* Falls back to AudioWorklet denoiser if ML initialization fails
|
|
71
|
-
*/
|
|
72
|
-
initializeMLNoiseSuppression(modelUrl: string): Promise<void>;
|
|
73
|
-
/**
|
|
74
|
-
* Get current noise suppression mode
|
|
75
|
-
*/
|
|
76
|
-
getNoiseSuppressionMode(): 'ml' | 'audioworklet' | 'none';
|
|
77
|
-
/**
|
|
78
|
-
* True if the TFJS model assets were loaded and the model is ready.
|
|
79
|
-
* This does NOT mean it is currently processing the live WebAudio stream.
|
|
80
|
-
*/
|
|
81
|
-
isMLModelLoaded(): boolean;
|
|
82
|
-
/**
|
|
83
|
-
* Setup spatial audio for a participant
|
|
84
|
-
*
|
|
85
|
-
* CRITICAL: Each participant gets their OWN audio processing chain:
|
|
86
|
-
* Stream -> Source -> Panner -> Analyser -> Gain -> Compressor -> Output
|
|
87
|
-
*
|
|
88
|
-
* This ensures:
|
|
89
|
-
* - Each voice is positioned independently in 3D space
|
|
90
|
-
* - No server-side mixing required
|
|
91
|
-
* - Scalable to unlimited participants (browser handles the mixing)
|
|
92
|
-
*
|
|
93
|
-
* @param participantId Unique ID for this participant
|
|
94
|
-
* @param track Audio track from MediaSoup consumer
|
|
95
|
-
* @param bypassSpatialization For testing - bypasses 3D positioning
|
|
96
|
-
*/
|
|
97
|
-
setupSpatialAudioForParticipant(participantId: string, track: MediaStreamTrack, bypassSpatialization?: boolean): Promise<void>;
|
|
98
|
-
private startMonitoring;
|
|
99
|
-
/**
|
|
100
|
-
* Toggle spatialization for a participant (for huddle/spatial switching)
|
|
101
|
-
* @param participantId The participant to update
|
|
102
|
-
* @param enableSpatialization True for spatial audio, false for non-spatial (huddle)
|
|
103
|
-
*/
|
|
104
|
-
setParticipantSpatialization(participantId: string, enableSpatialization: boolean): void;
|
|
105
|
-
/**
|
|
106
|
-
* Update spatial audio position and orientation for a participant
|
|
107
|
-
*
|
|
108
|
-
* This is called every time we receive position/direction updates from the server.
|
|
109
|
-
*
|
|
110
|
-
* Position: Where the participant is in 3D space (their location)
|
|
111
|
-
* Direction: Which way they're facing (their forward vector)
|
|
112
|
-
*
|
|
113
|
-
* Example:
|
|
114
|
-
* - Position: (x: -200, y: 0, z: 100) = 2m to your left
|
|
115
|
-
* - Direction: (x: 0, y: 1, z: 0) = facing forward (away from you)
|
|
116
|
-
* - Result: Sound comes from your left, oriented as if speaking away
|
|
117
|
-
*
|
|
118
|
-
* The Web Audio API's PannerNode uses HRTF to create realistic 3D audio
|
|
119
|
-
* based on these parameters plus the listener's position/orientation.
|
|
120
|
-
*
|
|
121
|
-
* @param participantId Who to update
|
|
122
|
-
* @param position Where they are (from socket data)
|
|
123
|
-
* @param direction Which way they're facing (from socket data)
|
|
124
|
-
*/
|
|
125
|
-
updateSpatialAudio(participantId: string, position: Position, direction?: {
|
|
126
|
-
x: number;
|
|
127
|
-
y: number;
|
|
128
|
-
z: number;
|
|
129
|
-
}, _spatialMeta?: {
|
|
130
|
-
pan?: number;
|
|
131
|
-
dxLocal?: number;
|
|
132
|
-
}): void;
|
|
133
|
-
/**
|
|
134
|
-
* Mute or unmute a participant's audio
|
|
135
|
-
* Used for channel-based audio routing (huddle vs spatial)
|
|
136
|
-
* @param participantId The participant to mute/unmute
|
|
137
|
-
* @param muted True to mute, false to unmute
|
|
138
|
-
*/
|
|
139
|
-
setParticipantMuted(participantId: string, muted: boolean): void;
|
|
140
|
-
/**
|
|
141
|
-
* Master mute/unmute for ALL audio output
|
|
142
|
-
* Use this to prevent audio from playing until user explicitly joins the space.
|
|
143
|
-
* @param muted True to mute all audio, false to unmute
|
|
144
|
-
*/
|
|
145
|
-
setMasterMuted(muted: boolean): void;
|
|
146
|
-
/**
|
|
147
|
-
* Get current master mute state
|
|
148
|
-
* @returns True if master mute is enabled
|
|
149
|
-
*/
|
|
150
|
-
getMasterMuted(): boolean;
|
|
151
|
-
/**
|
|
152
|
-
* Update listener position and orientation
|
|
153
|
-
* The \"listener\" is YOU - where your ears/head are positioned
|
|
154
|
-
*
|
|
155
|
-
* @param position Your HEAD position (camera position), not body position!
|
|
156
|
-
* @param orientation Which way your head is facing (forward and up vectors)
|
|
157
|
-
*/
|
|
158
|
-
setListenerPosition(position: Position, orientation: {
|
|
159
|
-
forwardX: number;
|
|
160
|
-
forwardY: number;
|
|
161
|
-
forwardZ: number;
|
|
162
|
-
upX: number;
|
|
163
|
-
upY: number;
|
|
164
|
-
upZ: number;
|
|
165
|
-
}): void;
|
|
166
|
-
/**
|
|
167
|
-
* POSITION-ONLY MODE: Set listener HEAD position (no direction needed)
|
|
168
|
-
* IMPORTANT: Uses CAMERA position (head) as listener, not body position!
|
|
169
|
-
*
|
|
170
|
-
* @param listenerPos Player body position (for reference, not used as listener)
|
|
171
|
-
* @param cameraPos Camera/HEAD position - THIS is the actual listener position for audio
|
|
172
|
-
* @param lookAtPos Look-at position (where camera is pointing) - stored but not used for panning
|
|
173
|
-
* @param rot Rotation data (pitch, yaw, roll) - stored but not used for panning
|
|
174
|
-
*/
|
|
175
|
-
setListenerFromLSD(listenerPos: Position, cameraPos: Position, lookAtPos: Position, rot?: {
|
|
176
|
-
x: number;
|
|
177
|
-
y: number;
|
|
178
|
-
z: number;
|
|
179
|
-
}, localParticipantId?: string): void;
|
|
180
|
-
private applyListenerTransform;
|
|
181
|
-
removeParticipant(participantId: string): void;
|
|
182
|
-
resumeAudioContext(): Promise<void>;
|
|
183
|
-
getAudioContextState(): AudioContextState;
|
|
184
|
-
private getDistanceConfig;
|
|
185
|
-
private applySpatialBoostIfNeeded;
|
|
186
|
-
private getDistanceBetween;
|
|
187
|
-
private calculateDistanceGain;
|
|
188
|
-
private normalizePositionUnits;
|
|
189
|
-
/**
|
|
190
|
-
* Snap position to grid to prevent jitter from micro-movements
|
|
191
|
-
* If the position hasn't changed significantly, return the cached position
|
|
192
|
-
* This prevents gain/pan fluctuation when users are "stationary"
|
|
193
|
-
*
|
|
194
|
-
* @param position New incoming position
|
|
195
|
-
* @param participantId Participant ID for caching (use 'listener' for listener)
|
|
196
|
-
* @returns Snapped position (either new or cached)
|
|
197
|
-
*/
|
|
198
|
-
private snapPosition;
|
|
199
|
-
private getVectorFromListener;
|
|
200
|
-
private applyDirectionalSuppression;
|
|
201
|
-
/**
|
|
202
|
-
* Dynamically adjust highpass filter based on voice characteristics
|
|
203
|
-
* Analyzes audio spectrum and sets filter between 85-300Hz
|
|
204
|
-
*/
|
|
205
|
-
private adjustVoiceAdaptiveFilter;
|
|
206
|
-
private calculateClarityScore;
|
|
207
|
-
private calculateProximityWeight;
|
|
208
|
-
private calculateDirectionFocus;
|
|
209
|
-
private normalizeVector;
|
|
210
|
-
private clamp;
|
|
211
|
-
private isDenoiserEnabled;
|
|
212
|
-
/**
|
|
213
|
-
* Compute estimated head/mouth position from body position
|
|
214
|
-
* Body position is typically at feet/base - add head height offset
|
|
215
|
-
* Average human head height: 1.6m (adjustable based on avatar)
|
|
216
|
-
*/
|
|
217
|
-
private computeHeadPosition;
|
|
218
|
-
private calculatePanning;
|
|
219
|
-
private panningFromPanValue;
|
|
220
|
-
/**
|
|
221
|
-
* SMOOTH PAN VALUE to prevent random left/right jumping
|
|
222
|
-
* Uses exponential moving average (EMA) to smooth out jittery position data
|
|
223
|
-
* With SNAP behavior for large direction changes (e.g., turning around)
|
|
224
|
-
* With DEAD-ZONE around center to prevent face-to-face oscillation
|
|
225
|
-
* @param participantId The participant to smooth pan for
|
|
226
|
-
* @param newPanValue The new calculated pan value (-1 to +1)
|
|
227
|
-
* @returns Smoothed pan value
|
|
228
|
-
*/
|
|
229
|
-
private smoothPanValue;
|
|
230
|
-
private computeAzimuthFromPositions;
|
|
231
|
-
/**
|
|
232
|
-
* OLD METHOD - Kept for reference but not used in position-only mode
|
|
233
|
-
* Calculate angle between listener and sound source in degrees (0-360)
|
|
234
|
-
* 0° = front, 90° = right, 180° = back, 270° = left
|
|
235
|
-
*/
|
|
236
|
-
private calculateAngle;
|
|
237
|
-
/**
|
|
238
|
-
* Calculate gain based on distance using logarithmic scale
|
|
239
|
-
* Distance range: 0.5m to 15m
|
|
240
|
-
* Gain range: 100% to 20% (reduced minimum for audibility at distance)
|
|
241
|
-
* Uses smoother curve for more consistent audio across distances
|
|
242
|
-
*
|
|
243
|
-
* TUNED FOR CONSISTENT VOICE CLARITY:
|
|
244
|
-
* - Near range (0-3m): Full volume for clear conversation
|
|
245
|
-
* - Medium range (3-8m): Gradual falloff, still easily audible
|
|
246
|
-
* - Far range (8-15m): Soft but still present
|
|
247
|
-
*/
|
|
248
|
-
/**
|
|
249
|
-
* Calculate gain based on distance - AGGRESSIVE FALLOFF
|
|
250
|
-
*
|
|
251
|
-
* Uses inverse-square law (realistic sound propagation) with floor:
|
|
252
|
-
* Gain = 1 / (1 + k * distance²)
|
|
253
|
-
*
|
|
254
|
-
* Distance → Gain mapping:
|
|
255
|
-
* - 0-1m → 100% (full volume, very close)
|
|
256
|
-
* - 2m → ~80%
|
|
257
|
-
* - 3m → ~55%
|
|
258
|
-
* - 5m → ~30%
|
|
259
|
-
* - 8m → ~15%
|
|
260
|
-
* - 10m+ → 5% (minimum, barely audible)
|
|
261
|
-
*/
|
|
262
|
-
private calculateLogarithmicGain;
|
|
263
|
-
/**
|
|
264
|
-
* Apply stereo panning to participant audio using StereoPannerNode
|
|
265
|
-
* This provides STABLE left-right panning without jitter
|
|
266
|
-
*/
|
|
267
|
-
private applyStereoPanning;
|
|
268
|
-
private ensureDenoiseWorklet;
|
|
269
|
-
private resolveOptions;
|
|
270
|
-
}
|
|
271
|
-
export {};
|