UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

124 lines (123 loc) 3.58 kB
"use strict"; 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); }); } }