https://bugs.webkit.org/show_bug.cgi?id=90357
Patch by Raymond Toy <rtoy@google.com> on 2012-07-13
Reviewed by Kenneth Russell.
Source/WebCore:
Increase delay buffer size slightly so that the read and write
pointers don't become equal when the delay and the max delay are
the same.
Tests: webaudio/delaynode-max-default-delay.html
webaudio/delaynode-max-nondefault-delay.html
* Modules/webaudio/DelayDSPKernel.cpp:
(WebCore): Moved SmoothingTimeConstant to WebCore namespace.
(WebCore::DelayDSPKernel::DelayDSPKernel): Add some additional checks to prevent crashes; use bufferLengthForDelay to compute buffer length.
(WebCore::DelayDSPKernel::bufferLengthForDelay): New function to compute buffer length.
* Modules/webaudio/DelayDSPKernel.h:
(DelayDSPKernel): Declare bufferLengthForDelay.
LayoutTests:
New tests to test the case when the delay node delay equals the
maximum allowed delay. Add one test for the default maximum delay
and a second test with a user-set maximum delay.
* webaudio/delaynode-max-default-delay-expected.txt: Added.
* webaudio/delaynode-max-default-delay.html: Added.
* webaudio/delaynode-max-nondefault-delay-expected.txt: Added.
* webaudio/delaynode-max-nondefault-delay.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@122630
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-07-13 Raymond Toy <rtoy@google.com>
+
+ DelayNode doesn't work if delayTime.value == delayTime.maxValue
+ https://bugs.webkit.org/show_bug.cgi?id=90357
+
+ Reviewed by Kenneth Russell.
+
+ New tests to test the case when the delay node delay equals the
+ maximum allowed delay. Add one test for the default maximum delay
+ and a second test with a user-set maximum delay.
+
+ * webaudio/delaynode-max-default-delay-expected.txt: Added.
+ * webaudio/delaynode-max-default-delay.html: Added.
+ * webaudio/delaynode-max-nondefault-delay-expected.txt: Added.
+ * webaudio/delaynode-max-nondefault-delay.html: Added.
+
2012-07-13 Vineet Chaudhary <rgf748@motorola.com>
Restructure V8Utilities::extractTransferables() with help of toV8Sequence()
--- /dev/null
+Tests DelayNode with delay set to default maximum delay.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Test signal was correctly delayed by 1 sec.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+
+<html>
+<head>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/audio-testing.js"></script>
+<script src="resources/delay-testing.js"></script>
+</head>
+
+<body>
+
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests DelayNode with delay set to default maximum delay.");
+
+function runTest() {
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ window.jsTestIsAsync = true;
+
+ // Create offline audio context.
+ var context = new webkitAudioContext(1, sampleRate * renderLengthSeconds, sampleRate);
+ var toneBuffer = createToneBuffer(context, 20, 20 * toneLengthSeconds, sampleRate); // 20Hz tone
+
+ var bufferSource = context.createBufferSource();
+ bufferSource.buffer = toneBuffer;
+
+ var delay = context.createDelayNode();
+ delayTimeSeconds = 1;
+ delay.delayTime.value = delayTimeSeconds;
+
+ bufferSource.connect(delay);
+ delay.connect(context.destination);
+ bufferSource.noteOn(0);
+
+ context.oncomplete = checkDelayedResult(toneBuffer);
+ context.startRendering();
+}
+
+runTest();
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+Tests DelayNode with delay set to non-default maximum delay.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Test signal was correctly delayed by 1.5 sec.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+
+<html>
+<head>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/audio-testing.js"></script>
+<script src="resources/delay-testing.js"></script>
+</head>
+
+<body>
+
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests DelayNode with delay set to non-default maximum delay.");
+
+function runTest() {
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ window.jsTestIsAsync = true;
+
+ // Create offline audio context.
+ var context = new webkitAudioContext(1, sampleRate * renderLengthSeconds, sampleRate);
+ var toneBuffer = createToneBuffer(context, 20, 20 * toneLengthSeconds, sampleRate); // 20Hz tone
+
+ var bufferSource = context.createBufferSource();
+ bufferSource.buffer = toneBuffer;
+
+ var maxDelay = 1.5;
+ var delay = context.createDelayNode(maxDelay);
+ delayTimeSeconds = maxDelay;
+ delay.delayTime.value = delayTimeSeconds;
+
+ bufferSource.connect(delay);
+ delay.connect(context.destination);
+ bufferSource.noteOn(0);
+
+ context.oncomplete = checkDelayedResult(toneBuffer);
+ context.startRendering();
+}
+
+runTest();
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
+2012-07-13 Raymond Toy <rtoy@google.com>
+
+ DelayNode doesn't work if delayTime.value == delayTime.maxValue
+ https://bugs.webkit.org/show_bug.cgi?id=90357
+
+ Reviewed by Kenneth Russell.
+
+ Increase delay buffer size slightly so that the read and write
+ pointers don't become equal when the delay and the max delay are
+ the same.
+
+ Tests: webaudio/delaynode-max-default-delay.html
+ webaudio/delaynode-max-nondefault-delay.html
+
+ * Modules/webaudio/DelayDSPKernel.cpp:
+ (WebCore): Moved SmoothingTimeConstant to WebCore namespace.
+ (WebCore::DelayDSPKernel::DelayDSPKernel): Add some additional checks to prevent crashes; use bufferLengthForDelay to compute buffer length.
+ (WebCore::DelayDSPKernel::bufferLengthForDelay): New function to compute buffer length.
+ * Modules/webaudio/DelayDSPKernel.h:
+ (DelayDSPKernel): Declare bufferLengthForDelay.
+
2012-07-13 Benjamin Poulain <bpoulain@apple.com>
Always aggressively preload on iOS
using namespace std;
-const float SmoothingTimeConstant = 0.020f; // 20ms
-
namespace WebCore {
+const float SmoothingTimeConstant = 0.020f; // 20ms
+
DelayDSPKernel::DelayDSPKernel(DelayProcessor* processor)
: AudioDSPKernel(processor)
, m_writeIndex(0)
, m_firstTime(true)
{
ASSERT(processor && processor->sampleRate() > 0);
- if (!processor)
+ if (!(processor && processor->sampleRate() > 0))
return;
m_maxDelayTime = processor->maxDelayTime();
- m_buffer.allocate(static_cast<size_t>(processor->sampleRate() * m_maxDelayTime));
+ ASSERT(m_maxDelayTime >= 0);
+ if (m_maxDelayTime < 0)
+ return;
+
+ m_buffer.allocate(bufferLengthForDelay(m_maxDelayTime, processor->sampleRate()));
m_buffer.zero();
m_smoothingRate = AudioUtilities::discreteTimeConstantForSampleRate(SmoothingTimeConstant, processor->sampleRate());
if (maxDelayTime <= 0.0)
return;
- size_t bufferLength = static_cast<size_t>(sampleRate * maxDelayTime);
+ size_t bufferLength = bufferLengthForDelay(maxDelayTime, sampleRate);
ASSERT(bufferLength);
if (!bufferLength)
return;
m_smoothingRate = AudioUtilities::discreteTimeConstantForSampleRate(SmoothingTimeConstant, sampleRate);
}
+size_t DelayDSPKernel::bufferLengthForDelay(double maxDelayTime, double sampleRate) const
+{
+ // Compute the length of the buffer needed to handle a max delay of |maxDelayTime|. One is
+ // added to handle the case where the actual delay equals the maximum delay.
+ return 1 + AudioUtilities::timeToSampleFrame(maxDelayTime, sampleRate);
+}
+
void DelayDSPKernel::process(const float* source, float* destination, size_t framesToProcess)
{
size_t bufferLength = m_buffer.size();
double m_desiredDelayFrames;
DelayProcessor* delayProcessor() { return static_cast<DelayProcessor*>(processor()); }
+ size_t bufferLengthForDelay(double delayTime, double sampleRate) const;
};
} // namespace WebCore