Index: Source/modules/webaudio/PannerNode.cpp |
diff --git a/Source/modules/webaudio/PannerNode.cpp b/Source/modules/webaudio/PannerNode.cpp |
index 3f2dde89def0dc6e3f5920d71ebb7663e6bd3d12..624f4bc7a499c792b2bc7d1f036c8d429e7dbeeb 100644 |
--- a/Source/modules/webaudio/PannerNode.cpp |
+++ b/Source/modules/webaudio/PannerNode.cpp |
@@ -49,6 +49,7 @@ static void fixNANs(double &x) |
PannerNode::PannerNode(AudioContext* context, float sampleRate) |
: AudioNode(context, sampleRate) |
, m_panningModel(Panner::PanningModelHRTF) |
+ , m_distanceModel(DistanceEffect::ModelInverse) |
, m_position(0, 0, 0) |
, m_orientation(1, 0, 0) |
, m_velocity(0, 0, 0) |
@@ -58,7 +59,7 @@ PannerNode::PannerNode(AudioContext* context, float sampleRate) |
, m_lastGain(-1.0) |
, m_cachedAzimuth(0) |
, m_cachedElevation(0) |
- , m_cachedDistanceConeGain(0) |
+ , m_cachedDistanceConeGain(1.0f) |
, m_cachedDopplerRate(1) |
, m_connectionCount(0) |
{ |
@@ -123,19 +124,19 @@ void PannerNode::process(size_t framesToProcess) |
return; |
} |
- // HRTFDatabase should be loaded before proceeding for offline audio context when panningModel() is "HRTF". |
- if (panningModel() == "HRTF" && !m_hrtfDatabaseLoader->isLoaded()) { |
- if (context()->isOfflineContext()) { |
- m_hrtfDatabaseLoader->waitForLoaderThreadCompletion(); |
- } else { |
- destination->zero(); |
- return; |
- } |
- } |
- |
// The audio thread can't block on this lock, so we call tryLock() instead. |
- MutexTryLocker tryLocker(m_pannerLock); |
+ MutexTryLocker tryLocker(m_processLock); |
if (tryLocker.locked()) { |
+ // HRTFDatabase should be loaded before proceeding for offline audio context when panningModel() is "HRTF". |
+ if (panningModel() == "HRTF" && !m_hrtfDatabaseLoader->isLoaded()) { |
+ if (context()->isOfflineContext()) { |
+ m_hrtfDatabaseLoader->waitForLoaderThreadCompletion(); |
+ } else { |
+ destination->zero(); |
+ return; |
+ } |
+ } |
+ |
// Apply the panning effect. |
double azimuth; |
double elevation; |
@@ -158,7 +159,8 @@ void PannerNode::process(size_t framesToProcess) |
// 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. |
+ // Too bad - The tryLock() failed. |
+ // We must be in the middle of changing the panning model, the distance model, or the source's location information. |
destination->zero(); |
} |
} |
@@ -217,7 +219,7 @@ bool PannerNode::setPanningModel(unsigned model) |
case HRTF: |
if (!m_panner.get() || model != m_panningModel) { |
// This synchronizes with process(). |
- MutexLocker processLocker(m_pannerLock); |
+ MutexLocker processLocker(m_processLock); |
OwnPtr<Panner> newPanner = Panner::create(model, sampleRate(), m_hrtfDatabaseLoader.get()); |
m_panner = newPanner.release(); |
@@ -233,37 +235,40 @@ bool PannerNode::setPanningModel(unsigned model) |
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; |
+ // This synchronizes with process(). |
+ MutexLocker processLocker(m_processLock); |
+ |
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; |
+ // This synchronizes with process(). |
+ MutexLocker processLocker(m_processLock); |
+ |
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; |
+ // This synchronizes with process(). |
+ MutexLocker processLocker(m_processLock); |
+ |
m_velocity = velocity; |
} |
@@ -300,7 +305,12 @@ bool PannerNode::setDistanceModel(unsigned model) |
case DistanceEffect::ModelLinear: |
case DistanceEffect::ModelInverse: |
case DistanceEffect::ModelExponential: |
- m_distanceEffect.setModel(static_cast<DistanceEffect::ModelType>(model), true); |
+ if (model != m_distanceModel) { |
+ // This synchronizes with process(). |
+ MutexLocker processLocker(m_processLock); |
+ m_distanceEffect.setModel(static_cast<DistanceEffect::ModelType>(model), true); |
+ m_distanceModel = model; |
+ } |
break; |
default: |
return false; |
@@ -371,7 +381,6 @@ void PannerNode::calculateAzimuthElevation(double* outAzimuth, double* outElevat |
*outElevation = elevation; |
} |
- |
double PannerNode::calculateDopplerRate() |
{ |
double dopplerShift = 1.0; |
@@ -436,6 +445,8 @@ float PannerNode::calculateDistanceConeGain() |
void PannerNode::azimuthElevation(double* outAzimuth, double* outElevation) |
{ |
+ ASSERT(context()->isAudioThread()); |
+ |
if (isAzimuthElevationDirty()) |
calculateAzimuthElevation(&m_cachedAzimuth, &m_cachedElevation); |
@@ -445,6 +456,8 @@ void PannerNode::azimuthElevation(double* outAzimuth, double* outElevation) |
double PannerNode::dopplerRate() |
{ |
+ ASSERT(context()->isAudioThread()); |
+ |
if (isDopplerRateDirty()) |
m_cachedDopplerRate = calculateDopplerRate(); |
@@ -453,6 +466,8 @@ double PannerNode::dopplerRate() |
float PannerNode::distanceConeGain() |
{ |
+ ASSERT(context()->isAudioThread()); |
+ |
if (isDistanceConeGainDirty()) |
m_cachedDistanceConeGain = calculateDistanceConeGain(); |
@@ -534,6 +549,8 @@ void PannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node, HashMap<Audi |
void PannerNode::updateCachedListener() |
{ |
+ ASSERT(context()->isAudioThread()); |
+ |
m_cachedListener->setPosition(listener()->position()); |
m_cachedListener->setOrientation(listener()->orientation()); |
m_cachedListener->setUpVector(listener()->upVector()); |
@@ -544,6 +561,8 @@ void PannerNode::updateCachedListener() |
void PannerNode::updateCachedSourceLocationInfo() |
{ |
+ ASSERT(context()->isAudioThread()); |
+ |
m_cachedPosition = m_position; |
m_cachedOrientation = m_orientation; |
m_cachedVelocity = m_velocity; |