virtual void ProcessBlock(AudioNodeStream* aStream,
                            const AudioChunk& aInput,
                            AudioChunk* aOutput,
                            bool* aFinished)
  {
    if (!mBuffer || !mBufferEnd) {
      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
      return;
    }

    uint32_t channels = mBuffer->GetChannels();
    if (!channels) {
      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
      return;
    }

    // WebKit treats the playbackRate as a k-rate parameter in their code,
    // despite the spec saying that it should be an a-rate parameter. We treat
    // it as k-rate. Spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21592
    UpdateSampleRateIfNeeded(channels);

    uint32_t written = 0;
    TrackTicks streamPosition = aStream->GetCurrentPosition();
    while (written < WEBAUDIO_BLOCK_SIZE) {
      if (mStop != TRACK_TICKS_MAX &&
          streamPosition >= mStop) {
        FillWithZeroes(aOutput, channels, &written, &streamPosition, TRACK_TICKS_MAX);
        continue;
      }
      if (streamPosition < mBeginProcessing) {
        FillWithZeroes(aOutput, channels, &written, &streamPosition,
                       mBeginProcessing);
        continue;
      }
      if (mLoop) {
        // mLoopEnd can become less than mBufferPosition when a LOOPEND engine
        // parameter is received after "loopend" is changed on the node or a
        // new buffer with lower samplerate is set.
        if (mBufferPosition >= mLoopEnd) {
          mBufferPosition = mLoopStart;
        }
        CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, mLoopEnd);
      } else {
        if (mBufferPosition < mBufferEnd || mRemainingResamplerTail) {
          CopyFromBuffer(aStream, aOutput, channels, &written, &streamPosition, 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 && mBufferPosition >= mBufferEnd && !mRemainingResamplerTail)) {
      *aFinished = true;
    }
  }
  virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                 const AudioChunk& aInput,
                                 AudioChunk* aOutput,
                                 bool* aFinished)
  {
    if (!mBuffer || !mDuration) {
      return;
    }

    uint32_t channels = mBuffer->GetChannels();
    if (!channels) {
      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
      return;
    }

    // WebKit treats the playbackRate as a k-rate parameter in their code,
    // despite the spec saying that it should be an a-rate parameter. We treat
    // it as k-rate. Spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21592
    UpdateSampleRateIfNeeded(aStream, channels);

    uint32_t written = 0;
    TrackTicks currentPosition = GetPosition(aStream);
    while (written < WEBAUDIO_BLOCK_SIZE) {
      if (mStop != TRACK_TICKS_MAX &&
          currentPosition >= mStop) {
        FillWithZeroes(aOutput, channels, &written, &currentPosition, TRACK_TICKS_MAX);
        continue;
      }
      if (currentPosition < mStart) {
        FillWithZeroes(aOutput, channels, &written, &currentPosition, mStart);
        continue;
      }
      TrackTicks t = currentPosition - mStart;
      if (mLoop) {
        if (mOffset + t < mLoopEnd) {
          CopyFromBuffer(aStream, aOutput, channels, &written, &currentPosition, mOffset + t, mLoopEnd);
        } else {
          uint32_t offsetInLoop = (mOffset + t - mLoopEnd) % (mLoopEnd - mLoopStart);
          CopyFromBuffer(aStream, aOutput, channels, &written, &currentPosition, mLoopStart + offsetInLoop, mLoopEnd);
        }
      } else {
        if (mOffset + t < mDuration) {
          CopyFromBuffer(aStream, aOutput, channels, &written, &currentPosition, mOffset + t, mDuration);
        } else {
          FillWithZeroes(aOutput, channels, &written, &currentPosition, TRACK_TICKS_MAX);
        }
      }
    }

    // We've finished if we've gone past mStop, or if we're past mDuration when
    // looping is disabled.
    if (currentPosition >= mStop ||
        (!mLoop && currentPosition - mStart + mOffset > mDuration)) {
      *aFinished = true;
    }
  }
  void ProcessBlock(AudioNodeStream* aStream,
                    GraphTime aFrom,
                    const AudioBlock& aInput,
                    AudioBlock* aOutput,
                    bool* aFinished) override
  {
    if (mBufferSampleRate == 0) {
      // start() has not yet been called or no buffer has yet been set
      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
      return;
    }

    StreamTime streamPosition = mDestination->GraphTimeToStreamTime(aFrom);
    uint32_t channels = mBuffer.ChannelCount();

    UpdateSampleRateIfNeeded(channels, streamPosition);

    uint32_t written = 0;
    while (written < WEBAUDIO_BLOCK_SIZE) {
      if (mStop != STREAM_TIME_MAX &&
          streamPosition >= mStop) {
        FillWithZeroes(aOutput, channels, &written, &streamPosition, STREAM_TIME_MAX);
        continue;
      }
      if (streamPosition < mBeginProcessing) {
        FillWithZeroes(aOutput, channels, &written, &streamPosition,
                       mBeginProcessing);
        continue;
      }
      if (mLoop) {
        // mLoopEnd can become less than mBufferPosition when a LOOPEND engine
        // parameter is received after "loopend" is changed on the node or a
        // new buffer with lower samplerate is set.
        if (mBufferPosition >= mLoopEnd) {
          mBufferPosition = mLoopStart;
        }
        CopyFromBuffer(aOutput, channels, &written, &streamPosition, mLoopEnd);
      } else {
        if (mBufferPosition < mBufferEnd || mRemainingResamplerTail) {
          CopyFromBuffer(aOutput, channels, &written, &streamPosition, mBufferEnd);
        } else {
          FillWithZeroes(aOutput, channels, &written, &streamPosition, STREAM_TIME_MAX);
        }
      }
    }

    // We've finished if we've gone past mStop, or if we're past mDuration when
    // looping is disabled.
    if (streamPosition >= mStop ||
        (!mLoop && mBufferPosition >= mBufferEnd && !mRemainingResamplerTail)) {
      *aFinished = true;
    }
  }
Example #4
0
 /*!
  * Reconstruct the buffer to be a copy of an C++ string.
  *
  *  @param[in] str      The string.
  *  @param[in] copy     Tells whether \a str is copied eagerly or lazily.
  */
 void Assign(const std::string &str, COPY copy = COPY_EAGER)
 {
     DetachBuf();
     CopyFromBuffer(str.c_str(), str.size(), copy);
 }
Example #5
0
 /*!
  * Reconstruct the buffer to be a copy of a C string (not including its terminating NUL).
  *
  *  @param[in] str      NUL-terminated string.
  *  @param[in] copy     Tells whether \a str is copied eagerly or lazily.
  */
 void Assign(const char *str, COPY copy = COPY_EAGER)
 {
     DetachBuf();
     CopyFromBuffer(str, std::strlen(str), copy);
 }
Example #6
0
 /*!
  * Reconstruct the buffer to be a copy of some existing data.
  *
  *  @param[in] buf      Points to the data to copy.
  *  @param[in] size     Size (bytes) of data in \a buf.
  *  @param[in] copy     Tells whether \a buf is copied eagerly or lazily.
  */
 void Assign(const void *buf, size_t size, COPY copy = COPY_EAGER)
 {
     DetachBuf();
     CopyFromBuffer(buf, size, copy);
 }
Example #7
0
 /*!
  * Construct a new buffer that is a copy of an C++ string.
  *
  *  @param[in] str      The string.
  *  @param[in] copy     Tells whether \a str is copied eagerly or lazily.
  */
 DATA(const std::string &str, COPY copy = COPY_EAGER)
 {
     CopyFromBuffer(str.c_str(), str.size(), copy);
 }
Example #8
0
 /*!
  * Construct a new buffer that is a copy of a C string (not including its terminating NUL).
  *
  *  @param[in] str      NUL-terminated string.
  *  @param[in] copy     Tells whether \a str is copied eagerly or lazily.
  */
 DATA(const char *str, COPY copy = COPY_EAGER)
 {
     CopyFromBuffer(str, std::strlen(str), copy);
 }
Example #9
0
 /*!
  * Construct a new buffer that is a copy of some existing data.
  *
  *  @param[in] buf      Points to the data to copy.
  *  @param[in] size     Size (bytes) of data in \a buf.
  *  @param[in] copy     Tells whether \a buf is copied eagerly or lazily.
  */
 DATA(const void *buf, size_t size, COPY copy = COPY_EAGER)
 {
     CopyFromBuffer(buf, size, copy);
 }