b=921675 use maximum instead of current delay for tail time because delay can increase faster than time passes r=ehsan
authorKarl Tomlinson <karlt+@karlt.net>
Tue, 01 Oct 2013 09:50:03 +1300
changeset 149382 3a8400387d03af8d227a6d83325a3688fba7daab
parent 149381 3ae5ae74b4a5303fb0413cff28a2eab3a656bd32
child 149383 cb856e6d57c1eeb387e3b57a5e4f95afc16f80cb
push id25386
push useremorley@mozilla.com
push dateTue, 01 Oct 2013 09:29:22 +0000
treeherdermozilla-central@6856c45f3688 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs921675
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=921675 use maximum instead of current delay for tail time because delay can increase faster than time passes r=ehsan
content/media/webaudio/DelayNode.cpp
content/media/webaudio/DelayProcessor.h
content/media/webaudio/test/mochitest.ini
content/media/webaudio/test/test_delayNodeTailIncrease.html
--- a/content/media/webaudio/DelayNode.cpp
+++ b/content/media/webaudio/DelayNode.cpp
@@ -83,17 +83,17 @@ public:
     const uint32_t numChannels = aInput.IsNull() ?
                                  mProcessor.BufferChannelCount() :
                                  aInput.mChannelData.Length();
 
     bool playedBackAllLeftOvers = false;
     if (mProcessor.BufferChannelCount() &&
         mLeftOverData == INT32_MIN &&
         aStream->AllInputsFinished()) {
-      mLeftOverData = mProcessor.CurrentDelayFrames() - WEBAUDIO_BLOCK_SIZE;
+      mLeftOverData = mProcessor.MaxDelayFrames() - WEBAUDIO_BLOCK_SIZE;
 
       if (mLeftOverData > 0) {
         nsRefPtr<PlayingRefChanged> refchanged =
           new PlayingRefChanged(aStream, PlayingRefChanged::ADDREF);
         NS_DispatchToMainThread(refchanged);
       }
     } else if (mLeftOverData != INT32_MIN) {
       mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
--- a/content/media/webaudio/DelayProcessor.h
+++ b/content/media/webaudio/DelayProcessor.h
@@ -32,17 +32,17 @@ public:
   // Process with a constant delay, which will be smoothed with the previous
   // delay.
   void Process(double aDelayFrames, const float* const* aInputChannels,
                float* const* aOutputChannels, int aChannelCount,
                int aFramesToProcess);
 
   void Reset() { mBuffer.Clear(); };
 
-  double CurrentDelayFrames() const { return mCurrentDelay; }
+  int MaxDelayFrames() const { return mMaxDelayFrames; }
   int BufferChannelCount() const { return mBuffer.Length(); }
 
 private:
   bool EnsureBuffer(uint32_t aNumberOfChannels);
 
   // Circular buffer for capturing delayed samples.
   AutoFallibleTArray<FallibleTArray<float>, 2> mBuffer;
   double mSmoothingRate;
--- a/content/media/webaudio/test/mochitest.ini
+++ b/content/media/webaudio/test/mochitest.ini
@@ -71,16 +71,17 @@ support-files =
 [test_convolverNodeWithGain.html]
 [test_convolverNode_mono_mono.html]
 [test_currentTime.html]
 [test_decodeMultichannel.html]
 [test_delayNode.html]
 [test_delayNodeAtMax.html]
 [test_delayNodeCycles.html]
 [test_delayNodeSmallMaxDelay.html]
+[test_delayNodeTailIncrease.html]
 [test_delayNodeWithGain.html]
 [test_dynamicsCompressorNode.html]
 [test_gainNode.html]
 [test_gainNodeInLoop.html]
 [test_maxChannelCount.html]
 [test_mediaDecoding.html]
 [test_mediaElementAudioSourceNode.html]
 [test_mediaStreamAudioDestinationNode.html]
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_delayNodeTailIncrease.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test increasing delay of DelayNode after input finishes</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const signalLength = 100;
+const bufferSize = 1024;
+// Delay should be long enough to allow CC to run
+const delayBufferCount = 50;
+const delayLength = delayBufferCount * bufferSize + 700;
+
+var count = 0;
+
+function applySignal(buffer, offset) {
+  for (var i = 0; i < signalLength; ++i) {
+    buffer.getChannelData(0)[offset + i] = Math.cos(Math.PI * i / signalLength);
+  }
+}
+
+function onAudioProcess(e) {
+  switch(count) {
+  case 5:
+    SpecialPowers.forceGC();
+    SpecialPowers.forceCC();
+    break;
+  case delayBufferCount:
+    var offset = delayLength - count * bufferSize;
+    var ctx = e.target.context;
+    var expected = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
+    applySignal(expected, offset);
+    compareBuffers(e.inputBuffer.getChannelData(0), expected.getChannelData(0));
+    SimpleTest.finish();
+  }
+  count++;
+}
+
+function startTest() {
+  var ctx = new AudioContext();
+  var processor = ctx.createScriptProcessor(bufferSize, 1, 0);
+  processor.onaudioprocess = onAudioProcess;
+
+  // Switch on delay at a time in the future.
+  var delayDuration = delayLength / ctx.sampleRate;
+  var delayStartTime = (delayLength - bufferSize) / ctx.sampleRate;
+  var delay = ctx.createDelay(delayDuration);
+  delay.delayTime.setValueAtTime(delayDuration, delayStartTime);
+  delay.connect(processor);
+
+  // Short signal that finishes before switching to long delay
+  var buffer = ctx.createBuffer(1, signalLength, ctx.sampleRate);
+  applySignal(buffer, 0);
+  var source = ctx.createBufferSource();
+  source.buffer = buffer;
+  source.start();
+  source.connect(delay);
+};
+
+startTest();
+</script>
+</pre>
+</body>
+</html>