@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.257 → 1.0.259
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} +13 -41
- 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 +455 -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} +31 -42
- 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 +30 -4
- 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 -272
- package/dist/SpatialAudioManager.js +0 -1537
- package/dist/types.d.ts +0 -73
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK Event Types
|
|
3
|
+
*/
|
|
4
|
+
import { Participant, MediaState, ParticipantSnapshot } from './participant';
|
|
5
|
+
import { Position, Direction } from './position';
|
|
6
|
+
/**
|
|
7
|
+
* Participants snapshot event from server
|
|
8
|
+
*/
|
|
9
|
+
export interface ParticipantsSnapshotEvent {
|
|
10
|
+
roomId: string;
|
|
11
|
+
participants: ParticipantSnapshot[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Room joined event data
|
|
15
|
+
*/
|
|
16
|
+
export interface RoomJoinedEvent {
|
|
17
|
+
roomId: string;
|
|
18
|
+
participantId: string;
|
|
19
|
+
participants: Participant[];
|
|
20
|
+
routerRtpCapabilities: any;
|
|
21
|
+
iceServers: any[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Consumer created event data
|
|
25
|
+
*/
|
|
26
|
+
export interface ConsumerCreatedEvent {
|
|
27
|
+
participant: Participant;
|
|
28
|
+
track: MediaStreamTrack;
|
|
29
|
+
consumer: any;
|
|
30
|
+
isScreenshare?: boolean;
|
|
31
|
+
appData?: any;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Consumer closed event data
|
|
35
|
+
*/
|
|
36
|
+
export interface ConsumerClosedEvent {
|
|
37
|
+
consumerId: string;
|
|
38
|
+
participantId: string;
|
|
39
|
+
kind: string;
|
|
40
|
+
isScreenshare?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Consumer paused event data
|
|
44
|
+
*/
|
|
45
|
+
export interface ConsumerPausedEvent {
|
|
46
|
+
consumerId: string;
|
|
47
|
+
participantId: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Consumer resumed event data
|
|
51
|
+
*/
|
|
52
|
+
export interface ConsumerResumedEvent {
|
|
53
|
+
consumerId: string;
|
|
54
|
+
participantId: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Participant joined event data
|
|
58
|
+
*/
|
|
59
|
+
export interface ParticipantJoinedEvent {
|
|
60
|
+
participantId: string;
|
|
61
|
+
userId: string;
|
|
62
|
+
deviceId: string;
|
|
63
|
+
position: Position;
|
|
64
|
+
direction: Direction;
|
|
65
|
+
mediaState: MediaState;
|
|
66
|
+
bodyHeight?: string;
|
|
67
|
+
bodyShape?: string;
|
|
68
|
+
userName?: string;
|
|
69
|
+
userEmail?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Participant left event data
|
|
73
|
+
*/
|
|
74
|
+
export interface ParticipantLeftEvent {
|
|
75
|
+
participantId: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Participant position updated event data
|
|
79
|
+
*/
|
|
80
|
+
export interface ParticipantPositionEvent {
|
|
81
|
+
participantId: string;
|
|
82
|
+
conferenceId: string;
|
|
83
|
+
roomId: string;
|
|
84
|
+
position: Position;
|
|
85
|
+
direction: Direction;
|
|
86
|
+
mediaState: MediaState;
|
|
87
|
+
consumerIds: string[];
|
|
88
|
+
timestamp: number;
|
|
89
|
+
bodyHeight?: string;
|
|
90
|
+
bodyShape?: string;
|
|
91
|
+
userName?: string;
|
|
92
|
+
userEmail?: string;
|
|
93
|
+
currentChannel?: string;
|
|
94
|
+
rot?: {
|
|
95
|
+
x: number;
|
|
96
|
+
y: number;
|
|
97
|
+
z: number;
|
|
98
|
+
};
|
|
99
|
+
pan?: number;
|
|
100
|
+
dxLocal?: number;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Mute state changed event data
|
|
104
|
+
*/
|
|
105
|
+
export interface MuteStateChangedEvent {
|
|
106
|
+
participantId: string;
|
|
107
|
+
muted: boolean;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Huddle invite received event data
|
|
111
|
+
*/
|
|
112
|
+
export interface HuddleInviteReceivedEvent {
|
|
113
|
+
inviteId: string;
|
|
114
|
+
fromParticipantId: string;
|
|
115
|
+
fromUserName?: string;
|
|
116
|
+
huddleId?: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Huddle response event data
|
|
120
|
+
*/
|
|
121
|
+
export interface HuddleResponseEvent {
|
|
122
|
+
success: boolean;
|
|
123
|
+
huddleId?: string;
|
|
124
|
+
channelId?: string;
|
|
125
|
+
participants?: string[];
|
|
126
|
+
error?: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* All SDK event types
|
|
130
|
+
*/
|
|
131
|
+
export type OdysseyEvent = "connected" | "disconnected" | "room-joined" | "all-participants-update" | "new-participant" | "participant-left" | "producer-created" | "consumer-created" | "consumer-closed" | "participant-media-state-updated" | "participant-position-updated" | "error" | "huddle-invite-received" | "private-huddle-started" | "huddle-updated" | "huddle-invite-rejected" | "huddle-ended" | "participant-channel-changed" | "mute-requested";
|
|
132
|
+
/**
|
|
133
|
+
* Event map for type-safe event handling
|
|
134
|
+
*/
|
|
135
|
+
export interface OdysseyEventMap {
|
|
136
|
+
'connected': void;
|
|
137
|
+
'disconnected': void;
|
|
138
|
+
'room-joined': RoomJoinedEvent;
|
|
139
|
+
'all-participants-update': Participant[];
|
|
140
|
+
'new-participant': Participant;
|
|
141
|
+
'participant-left': string;
|
|
142
|
+
'consumer-created': ConsumerCreatedEvent;
|
|
143
|
+
'consumer-closed': ConsumerClosedEvent;
|
|
144
|
+
'participant-media-state-updated': Participant;
|
|
145
|
+
'participant-position-updated': Participant;
|
|
146
|
+
'error': Error;
|
|
147
|
+
'huddle-invite-received': HuddleInviteReceivedEvent;
|
|
148
|
+
'private-huddle-started': HuddleResponseEvent;
|
|
149
|
+
'huddle-updated': any;
|
|
150
|
+
'huddle-invite-rejected': any;
|
|
151
|
+
'huddle-ended': any;
|
|
152
|
+
'participant-channel-changed': any;
|
|
153
|
+
'mute-requested': any;
|
|
154
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Types module - Re-exports all type definitions
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./position"), exports);
|
|
21
|
+
__exportStar(require("./participant"), exports);
|
|
22
|
+
__exportStar(require("./events"), exports);
|
|
23
|
+
__exportStar(require("./room"), exports);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Participant Types
|
|
3
|
+
*/
|
|
4
|
+
import { Position, Direction } from './position';
|
|
5
|
+
/**
|
|
6
|
+
* Media state for a participant
|
|
7
|
+
*/
|
|
8
|
+
export interface MediaState {
|
|
9
|
+
audio: boolean;
|
|
10
|
+
video: boolean;
|
|
11
|
+
sharescreen: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Full participant data
|
|
15
|
+
*/
|
|
16
|
+
export interface Participant {
|
|
17
|
+
participantId: string;
|
|
18
|
+
userId: string;
|
|
19
|
+
deviceId: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
avatarUrl?: string;
|
|
22
|
+
isLocal: boolean;
|
|
23
|
+
audioTrack?: MediaStreamTrack;
|
|
24
|
+
videoTrack?: MediaStreamTrack;
|
|
25
|
+
producers: Map<string, any>;
|
|
26
|
+
consumers: Map<string, any>;
|
|
27
|
+
position: Position;
|
|
28
|
+
direction: Direction;
|
|
29
|
+
mediaState: MediaState;
|
|
30
|
+
rot?: {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
z: number;
|
|
34
|
+
};
|
|
35
|
+
pan?: number;
|
|
36
|
+
dxLocal?: number;
|
|
37
|
+
bodyHeight?: string;
|
|
38
|
+
bodyShape?: string;
|
|
39
|
+
userName?: string;
|
|
40
|
+
userEmail?: string;
|
|
41
|
+
currentChannel?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Participant snapshot from server updates
|
|
45
|
+
*/
|
|
46
|
+
export interface ParticipantSnapshot {
|
|
47
|
+
participantId: string;
|
|
48
|
+
userId: string;
|
|
49
|
+
deviceId: string;
|
|
50
|
+
position: Position;
|
|
51
|
+
direction: Direction;
|
|
52
|
+
rot?: {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
z: number;
|
|
56
|
+
};
|
|
57
|
+
pan?: number;
|
|
58
|
+
dxLocal?: number;
|
|
59
|
+
bodyHeight: string;
|
|
60
|
+
bodyShape: string;
|
|
61
|
+
userName: string;
|
|
62
|
+
userEmail: string;
|
|
63
|
+
mediaState: MediaState;
|
|
64
|
+
currentChannel?: string;
|
|
65
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Position and Direction Types
|
|
3
|
+
*
|
|
4
|
+
* Coordinate system conventions:
|
|
5
|
+
* - Unreal Engine: X=forward, Y=right, Z=up (centimeters)
|
|
6
|
+
* - Standard/WebAudio: X=right, Y=up, Z=forward (meters)
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* 3D position in space
|
|
10
|
+
*/
|
|
11
|
+
export interface Position {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
z: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 3D direction vector (normalized)
|
|
18
|
+
*/
|
|
19
|
+
export interface Direction {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
z: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Rotation in degrees (Euler angles)
|
|
26
|
+
*/
|
|
27
|
+
export interface Rotation {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
z: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Listener right-ear vector (2D projection on XZ plane)
|
|
34
|
+
* Used for stereo panning calculations
|
|
35
|
+
*/
|
|
36
|
+
export interface ListenerRight {
|
|
37
|
+
x: number;
|
|
38
|
+
z: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Position in Unreal Engine coordinates (centimeters)
|
|
42
|
+
*/
|
|
43
|
+
export type UnrealPosition = Position;
|
|
44
|
+
/**
|
|
45
|
+
* Position in standard coordinates (meters)
|
|
46
|
+
*/
|
|
47
|
+
export type StandardPosition = Position;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Position and Direction Types
|
|
4
|
+
*
|
|
5
|
+
* Coordinate system conventions:
|
|
6
|
+
* - Unreal Engine: X=forward, Y=right, Z=up (centimeters)
|
|
7
|
+
* - Standard/WebAudio: X=right, Y=up, Z=forward (meters)
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Room and Transport Types
|
|
3
|
+
*/
|
|
4
|
+
import { Participant } from './participant';
|
|
5
|
+
import { Position, Direction } from './position';
|
|
6
|
+
/**
|
|
7
|
+
* Room state
|
|
8
|
+
*/
|
|
9
|
+
export interface Room {
|
|
10
|
+
id: string;
|
|
11
|
+
participants: Map<string, Participant>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Room joined data from server
|
|
15
|
+
*/
|
|
16
|
+
export interface RoomJoinedData {
|
|
17
|
+
participants: Participant[];
|
|
18
|
+
routerRtpCapabilities: any;
|
|
19
|
+
participantId: string;
|
|
20
|
+
roomId: string;
|
|
21
|
+
iceServers: any[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Join room request data
|
|
25
|
+
*/
|
|
26
|
+
export interface JoinRoomData {
|
|
27
|
+
roomId: string;
|
|
28
|
+
userId: string;
|
|
29
|
+
deviceId: string;
|
|
30
|
+
participantId?: string;
|
|
31
|
+
position: Position;
|
|
32
|
+
direction: Direction;
|
|
33
|
+
bodyHeight?: string;
|
|
34
|
+
bodyShape?: string;
|
|
35
|
+
userName?: string;
|
|
36
|
+
userEmail?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Consumer created data from server
|
|
40
|
+
*/
|
|
41
|
+
export interface ConsumerCreatedData {
|
|
42
|
+
consumerId: string;
|
|
43
|
+
producerId: string;
|
|
44
|
+
kind: 'audio' | 'video';
|
|
45
|
+
rtpParameters: any;
|
|
46
|
+
participantId: string;
|
|
47
|
+
conferenceId: string;
|
|
48
|
+
roomId: string;
|
|
49
|
+
position: Position;
|
|
50
|
+
direction: Direction;
|
|
51
|
+
mediaState: {
|
|
52
|
+
audio: boolean;
|
|
53
|
+
video: boolean;
|
|
54
|
+
sharescreen: boolean;
|
|
55
|
+
};
|
|
56
|
+
timestamp: number;
|
|
57
|
+
bodyHeight?: string;
|
|
58
|
+
bodyShape?: string;
|
|
59
|
+
userName?: string;
|
|
60
|
+
userEmail?: string;
|
|
61
|
+
appData?: {
|
|
62
|
+
isScreenshare?: boolean;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* WebRTC transport options
|
|
67
|
+
*/
|
|
68
|
+
export interface TransportOptions {
|
|
69
|
+
id: string;
|
|
70
|
+
iceParameters: any;
|
|
71
|
+
iceCandidates: any[];
|
|
72
|
+
dtlsParameters: any;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Producer options
|
|
76
|
+
*/
|
|
77
|
+
export interface ProducerOptions {
|
|
78
|
+
track: MediaStreamTrack;
|
|
79
|
+
appData?: {
|
|
80
|
+
isScreenshare?: boolean;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clarity Score Calculations
|
|
3
|
+
*
|
|
4
|
+
* Functions for calculating voice clarity based on distance and direction
|
|
5
|
+
*/
|
|
6
|
+
import { Position } from '../../types/position';
|
|
7
|
+
/**
|
|
8
|
+
* Calculate clarity score based on distance and direction
|
|
9
|
+
* Used for adjusting audio quality based on proximity and facing direction
|
|
10
|
+
*
|
|
11
|
+
* @param distance Distance to source
|
|
12
|
+
* @param vectorToSource Vector from listener to source
|
|
13
|
+
* @param listenerForward Listener's forward direction (optional)
|
|
14
|
+
* @returns Clarity score from 0 to 1
|
|
15
|
+
*/
|
|
16
|
+
export declare function calculateClarityScore(distance: number, vectorToSource: Position, listenerForward?: Position): number;
|
|
17
|
+
/**
|
|
18
|
+
* Calculate proximity weight based on distance
|
|
19
|
+
*
|
|
20
|
+
* @param distance Distance in meters
|
|
21
|
+
* @param closeRange Distance for full weight (default: 0.85m)
|
|
22
|
+
* @param fadeRange Distance for zero weight (default: 18m)
|
|
23
|
+
* @returns Weight from 0 to 1
|
|
24
|
+
*/
|
|
25
|
+
export declare function calculateProximityWeight(distance: number, closeRange?: number, fadeRange?: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a vector to unit length
|
|
28
|
+
*
|
|
29
|
+
* @param vector Vector to normalize
|
|
30
|
+
* @param fallback Fallback if vector is zero length
|
|
31
|
+
* @returns Normalized vector
|
|
32
|
+
*/
|
|
33
|
+
export declare function normalizeVector(vector: Position, fallback?: Position): Position;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Clarity Score Calculations
|
|
4
|
+
*
|
|
5
|
+
* Functions for calculating voice clarity based on distance and direction
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.calculateClarityScore = calculateClarityScore;
|
|
9
|
+
exports.calculateProximityWeight = calculateProximityWeight;
|
|
10
|
+
exports.normalizeVector = normalizeVector;
|
|
11
|
+
/**
|
|
12
|
+
* Calculate clarity score based on distance and direction
|
|
13
|
+
* Used for adjusting audio quality based on proximity and facing direction
|
|
14
|
+
*
|
|
15
|
+
* @param distance Distance to source
|
|
16
|
+
* @param vectorToSource Vector from listener to source
|
|
17
|
+
* @param listenerForward Listener's forward direction (optional)
|
|
18
|
+
* @returns Clarity score from 0 to 1
|
|
19
|
+
*/
|
|
20
|
+
function calculateClarityScore(distance, vectorToSource, listenerForward) {
|
|
21
|
+
const proximityWeight = calculateProximityWeight(distance);
|
|
22
|
+
const focusWeight = listenerForward
|
|
23
|
+
? calculateDirectionFocus(vectorToSource, listenerForward)
|
|
24
|
+
: 0.5;
|
|
25
|
+
return clamp(0.2 + proximityWeight * 0.6 + focusWeight * 0.2, 0, 1);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Calculate proximity weight based on distance
|
|
29
|
+
*
|
|
30
|
+
* @param distance Distance in meters
|
|
31
|
+
* @param closeRange Distance for full weight (default: 0.85m)
|
|
32
|
+
* @param fadeRange Distance for zero weight (default: 18m)
|
|
33
|
+
* @returns Weight from 0 to 1
|
|
34
|
+
*/
|
|
35
|
+
function calculateProximityWeight(distance, closeRange = 0.85, fadeRange = 18) {
|
|
36
|
+
if (distance <= closeRange) {
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
if (distance >= fadeRange) {
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
return 1 - (distance - closeRange) / (fadeRange - closeRange);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Calculate direction focus weight
|
|
46
|
+
* How much the listener is facing the source
|
|
47
|
+
*
|
|
48
|
+
* @param vectorToSource Vector from listener to source
|
|
49
|
+
* @param listenerForward Listener's forward direction
|
|
50
|
+
* @returns Focus weight from 0 to 1
|
|
51
|
+
*/
|
|
52
|
+
function calculateDirectionFocus(vectorToSource, listenerForward) {
|
|
53
|
+
const forward = normalizeVector(listenerForward);
|
|
54
|
+
const source = normalizeVector(vectorToSource, { x: 0, y: 0, z: 1 });
|
|
55
|
+
const dot = forward.x * source.x + forward.y * source.y + forward.z * source.z;
|
|
56
|
+
return clamp((dot + 1) / 2, 0, 1);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Normalize a vector to unit length
|
|
60
|
+
*
|
|
61
|
+
* @param vector Vector to normalize
|
|
62
|
+
* @param fallback Fallback if vector is zero length
|
|
63
|
+
* @returns Normalized vector
|
|
64
|
+
*/
|
|
65
|
+
function normalizeVector(vector, fallback = { x: 0, y: 0, z: 1 }) {
|
|
66
|
+
const length = Math.hypot(vector.x, vector.y, vector.z);
|
|
67
|
+
if (length < 1e-4) {
|
|
68
|
+
return { ...fallback };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
x: vector.x / length,
|
|
72
|
+
y: vector.y / length,
|
|
73
|
+
z: vector.z / length,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Clamp value between min and max
|
|
78
|
+
*/
|
|
79
|
+
function clamp(value, min, max) {
|
|
80
|
+
return Math.min(max, Math.max(min, value));
|
|
81
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Audio utilities - Re-exports all audio utility functions
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./clarity-score"), exports);
|
|
21
|
+
__exportStar(require("./voice-filter"), exports);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice Filter Calculations
|
|
3
|
+
*
|
|
4
|
+
* Functions for adaptive voice filtering
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Calculate adaptive highpass frequency based on voice characteristics
|
|
8
|
+
* Analyzes audio spectrum and returns optimal highpass cutoff (85-300Hz)
|
|
9
|
+
*
|
|
10
|
+
* @param frequencyData Frequency data from AnalyserNode
|
|
11
|
+
* @param sampleRate Audio sample rate
|
|
12
|
+
* @returns Optimal highpass frequency
|
|
13
|
+
*/
|
|
14
|
+
export declare function calculateAdaptiveHighpass(frequencyData: Uint8Array, sampleRate: number): number;
|
|
15
|
+
/**
|
|
16
|
+
* Voice filter chain configuration
|
|
17
|
+
*/
|
|
18
|
+
export interface VoiceFilterChain {
|
|
19
|
+
highpass: BiquadFilterNode;
|
|
20
|
+
lowpass: BiquadFilterNode;
|
|
21
|
+
voiceBand: BiquadFilterNode;
|
|
22
|
+
dynamicLowpass: BiquadFilterNode;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a voice-optimized filter chain
|
|
26
|
+
*
|
|
27
|
+
* @param audioContext AudioContext
|
|
28
|
+
* @returns Filter chain nodes
|
|
29
|
+
*/
|
|
30
|
+
export declare function createVoiceFilterChain(audioContext: AudioContext): VoiceFilterChain;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Voice Filter Calculations
|
|
4
|
+
*
|
|
5
|
+
* Functions for adaptive voice filtering
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.calculateAdaptiveHighpass = calculateAdaptiveHighpass;
|
|
9
|
+
exports.createVoiceFilterChain = createVoiceFilterChain;
|
|
10
|
+
/**
|
|
11
|
+
* Calculate adaptive highpass frequency based on voice characteristics
|
|
12
|
+
* Analyzes audio spectrum and returns optimal highpass cutoff (85-300Hz)
|
|
13
|
+
*
|
|
14
|
+
* @param frequencyData Frequency data from AnalyserNode
|
|
15
|
+
* @param sampleRate Audio sample rate
|
|
16
|
+
* @returns Optimal highpass frequency
|
|
17
|
+
*/
|
|
18
|
+
function calculateAdaptiveHighpass(frequencyData, sampleRate) {
|
|
19
|
+
const bufferLength = frequencyData.length;
|
|
20
|
+
const nyquist = sampleRate / 2;
|
|
21
|
+
const binWidth = nyquist / bufferLength;
|
|
22
|
+
let weightedSum = 0;
|
|
23
|
+
let totalEnergy = 0;
|
|
24
|
+
const maxBin = Math.floor(500 / binWidth); // Only analyze up to 500Hz
|
|
25
|
+
for (let i = 0; i < Math.min(maxBin, bufferLength); i++) {
|
|
26
|
+
const frequency = i * binWidth;
|
|
27
|
+
const magnitude = frequencyData[i] / 255.0;
|
|
28
|
+
weightedSum += frequency * magnitude;
|
|
29
|
+
totalEnergy += magnitude;
|
|
30
|
+
}
|
|
31
|
+
if (totalEnergy > 0.01) {
|
|
32
|
+
const centroid = weightedSum / totalEnergy;
|
|
33
|
+
// Map centroid to highpass frequency (85-300Hz)
|
|
34
|
+
// Lower centroid = deeper voice = use lower highpass (preserve bass)
|
|
35
|
+
// Higher centroid = higher voice = use higher highpass (remove mud)
|
|
36
|
+
return Math.max(85, Math.min(300, 85 + (centroid - 100) * 0.5));
|
|
37
|
+
}
|
|
38
|
+
// Default frequency if no significant energy
|
|
39
|
+
return 100;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a voice-optimized filter chain
|
|
43
|
+
*
|
|
44
|
+
* @param audioContext AudioContext
|
|
45
|
+
* @returns Filter chain nodes
|
|
46
|
+
*/
|
|
47
|
+
function createVoiceFilterChain(audioContext) {
|
|
48
|
+
// HIGHPASS FILTER: Remove low-frequency rumble and plosives
|
|
49
|
+
const highpass = audioContext.createBiquadFilter();
|
|
50
|
+
highpass.type = 'highpass';
|
|
51
|
+
highpass.frequency.value = 100; // Cut below 100Hz
|
|
52
|
+
highpass.Q.value = 0.5; // Gentle slope
|
|
53
|
+
// LOWPASS FILTER: Remove high-frequency hiss
|
|
54
|
+
const lowpass = audioContext.createBiquadFilter();
|
|
55
|
+
lowpass.type = 'lowpass';
|
|
56
|
+
lowpass.frequency.value = 10000; // Cut above 10kHz
|
|
57
|
+
lowpass.Q.value = 0.5;
|
|
58
|
+
// VOICE BAND EMPHASIS (disabled by default - can cause resonance)
|
|
59
|
+
const voiceBand = audioContext.createBiquadFilter();
|
|
60
|
+
voiceBand.type = 'peaking';
|
|
61
|
+
voiceBand.frequency.value = 180;
|
|
62
|
+
voiceBand.Q.value = 0.5;
|
|
63
|
+
voiceBand.gain.value = 0; // Disabled
|
|
64
|
+
// DYNAMIC LOWPASS for high-frequency control
|
|
65
|
+
const dynamicLowpass = audioContext.createBiquadFilter();
|
|
66
|
+
dynamicLowpass.type = 'lowpass';
|
|
67
|
+
dynamicLowpass.frequency.value = 12000;
|
|
68
|
+
dynamicLowpass.Q.value = 0.5;
|
|
69
|
+
return { highpass, lowpass, voiceBand, dynamicLowpass };
|
|
70
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utils module - Re-exports all utility functions
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./spatial"), exports);
|
|
21
|
+
__exportStar(require("./position"), exports);
|
|
22
|
+
__exportStar(require("./smoothing"), exports);
|
|
23
|
+
__exportStar(require("./audio"), exports);
|