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, ¤tPosition, TRACK_TICKS_MAX); continue; } if (currentPosition < mStart) { FillWithZeroes(aOutput, channels, &written, ¤tPosition, mStart); continue; } TrackTicks t = currentPosition - mStart; if (mLoop) { if (mOffset + t < mLoopEnd) { CopyFromBuffer(aStream, aOutput, channels, &written, ¤tPosition, mOffset + t, mLoopEnd); } else { uint32_t offsetInLoop = (mOffset + t - mLoopEnd) % (mLoopEnd - mLoopStart); CopyFromBuffer(aStream, aOutput, channels, &written, ¤tPosition, mLoopStart + offsetInLoop, mLoopEnd); } } else { if (mOffset + t < mDuration) { CopyFromBuffer(aStream, aOutput, channels, &written, ¤tPosition, mOffset + t, mDuration); } else { FillWithZeroes(aOutput, channels, &written, ¤tPosition, 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; } }