Bug 881959 - Clamp the DelayNode.delayTime to 128/AudioContext.sampleRate when in a cycle. r=ehsan, a=akeybl
authorPaul Adenot <paul@paul.cx>
Mon, 02 Sep 2013 15:15:24 +0200
changeset 154105 f9164302e0c30a6c307843dac51b4913a64da8d3
parent 154104 85081a64b652bd6d41a97c5f1b8541f56b5f7dd7
child 154106 29d6ea0f191aaba853599b90e06bd5f3f022cefb
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersehsan, akeybl
bugs881959
milestone25.0
Bug 881959 - Clamp the DelayNode.delayTime to 128/AudioContext.sampleRate when in a cycle. r=ehsan, a=akeybl
content/media/MediaStreamGraph.h
content/media/webaudio/DelayNode.cpp
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -928,16 +928,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
@@ -122,28 +122,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