text: 
  
  /**
   * Tutorials:
   * http://www.html5rocks.com/en/tutorials/webaudio/games/
   * http://www.html5rocks.com/en/tutorials/webaudio/positional_audio/ <- +1 as it is three.js
   * http://www.html5rocks.com/en/tutorials/webaudio/intro/
   *
   * Spec:
   * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
   *
   * Chromium Demo:
   * http://chromium.googlecode.com/svn/trunk/samples/audio/index.html  <- running page
   * http://code.google.com/p/chromium/source/browse/trunk/samples/audio/ <- source
  */
  
  
  /**
   * Notes on removing tQuery dependancy
   * * some stuff depends on tQuery
   * * find which one
   * * tQuery.Webaudio got a world link for the listener
   *   * do a plugin with followListener(world), unfollowListener(world)
   * * namespace become WebAudio.* instead of WebAudio.*
  */
  
  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////
  //		WebAudio							//
  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////
  
  
  /**
   * Main class to handle webkit audio
   * 
   * TODO make the clip detector from http://www.html5rocks.com/en/tutorials/webaudio/games/
   *
   * @class Handle webkit audio API
   *
   * @param {tQuery.World} [world] the world on which to run 
  */
  WebAudio	= function(){
  	// sanity check - the api MUST be available
  	console.assert(WebAudio.isAvailable === true, 'webkitAudioContext isnt available on your browser');
  
  	// create the context
  	this._ctx	= new webkitAudioContext();
  
  	// setup the end of the node chain
  	// TODO later code the clipping detection from http://www.html5rocks.com/en/tutorials/webaudio/games/ 
  	this._gainNode	= this._ctx.createGainNode();
  	this._compressor= this._ctx.createDynamicsCompressor();
  	this._gainNode.connect( this._compressor );
  	this._compressor.connect( this._ctx.destination );	
  };
  
  
  /**
   * vendor.js way to make plugins ala jQuery
   * @namespace
  */
  WebAudio.fn	= WebAudio.prototype;
  
  
  /**
   * destructor
  */
  WebAudio.prototype.destroy	= function(){
  };
  
  /**
   * 
   *
   * @return {Boolean} true if it is available or not
  */
  WebAudio.isAvailable	= window.webkitAudioContext ? true : false;
  
  //////////////////////////////////////////////////////////////////////////////////
  //										//
  //////////////////////////////////////////////////////////////////////////////////
  
  /**
   * get the audio context
   *
   * @returns {AudioContext} the audio context
  */
  WebAudio.prototype.context	= function(){
  	return this._ctx;
  };
  
  /**
   * Create a sound
   *
   * @returns {WebAudio.Sound} the sound just created
  */
  WebAudio.prototype.createSound	= function()
  {
  	var webaudio	= this;
  	var sound	= new WebAudio.Sound(webaudio);
  	return sound;
  }
  
  
  /**
   * return the entry node in the master node chains
  */
  WebAudio.prototype._entryNode	= function(){
  	//return this._ctx.destination;
  	return this._gainNode;
  }
  
  /**
   * getter/setter on the volume
  */
  WebAudio.prototype.volume	= function(value){
  	if( value === undefined )	return this._gainNode.gain.value;
  	this._gainNode.gain.value	= value;
  	return this;
  };
  
  /**
   * Constructor
   *
   * @class builder to generate nodes chains. Used in WebAudio.Sound
   * @param {webkitAudioContext} audioContext the audio context
  */
  WebAudio.NodeChainBuilder	= function(audioContext){
  	console.assert( audioContext instanceof webkitAudioContext );
  	this._context	= audioContext;
  	this._firstNode	= null;
  	this._lastNode	= null;
  	this._nodes	= {};
  };
  
  /**
   * destructor
  */
  WebAudio.NodeChainBuilder.prototype.destroy	= function(){
  };
  
  /**
   * getter for the nodes
  */
  WebAudio.NodeChainBuilder.prototype.nodes	= function(){
  	return this._nodes;
  }
  
  /**
   * @returns the first node of the chain
  */
  WebAudio.NodeChainBuilder.prototype.first	= function(){
  	return this._firstNode;
  }
  
  /**
   * @returns the last node of the chain
  */
  WebAudio.NodeChainBuilder.prototype.last	= function(){
  	return this._lastNode;
  }
  
  WebAudio.NodeChainBuilder.prototype._addNode	= function(node, properties)
  {
  	// update this._bufferSourceDst - needed for .cloneBufferSource()
  	var lastIsBufferSource	= this._lastNode && ('playbackRate' in this._lastNode) ? true : false;
  	if( lastIsBufferSource )	this._bufferSourceDst	= node;
  
  	// connect this._lastNode to node if suitable
  	if( this._lastNode !== null )	this._lastNode.connect(node);
  	
  	// update this._firstNode && this._lastNode
  	if( this._firstNode === null )	this._firstNode	= node;
  	this._lastNode	= node;
  		
  	// apply properties to the node
  	for( var property in properties ){
  		node[property]	= properties[property];
  	}
  
  	// for chained API
  	return this;
  };
  
  
  /**
   * Clone the bufferSource. Used just before playing a sound
   * @returns {AudioBufferSourceNode} the clone AudioBufferSourceNode
  */
  WebAudio.NodeChainBuilder.prototype.cloneBufferSource	= function(){
  	console.assert(this._nodes.bufferSource, "no buffersource presents. Add one.");
  	var orig	= this._nodes.bufferSource;
  	var clone	= this._context.createBufferSource()
  	clone.buffer		= orig.buffer;
  	clone.playbackRate	= orig.playbackRate;
  	clone.loop		= orig.loop;
  	clone.connect(this._bufferSourceDst);
  	return clone;
  }
  
  /**
   * add a bufferSource
   *
   * @param {Object} [properties] properties to set in the created node
  */
  WebAudio.NodeChainBuilder.prototype.bufferSource	= function(properties){
  	var node		= this._context.createBufferSource()
  	this._nodes.bufferSource= node;
  	return this._addNode(node, properties)
  };
  
  /**
   * add a panner
   * 
   * @param {Object} [properties] properties to set in the created node
  */
  WebAudio.NodeChainBuilder.prototype.panner	= function(properties){
  	var node		= this._context.createPanner()
  	this._nodes.panner	= node;
  	return this._addNode(node, properties)
  };
  
  /**
   * add a analyser
   *
   * @param {Object} [properties] properties to set in the created node
  */
  WebAudio.NodeChainBuilder.prototype.analyser	= function(properties){
  	var node		= this._context.createAnalyser()
  	this._nodes.analyser	= node;
  	return this._addNode(node, properties)
  };
  
  /**
   * add a gainNode
   *
   * @param {Object} [properties] properties to set in the created node
  */
  WebAudio.NodeChainBuilder.prototype.gainNode	= function(properties){
  	var node		= this._context.createGainNode()
  	this._nodes.gainNode	= node;
  	return this._addNode(node, properties)
  };
  
  /**
   * sound instance
   *
   * @class Handle one sound for WebAudio
   *
   * @param {tQuery.World} [world] the world on which to run
   * @param {WebAudio.NodeChainBuilder} [nodeChain] the nodeChain to use
  */
  WebAudio.Sound	= function(webaudio, nodeChain){
  	this._webaudio	= webaudio;
  	this._context	= this._webaudio.context();
  
  	console.assert( this._webaudio instanceof WebAudio );
  
  	// create a default NodeChainBuilder if needed
  	if( nodeChain === undefined ){
  		nodeChain	= new WebAudio.NodeChainBuilder(this._context)
  					.bufferSource().gainNode().analyser().panner();
  	}
  	// setup this._chain
  	console.assert( nodeChain instanceof WebAudio.NodeChainBuilder );
  	this._chain	= nodeChain;
  
  	// connect this._chain.last() node to this._webaudio._entryNode()
  	this._chain.last().connect( this._webaudio._entryNode() );
  	
  	// create some alias
  	this._source	= this._chain.nodes().bufferSource;
  	this._gainNode	= this._chain.nodes().gainNode;
  	this._analyser	= this._chain.nodes().analyser;
  	this._panner	= this._chain.nodes().panner;
  	
  	// sanity check
  	console.assert(this._source	, "no bufferSource: not yet supported")
  	console.assert(this._gainNode	, "no gainNode: not yet supported")
  	console.assert(this._analyser	, "no analyser: not yet supported")
  	console.assert(this._panner	, "no panner: not yet supported")
  };
  
  /**
   * destructor
  */
  WebAudio.Sound.prototype.destroy	= function(){
  	// disconnect from this._webaudio
  	this._chain.last().disconnect();
  	// destroy this._chain
  	this._chain.destroy();
  	this._chain	= null;
  };
  
  /**
   * vendor.js way to make plugins ala jQuery
   * @namespace
  */
  WebAudio.Sound.fn	= WebAudio.Sound.prototype;
  
  //////////////////////////////////////////////////////////////////////////////////
  //										//
  //////////////////////////////////////////////////////////////////////////////////
  
  /**
   * getter of the chain nodes
  */
  WebAudio.Sound.prototype.nodes	= function(){
  	return this._chain.nodes();
  };
  
  /**
   * @returns {Boolean} true if the sound is playable, false otherwise
  */
  WebAudio.Sound.prototype.isPlayable	= function(){
  	return this._source.buffer ? true : false;
  };
  
  /**
   * play the sound
   *
   * @param {Number} [time] time when to play the sound
  */
  WebAudio.Sound.prototype.play		= function(time){
  	if( time ===  undefined )	time	= 0;
  	// clone the bufferSource
  	var clonedNode	= this._chain.cloneBufferSource();
  	// set the noteOn
  	clonedNode.noteOn(time);
  	// create the source object
  	var source	= {
  		node	: clonedNode,
  		stop	: function(time){
  			if( time ===  undefined )	time	= 0;
  			this.node.noteOff(time);
  			return source;	// for chained API
  		}
  	}
  	// return it
  	return source;
  };
  
  /**
   * getter/setter on the volume
   *
   * @param {Number} [value] the value to set, if not provided, get current value
  */
  WebAudio.Sound.prototype.volume	= function(value){
  	if( value === undefined )	return this._gainNode.gain.value;
  	this._gainNode.gain.value	= value;
  	return this;	// for chained API
  };
  
  
  /**
   * getter/setter on the loop
   * 
   * @param {Number} [value] the value to set, if not provided, get current value
  */
  WebAudio.Sound.prototype.loop	= function(value){
  	if( value === undefined )	return this._source.loop;
  	this._source.loop	= value;
  	return this;	// for chained API
  };
  
  /**
   * getter/setter on the source buffer
   * 
   * @param {Number} [value] the value to set, if not provided, get current value
  */
  WebAudio.Sound.prototype.buffer	= function(value){
  	if( value === undefined )	return this._source.buffer;
  	this._source.buffer	= value;
  	return this;	// for chained API
  };
  
  
  /**
   * Set parameter for the pannerCone
   *
   * @param {Number} innerAngle the inner cone hangle in radian
   * @param {Number} outerAngle the outer cone hangle in radian
   * @param {Number} outerGain the gain to apply when in the outerCone
  */
  WebAudio.Sound.prototype.pannerCone	= function(innerAngle, outerAngle, outerGain)
  {
  	this._panner.coneInnerAngle	= innerAngle * 180 / Math.PI;
  	this._panner.coneOuterAngle	= outerAngle * 180 / Math.PI;
  	this._panner.coneOuterGain	= outerGain;
  	return this;	// for chained API
  };
  
  /**
   * getter/setter on the pannerConeInnerAngle
   * 
   * @param {Number} value the angle in radian
  */
  WebAudio.Sound.prototype.pannerConeInnerAngle	= function(value){
  	if( value === undefined )	return this._panner.coneInnerAngle / 180 * Math.PI;
  	this._panner.coneInnerAngle	= value * 180 / Math.PI;
  	return this;	// for chained API
  };
  
  /**
   * getter/setter on the pannerConeOuterAngle
   *
   * @param {Number} value the angle in radian
  */
  WebAudio.Sound.prototype.pannerConeOuterAngle	= function(value){
  	if( value === undefined )	return this._panner.coneOuterAngle / 180 * Math.PI;
  	this._panner.coneOuterAngle	= value * 180 / Math.PI;
  	return this;	// for chained API
  };
  
  /**
   * getter/setter on the pannerConeOuterGain
   * 
   * @param {Number} value the value
  */
  WebAudio.Sound.prototype.pannerConeOuterGain	= function(value){
  	if( value === undefined )	return this._panner.coneOuterGain;
  	this._panner.coneOuterGain	= value;
  	return this;	// for chained API
  };
  
  /**
   * compute the amplitude of the sound (not sure at all it is the proper term)
   *
   * @param {Number} width the number of frequencyBin to take into account
   * @returns {Number} return the amplitude of the sound
  */
  WebAudio.Sound.prototype.amplitude	= function(width)
  {
  	// handle paramerter
  	width		= width !== undefined ? width : 2;
  	// inint variable
  	var analyser	= this._analyser;
  	var freqByte	= new Uint8Array(analyser.frequencyBinCount);
  	// get the frequency data
  	analyser.getByteFrequencyData(freqByte);
  	// compute the sum
  	var sum	= 0;
  	for(var i = 0; i < width; i++){
  		sum	+= freqByte[i];
  	}
  	// complute the amplitude
  	var amplitude	= sum / (width*256-1);
  	// return ampliture
  	return amplitude;
  }
  
  /**
   * Generate a sinusoid buffer.
   * FIXME should likely be in a plugin
  */
  WebAudio.Sound.prototype.tone	= function(hertz, seconds){
  	// handle parameter
  	hertz	= hertz !== undefined ? hertz : 200;
  	seconds	= seconds !== undefined ? seconds : 1;
  	// set default value	
  	var nChannels	= 1;
  	var sampleRate	= 44100;
  	var amplitude	= 2;
  	// create the buffer
  	var buffer	= webaudio.context().createBuffer(nChannels, seconds*sampleRate, sampleRate);
  	var fArray	= buffer.getChannelData(0);
  	// filli the buffer
  	for(var i = 0; i < fArray.length; i++){
  		var time	= i / buffer.sampleRate;
  		var angle	= hertz * time * Math.PI;
  		fArray[i]	= Math.sin(angle)*amplitude;
  	}
  	// set the buffer
  	this.buffer(buffer).loop(true);
  	return this;	// for chained API
  }
  
  
  /**
   * Put this function is .Sound with getByt as private callback
  */
  WebAudio.Sound.prototype.makeHistogram	= function(nBar)
  {	
  	// get analyser node
  	var analyser	= this._analyser;
  	// allocate the private histo if needed - to avoid allocating at every frame
  	//this._privHisto	= this._privHisto || new Float32Array(analyser.frequencyBinCount);
  	this._privHisto	= this._privHisto || new Uint8Array(analyser.frequencyBinCount);
  	// just an alias
  	var freqData	= this._privHisto;
  
  	// get the data
  	//analyser.getFloatFrequencyData(freqData)
  	analyser.getByteFrequencyData(freqData);
  	//analyser.getByteTimeDomainData(freqData)
  
  	/**
  	 * This should be in imageprocessing.js almost
  	*/
  	var makeHisto	= function(srcArr, dstLength){
  		var barW	= Math.floor(srcArr.length / dstLength);
  		var nBar	= Math.floor(srcArr.length / barW);
  		var arr		= []
  		for(var x = 0, arrIdx = 0; x < srcArr.length; arrIdx++){
  			var sum	= 0;
  			for(var i = 0; i < barW; i++, x++){
  				sum += srcArr[x];
  			}
  			var average	= sum/barW;
  			arr[arrIdx]	= average;
  		}
  		return arr;
  	}
  	// build the histo
  	var histo	= makeHisto(freqData, nBar);
  	// return it
  	return histo;
  }
  
  //////////////////////////////////////////////////////////////////////////////////
  //										//
  //////////////////////////////////////////////////////////////////////////////////
  
  /**
   * Load a sound
   *
   * @param {String} url the url of the sound to load
   * @param {Function} callback function to notify once the url is loaded (optional)
  */
  WebAudio.Sound.prototype.load = function(url, callback){
  	this._loadAndDecodeSound(url, function(buffer){
  		this._source.buffer	= buffer;
  		callback && callback(this);
  	}.bind(this), function(){
  		console.warn("unable to load sound "+url);
  	});
  	return this;	// for chained API
  };
  
  /**
   * Load and decode a sound
   *
   * @param {String} url the url where to get the sound
   * @param {Function} onLoad the function called when the sound is loaded and decoded (optional)
   * @param {Function} onError the function called when an error occured (optional)
  */
  WebAudio.Sound.prototype._loadAndDecodeSound	= function(url, onLoad, onError){
  	var context	= this._context;
  	var request	= new XMLHttpRequest();
  	request.open('GET', url, true);
  	request.responseType	= 'arraybuffer';
  	// Decode asynchronously
  	request.onload	= function() {
  		context.decodeAudioData(request.response, function(buffer) {
  			onLoad && onLoad(buffer);
  		}, function(){
  			onError && onError();
  		});
  	};
  	// actually start the request
  	request.send();
  }
  /**
   * gowiththeflow.js - a javascript flow control micro library
   * https://github.com/jeromeetienne/gowiththeflow.js
  */
  WebAudio.Flow	= function(){
  	var self, stack = [], timerId = setTimeout(function(){ timerId = null; self._next(); }, 0);
  	return self = {
  		destroy : function(){ timerId && clearTimeout(timerId); },
  		par	: function(callback, isSeq){
  			if(isSeq || !(stack[stack.length-1] instanceof Array)) stack.push([]);
  			stack[stack.length-1].push(callback);
  			return self;
  		},seq	: function(callback){ return self.par(callback, true);	},
  		_next	: function(err, result){
  			var errors = [], results = [], callbacks = stack.shift() || [], nbReturn = callbacks.length, isSeq = nbReturn == 1;
  			for(var i = 0; i < callbacks.length; i++){
  				(function(fct, index){
  					fct(function(error, result){
  						errors[index]	= error;
  						results[index]	= result;		
  						if(--nbReturn == 0)	self._next(isSeq?errors[0]:errors, isSeq?results[0]:results)
  					}, err, result)
  				})(callbacks[i], i);
  			}
  		}
  	}
  };
  /**
   * Update the source with object3d. usefull for positional sounds
   * 
   * @param {THREE.Object3D} object3d the object which originate the source
   * @param {Number} deltaTime the number of seconds since last update
  */
  WebAudio.Sound.fn.updateWithObject3d	= function(object3d, deltaTime){
  	// sanity check on parameters
  	console.assert( object3d instanceof THREE.Object3D );
  	console.assert( typeof(deltaTime) === 'number' );
  
  	// ensure object3d.matrixWorld is up to date
  	object3d.updateMatrixWorld();
  	
  	this.updateWithMatrix4(object3d.matrixWorld, deltaTime);
  	
  	return this;	// for chained API
  }
  
  /**
   * Update the source with a matrixWorld. usefull for positional sounds
   * 
   * @param {THREE.Matrix4} matrixWorld the matrixWorld describing the position of the sound
   * @param {Number} deltaTime the number of seconds since last update
  */
  WebAudio.Sound.fn.updateWithMatrix4	= function(matrixWorld, deltaTime){
  	// sanity check on parameters
  	console.assert( matrixWorld instanceof THREE.Matrix4 );
  	console.assert( typeof(deltaTime) === 'number' );
  
  	////////////////////////////////////////////////////////////////////////
  	// set position
  	var position	= matrixWorld.getPosition();
  	this._panner.setPosition(position.x, position.y, position.z);
  
  	////////////////////////////////////////////////////////////////////////
  	// set orientation
  	var vOrientation= new THREE.Vector3(0,0,1);
  	var mOrientation= matrixWorld.clone();
  	// zero the translation
  	mOrientation.setPosition({x : 0, y: 0, z: 0});
  	// Multiply the 0,0,1 vector by the world matrix and normalize the result.
  	mOrientation.multiplyVector3(vOrientation);
  	vOrientation.normalize();
  	// Set panner orientation
  	this._panner.setOrientation(vOrientation.x, vOrientation.y, vOrientation.z);
  	
  	////////////////////////////////////////////////////////////////////////
  	// set velocity
  	if( this._prevPos === undefined ){
  		this._prevPos	= matrixWorld.getPosition().clone();
  	}else{
  		var position	= matrixWorld.getPosition();
  		var velocity	= position.clone().subSelf(this._prevPos).divideScalar(deltaTime);
  		this._prevPos	= matrixWorld.getPosition().clone();
  		this._panner.setVelocity(velocity.x, velocity.y, velocity.z);
  	}
  }
  /**
   * follow a object3D
  */
  WebAudio.Sound.fn.follow	= function(object3d, world){
  	console.assert( this.isFollowing() === false );
  	// handle parameter
  	if( object3d instanceof tQuery.Object3D ){
  		console.assert(object3d.length === 1)
  		object3d	= object3d.get(0);
  	}
  	// sanity check on parameters
  	console.assert( object3d instanceof THREE.Object3D );
  
  	// hook the world loop
  	this._followCb		= function(deltaTime){
  		this.updateWithObject3d(object3d, deltaTime);
  	}.bind(this);
  	world.hook(this._followCb);
  	// for chained API
  	return this;
  }
  
  /**
   * unfollow the object3D if any
  */
  WebAudio.Sound.fn.unfollow	= function(world){
  	this._world.unhook(this._followCb);
  	this._followCb		= null;
  	// for chained API
  	return this;
  }
  
  /**
   * @returns {Boolean} true if this sound is following a object3d, false overwise
  */
  WebAudio.Sound.prototype.isFollowing	= function(){
  	return this._followCb ? true : false;
  	// for chained API
  	return this;
  }
  /**
   * @fileoverview WebAudio.js plugin for tQuery
  */
  tQuery.World.registerInstance('enableWebAudio', function(){
  	// sanity check
  	console.assert( this.hasWebAudio() === false, "there is already a webaudio" );
  	// intenciate a tQuery.World.WebAudio
  	var webaudio	= new WebAudio();
  	// follow the listener
  	var world	= this;
  	webaudio.followListener(world);
  	// store webaudio in the world
  	tQuery.data(this, "webaudio", webaudio);
  	// for chained API
  	return this;
  });
  
  tQuery.World.registerInstance('disabledWebAudio', function(){
  	if( this.hasWebAudio() === false )	return this;
  	var webaudio	= tQuery.data(this, "webaudio");
  	webaudio.destroy();
  	tQuery.removeData(this, "webaudio");
  	return this;	// for chained API
  });
  
  tQuery.World.registerInstance('getWebAudio', function(){
  	var webaudio	= tQuery.data(this, "webaudio");
  	return webaudio;
  });
  
  tQuery.World.registerInstance('hasWebAudio', function(){
  	var webaudio	= tQuery.data(this, "webaudio");
  	return webaudio ? true : false;
  });
  
  tQuery.World.registerInstance('supportWebAudio', function(){
  	return WebAudio.isAvailable;
  });
  
  tQuery.registerStatic('createSound', function(world, nodeChain){
  	world	= world || tQuery.world;
  	return new WebAudio.Sound(world.getWebAudio(), nodeChain);
  });
  
  
  //////////////////////////////////////////////////////////////////////////////////
  //										//
  //////////////////////////////////////////////////////////////////////////////////
  
  WebAudio.fn.followListener	= function(world){
  	this._$followListenerCb	= function(deltaTime){
  		this._followListenerCb(world.camera(), deltaTime);
  	}.bind(this);
  	world.hook(this._$followListenerCb);
  }
  
  WebAudio.fn.unfollowListener	= function(world){
  	// unhook this._updateCb from this.world.loop()
  	world.unhook(this._$followListenerCb);
  	this._$followListenerCb	= null;
  }
  
  WebAudio.fn._followListenerCb	= function(object3d, deltaTime){
  	var context	= this._ctx;
  	// sanity check on parameters
  	console.assert( object3d instanceof THREE.Object3D );
  	console.assert( typeof(deltaTime) === 'number' );
  
  	// ensure object3d.matrixWorld is up to date
  	object3d.updateMatrixWorld();
  	
  	////////////////////////////////////////////////////////////////////////
  	// set position
  	var position	= object3d.matrixWorld.getPosition();
  	context.listener.setPosition(position.x, position.y, position.z);
  
  	////////////////////////////////////////////////////////////////////////
  	// set orientation
  	var mOrientation= object3d.matrixWorld.clone();
  	// zero the translation
  	mOrientation.setPosition({x : 0, y: 0, z: 0});
  	// Compute Front vector: Multiply the 0,0,1 vector by the world matrix and normalize the result.
  	var vFront= new THREE.Vector3(0,0,1);
  	mOrientation.multiplyVector3(vFront);
  	vFront.normalize();
  	// Compute UP vector: Multiply the 0,-1,0 vector by the world matrix and normalize the result.
  	var vUp= new THREE.Vector3(0,-1, 0);
  	mOrientation.multiplyVector3(vUp);
  	vUp.normalize();
  	// Set panner orientation
  	context.listener.setOrientation(vFront.x, vFront.y, vFront.z, vUp.x, vUp.y, vUp.z);
  
  	////////////////////////////////////////////////////////////////////////
  	// set velocity
  	if( this._prevPos === undefined ){
  		this._prevPos	= object3d.matrixWorld.getPosition().clone();
  	}else{
  		var position	= object3d.matrixWorld.getPosition();
  		var velocity	= position.clone().subSelf(this._prevPos).divideScalar(deltaTime);
  		this._prevPos	= object3d.matrixWorld.getPosition().clone();
  		context.listener.setVelocity(velocity.x, velocity.y, velocity.z);
  	}
  }
  
  
  