Tone.js/Tone/component/channel/Panner3D.ts
2019-12-21 22:07:05 -05:00

234 lines
5.9 KiB
TypeScript

import { Param } from "../../core/context/Param";
import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode";
import { Degrees, GainFactor } from "../../core/type/Units";
import { optionsFromArguments } from "../../core/util/Defaults";
import "../../core/context/Listener";
export interface Panner3DOptions extends ToneAudioNodeOptions {
coneInnerAngle: Degrees;
coneOuterAngle: Degrees;
coneOuterGain: GainFactor;
distanceModel: DistanceModelType;
maxDistance: number;
orientationX: number;
orientationY: number;
orientationZ: number;
panningModel: PanningModelType;
positionX: number;
positionY: number;
positionZ: number;
refDistance: number;
rolloffFactor: number;
}
/**
* A spatialized panner node which supports equalpower or HRTF panning.
* @category Component
*/
export class Panner3D extends ToneAudioNode<Panner3DOptions> {
readonly name: string = "Panner3D";
/**
* The panning object
*/
private _panner: PannerNode;
readonly input: PannerNode;
readonly output: PannerNode;
readonly positionX: Param<"number">;
readonly positionY: Param<"number">;
readonly positionZ: Param<"number">;
readonly orientationX: Param<"number">;
readonly orientationY: Param<"number">;
readonly orientationZ: Param<"number">;
/**
* @param positionX The initial x position.
* @param positionY The initial y position.
* @param positionZ The initial z position.
*/
constructor(positionX: number, positionY: number, positionZ: number);
constructor(options?: Partial<Panner3DOptions>);
constructor() {
super(optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]));
const options = optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]);
this._panner = this.input = this.output = this.context.createPanner();
// set some values
this.panningModel = options.panningModel;
this.maxDistance = options.maxDistance;
this.distanceModel = options.distanceModel;
this.coneOuterGain = options.coneOuterGain;
this.coneOuterAngle = options.coneOuterAngle;
this.coneInnerAngle = options.coneInnerAngle;
this.refDistance = options.refDistance;
this.rolloffFactor = options.rolloffFactor;
this.positionX = new Param({
context: this.context,
param: this._panner.positionX,
value: options.positionX,
});
this.positionY = new Param({
context: this.context,
param: this._panner.positionY,
value: options.positionY,
});
this.positionZ = new Param({
context: this.context,
param: this._panner.positionZ,
value: options.positionZ,
});
this.orientationX = new Param({
context: this.context,
param: this._panner.orientationX,
value: options.orientationX,
});
this.orientationY = new Param({
context: this.context,
param: this._panner.orientationY,
value: options.orientationY,
});
this.orientationZ = new Param({
context: this.context,
param: this._panner.orientationZ,
value: options.orientationZ,
});
}
static getDefaults(): Panner3DOptions {
return Object.assign(ToneAudioNode.getDefaults(), {
coneInnerAngle: 360,
coneOuterAngle: 360,
coneOuterGain: 0,
distanceModel: "inverse" as DistanceModelType,
maxDistance: 10000,
orientationX: 0,
orientationY: 0,
orientationZ: 0,
panningModel: "equalpower" as PanningModelType,
positionX: 0,
positionY: 0,
positionZ: 0,
refDistance: 1,
rolloffFactor: 1,
});
}
/**
* Sets the position of the source in 3d space.
*/
setPosition(x: number, y: number, z: number): this {
this.positionX.value = x;
this.positionY.value = y;
this.positionZ.value = z;
return this;
}
/**
* Sets the orientation of the source in 3d space.
*/
setOrientation(x: number, y: number, z: number): this {
this.orientationX.value = x;
this.orientationY.value = y;
this.orientationZ.value = z;
return this;
}
/**
* The panning model. Either "equalpower" or "HRTF".
*/
get panningModel(): PanningModelType {
return this._panner.panningModel;
}
set panningModel(val) {
this._panner.panningModel = val;
}
/**
* A reference distance for reducing volume as source move further from the listener
*/
get refDistance(): number {
return this._panner.refDistance;
}
set refDistance(val) {
this._panner.refDistance = val;
}
/**
* Describes how quickly the volume is reduced as source moves away from listener.
*/
get rolloffFactor(): number {
return this._panner.rolloffFactor;
}
set rolloffFactor(val) {
this._panner.rolloffFactor = val;
}
/**
* The distance model used by, "linear", "inverse", or "exponential".
*/
get distanceModel(): DistanceModelType {
return this._panner.distanceModel;
}
set distanceModel(val) {
this._panner.distanceModel = val;
}
/**
* The angle, in degrees, inside of which there will be no volume reduction
*/
get coneInnerAngle(): Degrees {
return this._panner.coneInnerAngle;
}
set coneInnerAngle(val) {
this._panner.coneInnerAngle = val;
}
/**
* The angle, in degrees, outside of which the volume will be reduced
* to a constant value of coneOuterGain
*/
get coneOuterAngle(): Degrees {
return this._panner.coneOuterAngle;
}
set coneOuterAngle(val) {
this._panner.coneOuterAngle = val;
}
/**
* The gain outside of the coneOuterAngle
*/
get coneOuterGain(): GainFactor {
return this._panner.coneOuterGain;
}
set coneOuterGain(val) {
this._panner.coneOuterGain = val;
}
/**
* The maximum distance between source and listener,
* after which the volume will not be reduced any further.
*/
get maxDistance(): number {
return this._panner.maxDistance;
}
set maxDistance(val) {
this._panner.maxDistance = val;
}
dispose(): this {
super.dispose();
this._panner.disconnect();
this.orientationX.dispose();
this.orientationY.dispose();
this.orientationZ.dispose();
this.positionX.dispose();
this.positionY.dispose();
this.positionZ.dispose();
return this;
}
}