aboutsummaryrefslogtreecommitdiffstats
path: root/howler.js-2.0.0-beta4/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'howler.js-2.0.0-beta4/src/plugins')
-rw-r--r--howler.js-2.0.0-beta4/src/plugins/howler.effects.js603
1 files changed, 603 insertions, 0 deletions
diff --git a/howler.js-2.0.0-beta4/src/plugins/howler.effects.js b/howler.js-2.0.0-beta4/src/plugins/howler.effects.js
new file mode 100644
index 0000000..116a184
--- /dev/null
+++ b/howler.js-2.0.0-beta4/src/plugins/howler.effects.js
@@ -0,0 +1,603 @@
+/*!
+ * Effects Plugin - Adds advanced Web Audio API functionality.
+ *
+ * howler.js v2.0.0-beta4
+ * howlerjs.com
+ *
+ * (c) 2013-2015, James Simpson of GoldFire Studios
+ * goldfirestudios.com
+ *
+ * MIT License
+ */
+
+(function() {
+
+ 'use strict';
+
+ /** Global Methods **/
+ /***************************************************************************/
+
+ /**
+ * Add new properties to the core global init.
+ * @param {Function} _super Core global init method.
+ * @return {Howl}
+ */
+ HowlerGlobal.prototype.init = (function(_super) {
+ return function() {
+ var self = this;
+
+ // Setup default effects properties.
+ self._pos = [0, 0, 0];
+ self._orientation = [0, 0, -1, 0, 1, 0];
+ self._velocity = [0, 0, 0];
+ self._listenerAttr = {
+ dopplerFactor: 1,
+ speedOfSound: 343.3
+ };
+
+ // Complete initilization with howler.js core's global init function.
+ return _super.call(this, o);
+ };
+ })(HowlerGlobal.prototype.init);
+
+ /**
+ * Get/set the position of the listener in 3D cartesian space. Sounds using
+ * 3D position will be relative to the listener's position.
+ * @param {Number} x The x-position of the listener.
+ * @param {Number} y The y-position of the listener.
+ * @param {Number} z The z-position of the listener.
+ * @return {Howler/Array} Self or current listener position.
+ */
+ HowlerGlobal.prototype.pos = function(x, y, z) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self.ctx || !self.ctx.listener) {
+ return self;
+ }
+
+ // Set the defaults for optional 'y' & 'z'.
+ y = (typeof y !== 'number') ? self._pos[1] : y;
+ z = (typeof z !== 'number') ? self._pos[2] : z;
+
+ if (typeof x === 'number') {
+ self._pos = [x, y, z];
+ self.ctx.listener.setPosition(self._pos[0], self._pos[1], self._pos[2]);
+ } else {
+ return self._pos;
+ }
+
+ return self;
+ };
+
+ /**
+ * Get/set the direction the listener is pointing in the 3D cartesian space.
+ * A front and up vector must be provided. The front is the direction the
+ * face of the listener is pointing, and up is the direction the top of the
+ * listener is pointing. Thus, these values are expected to be at right angles
+ * from each other.
+ * @param {Number} x The x-orientation of the listener.
+ * @param {Number} y The y-orientation of the listener.
+ * @param {Number} z The z-orientation of the listener.
+ * @param {Number} xUp The x-orientation of the top of the listener.
+ * @param {Number} yUp The y-orientation of the top of the listener.
+ * @param {Number} zUp The z-orientation of the top of the listener.
+ * @return {Howler/Array} Returns self or the current orientation vectors.
+ */
+ HowlerGlobal.prototype.orientation = function(x, y, z, xUp, yUp, zUp) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self.ctx || !self.ctx.listener) {
+ return self;
+ }
+
+ // Set the defaults for optional 'y' & 'z'.
+ var or = self._orientation;
+ y = (typeof y !== 'number') ? or[1] : y;
+ z = (typeof z !== 'number') ? or[2] : z;
+ xUp = (typeof xUp !== 'number') ? or[3] : xUp;
+ yUp = (typeof yUp !== 'number') ? or[4] : yUp;
+ zUp = (typeof zUp !== 'number') ? or[5] : zUp;
+
+ if (typeof x === 'number') {
+ self._orientation = [x, y, z, xUp, yUp, zUp];
+ self.ctx.listener.setOrientation(or[0], or[1], or[2], or[3], or[4], or[5]);
+ } else {
+ return or;
+ }
+
+ return self;
+ };
+
+ /**
+ * Get/set the velocity vector of the listener. This controls both direction and speed
+ * in 3D space, and is combined relative to a sound's velocity to determine how much
+ * doppler shift (pitch change) to apply.
+ * @param {Number} x The x-velocity of the listener.
+ * @param {Number} y The y-velocity of the listener.
+ * @param {Number} z The z-velocity of the listener.
+ * @return {Howler/Array} Self or current listener velocity.
+ */
+ HowlerGlobal.prototype.velocity = function(x, y, z) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self.ctx || !self.ctx.listener) {
+ return self;
+ }
+
+ // Set the defaults for optional 'y' & 'z'.
+ y = (typeof y !== 'number') ? self._velocity[1] : y;
+ z = (typeof z !== 'number') ? self._velocity[2] : z;
+
+ if (typeof x === 'number') {
+ self._velocity = [x, y, z];
+ self.ctx.listener.setVelocity(self._velocity[0], self._velocity[1], self._velocity[2]);
+ } else {
+ return self._velocity;
+ }
+
+ return self;
+ };
+
+ /**
+ * Get/set the audio listener attributes.
+ * Attributes:
+ * dopplerFactor - (`1` by default) Determines the amount of pitch shift from doppler effect.
+ * speedOfSound - (`343.3` by default) Speed of sound used to calculate doppler shift.
+ * @param {Object} o The attributes to set.
+ * @return {Howl/Object} Returns self or current listener attributes.
+ */
+ HowlerGlobal.prototype.listenerAttr = function(o) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self.ctx || !self.ctx.listener) {
+ return self;
+ }
+
+ var la = self._listenerAttr;
+ if (o) {
+ // Update the listener attribute values.
+ self._listenerAttr = {
+ dopplerFactor: typeof o.dopplerFactor !== 'undefined' ? o.dopplerFactor : la.dopplerFactor,
+ speedOfSound: typeof o.speedOfSound !== 'undefined' ? o.speedOfSound : la.speedOfSound
+ };
+
+ // Apply the new values.
+ self.ctx.listener.dopplerFactor = la.dopplerFactor;
+ self.ctx.listener.speedOfSound = la.speedOfSound;
+ } else {
+ return la;
+ }
+
+ return self;
+ };
+
+ /** Group Methods **/
+ /***************************************************************************/
+
+ /**
+ * Add new properties to the core init.
+ * @param {Function} _super Core init method.
+ * @return {Howl}
+ */
+ Howl.prototype.init = (function(_super) {
+ return function(o) {
+ var self = this;
+
+ // Setup user-defined default properties.
+ self._orientation = o.orientation || [1, 0, 0];
+ self._pos = o.pos || null;
+ self._velocity = o.velocity || [0, 0, 0];
+ self._pannerAttr = {
+ coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : 360,
+ coneOUterAngle: typeof o.coneOUterAngle !== 'undefined' ? o.coneOUterAngle : 360,
+ coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : 0,
+ distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : 'inverse',
+ maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : 10000,
+ panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : 'HRTF',
+ refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : 1,
+ rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : 1
+ };
+
+ // Complete initilization with howler.js core's init function.
+ return _super.call(this, o);
+ };
+ })(Howl.prototype.init);
+
+ /**
+ * Get/set the 3D spatial position of the audio source for this sound or
+ * all in the group. The most common usage is to set the 'x' position for
+ * left/right panning. Setting any value higher than 1.0 will begin to
+ * decrease the volume of the sound as it moves further away.
+ * @param {Number} x The x-position of the audio from -1000.0 to 1000.0.
+ * @param {Number} y The y-position of the audio from -1000.0 to 1000.0.
+ * @param {Number} z The z-position of the audio from -1000.0 to 1000.0.
+ * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.
+ * @return {Howl/Array} Returns self or the current 3D spatial position: [x, y, z].
+ */
+ Howl.prototype.pos = function(x, y, z, id) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self._webAudio) {
+ return self;
+ }
+
+ // Wait for the sound to play before changing position.
+ if (!self._loaded) {
+ self.once('play', function() {
+ self.pos(x, y, z, id);
+ });
+
+ return self;
+ }
+
+ // Set the defaults for optional 'y' & 'z'.
+ y = (typeof y !== 'number') ? 0 : y;
+ z = (typeof z !== 'number') ? -0.5 : z;
+
+ // Setup the group's spatial position if no ID is passed.
+ if (typeof id === 'undefined') {
+ // Return the group's spatial position if no parameters are passed.
+ if (typeof x === 'number') {
+ self._pos = [x, y, z];
+ } else {
+ return self._pos;
+ }
+ }
+
+ // Change the spatial position of one or all sounds in group.
+ var ids = self._getSoundIds(id);
+ for (var i=0; i<ids.length; i++) {
+ // Get the sound.
+ var sound = self._soundById(ids[i]);
+
+ if (sound) {
+ if (typeof x === 'number') {
+ sound._pos = [x, y, z];
+
+ if (sound._node) {
+ // Check if there is a panner setup and create a new one if not.
+ if (!sound._panner) {
+ setupPanner(sound);
+ }
+
+ sound._panner.setPosition(x, y, z);
+ }
+ } else {
+ return sound._pos;
+ }
+ }
+ }
+
+ return self;
+ };
+
+ /**
+ * Get/set the direction the audio source is pointing in the 3D cartesian coordinate
+ * space. Depending on how direction the sound is, based on the `cone` attributes,
+ * a sound pointing away from the listener can be quiet or silent.
+ * @param {Number} x The x-orientation of the source.
+ * @param {Number} y The y-orientation of the source.
+ * @param {Number} z The z-orientation of the source.
+ * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.
+ * @return {Howl/Array} Returns self or the current 3D spatial orientation: [x, y, z].
+ */
+ Howl.prototype.orientation = function(x, y, z, id) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self._webAudio) {
+ return self;
+ }
+
+ // Wait for the sound to play before changing orientation.
+ if (!self._loaded) {
+ self.once('play', function() {
+ self.orientation(x, y, z, id);
+ });
+
+ return self;
+ }
+
+ // Set the defaults for optional 'y' & 'z'.
+ y = (typeof y !== 'number') ? self._orientation[1] : y;
+ z = (typeof z !== 'number') ? self._orientation[1] : z;
+
+ // Setup the group's spatial orientation if no ID is passed.
+ if (typeof id === 'undefined') {
+ // Return the group's spatial orientation if no parameters are passed.
+ if (typeof x === 'number') {
+ self._orientation = [x, y, z];
+ } else {
+ return self._orientation;
+ }
+ }
+
+ // Change the spatial orientation of one or all sounds in group.
+ var ids = self._getSoundIds(id);
+ for (var i=0; i<ids.length; i++) {
+ // Get the sound.
+ var sound = self._soundById(ids[i]);
+
+ if (sound) {
+ if (typeof x === 'number') {
+ sound._orientation = [x, y, z];
+
+ if (sound._node) {
+ // Check if there is a panner setup and create a new one if not.
+ if (!sound._panner) {
+ setupPanner(sound);
+ }
+
+ sound._panner.setOrientation(x, y, z);
+ }
+ } else {
+ return sound._orientation;
+ }
+ }
+ }
+
+ return self;
+ };
+
+ /**
+ * Get/set the velocity vector of the audio source or group. This controls both
+ * direction and speed in 3D space and is relative to the listener's velocity.
+ * The units are meters/second and are independent of position and orientation.
+ * @param {Number} x The x-velocity of the source.
+ * @param {Number} y The y-velocity of the source.
+ * @param {Number} z The z-velocity of the source.
+ * @param {Number} id (optional) The sound ID. If none is passed, all in group will be updated.
+ * @return {Howl/Array} Returns self or the current 3D spatial velocity: [x, y, z].
+ */
+ Howl.prototype.velocity = function(x, y, z, id) {
+ var self = this;
+
+ // Stop right here if not using Web Audio.
+ if (!self._webAudio) {
+ return self;
+ }
+
+ // Wait for the sound to play before changing velocity.
+ if (!self._loaded) {
+ self.once('play', function() {
+ self.velocity(x, y, z, id);
+ });
+
+ return self;
+ }
+
+ // Set the defaults for optional 'y' & 'z'.
+ y = (typeof y !== 'number') ? self._velocity[1] : y;
+ z = (typeof z !== 'number') ? self._velocity[1] : z;
+
+ // Setup the group's spatial velocity if no ID is passed.
+ if (typeof id === 'undefined') {
+ // Return the group's spatial velocity if no parameters are passed.
+ if (typeof x === 'number') {
+ self._velocity = [x, y, z];
+ } else {
+ return self._velocity;
+ }
+ }
+
+ // Change the spatial velocity of one or all sounds in group.
+ var ids = self._getSoundIds(id);
+ for (var i=0; i<ids.length; i++) {
+ // Get the sound.
+ var sound = self._soundById(ids[i]);
+
+ if (sound) {
+ if (typeof x === 'number') {
+ sound._velocity = [x, y, z];
+
+ if (sound._node) {
+ // Check if there is a panner setup and create a new one if not.
+ if (!sound._panner) {
+ setupPanner(sound);
+ }
+
+ sound._panner.setVelocity(x, y, z);
+ }
+ } else {
+ return sound._velocity;
+ }
+ }
+ }
+
+ return self;
+ };
+
+ /**
+ * Get/set the panner node's attributes for a sound or group of sounds.
+ * This method can optionall take 0, 1 or 2 arguments.
+ * pannerAttr() -> Returns the group's values.
+ * pannerAttr(id) -> Returns the sound id's values.
+ * pannerAttr(o) -> Set's the values of all sounds in this Howl group.
+ * pannerAttr(o, id) -> Set's the values of passed sound id.
+ *
+ * Attributes:
+ * coneInnerAngle - (360 by default) There will be no volume reduction inside this angle.
+ * coneOUterAngle - (360 by default) The volume will be reduced to a constant value of
+ * `coneOuterGain` outside this angle.
+ * coneOuterGain - (0 by default) The amount of volume reduction outside of `coneOuterAngle`.
+ * distanceModel - ('inverse' by default) Determines algorithm to use to reduce volume as audio moves
+ * away from listener. Can be `linear`, `inverse` or `exponential.
+ * maxDistance - (10000 by default) Volume won't reduce between source/listener beyond this distance.
+ * panningModel - ('HRTF' by default) Determines which spatialization algorithm is used to position audio.
+ * Can be `HRTF` or `equalpower`.
+ * refDistance - (1 by default) A reference distance for reducing volume as the source
+ * moves away from the listener.
+ * rolloffFactor - (1 by default) How quickly the volume reduces as source moves from listener.
+ *
+ * @return {Howl/Object} Returns self or current panner attributes.
+ */
+ Howl.prototype.pannerAttr = function() {
+ var self = this;
+ var args = arguments;
+ var o, id, sound;
+
+ // Stop right here if not using Web Audio.
+ if (!self._webAudio) {
+ return self;
+ }
+
+ // Determine the values based on arguments.
+ if (args.length === 0) {
+ // Return the group's panner attribute values.
+ return self._pannerAttr;
+ } else if (args.length === 1) {
+ if (typeof args[0] === 'object') {
+ o = args[0];
+
+ // Set the grou's panner attribute values.
+ if (typeof id === 'undefined') {
+ self._pannerAttr = {
+ coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : self._coneInnerAngle,
+ coneOUterAngle: typeof o.coneOUterAngle !== 'undefined' ? o.coneOUterAngle : self._coneOUterAngle,
+ coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : self._coneOuterGain,
+ distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : self._distanceModel,
+ maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : self._maxDistance,
+ panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : self._panningModel,
+ refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : self._refDistance,
+ rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : self._rolloffFactor
+ };
+ }
+ } else {
+ // Return this sound's panner attribute values.
+ sound = self._soundById(parseInt(args[0], 10));
+ return sound ? sound._pannerAttr : self._pannerAttr;
+ }
+ } else if (args.length === 2) {
+ o = args[0];
+ id = parseInt(args[1], 10);
+ }
+
+ // Update the values of the specified sounds.
+ var ids = self._getSoundIds(id);
+ for (var i=0; i<ids.length; i++) {
+ sound = self._soundById(ids[i]);
+
+ if (sound) {
+ // Merge the new values into the sound.
+ var pa = sound._pannerAttr;
+ pa = {
+ coneInnerAngle: typeof o.coneInnerAngle !== 'undefined' ? o.coneInnerAngle : pa.coneInnerAngle,
+ coneOUterAngle: typeof o.coneOUterAngle !== 'undefined' ? o.coneOUterAngle : pa.coneOUterAngle,
+ coneOuterGain: typeof o.coneOuterGain !== 'undefined' ? o.coneOuterGain : pa.coneOuterGain,
+ distanceModel: typeof o.distanceModel !== 'undefined' ? o.distanceModel : pa.distanceModel,
+ maxDistance: typeof o.maxDistance !== 'undefined' ? o.maxDistance : pa.maxDistance,
+ panningModel: typeof o.panningModel !== 'undefined' ? o.panningModel : pa.panningModel,
+ refDistance: typeof o.refDistance !== 'undefined' ? o.refDistance : pa.refDistance,
+ rolloffFactor: typeof o.rolloffFactor !== 'undefined' ? o.rolloffFactor : pa.rolloffFactor
+ };
+
+ // Update the panner values or create a new panner if none exists.
+ var panner = sound._panner;
+ if (panner) {
+ panner.coneInnerAngle = pa.coneInnerAngle;
+ panner.coneOUterAngle = pa.coneOUterAngle;
+ panner.coneOuterGain = pa.coneOuterGain;
+ panner.distanceModel = pa.distanceModel;
+ panner.maxDistance = pa.maxDistance;
+ panner.panningModel = pa.panningModel;
+ panner.refDistance = pa.refDistance;
+ panner.rolloffFactor = pa.rolloffFactor;
+ } else {
+ // Make sure we have a position to setup the node with.
+ if (!sound._pos) {
+ sound._pos = self._pos || [0, 0, -0.5];
+ }
+
+ // Create a new panner node.
+ setupPanner(sound);
+ }
+ }
+ }
+
+ return self;
+ };
+
+ /** Single Sound Methods **/
+ /***************************************************************************/
+
+ /**
+ * Add new properties to the core Sound init.
+ * @param {Function} _super Core Sound init method.
+ * @return {Sound}
+ */
+ Sound.prototype.init = (function(_super) {
+ return function() {
+ var self = this;
+ var parent = self._parent;
+
+ // Setup user-defined default properties.
+ self._orientation = parent._orientation;
+ self._pos = parent._pos;
+ self._velocity = parent._velocity;
+ self._pannerAttr = parent._pannerAttr;
+
+ // Complete initilization with howler.js core Sound's init function.
+ _super.call(this);
+
+ // If a position was specified, set it up.
+ if (self._pos) {
+ parent.pos(self._pos[0], self._pos[1], self._pos[2], self._id);
+ }
+ };
+ })(Sound.prototype.init);
+
+ /**
+ * Override the Sound.reset method to clean up properties from the effects plugin.
+ * @param {Function} _super Sound reset method.
+ * @return {Sound}
+ */
+ Sound.prototype.reset = (function(_super) {
+ return function() {
+ var self = this;
+ var parent = self._parent;
+
+ // Reset all effects module properties on this sound.
+ self._orientation = parent._orientation;
+ self._pos = parent._pos;
+ self._velocity = parent._velocity;
+ self._pannerAttr = parent._pannerAttr;
+
+ // Complete resetting of the sound.
+ return _super.call(this);
+ };
+ })(Sound.prototype.reset);
+
+ /** Helper Methods **/
+ /***************************************************************************/
+
+ /**
+ * Create a new panner node and save it on the sound.
+ * @param {Sound} sound Specific sound to setup panning on.
+ */
+ var setupPanner = function(sound) {
+ // Create the new panner node.
+ sound._panner = Howler.ctx.createPanner();
+ sound._panner.coneInnerAngle = sound._pannerAttr.coneInnerAngle;
+ sound._panner.coneOUterAngle = sound._pannerAttr.coneOUterAngle;
+ sound._panner.coneOuterGain = sound._pannerAttr.coneOuterGain;
+ sound._panner.distanceModel = sound._pannerAttr.distanceModel;
+ sound._panner.maxDistance = sound._pannerAttr.maxDistance;
+ sound._panner.panningModel = sound._pannerAttr.panningModel;
+ sound._panner.refDistance = sound._pannerAttr.refDistance;
+ sound._panner.rolloffFactor = sound._pannerAttr.rolloffFactor;
+ sound._panner.setPosition(sound._pos[0], sound._pos[1], sound._pos[2]);
+ sound._panner.setOrientation(sound._orientation[0], sound._orientation[1], sound._orientation[2]);
+ sound._panner.setVelocity(sound._velocity[0], sound._velocity[1], sound._velocity[2]);
+ sound._panner.connect(sound._node);
+
+ // Update the connections.
+ if (!sound._paused) {
+ sound._parent.pause(sound._id).play(sound._id);
+ }
+ };
+})();