WebAudio: Optimize calculateNormalizationScale().
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jan 2012 23:52:14 +0000 (23:52 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Jan 2012 23:52:14 +0000 (23:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=74372

Reviewed by Eric Carlson.

No new tests; optimization of existing code, so covered by existing test cases.

* platform/audio/Reverb.cpp:
(WebCore::calculateNormalizationScale): Replace implementation with optimized vector
    math operation.
(WebCore::Reverb::Reverb):
* platform/audio/VectorMath.cpp:
(WebCore::VectorMath::vsvesq): Vector math operation for squared sum of elements.
* platform/audio/VectorMath.h:

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

Source/WebCore/ChangeLog
Source/WebCore/platform/audio/Reverb.cpp
Source/WebCore/platform/audio/VectorMath.cpp
Source/WebCore/platform/audio/VectorMath.h

index f2d7b2248b7e739515622543deaaaf3290cc6073..68ef476ab6f43e5b0db985e5eeafac13cf67e5da 100644 (file)
@@ -1,3 +1,20 @@
+2012-01-13  Jer Noble  <jer.noble@apple.com>
+
+        WebAudio: Optimize calculateNormalizationScale().
+        https://bugs.webkit.org/show_bug.cgi?id=74372
+
+        Reviewed by Eric Carlson.
+
+        No new tests; optimization of existing code, so covered by existing test cases.
+
+        * platform/audio/Reverb.cpp:
+        (WebCore::calculateNormalizationScale): Replace implementation with optimized vector
+            math operation.
+        (WebCore::Reverb::Reverb):
+        * platform/audio/VectorMath.cpp:
+        (WebCore::VectorMath::vsvesq): Vector math operation for squared sum of elements.
+        * platform/audio/VectorMath.h:
+
 2012-01-13  Nico Weber  <thakis@chromium.org>
 
         Remove a unused variable.
index 2b787ebf336d676dec7f401520c1187a4cc5d154..341626fd8ca18b773da8cad52872d0b733a0e2e8 100644 (file)
@@ -35,6 +35,7 @@
 #include "AudioBus.h"
 #include "AudioFileReader.h"
 #include "ReverbConvolver.h"
+#include "VectorMath.h"
 #include <math.h>
 #include <wtf/MathExtras.h>
 #include <wtf/OwnPtr.h>
@@ -46,28 +47,26 @@ using namespace std;
 
 namespace WebCore {
 
+using namespace VectorMath;
+
 // Empirical gain calibration tested across many impulse responses to ensure perceived volume is same as dry (unprocessed) signal
-const double GainCalibration = -58.0;
+const float GainCalibration = -58;
 
 // A minimum power value to when normalizing a silent (or very quiet) impulse response
-const double MinPower = 0.000125;
+const float MinPower = 0.000125f;
     
-static double calculateNormalizationScale(AudioBus* response)
+static float calculateNormalizationScale(AudioBus* response)
 {
     // Normalize by RMS power
     size_t numberOfChannels = response->numberOfChannels();
     size_t length = response->length();
 
-    double power = 0.0;
+    float power = 0;
 
     for (size_t i = 0; i < numberOfChannels; ++i) {
-        int n = length;
-        float* p = response->channel(i)->data();
-
-        while (n--) {
-            float sample = *p++;
-            power += sample * sample;
-        }
+        float channelPower = 0;
+        vsvesq(response->channel(i)->data(), 1, &channelPower, length);
+        power += channelPower;
     }
 
     power = sqrt(power / (numberOfChannels * length));
@@ -76,20 +75,20 @@ static double calculateNormalizationScale(AudioBus* response)
     if (isinf(power) || isnan(power) || power < MinPower)
         power = MinPower;
 
-    double scale = 1.0 / power;
+    float scale = 1 / power;
 
-    scale *= pow(10.0, GainCalibration * 0.05); // calibrate to make perceived volume same as unprocessed
+    scale *= powf(10, GainCalibration * 0.05f); // calibrate to make perceived volume same as unprocessed
 
     // True-stereo compensation
     if (response->numberOfChannels() == 4)
-        scale *= 0.5;
+        scale *= 0.5f;
 
     return scale;
 }
 
 Reverb::Reverb(AudioBus* impulseResponse, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize)
 {
-    double scale = 1;
+    float scale = 1;
 
     if (normalize) {
         scale = calculateNormalizationScale(impulseResponse);
@@ -104,7 +103,7 @@ Reverb::Reverb(AudioBus* impulseResponse, size_t renderSliceSize, size_t maxFFTS
     // FIXME: What about roundoff? Perhaps consider making a temporary scaled copy
     // instead of scaling and unscaling in place.
     if (normalize && scale)
-        impulseResponse->scale(1.0 / scale);
+        impulseResponse->scale(1 / scale);
 }
 
 void Reverb::initialize(AudioBus* impulseResponseBuffer, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads)
index 219298faa22c500ff0b06eec8ec47addd4591ffe..7eea85d6cc046f3804ec2d95919f90ffc8f6faaf 100644 (file)
@@ -95,6 +95,10 @@ void vsma(const float* sourceP, int sourceStride, const float* scale, float* des
     vDSP_vsma(sourceP, sourceStride, scale, destP, destStride, destP, destStride, framesToProcess);
 }
 
+void vsvesq(const float* sourceP, int sourceStride, float* sumP, size_t framesToProcess)
+{
+    vDSP_svesq(const_cast<float*>(sourceP), sourceStride, sumP, framesToProcess);
+}
 #else
 
 void vsma(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
@@ -152,7 +156,6 @@ void vsma(const float* sourceP, int sourceStride, const float* scale, float* des
     }
 }
 
-
 void vsmul(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
 {
 #ifdef __SSE2__
@@ -412,6 +415,20 @@ void zvmul(const float* real1P, const float* imag1P, const float* real2P, const
     }
 }
 
+void vsvesq(const float* sourceP, int sourceStride, float* sumP, size_t framesToProcess)
+{
+    // FIXME: optimize for SSE
+    int n = framesToProcess;
+    float sum = 0;
+    while (n--) {
+        float sample = *sourceP;
+        sum += sample * sample;
+        sourceP += sourceStride;
+    }
+
+    ASSERT(sumP);
+    *sumP = sum;
+}
 #endif // OS(DARWIN)
 
 } // namespace VectorMath
index eacb376b582dc6231f098a7bdd41be860e661efb..155a94b26b0b3a192dc013e010905049b56855f7 100644 (file)
@@ -37,6 +37,9 @@ void vsma(const float* sourceP, int sourceStride, const float* scale, float* des
 void vsmul(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess);
 void vadd(const float* source1P, int sourceStride1, const float* source2P, int sourceStride2, float* destP, int destStride, size_t framesToProcess);
 
+// Sums the squares of a float vector's elements.
+void vsvesq(const float* sourceP, int sourceStride, float* sumP, size_t framesToProcess);
+
 // For an element-by-element multiply of two float vectors.
 void vmul(const float* source1P, int sourceStride1, const float* source2P, int sourceStride2, float* destP, int destStride, size_t framesToProcess);