Bug 881959 - Clamp the DelayNode.delayTime to 128/AudioContext.sampleRate when in a cycle. r=ehsan
authorPaul Adenot <paul@paul.cx>
Mon, 02 Sep 2013 15:15:24 +0200
changeset 162688 fd52dbee297f089f6fa9eb671536a64204f86298
parent 162687 44b5ab1bb6d3813e639c5c05d150bc49f881bd5d
child 162689 1e2237c4172ce9ff553a111cac959d8a7439ce0c
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs881959
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
Bug 881959 - Clamp the DelayNode.delayTime to 128/AudioContext.sampleRate when in a cycle. r=ehsan
content/media/MediaStreamGraph.h
content/media/webaudio/DelayNode.cpp
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -938,16 +938,19 @@ public:
   virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo) = 0;
   void SetAutofinishImpl(bool aAutofinish) { mAutofinish = aAutofinish; }
 
   /**
    * Forward SetTrackEnabled() to the input MediaStream(s) and translate the ID
    */
   virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) {};
 
+  bool InCycle() const { return mInCycle; }
+
+
 protected:
   // This state is all accessed only on the media graph thread.
 
   // The list of all inputs that are currently enabled or waiting to be enabled.
   nsTArray<MediaInputPort*> mInputs;
   bool mAutofinish;
   // True if and only if this stream is in a cycle.
   // Updated by MediaStreamGraphImpl::UpdateStreamOrder.
--- a/content/media/webaudio/DelayNode.cpp
+++ b/content/media/webaudio/DelayNode.cpp
@@ -123,28 +123,38 @@ public:
       }
     }
 
     const float* const* inputChannels = input.IsNull() ? nullptr :
       reinterpret_cast<const float* const*>(input.mChannelData.Elements());
     float* const* outputChannels = reinterpret_cast<float* const*>
       (const_cast<void* const*>(aOutput->mChannelData.Elements()));
 
+
+    bool inCycle = aStream->AsProcessedStream()->InCycle();
     double sampleRate = aStream->SampleRate();
     if (mDelay.HasSimpleValue()) {
-      double delayFrames = mDelay.GetValue() * sampleRate;
-      mProcessor.Process(delayFrames, inputChannels, outputChannels,
+      // If this DelayNode is in a cycle, make sure the delay value is at least
+      // one block.
+      float delayFrames = mDelay.GetValue() * sampleRate;
+      float delayFramesClamped = inCycle ? std::max(static_cast<float>(WEBAUDIO_BLOCK_SIZE), delayFrames) :
+                                           delayFrames;
+      mProcessor.Process(delayFramesClamped, inputChannels, outputChannels,
                          numChannels, WEBAUDIO_BLOCK_SIZE);
     } else {
       // Compute the delay values for the duration of the input AudioChunk
+      // If this DelayNode is in a cycle, make sure the delay value is at least
+      // one block.
       double computedDelay[WEBAUDIO_BLOCK_SIZE];
       TrackTicks tick = aStream->GetCurrentPosition();
       for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
-        computedDelay[counter] =
-          mDelay.GetValueAtTime(tick, counter) * sampleRate;
+        float delayAtTick = mDelay.GetValueAtTime(tick, counter) * sampleRate;
+        float delayAtTickClamped = inCycle ? std::max(static_cast<float>(WEBAUDIO_BLOCK_SIZE), delayAtTick) :
+                                             delayAtTick;
+        computedDelay[counter] = delayAtTickClamped;
       }
       mProcessor.Process(computedDelay, inputChannels, outputChannels,
                          numChannels, WEBAUDIO_BLOCK_SIZE);
     }
 
 
     if (playedBackAllLeftOvers) {
       // Delete our buffered data once we no longer need it