Skip to content

Commit

Permalink
Update Audio Target System to use APP.audios
Browse files Browse the repository at this point in the history
  • Loading branch information
keianhzo committed Mar 15, 2023
1 parent f58c67b commit 1eb7da7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 51 deletions.
3 changes: 2 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MediaSearchStore from "./storage/media-search-store";
import Store from "./storage/store";
import qsTruthy from "./utils/qs_truthy";

import type { AElement, AScene } from "aframe";
import type { AComponent, AScene } from "aframe";
import HubChannel from "./utils/hub-channel";
import MediaDevicesManager from "./utils/media-devices-manager";

Expand Down Expand Up @@ -75,6 +75,7 @@ export class App {
entryManager?: SceneEntryManager;
messageDispatch?: any;
store: Store;
componentRegistry: { [key: string]: AComponent[] };

mediaSearchStore = new MediaSearchStore();

Expand Down
95 changes: 49 additions & 46 deletions src/bit-systems/audio-target-system.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { AComponent, AElement } from "aframe";
import { addComponent, defineQuery, enterQuery, exitQuery } from "bitecs";
import { Vector3, Object3D, LineSegments, WireframeGeometry, SphereBufferGeometry, PositionalAudio } from "three";
import { HubsWorld } from "../app";
import { AudioEmitter, AudioSettingsChanged, AudioSource, AudioTarget } from "../bit-components";
import { AudioSettingsChanged, AudioSource, AudioTarget } from "../bit-components";
import { SourceType } from "../components/audio-params";
import { getMediaStream } from "../components/avatar-audio-source";
import { AUDIO_SOURCE_FLAGS } from "../inflators/audio-source";
import { AudioSystem } from "../systems/audio-system";
import { Emitter2Audio, makeAudioEntity } from "./audio-emitter-system";
Expand All @@ -23,7 +25,7 @@ const createWhiteNoise = (audioContext: AudioContext, gain: number): AudioBuffer
return whiteNoise;
};

const addSourceToAudioTarget = (audioSourceEid: number, source: AudioBufferSourceNode) => {
const addSourceToAudioTarget = (audioSourceEid: number, source: AudioNode) => {
const audioTargetEids = source2Target.get(audioSourceEid);
audioTargetEids?.forEach(audioTargetEid => {
const audioEid = Emitter2Audio.get(audioTargetEid)!;
Expand All @@ -34,7 +36,7 @@ const addSourceToAudioTarget = (audioSourceEid: number, source: AudioBufferSourc
if (targetAudio instanceof PositionalAudio) {
targetAudio.panner.connect(targetAudio.gain);
}
targetAudio.setNodeSource(source);
targetAudio.setNodeSource(source as AudioBufferSourceNode);
targetAudio.connect();
});
};
Expand Down Expand Up @@ -69,14 +71,11 @@ const connectSourceToTarget = (audioSourceEid: number, audioTargetEid: number) =

const source2Noise = new Map<number, AudioBufferSourceNode>();
const source2Target = new Map<number, Array<number>>();
const source2Emitter = new Map<number, number>();
const source2Emitter = new Map<number, AElement>();
const source2Radius = new Map<number, number>();
const source2Debug = new Map<number, Object3D>();
const sourceWorldPos = new Vector3();
const emitterWorldPos = new Vector3();

const audioEmitterQuery = defineQuery([AudioEmitter]);
const audioEmitterExitQuery = exitQuery(audioEmitterQuery);
const audioTargetQuery = defineQuery([AudioTarget]);
const audioTargetEnterQuery = enterQuery(audioTargetQuery);
const audioTargetExitQuery = exitQuery(audioTargetQuery);
Expand All @@ -86,16 +85,6 @@ const audioSourceExitQuery = exitQuery(audioSourceQuery);
export function audioTargetSystem(world: HubsWorld, audioSystem: AudioSystem) {
const audioTargetEids = audioTargetQuery(world);
const audioSourceEids = audioSourceQuery(world);
audioEmitterExitQuery(world).forEach(audioEmitterEid => {
const audioSourceEids = [...source2Emitter]
.filter(([_, emitterEid]) => emitterEid === audioEmitterEid)
.map(([audioSourceEid, _]) => audioSourceEid);
audioSourceEids.forEach(audioSourceEid => {
source2Emitter.delete(audioSourceEid)!;
const whiteNoise = source2Noise.get(audioSourceEid)!;
addSourceToAudioTarget(audioSourceEid, whiteNoise);
});
});
audioTargetEnterQuery(world).forEach(audioTargetEid => {
const ctx = APP.audioListener.context;
const audioEid = makeAudioEntity(world, audioTargetEid, SourceType.AUDIO_TARGET, audioSystem);
Expand Down Expand Up @@ -162,45 +151,59 @@ export function audioTargetSystem(world: HubsWorld, audioSystem: AudioSystem) {
}
});
audioSourceEids.forEach(audioSourceEid => {
const obj = APP.world.eid2obj.get(audioSourceEid)!;
obj.updateMatrixWorld();
obj.getWorldPosition(sourceWorldPos);
const radius = source2Radius.get(audioSourceEid)!;
const currentEmitterEid = source2Emitter.get(audioSourceEid)!;
if (currentEmitterEid) {
const currentEmitterAudio = APP.audios.get(currentEmitterEid)!;
currentEmitterAudio.getWorldPosition(emitterWorldPos);
const distanceSquared = emitterWorldPos.distanceToSquared(sourceWorldPos);
if (distanceSquared > radius) {
const playerInfos = APP.componentRegistry["player-info"];
if (source2Emitter.has(audioSourceEid)) {
const emitterId = source2Emitter.get(audioSourceEid)!;
const playerInfoExists = playerInfos.find((playerInfo: AComponent) => playerInfo.el === emitterId);
if (playerInfoExists) {
const distanceSquared = emitterId.object3D.position.distanceToSquared(sourceWorldPos);
const radius = source2Radius.get(audioSourceEid)!;
if (distanceSquared > radius) {
source2Emitter.delete(audioSourceEid);
if (AudioSource.flags[audioSourceEid] & AUDIO_SOURCE_FLAGS.DEBUG) {
const whiteNoise = source2Noise.get(audioSourceEid)!;
addSourceToAudioTarget(audioSourceEid, whiteNoise);
}
}
} else {
source2Emitter.delete(audioSourceEid);
if (AudioSource.flags[audioSourceEid] & AUDIO_SOURCE_FLAGS.DEBUG) {
const whiteNoise = source2Noise.get(audioSourceEid)!;
addSourceToAudioTarget(audioSourceEid, whiteNoise);
}
APP.mutedState.delete(currentEmitterEid);
addComponent(world, AudioSettingsChanged, currentEmitterEid);
}
} else {
audioEmitterQuery(world).every(audioEmitterEid => {
const sourceType = APP.sourceType.get(audioEmitterEid);
if (sourceType === SourceType.AUDIO_TARGET) return true;
if (sourceType === SourceType.AVATAR_AUDIO_SOURCE) {
// Check permissions
}
const emitterAudio = APP.audios.get(audioEmitterEid)!;
emitterAudio.getWorldPosition(emitterWorldPos);
const distanceSquared = emitterWorldPos.distanceToSquared(sourceWorldPos);
for (let i = 0; i < playerInfos.length; i++) {
const playerInfo = playerInfos[i];
const avatar = playerInfo.el;

if (
AudioSource.flags[audioSourceEid] & AUDIO_SOURCE_FLAGS.ONLY_MODS &&
!(playerInfo as any).can("amplify_audio")
)
continue;

// don't use avatar-rig if not entering scene yet.
if (avatar.id === "avatar-rig" && !APP.scene!.is("entered")) continue;

const distanceSquared = avatar.object3D.position.distanceToSquared(sourceWorldPos);
const radius = source2Radius.get(audioSourceEid)!;
if (distanceSquared < radius) {
source2Emitter.set(audioSourceEid, audioEmitterEid);
if (AudioSource.flags[audioSourceEid] & AUDIO_SOURCE_FLAGS.MUTE_SELF) {
APP.mutedState.add(audioEmitterEid);
addComponent(world, AudioSettingsChanged, audioEmitterEid);
source2Emitter.set(audioSourceEid, avatar);
const muteSelf = AudioSource.flags[audioSourceEid] & AUDIO_SOURCE_FLAGS.MUTE_SELF;
const isOwnAvatar = avatar.id === "avatar-rig";
if (muteSelf && isOwnAvatar) {
removeSourceFromAudioTarget(audioSourceEid);
} else {
getMediaStream(avatar).then(stream => {
const audioListener = APP.audioListener;
const ctx = audioListener.context;
const node = ctx.createMediaStreamSource(stream);
addSourceToAudioTarget(audioSourceEid, node);
});
}
emitterAudio.source && addSourceToAudioTarget(audioSourceEid, emitterAudio.source);
return false;
}
return true;
});
}
}
});
}
2 changes: 1 addition & 1 deletion src/components/avatar-audio-source.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ async function getOwnerId(el) {
return networkedEl.components.networked.data.owner;
}

async function getMediaStream(el) {
export async function getMediaStream(el) {
const peerId = await getOwnerId(el);
if (!peerId) {
console.error(INFO_INIT_FAILED, INFO_NO_OWNER);
Expand Down
7 changes: 4 additions & 3 deletions types/aframe.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ declare module "aframe" {
};
getObject3D(string): Object3D?;
components: { [s: string]: AComponent };
eid: number;
isPlaying: boolean;
}

type FnTick = (t: number, dt: number) => void;
Expand All @@ -18,7 +20,7 @@ declare module "aframe" {
tick: FnTick;
tock: FnTick;
remove();
el: AScene;
el: Scene;
}

interface AComponent {
Expand All @@ -27,7 +29,7 @@ declare module "aframe" {
tick: FnTick;
tock: FnTick;
remove();
el: AScene;
el: AElement;
}

interface HubsSystems extends ASystem {
Expand Down Expand Up @@ -99,7 +101,6 @@ declare module "aframe" {
renderStarted: boolean;
renderer: WebGLRenderer;
tick(time: number, delta: number): void;
isPlaying: boolean;
behaviors: {
tick: AComponent[];
tock: AComponent[];
Expand Down

0 comments on commit 1eb7da7

Please sign in to comment.