Update framework

This commit is contained in:
2022-11-26 02:22:02 +01:00
parent 9a6ce1f832
commit ae057940af
508 changed files with 26011 additions and 14248 deletions

View File

@@ -0,0 +1,37 @@
import ResonatorAudioContext from '../audio-context';
import AudioGraph from '../audio-graph';
import ResonatorScene from '../scenes/webaudio-scene';
import { BaseSource } from './base-source';
import { SourceType } from './source-type';
export default class AudioSource implements BaseSource {
playing: boolean;
looping: boolean;
private node;
private sceneNode;
private buffer;
private context;
private graph;
private scene;
private playOnLoad;
private position;
private playbackRate;
private volume;
private gain;
private type;
constructor(graph: AudioGraph, scene: ResonatorScene, context: ResonatorAudioContext, buffer?: AudioBuffer, type?: SourceType);
init(): void;
getBuffer(): AudioBuffer;
setBuffer(data: AudioBuffer): void;
play(when?: number, offset?: number, duration?: number): void;
setPosition(x: number, y: number, z: number): void;
setPlaybackRate(rate: number): void;
getPlaybackRate(): number;
setVolume(volume: number): void;
getVolume(): number;
private createConnections;
stop(): void;
destroy(): void;
loop(value: boolean): void;
fadeOut(time: number): void;
fadeIn(time: number): void;
}

View File

@@ -0,0 +1,148 @@
// an audio source
// This is the actual sound
import { SourceType } from './source-type';
export default class AudioSource {
constructor(graph, scene, context, buffer = null, type = SourceType.WorldSource) {
this.position = {
x: 0,
y: 0,
z: 0
};
this.buffer = buffer;
this.context = context;
this.scene = scene;
this.graph = graph;
this.type = type;
this.playbackRate = 1;
this.volume = 1;
this.init();
}
init() {
this.gain = this.context.createGain();
// bind methods so we can add and removve them from event listeners
this.stop = this.stop.bind(this);
}
getBuffer() {
return this.buffer;
}
setBuffer(data) {
this.buffer = data;
if (this.playOnLoad) {
this.play();
this.playOnLoad = false;
}
}
play(when = 0, offset = 0, duration = this.buffer ? this.buffer.duration : 0) {
if (this.playing && this.node) {
this.stop();
}
if (!this.buffer) {
this.playOnLoad = true;
return;
}
if (!this.node) {
this.node = this.context.createBufferSource();
this.node.buffer = this.buffer;
this.createConnections();
}
if (this.node) {
this.node.playbackRate.value = this.playbackRate;
this.node.start(when, offset, duration);
this.node.loop = this.looping;
this.playing = true;
if (this.sceneNode) {
this.sceneNode.setPosition(this.position.x, this.position.y, this.position.z);
}
this.node.addEventListener('ended', this.stop);
}
}
setPosition(x, y, z) {
this.position = {
x,
y,
z
};
if (this.sceneNode)
this.sceneNode.setPosition(x, y, z);
}
setPlaybackRate(rate) {
this.playbackRate = rate;
if (this.node)
this.node.playbackRate.value = rate;
}
getPlaybackRate() {
return this.playbackRate;
}
setVolume(volume) {
this.volume = volume;
if (this.gain)
this.gain.gain.value = volume;
}
getVolume() {
return this.volume;
}
createConnections() {
switch (this.type) {
case SourceType.WorldSource:
if (!this.sceneNode) {
this.sceneNode = this.scene.createSource();
}
this.node.connect(this.gain);
this.gain.connect(this.sceneNode);
break;
case SourceType.UISource:
this.node.connect(this.gain);
this.graph.connectToUI(this.gain);
break;
default:
this.node.connect(this.gain);
this.graph.connectToMaster(this.gain);
break;
}
}
stop() {
this.playing = false;
if (this.node) {
this.node.removeEventListener('ended', this.stop);
this.node.stop();
this.node.disconnect();
this.node = null;
this.playing = false;
if (this.sceneNode) {
this.sceneNode.disconnect();
this.sceneNode = null;
}
}
}
destroy() {
this.stop();
// set all refs to null to encourage gc
this.node = null;
this.sceneNode = null;
this.buffer = null;
this.context = null;
this.graph = null;
this.scene = null;
}
loop(value) {
this.looping = value;
if (this.node) {
this.node.loop = value;
}
}
fadeOut(time) {
this.gain.gain.setValueAtTime(this.getVolume(), this.context.getContext().currentTime);
if (!this.node) {
return;
}
this.gain.gain.exponentialRampToValueAtTime(0.0001, this.context.getContext().currentTime + time);
setTimeout(() => this.stop(), time * 1000);
}
fadeIn(time) {
this.gain.gain.setValueAtTime(0.0001, this.context.getContext().currentTime);
if (!this.node) {
this.play();
}
this.gain.gain.exponentialRampToValueAtTime(this.volume, this.context.getContext().currentTime + time);
}
}

View File

@@ -0,0 +1,12 @@
export interface BaseSource {
play(when: number, offset: number, duration: number): void;
stop(): void;
setPlaybackRate(value: number): void;
getPlaybackRate(): number;
setVolume(value: number): void;
getVolume(): number;
loop(value: boolean): void;
fadeOut(time: number): void;
fadeIn(time: number): void;
destroy(): void;
}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,5 @@
export declare enum SourceType {
WorldSource = 0,
UISource = 1,
MasterSource = 2
}

View File

@@ -0,0 +1,6 @@
export var SourceType;
(function (SourceType) {
SourceType[SourceType["WorldSource"] = 0] = "WorldSource";
SourceType[SourceType["UISource"] = 1] = "UISource";
SourceType[SourceType["MasterSource"] = 2] = "MasterSource";
})(SourceType || (SourceType = {}));

View File

@@ -0,0 +1,33 @@
import { BaseSource } from './base-source';
import AudioGraph from '../audio-graph';
import ResonatorScene from '../scenes/webaudio-scene';
import ResonatorAudioContext from '../audio-context';
import { SourceType } from './source-type';
export declare class StreamingSource implements BaseSource {
private graph;
private scene;
private context;
private element;
private type;
playing: boolean;
private playOnAvailable;
private node;
private canPlay;
private sceneNode;
private gain;
private position;
constructor(graph: AudioGraph, scene: ResonatorScene, context: ResonatorAudioContext, element: HTMLAudioElement, type?: SourceType);
private init;
play(when?: number, offset?: number, duration?: number): void;
stop(): void;
getVolume(): number;
setVolume(value: number): void;
getPlaybackRate(): number;
setPlaybackRate(value: number): void;
private createConnections;
setPosition(x: number, y: number, z: number): void;
destroy(): void;
loop(value: boolean): void;
fadeIn(time: number): void;
fadeOut(time: number): void;
}

View File

@@ -0,0 +1,99 @@
import { SourceType } from './source-type';
export class StreamingSource {
constructor(graph, scene, context, element, type = SourceType.MasterSource) {
this.graph = graph;
this.scene = scene;
this.context = context;
this.element = element;
this.type = type;
this.position = {
x: 0,
y: 0,
z: 0
};
this.init();
}
init() {
this.node = this.context.createMediaElementSource(this.element);
this.gain = this.context.createGain();
this.createConnections();
this.element.addEventListener('canplay', (event) => {
this.canPlay = true;
if (this.playOnAvailable) {
this.play();
}
});
}
play(when = 0, offset = 0, duration = 0) {
if (this.canPlay) {
this.element.play();
}
this.playOnAvailable = true;
}
stop() {
this.element.pause();
}
getVolume() {
return this.element.volume;
}
setVolume(value) {
this.element.volume = value;
}
getPlaybackRate() {
return this.element.playbackRate;
}
setPlaybackRate(value) {
this.element.playbackRate = value;
}
createConnections() {
switch (this.type) {
case SourceType.WorldSource:
if (!this.sceneNode) {
this.sceneNode = this.scene.createSource();
}
this.node.connect(this.gain);
this.gain.connect(this.sceneNode);
break;
default:
this.node.connect(this.gain);
this.graph.connectToMaster(this.gain);
break;
}
}
setPosition(x, y, z) {
this.position = {
x,
y,
z
};
if (this.sceneNode)
this.sceneNode.setPosition(x, y, z);
}
destroy() {
this.stop();
this.element = null;
this.graph = null;
this.context = null;
this.node = null;
this.sceneNode = null;
this.scene = null;
}
loop(value) {
this.element.loop = true;
}
fadeIn(time) {
this.gain.gain.setValueAtTime(0.0001, this.context.getContext().currentTime);
if (!this.node) {
this.play();
}
this.gain.gain.exponentialRampToValueAtTime(this.getVolume(), this.context.getContext().currentTime + time);
}
fadeOut(time) {
this.gain.gain.setValueAtTime(this.getVolume(), this.context.getContext().currentTime);
if (!this.node) {
return;
}
this.gain.gain.exponentialRampToValueAtTime(0.0001, this.context.getContext().currentTime + time);
setTimeout(() => this.stop(), time * 1000);
}
}