b=967972 change DURATION engine parameter to BUFFEREND r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 06 Feb 2014 08:27:45 +1300
changeset 178130 a908ed1d0408be43d310715ac363702b245a824c
parent 178129 3eb7ea1fb2d7c48cad80de182668a8a9b87d950b
child 178131 d26d7a023b5b577db10870d1797efde0a77dbdc4
push id5439
push userffxbld
push dateMon, 17 Mar 2014 23:08:15 +0000
treeherdermozilla-aurora@c0befb3c8038 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs967972
milestone30.0a1
b=967972 change DURATION engine parameter to BUFFEREND r=padenot
content/media/webaudio/AudioBufferSourceNode.cpp
content/media/webaudio/AudioBufferSourceNode.h
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -42,28 +42,28 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
 
 NS_IMPL_ADDREF_INHERITED(AudioBufferSourceNode, AudioNode)
 NS_IMPL_RELEASE_INHERITED(AudioBufferSourceNode, AudioNode)
 
 /**
  * Media-thread playback engine for AudioBufferSourceNode.
  * Nothing is played until a non-null buffer has been set (via
- * AudioNodeStream::SetBuffer) and a non-zero duration has been set (via
+ * AudioNodeStream::SetBuffer) and a non-zero mBufferEnd has been set (via
  * AudioNodeStream::SetInt32Parameter).
  */
 class AudioBufferSourceNodeEngine : public AudioNodeEngine
 {
 public:
   explicit AudioBufferSourceNodeEngine(AudioNode* aNode,
                                        AudioDestinationNode* aDestination) :
     AudioNodeEngine(aNode),
     mStart(0), mStop(TRACK_TICKS_MAX),
     mResampler(nullptr), mRemainingResamplerTail(0),
-    mOffset(0), mDuration(0),
+    mOffset(0), mBufferEnd(0),
     mLoopStart(0), mLoopEnd(0),
     mBufferSampleRate(0), mPosition(0), mChannels(0), mPlaybackRate(1.0f),
     mDopplerShift(1.0f),
     mDestination(static_cast<AudioNodeStream*>(aDestination->Stream())),
     mPlaybackRateTimeline(1.0f), mLoop(false)
   {}
 
   ~AudioBufferSourceNodeEngine()
@@ -109,18 +109,18 @@ public:
       default:
         NS_ERROR("Bad AudioBufferSourceNodeEngine double parameter.");
     };
   }
   virtual void SetInt32Parameter(uint32_t aIndex, int32_t aParam)
   {
     switch (aIndex) {
     case AudioBufferSourceNode::SAMPLE_RATE: mBufferSampleRate = aParam; break;
-    case AudioBufferSourceNode::OFFSET: mOffset = aParam; break;
-    case AudioBufferSourceNode::DURATION: mDuration = aParam; break;
+    case AudioBufferSourceNode::BUFFERSTART: mOffset = aParam; break;
+    case AudioBufferSourceNode::BUFFEREND: mBufferEnd = aParam; break;
     case AudioBufferSourceNode::LOOP: mLoop = !!aParam; break;
     case AudioBufferSourceNode::LOOPSTART: mLoopStart = aParam; break;
     case AudioBufferSourceNode::LOOPEND: mLoopEnd = aParam; break;
     default:
       NS_ERROR("Bad AudioBufferSourceNodeEngine Int32Parameter");
     }
   }
   virtual void SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList> aBuffer)
@@ -213,17 +213,17 @@ public:
           static_cast<float*>(const_cast<void*>(aOutput->mChannelData[i])) +
           aOffsetWithinBlock;
 
         WebAudioUtils::SpeexResamplerProcess(resampler, i,
                                              inputData, &inSamples,
                                              outputData, &outSamples);
         if (++i == aChannels) {
           mPosition += inSamples;
-          MOZ_ASSERT(mPosition <= mDuration || mLoop);
+          MOZ_ASSERT(mOffset + mPosition <= mBufferEnd || mLoop);
           aFramesWritten = outSamples;
           if (inSamples == availableInInputBuffer && !mLoop) {
             // If the available output space were unbounded then the input
             // latency would always be the correct amount of extra input to
             // provide in order to advance the output position to align with
             // the final point in the buffer.  However, when the output space
             // becomes full, the resampler may read all available input
             // without writing out the corresponding output.  Add one more
@@ -385,17 +385,17 @@ public:
     }
   }
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
                                  AudioChunk* aOutput,
                                  bool* aFinished)
   {
-    if (!mBuffer || !mDuration) {
+    if (!mBuffer || !mBufferEnd) {
       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
       return;
     }
 
     uint32_t channels = mBuffer->GetChannels();
     if (!channels) {
       aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
       return;
@@ -422,41 +422,41 @@ public:
       if (mLoop) {
         if (mOffset + t < mLoopEnd) {
           CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mOffset + t, mLoopEnd);
         } else {
           uint32_t offsetInLoop = (mOffset + t - mLoopEnd) % (mLoopEnd - mLoopStart);
           CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mLoopStart + offsetInLoop, mLoopEnd);
         }
       } else {
-        if (t < mDuration || mRemainingResamplerTail) {
-          CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mOffset + t, mOffset + mDuration);
+        if (mOffset + t < mBufferEnd || mRemainingResamplerTail) {
+          CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mOffset + t, mBufferEnd);
         } else {
           FillWithZeroes(aOutput, channels, &written, &streamPosition, TRACK_TICKS_MAX);
         }
       }
     }
 
     // We've finished if we've gone past mStop, or if we're past mDuration when
     // looping is disabled.
     if (streamPosition >= mStop ||
-        (!mLoop && mPosition >= mDuration && !mRemainingResamplerTail)) {
+        (!mLoop && mOffset + mPosition >= mBufferEnd && !mRemainingResamplerTail)) {
       *aFinished = true;
     }
   }
 
   TrackTicks mStart;
   TrackTicks mStop;
   nsRefPtr<ThreadSharedFloatArrayBufferList> mBuffer;
   SpeexResamplerState* mResampler;
-  // mRemainingResamplerTail, like mPosition, mOffset, and mDuration, is
+  // mRemainingResamplerTail, like mPosition, mOffset, and mBufferEnd, is
   // measured in input buffer samples.
   int mRemainingResamplerTail;
   int32_t mOffset;
-  int32_t mDuration;
+  int32_t mBufferEnd;
   int32_t mLoopStart;
   int32_t mLoopEnd;
   int32_t mBufferSampleRate;
   int32_t mPosition;
   uint32_t mChannels;
   float mPlaybackRate;
   float mDopplerShift;
   AudioNodeStream* mDestination;
@@ -561,39 +561,39 @@ AudioBufferSourceNode::SendBufferParamet
 
 void
 AudioBufferSourceNode::SendOffsetAndDurationParametersToStream(AudioNodeStream* aStream)
 {
   NS_ASSERTION(mBuffer && mStartCalled,
                "Only call this when we have a buffer and start() has been called");
 
   float rate = mBuffer->SampleRate();
-  int32_t bufferLength = mBuffer->Length();
+  int32_t bufferEnd = mBuffer->Length();
   int32_t offsetSamples = std::max(0, NS_lround(mOffset * rate));
 
-  if (offsetSamples >= bufferLength) {
+  if (offsetSamples >= bufferEnd) {
     // The offset falls past the end of the buffer.  In this case, we need to
     // stop the playback immediately if it's in progress.
     // Note that we can't call Stop() here since that might be overridden if
     // web content calls Stop() too, so we just null out the buffer.
     if (mStartCalled) {
       aStream->SetBuffer(nullptr);
     }
     return;
   }
   // Don't set parameter unnecessarily
   if (offsetSamples > 0) {
-    aStream->SetInt32Parameter(OFFSET, offsetSamples);
+    aStream->SetInt32Parameter(BUFFERSTART, offsetSamples);
   }
 
-  int32_t playingLength = bufferLength - offsetSamples;
   if (mDuration != std::numeric_limits<double>::min()) {
-    playingLength = std::min(NS_lround(mDuration * rate), playingLength);
+    bufferEnd = std::min(bufferEnd,
+                         offsetSamples + NS_lround(mDuration * rate));
   }
-  aStream->SetInt32Parameter(DURATION, playingLength);
+  aStream->SetInt32Parameter(BUFFEREND, bufferEnd);
 }
 
 void
 AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv)
 {
   if (!WebAudioUtils::IsTimeValid(aWhen)) {
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return;
--- a/content/media/webaudio/AudioBufferSourceNode.h
+++ b/content/media/webaudio/AudioBufferSourceNode.h
@@ -108,24 +108,28 @@ public:
   IMPL_EVENT_HANDLER(ended)
 
   virtual void NotifyMainThreadStateChanged() MOZ_OVERRIDE;
 
 private:
   friend class AudioBufferSourceNodeEngine;
   // START is sent during Start().
   // STOP is sent during Stop().
-  // OFFSET and DURATION are sent when SetBuffer() and Start() have
+  // BUFFERSTART and BUFFEREND are sent when SetBuffer() and Start() have
   // been called (along with sending the buffer).
   enum EngineParameters {
     SAMPLE_RATE,
     START,
     STOP,
-    OFFSET,
-    DURATION,
+    // BUFFERSTART is the "offset" passed to start(), multiplied by
+    // buffer.sampleRate.
+    BUFFERSTART,
+    // BUFFEREND is the sum of "offset" and "duration" passed to start(),
+    // multiplied by buffer.sampleRate, or the size of the buffer, if smaller.
+    BUFFEREND,
     LOOP,
     LOOPSTART,
     LOOPEND,
     PLAYBACKRATE,
     DOPPLERSHIFT
   };
 
   void SendLoopParametersToStream();