Commit c9bdf292 authored by rtoy@chromium.org's avatar rtoy@chromium.org

The issue is summarized here: https://github.com/WebAudio/web-audio-api/issues/324

This CL can't solve all issues when the source position approaches the listener position because when the locations are equal, we get a singular point in the equations.

This just makes it continuous as the source approaches the listener. If the source then goes past, there will be a unavoidable discontinuity.

TEST=Listen to http://jsfiddle.net/UxwGP/10. When the slider position is 0, there should be no sudden change in pitch.

TEST=Listen to http://jsfiddle.net/qWHAt/34/ using mono source and HRTF panner.  Initially, the pitch is very low. Move the slider just to the left or right of center and the pitch goes up. As you move the slider through center slowly, the pitch drops drastically at center.  With this CL, this the pitch does not start out low, and as you move the slider around, the pitch never drops low at center. There is a discontinuity moving from left to right, but this is because the source was moving away from the listener and is not moving towards the listener.

BUG=141739

Review URL: https://codereview.chromium.org/301733002

git-svn-id: svn://svn.chromium.org/blink/trunk@175175 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent e1c4d43d
......@@ -385,13 +385,7 @@ void PannerNode::calculateAzimuthElevation(double* outAzimuth, double* outElevat
FloatPoint3D listenerPosition = listener()->position();
FloatPoint3D sourceListener = m_position - listenerPosition;
if (sourceListener.isZero()) {
// degenerate case if source and listener are at the same point
*outAzimuth = 0.0;
*outElevation = 0.0;
return;
}
// normalize() does nothing if the length of |sourceListener| is zero.
sourceListener.normalize();
// Align axes
......@@ -461,24 +455,30 @@ double PannerNode::calculateDopplerRate()
double sourceListenerMagnitude = sourceToListener.length();
double listenerProjection = sourceToListener.dot(listenerVelocity) / sourceListenerMagnitude;
double sourceProjection = sourceToListener.dot(sourceVelocity) / sourceListenerMagnitude;
if (!sourceListenerMagnitude) {
// Source and listener are at the same position. Skip the computation of the doppler
// shift, and just return the cached value.
dopplerShift = m_cachedDopplerRate;
} else {
double listenerProjection = sourceToListener.dot(listenerVelocity) / sourceListenerMagnitude;
double sourceProjection = sourceToListener.dot(sourceVelocity) / sourceListenerMagnitude;
listenerProjection = -listenerProjection;
sourceProjection = -sourceProjection;
listenerProjection = -listenerProjection;
sourceProjection = -sourceProjection;
double scaledSpeedOfSound = speedOfSound / dopplerFactor;
listenerProjection = min(listenerProjection, scaledSpeedOfSound);
sourceProjection = min(sourceProjection, scaledSpeedOfSound);
double scaledSpeedOfSound = speedOfSound / dopplerFactor;
listenerProjection = min(listenerProjection, scaledSpeedOfSound);
sourceProjection = min(sourceProjection, scaledSpeedOfSound);
dopplerShift = ((speedOfSound - dopplerFactor * listenerProjection) / (speedOfSound - dopplerFactor * sourceProjection));
fixNANs(dopplerShift); // avoid illegal values
dopplerShift = ((speedOfSound - dopplerFactor * listenerProjection) / (speedOfSound - dopplerFactor * sourceProjection));
fixNANs(dopplerShift); // avoid illegal values
// Limit the pitch shifting to 4 octaves up and 3 octaves down.
if (dopplerShift > 16.0)
dopplerShift = 16.0;
else if (dopplerShift < 0.125)
dopplerShift = 0.125;
// Limit the pitch shifting to 4 octaves up and 3 octaves down.
if (dopplerShift > 16.0)
dopplerShift = 16.0;
else if (dopplerShift < 0.125)
dopplerShift = 0.125;
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment