Browse Source

Audio: Use linearRampToValueAtTime()

Mugen87 6 years ago
parent
commit
e5e4cf05c8

+ 6 - 3
docs/api/en/audio/Audio.html

@@ -73,12 +73,15 @@
 		<p>Whether playback can be controlled using the [page:Audio.play play](),
 			[page:Audio.pause pause]() etc. methods. Default is *true*.</p>
 
-		<h3>[property:Number playbackRate]</h3>
-		<p>Speed of playback. Default is *1*.</p>
-
 		<h3>[property:Boolean isPlaying]</h3>
 		<p>Whether the audio is currently playing.</p>
 
+		<h3>[property:AudioListener listener]</h3>
+		<p>A reference to the listener object of this audio.</p>
+
+		<h3>[property:Number playbackRate]</h3>
+		<p>Speed of playback. Default is *1*.</p>
+
 		<h3>[property:Number startTime]</h3>
 		<p>The time at which the sound should begin to play. Same as the *when* paramter of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start](). Default is *0*.</p>
 

+ 2 - 0
docs/api/en/audio/AudioListener.html

@@ -67,6 +67,8 @@
 		<h3>[property:AudioNode filter]</h3>
 		<p>Default is *null*.</p>
 
+		<h3>[property:Number timeDelta]</h3>
+		<p>Time delta value for audio entities. Use in context of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime AudioParam.linearRampToValueAtTimeDefault](). Default is *0*.</p>
 
 		<h2>Methods</h2>
 

+ 3 - 0
docs/api/zh/audio/Audio.html

@@ -78,6 +78,9 @@
 		<h3>[property:Boolean isPlaying]</h3>
 		<p>是否正在播放</p>
 
+		<h3>[property:AudioListener listener]</h3>
+		<p>A reference to the listener object of this audio.</p>
+
 		<h3>[property:Number startTime]</h3>
 		<p>开始播放的时间. 和[link:https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start AudioBufferSourceNode.start]()的*when*参数一样. 默认为 *0*.</p>
 

+ 2 - 0
docs/api/zh/audio/AudioListener.html

@@ -66,6 +66,8 @@
 		<h3>[property:AudioNode filter]</h3>
 		<p>默认为*null*.</p>
 
+		<h3>[property:Number timeDelta]</h3>
+		<p>Time delta value for audio entities. Use in context of [link:https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/linearRampToValueAtTime AudioParam.linearRampToValueAtTimeDefault](). Default is *0*.</p>
 
 		<h2>方法</h2>
 

+ 1 - 0
src/audio/Audio.js

@@ -11,6 +11,7 @@ function Audio( listener ) {
 
 	this.type = 'Audio';
 
+	this.listener = listener;
 	this.context = listener.context;
 
 	this.gain = this.context.createGain();

+ 19 - 9
src/audio/AudioListener.js

@@ -4,6 +4,7 @@
 
 import { Vector3 } from '../math/Vector3.js';
 import { Quaternion } from '../math/Quaternion.js';
+import { Clock } from '../core/Clock.js';
 import { Object3D } from '../core/Object3D.js';
 import { AudioContext } from './AudioContext.js';
 
@@ -20,6 +21,8 @@ function AudioListener() {
 
 	this.filter = null;
 
+	this.timeDelta = 0;
+
 }
 
 AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
@@ -95,6 +98,7 @@ AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
 		var scale = new Vector3();
 
 		var orientation = new Vector3();
+		var clock = new Clock();
 
 		return function updateMatrixWorld( force ) {
 
@@ -103,21 +107,27 @@ AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
 			var listener = this.context.listener;
 			var up = this.up;
 
+			this.timeDelta = clock.getDelta();
+
 			this.matrixWorld.decompose( position, quaternion, scale );
 
 			orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion );
 
 			if ( listener.positionX ) {
 
-				listener.positionX.setValueAtTime( position.x, this.context.currentTime );
-				listener.positionY.setValueAtTime( position.y, this.context.currentTime );
-				listener.positionZ.setValueAtTime( position.z, this.context.currentTime );
-				listener.forwardX.setValueAtTime( orientation.x, this.context.currentTime );
-				listener.forwardY.setValueAtTime( orientation.y, this.context.currentTime );
-				listener.forwardZ.setValueAtTime( orientation.z, this.context.currentTime );
-				listener.upX.setValueAtTime( up.x, this.context.currentTime );
-				listener.upY.setValueAtTime( up.y, this.context.currentTime );
-				listener.upZ.setValueAtTime( up.z, this.context.currentTime );
+				// code path for Chrome (see #14393)
+
+				var endTime = this.context.currentTime + this.timeDelta;
+
+				listener.positionX.linearRampToValueAtTime( position.x, endTime );
+				listener.positionY.linearRampToValueAtTime( position.y, endTime );
+				listener.positionZ.linearRampToValueAtTime( position.z, endTime );
+				listener.forwardX.linearRampToValueAtTime( orientation.x, endTime );
+				listener.forwardY.linearRampToValueAtTime( orientation.y, endTime );
+				listener.forwardZ.linearRampToValueAtTime( orientation.z, endTime );
+				listener.upX.linearRampToValueAtTime( up.x, endTime );
+				listener.upY.linearRampToValueAtTime( up.y, endTime );
+				listener.upZ.linearRampToValueAtTime( up.z, endTime );
 
 			} else {
 

+ 19 - 2
src/audio/PositionalAudio.js

@@ -109,8 +109,25 @@ PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
 
 			orientation.set( 0, 0, 1 ).applyQuaternion( quaternion );
 
-			panner.setPosition( position.x, position.y, position.z );
-			panner.setOrientation( orientation.x, orientation.y, orientation.z );
+			if ( panner.positionX ) {
+
+				// code path for Chrome and Firefox (see #14393)
+
+				var endTime = this.context.currentTime + this.listener.timeDelta;
+
+				panner.positionX.linearRampToValueAtTime( position.x, endTime );
+				panner.positionY.linearRampToValueAtTime( position.y, endTime );
+				panner.positionZ.linearRampToValueAtTime( position.z, endTime );
+				panner.orientationX.linearRampToValueAtTime( orientation.x, endTime );
+				panner.orientationY.linearRampToValueAtTime( orientation.y, endTime );
+				panner.orientationZ.linearRampToValueAtTime( orientation.z, endTime );
+
+			} else {
+
+				panner.setPosition( position.x, position.y, position.z );
+				panner.setOrientation( orientation.x, orientation.y, orientation.z );
+
+			}
 
 		};