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):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@131459
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-10-15 Jer Noble <jer.noble@apple.com>
+
+ 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 <simon.hausmann@digia.com>
[Qt] Fix support for silent builds
--- /dev/null
+<!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>
+2012-10-15 Jer Noble <jer.noble@apple.com>
+
+ 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 <vsevik@chromium.org>
Web Inspector: Extract domain specific editing handling logic from UISourceCode (step 2).
{
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)
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
// 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
#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)
// 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;
}