Bladeren bron

evolution of Audio, adding buffer management, ambient sound, master volume

 Changes to be committed:
	modified:   examples/misc_sound.html
	new file:   examples/sounds/Project_Utopia.ogg
	modified:   examples/sounds/readme.txt
	modified:   src/audio/Audio.js
	new file:   src/audio/AudioBuffer.js
	modified:   src/audio/AudioListener.js
	new file:   src/audio/PositionAudio.js
	modified:   utils/build/includes/common.json
vincent 9 jaren geleden
bovenliggende
commit
3ad4b7fe0f

+ 56 - 14
examples/misc_sound.html

@@ -23,7 +23,7 @@
 			#info {
 				color:#fff;
 				position: absolute;
-				top: 0px; width: 100%;
+				top: 0px; left: 0px; width: 50%;
 				padding: 5px;
 				z-index:100;
 			}
@@ -34,8 +34,8 @@
 		<div id="info">
 			<a href="http://threejs.org" target="_blank">three.js</a> - webgl 3d sounds example -
 			music by <a href="http://www.newgrounds.com/audio/listen/358232" target="_blank">larrylarrybb</a> and
-			<a href="http://www.newgrounds.com/audio/listen/376737" target="_blank">skullbeatz</a> <br/><br/>
-
+			<a href="http://www.newgrounds.com/audio/listen/376737" target="_blank">skullbeatz</a>  and 
+			<a href="http://opengameart.org/content/project-utopia-seamless-loop" target="_blank">congusbongus</a><br/><br/>
 			navigate with WASD / arrows / mouse
 		</div>
 
@@ -48,6 +48,8 @@
 
 		<script src="js/Detector.js"></script>
 
+		<script src="js/libs/dat.gui.min.js"></script>
+
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
@@ -74,13 +76,7 @@
 				var listener = new THREE.AudioListener();
 				camera.add( listener );
 
-				controls = new THREE.FirstPersonControls( camera );
-
-				controls.movementSpeed = 70;
-				controls.lookSpeed = 0.05;
-				controls.noFly = true;
-				controls.lookVertical = false;
-
+				
 				scene = new THREE.Scene();
 				scene.fog = new THREE.FogExp2( 0x000000, 0.0035 );
 
@@ -99,8 +95,10 @@
 				mesh1.position.set( -250, 30, 0 );
 				scene.add( mesh1 );
 
-				var sound1 = new THREE.Audio( listener );
-				sound1.load( 'sounds/358232_j_s_song.ogg' );
+				var sound1 = new THREE.PositionAudio( listener );
+				var buffer1 = new THREE.AudioBuffer( listener );
+				buffer1.load( 'sounds/358232_j_s_song.ogg' );
+				sound1.setBuffer(buffer1);
 				sound1.setRefDistance( 20 );
 				sound1.autoplay = true;
 				mesh1.add( sound1 );
@@ -111,12 +109,24 @@
 				mesh2.position.set( 250, 30, 0 );
 				scene.add( mesh2 );
 
-				var sound2 = new THREE.Audio( listener );
-				sound2.load( 'sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg' );
+				var sound2 = new THREE.PositionAudio( listener );
+				var buffer2 = new THREE.AudioBuffer( listener );
+				buffer2.load( 'sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg' );
+				sound2.setBuffer(buffer2);
 				sound2.setRefDistance( 20 );
 				sound2.autoplay = true;
 				mesh2.add( sound2 );
 
+				// global ambient audio
+	
+				var sound3 = new THREE.Audio( listener );
+				var buffer3 = new THREE.AudioBuffer( listener );
+				buffer3.load( 'sounds/Project_Utopia.ogg' );
+				sound3.setBuffer(buffer3);
+				sound3.autoplay = true;
+				sound3.setLoop(true);
+				sound3.setVolume(0.5);
+				
 				// ground
 
 				var helper = new THREE.GridHelper( 500, 10 );
@@ -126,6 +136,30 @@
 				scene.add( helper );
 
 				//
+    			var SoundControls = function() {
+					   this.master = listener.getMasterVolume();
+					   this.firstSphere =  sound1.getVolume();
+					   this.secondSphere =  sound2.getVolume();
+					   this.Ambient =  sound3.getVolume();
+				};
+      			var gui = new dat.GUI();
+				var soundControls = new SoundControls();
+				var volumeFolder = gui.addFolder('sound volume');
+				volumeFolder.add(soundControls, 'master').min(0.0).max(1.0).step(0.01).onChange(function() {
+					listener.setMasterVolume(soundControls.master);
+				});
+				volumeFolder.add(soundControls, 'firstSphere').min(0.0).max(1.0).step(0.01).onChange(function() {
+					sound1.setVolume(soundControls.firstSphere);
+				});
+				volumeFolder.add(soundControls, 'secondSphere').min(0.0).max(1.0).step(0.01).onChange(function() {
+					sound2.setVolume(soundControls.secondSphere);
+				});
+				volumeFolder.add(soundControls, 'Ambient').min(0.0).max(1.0).step(0.01).onChange(function() {
+					sound3.setVolume(soundControls.Ambient);
+				});
+				volumeFolder.open();
+
+
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
@@ -135,6 +169,14 @@
 				container.appendChild( renderer.domElement );
 
 				//
+				controls = new THREE.FirstPersonControls( camera, renderer.domElement );
+
+				controls.movementSpeed = 70;
+				controls.lookSpeed = 0.05;
+				controls.noFly = true;
+				controls.lookVertical = false;
+
+				
 
 				window.addEventListener( 'resize', onWindowResize, false );
 

BIN
examples/sounds/Project_Utopia.ogg


+ 5 - 1
examples/sounds/readme.txt

@@ -5,4 +5,8 @@ Bad Cat [Master Version] by Skullbeatz
 http://www.newgrounds.com/audio/listen/376737
 
 The Sound of Epicness by larrylarrybb
-http://www.newgrounds.com/audio/listen/358232
+http://www.newgrounds.com/audio/listen/358232
+
+Music from opengameart, licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
+Project Utopia by congusbongus
+http://opengameart.org/content/project-utopia-seamless-loop

+ 13 - 63
src/audio/Audio.js

@@ -13,10 +13,7 @@ THREE.Audio = function ( listener ) {
 	this.source.onended = this.onEnded.bind( this );
 
 	this.gain = this.context.createGain();
-	this.gain.connect( this.context.destination );
-
-	this.panner = this.context.createPanner();
-	this.panner.connect( this.gain );
+	this.gain.connect( listener.getOutputNode());
 
 	this.autoplay = false;
 
@@ -29,30 +26,21 @@ THREE.Audio = function ( listener ) {
 THREE.Audio.prototype = Object.create( THREE.Object3D.prototype );
 THREE.Audio.prototype.constructor = THREE.Audio;
 
-THREE.Audio.prototype.load = function ( file ) {
+THREE.Audio.prototype.setBuffer = function ( audioBuffer ) {
 
 	var scope = this;
-
-	var request = new XMLHttpRequest();
-	request.open( 'GET', file, true );
-	request.responseType = 'arraybuffer';
-	request.onload = function ( e ) {
-
-		scope.context.decodeAudioData( this.response, function ( buffer ) {
-
-			scope.source.buffer = buffer;
-
-			if ( scope.autoplay ) scope.play();
-
-		} );
-
-	};
-	request.send();
+	
+	audioBuffer.onReady(function(buffer) {
+		scope.source.buffer = buffer;
+		if ( scope.autoplay ) scope.play();
+	});
 
 	return this;
 
 };
 
+
+
 THREE.Audio.prototype.play = function () {
 
 	if ( this.isPlaying === true ) {
@@ -97,11 +85,11 @@ THREE.Audio.prototype.connect = function () {
 	if ( this.filter !== undefined ) {
 
 		this.source.connect( this.filter );
-		this.filter.connect( this.panner );
+		this.filter.connect( this.gain );
 
 	} else {
 
-		this.source.connect( this.panner );
+		this.source.connect( this.gain );
 
 	}
 
@@ -112,11 +100,11 @@ THREE.Audio.prototype.disconnect = function () {
 	if ( this.filter !== undefined ) {
 
 		this.source.disconnect( this.filter );
-		this.filter.disconnect( this.panner );
+		this.filter.disconnect( this.gain );
 
 	} else {
 
-		this.source.disconnect( this.panner );
+		this.source.disconnect( this.gain );
 
 	}
 
@@ -180,29 +168,6 @@ THREE.Audio.prototype.getLoop = function () {
 
 };
 
-THREE.Audio.prototype.setRefDistance = function ( value ) {
-
-	this.panner.refDistance = value;
-
-};
-
-THREE.Audio.prototype.getRefDistance = function () {
-
-	return this.panner.refDistance;
-
-};
-
-THREE.Audio.prototype.setRolloffFactor = function ( value ) {
-
-	this.panner.rolloffFactor = value;
-
-};
-
-THREE.Audio.prototype.getRolloffFactor = function () {
-
-	return this.panner.rolloffFactor;
-
-};
 
 THREE.Audio.prototype.setVolume = function ( value ) {
 
@@ -216,18 +181,3 @@ THREE.Audio.prototype.getVolume = function () {
 
 };
 
-THREE.Audio.prototype.updateMatrixWorld = ( function () {
-
-	var position = new THREE.Vector3();
-
-	return function updateMatrixWorld( force ) {
-
-		THREE.Object3D.prototype.updateMatrixWorld.call( this, force );
-
-		position.setFromMatrixPosition( this.matrixWorld );
-
-		this.panner.setPosition( position.x, position.y, position.z );
-
-	};
-
-} )();

+ 51 - 0
src/audio/AudioBuffer.js

@@ -0,0 +1,51 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.AudioBuffer = function ( listener ) {
+
+	this.context = listener.context;
+	this.ready = false;
+	this.readyCallbacks = [];
+
+};
+
+THREE.AudioBuffer.prototype.load = function ( file ) {
+
+	var scope = this;
+
+	var request = new XMLHttpRequest();
+	request.open( 'GET', file, true );
+	request.responseType = 'arraybuffer';
+	request.onload = function ( e ) {
+
+		scope.context.decodeAudioData( this.response, function ( buffer ) {
+
+			scope.buffer = buffer;
+			scope.ready = true;
+			
+			for (var i = 0; i < scope.readyCallbacks.length; i++) {
+				scope.readyCallbacks[i](scope.buffer);
+			}
+			scope.readyCallbacks = [];
+			
+		} );
+
+	};
+	request.send();
+
+	return this;
+
+};
+
+THREE.AudioBuffer.prototype.onReady = function ( callback ) {
+	
+	if (this.ready) {
+		callback(this.buffer);
+	}
+	else {
+		this.readyCallbacks.push(callback);
+	}
+
+};
+

+ 60 - 1
src/audio/AudioListener.js

@@ -9,12 +9,71 @@ THREE.AudioListener = function () {
 	this.type = 'AudioListener';
 
 	this.context = new ( window.AudioContext || window.webkitAudioContext )();
-
+	this.masterGain =  this.context.createGain();
+	this.masterGain.connect(this.context.destination);
+	this.filter = null;
+	
 };
 
 THREE.AudioListener.prototype = Object.create( THREE.Object3D.prototype );
 THREE.AudioListener.prototype.constructor = THREE.AudioListener;
 
+THREE.AudioListener.prototype.getOutputNode = function () {
+	
+	return this.masterGain;
+	
+};
+
+THREE.AudioListener.prototype.removeFilter = function ( ) {
+	
+	if (this.filter !== null && this.filter !== undefined) {
+	
+		this.masterGain.disconnect(this.filter);
+		this.filter.disconnect(this.context.destination);
+		this.masterGain.connect(this.context.destination);
+		this.filter = null;
+		
+	}
+	
+}
+
+THREE.AudioListener.prototype.setFilter = function ( value ) {
+
+	if (this.filter !== null && this.filter !== undefined) {
+		
+		this.masterGain.disconnect(this.filter);
+		this.filter.disconnect(this.context.destination);
+
+	} else {
+		
+		this.masterGain.disconnect(this.context.destination);
+		
+	}
+	this.filter = value;
+	this.masterGain.connect(this.filter);
+	this.filter.connect(this.context.destination);	
+	
+};
+
+THREE.AudioListener.prototype.getFilter = function () {
+
+	return this.filter;
+
+};
+
+THREE.AudioListener.prototype.setMasterVolume = function ( value ) {
+
+	this.masterGain.gain.value = value;
+
+};
+
+THREE.AudioListener.prototype.getMasterVolume = function () {
+
+	return this.masterGain.gain.value;
+
+};
+
+
 THREE.AudioListener.prototype.updateMatrixWorld = ( function () {
 
 	var position = new THREE.Vector3();

+ 109 - 0
src/audio/PositionAudio.js

@@ -0,0 +1,109 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.PositionAudio = function ( listener ) {
+
+	THREE.Audio.call( this, listener );
+
+	this.panner = this.context.createPanner();
+	this.panner.connect( this.gain );
+
+};
+
+THREE.PositionAudio.prototype = Object.create( THREE.Audio.prototype );
+THREE.PositionAudio.prototype.constructor = THREE.PositionAudio;
+
+
+
+THREE.PositionAudio.prototype.connect = function () {
+
+	if ( this.filter !== undefined ) {
+
+		this.source.connect( this.filter );
+		this.filter.connect( this.panner );
+
+	} else {
+
+		this.source.connect( this.panner );
+
+	}
+
+};
+
+THREE.PositionAudio.prototype.disconnect = function () {
+
+	if ( this.filter !== undefined ) {
+
+		this.source.disconnect( this.filter );
+		this.filter.disconnect( this.panner );
+
+	} else {
+
+		this.source.disconnect( this.panner );
+
+	}
+
+};
+
+THREE.PositionAudio.prototype.setFilter = function ( value ) {
+
+	if ( this.isPlaying === true ) {
+
+		this.disconnect();
+		this.filter = value;
+		this.connect();
+
+	} else {
+
+		this.filter = value;
+
+	}
+
+};
+
+THREE.PositionAudio.prototype.getFilter = function () {
+
+	return this.filter;
+
+};
+
+THREE.PositionAudio.prototype.setRefDistance = function ( value ) {
+
+	this.panner.refDistance = value;
+
+};
+
+THREE.PositionAudio.prototype.getRefDistance = function () {
+
+	return this.panner.refDistance;
+
+};
+
+THREE.PositionAudio.prototype.setRolloffFactor = function ( value ) {
+
+	this.panner.rolloffFactor = value;
+
+};
+
+THREE.PositionAudio.prototype.getRolloffFactor = function () {
+
+	return this.panner.rolloffFactor;
+
+};
+
+THREE.PositionAudio.prototype.updateMatrixWorld = ( function () {
+
+	var position = new THREE.Vector3();
+
+	return function updateMatrixWorld( force ) {
+
+		THREE.Object3D.prototype.updateMatrixWorld.call( this, force );
+
+		position.setFromMatrixPosition( this.matrixWorld );
+
+		this.panner.setPosition( position.x, position.y, position.z );
+
+	};
+
+} )();

+ 3 - 1
utils/build/includes/common.json

@@ -52,7 +52,9 @@
 	"src/animation/tracks/StringKeyframeTrack.js",
 	"src/animation/tracks/VectorKeyframeTrack.js",
 	"src/audio/Audio.js",
-	"src/audio/AudioListener.js",
+	"src/audio/AudioBuffer.js",	
+	"src/audio/PositionAudio.js",
+	"src/audio/AudioListener.js",	
 	"src/cameras/Camera.js",
 	"src/cameras/CubeCamera.js",
 	"src/cameras/OrthographicCamera.js",