- Revision
- 131459
- Author
- [email protected]
- Date
- 2012-10-16 08:51:25 -0700 (Tue, 16 Oct 2012)
Log Message
WebAudio: limit output level to 0db
https://bugs.webkit.org/show_bug.cgi?id=95792
<rdar://problem/11966135>
Reviewed by Chris Rogers.
.:
Add a manual test to determine that output volume has been limited to 0db.
* ManualTests/webaudio/limit-level-0db.html: Added.
Source/WebCore:
Clamp the output buffer data to the range of [-1,1], which limits
output volume to 0db. This ensures that malicious or poorly-written
pages will not be able to blow through the system volume limit by
creating >0db buffers and effects.
No new tests; added ManualTests/webaudio/limit-level-0db.html.
Clamp the output vector to values of [-1,1]:
* platform/audio/mac/AudioDestinationMac.cpp:
(WebCore::AudioDestinationMac::render):
Add a VectorMath wrapper for vDSP_clip to provide accelerated vector threshold operations:
* platform/audio/VectorMath.h:
* platform/audio/VectorMath.cpp:
(VectorMath):
(WebCore::VectorMath::vclip):
Modified Paths
Added Paths
Diff
Modified: trunk/ChangeLog (131458 => 131459)
--- trunk/ChangeLog 2012-10-16 15:43:13 UTC (rev 131458)
+++ trunk/ChangeLog 2012-10-16 15:51:25 UTC (rev 131459)
@@ -1,3 +1,15 @@
+2012-10-15 Jer Noble <[email protected]>
+
+ WebAudio: limit output level to 0db
+ https://bugs.webkit.org/show_bug.cgi?id=95792
+ <rdar://problem/11966135>
+
+ Reviewed by Chris Rogers.
+
+ Add a manual test to determine that output volume has been limited to 0db.
+
+ * ManualTests/webaudio/limit-level-0db.html: Added.
+
2012-10-16 Simon Hausmann <[email protected]>
[Qt] Fix support for silent builds
Added: trunk/ManualTests/webaudio/limit-level-0db.html (0 => 131459)
--- trunk/ManualTests/webaudio/limit-level-0db.html (rev 0)
+++ trunk/ManualTests/webaudio/limit-level-0db.html 2012-10-16 15:51:25 UTC (rev 131459)
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Web Audio Sample</title>
+ <script>
+ var context = new webkitAudioContext();
+ var gainNode = context.createGainNode();
+ gainNode.connect(context.destination);
+ gainNode.gain.value = 2;
+
+ var frequency = 1000;
+ var duration = 1000;
+
+ function playNormal() {
+ var oscillator = context.createOscillator();
+ oscillator.frequency.value = frequency;
+ oscillator.type = 0;
+ oscillator.connect(context.destination);
+ oscillator.noteOn(0);
+ setTimeout(function(){ oscillator.disconnect(); }, duration);
+ }
+
+ function playLoud() {
+ var oscillator = context.createOscillator();
+ oscillator.frequency.value = frequency;
+ oscillator.type = 0;
+ oscillator.connect(gainNode);
+ oscillator.noteOn(0);
+ setTimeout(function(){ oscillator.disconnect(); }, duration);
+ }
+ </script>
+</head>
+<body>
+ <p>
+ This tests that output audio is clamped to 0db maximum. Press each button below in turn. The apparent volume for both should be equal, even though the second button plays with 2x gain of the first. The resulting waveforms are not equal, however, as the second button audio is clipped to a square wave shape.
+ </p>
+ <button _onclick_="playNormal()">normal volume</button><button _onclick_="playLoud()">double volume</button>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (131458 => 131459)
--- trunk/Source/WebCore/ChangeLog 2012-10-16 15:43:13 UTC (rev 131458)
+++ trunk/Source/WebCore/ChangeLog 2012-10-16 15:51:25 UTC (rev 131459)
@@ -1,3 +1,28 @@
+2012-10-15 Jer Noble <[email protected]>
+
+ WebAudio: limit output level to 0db
+ https://bugs.webkit.org/show_bug.cgi?id=95792
+ <rdar://problem/11966135>
+
+ Reviewed by Chris Rogers.
+
+ Clamp the output buffer data to the range of [-1,1], which limits
+ output volume to 0db. This ensures that malicious or poorly-written
+ pages will not be able to blow through the system volume limit by
+ creating >0db buffers and effects.
+
+ No new tests; added ManualTests/webaudio/limit-level-0db.html.
+
+ Clamp the output vector to values of [-1,1]:
+ * platform/audio/mac/AudioDestinationMac.cpp:
+ (WebCore::AudioDestinationMac::render):
+
+ Add a VectorMath wrapper for vDSP_clip to provide accelerated vector threshold operations:
+ * platform/audio/VectorMath.h:
+ * platform/audio/VectorMath.cpp:
+ (VectorMath):
+ (WebCore::VectorMath::vclip):
+
2012-10-15 Vsevolod Vlasov <[email protected]>
Web Inspector: Extract domain specific editing handling logic from UISourceCode (step 2).
Modified: trunk/Source/WebCore/platform/audio/VectorMath.cpp (131458 => 131459)
--- trunk/Source/WebCore/platform/audio/VectorMath.cpp 2012-10-16 15:43:13 UTC (rev 131458)
+++ trunk/Source/WebCore/platform/audio/VectorMath.cpp 2012-10-16 15:51:25 UTC (rev 131459)
@@ -111,6 +111,11 @@
{
vDSP_svesq(const_cast<float*>(sourceP), sourceStride, sumP, framesToProcess);
}
+
+void vclip(const float* sourceP, int sourceStride, const float* lowThresholdP, const float* highThresholdP, float* destP, int destStride, size_t framesToProcess)
+{
+ vDSP_vclip(const_cast<float*>(sourceP), sourceStride, const_cast<float*>(lowThresholdP), const_cast<float*>(highThresholdP), destP, destStride, framesToProcess);
+}
#else
void vsma(const float* sourceP, int sourceStride, const float* scale, float* destP, int destStride, size_t framesToProcess)
@@ -642,6 +647,22 @@
ASSERT(maxP);
*maxP = max;
}
+
+void vclip(const float* sourceP, int sourceStride, const float* lowThresholdP, const float* highThresholdP, float* destP, int destStride, size_t framesToProcess)
+{
+ int n = framesToProcess;
+ float lowThreshold = *lowThresholdP;
+ float highThreshold = *highThresholdP;
+
+ // FIXME: Optimize for SSE2.
+ // FIXME: Optimize for NEON.
+ while (n--) {
+ *destP = std::max(std::min(*sourceP, highThreshold), lowThreshold);
+ sourceP += sourceStride;
+ destP += destStride;
+ }
+}
+
#endif // OS(DARWIN)
} // namespace VectorMath
Modified: trunk/Source/WebCore/platform/audio/VectorMath.h (131458 => 131459)
--- trunk/Source/WebCore/platform/audio/VectorMath.h 2012-10-16 15:43:13 UTC (rev 131458)
+++ trunk/Source/WebCore/platform/audio/VectorMath.h 2012-10-16 15:51:25 UTC (rev 131459)
@@ -49,6 +49,9 @@
// Multiplies two complex vectors.
void zvmul(const float* real1P, const float* imag1P, const float* real2P, const float* imag2P, float* realDestP, float* imagDestP, size_t framesToProcess);
+// Copies elements while clipping values to the threshold inputs.
+void vclip(const float* sourceP, int sourceStride, const float* lowThresholdP, const float* highThresholdP, float* destP, int destStride, size_t framesToProcess);
+
} // namespace VectorMath
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp (131458 => 131459)
--- trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp 2012-10-16 15:43:13 UTC (rev 131458)
+++ trunk/Source/WebCore/platform/audio/mac/AudioDestinationMac.cpp 2012-10-16 15:51:25 UTC (rev 131459)
@@ -34,11 +34,14 @@
#include "AudioIOCallback.h"
#include "FloatConversion.h"
+#include "VectorMath.h"
#include <CoreAudio/AudioHardware.h>
namespace WebCore {
const int kBufferSize = 128;
+const float kLowThreshold = -1;
+const float kHighThreshold = 1;
// Factory method: Mac-implementation
PassOwnPtr<AudioDestination> AudioDestination::create(AudioIOCallback& callback, float sampleRate)
@@ -158,6 +161,12 @@
// FIXME: Add support for local/live audio input.
m_callback.render(0, &m_renderBus, numberOfFrames);
+ // Clamp values at 0db (i.e., [-1.0, 1.0])
+ for (unsigned i = 0; i < m_renderBus.numberOfChannels(); ++i) {
+ AudioChannel* channel = m_renderBus.channel(i);
+ VectorMath::vclip(channel->data(), 1, &kLowThreshold, &kHighThreshold, channel->mutableData(), 1, numberOfFrames);
+ }
+
return noErr;
}