Diff
Modified: trunk/Source/WebCore/ChangeLog (105003 => 105004)
--- trunk/Source/WebCore/ChangeLog 2012-01-13 23:40:36 UTC (rev 105003)
+++ trunk/Source/WebCore/ChangeLog 2012-01-13 23:52:14 UTC (rev 105004)
@@ -1,3 +1,20 @@
+2012-01-13 Jer Noble <jer.no...@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 <tha...@chromium.org>
Remove a unused variable.
Modified: trunk/Source/WebCore/platform/audio/Reverb.cpp (105003 => 105004)
--- trunk/Source/WebCore/platform/audio/Reverb.cpp 2012-01-13 23:40:36 UTC (rev 105003)
+++ trunk/Source/WebCore/platform/audio/Reverb.cpp 2012-01-13 23:52:14 UTC (rev 105004)
@@ -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 @@
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 @@
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 @@
// 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)
Modified: trunk/Source/WebCore/platform/audio/VectorMath.cpp (105003 => 105004)
--- trunk/Source/WebCore/platform/audio/VectorMath.cpp 2012-01-13 23:40:36 UTC (rev 105003)
+++ trunk/Source/WebCore/platform/audio/VectorMath.cpp 2012-01-13 23:52:14 UTC (rev 105004)
@@ -95,6 +95,10 @@
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 vsmul(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
{
#ifdef __SSE2__
@@ -412,6 +415,20 @@
}
}
+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
Modified: trunk/Source/WebCore/platform/audio/VectorMath.h (105003 => 105004)
--- trunk/Source/WebCore/platform/audio/VectorMath.h 2012-01-13 23:40:36 UTC (rev 105003)
+++ trunk/Source/WebCore/platform/audio/VectorMath.h 2012-01-13 23:52:14 UTC (rev 105004)
@@ -37,6 +37,9 @@
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);