Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Unified Diff: Source/modules/webaudio/PannerNode.cpp

Issue 189143010: Cache values for panning and spatialization effects to enhance performance on pannerNode. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/modules/webaudio/PannerNode.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/webaudio/PannerNode.cpp
diff --git a/Source/modules/webaudio/PannerNode.cpp b/Source/modules/webaudio/PannerNode.cpp
index 27e06244babb4cedc8f5a3bf61d400684df839df..3f2dde89def0dc6e3f5920d71ebb7663e6bd3d12 100644
--- a/Source/modules/webaudio/PannerNode.cpp
+++ b/Source/modules/webaudio/PannerNode.cpp
@@ -49,7 +49,17 @@ static void fixNANs(double &x)
PannerNode::PannerNode(AudioContext* context, float sampleRate)
: AudioNode(context, sampleRate)
, m_panningModel(Panner::PanningModelHRTF)
+ , m_position(0, 0, 0)
+ , m_orientation(1, 0, 0)
+ , m_velocity(0, 0, 0)
+ , m_cachedPosition(0, 0, 0)
+ , m_cachedOrientation(1, 0, 0)
+ , m_cachedVelocity(0, 0, 0)
, m_lastGain(-1.0)
+ , m_cachedAzimuth(0)
+ , m_cachedElevation(0)
+ , m_cachedDistanceConeGain(0)
+ , m_cachedDopplerRate(1)
, m_connectionCount(0)
{
// Load the HRTF database asynchronously so we don't block the Javascript thread while creating the HRTF database.
@@ -68,9 +78,7 @@ PannerNode::PannerNode(AudioContext* context, float sampleRate)
m_distanceGain = AudioParam::create(context, "distanceGain", 1.0, 0.0, 1.0);
m_coneGain = AudioParam::create(context, "coneGain", 1.0, 0.0, 1.0);
- m_position = FloatPoint3D(0, 0, 0);
- m_orientation = FloatPoint3D(1, 0, 0);
- m_velocity = FloatPoint3D(0, 0, 0);
+ m_cachedListener = AudioListener::create();
setNodeType(NodeTypePanner);
@@ -131,11 +139,12 @@ void PannerNode::process(size_t framesToProcess)
// Apply the panning effect.
double azimuth;
double elevation;
- getAzimuthElevation(&azimuth, &elevation);
+ azimuthElevation(&azimuth, &elevation);
+
m_panner->pan(azimuth, elevation, source, destination, framesToProcess);
// Get the distance and cone gain.
- double totalGain = distanceConeGain();
+ float totalGain = distanceConeGain();
// Snap to desired gain at the beginning.
if (m_lastGain == -1.0)
@@ -143,6 +152,11 @@ void PannerNode::process(size_t framesToProcess)
// Apply gain in-place with de-zippering.
destination->copyWithGainFrom(*destination, &m_lastGain, totalGain);
+
+ // Update the cached listener in case listener has moved.
+ updateCachedListener();
+ // Now update the cached source location in case the source has changed.
+ updateCachedSourceLocationInfo();
} else {
// Too bad - The tryLock() failed. We must be in the middle of changing the panner.
destination->zero();
@@ -217,6 +231,42 @@ bool PannerNode::setPanningModel(unsigned model)
return true;
}
+void PannerNode::setPosition(float x, float y, float z)
+{
+ // FIXME : consider thread safety about m_position in audio thread.
+ // See http://crbugs.com/350583.
+ FloatPoint3D position = FloatPoint3D(x, y, z);
+
+ if (m_position == position)
+ return;
+
+ m_position = position;
+}
+
+void PannerNode::setOrientation(float x, float y, float z)
+{
+ // FIXME : consider thread safety about m_orientation in audio thread.
+ // See http://crbugs.com/350583.
+ FloatPoint3D orientation = FloatPoint3D(x, y, z);
+
+ if (m_orientation == orientation)
+ return;
+
+ m_orientation = orientation;
+}
+
+void PannerNode::setVelocity(float x, float y, float z)
+{
+ // FIXME : consider thread safety about m_velocity in audio thread.
+ // See http://crbugs.com/350583.
+ FloatPoint3D velocity = FloatPoint3D(x, y, z);
+
+ if (m_velocity == velocity)
+ return;
+
+ m_velocity = velocity;
+}
+
String PannerNode::distanceModel() const
{
switch (const_cast<PannerNode*>(this)->m_distanceEffect.model()) {
@@ -259,10 +309,8 @@ bool PannerNode::setDistanceModel(unsigned model)
return true;
}
-void PannerNode::getAzimuthElevation(double* outAzimuth, double* outElevation)
+void PannerNode::calculateAzimuthElevation(double* outAzimuth, double* outElevation)
{
- // FIXME: we should cache azimuth and elevation (if possible), so we only re-calculate if a change has been made.
-
double azimuth = 0.0;
// Calculate the source-listener vector
@@ -323,11 +371,10 @@ void PannerNode::getAzimuthElevation(double* outAzimuth, double* outElevation)
*outElevation = elevation;
}
-float PannerNode::dopplerRate()
+
+double PannerNode::calculateDopplerRate()
{
double dopplerShift = 1.0;
-
- // FIXME: optimize for case when neither source nor listener has changed...
double dopplerFactor = listener()->dopplerFactor();
if (dopplerFactor > 0.0) {
@@ -368,10 +415,10 @@ float PannerNode::dopplerRate()
}
}
- return static_cast<float>(dopplerShift);
+ return dopplerShift;
}
-float PannerNode::distanceConeGain()
+float PannerNode::calculateDistanceConeGain()
{
FloatPoint3D listenerPosition = listener()->position();
@@ -380,7 +427,6 @@ float PannerNode::distanceConeGain()
m_distanceGain->setValue(static_cast<float>(distanceGain));
- // FIXME: could optimize by caching coneGain
double coneGain = m_coneEffect.gain(m_position, m_orientation, listenerPosition);
m_coneGain->setValue(static_cast<float>(coneGain));
@@ -388,6 +434,72 @@ float PannerNode::distanceConeGain()
return float(distanceGain * coneGain);
}
+void PannerNode::azimuthElevation(double* outAzimuth, double* outElevation)
+{
+ if (isAzimuthElevationDirty())
+ calculateAzimuthElevation(&m_cachedAzimuth, &m_cachedElevation);
+
+ *outAzimuth = m_cachedAzimuth;
+ *outElevation = m_cachedElevation;
+}
+
+double PannerNode::dopplerRate()
+{
+ if (isDopplerRateDirty())
+ m_cachedDopplerRate = calculateDopplerRate();
+
+ return m_cachedDopplerRate;
+}
+
+float PannerNode::distanceConeGain()
+{
+ if (isDistanceConeGainDirty())
+ m_cachedDistanceConeGain = calculateDistanceConeGain();
+
+ return m_cachedDistanceConeGain;
+}
+
+bool PannerNode::isAzimuthElevationDirty()
+{
+ // Do a quick test and return if possible.
+ if (m_cachedPosition != m_position)
+ return true;
+
+ if (m_cachedListener->position() != listener()->position()
+ || m_cachedListener->orientation() != listener()->orientation()
+ || m_cachedListener->upVector() != listener()->upVector())
+ return true;
+
+ return false;
+}
+
+bool PannerNode::isDistanceConeGainDirty()
+{
+ // Do a quick test and return if possible.
+ if (m_cachedPosition != m_position || m_cachedOrientation != m_orientation)
+ return true;
+
+ if (m_cachedListener->position() != listener()->position())
+ return true;
+
+ return false;
+}
+
+bool PannerNode::isDopplerRateDirty()
+{
+ // Do a quick test and return if possible.
+ if (m_cachedPosition != m_position || m_cachedVelocity != m_velocity)
+ return true;
+
+ if (m_cachedListener->position() != listener()->position()
+ || m_cachedListener->velocity() != listener()->velocity()
+ || m_cachedListener->dopplerFactor() != listener()->dopplerFactor()
+ || m_cachedListener->speedOfSound() != listener()->speedOfSound())
+ return true;
+
+ return false;
+}
+
void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<AudioNode*, bool>& visitedNodes)
{
ASSERT(node);
@@ -420,6 +532,23 @@ void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<Audi
}
}
+void PannerNode::updateCachedListener()
+{
+ m_cachedListener->setPosition(listener()->position());
+ m_cachedListener->setOrientation(listener()->orientation());
+ m_cachedListener->setUpVector(listener()->upVector());
+ m_cachedListener->setVelocity(listener()->velocity());
+ m_cachedListener->setDopplerFactor(listener()->dopplerFactor());
+ m_cachedListener->setSpeedOfSound(listener()->speedOfSound());
+}
+
+void PannerNode::updateCachedSourceLocationInfo()
+{
+ m_cachedPosition = m_position;
+ m_cachedOrientation = m_orientation;
+ m_cachedVelocity = m_velocity;
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_AUDIO)
« no previous file with comments | « Source/modules/webaudio/PannerNode.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698