@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
155 lines (154 loc) • 4.75 kB
JavaScript
"use strict";
import { NodeParamsConfig, ParamConfig } from "../utils/params/ParamsConfig";
import { TypedEventNode } from "./_Base";
import { EventConnectionPoint, EventConnectionPointType } from "../utils/io/connections/Event";
import { ALL_NOTES, DEFAULT_NOTE } from "../../../core/audio/Notes";
import { NodeContext } from "../../poly/NodeContext";
import { AudioListenerObjNode } from "../obj/AudioListener";
import { Player } from "tone/build/esm/source/buffer/Player";
import { AudioPlayerCallbacksManager } from "./../../../core/audio/PlayerCallbacksManager";
export var AudioEventOutput = /* @__PURE__ */ ((AudioEventOutput2) => {
AudioEventOutput2["ON_STOP"] = "onStop";
return AudioEventOutput2;
})(AudioEventOutput || {});
class AudioEventParamsConfig extends NodeParamsConfig {
constructor() {
super(...arguments);
/** @parm audio node */
this.audio = ParamConfig.NODE_PATH("", {
nodeSelection: { context: NodeContext.AUDIO },
dependentOnFoundNode: false
});
/** @param note */
this.note = ParamConfig.STRING(DEFAULT_NOTE, {
menuString: {
entries: ALL_NOTES.sort().map((note) => {
return { value: note, name: note };
})
},
cook: false
});
/** @param duration */
this.duration = ParamConfig.FLOAT(0.125, {
range: [0, 1],
rangeLocked: [true, false],
cook: false
});
/** @param button to presse to trigger the event */
this.play = ParamConfig.BUTTON(null, {
callback: (node) => {
AudioEventNode.PARAM_CALLBACK_play(node);
}
});
}
/** @param button to presse to trigger the event */
// stop = ParamConfig.BUTTON(null, {
// callback: (node: BaseNodeType) => {
// AudioEventNode.PARAM_CALLBACK_stop(node as AudioEventNode);
// },
// });
}
const ParamsConfig = new AudioEventParamsConfig();
export class AudioEventNode extends TypedEventNode {
constructor() {
super(...arguments);
this.paramsConfig = ParamsConfig;
this._onSourcePlayerStopBound = this._onSourcePlayerStop.bind(this);
}
static type() {
return "audio";
}
initializeNode() {
this.io.inputs.setNamedInputConnectionPoints([
new EventConnectionPoint("play", EventConnectionPointType.BASE, this._triggerPlay.bind(this))
// new EventConnectionPoint('stop', EventConnectionPointType.BASE, this._triggerPlay.bind(this)),
]);
this.io.outputs.setNamedOutputConnectionPoints([
new EventConnectionPoint("onStop" /* ON_STOP */, EventConnectionPointType.BASE)
]);
}
_triggerPlay(context) {
this._play();
}
async _play() {
if (!AudioListenerObjNode.soundActivated()) {
console.warn("sound not activated");
return;
}
this.states.error.clear();
const playable = await this._getPlayable();
if (!playable) {
return;
}
const { instrument, source } = playable;
if (!(instrument || source)) {
return;
}
if (instrument) {
const note = this.pv.note;
if (note == "") {
return;
}
instrument.triggerAttackRelease(note, this.pv.duration);
} else {
if (source) {
if (source instanceof Player) {
this._sourcePlayer = source;
this._addPlayerEvent(source);
source.start();
}
}
}
}
dispose() {
super.dispose();
this._removePlayerEvent();
}
_addPlayerEvent(sourcePlayer) {
AudioPlayerCallbacksManager.onStop(sourcePlayer, this._onSourcePlayerStopBound);
}
_removePlayerEvent() {
if (!this._sourcePlayer) {
return;
}
AudioPlayerCallbacksManager.removeOnStop(this._sourcePlayer, this._onSourcePlayerStopBound);
}
_onSourcePlayerStop() {
this.dispatchEventToOutput("onStop" /* ON_STOP */, {});
}
// private _stop() {
// const instrument = await this._getInstrument()
// if(!instrument){return}
// instrument.triggerAttackRelease(this.pv.note, this.pv.duration)
// // if (this._prevNote) {
// // this._currentSynth.triggerRelease(undefined!);
// // }
// }
async _getPlayable() {
const param = this.p.audio;
if (param.isDirty()) {
await param.compute();
}
const node = param.value.nodeWithContext(NodeContext.AUDIO);
if (!node) {
return;
}
const container = await node.compute();
if (!container) {
return;
}
const audioBuilder = container.coreContent();
if (!audioBuilder) {
return;
}
const instrument = audioBuilder.instrument();
const source = audioBuilder.source();
return { instrument, source };
}
static PARAM_CALLBACK_play(node) {
node._play();
}
// static PARAM_CALLBACK_stop(node: AudioEventNode) {
// node._stop();
// }
}