Bug 1308438 - Part 3: Modify CopyFromBuffer to work with negative playback rate. r?dminor, r?padenot draft
authorBeekill95 <nnn_bikiu0707@yahoo.com>
Tue, 21 Mar 2017 22:07:54 +0700
changeset 502800 fc61f5cdec7657b7ec293e4e2cce6d02ac95617c
parent 502799 fb7641e07bad3ab775d9f10673eb3bd3574b43b7
child 502801 7f9789e8723595a557994c376246747e5df1e46b
child 569479 7ca93444fa7e6729430483d09ee1b6a150ad333f
push id50409
push userbmo:nnn_bikiu0707@yahoo.com
push dateWed, 22 Mar 2017 11:28:53 +0000
reviewersdminor, padenot
bugs1308438
milestone54.0a1
Bug 1308438 - Part 3: Modify CopyFromBuffer to work with negative playback rate. r?dminor, r?padenot MozReview-Commit-ID: LpBBmQy4VSR
dom/media/webaudio/AudioBufferSourceNode.cpp
--- a/dom/media/webaudio/AudioBufferSourceNode.cpp
+++ b/dom/media/webaudio/AudioBufferSourceNode.cpp
@@ -429,39 +429,53 @@ public:
       TrackTicks start = *aCurrentPosition *
         mBufferSampleRate / mResamplerOutRate;
       TrackTicks end = (*aCurrentPosition + availableInOutput) *
         mBufferSampleRate / mResamplerOutRate;
       mBufferPosition += end - start;
       return;
     }
 
-    uint32_t numFrames = std::min(aBufferMax - mBufferPosition,
-                                  availableInOutput);
+    float playbackRate = mPlaybackRateTimeline.HasSimpleValue() ?
+                         mPlaybackRateTimeline.GetValue() :
+                         mPlaybackRateTimeline.GetValueAtTime(*aCurrentPosition);
+    uint32_t numFrames = playbackRate >= 0 ?
+                         std::min(aBufferMax - mBufferPosition, availableInOutput) :
+                         std::min(mBufferPosition - aBufferMin, availableInOutput);
 
     bool inputBufferAligned = true;
     for (uint32_t i = 0; i < aChannels; ++i) {
       if (!IS_ALIGNED16(mBuffer->GetData(i) + mBufferPosition)) {
         inputBufferAligned = false;
       }
     }
 
-    if (numFrames == WEBAUDIO_BLOCK_SIZE && inputBufferAligned) {
+    if (numFrames == WEBAUDIO_BLOCK_SIZE && inputBufferAligned && playbackRate >= 0) {
       MOZ_ASSERT(mBufferPosition < aBufferMax);
       BorrowFromInputBuffer(aOutput, aChannels);
     } else {
       if (*aOffsetWithinBlock == 0) {
         aOutput->AllocateChannels(aChannels);
       }
-      MOZ_ASSERT(mBufferPosition < aBufferMax);
-      CopyFromInputBuffer(aOutput, aChannels, *aOffsetWithinBlock, numFrames);
+      if (playbackRate >= 0) {
+        MOZ_ASSERT(mBufferPosition < aBufferMax);
+        CopyFromInputBuffer(aOutput, aChannels, *aOffsetWithinBlock, numFrames);
+      } else {
+        MOZ_ASSERT(mBufferPosition <= aBufferMax);
+        ReverseCopyFromInputBuffer(aOutput, aChannels, *aOffsetWithinBlock, numFrames);
+      }
     }
     *aOffsetWithinBlock += numFrames;
     *aCurrentPosition += numFrames;
-    mBufferPosition += numFrames;
+    if (playbackRate >= 0) {
+      mBufferPosition += numFrames;
+    } else {
+      MOZ_ASSERT(numFrames <= mBufferPosition);
+      mBufferPosition -= numFrames;
+    }
   }
 
   int32_t ComputeFinalOutSampleRate(float aPlaybackRate, float aDetune)
   {
     float computedPlaybackRate = aPlaybackRate * pow(2, aDetune / 1200.f);
     // Make sure the playback rate and the doppler shift are something
     // our resampler can work with.
     int32_t rate = WebAudioUtils::