@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
124 lines (123 loc) • 3.58 kB
JavaScript
;
import { NodeContext } from "../poly/NodeContext";
import { NamedFunction3, ObjectNamedFunction1, ObjectNamedFunction3 } from "./_Base";
import { Player } from "tone/build/esm/source/buffer/Player";
import { AudioPlayerCallbacksManager } from "../../core/audio/PlayerCallbacksManager";
import { ThreejsCoreObject } from "../../core/geometry/modules/three/ThreejsCoreObject";
export const AUDIO_ATTRIB_NAME_LAST_INSTRUMENT_TYPE = "__lastInstrumentType__";
export const AUDIO_ATTRIB_NAME_LAST_NOTE = "__lastNote__";
const listenersByAudioSource = /* @__PURE__ */ new Map();
function onAudioSourceStop(nodePath, listener) {
let listeners = listenersByAudioSource.get(nodePath);
if (!listeners) {
listeners = /* @__PURE__ */ new Set();
listenersByAudioSource.set(nodePath, listeners);
}
listeners.add(listener);
}
function removeAudioSourceStopListener(nodePath, listener) {
const listeners = listenersByAudioSource.get(nodePath);
if (!listeners) {
return;
}
listeners.delete(listener);
}
function dispatchAudioSourceStop(nodePath) {
const listeners = listenersByAudioSource.get(nodePath);
if (!listeners) {
return;
}
listeners.forEach((listener) => {
listener();
});
}
async function getAudioSource(scene, nodePath) {
const audioNode = scene.node(nodePath);
if (!audioNode) {
return;
}
if (audioNode.context() != NodeContext.AUDIO) {
return;
}
const container = await audioNode.compute();
const audioBuilder = container.coreContent();
if (!audioBuilder) {
return;
}
const source = audioBuilder.source();
if (!source) {
return;
}
if (!(source instanceof Player)) {
return;
}
return source;
}
export class addAudioStopEventListener extends NamedFunction3 {
static type() {
return "addAudioStopEventListener";
}
func(nodePath, listener, evaluator) {
onAudioSourceStop(nodePath, listener);
evaluator.onDispose(() => {
removeAudioSourceStopListener(nodePath, listener);
});
}
}
export class playAudioSource extends ObjectNamedFunction1 {
static type() {
return "playAudioSource";
}
func(object3D, nodePath) {
getAudioSource(this.scene, nodePath).then((source) => {
if (!source) {
return;
}
source.start();
AudioPlayerCallbacksManager.onStop(source, () => {
dispatchAudioSourceStop(nodePath);
});
});
}
}
export class pauseAudioSource extends ObjectNamedFunction1 {
static type() {
return "pauseAudioSource";
}
func(object3D, nodePath) {
getAudioSource(this.scene, nodePath).then((source) => {
if (!source) {
return;
}
source.stop();
});
}
}
export class playInstrumentNote extends ObjectNamedFunction3 {
static type() {
return "playInstrumentNote";
}
func(object3D, nodePath, note, duration) {
const audioNode = this.scene.node(nodePath);
if (!audioNode) {
return;
}
if (audioNode.context() != NodeContext.AUDIO) {
return;
}
audioNode.compute().then((container) => {
const audioBuilder = container.coreContent();
if (!audioBuilder) {
return;
}
const instrument = audioBuilder.instrument();
if (!instrument) {
return;
}
const lastInstrumentType = instrument.triggerAttackRelease(note, duration);
const lastNote = note;
ThreejsCoreObject.addAttribute(object3D, AUDIO_ATTRIB_NAME_LAST_INSTRUMENT_TYPE, lastInstrumentType);
ThreejsCoreObject.addAttribute(object3D, AUDIO_ATTRIB_NAME_LAST_NOTE, lastNote);
});
}
}