mirror of
https://github.com/Tonejs/Tone.js
synced 2024-12-29 04:53:10 +00:00
328 lines
8 KiB
JavaScript
328 lines
8 KiB
JavaScript
import Tone from "../core/Tone";
|
|
import "../component/CrossFade";
|
|
import "../component/Merge";
|
|
import "../component/Split";
|
|
import "../signal/Signal";
|
|
import "../signal/AudioToGain";
|
|
import "../signal/Zero";
|
|
import "../core/AudioNode";
|
|
|
|
/**
|
|
* @class A spatialized panner node which supports equalpower or HRTF panning.
|
|
* Tries to normalize the API across various browsers. See Tone.Listener
|
|
*
|
|
* @constructor
|
|
* @extends {Tone.AudioNode}
|
|
* @param {Number} positionX The initial x position.
|
|
* @param {Number} positionY The initial y position.
|
|
* @param {Number} positionZ The initial z position.
|
|
*/
|
|
Tone.Panner3D = function(){
|
|
|
|
var options = Tone.defaults(arguments, ["positionX", "positionY", "positionZ"], Tone.Panner3D);
|
|
Tone.AudioNode.call(this);
|
|
|
|
/**
|
|
* The panner node
|
|
* @type {PannerNode}
|
|
* @private
|
|
*/
|
|
this._panner = this.input = this.output = this.context.createPanner();
|
|
//set some values
|
|
this._panner.panningModel = options.panningModel;
|
|
this._panner.maxDistance = options.maxDistance;
|
|
this._panner.distanceModel = options.distanceModel;
|
|
this._panner.coneOuterGain = options.coneOuterGain;
|
|
this._panner.coneOuterAngle = options.coneOuterAngle;
|
|
this._panner.coneInnerAngle = options.coneInnerAngle;
|
|
this._panner.refDistance = options.refDistance;
|
|
this._panner.rolloffFactor = options.rolloffFactor;
|
|
|
|
/**
|
|
* Holds the current orientation
|
|
* @type {Array}
|
|
* @private
|
|
*/
|
|
this._orientation = [options.orientationX, options.orientationY, options.orientationZ];
|
|
|
|
/**
|
|
* Holds the current position
|
|
* @type {Array}
|
|
* @private
|
|
*/
|
|
this._position = [options.positionX, options.positionY, options.positionZ];
|
|
|
|
// set the default position/orientation
|
|
this.orientationX = options.orientationX;
|
|
this.orientationY = options.orientationY;
|
|
this.orientationZ = options.orientationZ;
|
|
this.positionX = options.positionX;
|
|
this.positionY = options.positionY;
|
|
this.positionZ = options.positionZ;
|
|
};
|
|
|
|
Tone.extend(Tone.Panner3D, Tone.AudioNode);
|
|
|
|
/**
|
|
* Defaults according to the specification
|
|
* @static
|
|
* @const
|
|
* @type {Object}
|
|
*/
|
|
Tone.Panner3D.defaults = {
|
|
"positionX" : 0,
|
|
"positionY" : 0,
|
|
"positionZ" : 0,
|
|
"orientationX" : 0,
|
|
"orientationY" : 0,
|
|
"orientationZ" : 0,
|
|
"panningModel" : "equalpower",
|
|
"maxDistance" : 10000,
|
|
"distanceModel" : "inverse",
|
|
"coneOuterGain" : 0,
|
|
"coneOuterAngle" : 360,
|
|
"coneInnerAngle" : 360,
|
|
"refDistance" : 1,
|
|
"rolloffFactor" : 1
|
|
};
|
|
|
|
/**
|
|
* The ramp time which is applied to the setTargetAtTime
|
|
* @type {Number}
|
|
* @private
|
|
*/
|
|
Tone.Panner3D.prototype._rampTimeConstant = 0.01;
|
|
|
|
/**
|
|
* Sets the position of the source in 3d space.
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @param {Number} z
|
|
* @return {Tone.Panner3D} this
|
|
*/
|
|
Tone.Panner3D.prototype.setPosition = function(x, y, z){
|
|
if (this._panner.positionX){
|
|
var now = this.now();
|
|
this._panner.positionX.setTargetAtTime(x, now, this._rampTimeConstant);
|
|
this._panner.positionY.setTargetAtTime(y, now, this._rampTimeConstant);
|
|
this._panner.positionZ.setTargetAtTime(z, now, this._rampTimeConstant);
|
|
} else {
|
|
this._panner.setPosition(x, y, z);
|
|
}
|
|
this._position = Array.prototype.slice.call(arguments);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Sets the orientation of the source in 3d space.
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
* @param {Number} z
|
|
* @return {Tone.Panner3D} this
|
|
*/
|
|
Tone.Panner3D.prototype.setOrientation = function(x, y, z){
|
|
if (this._panner.orientationX){
|
|
var now = this.now();
|
|
this._panner.orientationX.setTargetAtTime(x, now, this._rampTimeConstant);
|
|
this._panner.orientationY.setTargetAtTime(y, now, this._rampTimeConstant);
|
|
this._panner.orientationZ.setTargetAtTime(z, now, this._rampTimeConstant);
|
|
} else {
|
|
this._panner.setOrientation(x, y, z);
|
|
}
|
|
this._orientation = Array.prototype.slice.call(arguments);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* The x position of the panner object.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name positionX
|
|
*/
|
|
Object.defineProperty(Tone.Panner3D.prototype, "positionX", {
|
|
set : function(pos){
|
|
this._position[0] = pos;
|
|
this.setPosition.apply(this, this._position);
|
|
},
|
|
get : function(){
|
|
return this._position[0];
|
|
}
|
|
});
|
|
|
|
/**
|
|
* The y position of the panner object.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name positionY
|
|
*/
|
|
Object.defineProperty(Tone.Panner3D.prototype, "positionY", {
|
|
set : function(pos){
|
|
this._position[1] = pos;
|
|
this.setPosition.apply(this, this._position);
|
|
},
|
|
get : function(){
|
|
return this._position[1];
|
|
}
|
|
});
|
|
|
|
/**
|
|
* The z position of the panner object.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name positionZ
|
|
*/
|
|
Object.defineProperty(Tone.Panner3D.prototype, "positionZ", {
|
|
set : function(pos){
|
|
this._position[2] = pos;
|
|
this.setPosition.apply(this, this._position);
|
|
},
|
|
get : function(){
|
|
return this._position[2];
|
|
}
|
|
});
|
|
|
|
/**
|
|
* The x orientation of the panner object.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name orientationX
|
|
*/
|
|
Object.defineProperty(Tone.Panner3D.prototype, "orientationX", {
|
|
set : function(pos){
|
|
this._orientation[0] = pos;
|
|
this.setOrientation.apply(this, this._orientation);
|
|
},
|
|
get : function(){
|
|
return this._orientation[0];
|
|
}
|
|
});
|
|
|
|
/**
|
|
* The y orientation of the panner object.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name orientationY
|
|
*/
|
|
Object.defineProperty(Tone.Panner3D.prototype, "orientationY", {
|
|
set : function(pos){
|
|
this._orientation[1] = pos;
|
|
this.setOrientation.apply(this, this._orientation);
|
|
},
|
|
get : function(){
|
|
return this._orientation[1];
|
|
}
|
|
});
|
|
|
|
/**
|
|
* The z orientation of the panner object.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name orientationZ
|
|
*/
|
|
Object.defineProperty(Tone.Panner3D.prototype, "orientationZ", {
|
|
set : function(pos){
|
|
this._orientation[2] = pos;
|
|
this.setOrientation.apply(this, this._orientation);
|
|
},
|
|
get : function(){
|
|
return this._orientation[2];
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Proxy a property on the panner to an exposed public propery
|
|
* @param {String} prop
|
|
* @private
|
|
*/
|
|
Tone.Panner3D._aliasProperty = function(prop){
|
|
Object.defineProperty(Tone.Panner3D.prototype, prop, {
|
|
set : function(val){
|
|
this._panner[prop] = val;
|
|
},
|
|
get : function(){
|
|
return this._panner[prop];
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* The panning model. Either "equalpower" or "HRTF".
|
|
* @type {String}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name panningModel
|
|
*/
|
|
Tone.Panner3D._aliasProperty("panningModel");
|
|
|
|
/**
|
|
* A reference distance for reducing volume as source move further from the listener
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name refDistance
|
|
*/
|
|
Tone.Panner3D._aliasProperty("refDistance");
|
|
|
|
/**
|
|
* Describes how quickly the volume is reduced as source moves away from listener.
|
|
* @type {Number}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name rolloffFactor
|
|
*/
|
|
Tone.Panner3D._aliasProperty("rolloffFactor");
|
|
|
|
/**
|
|
* The distance model used by, "linear", "inverse", or "exponential".
|
|
* @type {String}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name distanceModel
|
|
*/
|
|
Tone.Panner3D._aliasProperty("distanceModel");
|
|
|
|
/**
|
|
* The angle, in degrees, inside of which there will be no volume reduction
|
|
* @type {Degrees}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name coneInnerAngle
|
|
*/
|
|
Tone.Panner3D._aliasProperty("coneInnerAngle");
|
|
|
|
/**
|
|
* The angle, in degrees, outside of which the volume will be reduced
|
|
* to a constant value of coneOuterGain
|
|
* @type {Degrees}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name coneOuterAngle
|
|
*/
|
|
Tone.Panner3D._aliasProperty("coneOuterAngle");
|
|
|
|
/**
|
|
* The gain outside of the coneOuterAngle
|
|
* @type {Gain}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name coneOuterGain
|
|
*/
|
|
Tone.Panner3D._aliasProperty("coneOuterGain");
|
|
|
|
/**
|
|
* The maximum distance between source and listener,
|
|
* after which the volume will not be reduced any further.
|
|
* @type {Positive}
|
|
* @memberOf Tone.Panner3D#
|
|
* @name maxDistance
|
|
*/
|
|
Tone.Panner3D._aliasProperty("maxDistance");
|
|
|
|
/**
|
|
* Clean up.
|
|
* @returns {Tone.Panner3D} this
|
|
*/
|
|
Tone.Panner3D.prototype.dispose = function(){
|
|
Tone.AudioNode.prototype.dispose.call(this);
|
|
this._panner.disconnect();
|
|
this._panner = null;
|
|
this._orientation = null;
|
|
this._position = null;
|
|
return this;
|
|
};
|
|
|
|
export default Tone.Panner3D;
|
|
|