Bug 1308438 - Part 3: Modify CopyFromBuffer to work with negative playback rate. r?dminor, r?padenot
MozReview-Commit-ID: LpBBmQy4VSR
--- 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::