b=907986 handle zero front-right plane projection without NaNs r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 04 Sep 2013 21:20:59 +1200
changeset 145490 1100a5bc013b541c635bc42bd753531e95c952e4
parent 145489 1eaccb673d334e5fcf3c8f62ce86a7ec98a02a1d
child 145491 c2bfb5b08f75e6bbe246271170f200b2ece5158a
push id33296
push userktomlinson@mozilla.com
push dateWed, 04 Sep 2013 20:32:35 +0000
treeherdermozilla-inbound@15a71c6cb0d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs907986
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=907986 handle zero front-right plane projection without NaNs r=padenot The azimuth calculation in the Web Audio spec becomes undefined in this situation as it requires normalizing a zero vector. The panning effect should not depend on azimuth when the source is directly above the listener (because position does not depend on azimuth), but the specified "equalpower" panning model does depend on azimuth even at this elevation. Setting azimuth to zero produces the same result as if the normalized projection were replaced with a zero vector.
content/media/webaudio/PannerNode.cpp
--- a/content/media/webaudio/PannerNode.cpp
+++ b/content/media/webaudio/PannerNode.cpp
@@ -391,18 +391,30 @@ PannerNodeEngine::ComputeAzimuthAndEleva
   sourceListener.Normalize();
 
   // Project the source-listener vector on the x-z plane.
   const ThreeDPoint& listenerFront = mListenerFrontVector;
   const ThreeDPoint& listenerRight = mListenerRightVector;
   ThreeDPoint up = listenerRight.CrossProduct(listenerFront);
 
   double upProjection = sourceListener.DotProduct(up);
+  aElevation = 90 - 180 * acos(upProjection) / M_PI;
+
+  if (aElevation > 90) {
+    aElevation = 180 - aElevation;
+  } else if (aElevation < -90) {
+    aElevation = -180 - aElevation;
+  }
 
   ThreeDPoint projectedSource = sourceListener - up * upProjection;
+  if (projectedSource.IsZero()) {
+    // source - listener direction is up or down.
+    aAzimuth = 0.0;
+    return;
+  }
   projectedSource.Normalize();
 
   // Actually compute the angle, and convert to degrees
   double projection = projectedSource.DotProduct(listenerRight);
   aAzimuth = 180 * acos(projection) / M_PI;
 
   // Compute whether the source is in front or behind the listener.
   double frontBack = projectedSource.DotProduct(listenerFront);
@@ -411,24 +423,16 @@ PannerNodeEngine::ComputeAzimuthAndEleva
   }
   // Rotate the azimuth so it is relative to the listener front vector instead
   // of the right vector.
   if ((aAzimuth >= 0) && (aAzimuth <= 270)) {
     aAzimuth = 90 - aAzimuth;
   } else {
     aAzimuth = 450 - aAzimuth;
   }
-
-  aElevation = 90 - 180 * acos(upProjection) / M_PI;
-
-  if (aElevation > 90) {
-    aElevation = 180 - aElevation;
-  } else if (aElevation < -90) {
-    aElevation = -180 - aElevation;
-  }
 }
 
 // This algorithm is described in the WebAudio spec.
 float
 PannerNodeEngine::ComputeConeGain()
 {
   // Omnidirectional source
   if (mOrientation.IsZero() || ((mConeInnerAngle == 360) && (mConeOuterAngle == 360))) {