Synchronize setting of panner node model and processing
authorrtoy@google.com <rtoy@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Feb 2013 00:10:45 +0000 (00:10 +0000)
committerrtoy@google.com <rtoy@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Feb 2013 00:10:45 +0000 (00:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109599

Reviewed by Chris Rogers.

No new tests.

* Modules/webaudio/PannerNode.cpp:
(WebCore::PannerNode::process):
(WebCore::PannerNode::setPanningModel):
* Modules/webaudio/PannerNode.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@142687 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/webaudio/PannerNode.cpp
Source/WebCore/Modules/webaudio/PannerNode.h

index 9d025be3e5c6716e4c2a4913d6cc9ca424874473..eba56182bdd9ef7f971bef22052f737da3af947d 100644 (file)
@@ -1,3 +1,17 @@
+2013-02-12  Raymond Toy  <rtoy@google.com>
+
+        Synchronize setting of panner node model and processing
+        https://bugs.webkit.org/show_bug.cgi?id=109599
+
+        Reviewed by Chris Rogers.
+
+        No new tests.
+
+        * Modules/webaudio/PannerNode.cpp:
+        (WebCore::PannerNode::process):
+        (WebCore::PannerNode::setPanningModel):
+        * Modules/webaudio/PannerNode.h:
+
 2013-02-12  Dean Jackson  <dino@apple.com>
 
         Add class name for snapshotted plugin based on dimensions
index 312499b910a1f47a828709187de8bc846111b693..c970cb0b9f158632698fd4270f789740a7010dfb 100644 (file)
@@ -104,21 +104,28 @@ void PannerNode::process(size_t framesToProcess)
         return;
     }
 
-    // Apply the panning effect.
-    double azimuth;
-    double elevation;
-    getAzimuthElevation(&azimuth, &elevation);
-    m_panner->pan(azimuth, elevation, source, destination, framesToProcess);
-
-    // Get the distance and cone gain.
-    double totalGain = distanceConeGain();
-
-    // Snap to desired gain at the beginning.
-    if (m_lastGain == -1.0)
-        m_lastGain = totalGain;
+    // The audio thread can't block on this lock, so we call tryLock() instead.
+    MutexTryLocker tryLocker(m_pannerLock);
+    if (tryLocker.locked()) {
+        // Apply the panning effect.
+        double azimuth;
+        double elevation;
+        getAzimuthElevation(&azimuth, &elevation);
+        m_panner->pan(azimuth, elevation, source, destination, framesToProcess);
+
+        // Get the distance and cone gain.
+        double totalGain = distanceConeGain();
+
+        // Snap to desired gain at the beginning.
+        if (m_lastGain == -1.0)
+            m_lastGain = totalGain;
         
-    // Apply gain in-place with de-zippering.
-    destination->copyWithGainFrom(*destination, &m_lastGain, totalGain);
+        // Apply gain in-place with de-zippering.
+        destination->copyWithGainFrom(*destination, &m_lastGain, totalGain);
+    } else {
+        // Too bad - The tryLock() failed. We must be in the middle of changing the panner.
+        destination->zero();
+    }
 }
 
 void PannerNode::reset()
@@ -185,6 +192,9 @@ bool PannerNode::setPanningModel(unsigned model)
     case EQUALPOWER:
     case HRTF:
         if (!m_panner.get() || model != m_panningModel) {
+            // This synchronizes with process().
+            MutexLocker processLocker(m_pannerLock);
+            
             OwnPtr<Panner> newPanner = Panner::create(model, sampleRate());
             m_panner = newPanner.release();
             m_panningModel = model;
index 52f44debd227b04f41f28be9ba277631c17ba26d..375c8983d0c6d405e876c0a41b10c011dbe4f8c2 100644 (file)
@@ -154,6 +154,9 @@ private:
     float m_lastGain;
 
     unsigned m_connectionCount;
+
+    // Synchronize process() and setPanningModel() which can change the panner.
+    mutable Mutex m_pannerLock;
 };
 
 } // namespace WebCore